@crouton-kit/crouter 0.1.6 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -13,7 +13,7 @@ import { registerPlanCommand } from './commands/plan.js';
13
13
  import { registerSpecCommand } from './commands/spec.js';
14
14
  import { registerAgentCommand } from './commands/agent.js';
15
15
  import { maybeAutoUpdate } from './core/auto-update.js';
16
- import { ensureBootSkill, ensureOfficialMarketplace } from './core/bootstrap.js';
16
+ import { ensureBootSkill, ensureOfficialMarketplace, ensureProjectScope } from './core/bootstrap.js';
17
17
  function readPackageVersion() {
18
18
  const here = dirname(fileURLToPath(import.meta.url));
19
19
  const pkgPath = join(here, '..', 'package.json');
@@ -38,6 +38,7 @@ registerSpecCommand(program);
38
38
  registerAgentCommand(program);
39
39
  ensureOfficialMarketplace(process.argv);
40
40
  ensureBootSkill(process.argv);
41
+ ensureProjectScope(process.argv);
41
42
  maybeAutoUpdate(process.argv);
42
43
  program.parseAsync().catch((err) => {
43
44
  process.stderr.write(`crtr: ${err instanceof Error ? err.message : String(err)}\n`);
@@ -9,7 +9,7 @@ import { resolveSkill, listAllSkills, listInstalledPlugins, findPluginByName, pa
9
9
  import { updateConfig, ensureScopeInitialized } from '../core/config.js';
10
10
  import { parseFrontmatter, serializeFrontmatter } from '../core/frontmatter.js';
11
11
  import { ensureDir, pathExists, readText, walkFiles } from '../core/fs-utils.js';
12
- import { skillPrompt, skillCreatePrompt } from '../prompts/skill.js';
12
+ import { skillPrompt, skillCreatePrompt, skillTemplatePrompt } from '../prompts/skill.js';
13
13
  const KNOWN_VERBS = new Set([
14
14
  'list',
15
15
  'show',
@@ -17,6 +17,7 @@ const KNOWN_VERBS = new Set([
17
17
  'grep',
18
18
  'new',
19
19
  'create',
20
+ 'template',
20
21
  'where',
21
22
  'enable',
22
23
  'disable',
@@ -286,14 +287,22 @@ export function registerSkillCommands(program) {
286
287
  handleError(e);
287
288
  }
288
289
  });
289
- // create — walkthrough for capturing knowledge as a skill
290
+ // create — pick a template type
290
291
  skill
291
292
  .command('create [topic...]')
292
- .description('walkthrough for capturing knowledge as a new skill')
293
+ .description('pick a template type for a new skill (primer | playbook | freeform)')
293
294
  .action(async (topic) => {
294
295
  const arg = topic && topic.length > 0 ? topic.join(' ') : '';
295
296
  out(skillCreatePrompt(arg));
296
297
  });
298
+ // template — full workflow + skeleton for one template type
299
+ skill
300
+ .command('template <type> [topic...]')
301
+ .description('full workflow + skeleton for a template type (primer | playbook | freeform)')
302
+ .action(async (type, topic) => {
303
+ const arg = topic && topic.length > 0 ? topic.join(' ') : '';
304
+ out(skillTemplatePrompt(type, arg));
305
+ });
297
306
  // where
298
307
  skill
299
308
  .command('where <name>')
@@ -3,3 +3,4 @@ export declare const OFFICIAL_MARKETPLACE_URL = "https://github.com/crouton-labs
3
3
  export declare const OFFICIAL_MARKETPLACE_REF = "main";
4
4
  export declare function ensureBootSkill(argv: string[]): void;
5
5
  export declare function ensureOfficialMarketplace(argv: string[]): void;
6
+ export declare function ensureProjectScope(argv: string[]): void;
@@ -1,11 +1,12 @@
1
1
  import { writeFileSync } from 'node:fs';
2
2
  import { homedir } from 'node:os';
3
3
  import { join } from 'node:path';
4
- import { userScopeRoot } from './scope.js';
4
+ import { findProjectScopeRoot, resetScopeCache, userScopeRoot } from './scope.js';
5
5
  import { ensureDir, pathExists, readText, removePath, nowIso } from './fs-utils.js';
6
6
  import { readConfig, readState, updateConfig, updateState, ensureScopeInitialized } from './config.js';
7
7
  import { clone } from './git.js';
8
8
  import { readMarketplaceManifest } from './manifest.js';
9
+ import { CRTR_DIR_NAME } from '../types.js';
9
10
  export const OFFICIAL_MARKETPLACE_NAME = 'crouter-official-marketplace';
10
11
  export const OFFICIAL_MARKETPLACE_URL = 'https://github.com/crouton-labs/crouter-official-marketplace.git';
11
12
  export const OFFICIAL_MARKETPLACE_REF = 'main';
@@ -23,48 +24,42 @@ function shouldSkipForArgv(argv) {
23
24
  return SKIP_SUBCOMMANDS.has(sub);
24
25
  }
25
26
  const BOOT_SKILL_NAME = 'crtr-skills';
26
- const BOOT_SKILL_MARKER = '<!-- crtr-boot-skill v1 -->';
27
+ const BOOT_SKILL_MARKER = '<!-- crtr-boot-skill v2 -->';
28
+ const BOOT_SKILL_MARKER_PREFIX = '<!-- crtr-boot-skill v';
27
29
  function bootSkillBody() {
28
30
  return `---
29
31
  name: crtr-skills
30
- description: Capture, list, search, and load skills via the crtr CLI. Use when the user wants to remember something, save knowledge, build a context primer, or recall a previously saved skill. Triggers: "save", "remember", "build context for", "what skills do we have", "skill for X".
32
+ description: Capture, list, search, and load skills via the crtr CLI. Skills are durable agent memory — markdown future LLM sessions load on demand. Use when the user wants to remember/save knowledge, build a context primer, or recall a previously saved skill. Triggers: "save", "remember", "build context for", "what skills do we have", "skill for X".
31
33
  argument-hint: [topic or verb]
32
34
  ---
33
35
 
34
36
  ${BOOT_SKILL_MARKER}
35
37
 
36
- # /crtr:skills — the skill router
38
+ # /crtr-skills — skill router
37
39
 
38
- \`crtr\` is the source of truth for skills on this machine. Every skill the
39
- agent should know about is discoverable via \`crtr skill\`. This file is a
40
- thin router; the CLI is the index.
40
+ Skills = durable agent memory. Written for **future LLM sessions**, not the
41
+ user. \`crtr skill\` is the index discoverable via list/search/grep.
41
42
 
42
- ## What the user is asking for
43
+ ## Route by intent
43
44
 
44
- - **Capture new knowledge** ("save this", "remember", "build context for X",
45
- "make a skill that…"): run \`crtr skill create $ARGUMENTS\` and follow the
46
- walkthrough it prints. It picks a template (primer/preference/runbook/
47
- glossary/decision/freeform) and walks you through scoping, researching,
48
- and scaffolding.
49
- - **Find a relevant skill** ("what do we have on X"): run
50
- \`crtr skill search "$ARGUMENTS"\` and load the best hit with
51
- \`crtr skill show <name>\`.
52
- - **Load a known skill by name**: run \`crtr skill show <name>\`.
53
- - **List everything**: run \`crtr skill list\`.
54
- - **Anything else skill-related**: run \`crtr skill\` (no args) — it prints
55
- the full skill workflow guide. Follow it.
45
+ - **Capture** ("save", "remember", "build context for", "make a skill"):
46
+ \`crtr skill create $ARGUMENTS\` pick template (primer/playbook/freeform)
47
+ \`crtr skill template <type> $ARGUMENTS\` for the full workflow. Follow it
48
+ directly.
49
+ - **Find** ("what do we have on X"): \`crtr skill search "$ARGUMENTS"\` →
50
+ \`crtr skill show <name>\` on the best hit.
51
+ - **Load by name**: \`crtr skill show <name>\`.
52
+ - **List all**: \`crtr skill list\`.
53
+ - **Anything else**: \`crtr skill\` (no args) prints the full workflow guide.
56
54
 
57
- \`$ARGUMENTS\` is the user's request as a string. Use it to seed the topic for
58
- \`create\` or the query for \`search\`. If it's empty, ask the user what they
59
- want before running anything.
55
+ If \`$ARGUMENTS\` is empty, ask the user what they want before running.
60
56
 
61
- ## Output rules
57
+ ## Rules
62
58
 
63
- The CLI's stdout is the prompt. Read it, then act on it. Don't paraphrase the
64
- guidance back at the user just do the work it describes.
65
-
66
- If \`crtr\` isn't on PATH, tell the user and stop. This skill assumes
67
- \`@crouton-kit/crouter\` is installed globally.
59
+ - CLI stdout is the prompt act on it, don't paraphrase to the user.
60
+ - Don't load \`create\` and \`template\` outputs in the same turn (progressive
61
+ disclosure). \`create\` decides type; \`template\` returns the workflow.
62
+ - If \`crtr\` is not on PATH, tell the user and stop.
68
63
  `;
69
64
  }
70
65
  export function ensureBootSkill(argv) {
@@ -81,11 +76,11 @@ export function ensureBootSkill(argv) {
81
76
  const skillDir = join(claudeSkillsRoot, BOOT_SKILL_NAME);
82
77
  const skillFile = join(skillDir, 'SKILL.md');
83
78
  if (pathExists(skillFile)) {
84
- // Idempotent: only rewrite if it's still our marker version.
85
79
  const existing = readText(skillFile);
86
- if (!existing.includes(BOOT_SKILL_MARKER))
80
+ // If the user customized (no boot-skill marker at all), don't clobber.
81
+ if (!existing.includes(BOOT_SKILL_MARKER_PREFIX))
87
82
  return;
88
- // Same marker check if body needs update, otherwise skip.
83
+ // Any marker version present roll forward to current. Skip if identical.
89
84
  if (existing === bootSkillBody())
90
85
  return;
91
86
  }
@@ -147,3 +142,29 @@ export function ensureOfficialMarketplace(argv) {
147
142
  }
148
143
  }
149
144
  }
145
+ export function ensureProjectScope(argv) {
146
+ try {
147
+ if (process.env.CRTR_NO_AUTO_INIT === '1')
148
+ return;
149
+ if (shouldSkipForArgv(argv))
150
+ return;
151
+ // Already inside a project scope (here or in an ancestor) — nothing to do.
152
+ if (findProjectScopeRoot() !== null)
153
+ return;
154
+ const cwd = process.cwd();
155
+ // Never auto-init at $HOME — that path is reserved for the user scope.
156
+ if (cwd === homedir())
157
+ return;
158
+ const projectRoot = join(cwd, CRTR_DIR_NAME);
159
+ if (projectRoot === userScopeRoot())
160
+ return;
161
+ ensureScopeInitialized('project', projectRoot);
162
+ resetScopeCache();
163
+ }
164
+ catch (e) {
165
+ if (process.env.CRTR_DEBUG === '1') {
166
+ const msg = e instanceof Error ? e.message : String(e);
167
+ process.stderr.write(`crtr: project-init error: ${msg}\n`);
168
+ }
169
+ }
170
+ }
@@ -1,2 +1,3 @@
1
1
  export declare function skillPrompt(): string;
2
2
  export declare function skillCreatePrompt(topic: string): string;
3
+ export declare function skillTemplatePrompt(type: string, topic: string): string;
@@ -1,176 +1,175 @@
1
1
  export function skillPrompt() {
2
- return `# Skills — capture and recall knowledge
2
+ return `# Skills — durable agent memory
3
3
 
4
- \`crtr\` skills are markdown documents the agent loads on demand. Use them for
5
- anything you want recalled later: architectural primers, runbooks, your
6
- personal preferences, domain glossaries, decision records methodology *or*
7
- captured knowledge. The CLI is the index; \`crtr skill list/search/grep\`
8
- discovers what's available so you never need a hand-maintained router file.
4
+ Skills are markdown the agent loads on demand. **Audience: future LLM agent
5
+ sessions, not humans.** Write for the model: terse, decision-first, dense.
6
+ The CLI is the index\`crtr skill list/search/grep\` discovers what's saved.
9
7
 
10
- Skills live in three places, in resolution order:
11
- 1. **Scope-direct** \`<scope-root>/skills/<name>/SKILL.md\` (no plugin wrapper, shown as \`user:<name>\` or \`project:<name>\`)
12
- 2. **Plugin skills** \`<plugin>/skills/<name>/SKILL.md\` (shown as \`<scope>:<plugin>/<name>\`)
13
- 3. Project scope beats user scope; non-marketplace plugins beat marketplace ones.
8
+ Locations (resolution order):
9
+ 1. **Scope-direct** \`<scope-root>/skills/<name>/SKILL.md\` \`user:<name>\` / \`project:<name>\`
10
+ 2. **Plugin skills** \`<plugin>/skills/<name>/SKILL.md\` \`<scope>:<plugin>/<name>\`
11
+ 3. Project > user; non-marketplace plugins > marketplace.
14
12
 
15
- Ambiguous names exit \`4\` — disambiguate with \`<plugin>:<name>\` or \`_:<name>\`
16
- for scope-direct.
13
+ Ambiguous names exit \`4\` — disambiguate with \`<plugin>:<name>\` or \`_:<name>\`.
17
14
 
18
15
  ## Discover
19
16
 
20
17
  \`\`\`
21
- crtr skill list # one per line: <qualifier> — <description>
22
- crtr skill search <query> # rank by name, description, keywords
23
- crtr skill grep <pattern> # regex search across SKILL.md bodies
18
+ crtr skill list # <qualifier> — <description>
19
+ crtr skill search <query> # ranked by name/description/keywords
20
+ crtr skill grep <pattern> # regex across SKILL.md bodies
24
21
  \`\`\`
25
22
 
26
23
  ## Load
27
24
 
28
25
  \`\`\`
29
- crtr skill show <name> # print SKILL.md body to stdout
30
- crtr skill show <plugin>:<name> # disambiguate when names collide
26
+ crtr skill show <name> # body to stdout (default verb)
31
27
  crtr skill show _:<name> # explicit scope-direct
32
- crtr skill path <name> # absolute path to SKILL.md
33
- crtr skill where <name> # {scope, plugin, path} as JSON
28
+ crtr skill path <name> # absolute path
29
+ crtr skill where <name> # {scope, plugin, path} JSON
34
30
  \`\`\`
35
31
 
36
- \`show\` is the default verb: \`crtr skill <name>\` (with no verb) also prints
37
- the body.
38
-
39
- ## Author
32
+ ## Author (progressive disclosure)
40
33
 
41
34
  \`\`\`
42
- crtr skill create [topic...] # walkthrough — pick a template, capture knowledge
43
- crtr skill new <name> # bare scaffold, scope-direct (asks for --scope)
44
- crtr skill new <plugin>:<name> # bare scaffold inside an existing plugin
45
- crtr skill show authoring-skills # the SKILL.md authoring guide
35
+ crtr skill create [topic...] # pick a template type
36
+ crtr skill template <type> [topic] # workflow + skeleton for that type
37
+ crtr skill new <name> # bare scaffold, scope-direct
46
38
  \`\`\`
47
39
 
48
- Reach for \`create\` when capturing something new it walks you through choosing
49
- a template (architectural primer, preference, runbook, glossary, decision,
50
- freeform) and applies the right research workflow for that template.
40
+ Don't load \`create\` and \`template\` in the same turn \`create\` decides the
41
+ type, then call \`template\`.
51
42
 
52
43
  ## Toggle
53
44
 
54
45
  \`\`\`
55
- crtr skill enable <name> # clear any disable in the chosen scope
56
- crtr skill disable <name> # hide from list and agent discovery
46
+ crtr skill enable <name>
47
+ crtr skill disable <name>
57
48
  \`\`\`
58
49
 
59
50
  ## Exit codes
60
51
 
61
- - \`0\` success
62
- - \`3\` — skill not found
63
- - \`4\` — ambiguous name; use \`<plugin>:<name>\`
52
+ \`0\` success · \`3\` not found · \`4\` ambiguous (qualify name)
64
53
  `;
65
54
  }
66
55
  export function skillCreatePrompt(topic) {
67
56
  const topicLine = topic
68
- ? `User-provided topic: **${topic}**`
69
- : `No topic was provided — ask the user what they want to capture before continuing.`;
70
- return `# Capture knowledge as a skill
57
+ ? `Topic: **${topic}**`
58
+ : `No topic provided — ask the user what to capture before proceeding.`;
59
+ return `# Author a skill step 1: pick template type
71
60
 
72
- You are about to author a new \`crtr\` skill a SKILL.md the agent will recall
73
- on demand. Skills can capture *any* kind of durable knowledge: architectural
74
- primers, runbooks, personal preferences, domain glossaries, decision records,
75
- freeform notes. Don't conflate this with "methodology only" — if the user wants
76
- the agent to remember something later, a skill is the right shape.
61
+ You are about to write a skill (markdown read by future LLM agent sessions,
62
+ not humans). Pick the template, then load its workflow.
77
63
 
78
64
  ${topicLine}
79
65
 
80
- ## Step 1 — Decide the template
66
+ ## Templates
81
67
 
82
- Ask the user (use \`AskUserQuestion\` if available) which template fits, with
83
- your best guess pre-selected. Don't write anything until this is settled.
68
+ - \`primer\` codebase/architectural knowledge ("how does X work, why, what
69
+ are the gotchas"). Triggers parallel-explore research.
70
+ - \`playbook\` — methodology/judgment ("how to think about X"). The
71
+ \`authoring:skills\`-style skill that teaches decisions, not facts.
72
+ - \`freeform\` — anything else (glossary, decision record, runbook, prefs).
84
73
 
85
- | Template | When to use | Research workflow |
86
- |----------|-------------|-------------------|
87
- | \`primer\` | Architectural/codebase knowledge — "how does X work, why does it exist" | Parallel-explore (Step 3a) |
88
- | \`preference\` | User preferences, style guides, "remember I like X" | None — just ask 2-3 sharpening questions |
89
- | \`runbook\` | Operational procedure, incident response, "here's how to do X" | Light — confirm steps with the user |
90
- | \`glossary\` | Domain terms and invariants | None — list terms, get definitions from user |
91
- | \`decision\` | ADR-style record: context / decision / consequences | Confirm context and tradeoffs with user |
92
- | \`freeform\` | Anything else | Ask what shape they want |
74
+ ## Next
93
75
 
94
- If the user is asking for a codebase primer, **also** consider whether the
95
- subsystem is large enough to justify it. Small/self-evident systems do not
96
- need a primer — push back and offer to write a one-paragraph note instead.
76
+ 1. Pick a type. If unclear, use \`AskUserQuestion\` with your best guess first.
77
+ 2. Run:
97
78
 
98
- ## Step 2 — Decide the scope and name
79
+ \`\`\`
80
+ crtr skill template <type>${topic ? ` ${topic}` : ' [topic]'}
81
+ \`\`\`
99
82
 
100
- Ask the user:
101
- - **Scope** \`user\` (lives in \`~/.crouter/skills/\`, available everywhere) or
102
- \`project\` (lives in \`<project>/.crouter/skills/\`, only here). Default
103
- \`project\` if cwd is inside a project scope; otherwise \`user\`.
104
- - **Name** — kebab-case slug. Suggest one from the topic.
83
+ That output contains the research methodology, SKILL.md skeleton, and
84
+ scaffold command. Follow it directly don't paraphrase.
105
85
 
106
- Check for collisions: \`crtr skill where <name>\`. If it exists, ask whether to
107
- update the existing one or pick a different name.
86
+ ## Push back when
108
87
 
109
- ## Step 3 Research (template-specific)
88
+ - Subsystem is small/self-evident suggest CLAUDE.md note instead of primer.
89
+ - "Topic" is really a one-off task → don't capture; just do the work.
90
+ `;
91
+ }
92
+ export function skillTemplatePrompt(type, topic) {
93
+ const t = type.toLowerCase();
94
+ if (t === 'primer')
95
+ return primerTemplatePrompt(topic);
96
+ if (t === 'playbook')
97
+ return playbookTemplatePrompt(topic);
98
+ if (t === 'freeform')
99
+ return freeformTemplatePrompt(topic);
100
+ return `unknown template type: ${type}\nvalid: primer | playbook | freeform\nrun \`crtr skill create\` to pick.\n`;
101
+ }
102
+ function topicLine(topic) {
103
+ return topic
104
+ ? `Topic: **${topic}**`
105
+ : `No topic — confirm with the user before continuing.`;
106
+ }
107
+ function primerTemplatePrompt(topic) {
108
+ return `# Primer — codebase knowledge skill
110
109
 
111
- ### 3a. \`primer\` parallel codebase exploration
110
+ **Audience: future LLM agent sessions.** Captures *why* a subsystem exists +
111
+ non-obvious facts that code alone doesn't reveal. Lets a future session skip
112
+ re-exploration.
112
113
 
113
- Dispatch 4–8 \`Explore\` subagents in parallel. Partition by **slice, not by
114
- directory**:
114
+ ${topicLine(topic)}
115
115
 
116
- - **Entry points** — HTTP routes, CLI commands, cron, event handlers, public exports
117
- - **Data model** — schemas, types, DB tables, key invariants
118
- - **Control flow** — how a typical request/job traverses the system end-to-end
119
- - **External integrations** — third-party APIs, queues, services, env vars
120
- - **Tests** — what's tested reveals what's load-bearing
121
- - **History** — recent \`git log\` for this area surfaces ongoing work and pain
122
- - **Cross-cutting** — auth, errors, logging, feature flags as they apply here
116
+ ## 1. Inventory (parallel)
123
117
 
124
- Each subagent must return **concrete \`file:line\` references**, *non-obvious*
125
- facts (skip what's obvious from filenames), naming conventions, and gotchas.
126
- Reject vague summaries.
118
+ - \`ls\` repo top level
119
+ - check stack manifests
120
+ - \`git log --oneline -15\` in this area
121
+ - \`crtr skill search <topic>\` / \`crtr skill list\` — does a primer already exist?
127
122
 
128
- ### 3b. \`preference\` / \`glossary\` / \`decision\` interview
123
+ If subsystem is small/self-evident, **stop**. Suggest a CLAUDE.md note. Primers
124
+ are for large, complicated, or unintuitive systems only.
129
125
 
130
- Use \`AskUserQuestion\` to batch sharpening questions (≤4 at a time, multiple
131
- choice with your best guess first). Frame each as "here's my read; is this
132
- right?" Never write assumptions into the skill — if a fact isn't confirmed by
133
- code or the user, it doesn't go in.
126
+ ## 2. Scope + name
134
127
 
135
- ### 3c. \`runbook\` walk it
128
+ - **Scope**: \`project\` by default. \`user\` only if cross-repo.
129
+ - **Name**: kebab-case. Confirm no collision: \`crtr skill where <name>\`.
136
130
 
137
- If the procedure exists, run/grep it and confirm. Otherwise, have the user
138
- narrate it once and read back the steps.
131
+ ## 3. Parallel exploration
139
132
 
140
- ## Step 4 Verify intent
133
+ Dispatch **4–8 \`Explore\` subagents in parallel**, partitioned by *slice* (not
134
+ directory):
141
135
 
142
- Before writing, summarize your working hypothesis back to the user in 2-3
143
- sentences: **what this skill is about and when it should be loaded.** This is
144
- what code and grep can't tell you. Get a yes or correction.
136
+ - Entry points (routes, CLI, events, public exports)
137
+ - Data model (schemas, types, invariants)
138
+ - Control flow (typical request/job end-to-end)
139
+ - External integrations (APIs, queues, env vars)
140
+ - Tests (what's tested = what's load-bearing)
141
+ - History (recent git log surfaces pain points)
142
+ - Cross-cutting (auth, errors, logging, flags as they apply)
145
143
 
146
- ## Step 5 Scaffold and write
144
+ Each subagent returns: concrete \`file:line\` refs, *non-obvious* facts (skip
145
+ filename-obvious), naming conventions, gotchas. Reject vague summaries.
147
146
 
148
- Run:
147
+ ## 4. Verify with user
149
148
 
150
- \`\`\`
151
- crtr skill new <name> --scope <user|project> --description "<one-line trigger>"
152
- \`\`\`
149
+ Code = *what*. User = *why*. Use \`AskUserQuestion\` (≤4 questions,
150
+ multi-choice, best-guess first):
153
151
 
154
- (For a plugin-scoped skill instead, use \`crtr skill new <plugin>:<name>\`.)
152
+ - Business purpose / who depends on it
153
+ - Surprising-looking architectural decisions
154
+ - Ownership / deprecation status / expected scale
155
+ - Canonical flow when multiple exist
155
156
 
156
- This creates \`SKILL.md\` with frontmatter only. Open it and fill the body
157
- using the template skeleton below for the kind you chose. **Density rules:**
158
- \`file:line\` over prose; tables where structure fits; skip anything
159
- self-evident from a 30-second skim of the code; no "this section covers…"
160
- meta-commentary.
157
+ Skip if greppable or won't change the primer. **Never write unconfirmed
158
+ assumptions.**
161
159
 
162
- The \`description:\` field drives auto-discovery — front-load the trigger
163
- keywords the user (or agent) would naturally say. Aim for ≤250 chars.
160
+ ## 5. Scaffold
164
161
 
165
- ### Skeletons
162
+ \`\`\`
163
+ crtr skill new <name> --scope project --description "<what+when, ≤250 chars, front-loaded triggers>"
164
+ \`\`\`
166
165
 
167
- **\`primer\`**
166
+ ## 6. Write the body
168
167
 
169
168
  \`\`\`markdown
170
169
  # <topic>
171
170
 
172
171
  ## Purpose
173
- Why this exists. The business problem it solves. Who depends on it.
172
+ Why this exists. Problem solved. Who depends on it.
174
173
  (1–3 tight paragraphs — what code can't tell you.)
175
174
 
176
175
  ## Architecture
@@ -185,97 +184,252 @@ Components, responsibilities, data/control flow, boundaries.
185
184
  Domain terms, invariants, non-obvious constraints.
186
185
 
187
186
  ## Entry points
188
- Where work enters the system, with \`file:line\`.
187
+ \`file:line\` where work enters.
189
188
 
190
189
  ## Gotchas
191
- Non-obvious coupling. Things that look broken but aren't. Past footguns.
190
+ Non-obvious coupling. Looks-broken-but-isn't. Past footguns.
192
191
 
193
192
  ## Related
194
- - \`<other-skill>\` — how they interact
193
+ - \`<other-skill>\` — interaction
195
194
  \`\`\`
196
195
 
197
- **\`preference\`**
196
+ **Density rules:**
197
+ - \`file:line\` over prose
198
+ - Tables where structure fits
199
+ - Skip 30-second-skim-obvious
200
+ - No "this section covers…" meta
201
+ - Budget ~150 lines; deeper reference → sibling files
198
202
 
199
- \`\`\`markdown
200
- # <topic preferences>
203
+ ## 7. Verify
201
204
 
202
- ## Rule
203
- What the user wants.
205
+ \`\`\`
206
+ crtr skill where <name>
207
+ crtr skill show <name>
208
+ crtr skill search <keyword> # confirm description triggers discovery
209
+ \`\`\`
204
210
 
205
- ## Why
206
- Reason given — past incident, strong preference, constraint.
211
+ Sharpen description if discovery misses. Cut body if bloated.
207
212
 
208
- ## How to apply
209
- When/where this guidance kicks in.
213
+ ## Updates
214
+
215
+ If updating existing primer: diff draft vs current, call out changes + why
216
+ before writing. Update related skills' \`## Related\` sections.
217
+ `;
218
+ }
219
+ function playbookTemplatePrompt(topic) {
220
+ return `# Playbook — methodology skill
221
+
222
+ **Audience: future LLM agent sessions.** Teaches *judgment*, not facts —
223
+ decision frameworks, heuristics, when-to-use / when-not-to-use. Examples:
224
+ skill-authoring, debugging methodology, multi-agent orchestration.
225
+
226
+ ${topicLine(topic)}
227
+
228
+ ## Litmus test
229
+
230
+ > Does this teach judgment, or describe an API?
231
+
232
+ If you'd write *"when X, do Y because Z"* → playbook. If you'd write tables
233
+ of fields/flags/events → reference material (put in sibling \`reference.md\`,
234
+ not SKILL.md). If neither fits → use \`crtr skill template freeform\` instead.
235
+
236
+ **Playbook markers:** teaches a framework · has "when (not) to use" · prose
237
+ over tables · reader makes better decisions after 30 seconds.
238
+
239
+ ## 1. Interview
240
+
241
+ A playbook = user's accumulated judgment. Not greppable. Use
242
+ \`AskUserQuestion\` (≤4, multi-choice, best-guess first):
243
+
244
+ - The decision this skill teaches
245
+ - 2–4 most common failure modes without it
246
+ - Triggers (words/situations that should load it)
247
+ - Non-obvious rules that surprise newcomers
248
+
249
+ Push back on vagueness. *"Be thoughtful"* ≠ heuristic. *"Prefer one bundled
250
+ PR over many small ones for refactors here, because review churn dominates"*
251
+ = heuristic.
252
+
253
+ ## 2. Scope + name
254
+
255
+ - **Scope**: \`user\` for cross-project methodology. \`project\` for repo-specific.
256
+ - **Name**: kebab-case, verb-or-noun-phrase. Not "guide-to-X".
257
+ - Check \`crtr skill where <name>\`.
258
+
259
+ ## 3. Scaffold
260
+
261
+ \`\`\`
262
+ crtr skill new <name> --scope <user|project> --description "<what it teaches + when to load, ≤250 chars, front-loaded triggers>"
210
263
  \`\`\`
211
264
 
212
- **\`runbook\`**
265
+ ## 4. Density rules
266
+
267
+ LLM reasoning degrades past ~3k tokens. **Budget ~150 lines for SKILL.md.**
268
+
269
+ - Decision-first. *"When you need X"* before *"how X works"*.
270
+ - One well-placed "don't" > three paragraphs of explanation.
271
+ - Reasoning chains > example outputs. Show *how to think*, not *what to produce*.
272
+ - Section >20 lines without teaching judgment → move to \`reference.md\`.
273
+
274
+ **Test:** can someone reading 30 seconds make a better decision? If they need
275
+ to read the whole thing for value, you've buried the judgment.
276
+
277
+ ## 5. Body skeleton
213
278
 
214
279
  \`\`\`markdown
215
- # <procedure>
280
+ # <skill name>
216
281
 
217
- ## When to run this
218
- Triggering condition.
282
+ <1-paragraph: what + when to load>
219
283
 
220
- ## Steps
221
- 1.
222
- 2. …
284
+ ## When to use
285
+ - <trigger>
223
286
 
224
- ## Verification
225
- How to confirm success.
287
+ ## When NOT to use
288
+ - <anti-trigger>
226
289
 
227
- ## Rollback
228
- How to undo if something goes wrong.
290
+ ## The core decision
291
+ <central judgment usually a heuristic or framework>
292
+
293
+ ## <heuristic 1>
294
+ <2–6 lines, brief (anti-)example>
295
+
296
+ ## <heuristic 2>
297
+
298
+
299
+ ## Failure modes
300
+ - **<name>**: what it looks like; how to avoid
301
+
302
+ ## Related
303
+ - \`<other-skill>\` — interaction
304
+ \`\`\`
305
+
306
+ ## 6. Progressive disclosure
307
+
308
+ If deep reference is needed:
309
+
310
+ \`\`\`
311
+ <skill-dir>/
312
+ SKILL.md # judgment layer — <150 lines
313
+ reference.md # lookup layer
314
+ examples.md # optional worked examples
229
315
  \`\`\`
230
316
 
231
- **\`glossary\`**
317
+ SKILL.md *links* to siblings (\`see [reference.md](reference.md)\`). Agent
318
+ loads supporting files only when needed.
232
319
 
320
+ ## 7. Verify
321
+
322
+ \`\`\`
323
+ crtr skill where <name>
324
+ crtr skill show <name>
325
+ crtr skill search <keyword>
326
+ \`\`\`
327
+
328
+ ## Deep-dive reference
329
+
330
+ For canonical SKILL.md authoring (frontmatter fields, argument passing,
331
+ dynamic context, subagent forking, hooks):
332
+
333
+ \`\`\`
334
+ crtr skill show authoring-skills
335
+ \`\`\`
336
+
337
+ The playbook above gives you structure + density rules. \`authoring-skills\`
338
+ covers the SKILL.md surface itself.
339
+
340
+ ## Constraints
341
+
342
+ - Topic fails litmus? → \`crtr skill template freeform\` or \`primer\`.
343
+ - No unconfirmed heuristics — if not from user experience or clear principle,
344
+ leave it out.
345
+ - Update related skills' \`## Related\` if interactions exist.
346
+ `;
347
+ }
348
+ function freeformTemplatePrompt(topic) {
349
+ return `# Freeform — escape hatch skill
350
+
351
+ **Audience: future LLM agent sessions.** Use when content doesn't fit
352
+ \`primer\` (codebase knowledge) or \`playbook\` (methodology) — glossaries,
353
+ decisions, runbooks, lists, preferences.
354
+
355
+ ${topicLine(topic)}
356
+
357
+ ## 1. Pick a shape
358
+
359
+ What kind of thing is this?
360
+
361
+ - Terms + definitions → glossary-shaped
362
+ - "We decided X, here's why" → decision-shaped
363
+ - Procedure with steps + rollback → runbook-shaped
364
+ - User preferences → preference-shaped
365
+ - None of the above → freeform
366
+
367
+ No strict template; the shape just tells you what to ask for.
368
+
369
+ ## 2. Interview
370
+
371
+ \`AskUserQuestion\` (≤4, multi-choice, best-guess first). Get only what you
372
+ need to write the skill. **No unconfirmed assumptions** — if not from user
373
+ or grep, omit it.
374
+
375
+ ## 3. Scope + name + scaffold
376
+
377
+ \`\`\`
378
+ crtr skill new <name> --scope <user|project> --description "<what+when, ≤250 chars, front-loaded triggers>"
379
+ \`\`\`
380
+
381
+ ## 4. Body — pick the closest skeleton
382
+
383
+ **Glossary:**
233
384
  \`\`\`markdown
234
385
  # <domain> glossary
235
-
236
386
  | Term | Definition | Notes |
237
387
  |------|------------|-------|
238
- | … | … | … |
239
388
  \`\`\`
240
389
 
241
- **\`decision\`**
242
-
390
+ **Decision:**
243
391
  \`\`\`markdown
244
- # <decision title> — <date>
245
-
392
+ # <decision> — <date>
246
393
  ## Context
247
- What forced the decision.
248
-
249
394
  ## Decision
250
- What we chose.
251
-
252
395
  ## Consequences
253
- What this costs us. What it buys us.
254
-
255
396
  ## Alternatives considered
256
- - …
257
397
  \`\`\`
258
398
 
259
- ## Step 6 — Verify the skill is discoverable
399
+ **Runbook:**
400
+ \`\`\`markdown
401
+ # <procedure>
402
+ ## When to run
403
+ ## Steps
404
+ ## Verification
405
+ ## Rollback
406
+ \`\`\`
407
+
408
+ **Preference:**
409
+ \`\`\`markdown
410
+ # <preference>
411
+ ## Rule
412
+ ## Why
413
+ ## How to apply
414
+ \`\`\`
415
+
416
+ Or invent your own. Stay tight — no padding.
417
+
418
+ ## 5. Verify
260
419
 
261
420
  \`\`\`
262
- crtr skill where <name> # confirm path/scope
263
- crtr skill list # confirm it shows up
264
- crtr skill show <name> # confirm the body reads well
421
+ crtr skill where <name>
422
+ crtr skill show <name>
423
+ crtr skill search <keyword>
265
424
  \`\`\`
266
425
 
267
- If \`description:\` doesn't trigger the right discoveries, sharpen it. If the
268
- body is bloated, cut it. Budget ~150 lines for SKILL.md; move deep reference
269
- into sibling files in the same directory.
426
+ ## Switch templates if needed
270
427
 
271
- ## Constraints
428
+ If the content is actually methodology or codebase knowledge:
272
429
 
273
- - Push back on trivial captures — if a one-line note in CLAUDE.md or a code
274
- comment would do, suggest that instead.
275
- - Never write unconfirmed assumptions into the skill.
276
- - For updates to an existing skill, diff your draft against the current file
277
- and call out what changed and why before writing.
278
- - Update related skills' \`## Related\` sections if you're adding something
279
- that interacts with them.
430
+ \`\`\`
431
+ crtr skill template playbook ${topic ? topic : '<topic>'}
432
+ crtr skill template primer ${topic ? topic : '<topic>'}
433
+ \`\`\`
280
434
  `;
281
435
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crouton-kit/crouter",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "crtr — fast access to skills, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",