@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.
- package/README.md +88 -0
- package/dist/adapters/index.d.ts +20 -0
- package/dist/adapters/index.js +452 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +40 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/acceptance-check.d.ts +26 -0
- package/dist/commands/acceptance-check.js +213 -0
- package/dist/commands/acceptance-check.js.map +1 -0
- package/dist/commands/check-orphans.d.ts +8 -0
- package/dist/commands/check-orphans.js +157 -0
- package/dist/commands/check-orphans.js.map +1 -0
- package/dist/commands/commithook.d.ts +15 -0
- package/dist/commands/commithook.js +389 -0
- package/dist/commands/commithook.js.map +1 -0
- package/dist/commands/coverage.d.ts +41 -0
- package/dist/commands/coverage.js +390 -0
- package/dist/commands/coverage.js.map +1 -0
- package/dist/commands/dod.d.ts +13 -0
- package/dist/commands/dod.js +141 -0
- package/dist/commands/dod.js.map +1 -0
- package/dist/commands/init.d.ts +14 -0
- package/dist/commands/init.js +378 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/link-commits.d.ts +12 -0
- package/dist/commands/link-commits.js +126 -0
- package/dist/commands/link-commits.js.map +1 -0
- package/dist/commands/overview.d.ts +6 -0
- package/dist/commands/overview.js +192 -0
- package/dist/commands/overview.js.map +1 -0
- package/dist/commands/plan.d.ts +23 -0
- package/dist/commands/plan.js +167 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/sync-check.d.ts +8 -0
- package/dist/commands/sync-check.js +118 -0
- package/dist/commands/sync-check.js.map +1 -0
- package/dist/commands/update.d.ts +7 -0
- package/dist/commands/update.js +309 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/validate-format.d.ts +8 -0
- package/dist/commands/validate-format.js +93 -0
- package/dist/commands/validate-format.js.map +1 -0
- package/dist/commands/validate-structure.d.ts +8 -0
- package/dist/commands/validate-structure.js +29 -0
- package/dist/commands/validate-structure.js.map +1 -0
- package/dist/core/config.d.ts +6 -0
- package/dist/core/config.js +86 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/configuration.d.ts +7 -0
- package/dist/core/configuration.js +112 -0
- package/dist/core/configuration.js.map +1 -0
- package/dist/core/dod-runner.d.ts +20 -0
- package/dist/core/dod-runner.js +233 -0
- package/dist/core/dod-runner.js.map +1 -0
- package/dist/core/dor-runner.d.ts +18 -0
- package/dist/core/dor-runner.js +156 -0
- package/dist/core/dor-runner.js.map +1 -0
- package/dist/core/fs-walker.d.ts +5 -0
- package/dist/core/fs-walker.js +74 -0
- package/dist/core/fs-walker.js.map +1 -0
- package/dist/core/git.d.ts +24 -0
- package/dist/core/git.js +76 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/impl-reader.d.ts +8 -0
- package/dist/core/impl-reader.js +39 -0
- package/dist/core/impl-reader.js.map +1 -0
- package/dist/core/language.d.ts +39 -0
- package/dist/core/language.js +159 -0
- package/dist/core/language.js.map +1 -0
- package/dist/core/markdown-parser.d.ts +3 -0
- package/dist/core/markdown-parser.js +37 -0
- package/dist/core/markdown-parser.js.map +1 -0
- package/dist/core/reporter.d.ts +3 -0
- package/dist/core/reporter.js +33 -0
- package/dist/core/reporter.js.map +1 -0
- package/dist/templates/index.d.ts +4 -0
- package/dist/templates/index.js +126 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/validators/format-rules.d.ts +10 -0
- package/dist/validators/format-rules.js +238 -0
- package/dist/validators/format-rules.js.map +1 -0
- package/dist/validators/structure-rules.d.ts +10 -0
- package/dist/validators/structure-rules.js +94 -0
- package/dist/validators/structure-rules.js.map +1 -0
- package/dist/validators/types.d.ts +68 -0
- package/dist/validators/types.js +2 -0
- package/dist/validators/types.js.map +1 -0
- package/docs/agents.md +88 -0
- package/docs/architecture.md +53 -0
- package/docs/cli.md +226 -0
- package/docs/concepts.md +268 -0
- package/docs/configuration.md +255 -0
- package/docs/demo.svg +111 -0
- package/docs/patterns.md +118 -0
- package/docs/security.md +95 -0
- package/docs/workflows.md +151 -0
- package/languages/de.json +20 -0
- package/languages/en.json +20 -0
- package/languages/es.json +20 -0
- package/languages/fr.json +20 -0
- package/languages/ja.json +20 -0
- package/languages/pt.json +20 -0
- package/package.json +54 -0
- package/skills/analyse-change.md +101 -0
- package/skills/behaviour.md +179 -0
- package/skills/bug.md +70 -0
- package/skills/commit.md +99 -0
- package/skills/decompose.md +101 -0
- package/skills/discover.md +392 -0
- package/skills/grill-me.md +65 -0
- package/skills/guide.md +118 -0
- package/skills/implement.md +149 -0
- package/skills/ineed.md +147 -0
- package/skills/intent.md +104 -0
- package/skills/plan.md +63 -0
- package/skills/promote.md +69 -0
- package/skills/refine.md +78 -0
- package/skills/research.md +122 -0
- package/skills/review-all.md +92 -0
- package/skills/review.md +80 -0
- package/skills/status.md +103 -0
- package/skills/sweep.md +89 -0
- package/skills/trace.md +151 -0
|
@@ -0,0 +1,112 @@
|
|
|
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
|
+
import { supportedLanguages } from './language.js';
|
|
8
|
+
export function buildConfigurationMd() {
|
|
9
|
+
const langs = supportedLanguages().join(', ');
|
|
10
|
+
return `# Taproot Configuration Reference
|
|
11
|
+
|
|
12
|
+
Edit \`.taproot/settings.yaml\` to configure taproot.
|
|
13
|
+
|
|
14
|
+
**After changing \`language\` or \`vocabulary\`:** run \`taproot update\` to regenerate skill files and adapters.
|
|
15
|
+
**After changing \`definitionOfDone\` or \`definitionOfReady\`:** no \`taproot update\` needed — these are read at runtime.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## language
|
|
20
|
+
|
|
21
|
+
Language pack for section headers, Gherkin keywords, and status values in skill files.
|
|
22
|
+
|
|
23
|
+
\`\`\`yaml
|
|
24
|
+
language: de
|
|
25
|
+
\`\`\`
|
|
26
|
+
|
|
27
|
+
**Supported values:** ${langs}
|
|
28
|
+
|
|
29
|
+
**Default:** English (omit the field)
|
|
30
|
+
|
|
31
|
+
**Requires \`taproot update\`:** yes — skill files and adapter descriptions are regenerated with translated terminology.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## vocabulary
|
|
36
|
+
|
|
37
|
+
Domain-specific term substitutions applied to all skill file output. Use this to replace taproot's default terminology with words native to your project's domain.
|
|
38
|
+
|
|
39
|
+
\`\`\`yaml
|
|
40
|
+
vocabulary:
|
|
41
|
+
feature: story
|
|
42
|
+
behaviour: acceptance criterion
|
|
43
|
+
intent: epic
|
|
44
|
+
\`\`\`
|
|
45
|
+
|
|
46
|
+
**Format:** a YAML map of \`original: replacement\` string pairs. Keys are matched case-insensitively on whole words. Declaration order governs overlap — declare longer keys before their prefixes.
|
|
47
|
+
|
|
48
|
+
**Default:** no substitutions (omit the field)
|
|
49
|
+
|
|
50
|
+
**Requires \`taproot update\`:** yes — skill files are regenerated with the substituted terminology.
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## definitionOfDone
|
|
55
|
+
|
|
56
|
+
Shell commands run as gates before implementation commits. Each command must exit 0 for the commit to proceed.
|
|
57
|
+
|
|
58
|
+
\`\`\`yaml
|
|
59
|
+
definitionOfDone:
|
|
60
|
+
- condition: tests-passing
|
|
61
|
+
run: npm test
|
|
62
|
+
- condition: lint-clean
|
|
63
|
+
run: npm run lint
|
|
64
|
+
\`\`\`
|
|
65
|
+
|
|
66
|
+
**Format:** a list of objects with \`condition\` (name shown in output) and \`run\` (shell command).
|
|
67
|
+
|
|
68
|
+
**Default:** baseline checks only (validate-format, validate-structure, tests-passing)
|
|
69
|
+
|
|
70
|
+
**Requires \`taproot update\`:** no — read at runtime by \`taproot dod\`.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## definitionOfReady
|
|
75
|
+
|
|
76
|
+
Shell commands run as gates before declaration commits (new impl.md). Each command must exit 0 for the commit to proceed.
|
|
77
|
+
|
|
78
|
+
\`\`\`yaml
|
|
79
|
+
definitionOfReady:
|
|
80
|
+
- condition: spec-reviewed
|
|
81
|
+
run: echo "Spec reviewed"
|
|
82
|
+
\`\`\`
|
|
83
|
+
|
|
84
|
+
**Format:** same as \`definitionOfDone\`.
|
|
85
|
+
|
|
86
|
+
**Default:** baseline checks only
|
|
87
|
+
|
|
88
|
+
**Requires \`taproot update\`:** no — read at runtime by the pre-commit hook.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Full example
|
|
93
|
+
|
|
94
|
+
\`\`\`yaml
|
|
95
|
+
version: 1
|
|
96
|
+
language: de
|
|
97
|
+
vocabulary:
|
|
98
|
+
feature: story
|
|
99
|
+
behaviour: acceptance criterion
|
|
100
|
+
definitionOfDone:
|
|
101
|
+
- condition: tests-passing
|
|
102
|
+
run: npm test
|
|
103
|
+
- condition: lint-clean
|
|
104
|
+
run: npm run lint
|
|
105
|
+
\`\`\`
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
*Generated by taproot. Run \`taproot update\` to refresh this file after upgrading.*
|
|
110
|
+
`;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=configuration.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configuration.js","sourceRoot":"","sources":["../../src/core/configuration.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAEnD,MAAM,UAAU,oBAAoB;IAClC,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE9C,OAAO;;;;;;;;;;;;;;;;;wBAiBe,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmF5B,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { DodConditionEntry } from '../validators/types.js';
|
|
2
|
+
export interface DodResult {
|
|
3
|
+
name: string;
|
|
4
|
+
passed: boolean;
|
|
5
|
+
output: string;
|
|
6
|
+
correction: string;
|
|
7
|
+
}
|
|
8
|
+
export interface DodReport {
|
|
9
|
+
configured: boolean;
|
|
10
|
+
results: DodResult[];
|
|
11
|
+
allPassed: boolean;
|
|
12
|
+
usecaseCascade?: string;
|
|
13
|
+
}
|
|
14
|
+
/** Read agent-check resolutions recorded in impl.md's ## DoD Resolutions section.
|
|
15
|
+
* Returns an empty set if impl.md has been modified after the resolutions were written
|
|
16
|
+
* (indicating more implementation work happened since the agent resolved the checks). */
|
|
17
|
+
export declare function readResolutions(implPath: string, cwd: string): Set<string>;
|
|
18
|
+
export declare function runDodChecks(conditions: DodConditionEntry[] | undefined, cwd: string, options?: {
|
|
19
|
+
implPath?: string;
|
|
20
|
+
}): DodReport;
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { existsSync, readFileSync, statSync } from 'fs';
|
|
2
|
+
import { join, dirname, resolve } from 'path';
|
|
3
|
+
import { spawnSync } from 'child_process';
|
|
4
|
+
import { parseMarkdown } from './markdown-parser.js';
|
|
5
|
+
import { validateFormat } from '../validators/format-rules.js';
|
|
6
|
+
import { loadConfig } from './config.js';
|
|
7
|
+
const BUILTINS = {
|
|
8
|
+
'tests-passing': {
|
|
9
|
+
run: 'npm test',
|
|
10
|
+
correction: 'Fix failing tests and re-run.',
|
|
11
|
+
},
|
|
12
|
+
'linter-clean': {
|
|
13
|
+
run: 'npm run lint',
|
|
14
|
+
correction: 'Fix lint errors reported above and re-run.',
|
|
15
|
+
},
|
|
16
|
+
'commit-conventions': {
|
|
17
|
+
run: 'npm run check:commits',
|
|
18
|
+
correction: 'Ensure your commits follow the project commit convention.',
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
const TIMEOUT_MS = 30_000;
|
|
22
|
+
function resolveCondition(entry) {
|
|
23
|
+
if (typeof entry === 'object' && 'document-current' in entry) {
|
|
24
|
+
const description = entry['document-current'];
|
|
25
|
+
return {
|
|
26
|
+
name: 'document-current',
|
|
27
|
+
correction: description,
|
|
28
|
+
agentCheck: true,
|
|
29
|
+
description,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (typeof entry === 'object' && 'check-if-affected' in entry) {
|
|
33
|
+
const target = entry['check-if-affected'];
|
|
34
|
+
return {
|
|
35
|
+
name: `check-if-affected: ${target}`,
|
|
36
|
+
agentCheck: true,
|
|
37
|
+
description: target,
|
|
38
|
+
correction: `Review whether this change requires updating ${target} and apply updates if needed.`,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
if (typeof entry === 'object' && 'check-if-affected-by' in entry) {
|
|
42
|
+
const behaviourPath = entry['check-if-affected-by'];
|
|
43
|
+
return {
|
|
44
|
+
name: `check-if-affected-by: ${behaviourPath}`,
|
|
45
|
+
agentCheck: true,
|
|
46
|
+
description: behaviourPath,
|
|
47
|
+
correction: `Read the behaviour spec at ${behaviourPath}/usecase.md. Determine whether it applies to this implementation and verify compliance. If it applies, ensure this implementation satisfies it; if not, record why it does not apply.`,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (typeof entry === 'object' && 'check' in entry) {
|
|
51
|
+
const question = entry['check'];
|
|
52
|
+
return {
|
|
53
|
+
name: `check: ${question}`,
|
|
54
|
+
agentCheck: true,
|
|
55
|
+
description: question,
|
|
56
|
+
correction: question,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (typeof entry === 'string') {
|
|
60
|
+
const builtin = BUILTINS[entry];
|
|
61
|
+
if (!builtin) {
|
|
62
|
+
return {
|
|
63
|
+
name: entry,
|
|
64
|
+
run: entry,
|
|
65
|
+
correction: `Unknown built-in condition "${entry}". Use a known built-in or specify a "run:" command.`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
return { name: entry, run: builtin.run, correction: builtin.correction };
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
name: entry.name ?? entry.run,
|
|
72
|
+
run: entry.run,
|
|
73
|
+
correction: entry.correction ?? 'Fix the issue reported above, then re-run.',
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
function runCondition(name, command, cwd, correction) {
|
|
77
|
+
let result;
|
|
78
|
+
try {
|
|
79
|
+
result = spawnSync(command, {
|
|
80
|
+
shell: true,
|
|
81
|
+
cwd,
|
|
82
|
+
encoding: 'utf-8',
|
|
83
|
+
timeout: TIMEOUT_MS,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
return {
|
|
88
|
+
name,
|
|
89
|
+
passed: false,
|
|
90
|
+
output: err.message,
|
|
91
|
+
correction: 'Ensure the command exists and is executable from the project root.',
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
if (result.error) {
|
|
95
|
+
const isTimeout = result.error.message.includes('ETIMEDOUT') || result.error.message.includes('timeout');
|
|
96
|
+
return {
|
|
97
|
+
name,
|
|
98
|
+
passed: false,
|
|
99
|
+
output: result.error.message,
|
|
100
|
+
correction: isTimeout
|
|
101
|
+
? 'Check for hanging processes or increase the timeout.'
|
|
102
|
+
: 'Ensure the command exists and is executable from the project root.',
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const output = [result.stdout ?? '', result.stderr ?? ''].filter(Boolean).join('\n').trim();
|
|
106
|
+
const passed = result.status === 0;
|
|
107
|
+
// Exit code 127 = shell "command not found"
|
|
108
|
+
if (result.status === 127) {
|
|
109
|
+
return {
|
|
110
|
+
name,
|
|
111
|
+
passed: false,
|
|
112
|
+
output,
|
|
113
|
+
correction: 'Ensure the command exists and is executable from the project root.',
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
return { name, passed, output, correction: passed ? '' : correction };
|
|
117
|
+
}
|
|
118
|
+
/** Run the always-on DoD baseline: usecase.md exists, state=specified, format-valid. */
|
|
119
|
+
function runDodBaseline(implPath, cwd) {
|
|
120
|
+
const absImpl = resolve(cwd, implPath);
|
|
121
|
+
const behaviourDir = dirname(dirname(absImpl));
|
|
122
|
+
const usecasePath = join(behaviourDir, 'usecase.md');
|
|
123
|
+
const results = [];
|
|
124
|
+
if (!existsSync(usecasePath)) {
|
|
125
|
+
results.push({
|
|
126
|
+
name: 'baseline-usecase-exists',
|
|
127
|
+
passed: false,
|
|
128
|
+
output: `No usecase.md at ${usecasePath}`,
|
|
129
|
+
correction: 'The behaviour spec this implementation references is missing. Restore it before marking complete.',
|
|
130
|
+
});
|
|
131
|
+
return results; // cannot check further without usecase
|
|
132
|
+
}
|
|
133
|
+
const content = readFileSync(usecasePath, 'utf-8');
|
|
134
|
+
const parsed = parseMarkdown(usecasePath, content);
|
|
135
|
+
// state: specified or more advanced (implemented/tested) — must not have regressed to proposed/deprecated
|
|
136
|
+
const statusSection = parsed.sections.get('status');
|
|
137
|
+
const stateMatch = statusSection?.rawBody.match(/\*\*State:\*\*\s*(\S+)/);
|
|
138
|
+
const state = stateMatch?.[1] ?? 'unknown';
|
|
139
|
+
const acceptedStates = new Set(['specified', 'implemented', 'tested']);
|
|
140
|
+
const isReady = acceptedStates.has(state);
|
|
141
|
+
results.push({
|
|
142
|
+
name: 'baseline-state-specified',
|
|
143
|
+
passed: isReady,
|
|
144
|
+
output: isReady ? '' : `usecase.md state is '${state}'`,
|
|
145
|
+
correction: "Restore usecase.md to 'specified' (or more advanced) before marking implementation complete.",
|
|
146
|
+
});
|
|
147
|
+
// validate-format
|
|
148
|
+
const { config } = loadConfig(cwd);
|
|
149
|
+
const violations = validateFormat(parsed, 'behaviour', config).filter(v => v.type === 'error');
|
|
150
|
+
const formatPassed = violations.length === 0;
|
|
151
|
+
results.push({
|
|
152
|
+
name: 'baseline-validate-format',
|
|
153
|
+
passed: formatPassed,
|
|
154
|
+
output: formatPassed ? '' : violations.map(v => v.message).join('\n'),
|
|
155
|
+
correction: 'Fix format violations in usecase.md and re-run.',
|
|
156
|
+
});
|
|
157
|
+
return results;
|
|
158
|
+
}
|
|
159
|
+
// Buffer to account for the time between Date.now() and the writeFileSync mtime.
|
|
160
|
+
// Resolutions written within this window of impl.md's mtime are considered current.
|
|
161
|
+
const RESOLUTION_STALE_BUFFER_MS = 2_000;
|
|
162
|
+
/** Read agent-check resolutions recorded in impl.md's ## DoD Resolutions section.
|
|
163
|
+
* Returns an empty set if impl.md has been modified after the resolutions were written
|
|
164
|
+
* (indicating more implementation work happened since the agent resolved the checks). */
|
|
165
|
+
export function readResolutions(implPath, cwd) {
|
|
166
|
+
const absPath = resolve(cwd, implPath);
|
|
167
|
+
if (!existsSync(absPath))
|
|
168
|
+
return new Set();
|
|
169
|
+
const content = readFileSync(absPath, 'utf-8');
|
|
170
|
+
const parsed = parseMarkdown(absPath, content);
|
|
171
|
+
const section = parsed.sections.get('dod resolutions');
|
|
172
|
+
if (!section)
|
|
173
|
+
return new Set();
|
|
174
|
+
const entries = [];
|
|
175
|
+
for (const line of section.rawBody.split('\n')) {
|
|
176
|
+
const m = line.match(/^-\s+condition:\s+(.+?)\s+\|.*\|\s+resolved:\s+(.+)$/);
|
|
177
|
+
if (m) {
|
|
178
|
+
const ts = Date.parse(m[2].trim());
|
|
179
|
+
if (!isNaN(ts))
|
|
180
|
+
entries.push({ condition: m[1].trim(), timestampMs: ts });
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (entries.length === 0)
|
|
184
|
+
return new Set();
|
|
185
|
+
// If impl.md is already complete, resolutions are always valid — DoD already passed.
|
|
186
|
+
// Only check staleness for in-progress impls, where the developer may have changed
|
|
187
|
+
// implementation code after the agent recorded resolutions.
|
|
188
|
+
const isComplete = /\*\*State:\*\*\s*complete/.test(content);
|
|
189
|
+
if (!isComplete) {
|
|
190
|
+
const implMtimeMs = statSync(absPath).mtimeMs;
|
|
191
|
+
const latestResolutionMs = Math.max(...entries.map(e => e.timestampMs));
|
|
192
|
+
if (implMtimeMs > latestResolutionMs + RESOLUTION_STALE_BUFFER_MS) {
|
|
193
|
+
return new Set(); // stale — impl.md changed after resolutions were recorded
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return new Set(entries.map(e => e.condition));
|
|
197
|
+
}
|
|
198
|
+
export function runDodChecks(conditions, cwd, options) {
|
|
199
|
+
const results = [];
|
|
200
|
+
// Always run baseline when implPath is provided
|
|
201
|
+
if (options?.implPath) {
|
|
202
|
+
results.push(...runDodBaseline(options.implPath, cwd));
|
|
203
|
+
}
|
|
204
|
+
if (!conditions || conditions.length === 0) {
|
|
205
|
+
const configured = results.length > 0;
|
|
206
|
+
return { configured, results, allPassed: results.every(r => r.passed) };
|
|
207
|
+
}
|
|
208
|
+
// Read any agent-check resolutions recorded in impl.md
|
|
209
|
+
const resolvedChecks = options?.implPath
|
|
210
|
+
? readResolutions(options.implPath, cwd)
|
|
211
|
+
: new Set();
|
|
212
|
+
for (const entry of conditions) {
|
|
213
|
+
const resolved = resolveCondition(entry);
|
|
214
|
+
if (resolved.agentCheck) {
|
|
215
|
+
const isResolved = resolvedChecks.has(resolved.name);
|
|
216
|
+
results.push({
|
|
217
|
+
name: resolved.name,
|
|
218
|
+
passed: isResolved,
|
|
219
|
+
output: isResolved ? '' : `Agent check required: ${resolved.description}`,
|
|
220
|
+
correction: resolved.correction,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
results.push(runCondition(resolved.name, resolved.run, cwd, resolved.correction));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return {
|
|
228
|
+
configured: true,
|
|
229
|
+
results,
|
|
230
|
+
allPassed: results.every(r => r.passed),
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
//# sourceMappingURL=dod-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dod-runner.js","sourceRoot":"","sources":["../../src/core/dod-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Read agent-check resolutions from impl.md's ## DoR Resolutions section. */
|
|
2
|
+
export declare function readDorResolutions(implMdPath: string, cwd: string): Set<string>;
|
|
3
|
+
export interface DorResult {
|
|
4
|
+
name: string;
|
|
5
|
+
passed: boolean;
|
|
6
|
+
output: string;
|
|
7
|
+
correction: string;
|
|
8
|
+
}
|
|
9
|
+
export interface DorReport {
|
|
10
|
+
results: DorResult[];
|
|
11
|
+
allPassed: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Resolve the parent usecase.md from an impl.md path.
|
|
14
|
+
* impl.md lives at taproot/<intent>/<behaviour>/<impl>/impl.md
|
|
15
|
+
* usecase.md lives at taproot/<intent>/<behaviour>/usecase.md
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveUsecasePath(implMdPath: string, cwd: string): string;
|
|
18
|
+
export declare function runDorChecks(implMdPath: string, cwd: string): DorReport;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'fs';
|
|
2
|
+
import { join, dirname, resolve } from 'path';
|
|
3
|
+
import { spawnSync } from 'child_process';
|
|
4
|
+
import { parseMarkdown } from './markdown-parser.js';
|
|
5
|
+
import { loadConfig } from './config.js';
|
|
6
|
+
import { loadLanguagePack } from './language.js';
|
|
7
|
+
/** Resolve an English section key to its localised lowercase equivalent via the pack. */
|
|
8
|
+
function localizedSectionKey(englishKey, pack) {
|
|
9
|
+
if (!pack)
|
|
10
|
+
return englishKey;
|
|
11
|
+
const packKey = Object.keys(pack).find(k => k.toLowerCase() === englishKey);
|
|
12
|
+
if (!packKey)
|
|
13
|
+
return englishKey;
|
|
14
|
+
return pack[packKey].toLowerCase();
|
|
15
|
+
}
|
|
16
|
+
/** Read agent-check resolutions from impl.md's ## DoR Resolutions section. */
|
|
17
|
+
export function readDorResolutions(implMdPath, cwd) {
|
|
18
|
+
const absPath = resolve(cwd, implMdPath);
|
|
19
|
+
if (!existsSync(absPath))
|
|
20
|
+
return new Set();
|
|
21
|
+
const content = readFileSync(absPath, 'utf-8');
|
|
22
|
+
const parsed = parseMarkdown(absPath, content);
|
|
23
|
+
const section = parsed.sections.get('dor resolutions');
|
|
24
|
+
if (!section)
|
|
25
|
+
return new Set();
|
|
26
|
+
const conditions = new Set();
|
|
27
|
+
for (const line of section.rawBody.split('\n')) {
|
|
28
|
+
const m = line.match(/^-\s+condition:\s+(.+?)\s+\|/);
|
|
29
|
+
if (m)
|
|
30
|
+
conditions.add(m[1].trim());
|
|
31
|
+
}
|
|
32
|
+
return conditions;
|
|
33
|
+
}
|
|
34
|
+
/** Resolve the parent usecase.md from an impl.md path.
|
|
35
|
+
* impl.md lives at taproot/<intent>/<behaviour>/<impl>/impl.md
|
|
36
|
+
* usecase.md lives at taproot/<intent>/<behaviour>/usecase.md
|
|
37
|
+
*/
|
|
38
|
+
export function resolveUsecasePath(implMdPath, cwd) {
|
|
39
|
+
const absImpl = resolve(cwd, implMdPath);
|
|
40
|
+
const implDir = dirname(absImpl); // <impl>/
|
|
41
|
+
const behaviourDir = dirname(implDir); // <behaviour>/
|
|
42
|
+
return join(behaviourDir, 'usecase.md');
|
|
43
|
+
}
|
|
44
|
+
export function runDorChecks(implMdPath, cwd) {
|
|
45
|
+
const results = [];
|
|
46
|
+
const usecasePath = resolveUsecasePath(implMdPath, cwd);
|
|
47
|
+
// 1. usecase.md exists
|
|
48
|
+
if (!existsSync(usecasePath)) {
|
|
49
|
+
results.push({
|
|
50
|
+
name: 'usecase-exists',
|
|
51
|
+
passed: false,
|
|
52
|
+
output: `No usecase.md found at ${usecasePath}`,
|
|
53
|
+
correction: 'Create a behaviour spec with /tr-behaviour before committing an impl.md',
|
|
54
|
+
});
|
|
55
|
+
return { results, allPassed: false };
|
|
56
|
+
}
|
|
57
|
+
const content = readFileSync(usecasePath, 'utf-8');
|
|
58
|
+
const parsed = parseMarkdown(usecasePath, content);
|
|
59
|
+
// 2. state: specified
|
|
60
|
+
const statusSection = parsed.sections.get('status');
|
|
61
|
+
const stateMatch = statusSection?.rawBody.match(/\*\*State:\*\*\s*(\S+)/);
|
|
62
|
+
const state = stateMatch?.[1] ?? 'unknown';
|
|
63
|
+
const isSpecified = state === 'specified';
|
|
64
|
+
results.push({
|
|
65
|
+
name: 'state-specified',
|
|
66
|
+
passed: isSpecified,
|
|
67
|
+
output: isSpecified ? '' : `usecase.md state is '${state}'`,
|
|
68
|
+
correction: "Bring the spec to 'specified' (run /tr-review then /tr-refine) before starting implementation",
|
|
69
|
+
});
|
|
70
|
+
// 3. Required sections (localised via language pack)
|
|
71
|
+
const { config } = loadConfig(cwd);
|
|
72
|
+
const pack = config.language ? loadLanguagePack(config.language) : null;
|
|
73
|
+
const required = [
|
|
74
|
+
['actor', 'Actor'],
|
|
75
|
+
['preconditions', 'Preconditions'],
|
|
76
|
+
['main flow', 'Main Flow'],
|
|
77
|
+
['postconditions', 'Postconditions'],
|
|
78
|
+
];
|
|
79
|
+
for (const [englishKey, label] of required) {
|
|
80
|
+
const key = localizedSectionKey(englishKey, pack);
|
|
81
|
+
const present = parsed.sections.has(key);
|
|
82
|
+
results.push({
|
|
83
|
+
name: `section-${key.replace(' ', '-')}`,
|
|
84
|
+
passed: present,
|
|
85
|
+
output: present ? '' : `Missing ## ${label} section`,
|
|
86
|
+
correction: `Add a ## ${label} section to usecase.md`,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
// 4. Flow (Mermaid diagram)
|
|
90
|
+
const hasFlow = parsed.sections.has('flow');
|
|
91
|
+
results.push({
|
|
92
|
+
name: 'flow-diagram',
|
|
93
|
+
passed: hasFlow,
|
|
94
|
+
output: hasFlow ? '' : 'Missing ## Flow section with Mermaid diagram',
|
|
95
|
+
correction: 'Add a ## Flow section with a mermaid diagram to usecase.md',
|
|
96
|
+
});
|
|
97
|
+
// 5. Related behaviours
|
|
98
|
+
const hasRelated = parsed.sections.has('related');
|
|
99
|
+
results.push({
|
|
100
|
+
name: 'related-behaviours',
|
|
101
|
+
passed: hasRelated,
|
|
102
|
+
output: hasRelated ? '' : 'Missing ## Related section',
|
|
103
|
+
correction: 'Add a ## Related section documenting related behaviours to usecase.md',
|
|
104
|
+
});
|
|
105
|
+
// 6. Configured definitionOfReady conditions
|
|
106
|
+
const dorConditions = config.definitionOfReady;
|
|
107
|
+
if (dorConditions && dorConditions.length > 0) {
|
|
108
|
+
const resolvedChecks = readDorResolutions(implMdPath, cwd);
|
|
109
|
+
for (const entry of dorConditions) {
|
|
110
|
+
if (typeof entry === 'object' && 'check' in entry) {
|
|
111
|
+
const question = entry['check'];
|
|
112
|
+
const name = `check: ${question}`;
|
|
113
|
+
const isResolved = resolvedChecks.has(name);
|
|
114
|
+
results.push({
|
|
115
|
+
name,
|
|
116
|
+
passed: isResolved,
|
|
117
|
+
output: isResolved ? '' : `Agent check required: ${question}`,
|
|
118
|
+
correction: `Reason about the question and record a resolution in impl.md under ## DoR Resolutions: "- condition: ${name} | note: <reasoning> | resolved: <ISO-timestamp>"`,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
else if (typeof entry === 'object' && ('document-current' in entry || 'check-if-affected' in entry || 'check-if-affected-by' in entry)) {
|
|
122
|
+
// Other agent-check types — treat as unresolvable shell-side, report as agent check
|
|
123
|
+
const key = 'document-current' in entry ? 'document-current' : 'check-if-affected' in entry ? 'check-if-affected' : 'check-if-affected-by';
|
|
124
|
+
const value = entry[key];
|
|
125
|
+
const name = `${key}: ${value}`;
|
|
126
|
+
const isResolved = resolvedChecks.has(name);
|
|
127
|
+
results.push({
|
|
128
|
+
name,
|
|
129
|
+
passed: isResolved,
|
|
130
|
+
output: isResolved ? '' : `Agent check required: ${value}`,
|
|
131
|
+
correction: `Resolve this agent check and record it in impl.md under ## DoR Resolutions.`,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
else if (typeof entry === 'string') {
|
|
135
|
+
const r = spawnSync(entry, { shell: true, cwd, encoding: 'utf-8', timeout: 30_000 });
|
|
136
|
+
results.push({
|
|
137
|
+
name: entry,
|
|
138
|
+
passed: r.status === 0,
|
|
139
|
+
output: [r.stdout, r.stderr].filter(Boolean).join('\n').trim(),
|
|
140
|
+
correction: 'Fix the issue reported above, then re-commit',
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
else if ('run' in entry) {
|
|
144
|
+
const r = spawnSync(entry.run, { shell: true, cwd, encoding: 'utf-8', timeout: 30_000 });
|
|
145
|
+
results.push({
|
|
146
|
+
name: entry.name ?? entry.run,
|
|
147
|
+
passed: r.status === 0,
|
|
148
|
+
output: [r.stdout, r.stderr].filter(Boolean).join('\n').trim(),
|
|
149
|
+
correction: entry.correction ?? 'Fix the issue reported above, then re-commit',
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return { results, allPassed: results.every(r => r.passed) };
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=dor-runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dor-runner.js","sourceRoot":"","sources":["../../src/core/dor-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { readdirSync, statSync } from 'fs';
|
|
2
|
+
import { join, relative, basename } from 'path';
|
|
3
|
+
const MARKER_FILES = {
|
|
4
|
+
'intent.md': 'intent',
|
|
5
|
+
'usecase.md': 'behaviour',
|
|
6
|
+
'impl.md': 'impl',
|
|
7
|
+
};
|
|
8
|
+
const DEFAULT_EXCLUDE = new Set(['_brainstorms', 'skills', '.git', 'node_modules', 'dist']);
|
|
9
|
+
export function walkHierarchy(rootPath, options = {}) {
|
|
10
|
+
const excludeDirs = options.excludeDirs ?? DEFAULT_EXCLUDE;
|
|
11
|
+
return walkDir(rootPath, rootPath, null, 0, excludeDirs);
|
|
12
|
+
}
|
|
13
|
+
function walkDir(dirPath, rootPath, parent, depth, excludeDirs) {
|
|
14
|
+
let entries;
|
|
15
|
+
try {
|
|
16
|
+
entries = readdirSync(dirPath);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
entries = [];
|
|
20
|
+
}
|
|
21
|
+
const markerFiles = [];
|
|
22
|
+
const subdirs = [];
|
|
23
|
+
for (const entry of entries) {
|
|
24
|
+
if (MARKER_FILES[entry]) {
|
|
25
|
+
markerFiles.push(entry);
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const fullPath = join(dirPath, entry);
|
|
29
|
+
if (statSync(fullPath).isDirectory() && !excludeDirs.has(entry)) {
|
|
30
|
+
subdirs.push(entry);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// skip unreadable entries
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
const node = {
|
|
38
|
+
absolutePath: dirPath,
|
|
39
|
+
relativePath: relative(rootPath, dirPath) || '.',
|
|
40
|
+
name: basename(dirPath),
|
|
41
|
+
marker: null,
|
|
42
|
+
markerFiles,
|
|
43
|
+
children: [],
|
|
44
|
+
parent,
|
|
45
|
+
depth,
|
|
46
|
+
hasDescendantWithMarker: false,
|
|
47
|
+
};
|
|
48
|
+
// Determine marker (first found wins; duplicates are reported as violations)
|
|
49
|
+
if (markerFiles.length > 0) {
|
|
50
|
+
node.marker = MARKER_FILES[markerFiles[0] ?? ''] ?? null;
|
|
51
|
+
}
|
|
52
|
+
// Recurse into subdirectories (post-order: children first)
|
|
53
|
+
for (const subdir of subdirs.sort()) {
|
|
54
|
+
const child = walkDir(join(dirPath, subdir), rootPath, node, depth + 1, excludeDirs);
|
|
55
|
+
node.children.push(child);
|
|
56
|
+
if (child.marker !== null || child.hasDescendantWithMarker) {
|
|
57
|
+
node.hasDescendantWithMarker = true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return node;
|
|
61
|
+
}
|
|
62
|
+
export function flattenTree(root) {
|
|
63
|
+
const result = [];
|
|
64
|
+
const stack = [root];
|
|
65
|
+
while (stack.length > 0) {
|
|
66
|
+
const node = stack.pop();
|
|
67
|
+
result.push(node);
|
|
68
|
+
for (const child of [...node.children].reverse()) {
|
|
69
|
+
stack.push(child);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=fs-walker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-walker.js","sourceRoot":"","sources":["../../src/core/fs-walker.ts"],"names":[],"mappings":"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"}
|