@imix-js/taproot 0.2.0

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.
Files changed (124) hide show
  1. package/README.md +88 -0
  2. package/dist/adapters/index.d.ts +20 -0
  3. package/dist/adapters/index.js +452 -0
  4. package/dist/adapters/index.js.map +1 -0
  5. package/dist/cli.d.ts +2 -0
  6. package/dist/cli.js +40 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/commands/acceptance-check.d.ts +26 -0
  9. package/dist/commands/acceptance-check.js +213 -0
  10. package/dist/commands/acceptance-check.js.map +1 -0
  11. package/dist/commands/check-orphans.d.ts +8 -0
  12. package/dist/commands/check-orphans.js +157 -0
  13. package/dist/commands/check-orphans.js.map +1 -0
  14. package/dist/commands/commithook.d.ts +15 -0
  15. package/dist/commands/commithook.js +389 -0
  16. package/dist/commands/commithook.js.map +1 -0
  17. package/dist/commands/coverage.d.ts +41 -0
  18. package/dist/commands/coverage.js +390 -0
  19. package/dist/commands/coverage.js.map +1 -0
  20. package/dist/commands/dod.d.ts +13 -0
  21. package/dist/commands/dod.js +141 -0
  22. package/dist/commands/dod.js.map +1 -0
  23. package/dist/commands/init.d.ts +14 -0
  24. package/dist/commands/init.js +378 -0
  25. package/dist/commands/init.js.map +1 -0
  26. package/dist/commands/link-commits.d.ts +12 -0
  27. package/dist/commands/link-commits.js +126 -0
  28. package/dist/commands/link-commits.js.map +1 -0
  29. package/dist/commands/overview.d.ts +6 -0
  30. package/dist/commands/overview.js +192 -0
  31. package/dist/commands/overview.js.map +1 -0
  32. package/dist/commands/plan.d.ts +23 -0
  33. package/dist/commands/plan.js +167 -0
  34. package/dist/commands/plan.js.map +1 -0
  35. package/dist/commands/sync-check.d.ts +8 -0
  36. package/dist/commands/sync-check.js +118 -0
  37. package/dist/commands/sync-check.js.map +1 -0
  38. package/dist/commands/update.d.ts +7 -0
  39. package/dist/commands/update.js +309 -0
  40. package/dist/commands/update.js.map +1 -0
  41. package/dist/commands/validate-format.d.ts +8 -0
  42. package/dist/commands/validate-format.js +93 -0
  43. package/dist/commands/validate-format.js.map +1 -0
  44. package/dist/commands/validate-structure.d.ts +8 -0
  45. package/dist/commands/validate-structure.js +29 -0
  46. package/dist/commands/validate-structure.js.map +1 -0
  47. package/dist/core/config.d.ts +6 -0
  48. package/dist/core/config.js +86 -0
  49. package/dist/core/config.js.map +1 -0
  50. package/dist/core/configuration.d.ts +7 -0
  51. package/dist/core/configuration.js +112 -0
  52. package/dist/core/configuration.js.map +1 -0
  53. package/dist/core/dod-runner.d.ts +20 -0
  54. package/dist/core/dod-runner.js +233 -0
  55. package/dist/core/dod-runner.js.map +1 -0
  56. package/dist/core/dor-runner.d.ts +18 -0
  57. package/dist/core/dor-runner.js +156 -0
  58. package/dist/core/dor-runner.js.map +1 -0
  59. package/dist/core/fs-walker.d.ts +5 -0
  60. package/dist/core/fs-walker.js +74 -0
  61. package/dist/core/fs-walker.js.map +1 -0
  62. package/dist/core/git.d.ts +24 -0
  63. package/dist/core/git.js +76 -0
  64. package/dist/core/git.js.map +1 -0
  65. package/dist/core/impl-reader.d.ts +8 -0
  66. package/dist/core/impl-reader.js +39 -0
  67. package/dist/core/impl-reader.js.map +1 -0
  68. package/dist/core/language.d.ts +39 -0
  69. package/dist/core/language.js +159 -0
  70. package/dist/core/language.js.map +1 -0
  71. package/dist/core/markdown-parser.d.ts +3 -0
  72. package/dist/core/markdown-parser.js +37 -0
  73. package/dist/core/markdown-parser.js.map +1 -0
  74. package/dist/core/reporter.d.ts +3 -0
  75. package/dist/core/reporter.js +33 -0
  76. package/dist/core/reporter.js.map +1 -0
  77. package/dist/templates/index.d.ts +4 -0
  78. package/dist/templates/index.js +126 -0
  79. package/dist/templates/index.js.map +1 -0
  80. package/dist/validators/format-rules.d.ts +10 -0
  81. package/dist/validators/format-rules.js +238 -0
  82. package/dist/validators/format-rules.js.map +1 -0
  83. package/dist/validators/structure-rules.d.ts +10 -0
  84. package/dist/validators/structure-rules.js +94 -0
  85. package/dist/validators/structure-rules.js.map +1 -0
  86. package/dist/validators/types.d.ts +68 -0
  87. package/dist/validators/types.js +2 -0
  88. package/dist/validators/types.js.map +1 -0
  89. package/docs/agents.md +88 -0
  90. package/docs/architecture.md +53 -0
  91. package/docs/cli.md +226 -0
  92. package/docs/concepts.md +268 -0
  93. package/docs/configuration.md +255 -0
  94. package/docs/demo.svg +111 -0
  95. package/docs/patterns.md +118 -0
  96. package/docs/security.md +95 -0
  97. package/docs/workflows.md +151 -0
  98. package/languages/de.json +20 -0
  99. package/languages/en.json +20 -0
  100. package/languages/es.json +20 -0
  101. package/languages/fr.json +20 -0
  102. package/languages/ja.json +20 -0
  103. package/languages/pt.json +20 -0
  104. package/package.json +54 -0
  105. package/skills/analyse-change.md +101 -0
  106. package/skills/behaviour.md +179 -0
  107. package/skills/bug.md +70 -0
  108. package/skills/commit.md +99 -0
  109. package/skills/decompose.md +101 -0
  110. package/skills/discover.md +392 -0
  111. package/skills/grill-me.md +65 -0
  112. package/skills/guide.md +118 -0
  113. package/skills/implement.md +149 -0
  114. package/skills/ineed.md +147 -0
  115. package/skills/intent.md +104 -0
  116. package/skills/plan.md +63 -0
  117. package/skills/promote.md +69 -0
  118. package/skills/refine.md +78 -0
  119. package/skills/research.md +122 -0
  120. package/skills/review-all.md +92 -0
  121. package/skills/review.md +80 -0
  122. package/skills/status.md +103 -0
  123. package/skills/sweep.md +89 -0
  124. package/skills/trace.md +151 -0
package/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # Taproot
2
+
3
+ <p align="center">
4
+ <img src="docs/demo.svg" alt="Taproot demo — npx taproot init, /tr-ineed, taproot dod" width="700"/>
5
+ </p>
6
+
7
+ **Your AI coding agent finally knows why.**
8
+
9
+ AI coding agents generate code fast — but six months later, nobody knows *why* a module exists, who asked for it, or whether it's still needed. The requirement lived in a chat window. The chat window is gone.
10
+
11
+ Taproot keeps requirements as first-class files in your repo — git-versioned, agent-readable, and validated on every commit.
12
+
13
+ ## Quick Start
14
+
15
+ ```bash
16
+ npm install -g @imix-js/taproot
17
+ taproot init
18
+ ```
19
+
20
+ Taproot will ask which agent adapter to install and whether to set up the pre-commit hook. Then open your agent and run:
21
+
22
+ ```
23
+ /tr-guide
24
+ ```
25
+
26
+ That's it. The guide walks you through the rest.
27
+
28
+ ## The workflow
29
+
30
+ Once taproot is set up, your AI agent has the full workflow available as slash commands:
31
+
32
+ ```
33
+ /tr-ineed user authentication ← route any requirement into the hierarchy
34
+ (discovery, spec writing, placement)
35
+
36
+ /tr-implement taproot/auth/login/ ← implement a behaviour: code + tests +
37
+ traceability record, committed atomically
38
+
39
+ /tr-status ← health dashboard: coverage, orphans,
40
+ stale specs, parked items
41
+
42
+ /tr-discover ← reverse-engineer an existing codebase
43
+ into a taproot hierarchy
44
+ ```
45
+
46
+ The full list is in [docs/workflows.md](docs/workflows.md).
47
+
48
+ ## Why it matters
49
+
50
+ - **Ask "why does this code exist?"** and get a structured answer — intent, actor, acceptance criteria — not a two-year-old git blame
51
+ - **AI agents generate better code** because they have the business goal alongside the technical context
52
+ - **Requirements always show current state** — when a spec changes, it's refined in place. No amendment chains, no "change request #4 layered on top of #3 layered on top of #2". The document is always the truth as it stands today.
53
+ - **Changes are safer** — trace any file back to its behaviour spec and understand what breaks if you touch it
54
+ - **Nothing drifts silently** — `taproot sync-check` flags source files modified after their spec was last reviewed
55
+ - **Vague specs are caught at commit time** — DoD/DoR gates block incomplete implementations before they merge
56
+
57
+ **How requirements are stored:**
58
+
59
+ ```
60
+ taproot/
61
+ ├── password-reset/ ← Intent: why this exists and for whom
62
+ │ ├── intent.md
63
+ │ └── request-reset/ ← Behaviour: what the system does
64
+ │ ├── usecase.md
65
+ │ └── email-trigger/ ← Implementation: how it's built
66
+ │ └── impl.md
67
+ ```
68
+
69
+ Plain Markdown files, no database, git-versioned with your code. Any agent that can read files can use taproot.
70
+
71
+ ## Taproot tracks itself
72
+
73
+ Taproot's own requirements are managed with Taproot. [`taproot/OVERVIEW.md`](taproot/OVERVIEW.md) shows 18 intents, 53 behaviours, and 53 implementations — all complete — covering everything from validation rules to agent skill architecture to this README.
74
+
75
+ It's a working example of what a mature hierarchy looks like in practice.
76
+
77
+ ## Docs
78
+
79
+ - [Workflows](docs/workflows.md) — common patterns: new feature, bug fix, onboarding, discovery
80
+ - [Document types & examples](docs/concepts.md)
81
+ - [CLI reference](docs/cli.md)
82
+ - [Agent setup & tiers](docs/agents.md)
83
+ - [Configuration & CI](docs/configuration.md)
84
+ - [Patterns](docs/patterns.md)
85
+
86
+ ## License
87
+
88
+ MIT
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Agent adapter generators.
3
+ *
4
+ * Each generator reads the canonical skill definitions from the bundled
5
+ * skills/ directory and produces agent-specific wrapper files. Adapters
6
+ * are derived — regenerating them is always safe and idempotent.
7
+ */
8
+ export type AgentName = 'claude' | 'cursor' | 'copilot' | 'windsurf' | 'gemini' | 'generic';
9
+ export declare const ALL_AGENTS: AgentName[];
10
+ export type AgentTier = 1 | 2 | 3;
11
+ export declare const AGENT_TIERS: Record<AgentName, AgentTier>;
12
+ export declare function getTierLabel(agent: AgentName): string;
13
+ export interface AdapterResult {
14
+ agent: AgentName;
15
+ files: Array<{
16
+ path: string;
17
+ status: 'created' | 'updated' | 'exists';
18
+ }>;
19
+ }
20
+ export declare function generateAdapters(agents: AgentName | AgentName[] | 'all', projectRoot: string): AdapterResult[];
@@ -0,0 +1,452 @@
1
+ /**
2
+ * Agent adapter generators.
3
+ *
4
+ * Each generator reads the canonical skill definitions from the bundled
5
+ * skills/ directory and produces agent-specific wrapper files. Adapters
6
+ * are derived — regenerating them is always safe and idempotent.
7
+ */
8
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
9
+ import { join, resolve, dirname } from 'path';
10
+ import { fileURLToPath } from 'url';
11
+ import { SKILL_FILES } from '../commands/init.js';
12
+ import { loadConfig } from '../core/config.js';
13
+ import { loadLanguagePack, substituteTokens, applyVocabulary, getStructuralKeys } from '../core/language.js';
14
+ const __dirname = dirname(fileURLToPath(import.meta.url));
15
+ const BUNDLED_SKILLS_DIR = resolve(__dirname, '..', '..', 'skills');
16
+ // Markers for idempotent section injection into existing files
17
+ const TAPROOT_START = '<!-- TAPROOT:START -->';
18
+ const TAPROOT_END = '<!-- TAPROOT:END -->';
19
+ export const ALL_AGENTS = ['claude', 'cursor', 'copilot', 'windsurf', 'gemini', 'generic'];
20
+ export const AGENT_TIERS = {
21
+ claude: 1,
22
+ gemini: 2,
23
+ cursor: 3,
24
+ copilot: 3,
25
+ windsurf: 3,
26
+ generic: 3,
27
+ };
28
+ const TIER_LABELS = {
29
+ 1: 'Tier 1 — fully supported',
30
+ 2: 'Tier 2 — implemented & tested',
31
+ 3: 'Tier 3 — community supported',
32
+ };
33
+ export function getTierLabel(agent) {
34
+ return TIER_LABELS[AGENT_TIERS[agent]];
35
+ }
36
+ // ─── Public entry point ───────────────────────────────────────────────────────
37
+ export function generateAdapters(agents, projectRoot) {
38
+ const targets = agents === 'all' ? ALL_AGENTS : Array.isArray(agents) ? agents : [agents];
39
+ return targets.map(agent => generateAdapter(agent, projectRoot));
40
+ }
41
+ function generateAdapter(agent, projectRoot) {
42
+ const { config } = loadConfig(projectRoot);
43
+ const pack = config.language ? loadLanguagePack(config.language) : null;
44
+ const vocab = config.vocabulary ?? null;
45
+ const skills = loadSkills(pack, vocab);
46
+ switch (agent) {
47
+ case 'claude': return generateClaudeAdapter(skills, projectRoot);
48
+ case 'cursor': return generateCursorAdapter(skills, projectRoot);
49
+ case 'copilot': return generateCopilotAdapter(skills, projectRoot);
50
+ case 'windsurf': return generateWindsurfAdapter(skills, projectRoot);
51
+ case 'gemini': return generateGeminiAdapter(skills, projectRoot);
52
+ case 'generic': return generateGenericAdapter(skills, projectRoot);
53
+ }
54
+ }
55
+ function loadSkills(pack, vocab) {
56
+ return SKILL_FILES.map(filename => {
57
+ const name = filename.replace('.md', '');
58
+ const path = join(BUNDLED_SKILLS_DIR, filename);
59
+ let content = existsSync(path) ? readFileSync(path, 'utf-8') : `# Skill: ${name}\n\n(skill file not found)`;
60
+ if (pack)
61
+ content = substituteTokens(content, pack);
62
+ if (vocab && Object.keys(vocab).length > 0) {
63
+ const structuralKeys = getStructuralKeys(pack ?? null);
64
+ const { result } = applyVocabulary(content, vocab, structuralKeys);
65
+ content = result;
66
+ }
67
+ const description = extractFirstSentence(content);
68
+ return { filename, name, content, description, invocation: `/taproot:${name}` };
69
+ });
70
+ }
71
+ function extractFirstSentence(content) {
72
+ const descMatch = /^## Description\s*\n+([\s\S]+?)(?=\n##|\n\n\n|$)/m.exec(content);
73
+ if (!descMatch)
74
+ return '';
75
+ const body = descMatch[1]?.trim() ?? '';
76
+ // First sentence or first line
77
+ const sentence = body.split(/\.\s+/)[0] ?? body.split('\n')[0] ?? '';
78
+ return sentence.replace(/\.$/, '').trim();
79
+ }
80
+ // ─── Claude Code adapter ──────────────────────────────────────────────────────
81
+ // One .md file per skill in .claude/commands/, prefixed with tr-
82
+ // Invoked as /tr-<name>
83
+ // Skills that modify the taproot hierarchy — need OVERVIEW.md regenerated after
84
+ const TREE_MODIFYING_SKILLS = new Set([
85
+ 'intent', 'behaviour', 'implement', 'refine', 'promote', 'decompose', 'trace', 'discover', 'sweep',
86
+ ]);
87
+ function generateClaudeAdapter(skills, projectRoot) {
88
+ const targetDir = join(projectRoot, '.claude', 'commands');
89
+ mkdirSync(targetDir, { recursive: true });
90
+ const files = [];
91
+ for (const skill of skills) {
92
+ const destPath = join(targetDir, `tr-${skill.filename}`);
93
+ const existed = existsSync(destPath);
94
+ const content = buildClaudeSkillFile(skill);
95
+ writeFileSync(destPath, content, 'utf-8');
96
+ files.push({ path: destPath, status: existed ? 'updated' : 'created' });
97
+ }
98
+ // Configuration Quick Reference — a standalone reference file (not a skill launcher)
99
+ const refPath = join(targetDir, 'tr-taproot.md');
100
+ const refExisted = existsSync(refPath);
101
+ writeFileSync(refPath, buildClaudeConfigRefFile(), 'utf-8');
102
+ files.push({ path: refPath, status: refExisted ? 'updated' : 'created' });
103
+ return { agent: 'claude', files };
104
+ }
105
+ function buildClaudeConfigRefFile() {
106
+ return `---
107
+ name: 'tr-taproot'
108
+ description: 'Taproot configuration quick reference — settings.yaml options and how to apply them'
109
+ ---
110
+
111
+ # Taproot — Configuration Reference
112
+
113
+ This file is a quick reference for configuring taproot. Read it when asked to change taproot settings (language, vocabulary, definition of done, etc.).
114
+
115
+ ${buildConfigQuickRef()}
116
+ `;
117
+ }
118
+ function buildClaudeSkillFile(skill) {
119
+ const overviewStep = TREE_MODIFYING_SKILLS.has(skill.name)
120
+ ? '\n6. Run `taproot overview` to update @{project-root}/taproot/OVERVIEW.md with the current project state'
121
+ : '';
122
+ return `---
123
+ name: 'tr-${skill.name}'
124
+ description: '${skill.description.replace(/'/g, "\\'")}'
125
+ ---
126
+
127
+ IT IS CRITICAL THAT YOU FOLLOW THESE STEPS EXACTLY:
128
+
129
+ <steps CRITICAL="TRUE">
130
+ 1. LOAD the FULL skill file at @{project-root}/.taproot/skills/${skill.filename}
131
+ 2. READ its entire contents — this contains the complete skill definition with steps, inputs, and output format
132
+ 3. FOLLOW every step in the ## Steps section precisely and in order
133
+ 4. When the skill references other taproot commands (e.g. \`/taproot:intent\`), use the corresponding \`/tr-intent\` command instead
134
+ 5. Save all outputs to the paths specified in the skill's ## Output section${overviewStep}
135
+ </steps>
136
+ `;
137
+ }
138
+ // ─── Cursor adapter ───────────────────────────────────────────────────────────
139
+ // .cursor/rules/taproot.md — one combined rules file
140
+ function generateCursorAdapter(skills, projectRoot) {
141
+ const targetDir = join(projectRoot, '.cursor', 'rules');
142
+ mkdirSync(targetDir, { recursive: true });
143
+ const destPath = join(targetDir, 'taproot.md');
144
+ const existed = existsSync(destPath);
145
+ const content = buildCursorRulesFile(skills);
146
+ writeFileSync(destPath, content, 'utf-8');
147
+ return {
148
+ agent: 'cursor',
149
+ files: [{ path: destPath, status: existed ? 'updated' : 'created' }],
150
+ };
151
+ }
152
+ function buildCursorRulesFile(skills) {
153
+ const skillIndex = skills.map(s => `- \`@taproot ${s.name}\` — ${s.description}`).join('\n');
154
+ const skillSections = skills.map(s => `
155
+ ---
156
+
157
+ ## @taproot ${s.name}
158
+
159
+ ${s.content}
160
+ `.trimStart()).join('\n');
161
+ return `---
162
+ description: Taproot requirement hierarchy — skill definitions and document conventions
163
+ globs: ["taproot/**", ".taproot/settings.yaml"]
164
+ alwaysApply: false
165
+ ---
166
+
167
+ # Taproot Skills for Cursor
168
+
169
+ This project uses [Taproot](https://github.com/anthropics/taproot) to maintain a living requirement hierarchy alongside the codebase. The hierarchy lives in \`taproot/\` with three layers: **intent** (why), **behaviour** (what), and **implementation** (how).
170
+
171
+ ## Available Skills
172
+
173
+ Invoke these by mentioning \`@taproot <skill>\` in chat:
174
+
175
+ ${skillIndex}
176
+
177
+ ## Quick Reference
178
+
179
+ - Hierarchy lives in \`taproot/\` — intents → behaviours → implementations
180
+ - Validate with: \`taproot validate-structure\` and \`taproot validate-format\`
181
+ - See coverage: \`taproot coverage\`
182
+
183
+ ${buildConfigQuickRef()}
184
+
185
+ ${skillSections}
186
+ `.trimStart();
187
+ }
188
+ // ─── GitHub Copilot adapter ───────────────────────────────────────────────────
189
+ // .github/copilot-instructions.md — appends/replaces a marked section
190
+ function generateCopilotAdapter(skills, projectRoot) {
191
+ const targetDir = join(projectRoot, '.github');
192
+ mkdirSync(targetDir, { recursive: true });
193
+ const destPath = join(targetDir, 'copilot-instructions.md');
194
+ const existed = existsSync(destPath);
195
+ const taprootSection = buildCopilotSection(skills);
196
+ let finalContent;
197
+ if (existed) {
198
+ const existing = readFileSync(destPath, 'utf-8');
199
+ finalContent = replaceTaprootSection(existing, taprootSection);
200
+ }
201
+ else {
202
+ finalContent = taprootSection;
203
+ }
204
+ writeFileSync(destPath, finalContent, 'utf-8');
205
+ return {
206
+ agent: 'copilot',
207
+ files: [{ path: destPath, status: existed ? 'updated' : 'created' }],
208
+ };
209
+ }
210
+ function buildCopilotSection(skills) {
211
+ const skillSummary = skills.map(s => `- **\`/taproot:${s.name}\`** — ${s.description}. Full definition: \`.taproot/skills/${s.filename}\``).join('\n');
212
+ return `${TAPROOT_START}
213
+ ## Taproot Requirement Hierarchy
214
+
215
+ This project uses Taproot to maintain traceability from business intent to code. The hierarchy lives in \`taproot/\` with three layers:
216
+
217
+ - **Intent** (\`intent.md\`): business goal, stakeholders, success criteria
218
+ - **Behaviour** (\`usecase.md\`): observable system behaviour in UseCase format
219
+ - **Implementation** (\`impl.md\`): links to source files, commits, and tests
220
+
221
+ ### Available Taproot Skills
222
+
223
+ ${skillSummary}
224
+
225
+ ### CLI Commands
226
+
227
+ Run these to validate and inspect the hierarchy:
228
+ - \`taproot validate-structure\` — check folder nesting rules
229
+ - \`taproot validate-format\` — check document schemas
230
+ - \`taproot coverage\` — view completeness summary
231
+ - \`taproot check-orphans\` — find broken references
232
+ - \`taproot sync-check\` — detect stale specs
233
+
234
+ ### Conventions
235
+
236
+ - Commits that implement a behaviour: \`taproot(<intent>/<behaviour>/<impl>): <message>\`
237
+ - Full conventions: \`taproot/CONVENTIONS.md\`
238
+
239
+ ${buildConfigQuickRef()}
240
+ ${TAPROOT_END}
241
+ `;
242
+ }
243
+ // ─── Windsurf adapter ─────────────────────────────────────────────────────────
244
+ // .windsurfrules — appends/replaces a marked section
245
+ function generateWindsurfAdapter(skills, projectRoot) {
246
+ const destPath = join(projectRoot, '.windsurfrules');
247
+ const existed = existsSync(destPath);
248
+ const taprootSection = buildWindsurfSection(skills);
249
+ let finalContent;
250
+ if (existed) {
251
+ const existing = readFileSync(destPath, 'utf-8');
252
+ finalContent = replaceTaprootSection(existing, taprootSection);
253
+ }
254
+ else {
255
+ finalContent = taprootSection;
256
+ }
257
+ writeFileSync(destPath, finalContent, 'utf-8');
258
+ return {
259
+ agent: 'windsurf',
260
+ files: [{ path: destPath, status: existed ? 'updated' : 'created' }],
261
+ };
262
+ }
263
+ function buildWindsurfSection(skills) {
264
+ const skillIndex = skills.map(s => `- \`/taproot:${s.name}\` — ${s.description}`).join('\n');
265
+ const skillSections = skills.map(s => `
266
+ ### /taproot:${s.name}
267
+
268
+ ${s.content}
269
+ `.trimStart()).join('\n');
270
+ return `${TAPROOT_START}
271
+ # Taproot Requirement Hierarchy
272
+
273
+ This project uses Taproot to maintain traceability from business intent to code. The hierarchy lives in \`taproot/\`.
274
+
275
+ ## Taproot Skills
276
+
277
+ ${skillIndex}
278
+
279
+ ${buildConfigQuickRef()}
280
+
281
+ ## Skill Definitions
282
+
283
+ ${skillSections}
284
+ ${TAPROOT_END}
285
+ `;
286
+ }
287
+ // ─── Gemini CLI adapter ───────────────────────────────────────────────────────
288
+ // One .toml file per skill in .gemini/commands/, prefixed with tr-
289
+ // Invoked as /tr-<name> in Gemini CLI
290
+ function generateGeminiAdapter(skills, projectRoot) {
291
+ const targetDir = join(projectRoot, '.gemini', 'commands');
292
+ mkdirSync(targetDir, { recursive: true });
293
+ const files = [];
294
+ for (const skill of skills) {
295
+ const destPath = join(targetDir, `tr-${skill.name}.toml`);
296
+ const existed = existsSync(destPath);
297
+ const content = buildGeminiSkillFile(skill);
298
+ writeFileSync(destPath, content, 'utf-8');
299
+ files.push({ path: destPath, status: existed ? 'updated' : 'created' });
300
+ }
301
+ // Configuration Quick Reference reference file
302
+ const refPath = join(targetDir, 'tr-taproot.toml');
303
+ const refExisted = existsSync(refPath);
304
+ writeFileSync(refPath, buildGeminiConfigRefFile(), 'utf-8');
305
+ files.push({ path: refPath, status: refExisted ? 'updated' : 'created' });
306
+ return { agent: 'gemini', files };
307
+ }
308
+ function buildGeminiConfigRefFile() {
309
+ return `description = "Taproot configuration quick reference — settings.yaml options and how to apply them"
310
+
311
+ prompt = """
312
+ # Taproot — Configuration Reference
313
+
314
+ Read this when asked to change taproot settings (language, vocabulary, definition of done, etc.).
315
+
316
+ ## Configuration Quick Reference
317
+
318
+ Edit .taproot/settings.yaml to configure taproot. Run taproot update after changes.
319
+
320
+ Options:
321
+ - language: Language pack for section headers and keywords (e.g. de, fr, es). Default: English.
322
+ - vocabulary: Domain-specific term substitutions in skill output (e.g. feature: story).
323
+ - definitionOfDone: Shell commands run as gates before implementation commits.
324
+
325
+ See .taproot/CONFIGURATION.md for the full reference and examples.
326
+ """
327
+ `;
328
+ }
329
+ function buildGeminiSkillFile(skill) {
330
+ const overviewStep = TREE_MODIFYING_SKILLS.has(skill.name)
331
+ ? '\n5. Run `taproot overview` to update taproot/OVERVIEW.md with the current project state'
332
+ : '';
333
+ return `description = "${skill.description.replace(/"/g, '\\"')}"
334
+
335
+ prompt = """
336
+ IT IS CRITICAL THAT YOU FOLLOW THESE STEPS EXACTLY:
337
+
338
+ 1. LOAD the FULL skill file at .taproot/skills/${skill.filename}
339
+ 2. READ its entire contents — this contains the complete skill definition with steps, inputs, and output format
340
+ 3. FOLLOW every step in the ## Steps section precisely and in order
341
+ 4. Save all outputs to the paths specified in the skill's ## Output section${overviewStep}
342
+ """
343
+ `;
344
+ }
345
+ // ─── Generic adapter ──────────────────────────────────────────────────────────
346
+ // AGENTS.md at project root — readable by any AI agent on startup
347
+ function generateGenericAdapter(skills, projectRoot) {
348
+ const destPath = join(projectRoot, 'AGENTS.md');
349
+ const existed = existsSync(destPath);
350
+ const taprootSection = buildGenericAgentsFile(skills);
351
+ let finalContent;
352
+ if (existed) {
353
+ const existing = readFileSync(destPath, 'utf-8');
354
+ finalContent = replaceTaprootSection(existing, taprootSection);
355
+ }
356
+ else {
357
+ finalContent = taprootSection;
358
+ }
359
+ writeFileSync(destPath, finalContent, 'utf-8');
360
+ return {
361
+ agent: 'generic',
362
+ files: [{ path: destPath, status: existed ? 'updated' : 'created' }],
363
+ };
364
+ }
365
+ function buildGenericAgentsFile(skills) {
366
+ const skillIndex = skills.map(s => `- **\`/taproot:${s.name}\`** — ${s.description}`).join('\n');
367
+ const skillSections = skills.map(s => `
368
+ ---
369
+
370
+ ${s.content}
371
+ `.trimStart()).join('\n');
372
+ return `${TAPROOT_START}
373
+ # Taproot — Agent Instructions
374
+
375
+ This project uses **Taproot** to maintain a living requirement hierarchy alongside the code. Before making changes, check whether the relevant behaviour spec exists in \`taproot/\`.
376
+
377
+ ## Hierarchy Overview
378
+
379
+ \`\`\`
380
+ taproot/
381
+ ├── <intent-slug>/ # business goal (intent.md)
382
+ │ └── <behaviour-slug>/ # system behaviour (usecase.md)
383
+ │ └── <impl-slug>/ # implementation record (impl.md)
384
+ \`\`\`
385
+
386
+ - **Intent** (\`intent.md\`): stakeholders, goal, success criteria, constraints
387
+ - **Behaviour** (\`usecase.md\`): actor, preconditions, main flow, postconditions, error conditions
388
+ - **Implementation** (\`impl.md\`): source files, commits, tests — traceability bridge
389
+
390
+ ## Using Taproot Skills
391
+
392
+ The following skills are available. Invoke them by name when the user asks for the corresponding action.
393
+
394
+ ${skillIndex}
395
+
396
+ ## CLI Commands
397
+
398
+ \`\`\`bash
399
+ taproot validate-structure # check folder hierarchy rules
400
+ taproot validate-format # check document schemas
401
+ taproot coverage # completeness tree
402
+ taproot check-orphans # find broken references
403
+ taproot sync-check # detect stale specs
404
+ taproot link-commits # auto-link git commits to impl.md
405
+ \`\`\`
406
+
407
+ ${buildConfigQuickRef()}
408
+
409
+ ## Commit Convention
410
+
411
+ When implementing a behaviour, commit with:
412
+ \`\`\`
413
+ taproot(<intent>/<behaviour>/<impl>): <what this commit does>
414
+ \`\`\`
415
+
416
+ ## Skill Definitions
417
+
418
+ ${skillSections}
419
+ ${TAPROOT_END}
420
+ `;
421
+ }
422
+ // ─── Configuration Quick Reference ───────────────────────────────────────────
423
+ function buildConfigQuickRef() {
424
+ return `## Configuration Quick Reference
425
+
426
+ Edit \`.taproot/settings.yaml\` to configure taproot. Run \`taproot update\` after changes.
427
+
428
+ | Option | Type | Description |
429
+ |--------|------|-------------|
430
+ | \`language\` | string | Language pack for section headers and keywords (e.g. \`de\`, \`fr\`, \`es\`). Default: English. |
431
+ | \`vocabulary\` | map | Domain-specific term substitutions in skill output (e.g. \`feature: story\`). |
432
+ | \`definitionOfDone\` | list | Shell commands run as gates before implementation commits. |
433
+
434
+ See \`.taproot/CONFIGURATION.md\` for the full reference and examples.`;
435
+ }
436
+ // ─── Helpers ──────────────────────────────────────────────────────────────────
437
+ /**
438
+ * Replace the Taproot section (between markers) in an existing file,
439
+ * or append it if no markers are present.
440
+ */
441
+ function replaceTaprootSection(existing, newSection) {
442
+ const startIdx = existing.indexOf(TAPROOT_START);
443
+ const endIdx = existing.indexOf(TAPROOT_END);
444
+ if (startIdx !== -1 && endIdx !== -1 && endIdx > startIdx) {
445
+ return (existing.slice(0, startIdx) +
446
+ newSection +
447
+ existing.slice(endIdx + TAPROOT_END.length));
448
+ }
449
+ // No markers — append
450
+ return existing.trimEnd() + '\n\n' + newSection;
451
+ }
452
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,40 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { registerInit } from './commands/init.js';
4
+ import { registerValidateStructure } from './commands/validate-structure.js';
5
+ import { registerValidateFormat } from './commands/validate-format.js';
6
+ import { registerLinkCommits } from './commands/link-commits.js';
7
+ import { registerCheckOrphans } from './commands/check-orphans.js';
8
+ import { registerCoverage } from './commands/coverage.js';
9
+ import { registerSyncCheck } from './commands/sync-check.js';
10
+ import { registerUpdate } from './commands/update.js';
11
+ import { registerOverview } from './commands/overview.js';
12
+ import { registerPlan } from './commands/plan.js';
13
+ import { registerDod } from './commands/dod.js';
14
+ import { registerCommithook } from './commands/commithook.js';
15
+ import { registerAcceptanceCheck } from './commands/acceptance-check.js';
16
+ const program = new Command();
17
+ program
18
+ .name('taproot')
19
+ .description('Folder-based requirement hierarchy CLI')
20
+ .version('0.1.0')
21
+ .addHelpText('after', '\nConfiguration: edit .taproot/settings.yaml — see .taproot/CONFIGURATION.md for all options');
22
+ registerInit(program);
23
+ registerValidateStructure(program);
24
+ registerValidateFormat(program);
25
+ registerLinkCommits(program);
26
+ registerCheckOrphans(program);
27
+ registerCoverage(program);
28
+ registerSyncCheck(program);
29
+ registerUpdate(program);
30
+ registerOverview(program);
31
+ registerPlan(program);
32
+ registerDod(program);
33
+ registerCommithook(program);
34
+ registerAcceptanceCheck(program);
35
+ program.parseAsync().catch((err) => {
36
+ const message = err instanceof Error ? err.message : String(err);
37
+ process.stderr.write(`error: ${message}\n`);
38
+ process.exitCode = 1;
39
+ });
40
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,wCAAwC,CAAC;KACrD,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,OAAO,EAAE,8FAA8F,CAAC,CAAC;AAExH,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,yBAAyB,CAAC,OAAO,CAAC,CAAC;AACnC,sBAAsB,CAAC,OAAO,CAAC,CAAC;AAChC,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAC9B,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,iBAAiB,CAAC,OAAO,CAAC,CAAC;AAC3B,cAAc,CAAC,OAAO,CAAC,CAAC;AACxB,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC1B,YAAY,CAAC,OAAO,CAAC,CAAC;AACtB,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,uBAAuB,CAAC,OAAO,CAAC,CAAC;AAEjC,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC1C,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,OAAO,IAAI,CAAC,CAAC;IAC5C,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { Command } from 'commander';
2
+ interface CriterionRef {
3
+ id: string;
4
+ usecasePath: string;
5
+ }
6
+ interface TestRef {
7
+ id: string;
8
+ file: string;
9
+ line: number;
10
+ }
11
+ export interface AcceptanceReport {
12
+ specCriteria: CriterionRef[];
13
+ covered: string[];
14
+ uncovered: CriterionRef[];
15
+ orphaned: TestRef[];
16
+ missingSections: string[];
17
+ }
18
+ export declare function registerAcceptanceCheck(program: Command): void;
19
+ export declare function runAcceptanceCheck(rootPath: string, testDirs: string[]): AcceptanceReport;
20
+ /** Walk the hierarchy and extract AC-N IDs from ## Acceptance Criteria sections. */
21
+ export declare function collectCriteria(rootPath: string): CriterionRef[];
22
+ /** Collect usecase.md files that have impl children but no ## Acceptance Criteria section. */
23
+ export declare function collectMissingSections(rootPath: string): string[];
24
+ /** Walk test directories and collect all AC-N references with file+line. */
25
+ export declare function scanTestFiles(testDirs: string[]): TestRef[];
26
+ export {};