Skip to content

Commit e33ca83

Browse files
authored
feat: self-documenting docmap CLI + setup-guide skill
- The `docmap` CLI is now self-documenting: `--help` prints full usage, `--guide` prints the authoring conventions, and `--search "<terms>"` filters documents by path and frontmatter (title, summary, read_when) using case-insensitive AND matching. - Bare invocation over a small doc set (under 20 files) lists recursively and prepends a short help preamble; larger sets keep the top-level listing. - Every displayed command uses the detected package-manager prefix; with no lockfile it falls back to the package-runner form (`npx` / `pnpm dlx` / `yarn dlx` / `bunx`). Help and guide command blocks are column-aligned per package manager. - The authoring guide is stored as a Markdown template (`packages/docmap/templates/guide.md`) and read at runtime; the template ships with the package. - Added the `alignfirst-setup-guide` skill — a one-time setup dispatcher that investigates a consumer repo, discusses which of {docmap, workspace, alignfirst skills} to install or upgrade, and follows the matching reference. All docmap/workspace/alignfirst setup and migration procedures live under its `references/`. - Removed the `docmap` and `workspace-guide` skills and the `migrations/` directory; their knowledge now lives in the CLI guide and the setup-guide skill. - Simplified the consumer `AGENTS.md` docmap section to a single mandatory line, and updated the docmap README, root README, and architecture docs accordingly.
1 parent 3a2aa4d commit e33ca83

58 files changed

Lines changed: 822 additions & 326 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@
2727

2828
## Docmap - Seek Documentation
2929

30-
**Before any investigation or code exploration**, run `npm run docmap` to list the documentation index. This is mandatory for every task — do not skip it. Browse subdirectories or read files by passing them as arguments (`npm run docmap -- topic-a docs/topic-b/doc.md`), or list everything (`npm run docmap -- --recursive`).
30+
**Before any investigation or code exploration**, run `npm run docmap`, then read the relevant documentation. Mandatory for every task.
3131

3232
## AlignFirst - Ticket ID, Commit Message, Branch Name
3333

3434
_Ticket ID_: Format is numeric. Use the ticket ID if explicitly provided. Otherwise, deduce it from the current branch name (no confirmation needed). If the branch name is unavailable, get it via `git branch --show-current`. Only ask the user as a last resort.
3535

3636
Commit message convention: we use conventional commit, e.g., `feat: [#123] add new feature`. Always prefix the ticket ID with a `#` sign. Do not add a "Co-Authored-By:" line.
3737

38-
Branch naming convention: `<type>/<ticket-id>` (with type from conventional commit, e.g., `feat/123`, `fix/123`, `refactor/123`, `chore/123`).
38+
Branch naming convention: `<ticket-id>/<1-3-words>`.
3939

4040
Add `paleo-typescript-style` skill to every plan.
4141

alignfirst-skills.md

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,38 +19,20 @@ npx skills add https://github.com/paleo/alignfirst --global --skill alignfirst -
1919
2020
### Configure your project (optional)
2121

22-
This adds `.plans` to `.gitignore` and an AlignFirst section to your `AGENTS.md` (or `CLAUDE.md`). Give your agent this prompt:
22+
This adds `.plans` to `.gitignore` and an AlignFirst section to your `AGENTS.md` (or `CLAUDE.md`). Install the setup-guide skill temporarily:
2323

24-
```markdown
25-
I just installed the alignfirst skill. Help me configure it:
26-
27-
1. Create `.plans/` directory if it doesn't exist, and add `.plans` to `.gitignore` if needed.
28-
2. Check if `AGENTS.md` or `CLAUDE.md` exists. If one exists, use it. If neither exists, create `AGENTS.md`. This file is our INSTRUCTION_FILE.
29-
3. Look at our git branches (`git branch -a`) to detect our ticket ID format (e.g., `ABC-###`, `PROJ-###`, or numeric).
30-
- If no pattern is found, ask me for our ticket ID format:
31-
32-
> "I couldn't detect a ticket ID format from the branch names. Please provide the ticket ID format (e.g., "numeric", `ABC-###`, etc.) or type 'skip' to omit."
33-
34-
4. From our recent commit messages (`git log --oneline -20`), deduce the commit message convention (e.g., `<type>: [<ticket-id>] description`, `<type>(<scope>): description`, `[<ticket-id>] description`, etc.).
35-
- If no pattern is found, ask me for our commit message convention:
36-
37-
> "I couldn't detect a commit message convention. Please describe it (e.g., `feat: [AB-123] short description`, `type(scope): description`, etc.) or type 'skip' to omit."
38-
39-
5. Detect the default branch with `git remote show origin | grep "HEAD branch"` (e.g., `main`, `master`, `develop`).
24+
```bash
25+
npx skills add https://github.com/paleo/alignfirst --skill alignfirst-setup-guide
26+
```
4027

41-
6. Insert the following into the INSTRUCTION_FILE (skip any part already present):
42-
- Add this line where it feels appropriate: "Always ignore the `.plans` directory when searching the codebase."
43-
- If a ticket ID format was found, add this section (include each convention line only if one was detected or provided):
28+
Then ask your agent:
4429

45-
> ## AlignFirst - Ticket ID, Commit Message, Default Branch
46-
>
47-
> _Ticket ID:_ Format is `{DETECTED_FORMAT}`. Use the ticket ID if explicitly provided. Otherwise, deduce it from the current branch name (no confirmation needed). If the branch name is unavailable, get it via `git branch --show-current`. Only ask the user as a last resort.
48-
>
49-
> _Commit message convention:_ `{DETECTED_CONVENTION}`
50-
>
51-
> _Default branch:_ `{DETECTED_DEFAULT_BRANCH}`
30+
```text
31+
Use your alignfirst-setup-guide skill. Configure the AlignFirst skills in this project.
5232
```
5333

34+
Once done, you can uninstall the setup-guide skill — it won't be used by your project anymore.
35+
5436
> **Note (2026-03-09):** On Cursor, to make the skills available as commands (using `/`), I had to create a symlink: `cd ~/.cursor/ && ln -s ../.agents/skills .`
5537
5638
## Usage
@@ -152,28 +134,25 @@ Specs, plans, and summaries should be written in well-organized (git-ignored) lo
152134

153135
## Upgrade from v1 or v2
154136

155-
1. Install the docmap skill:
137+
1. Install the setup-guide skill:
156138

157139
```bash
158-
npx skills add https://github.com/paleo/alignfirst --skill docmap
140+
npx skills add https://github.com/paleo/alignfirst --skill alignfirst-setup-guide
159141
```
160142

161-
Then, ask your agent to install the docmap CLI:
143+
2. Ask your agent to run the upgrade:
162144

163145
```text
164-
Use your docmap skill. Install docmap CLI in this project.
146+
Use your alignfirst-setup-guide skill. Upgrade AlignFirst in this project.
165147
```
166148

167-
At the end, the agent will suggest available instructions: ignore them, we will handle that in the prompt of step 2.
168-
169-
2. Give your agent **[this upgrade prompt](https://raw.githubusercontent.com/paleo/alignfirst/refs/heads/main/migrations/upgrade.md)**.
170-
3. Install the new alignfirst skill:
149+
3. Install the new alignfirst skills:
171150

172151
```bash
173152
npx skills add https://github.com/paleo/alignfirst --global --skill alignfirst --skill al --skill alplan --skill alspec --skill aldescription --skill alreview --skill alread --skill almerge
174153
```
175154

176-
> **Note:** We recommend installing the alignfirst skills globally so they're easier to update. For the docmap skill, prefer a local/project installation.
155+
> **Note:** We recommend installing the alignfirst skills globally so they're easier to update.
177156
178157
## License
179158

docs/docmap-architecture.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,26 @@ Three TypeScript modules in `packages/docmap/src/`, compiled to `packages/docmap
2020
| --- | --- |
2121
| `src/parser.ts` | YAML frontmatter extraction (`extractMetadata`) and stripping (`stripFrontmatter`). |
2222
| `src/formatter.ts` | Directory reading, listing/formatting, name validation, `--check`, and file resolution (`readDocFile`, direct path then fuzzy basename search; returns `undefined` when nothing resolves). |
23-
| `src/cli.ts` | Argument parsing, flow orchestration, package-manager detection for tips. |
23+
| `src/cli.ts` | Argument parsing, flow orchestration, package-manager detection, and help/guide rendering (the `--guide` body is read from `templates/guide.md`). |
2424

2525
Entry point: `packages/docmap/bin/docmap.mjs` → imports `packages/docmap/dist/cli.js` → calls `main()` → returns an exit code.
2626

27+
The `--guide` text lives as Markdown in `packages/docmap/templates/guide.md` with three placeholders: `{{PM}}` for a bare invocation, `{{PM_ARGS}}` for one that forwards arguments, and `{{COMMANDS}}` for the rendered "Browsing with CLI" command block. `{{PM}}` and `{{PM_ARGS}}` differ only for npm, whose `run` script needs a `--` separator before args (`npm run docmap` vs `npm run docmap --`); every other manager forwards args verbatim, so both resolve to the same command. `renderGuide()` reads the file via `new URL("../templates/guide.md", import.meta.url)` — the path resolves from both `src/cli.ts` (dev/test) and `dist/cli.js` (published), each one level under the package root — and substitutes all three tokens. `templates/` is listed in `package.json` `files` so it ships with the package.
28+
29+
Help and guide command lists are built from shared `CommandRow[]` builders (`browseCommands`, `moreCommands`, `guideCommands`) and rendered through one `renderCommands()` helper that pads each command to the group's longest, so the `#` comments stay vertically aligned for any package-manager prefix. Short help, full help (`Commands:` + `More:`), and the guide's `{{COMMANDS}}` block all flow through it; each group aligns independently.
30+
2731
## CLI Flow
2832

2933
`main()` in `src/cli.ts` drives everything:
3034

31-
1. **Parse args**`parseArgs()` extracts `--recursive`, `--root`, `--check`, collects positional **paths**, and collects unknown `--flags`. Tokens starting with `--` are never paths; an unknown one is recorded and later warned about on stderr (so a stale `docmap --dir topic-a` still works — `--dir` is skipped, `topic-a` is a positional). `parseArgs` is pure (no writes).
35+
1. **Parse args**`parseArgs()` extracts the mode flags `--help`, `--guide`, `--search <terms>`, `--recursive`, `--root <path>`, `--check`, collects positional **paths**, and collects unknown `--flags`. `--search` consumes the next token as its value (same shape as `--root`); without a following token it is recorded as unknown. Tokens starting with `--` are never paths; an unknown one is recorded and later warned about on stderr (so a stale `docmap --dir topic-a` still works — `--dir` is skipped, `topic-a` is a positional). `parseArgs` is pure (no writes).
3236
2. **Resolve base directory**`--root` or default `docs/` relative to `cwd`. The **display prefix** is `relative(cwd, baseDir)``docs` by default, or the root's path for a custom `--root` (e.g. `config/docs`, or `../shared` outside cwd). All displayed paths carry this prefix, so they stay real and openable; the empty prefix (root === cwd) yields bare paths.
33-
3. **`--check`**`checkAll()` validates every file and directory name (shell-safe regex) and every `.md` frontmatter. Returns exit code 1 if any issues. (Only `--check` returns non-zero.)
34-
4. **Classify positionals** — each path is normalized (trailing slashes stripped, leading display prefix removed; the bare prefix → root), resolved under the base dir, then `statSync`-tested. Existing directory → listing bucket; everything else (existing file, or missing) → read bucket. `statSync` throwing on a missing path is caught and treated as "not a directory". The filesystem is the source of truth — no extension heuristic.
35-
5. **Listings** — produced for each directory-classified path via `listDirectory()`/`formatDirectory()` or `formatRecursive()`. With no positionals at all, or with `--recursive` and no directory positionals, the root is listed. Files-only with `--recursive` off produces no listing.
36-
6. **Reads** — each read-bucket path goes through `readDocFile()` (direct path, then fuzzy basename search). A resolved result is wrapped in `<document_file>` tags; an unresolved one becomes a single generic `⚠ Not found: <path>` line (same wording for a mistyped file or directory — classification can't read intent, and a not-found read keeps exit code 0). Reads follow listings, separated by a blank line.
37-
7. **Tip** — After a listing, one contextual tip (`formatTip`) is appended explaining that several paths can be passed at once; the example shows directory args only when subdirs exist and file args (carrying the display prefix) only when files exist. The package manager is auto-detected from lockfiles.
37+
3. **Mode dispatch** — modes are tried in precedence and each returns early after printing only its own output: `--help` (full help) → `--guide` (authoring guide) → `--search` (path + frontmatter match) → `--check` (validation) → listing/read. `--help`/`--guide`/`--search` always return `0`; only `--check` can return `1`. Help and guide text is rendered from the auto-detected package manager so every shown command is copy-pasteable.
38+
4. **`--search`**`searchDocs()` walks the tree (`collectAllFiles`), reads each file, and keeps the ones whose joined `relative-path + title + summary + read_when` text contains every whitespace-split term (case-insensitive; body text is not searched). Including the relative path means a basename or directory segment matches even when absent from frontmatter. Matches render as file bullets, or a single `No documents match: <terms>` line.
39+
5. **Classify positionals** — each path is normalized (trailing slashes stripped, leading display prefix removed; the bare prefix → root), resolved under the base dir, then `statSync`-tested. Existing directory → listing bucket; everything else (existing file, or missing) → read bucket. `statSync` throwing on a missing path is caught and treated as "not a directory". The filesystem is the source of truth — no extension heuristic.
40+
6. **Listings** — produced for each directory-classified path via `listDirectory()`/`formatDirectory()` or `formatRecursive()`. With no positionals at all, or with `--recursive` and no directory positionals, the root is listed. A **bare** invocation (no positionals, none of `--recursive`/`--check`/`--help`/`--guide`/`--search`) lists recursively when the tree holds fewer than 20 `.md` files (`collectAllFiles` count), and is the only case prefixed with short help; at ≥20 it keeps the top-level listing. An explicit `--recursive` is unaffected. Files-only with `--recursive` off produces no listing.
41+
7. **Reads** — each read-bucket path goes through `readDocFile()` (direct path, then fuzzy basename search). A resolved result is wrapped in `<document_file>` tags; an unresolved one becomes a single generic `⚠ Not found: <path>` line (same wording for a mistyped file or directory — classification can't read intent, and a not-found read keeps exit code 0). Reads follow listings, separated by a blank line.
42+
8. **Tip** — After a listing, one contextual tip (`formatTip`) is appended explaining that several paths can be passed at once; the example shows directory args only when subdirs exist and file args (carrying the display prefix) only when files exist. The package manager is auto-detected from lockfiles, falling back to bare `docmap` when no lockfile is found.
3843

3944
## Frontmatter Contract
4045

@@ -74,8 +79,8 @@ Warnings (⚠) appear inline for name issues or frontmatter errors.
7479
| `npm -w @paleo/docmap test` | Run tests with Vitest |
7580
| `npm run lint` | Biome linter (root) |
7681

77-
Tests live in `packages/docmap/test/docmap.test.ts` and use fixture directories under `packages/docmap/test/fixtures/` (basic, errors, empty, nested, bad-names, subdirs-only). Each fixture is a self-contained `docs/`-like tree passed via `--root`.
82+
Tests live in `packages/docmap/test/docmap.test.ts` and use fixture directories under `packages/docmap/test/fixtures/` (basic, errors, empty, nested, bad-names, subdirs-only, classify, no-frontmatter, large). Each fixture is a self-contained `docs/`-like tree passed via `--root`. The `large` fixture (≥20 `.md` files) exercises the top-level listing kept above the recursive-default threshold.
7883

79-
## Agent Skill
84+
## Authoring Guide and Setup
8085

81-
The `skills/docmap/` directory ships a reusable agent skill that teaches AI agents how to use docmap, write documents, install it in a project, bootstrap a `docs/` directory, and migrate documentation from skills. It is distributed separately from the npm package.
86+
The authoring conventions (frontmatter contract, naming, workflow) ship with the CLI as `templates/guide.md`: `docmap --guide` prints that file, rendered with the project's package-manager prefix. Project setup — bootstrapping a `docs/` tree, wiring docmap into a repo, and migrating existing docs or skills — lives in the separate `alignfirst-setup-guide` skill, distributed outside the npm package.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

docs/workspace-architecture.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Workspace Package Architecture
3-
summary: Internals of the `@paleo/workspace` kernel — foreground self-exit, stop/teardown signal mechanics, cross-worktree callback dispatch, the `workspace remove` re-exec, the concurrency-cap race, and registry liveness. Complements the `workspace-guide` skill (the consumer-facing blueprint).
3+
summary: Internals of the `@paleo/workspace` kernel — foreground self-exit, stop/teardown signal mechanics, cross-worktree callback dispatch, the `workspace remove` re-exec, the concurrency-cap race, and registry liveness. Complements the workspace setup blueprint (`skills/alignfirst-setup-guide/references/workspace-setup.md`), the consumer-facing guide.
44
read_when:
55
- onboarding to the @paleo/workspace codebase
66
- changing dev-server start/stop, foreground, or eviction behavior
@@ -10,7 +10,7 @@ read_when:
1010

1111
# Workspace Package Architecture
1212

13-
For the consumer-facing blueprint — concepts, config fields, the CLI surface, and how to adapt the system to a repository — see the [`workspace-guide` skill](../skills/workspace-guide/SKILL.md). This document covers package internals and edge-case behavior that don't belong in that guide.
13+
For the consumer-facing blueprint — concepts, config fields, the CLI surface, and how to adapt the system to a repository — see the [workspace setup blueprint](../skills/alignfirst-setup-guide/references/workspace-setup.md). This document covers package internals and edge-case behavior that don't belong in that guide.
1414

1515
## Foreground self-exit
1616

packages/docmap/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# @paleo/docmap
22

3+
## 0.6.0
4+
5+
### Minor Changes
6+
7+
- 4396c78: Self-documenting CLI: add `--help`, `--guide`, and `--search`. Bare run lists recursively for small doc sets. No-lockfile fallback now suggests the package-runner form.
8+
39
## 0.5.1
410

511
### Patch Changes

0 commit comments

Comments
 (0)