Repository navigation
Give each built-in tool its CLI command and return it with fetched skills; fetch one skill by name; version the skill list #3540
Description
Overview
A coding agent (Claude Code, Codex, Pi, OpenCode) fetches NodeSpace's skills with nodespace skill guidance. Built-in skills are rendered for it: a step that has to name how it is done is a rule with an agent form and a CLI form. Three things are still missing for that fetch to serve every skill and the harness plugins that will sit on it:
- A tool named anywhere else is not translated: in a skill a user wrote or edited, or in a built-in skill's prose outside a rule.
- A skill cannot be fetched by its name, only matched by a task description.
- The skill list has no version, so a client cannot tell that the list changed since it last read it.
Problem Statement
Tool names reach a coding agent untranslated. A user-written or user-edited skill is served as stored. If its body says "use search_nodes when you know the name", or its tool_whitelist lists create_relationship, a coding agent has no such tool and nothing tells it which nodespace command does the same thing. Skills are meant to be any instruction a user writes, and a body may say which tool to use in which case, so this is the common case for user skills, not an edge.
No fetch by name. An agent that sees "Writing a Spec" in the skill list has to describe a task and hope the match returns that skill. A plugin that lists skills needs a deterministic way to load the one the agent picked.
No way to detect a changed list. Skills change while a session is open (a teammate adds a policy, a user edits a procedure). A plugin needs one cheap call to learn whether the list it showed the agent is still current.
Proposed Solution
- Record each built-in tool's CLI command on its registry node. Add an optional text field to
tool-nativeholding thenodespacecommand that does the same thing (for examplecreate_relationship→nodespace relationship create). A tool with no CLI equivalent leaves it unset. - Return tool commands with a fetched skill. For each skill a fetch returns to a coding agent, include the CLI command of every registry tool the skill lists in
tool_whitelistor names in its body. This applies to built-in, user-edited and user-written skills alike. The body is not rewritten. - Keep the per-audience rules. A built-in step whose procedure differs between the built-in agent and the CLI (deleting, which the CLI previews and then confirms; a task's status, which the CLI sets with its own command) stays a rule with a form per audience. The command field translates a name; a rule covers a different procedure.
- Fetch one skill by name or id, returning the same content a match returns for it: instructions, referenced schemas, tool commands, provenance.
- Version the skill list. The list output carries a version that changes whenever a skill is added, removed or archived, or its name, description or body changes.
Documentation
- ADR-093 §1 - the list, match and get operations and the list version; §2 - skills name tools from the registry, a tool carries its command-line form, and a step whose procedure differs keeps a form per reader
- ADR-064 §5 (revised) - the skill file is the entry point, skill nodes own procedure, per-audience rules; extended by ADR-093 §2
- Tool Registry -
toolandtool-native, the fields a tool node carries - Node type sequence - mandatory for the new
tool-nativefield - ADR-086 - one wire definition, generated TypeScript, closed schemas
- Updates:
components/node-types.md(thetool-nativesheet),components/tool-registry.md(the new field),architecture/prompt-skill-system.md(what a fetch returns)
Architecture Impact
Implements ADR-093 §1 and §2. ADR-093 §2 extends ADR-064 §5 (revised): the per-audience rule form stays for steps whose procedure differs, and the registry command is added for tool names everywhere else. Both ADRs already say this; no further decision change is needed. The docs listed under Updates change in the same work.
Acceptance Criteria
-
tool-nativedeclares an optional text field for the tool's CLI command, added through the node type sequence: schema, registry, wire type, typed update, regenerated TypeScript (bun run gen:types), and thetool-nativesheet innode-types.md - Every seeded built-in tool that has a
nodespaceequivalent carries its command; a test fails if a built-in tool named by any seeded skill (intool_whitelistor body) has none - A fetch by a coding agent returns, for each skill, the CLI command of every registry tool the skill lists in
tool_whitelistor names in its body - The same holds for a user-written skill and a user-edited built-in skill; a test covers a user-written skill whose body names a built-in tool
- A tool name is matched in a body at word boundaries, so
update_nodedoes not match insideupdate_nodes_from_markdown - A tool with no CLI command is left out of the returned commands, and the fetch still succeeds
- The built-in agent's rendering of every skill is unchanged; prompt and routing golden snapshots show no diff
- The per-audience rule forms are unchanged
- A skill can be fetched by exact name or by id, returning the same content a match returns for that skill, inside the same provenance envelope; an unknown name fails with a message naming it
- The no-task listing carries a version in
--jsonoutput and in human output - The version changes when a skill is added, removed or archived, and when a skill's name, description or any part of its body changes; it does not change when unrelated nodes change
- Two listings with no skill change between them return the same version
- The CLI output changes are reflected in
packages/skill/SKILL.mdandpackages/skill/references/cli.md, including when to fetch a skill by name, andbun run skill:checkpasses -
SKILL.mdtells the agent that the returned tool commands are how it carries out a step that names a tool - The live skill-fetch test covers a user-written skill that names a built-in tool: the agent runs the corresponding
nodespacecommand -
tool-registry.mdandprompt-skill-system.mdupdated as listed under Documentation - Code passes
bun run quality:fix - Tests pass (
bun run test:changed)
Technical Specifications
Reference Files
packages/core/src/models/core_schemas.rs- thetoolandtool-nativeschemaspackages/agent/src/skill_pipeline.rs-seed_tool_nodes(each built-in tool's node, keyed byhandler),SKILL_SEEDSpackages/core/src/ops/skill_ops.rs-find_skills,render_skill_instructions,mentions_phrase(word-boundary matching)packages/daemon/src/services/node_service.rsandpackages/proto/proto/node_service.proto- theGetSkillGuidanceRPCpackages/cli/src/commands/skill.rs-skill guidance, the provenance envelope and its printerpackages/agent/src/skill_rules.rs- the per-audience rule forms, which staypackages/agent/tests/it/live_skill_guidance_fetch.rs- the live fetch testpackages/cli/examples/gen_skill_md.rs,packages/cli/tests/it/skill_md_generation.rs- the generated regions ofSKILL.mdandreferences/cli.mdpackages/nodespace-types- thetool-nativewire type
Implementation Details
- Field names are snake_case and stored names are user-visible keys, so choose the field's name once. It describes what it holds (the tool's CLI command), not who reads it.
- The command is the command and subcommand, not a full invocation with flags. Argument shapes stay in
references/cli.mdand--help(ADR-064). - Resolve tool nodes through the registry (
type_is_a), not a literalnode_typecomparison. An archived tool is not offered and its command is not returned. - The version is derived from stored state (for example a hash over each skill's id and version, including its subtree), not kept as a counter. Nothing is written when a skill changes.
- Whether fetch-by-name is a flag on
skill guidanceor its own subcommand is the implementer's choice; say which in the PR and document it incli.md. - A new or changed RPC means regenerating the proto stubs.
- Seed changes need a database reset, not a backfill.
Related Issues
- Let agents fetch NodeSpace's skills and schemas by intent: make skill guidance return them, and embed schemas #3502 (built the fetch this extends)
- Audit skill retrieval text: rename description/exclusion to use_for/not_for, tighten what each skill is for, and add measured not_for entries #3522 (renames the skill fields the list shows)
Non-Goals
- Harness plugins, ready tasks, task context and the project lookup (other parts of ADR-093)
- Turning
tool_whitelistfrom names into declared links to tool nodes - Bindings for remote tools (
tool-mcp,tool-rest,tool-cli)
Activity
malibio commentedon Oct 4, 2026
Baseline — Frontend: 315 test files passed (5690 tests)
Record each built-in tool's CLI command and return it with fetched sk…