# context

## Objective

Rename the `learn` tool to `docs` and consolidate built-in learn articles, neovim help docs (`doc/*.txt`), and user-defined docs (`.magenta/docs/`) into a single tool. The tool's input schema description lists all available docs (built-in + user), similar to how `learn` currently lists its three articles. A precommit check ensures all `doc/*.txt` files are linked.

## Key design decisions

- **Neovim docs**: Hardcode name + description in TypeScript; read content from `doc/*.txt` at runtime. Path derived from `__dirname` (same pattern as current learn tool).
- **User docs**: Discovered from `.magenta/docs/` (hardcoded, not configurable). Same YAML frontmatter as skills (`name` + `description`). Flat `.md` files (not subdirectories).
- **Skills**: Remain separate — skills are about scripts on the filesystem, docs are reference material.
- **Tool spec**: Dynamic (like `spawn_subagents`), since user docs are discovered at runtime. Built-in doc names/descriptions are static; user docs are appended.
- **System prompt**: Doc descriptions appear in the tool's `input_schema.properties.name.description`, exactly as learn does today.

## Relevant files

- `node/core/src/tools/learn.ts` — current learn tool implementation (rename to `docs.ts`)
- `node/core/src/tools/learn/` — directory with 3 built-in markdown articles
- `node/core/src/tools/tool-registry.ts` — `STATIC_TOOL_NAMES` and capability lists
- `node/core/src/tools/toolManager.ts` — `StaticToolMap`, `TOOL_SPEC_MAP`, `getToolSpecs()`
- `node/core/src/tools/create-tool.ts` — `createTool()` switch, `CreateToolContext`
- `node/core/src/tools/helpers.ts` — `validateInput()` switch
- `node/core/src/tool-types.ts` — `ToolStructuredResult` union, `Learn` import
- `node/render-tools/index.ts` — tool display rendering (cases for `"learn"`)
- `node/render-tools/streaming.ts` — streaming display (case for `"learn"`)
- `node/tools/learn.test.ts` — integration test
- `node/core/src/providers/skills.ts` — skill discovery (reference for user doc discovery pattern)
- `node/core/src/thread-core.ts` — calls `getToolSpecs()`, has `cwd` in context
- `.git/hooks/pre-commit` — existing precommit script

## Types

```typescript
// Built-in doc entry (hardcoded in docs.ts)
type BuiltinDoc = {
  name: string;           // e.g. "create-skill", "magenta-commands"
  description: string;    // one-line description for tool spec
  source: "article" | "help";  // article = learn/*.md, help = doc/*.txt
};

// User doc entry (discovered from .magenta/docs/)
type UserDoc = {
  name: string;
  description: string;
  filePath: string;       // absolute path to the .md file
};

// Combined
type DocEntry = BuiltinDoc | UserDoc;
```

# implementation

## Step 1: Rename `learn` → `docs` across the codebase

Mechanical rename — no behavior change.

- [ ] Rename `node/core/src/tools/learn.ts` → `node/core/src/tools/docs.ts`
- [ ] Rename `node/core/src/tools/learn/` → `node/core/src/tools/docs/`
- [ ] Update `tool-registry.ts`: replace `"learn"` with `"docs"` in all arrays and capability map
- [ ] Update `toolManager.ts`: replace `Learn` import → `Docs`, update `StaticToolMap` key, update `TOOL_SPEC_MAP`
- [ ] Update `create-tool.ts`: replace `Learn` import → `Docs`, update switch case
- [ ] Update `helpers.ts`: replace `Learn` import → `Docs`, update switch case
- [ ] Update `tool-types.ts`: replace `Learn` import → `Docs`, update `ToolStructuredResult`
- [ ] Update `render-tools/index.ts`: replace `"learn"` cases with `"docs"`
- [ ] Update `render-tools/streaming.ts`: replace `"learn"` case with `"docs"`
- [ ] Rename `node/tools/learn.test.ts` → `node/tools/docs.test.ts`, update tool name in test
- [ ] Update `node/core/src/index.ts` if it exports anything learn-related
- [ ] Run type check (`npx tsgo -b`) and fix any remaining references
- [ ] Run tests and verify the existing learn test passes with new name

## Step 2: Add neovim help docs as built-in docs

- [ ] In `docs.ts`, define a `BUILTIN_DOCS` array with entries for both article docs and help docs:
  ```typescript
  const BUILTIN_DOCS: BuiltinDoc[] = [
    // Existing articles
    { name: "create-skill", description: "Guide for creating new skills...", source: "article" },
    { name: "update-permissions", description: "Configure sandbox permissions...", source: "article" },
    { name: "plan", description: "Guide for creating implementation plans...", source: "article" },
    // Neovim help docs
    { name: "magenta", description: "Overview, installation, and quick start guide", source: "help" },
    { name: "magenta-commands", description: "Commands, keymaps, and input reference", source: "help" },
    { name: "magenta-config", description: "Configuration options, profiles, and project settings", source: "help" },
    { name: "magenta-tools", description: "Available tools, sub-agents, MCP support, and permissions", source: "help" },
    { name: "magenta-providers", description: "Provider configuration and supported models", source: "help" },
  ];
  ```
- [ ] Compute `HELP_DIR` from `__dirname` (e.g. `join(__dirname, "../../../../doc")`) — same relative-path pattern as current `LEARN_DIR`
- [ ] Update `loadDoc()` to handle both sources: articles from `DOCS_DIR` (renamed from `LEARN_DIR`), help from `HELP_DIR`
- [ ] Update `spec` generation to include all built-in docs in the enum and description
- [ ] Update `validateInput()` to accept the new doc names
- [ ] Test: request a neovim help doc (e.g. `magenta-commands`) and verify content is returned
  - **Setup**: standard `withDriver` test
  - **Actions**: mock agent requests `docs` tool with `{ name: "magenta-commands" }`
  - **Assertions**: tool result contains text from `doc/magenta-commands.txt` (e.g. check for "magenta-send" or similar known content)

## Step 3: Add user doc discovery

- [ ] Create a `loadUserDocs()` function in `docs.ts` (or a separate `user-docs.ts` in core):
  - Takes `cwd: NvimCwd` and `logger: Logger`
  - Scans `.magenta/docs/` relative to cwd for `*.md` files
  - Parses YAML frontmatter (reuse `extractYamlFrontmatter` from `skills.ts` — export it, or extract to a shared utility)
  - Returns `UserDoc[]`
- [ ] The `docs` tool needs runtime access to discovered user docs for two reasons:
  1. **Spec generation**: `getSpec(userDocs)` builds dynamic enum + description
  2. **Execution**: `execute(request, { userDocs })` loads content from the right file
- [ ] Make `getToolSpecs()` accept user docs and pass them to `Docs.getSpec()`:
  - Add `userDocs?: UserDoc[]` parameter to `getToolSpecs()`
  - Thread `userDocs` from `ThreadCoreContext` (where `cwd` is available) down to spec generation
  - `ThreadCore` calls `loadUserDocs()` once and stores the result, passing it to both `getToolSpecs()` and `createTool()`
- [ ] Update `CreateToolContext` to include `userDocs` so `execute()` can resolve user doc paths
- [ ] Update `validateInput()` to accept user doc names (pass the valid names set)
- [ ] Test: user doc discovery
  - **Setup**: create a temp `.magenta/docs/my-guide.md` with frontmatter `name: my-guide`, `description: My custom guide`
  - **Actions**: call `loadUserDocs()` with temp dir as cwd
  - **Assertions**: returns array with one entry matching the frontmatter
- [ ] Test: requesting a user doc returns its content
  - **Setup**: `withDriver` with a `.magenta/docs/` file in the test project dir
  - **Actions**: mock agent requests `docs` tool with `{ name: "my-guide" }`
  - **Assertions**: tool result contains the markdown content of the file

## Step 4: Add precommit check

- [ ] Create a check script (inline in `.git/hooks/pre-commit` or as a separate `scripts/check-docs.mjs`):
  - List all `doc/*.txt` files (excluding `tags`)
  - Extract the expected doc names (filename without `.txt`)
  - Read `node/core/src/tools/docs.ts` and extract the `BUILTIN_DOCS` array entries with `source: "help"`
  - Assert every `doc/*.txt` file has a corresponding entry, and every help entry has a corresponding file
  - Exit non-zero with a clear message if there's a mismatch
- [ ] Add the check to the existing pre-commit hook (`.git/hooks/pre-commit`) as a parallel check alongside typecheck and biome
- [ ] Test: temporarily add a `doc/fake.txt` file, run the check, verify it fails; remove it, verify it passes

## Step 5: Update learn article for create-skill

- [ ] Update `node/core/src/tools/docs/create-skill.md` to mention that `.magenta/docs/` is for reference docs (not scripts), distinguishing from `.magenta/skills/`
- [ ] Briefly describe the frontmatter format for user docs

## Step 6: Update existing test

- [ ] Update `node/tools/docs.test.ts` (renamed in step 1) to also test a neovim help doc
- [ ] Verify all tests pass with `TEST_MODE=sandbox npx vitest run`
