@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
@@ -0,0 +1,309 @@
1
+ import { existsSync, rmSync, readdirSync, readFileSync, writeFileSync, unlinkSync, mkdirSync, renameSync } from 'fs';
2
+ import { join, dirname, relative, resolve } from 'path';
3
+ import { buildConfigurationMd } from '../core/configuration.js';
4
+ import { generateAdapters } from '../adapters/index.js';
5
+ import { installSkills, installDocs, SKILL_FILES } from './init.js';
6
+ import { runOverview } from './overview.js';
7
+ import { DEFAULT_CONFIG, loadConfig } from '../core/config.js';
8
+ import { loadLanguagePack, supportedLanguages } from '../core/language.js';
9
+ import { walkHierarchy, flattenTree } from '../core/fs-walker.js';
10
+ const TAPROOT_START = '<!-- TAPROOT:START -->';
11
+ // Stale paths left behind by older taproot versions
12
+ const STALE_PATHS = [
13
+ '.claude/skills/taproot', // pre-tr- layout: skills were in a subdirectory
14
+ // tr- files that lived in skills/ before moving to commands/
15
+ // resolved dynamically for globbing — see removeStale()
16
+ ];
17
+ function detectInstalledAgents(cwd) {
18
+ const installed = [];
19
+ // claude: tr-*.md files in .claude/commands/ (current), .claude/skills/ (old), or taproot/ subdir (oldest)
20
+ const claudeCommandsDir = join(cwd, '.claude', 'commands');
21
+ const claudeSkillsDir = join(cwd, '.claude', 'skills');
22
+ const oldClaudeSubdir = join(cwd, '.claude', 'skills', 'taproot');
23
+ if ((existsSync(claudeCommandsDir) && readdirSync(claudeCommandsDir).some(f => f.startsWith('tr-'))) ||
24
+ existsSync(oldClaudeSubdir) ||
25
+ (existsSync(claudeSkillsDir) && readdirSync(claudeSkillsDir).some(f => f.startsWith('tr-')))) {
26
+ installed.push('claude');
27
+ }
28
+ // cursor: .cursor/rules/taproot.md
29
+ if (existsSync(join(cwd, '.cursor', 'rules', 'taproot.md'))) {
30
+ installed.push('cursor');
31
+ }
32
+ // copilot: .github/copilot-instructions.md containing taproot section
33
+ const copilotPath = join(cwd, '.github', 'copilot-instructions.md');
34
+ if (existsSync(copilotPath) && readFileSync(copilotPath, 'utf-8').includes(TAPROOT_START)) {
35
+ installed.push('copilot');
36
+ }
37
+ // windsurf: .windsurfrules containing taproot section
38
+ const windsurfPath = join(cwd, '.windsurfrules');
39
+ if (existsSync(windsurfPath) && readFileSync(windsurfPath, 'utf-8').includes(TAPROOT_START)) {
40
+ installed.push('windsurf');
41
+ }
42
+ // generic: AGENTS.md containing taproot section
43
+ const agentsPath = join(cwd, 'AGENTS.md');
44
+ if (existsSync(agentsPath) && readFileSync(agentsPath, 'utf-8').includes(TAPROOT_START)) {
45
+ installed.push('generic');
46
+ }
47
+ return installed;
48
+ }
49
+ function removeStale(cwd) {
50
+ const messages = [];
51
+ // Remove old taproot/ subdirectory
52
+ const oldSubdir = join(cwd, '.claude', 'skills', 'taproot');
53
+ if (existsSync(oldSubdir)) {
54
+ rmSync(oldSubdir, { recursive: true, force: true });
55
+ messages.push(`removed .claude/skills/taproot`);
56
+ }
57
+ // Remove tr-*.md files that were placed in .claude/skills/ (before commands/ layout)
58
+ const claudeSkillsDir = join(cwd, '.claude', 'skills');
59
+ if (existsSync(claudeSkillsDir)) {
60
+ for (const f of readdirSync(claudeSkillsDir)) {
61
+ if (f.startsWith('tr-') && f.endsWith('.md')) {
62
+ unlinkSync(join(claudeSkillsDir, f));
63
+ messages.push(`removed .claude/skills/${f}`);
64
+ }
65
+ }
66
+ }
67
+ // Migrate taproot/skills/ → .taproot/skills/
68
+ const oldSkillsDir = join(cwd, DEFAULT_CONFIG.root, 'skills');
69
+ const newSkillsDir = join(cwd, '.taproot', 'skills');
70
+ if (existsSync(oldSkillsDir) && !existsSync(newSkillsDir)) {
71
+ mkdirSync(join(cwd, '.taproot'), { recursive: true });
72
+ renameSync(oldSkillsDir, newSkillsDir);
73
+ messages.push(`migrated taproot/skills/ → .taproot/skills/`);
74
+ }
75
+ else if (existsSync(oldSkillsDir)) {
76
+ rmSync(oldSkillsDir, { recursive: true, force: true });
77
+ messages.push(`removed taproot/skills/ (already migrated to .taproot/skills/)`);
78
+ }
79
+ // Remove taproot/_brainstorms/
80
+ const brainsDir = join(cwd, DEFAULT_CONFIG.root, '_brainstorms');
81
+ if (existsSync(brainsDir)) {
82
+ rmSync(brainsDir, { recursive: true, force: true });
83
+ messages.push(`removed taproot/_brainstorms/`);
84
+ }
85
+ // Migrate old pre-commit hook content to taproot commithook
86
+ const hookPath = join(cwd, '.git', 'hooks', 'pre-commit');
87
+ if (existsSync(hookPath)) {
88
+ const hookContent = readFileSync(hookPath, 'utf-8');
89
+ if (hookContent.includes('validate-structure') || hookContent.includes('validate-format')) {
90
+ writeFileSync(hookPath, '#!/bin/sh\ntaproot commithook\n', { mode: 0o755 });
91
+ messages.push(`migrated .git/hooks/pre-commit → taproot commithook`);
92
+ }
93
+ }
94
+ return messages;
95
+ }
96
+ function extractTitle(content, fallback) {
97
+ const m = content.match(/^# (?:[^:\n]+: )?(.+)$/m);
98
+ return m?.[1]?.trim() ?? fallback;
99
+ }
100
+ function upsertLinkSection(content, docPath, sectionTitle, childNodes, childDoc) {
101
+ const managedHeader = `## ${sectionTitle} <!-- taproot-managed -->`;
102
+ // Build desired links: rel path → title
103
+ const desiredLinks = [];
104
+ for (const child of childNodes) {
105
+ const childDocPath = join(child.absolutePath, childDoc);
106
+ if (!existsSync(childDocPath))
107
+ continue;
108
+ const rel = './' + relative(dirname(docPath), childDocPath).replace(/\\/g, '/');
109
+ const childContent = readFileSync(childDocPath, 'utf-8');
110
+ desiredLinks.push({ rel, title: extractTitle(childContent, child.name) });
111
+ }
112
+ const lines = content.split('\n');
113
+ // Find section start: any "## <Title>" line (with or without managed comment)
114
+ const sectionPattern = new RegExp(`^## ${sectionTitle}(\\s|$)`);
115
+ const sectionStartIdx = lines.findIndex(l => sectionPattern.test(l));
116
+ if (sectionStartIdx === -1) {
117
+ if (desiredLinks.length === 0)
118
+ return content;
119
+ // Insert before ## Status or append at end
120
+ const statusIdx = lines.findIndex(l => /^## Status(\s|$)/.test(l));
121
+ const newBlock = [managedHeader, ...desiredLinks.map(l => `- [${l.title}](${l.rel})`), ''];
122
+ if (statusIdx !== -1) {
123
+ lines.splice(statusIdx, 0, ...newBlock, '');
124
+ }
125
+ else {
126
+ if (lines[lines.length - 1] !== '')
127
+ lines.push('');
128
+ lines.push(...newBlock);
129
+ }
130
+ return lines.join('\n');
131
+ }
132
+ // Find section end: next "## " heading or EOF
133
+ let sectionEndIdx = lines.length;
134
+ for (let i = sectionStartIdx + 1; i < lines.length; i++) {
135
+ if (/^## /.test(lines[i])) {
136
+ sectionEndIdx = i;
137
+ break;
138
+ }
139
+ }
140
+ // Process body lines: prune stale links, collect existing
141
+ const bodyLines = lines.slice(sectionStartIdx + 1, sectionEndIdx);
142
+ const existingRels = new Set();
143
+ const prunedBody = [];
144
+ for (const line of bodyLines) {
145
+ const linkMatch = line.match(/\[.*?\]\((.+?)\)/);
146
+ if (linkMatch) {
147
+ const rel = linkMatch[1];
148
+ const resolved = resolve(dirname(docPath), rel);
149
+ if (!existsSync(resolved))
150
+ continue; // prune stale
151
+ existingRels.add(rel);
152
+ }
153
+ prunedBody.push(line);
154
+ }
155
+ // Append missing links
156
+ for (const { rel, title } of desiredLinks) {
157
+ if (!existingRels.has(rel)) {
158
+ prunedBody.push(`- [${title}](${rel})`);
159
+ }
160
+ }
161
+ // Replace the section (update header to managed form, replace body)
162
+ lines.splice(sectionStartIdx, sectionEndIdx - sectionStartIdx, managedHeader, ...prunedBody);
163
+ return lines.join('\n');
164
+ }
165
+ export function refreshLinks(cwd, taprootDir) {
166
+ const messages = [];
167
+ if (!existsSync(taprootDir))
168
+ return messages;
169
+ const tree = walkHierarchy(taprootDir);
170
+ const nodes = flattenTree(tree).filter(n => n.marker === 'intent' || n.marker === 'behaviour');
171
+ for (const node of nodes) {
172
+ const markerFile = node.marker === 'intent' ? 'intent.md' : 'usecase.md';
173
+ const docPath = join(node.absolutePath, markerFile);
174
+ if (!existsSync(docPath))
175
+ continue;
176
+ const childMarker = node.marker === 'intent' ? 'behaviour' : 'impl';
177
+ const childDoc = childMarker === 'behaviour' ? 'usecase.md' : 'impl.md';
178
+ const sectionTitle = node.marker === 'intent' ? 'Behaviours' : 'Implementations';
179
+ const childNodes = node.children.filter(c => c.marker === childMarker);
180
+ const content = readFileSync(docPath, 'utf-8');
181
+ const updated = upsertLinkSection(content, docPath, sectionTitle, childNodes, childDoc);
182
+ if (updated !== content) {
183
+ writeFileSync(docPath, updated, 'utf-8');
184
+ messages.push(`updated ${relative(cwd, docPath)}`);
185
+ }
186
+ }
187
+ return messages;
188
+ }
189
+ export async function runUpdate(options) {
190
+ const cwd = options.cwd ?? process.cwd();
191
+ const messages = [];
192
+ // Validate language pack before modifying any files (AC-4)
193
+ const { config } = loadConfig(cwd);
194
+ let pack = null;
195
+ if (config.language) {
196
+ pack = loadLanguagePack(config.language);
197
+ if (!pack) {
198
+ messages.push(`error Unknown language pack '${config.language}'. ` +
199
+ `Supported: ${supportedLanguages().join(', ')}. ` +
200
+ `No files modified.`);
201
+ return messages;
202
+ }
203
+ messages.push(`language ${config.language} (${Object.keys(pack).length} tokens)`);
204
+ }
205
+ // Validate vocabulary overrides before modifying any files
206
+ const vocab = config.vocabulary ?? null;
207
+ if (vocab && Object.keys(vocab).length > 0) {
208
+ const emptyKeys = Object.entries(vocab)
209
+ .filter(([, v]) => v === '')
210
+ .map(([k]) => k);
211
+ if (emptyKeys.length > 0) {
212
+ for (const key of emptyKeys) {
213
+ messages.push(`error Vocabulary override '${key}' maps to an empty string — ` +
214
+ `this would silently delete the term from skill files. ` +
215
+ `Provide a non-empty replacement or remove the key.`);
216
+ }
217
+ messages.push('No files modified.');
218
+ return messages;
219
+ }
220
+ messages.push(`vocabulary ${Object.keys(vocab).length} overrides`);
221
+ }
222
+ const agents = detectInstalledAgents(cwd);
223
+ if (agents.length === 0) {
224
+ messages.push('No taproot agent adapters detected — nothing to update.');
225
+ messages.push('Run `taproot init --agent <name>` to install adapters.');
226
+ return Promise.resolve(messages);
227
+ }
228
+ messages.push(`Detected adapters: ${agents.join(', ')}`);
229
+ messages.push('');
230
+ // Remove stale paths from old versions
231
+ messages.push(...removeStale(cwd));
232
+ // Regenerate detected adapters
233
+ for (const agent of agents) {
234
+ const results = generateAdapters(agent, cwd);
235
+ for (const result of results) {
236
+ for (const file of result.files) {
237
+ const rel = file.path.replace(cwd + '/', '').replace(cwd + '\\', '');
238
+ const verb = file.status === 'created' ? 'created' : file.status === 'updated' ? 'updated' : 'exists ';
239
+ messages.push(`${verb} ${rel}`);
240
+ }
241
+ }
242
+ }
243
+ // Refresh/install skills — always when claude adapter is present, otherwise only if already installed
244
+ const skillsDir = join(cwd, '.taproot', 'skills');
245
+ const hasInstalledSkills = existsSync(skillsDir) &&
246
+ SKILL_FILES.some(f => existsSync(join(skillsDir, f)));
247
+ if (agents.includes('claude') || hasInstalledSkills) {
248
+ messages.push('');
249
+ messages.push(...installSkills(skillsDir, true, pack, vocab));
250
+ messages.push(...installDocs(join(cwd, '.taproot', 'docs'), true));
251
+ }
252
+ // Install or refresh .taproot/CONFIGURATION.md (AC-6/AC-7 of update-adapters-and-skills)
253
+ const taprootConfigDir = join(cwd, '.taproot');
254
+ const configMdPath = join(taprootConfigDir, 'CONFIGURATION.md');
255
+ try {
256
+ mkdirSync(taprootConfigDir, { recursive: true });
257
+ const content = buildConfigurationMd();
258
+ const existed = existsSync(configMdPath);
259
+ writeFileSync(configMdPath, content, 'utf-8');
260
+ messages.push('');
261
+ messages.push(`${existed ? 'updated' : 'created'} .taproot/CONFIGURATION.md`);
262
+ }
263
+ catch (err) {
264
+ messages.push(`warning Could not write .taproot/CONFIGURATION.md: ${err.message}`);
265
+ }
266
+ // Refresh cross-links (## Behaviours / ## Implementations sections)
267
+ const taprootDir = join(cwd, DEFAULT_CONFIG.root);
268
+ const linkMsgs = refreshLinks(cwd, taprootDir);
269
+ if (linkMsgs.length > 0) {
270
+ messages.push('');
271
+ messages.push(...linkMsgs);
272
+ }
273
+ // Regenerate OVERVIEW.md
274
+ const overviewMsgs = await runOverview({ taprootDir, cwd });
275
+ if (overviewMsgs.length > 0) {
276
+ messages.push('');
277
+ messages.push(...overviewMsgs);
278
+ }
279
+ // Install hook if --with-hooks and none exists
280
+ if (options.withHooks) {
281
+ const hookDir = join(cwd, '.git', 'hooks');
282
+ const hookPath = join(hookDir, 'pre-commit');
283
+ if (existsSync(join(cwd, '.git')) && !existsSync(hookPath)) {
284
+ mkdirSync(hookDir, { recursive: true });
285
+ writeFileSync(hookPath, '#!/bin/sh\ntaproot commithook\n', { mode: 0o755 });
286
+ messages.push(`created .git/hooks/pre-commit`);
287
+ }
288
+ else if (existsSync(hookPath)) {
289
+ messages.push(`exists .git/hooks/pre-commit`);
290
+ }
291
+ }
292
+ messages.push('');
293
+ messages.push('Update complete.');
294
+ return messages;
295
+ }
296
+ export function registerUpdate(program) {
297
+ program
298
+ .command('update')
299
+ .description('Regenerate agent adapters and refresh installed skills')
300
+ .option('--path <path>', 'Project directory to update', process.cwd())
301
+ .option('--with-hooks', 'Install pre-commit hook if not already present')
302
+ .action(async (options) => {
303
+ const msgs = await runUpdate({ cwd: options.path, withHooks: options.withHooks });
304
+ for (const msg of msgs) {
305
+ process.stdout.write(msg + '\n');
306
+ }
307
+ });
308
+ }
309
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Command } from 'commander';
2
+ import type { Violation } from '../validators/types.js';
3
+ export declare function registerValidateFormat(program: Command): void;
4
+ export declare function runValidateFormat(options: {
5
+ path?: string;
6
+ fix?: boolean;
7
+ cwd?: string;
8
+ }): Promise<Violation[]>;
@@ -0,0 +1,93 @@
1
+ import { resolve, join } from 'path';
2
+ import { readFileSync, writeFileSync } from 'fs';
3
+ import { loadConfig } from '../core/config.js';
4
+ import { loadLanguagePack, supportedLanguages } from '../core/language.js';
5
+ import { walkHierarchy, flattenTree } from '../core/fs-walker.js';
6
+ import { parseMarkdown } from '../core/markdown-parser.js';
7
+ import { validateFormat } from '../validators/format-rules.js';
8
+ import { renderViolations, exitCode } from '../core/reporter.js';
9
+ import { SECTION_PLACEHOLDERS } from '../templates/index.js';
10
+ const MARKER_FILE = {
11
+ intent: 'intent.md',
12
+ behaviour: 'usecase.md',
13
+ impl: 'impl.md',
14
+ };
15
+ export function registerValidateFormat(program) {
16
+ program
17
+ .command('validate-format')
18
+ .description('Validate marker file contents against their schemas')
19
+ .option('--path <path>', 'Root path to validate (overrides config)')
20
+ .option('--fix', 'Add missing section headers with placeholder content')
21
+ .action(async (options) => {
22
+ const violations = await runValidateFormat({
23
+ path: options.path,
24
+ fix: options.fix ?? false,
25
+ });
26
+ process.stdout.write(renderViolations(violations));
27
+ process.exit(exitCode(violations));
28
+ });
29
+ }
30
+ export async function runValidateFormat(options) {
31
+ const { config, configDir } = loadConfig(options.cwd);
32
+ const rootPath = options.path
33
+ ? resolve(options.path)
34
+ : config.root.startsWith('/') ? config.root : resolve(configDir, config.root);
35
+ // Load language pack if configured
36
+ let pack = null;
37
+ if (config.language) {
38
+ pack = loadLanguagePack(config.language);
39
+ if (!pack) {
40
+ process.stderr.write(`Warning: Language pack '${config.language}' could not be loaded — falling back to English. ` +
41
+ `Supported: ${supportedLanguages().join(', ')}. Check your taproot installation.\n`);
42
+ }
43
+ }
44
+ const tree = walkHierarchy(rootPath);
45
+ const nodes = flattenTree(tree).filter((n) => n.marker !== null);
46
+ const violations = [];
47
+ for (const node of nodes) {
48
+ const markerFile = MARKER_FILE[node.marker];
49
+ const filePath = join(node.absolutePath, markerFile);
50
+ let content;
51
+ try {
52
+ content = readFileSync(filePath, 'utf-8');
53
+ }
54
+ catch {
55
+ violations.push({
56
+ type: 'error',
57
+ filePath,
58
+ code: 'UNREADABLE_FILE',
59
+ message: `Could not read file: ${filePath}`,
60
+ });
61
+ continue;
62
+ }
63
+ const parsed = parseMarkdown(filePath, content);
64
+ const nodeViolations = validateFormat(parsed, node.marker, config, node, pack);
65
+ if (options.fix && nodeViolations.some(v => v.code === 'MISSING_SECTION')) {
66
+ const fixed = applyFix(content, parsed, node.marker);
67
+ writeFileSync(filePath, fixed, 'utf-8');
68
+ // Re-parse and re-validate after fix
69
+ const reparsed = parseMarkdown(filePath, fixed);
70
+ violations.push(...validateFormat(reparsed, node.marker, config, node));
71
+ }
72
+ else {
73
+ violations.push(...nodeViolations);
74
+ }
75
+ }
76
+ return violations;
77
+ }
78
+ function applyFix(content, parsed, markerType) {
79
+ const placeholders = SECTION_PLACEHOLDERS[markerType] ?? {};
80
+ const required = markerType === 'intent' ? ['stakeholders', 'goal', 'success criteria', 'status'] :
81
+ markerType === 'behaviour' ? ['actor', 'preconditions', 'main flow', 'postconditions', 'status'] :
82
+ ['behaviour', 'commits', 'tests', 'status'];
83
+ const missing = required.filter(s => !parsed.sections.has(s));
84
+ if (missing.length === 0)
85
+ return content;
86
+ const additions = missing.map(section => {
87
+ const placeholder = placeholders[section] ?? '<placeholder>';
88
+ const heading = section.replace(/\b\w/g, c => c.toUpperCase());
89
+ return `\n## ${heading}\n${placeholder}\n`;
90
+ });
91
+ return content.trimEnd() + '\n' + additions.join('');
92
+ }
93
+ //# sourceMappingURL=validate-format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-format.js","sourceRoot":"","sources":["../../src/commands/validate-format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Command } from 'commander';
2
+ import type { Violation } from '../validators/types.js';
3
+ export declare function registerValidateStructure(program: Command): void;
4
+ export declare function runValidateStructure(options: {
5
+ path?: string;
6
+ strict?: boolean;
7
+ cwd?: string;
8
+ }): Promise<Violation[]>;
@@ -0,0 +1,29 @@
1
+ import { resolve } from 'path';
2
+ import { loadConfig } from '../core/config.js';
3
+ import { walkHierarchy } from '../core/fs-walker.js';
4
+ import { validateStructure } from '../validators/structure-rules.js';
5
+ import { renderViolations, exitCode } from '../core/reporter.js';
6
+ export function registerValidateStructure(program) {
7
+ program
8
+ .command('validate-structure')
9
+ .description('Validate folder hierarchy nesting rules')
10
+ .option('--path <path>', 'Root path to validate (overrides config)')
11
+ .option('--strict', 'Also warn on empty folders and missing optional fields')
12
+ .action(async (options) => {
13
+ const violations = await runValidateStructure({
14
+ path: options.path,
15
+ strict: options.strict ?? false,
16
+ });
17
+ process.stdout.write(renderViolations(violations));
18
+ process.exit(exitCode(violations));
19
+ });
20
+ }
21
+ export async function runValidateStructure(options) {
22
+ const { config, configDir } = loadConfig(options.cwd);
23
+ const rootPath = options.path
24
+ ? resolve(options.path)
25
+ : config.root.startsWith('/') ? config.root : resolve(configDir, config.root);
26
+ const tree = walkHierarchy(rootPath);
27
+ return validateStructure(tree, { strict: options.strict ?? false });
28
+ }
29
+ //# sourceMappingURL=validate-structure.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate-structure.js","sourceRoot":"","sources":["../../src/commands/validate-structure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAE/B,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGjE,MAAM,UAAU,yBAAyB,CAAC,OAAgB;IACxD,OAAO;SACJ,OAAO,CAAC,oBAAoB,CAAC;SAC7B,WAAW,CAAC,yCAAyC,CAAC;SACtD,MAAM,CAAC,eAAe,EAAE,0CAA0C,CAAC;SACnE,MAAM,CAAC,UAAU,EAAE,wDAAwD,CAAC;SAC5E,MAAM,CAAC,KAAK,EAAE,OAA4C,EAAE,EAAE;QAC7D,MAAM,UAAU,GAAG,MAAM,oBAAoB,CAAC;YAC5C,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK;SAChC,CAAC,CAAC;QACH,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACP,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,OAI1C;IACC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI;QAC3B,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC;QACvB,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAEhF,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACrC,OAAO,iBAAiB,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { TaprootConfig } from '../validators/types.js';
2
+ export declare const DEFAULT_CONFIG: TaprootConfig;
3
+ export declare function loadConfig(cwd?: string): {
4
+ config: TaprootConfig;
5
+ configDir: string;
6
+ };
@@ -0,0 +1,86 @@
1
+ import { readFileSync, existsSync } from 'fs';
2
+ import { resolve, dirname, join } from 'path';
3
+ import yaml from 'js-yaml';
4
+ export const DEFAULT_CONFIG = {
5
+ version: 1,
6
+ root: 'taproot/',
7
+ commitPattern: 'taproot\\(([^)]+)\\):',
8
+ commitTrailer: 'Taproot',
9
+ agents: ['claude', 'cursor', 'generic'],
10
+ validation: {
11
+ requireDates: true,
12
+ requireStatus: true,
13
+ allowedIntentStates: ['draft', 'active', 'achieved', 'deprecated'],
14
+ allowedBehaviourStates: ['proposed', 'specified', 'implemented', 'tested', 'deprecated', 'deferred'],
15
+ allowedImplStates: ['planned', 'in-progress', 'complete', 'needs-rework', 'deferred'],
16
+ },
17
+ hooks: {
18
+ preCommit: ['taproot validate-structure', 'taproot validate-format'],
19
+ },
20
+ ci: {
21
+ onPr: [
22
+ 'taproot validate-structure',
23
+ 'taproot validate-format',
24
+ 'taproot check-orphans',
25
+ 'taproot sync-check',
26
+ ],
27
+ onMerge: [
28
+ 'taproot link-commits',
29
+ 'taproot coverage --format markdown >> pr-comment',
30
+ 'taproot coverage --format context',
31
+ ],
32
+ },
33
+ };
34
+ function findConfigFile(startDir) {
35
+ let current = resolve(startDir);
36
+ while (true) {
37
+ const candidate = join(current, '.taproot', 'settings.yaml');
38
+ if (existsSync(candidate))
39
+ return { configFile: candidate, projectRoot: current };
40
+ const parent = dirname(current);
41
+ if (parent === current)
42
+ return null;
43
+ current = parent;
44
+ }
45
+ }
46
+ function deepMerge(defaults, overrides) {
47
+ const result = { ...defaults };
48
+ for (const key of Object.keys(overrides)) {
49
+ const override = overrides[key];
50
+ const def = defaults[key];
51
+ if (override !== undefined && override !== null) {
52
+ if (typeof override === 'object' &&
53
+ !Array.isArray(override) &&
54
+ typeof def === 'object' &&
55
+ !Array.isArray(def) &&
56
+ def !== null) {
57
+ result[key] = deepMerge(def, override);
58
+ }
59
+ else {
60
+ result[key] = override;
61
+ }
62
+ }
63
+ }
64
+ return result;
65
+ }
66
+ export function loadConfig(cwd = process.cwd()) {
67
+ const found = findConfigFile(cwd);
68
+ if (!found) {
69
+ return {
70
+ config: { ...DEFAULT_CONFIG, root: resolve(cwd, DEFAULT_CONFIG.root) },
71
+ configDir: cwd,
72
+ };
73
+ }
74
+ const { configFile, projectRoot } = found;
75
+ let raw;
76
+ try {
77
+ raw = yaml.load(readFileSync(configFile, 'utf-8'));
78
+ }
79
+ catch (err) {
80
+ throw new Error(`Failed to parse ${configFile}: ${err.message}`);
81
+ }
82
+ const merged = deepMerge(DEFAULT_CONFIG, (raw ?? {}));
83
+ merged.root = resolve(projectRoot, merged.root);
84
+ return { config: merged, configDir: projectRoot };
85
+ }
86
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,IAAI,MAAM,SAAS,CAAC;AAG3B,MAAM,CAAC,MAAM,cAAc,GAAkB;IAC3C,OAAO,EAAE,CAAC;IACV,IAAI,EAAE,UAAU;IAChB,aAAa,EAAE,uBAAuB;IACtC,aAAa,EAAE,SAAS;IACxB,MAAM,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC;IACvC,UAAU,EAAE;QACV,YAAY,EAAE,IAAI;QAClB,aAAa,EAAE,IAAI;QACnB,mBAAmB,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,YAAY,CAAC;QAClE,sBAAsB,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,CAAC;QACpG,iBAAiB,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,CAAC;KACtF;IACD,KAAK,EAAE;QACL,SAAS,EAAE,CAAC,4BAA4B,EAAE,yBAAyB,CAAC;KACrE;IACD,EAAE,EAAE;QACF,IAAI,EAAE;YACJ,4BAA4B;YAC5B,yBAAyB;YACzB,uBAAuB;YACvB,oBAAoB;SACrB;QACD,OAAO,EAAE;YACP,sBAAsB;YACtB,kDAAkD;YAClD,mCAAmC;SACpC;KACF;CACF,CAAC;AAEF,SAAS,cAAc,CAAC,QAAgB;IACtC,IAAI,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChC,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;QAC7D,IAAI,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,CAAC;QAClF,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QAChC,IAAI,MAAM,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC;QACpC,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAI,QAAW,EAAE,SAAqB;IACtD,MAAM,MAAM,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,CAAmB,EAAE,CAAC;QAC3D,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YAChD,IACE,OAAO,QAAQ,KAAK,QAAQ;gBAC5B,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;gBACxB,OAAO,GAAG,KAAK,QAAQ;gBACvB,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;gBACnB,GAAG,KAAK,IAAI,EACZ,CAAC;gBACD,MAAM,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC,GAAG,EAAE,QAA+B,CAAC,CAAC;YAChE,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,GAAG,CAAC,GAAG,QAAsB,CAAC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IACpD,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAElC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO;YACL,MAAM,EAAE,EAAE,GAAG,cAAc,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,CAAC,EAAE;YACtE,SAAS,EAAE,GAAG;SACf,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC;IAC1C,IAAI,GAAY,CAAC;IACjB,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,mBAAmB,UAAU,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,cAAc,EAAE,CAAC,GAAG,IAAI,EAAE,CAA2B,CAAC,CAAC;IAChF,MAAM,CAAC,IAAI,GAAG,OAAO,CAAC,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAEhD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC;AACpD,CAAC"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * CONFIGURATION.md generator.
3
+ *
4
+ * Produces the content installed at .taproot/CONFIGURATION.md — the primary
5
+ * discoverability surface for agents completing configuration tasks.
6
+ */
7
+ export declare function buildConfigurationMd(): string;