Skip to content

Ship a Claude Code plugin that lists NodeSpace's skills in the session and tracks changes; slim the static skill and remove the tool shims #3545

Closed

Description

@malibio

Overview

A Claude Code session reaches NodeSpace today only if the model decides to open the one static nodespace skill and then decides to fetch. This issue ships a Claude Code plugin that puts NodeSpace in the session from the start: it checks NodeSpace is reachable, finds the project for the checkout, lists every skill in the system prompt, and tells the agent when the list changes. The same plugin serves a session started from a terminal and one NodeSpace launches.

Problem Statement

  • The skills in the graph are not listed anywhere the agent can see. It has to decide to look without knowing what exists, so a team's process is followed only when the model happens to ask.
  • The preflight (is the CLI installed, is the daemon up) is prose the model must remember to run.
  • packages/skill/shims/ holds four tool-registration scripts that no harness loads. The Claude Code one calls a global hook() that does not exist and imports Node modules the plugin runtime does not have. They, their parity test and their packaging are dead weight that reads as if it worked.

Proposed Solution

The plugin. A Claude Code plugin of function hooks, shipped in the skill package and installed with it. It does four things (ADR-093 §5):

  1. At session start: confirm the nodespace CLI and daemon answer; read the checkout's git remote and look up its project.
  2. Add one section to the system prompt holding a short orientation shipped with the plugin (this project's process and context live in NodeSpace, how to reach them, and that they take precedence over instruction files in the repository where the two differ), the consent rules shipped with the plugin, and the skill list read from the graph and marked as graph-authored.
  3. On each prompt: compare the skill list's version with the one last read; if it changed, add a note to the conversation naming what was added, changed or removed, including a skill this session already fetched.
  4. Show status: reachable or not, and the project.

With no project for the checkout, it shows that NodeSpace is reachable and adds nothing else. With the daemon unreachable, it says so once and adds nothing.

The plugin holds no retrieval or assembly logic: every piece of content comes from a nodespace command.

The static skill. SKILL.md keeps what an agent without the plugin needs: what NodeSpace is, how to reach it, when and how to fetch, the consent rules, and the pointer to the command reference.

Removal. Delete all four shims, their parity test, and everything that stages, type-checks or publishes them.

Documentation

  • ADR-093 §5 - what a plugin does and where it loads from; §6 - what the static skill keeps; §7 - procedure, not permission; §9 - what is removed; Consequences - plugins are thin, the CLI operations are a contract
  • ADR-064 §5 (revised) - the skill file owns the entry point
  • ADR-035 - one client, the CLI; amended by ADR-093 to drop the shims as the catalog
  • ADR-052 - local trust, for graph-authored text placed in the system prompt
  • ADR-081 - the plugin and its text name no other product
  • Updates: architecture/agent-session.md (how a coding agent gets NodeSpace's context), ADR-035's and ADR-032's descriptions of the shims if still cited as current

Architecture Impact

Implements ADR-093 §5, §6 (static skill), §7 and §9 (shims). ADR-093 already amends ADR-035 and ADR-038 for this; no further decision changes.

Acceptance Criteria

Plugin

  • The plugin is a manifest, a hooks file and one hooks module, installed by the skill installer into the Claude Code skill folder so Claude Code loads it with no flag; the published plugin carries it too
  • claude plugin validate on the installed folder reports no refusals
  • At session start it runs the CLI's version and diagnostics checks and the query that finds the project by its repository URL, with no Node or DOM API: every outside call goes through the plugin runtime's own process and state calls
  • The system prompt section contains the orientation, the consent rules and the skill list; the list is visibly marked as read from the graph and each entry is a title and its description
  • The orientation and consent rules are shipped text, not read from the graph
  • The orientation states that NodeSpace takes precedence over repository instruction files where they differ on process
  • On a prompt after a skill was added, edited or removed, a note names the change before the agent acts; with no change, nothing is added
  • During a turn, before a tool call and at most once in a set interval, the plugin compares the version of the context read for the item the session is working on with the one last seen
  • If that item was finished, cancelled or changed under the session, further tool calls are refused with the reason until the user responds, so the agent stops and reports; if only its governing nodes or skills changed, a note is added and the work continues
  • With no item being worked on, the check does nothing; the interval is configurable and a failed check never blocks a tool call
  • The plugin learns which item the session is working on from the agent's own NodeSpace commands, with no knowledge of any node type
  • A skill the session has fetched and that changed since is named in the note as changed
  • The skill list is re-read at session start and after compaction or /clear, and the plugin's record of what it delivered is reset then
  • A long skill list is capped, and the section says how to list the rest
  • With no matching project the plugin adds only the status entry; with the daemon unreachable it says so once and adds nothing else
  • NODESPACE_DATABASE in the session's environment selects the database for every command the plugin runs
  • The plugin's behaviour is covered by plugin tests that run outside the merge gate, and a script and note in the package say how to run them
  • The PR records two findings: whether the section and hooks reach subagents, and whether anything the plugin registers appears in the model's own skill listing

Static skill

  • SKILL.md carries no preflight steps the plugin performs for Claude Code beyond what an agent without the plugin needs, and nothing in it contradicts references/cli.md
  • bun run skill:check passes

Removal

  • packages/skill/shims/ and packages/skill/src/tests/shim-parity.test.ts are deleted
  • No installer target, staging list, package files entry, TypeScript project, publish script or release step refers to a shim
  • A reinstall removes a previously installed shim file from each harness folder, through the existing install record
  • No text in packages/, scripts/ or README.md claims a harness loads tools from a shim

General

  • scripts/check-pro-boundary.ts passes
  • Docs updated as listed under Documentation
  • Code passes bun run quality:fix
  • Tests pass (bun run test:changed)

Technical Specifications

Reference Files

  • packages/skill/src/agents.ts - per-harness install targets and the shims lists
  • packages/skill/src/installer.ts - install, the install record, the plugin-managed skip, uninstall
  • packages/skill/shims/, packages/skill/tsconfig.shims.json, packages/skill/package.json - to delete or edit
  • scripts/build-skill.ts (STAGED_ENTRIES), scripts/publish-skill-repo.ts, .github/workflows/release.yml - staging and publishing
  • packages/skill/SKILL.md, packages/cli/examples/gen_skill_md.rs, packages/cli/tests/it/skill_md_generation.rs - the static skill and its generator
  • packages/cli/src/commands/skill.rs - the skill list, match and fetch commands the plugin calls

Implementation Details

  • Load Claude Code's plugin-authoring skill before writing the hooks module: it gives this build's type declarations, the validate and test commands, and the events. The ones this plugin needs are session start, system prompt composition, prompt submission, appending a note to the conversation, the status line, running a host command by argv, and session state.
  • The plugin API is early access and changes between releases. Keep the module to glue around CLI calls so a change breaks little.
  • Keep what the plugin has delivered in session state, not module variables: a reload loses those.
  • A hook has a time budget. The session-start checks and the per-prompt version check each make one CLI call; do not add a search per prompt.
  • Do not rewrite the system prompt mid-session to refresh the list; that invalidates the prompt cache. Changes arrive as notes.
  • The installer already skips its own copy when a plugin-managed install exists; keep one copy loaded, never two.

Dependencies

Related Issues

Non-Goals

  • Matching every prompt and attaching a skill automatically
  • Recording pull request and commit links from a hook
  • Plugins for other harnesses
  • Changes to how NodeSpace launches a session

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions