Skip to content

Chapter 13 · Two-Layer Skill System and Custom Extensions ​

Chapter goals: Understand the two-layer layout difference between .agents/skills/ internal skills and skills/ public skills, master the SKILL.md structure规范, and tour the bin/ toolbelt to lay the foundation for writing custom skills.

13.1 Two-Layer Layout: Why Skills Are Split ​

Open the FirstMate repo and you'll find skills stored in two different directories:

text
firstmate/
├── .agents/skills/     # Agent-loaded internal skills (~20)
│   ├── afk/SKILL.md
│   ├── ahoy/SKILL.md
│   ├── bearings/SKILL.md
│   ├── stow/SKILL.md
│   ├── secondmate-provisioning/SKILL.md
│   └── ...
└── skills/             # Public, installer-facing standalone skills
    └── stow/SKILL.md   # Currently the only one

This split is not arbitrary组织 — it is determined by audience:

  • .agents/skills/: loaded by the firstmate itself. Each assumes "a live firstmate home exists" — without this context they are meaningless,甚至 actively misleading. For example, the secondmate-provisioning skill references paths, tools, and vocabulary that only make sense inside a firstmate home.
  • skills/: public, independently-installable skills, designed to work in any project without依赖 any firstmate私有 paths, tools, or vocabulary.

An interesting detail: the stow "twin" design. .agents/skills/stow and skills/stow are two deliberately independent files with零 shared code. The official maintenance comment reads: keep them independent — each evolves without拖拽 the other. The internal version writes the firstmate home's operational记忆 and cascades to secondmates; the public version routes through a three-level rule chain: explicit instruction → local convention → private .stow-notes.md fallback — toany project.

13.2 metadata.internal: true — Invisible to Installers ​

Comparing the two stow frontmatters reveals the关键差异:

yaml
# .agents/skills/stow/SKILL.md (internal version)
---
name: stow
description: Sweep the current session for uncaptured durable knowledge...
user-invocable: true
metadata:
  internal: true          # ← internal flag
---
yaml
# skills/stow/SKILL.md (public version)
---
name: stow
description: Sweep the current conversation for durable knowledge...
user-invocable: true      # ← no metadata.internal
---

The purpose of metadata.internal: true: it causes installers like npx skills add to skip the skill during discovery — internal skills should not be installed elsewhere. Meanwhile, it is完全 inert to the firstmate's own skill loader (frontmatter metadata is inert to the loader): loading and trigger points proceed normally.

This is the两层的 safety mechanism: visibility is determined by audience; loading behavior is determined by trigger points.

13.3 SKILL.md Anatomy and Trigger Points ​

Each skill's核心 is a SKILL.md file with three parts:

markdown
---
name: bearings                      # Globally unique skill name
description: Generate a concise four-section chat digest...
user-invocable: true                # Whether可被用户直接调用
metadata:
  internal: true                    # Only carried by internal skills
---

<!-- Maintainer注释区 -->

# bearings

Body: methodology, steps, boundary constraints…
The agent loads the full text and follows executionwhen the trigger点 hits.

Two trigger点 categories:

  1. User invocation (user-invocable: true): the captain types /ahoy, $stow etc.;
  2. Agent-only reference: skills without the user-invocable mark (e.g., ask-user-authority, captain-hold-lifecycle, diagnostic-reasoning, harness-adapters etc.) are named and loaded按需 by AGENTS.md at specific程序节点.

13.4 Methodology for Writing Custom Skills for FirstMate ​

Based on the structure above, the思路 for adding a custom skill to firstmate is clear:

text
1. Judge the audience:
   - Depends on FM_HOME/state/projects等 firstmate context?
     → Place in .agents/skills/ and加 metadata.internal: true
   - Usable in any project?
     → Consider a standalone skill under skills/
2. Write SKILL.md:
   - name unique; description clearly states when totrigger
   - Body writes executable methodology, not空泛 description
3. Explicitly write边界:
   - Internal skills can onlypersist through FirstMate's既有所有权 and写入边界
4. Test: the repo自带行为测试运行器 fm-test-run.sh可验证

One important discipline from official maintenance comments: public skills must remain standalone — no私有 project paths, tool assumptions, or environment branch logic.

13.5 bin/ Toolbelt Tour ​

Skills负责 "知道怎么做"; the dozens of scripts under bin/负责 "真正去做". The official docs/scripts.md gives a full清单; here we认识 the core batch by职能:

text
Session lifecycle
├── fm-session-start.sh    # Composes lock/bootstrap/wake-drain into a single ordered digest
├── fm-bootstrap.sh        # Toolchain self-check + install approved missing tools
├── fm-teardown.sh         # Owner of the landed-work完整性测试 (Hard Rule 3)
└── fm-send.sh             # Send messages to tasks; fail closed if FM_HOME is不明确

Task dispatch and briefs
├── fm-spawn.sh            # Spawn crewmates/scouts/batches/secondmates
├── fm-brief.sh            # Scaffold ship/scout/charter briefs (--mode explicitly specified)
└── fm-captain-hold.sh     # Suspend task waiting for captain decision; record answer; gate completion

Supervision engine
├── fm-watch.sh            # Singleton-safe常驻 watcher (Chapter 11)
├── fm-turnend-guard.sh    # No-turn-ends-blind判定谓词 (Chapter 11)
└── fm-guard.sh            # Pull-style mid-course warnings

Config and merge
├── fm-config-push.sh      # Push declared inheritance materials to local/remote secondmates
├── fm-merge-local.sh      # Captain-approved fast-forward merge for local-only projects
└── fm-project-mode.sh     # Parse project delivery posture from data/projects.md

Two使用要点 worth单独强调:

First, fm-send.sh's fail-closed design: if FM_HOME is不明确, the send直接失败 rather than guessing the target — this prevents a steer from silently landing in the wrong home. It is the "multi-home isolation"原则 reflected at the script层.

Second, read the header before using: docs/scripts.md gives only a one-line用途概括 per script; the script's own头部注释is the权威描述 of its behavior, flags, and contract. The official反复强调 read the header before first use.

Also note fm-decision-hold.sh's特殊性: it is a one-release兼容垫片 (shim) that映射 the retired decision command to fm-captain-hold.sh —说明这套工具带本身也在演进; when encountering an old command, check for a shimfirst.

13.6 Chapter Summary ​

  • Two-layer skill system: .agents/skills/ for内部 skills that依赖 the firstmate home context; skills/ for零-dependency public skills;
  • metadata.internal: true makes内部 skills invisible to installers like skills.sh, while不affecting the firstmate's own loader (frontmatter metadata is inert to the loader);
  • SKILL.md = frontmatter (name/description/user-invocable/metadata) + methodology body; trigger points分 user slash-calls and AGENTS.md-named agent-only loads;
  • Writing custom skills: judge audience first, then位置; public skills必须 standalone; internal skills must走既有写入边界;
  • bin/ is the execution toolbelt: fm-send.sh's FM_HOME fail-closed and "read the header before using" are the two most important使用纪律.

🧪 随堂测验

点击你认为正确的选项。答错时会展示正确答案与原因解析。

1. Why do skills in .agents/skills/ carry metadata.internal: true?

2. What determines whether a skill is user-invocable or agent-only?

3. What is the key difference between .agents/skills/stow and skills/stow?

4. What does fm-send.sh do if FM_HOME is not set?

🛠️ Hands-On Exercises ​

  1. List all skill directories under .agents/skills/; check each frontmatter for metadata.internal: true and user-invocable: true; organize into a two-column table (user-invocable / agent-only) and对照 Chapter 12's five built-in skills.
  2. Compare-read the bodies of .agents/skills/stow/SKILL.md and skills/stow/SKILL.md; find at least threebehavioral differences caused by different audiences; write a short comment explaining why the官方坚持零共享代码.
  3. Pick three bin/fm-*.sh scripts you care about (建议含 fm-send.sh); read each header注释; summarize the usage contract (parameters, env requirements, failure behavior) in your own words; corroborate against the one-line概括 in docs/scripts.md.

Two-layer skills understood. Next, Secondmate: persistent isolated deputy and charter.