forgecraft-mcp 1.7.0 → 1.8.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 +79 -0
- package/dist/registry/remote-gates.d.ts +16 -0
- package/dist/registry/remote-gates.d.ts.map +1 -1
- package/dist/registry/remote-gates.js +56 -0
- package/dist/registry/remote-gates.js.map +1 -1
- package/dist/registry/sentinel-domain-map.d.ts.map +1 -1
- package/dist/registry/sentinel-domain-map.js +16 -9
- package/dist/registry/sentinel-domain-map.js.map +1 -1
- package/dist/registry/sentinel-renderer.d.ts +13 -8
- package/dist/registry/sentinel-renderer.d.ts.map +1 -1
- package/dist/registry/sentinel-renderer.js +440 -162
- package/dist/registry/sentinel-renderer.js.map +1 -1
- package/dist/shared/harness-budget.d.ts +49 -0
- package/dist/shared/harness-budget.d.ts.map +1 -0
- package/dist/shared/harness-budget.js +123 -0
- package/dist/shared/harness-budget.js.map +1 -0
- package/dist/shared/hook-installer.d.ts.map +1 -1
- package/dist/shared/hook-installer.js +2 -1
- package/dist/shared/hook-installer.js.map +1 -1
- package/dist/tools/close-cycle-helpers.d.ts +9 -0
- package/dist/tools/close-cycle-helpers.d.ts.map +1 -1
- package/dist/tools/close-cycle-helpers.js.map +1 -1
- package/dist/tools/close-cycle.d.ts.map +1 -1
- package/dist/tools/close-cycle.js +29 -0
- package/dist/tools/close-cycle.js.map +1 -1
- package/dist/tools/contribute-gate.d.ts +30 -4
- package/dist/tools/contribute-gate.d.ts.map +1 -1
- package/dist/tools/contribute-gate.js +180 -66
- package/dist/tools/contribute-gate.js.map +1 -1
- package/dist/tools/gate-genesis.d.ts +47 -0
- package/dist/tools/gate-genesis.d.ts.map +1 -0
- package/dist/tools/gate-genesis.js +241 -0
- package/dist/tools/gate-genesis.js.map +1 -0
- package/dist/tools/learning-graph.d.ts +31 -0
- package/dist/tools/learning-graph.d.ts.map +1 -0
- package/dist/tools/learning-graph.js +266 -0
- package/dist/tools/learning-graph.js.map +1 -0
- package/dist/tools/setup-artifact-writers.d.ts +15 -3
- package/dist/tools/setup-artifact-writers.d.ts.map +1 -1
- package/dist/tools/setup-artifact-writers.js +149 -13
- package/dist/tools/setup-artifact-writers.js.map +1 -1
- package/dist/tools/setup-phase2.d.ts +9 -0
- package/dist/tools/setup-phase2.d.ts.map +1 -1
- package/dist/tools/setup-phase2.js +13 -0
- package/dist/tools/setup-phase2.js.map +1 -1
- package/dist/tools/setup-project.d.ts +6 -0
- package/dist/tools/setup-project.d.ts.map +1 -1
- package/dist/tools/setup-project.js +21 -4
- package/dist/tools/setup-project.js.map +1 -1
- package/package.json +99 -98
- package/templates/api/instructions.yaml +50 -188
- package/templates/universal/instructions.yaml +194 -1003
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate-genesis.js","sourceRoot":"","sources":["../../src/tools/gate-genesis.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* learning-graph.csv emission — the harness as a literal Compact Knowledge Graph.
|
|
3
|
+
*
|
|
4
|
+
* Serializes the project's knowledge structure as a learning graph per
|
|
5
|
+
* Yarmoluk & McCreary's Definition 1: G = (C, E, T, τ) in the 4-column CSV
|
|
6
|
+
* schema `ConceptID,ConceptLabel,Dependencies,TaxonomyID` (Dependencies =
|
|
7
|
+
* pipe-delimited prerequisite ConceptIDs; the pair (C,E) must be a DAG).
|
|
8
|
+
*
|
|
9
|
+
* Concepts are the harness artifacts; edges encode reading order ("understand
|
|
10
|
+
* X before Y"): the routing table, the doc obligation table, and @gs-links.
|
|
11
|
+
* Empirical basis: the KX experiment (experiments/kx) measured CNT-routed
|
|
12
|
+
* retrieval at RDS 1.7–5.6× over dump/search baselines — the CKG economics.
|
|
13
|
+
*
|
|
14
|
+
* This is a DERIVED artifact (Living Documentation): regenerated on every
|
|
15
|
+
* setup/refresh, never hand-edited. It is machine data, not session prose —
|
|
16
|
+
* it is not part of the routed CNT and does not count against the harness budget.
|
|
17
|
+
*/
|
|
18
|
+
export interface LearningGraphResult {
|
|
19
|
+
readonly written: boolean;
|
|
20
|
+
readonly concepts: number;
|
|
21
|
+
readonly edges: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Emit docs/learning-graph.csv from the project's harness artifacts.
|
|
25
|
+
* Always regenerates (derived artifact). Returns counts for reporting.
|
|
26
|
+
*
|
|
27
|
+
* @param projectDir - Project root
|
|
28
|
+
* @returns written flag + concept/edge counts (written=false when no harness)
|
|
29
|
+
*/
|
|
30
|
+
export declare function emitLearningGraph(projectDir: string): LearningGraphResult;
|
|
31
|
+
//# sourceMappingURL=learning-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"learning-graph.d.ts","sourceRoot":"","sources":["../../src/tools/learning-graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAsBD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,mBAAmB,CAmOzE"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* learning-graph.csv emission — the harness as a literal Compact Knowledge Graph.
|
|
3
|
+
*
|
|
4
|
+
* Serializes the project's knowledge structure as a learning graph per
|
|
5
|
+
* Yarmoluk & McCreary's Definition 1: G = (C, E, T, τ) in the 4-column CSV
|
|
6
|
+
* schema `ConceptID,ConceptLabel,Dependencies,TaxonomyID` (Dependencies =
|
|
7
|
+
* pipe-delimited prerequisite ConceptIDs; the pair (C,E) must be a DAG).
|
|
8
|
+
*
|
|
9
|
+
* Concepts are the harness artifacts; edges encode reading order ("understand
|
|
10
|
+
* X before Y"): the routing table, the doc obligation table, and @gs-links.
|
|
11
|
+
* Empirical basis: the KX experiment (experiments/kx) measured CNT-routed
|
|
12
|
+
* retrieval at RDS 1.7–5.6× over dump/search baselines — the CKG economics.
|
|
13
|
+
*
|
|
14
|
+
* This is a DERIVED artifact (Living Documentation): regenerated on every
|
|
15
|
+
* setup/refresh, never hand-edited. It is machine data, not session prose —
|
|
16
|
+
* it is not part of the routed CNT and does not count against the harness budget.
|
|
17
|
+
*/
|
|
18
|
+
import { existsSync, readFileSync, writeFileSync, readdirSync } from "fs";
|
|
19
|
+
import { join, relative } from "path";
|
|
20
|
+
/** Taxonomy categories (τ): coarse artifact classes, per LG convention (≤16). */
|
|
21
|
+
const TAXONOMY = {
|
|
22
|
+
CNT: "CNT", // navigation tree branches
|
|
23
|
+
DOC: "DOC", // core documents (PRD, TechSpec, status, manifest)
|
|
24
|
+
ARCH: "ARCH", // architecture branch docs
|
|
25
|
+
ADR: "ADR", // decision records
|
|
26
|
+
UC: "UC", // use cases
|
|
27
|
+
SPEC: "SPEC", // spec decision records
|
|
28
|
+
GATE: "GATE", // quality gates
|
|
29
|
+
STD: "STD", // domain standards
|
|
30
|
+
CODE: "CODE", // source files carrying @gs-links
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Emit docs/learning-graph.csv from the project's harness artifacts.
|
|
34
|
+
* Always regenerates (derived artifact). Returns counts for reporting.
|
|
35
|
+
*
|
|
36
|
+
* @param projectDir - Project root
|
|
37
|
+
* @returns written flag + concept/edge counts (written=false when no harness)
|
|
38
|
+
*/
|
|
39
|
+
export function emitLearningGraph(projectDir) {
|
|
40
|
+
const rootMd = join(projectDir, "CLAUDE.md");
|
|
41
|
+
if (!existsSync(rootMd))
|
|
42
|
+
return { written: false, concepts: 0, edges: 0 };
|
|
43
|
+
const nodes = [];
|
|
44
|
+
const byLabel = new Map();
|
|
45
|
+
let nextId = 1;
|
|
46
|
+
const addNode = (label, taxonomy) => {
|
|
47
|
+
const clean = sanitizeLabel(label);
|
|
48
|
+
const existing = byLabel.get(clean);
|
|
49
|
+
if (existing)
|
|
50
|
+
return existing;
|
|
51
|
+
const node = {
|
|
52
|
+
id: nextId++,
|
|
53
|
+
label: clean,
|
|
54
|
+
taxonomy,
|
|
55
|
+
deps: new Set(),
|
|
56
|
+
};
|
|
57
|
+
nodes.push(node);
|
|
58
|
+
byLabel.set(clean, node);
|
|
59
|
+
return node;
|
|
60
|
+
};
|
|
61
|
+
const addEdge = (from, prerequisite) => {
|
|
62
|
+
// Self-references and forward cycles are excluded by construction:
|
|
63
|
+
// prerequisites are always added before their dependents, and we never
|
|
64
|
+
// point a node at itself.
|
|
65
|
+
if (from.id !== prerequisite.id)
|
|
66
|
+
from.deps.add(prerequisite.id);
|
|
67
|
+
};
|
|
68
|
+
// ── Foundational layer: CNT root + always-load ──────────────────────
|
|
69
|
+
const root = addNode("CLAUDE.md (CNT root)", TAXONOMY.CNT);
|
|
70
|
+
const constitution = maybeNode(projectDir, ".claude/constitution.md", "Constitution", TAXONOMY.CNT, addNode);
|
|
71
|
+
const corrections = maybeNode(projectDir, ".claude/corrections.md", "Corrections Log", TAXONOMY.CNT, addNode);
|
|
72
|
+
for (const n of [constitution, corrections])
|
|
73
|
+
if (n)
|
|
74
|
+
addEdge(n, root);
|
|
75
|
+
// CNT branches depend on the root (read root first, then descend)
|
|
76
|
+
const lifecycle = maybeNode(projectDir, ".claude/lifecycle.md", "Lifecycle", TAXONOMY.CNT, addNode);
|
|
77
|
+
const routesCode = maybeNode(projectDir, ".claude/routes/code.md", "Code Routes", TAXONOMY.CNT, addNode);
|
|
78
|
+
const routesDocs = maybeNode(projectDir, ".claude/routes/docs.md", "Docs Routes", TAXONOMY.CNT, addNode);
|
|
79
|
+
for (const n of [lifecycle, routesCode, routesDocs])
|
|
80
|
+
if (n)
|
|
81
|
+
addEdge(n, root);
|
|
82
|
+
// ── Core documents ───────────────────────────────────────────────────
|
|
83
|
+
const prd = maybeNode(projectDir, "docs/PRD.md", "PRD", TAXONOMY.DOC, addNode);
|
|
84
|
+
const techSpec = maybeNode(projectDir, "docs/TechSpec.md", "TechSpec", TAXONOMY.DOC, addNode);
|
|
85
|
+
const status = maybeNode(projectDir, "docs/status.md", "Status", TAXONOMY.DOC, addNode);
|
|
86
|
+
const manifest = maybeNode(projectDir, "docs/manifest.yaml", "Docs Manifest", TAXONOMY.DOC, addNode);
|
|
87
|
+
if (techSpec && prd)
|
|
88
|
+
addEdge(techSpec, prd); // architecture derives from spec
|
|
89
|
+
if (status && root)
|
|
90
|
+
addEdge(status, root);
|
|
91
|
+
if (manifest && root)
|
|
92
|
+
addEdge(manifest, root);
|
|
93
|
+
// ── Architecture branch docs (depend on TechSpec when present) ──────
|
|
94
|
+
const archDir = join(projectDir, "docs", "architecture");
|
|
95
|
+
if (existsSync(archDir)) {
|
|
96
|
+
for (const f of readdirSync(archDir).filter((x) => x.endsWith(".md"))) {
|
|
97
|
+
const n = addNode(`Architecture: ${f.replace(/\.md$/, "")}`, TAXONOMY.ARCH);
|
|
98
|
+
if (techSpec)
|
|
99
|
+
addEdge(n, techSpec);
|
|
100
|
+
else if (prd)
|
|
101
|
+
addEdge(n, prd);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// ── ADRs (decisions derive from the spec context) ───────────────────
|
|
105
|
+
const adrNodesByFile = new Map();
|
|
106
|
+
for (const adrDir of ["docs/adrs/active", "docs/adrs"]) {
|
|
107
|
+
const dir = join(projectDir, ...adrDir.split("/"));
|
|
108
|
+
if (!existsSync(dir))
|
|
109
|
+
continue;
|
|
110
|
+
for (const f of readdirSync(dir).filter((x) => /^ADR-.*\.md$/i.test(x) || /^\d{4}-.*\.md$/.test(x))) {
|
|
111
|
+
const label = `ADR: ${f.replace(/\.md$/, "")}`;
|
|
112
|
+
if (byLabel.has(sanitizeLabel(label)))
|
|
113
|
+
continue;
|
|
114
|
+
const n = addNode(label, TAXONOMY.ADR);
|
|
115
|
+
adrNodesByFile.set(`${adrDir}/${f}`.replace("docs/adrs/active", "docs/adrs"), n);
|
|
116
|
+
adrNodesByFile.set(`docs/adrs/${f}`, n);
|
|
117
|
+
if (prd)
|
|
118
|
+
addEdge(n, prd);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// ── Use cases (behavioral contracts derive from the PRD) ────────────
|
|
122
|
+
const ucNodesById = new Map();
|
|
123
|
+
const ucFile = join(projectDir, "docs", "use-cases.md");
|
|
124
|
+
if (existsSync(ucFile)) {
|
|
125
|
+
for (const line of readFileSync(ucFile, "utf-8").split("\n")) {
|
|
126
|
+
const m = /^## (UC-\d+):\s*(.+)$/.exec(line.trim());
|
|
127
|
+
if (!m)
|
|
128
|
+
continue;
|
|
129
|
+
const n = addNode(`${m[1]}: ${m[2]}`, TAXONOMY.UC);
|
|
130
|
+
ucNodesById.set(m[1], n);
|
|
131
|
+
if (prd)
|
|
132
|
+
addEdge(n, prd);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// ── Spec decision records (derive from PRD + their use cases) ───────
|
|
136
|
+
const specNodesByFile = new Map();
|
|
137
|
+
const specsDir = join(projectDir, "docs", "specs");
|
|
138
|
+
if (existsSync(specsDir)) {
|
|
139
|
+
for (const f of readdirSync(specsDir).filter((x) => x.endsWith(".md") && x !== "README.md")) {
|
|
140
|
+
const n = addNode(`Spec: ${f.replace(/\.md$/, "")}`, TAXONOMY.SPEC);
|
|
141
|
+
specNodesByFile.set(`docs/specs/${f}`, n);
|
|
142
|
+
if (prd)
|
|
143
|
+
addEdge(n, prd);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// ── Quality gates (mandated by the constitution) ────────────────────
|
|
147
|
+
for (const gatesSub of ["active", "registry"]) {
|
|
148
|
+
const base = join(projectDir, ".forgecraft", "gates", gatesSub);
|
|
149
|
+
if (!existsSync(base))
|
|
150
|
+
continue;
|
|
151
|
+
walkYaml(base, (full) => {
|
|
152
|
+
const rel = relative(base, full).split("\\").join("/");
|
|
153
|
+
const id = rel
|
|
154
|
+
.replace(/\.ya?ml$/, "")
|
|
155
|
+
.split("/")
|
|
156
|
+
.pop();
|
|
157
|
+
const label = `Gate: ${id}`;
|
|
158
|
+
if (byLabel.has(sanitizeLabel(label)))
|
|
159
|
+
return;
|
|
160
|
+
const n = addNode(label, TAXONOMY.GATE);
|
|
161
|
+
if (constitution)
|
|
162
|
+
addEdge(n, constitution);
|
|
163
|
+
else
|
|
164
|
+
addEdge(n, root);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
// ── Standards (expand the constitution per domain) ──────────────────
|
|
168
|
+
const stdDir = join(projectDir, ".claude", "standards");
|
|
169
|
+
if (existsSync(stdDir)) {
|
|
170
|
+
for (const f of readdirSync(stdDir).filter((x) => x.endsWith(".md"))) {
|
|
171
|
+
const n = addNode(`Standards: ${f.replace(/\.md$/, "")}`, TAXONOMY.STD);
|
|
172
|
+
if (constitution)
|
|
173
|
+
addEdge(n, constitution);
|
|
174
|
+
else
|
|
175
|
+
addEdge(n, root);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
// ── @gs-links: code nodes depend on their governing documents ───────
|
|
179
|
+
const srcDir = join(projectDir, "src");
|
|
180
|
+
if (existsSync(srcDir)) {
|
|
181
|
+
walkSource(srcDir, (full) => {
|
|
182
|
+
const head = readFileSync(full, "utf-8").slice(0, 2000);
|
|
183
|
+
const m = /@gs-links:\s*(.+)/.exec(head);
|
|
184
|
+
if (!m)
|
|
185
|
+
return;
|
|
186
|
+
const rel = relative(projectDir, full).split("\\").join("/");
|
|
187
|
+
const codeNode = addNode(`Code: ${rel}`, TAXONOMY.CODE);
|
|
188
|
+
for (const linkRaw of m[1].split(",")) {
|
|
189
|
+
const link = linkRaw
|
|
190
|
+
.trim()
|
|
191
|
+
.replace(/\*\/?\s*$/, "")
|
|
192
|
+
.trim();
|
|
193
|
+
const target = specNodesByFile.get(link) ??
|
|
194
|
+
adrNodesByFile.get(link) ??
|
|
195
|
+
resolveLooseLink(link, ucNodesById, byLabel);
|
|
196
|
+
if (target)
|
|
197
|
+
addEdge(codeNode, target);
|
|
198
|
+
}
|
|
199
|
+
if (codeNode.deps.size === 0 && routesCode)
|
|
200
|
+
addEdge(codeNode, routesCode);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
// ── Serialize (4-column CSV per Definition 1) ────────────────────────
|
|
204
|
+
const lines = ["ConceptID,ConceptLabel,Dependencies,TaxonomyID"];
|
|
205
|
+
let edgeCount = 0;
|
|
206
|
+
for (const n of nodes) {
|
|
207
|
+
const deps = [...n.deps].sort((a, b) => a - b).join("|");
|
|
208
|
+
edgeCount += n.deps.size;
|
|
209
|
+
lines.push(`${n.id},${csvField(n.label)},${deps},${n.taxonomy}`);
|
|
210
|
+
}
|
|
211
|
+
const outPath = join(projectDir, "docs", "learning-graph.csv");
|
|
212
|
+
writeFileSync(outPath, lines.join("\n") + "\n", "utf-8");
|
|
213
|
+
return { written: true, concepts: nodes.length, edges: edgeCount };
|
|
214
|
+
}
|
|
215
|
+
// ── Helpers ───────────────────────────────────────────────────────────
|
|
216
|
+
function maybeNode(projectDir, rel, label, taxonomy, addNode) {
|
|
217
|
+
return existsSync(join(projectDir, ...rel.split("/")))
|
|
218
|
+
? addNode(label, taxonomy)
|
|
219
|
+
: null;
|
|
220
|
+
}
|
|
221
|
+
function walkYaml(dir, visit) {
|
|
222
|
+
for (const e of readdirSync(dir, { withFileTypes: true })) {
|
|
223
|
+
const full = join(dir, e.name);
|
|
224
|
+
if (e.isDirectory())
|
|
225
|
+
walkYaml(full, visit);
|
|
226
|
+
else if (/\.ya?ml$/.test(e.name))
|
|
227
|
+
visit(full);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function walkSource(dir, visit) {
|
|
231
|
+
for (const e of readdirSync(dir, { withFileTypes: true })) {
|
|
232
|
+
const full = join(dir, e.name);
|
|
233
|
+
if (e.isDirectory())
|
|
234
|
+
walkSource(full, visit);
|
|
235
|
+
else if (/\.(ts|tsx|js|py)$/.test(e.name) &&
|
|
236
|
+
!/\.test\.|\.spec\./.test(e.name))
|
|
237
|
+
visit(full);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function resolveLooseLink(link, ucNodesById, byLabel) {
|
|
241
|
+
const uc = /UC-\d+/.exec(link);
|
|
242
|
+
if (uc)
|
|
243
|
+
return ucNodesById.get(uc[0]);
|
|
244
|
+
if (/use-cases\.md/.test(link)) {
|
|
245
|
+
// generic use-cases link → first UC node if any (closest stable anchor)
|
|
246
|
+
return ucNodesById.values().next().value;
|
|
247
|
+
}
|
|
248
|
+
const adr = /ADR-[\w-]+/.exec(link);
|
|
249
|
+
if (adr) {
|
|
250
|
+
for (const [label, node] of byLabel) {
|
|
251
|
+
if (label.includes(adr[0]))
|
|
252
|
+
return node;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return undefined;
|
|
256
|
+
}
|
|
257
|
+
function sanitizeLabel(label) {
|
|
258
|
+
return label
|
|
259
|
+
.replace(/[,\r\n"]+/g, " ")
|
|
260
|
+
.replace(/\s+/g, " ")
|
|
261
|
+
.trim();
|
|
262
|
+
}
|
|
263
|
+
function csvField(s) {
|
|
264
|
+
return /[,"]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s;
|
|
265
|
+
}
|
|
266
|
+
//# sourceMappingURL=learning-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"learning-graph.js","sourceRoot":"","sources":["../../src/tools/learning-graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,7 +40,7 @@ export declare function initGitRepo(projectDir: string): string;
|
|
|
40
40
|
* @param brownfield - Whether this is a brownfield project
|
|
41
41
|
* @returns True if the file was written or updated
|
|
42
42
|
*/
|
|
43
|
-
export declare function writeForgeYaml(projectDir: string, projectName: string, tags: string[], decisions: CascadeDecision[], sensitiveData?: boolean, brownfield?: boolean): boolean;
|
|
43
|
+
export declare function writeForgeYaml(projectDir: string, projectName: string, tags: string[], decisions: CascadeDecision[], sensitiveData?: boolean, brownfield?: boolean, language?: string): boolean;
|
|
44
44
|
/**
|
|
45
45
|
* If forgecraft.yaml has an experiment block with an id but no group,
|
|
46
46
|
* sets experiment.group = 'gs'.
|
|
@@ -69,15 +69,17 @@ export interface UseCaseInput {
|
|
|
69
69
|
}
|
|
70
70
|
/**
|
|
71
71
|
* Write docs/PRD.md using AI-extracted fields when available.
|
|
72
|
+
* When AI fields are absent but a raw spec exists (CLI-only path, no AI in
|
|
73
|
+
* the loop), the source spec is embedded so its content is never lost.
|
|
72
74
|
* Never overwrites an existing PRD.
|
|
73
75
|
*
|
|
74
76
|
* @param projectDir - Project root
|
|
75
77
|
* @param projectName - Project name for the PRD title
|
|
76
78
|
* @param aiFields - AI-extracted problem, users, criteria
|
|
77
|
-
* @param
|
|
79
|
+
* @param specContent - Raw spec text — embedded when AI fields are absent
|
|
78
80
|
* @returns True if a new PRD was written
|
|
79
81
|
*/
|
|
80
|
-
export declare function writePrd(projectDir: string, projectName: string, aiFields: AiExtractedFields,
|
|
82
|
+
export declare function writePrd(projectDir: string, projectName: string, aiFields: AiExtractedFields, specContent: string | null): boolean;
|
|
81
83
|
/**
|
|
82
84
|
* Write docs/use-cases.md from structured spec-derived use cases when available,
|
|
83
85
|
* or from AI-extracted fields as a fallback. Never overwrites an existing use-cases.md.
|
|
@@ -155,6 +157,16 @@ export declare function writeProjectManifest(projectDir: string, projectName: st
|
|
|
155
157
|
* @returns True if the file was written
|
|
156
158
|
*/
|
|
157
159
|
export declare function writeStatusMd(projectDir: string, projectName: string): boolean;
|
|
160
|
+
/**
|
|
161
|
+
* Write docs/architecture/ CNT branch stubs — four scoped nodes for
|
|
162
|
+
* layers, modules, data-model, and integrations.
|
|
163
|
+
* Never overwrites existing files.
|
|
164
|
+
*
|
|
165
|
+
* @param projectDir - Project root
|
|
166
|
+
* @param projectName - Project name
|
|
167
|
+
* @returns Array of relative paths written
|
|
168
|
+
*/
|
|
169
|
+
export declare function writeArchitectureCntStubs(projectDir: string, projectName: string): string[];
|
|
158
170
|
/**
|
|
159
171
|
* Load cascade decisions from forgecraft.yaml (convenience re-used in writers).
|
|
160
172
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setup-artifact-writers.d.ts","sourceRoot":"","sources":["../../src/tools/setup-artifact-writers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,OAAO,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AAItE;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEtD;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAQ5D;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAwBtD;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EAAE,EACd,SAAS,EAAE,eAAe,EAAE,EAC5B,aAAa,CAAC,EAAE,OAAO,EACvB,UAAU,CAAC,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"setup-artifact-writers.d.ts","sourceRoot":"","sources":["../../src/tools/setup-artifact-writers.ts"],"names":[],"mappings":"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"}
|
|
@@ -69,7 +69,7 @@ export function initGitRepo(projectDir) {
|
|
|
69
69
|
* @param brownfield - Whether this is a brownfield project
|
|
70
70
|
* @returns True if the file was written or updated
|
|
71
71
|
*/
|
|
72
|
-
export function writeForgeYaml(projectDir, projectName, tags, decisions, sensitiveData, brownfield) {
|
|
72
|
+
export function writeForgeYaml(projectDir, projectName, tags, decisions, sensitiveData, brownfield, language) {
|
|
73
73
|
const yamlPath = join(projectDir, "forgecraft.yaml");
|
|
74
74
|
let config;
|
|
75
75
|
if (existsSync(yamlPath)) {
|
|
@@ -82,6 +82,8 @@ export function writeForgeYaml(projectDir, projectName, tags, decisions, sensiti
|
|
|
82
82
|
}
|
|
83
83
|
else {
|
|
84
84
|
config = { projectName, tags: tags.length > 0 ? tags : ["UNIVERSAL"] };
|
|
85
|
+
if (language && language !== "typescript")
|
|
86
|
+
config["language"] = language;
|
|
85
87
|
if (sensitiveData !== undefined)
|
|
86
88
|
config["sensitiveData"] = sensitiveData;
|
|
87
89
|
if (brownfield === true)
|
|
@@ -127,23 +129,25 @@ export function setExperimentGroupIfMissing(projectDir) {
|
|
|
127
129
|
}
|
|
128
130
|
/**
|
|
129
131
|
* Write docs/PRD.md using AI-extracted fields when available.
|
|
132
|
+
* When AI fields are absent but a raw spec exists (CLI-only path, no AI in
|
|
133
|
+
* the loop), the source spec is embedded so its content is never lost.
|
|
130
134
|
* Never overwrites an existing PRD.
|
|
131
135
|
*
|
|
132
136
|
* @param projectDir - Project root
|
|
133
137
|
* @param projectName - Project name for the PRD title
|
|
134
138
|
* @param aiFields - AI-extracted problem, users, criteria
|
|
135
|
-
* @param
|
|
139
|
+
* @param specContent - Raw spec text — embedded when AI fields are absent
|
|
136
140
|
* @returns True if a new PRD was written
|
|
137
141
|
*/
|
|
138
|
-
export function writePrd(projectDir, projectName, aiFields,
|
|
142
|
+
export function writePrd(projectDir, projectName, aiFields, specContent) {
|
|
139
143
|
const prdPath = join(projectDir, "docs", "PRD.md");
|
|
140
144
|
if (existsSync(prdPath))
|
|
141
145
|
return false;
|
|
142
146
|
mkdirSync(join(projectDir, "docs"), { recursive: true });
|
|
143
|
-
writeFileSync(prdPath, buildPrdContent(projectName, aiFields), "utf-8");
|
|
147
|
+
writeFileSync(prdPath, buildPrdContent(projectName, aiFields, specContent), "utf-8");
|
|
144
148
|
return true;
|
|
145
149
|
}
|
|
146
|
-
function buildPrdContent(projectName, aiFields) {
|
|
150
|
+
function buildPrdContent(projectName, aiFields, specContent) {
|
|
147
151
|
const fill = (placeholder) => `<!-- FILL: ${placeholder} -->`;
|
|
148
152
|
const listOrFill = (csv, placeholder) => csv
|
|
149
153
|
? csv
|
|
@@ -151,14 +155,24 @@ function buildPrdContent(projectName, aiFields) {
|
|
|
151
155
|
.map((s) => `- ${s.trim()}`)
|
|
152
156
|
.join("\n")
|
|
153
157
|
: fill(placeholder);
|
|
154
|
-
|
|
158
|
+
const sections = [
|
|
155
159
|
`# ${projectName}\n`,
|
|
156
160
|
`## Problem\n\n${aiFields.problemStatement ?? fill("describe the problem this project solves")}\n`,
|
|
157
161
|
`## Users\n\n${listOrFill(aiFields.primaryUsers, "list the target users or personas")}\n`,
|
|
158
162
|
`## Success Criteria\n\n${listOrFill(aiFields.successCriteria, "define measurable success criteria")}\n`,
|
|
159
163
|
`## Components\n\n${fill("list the major components or modules")}\n`,
|
|
160
164
|
`## External Systems\n\n${fill("list external APIs, services, or integrations")}\n`,
|
|
161
|
-
]
|
|
165
|
+
];
|
|
166
|
+
// No AI extraction happened but the user provided a spec — preserve it.
|
|
167
|
+
// The sections above stay as FILL markers; the source is the ground truth
|
|
168
|
+
// the AI (or human) extracts from on the next pass.
|
|
169
|
+
const noAiFields = !aiFields.problemStatement &&
|
|
170
|
+
!aiFields.primaryUsers &&
|
|
171
|
+
!aiFields.successCriteria;
|
|
172
|
+
if (noAiFields && specContent?.trim()) {
|
|
173
|
+
sections.push(`## Source Specification\n`, `> Original spec provided at setup. Extract the sections above from this`, `> content, then remove this section once the PRD is fully derived.\n`, specContent.trim(), ``);
|
|
174
|
+
}
|
|
175
|
+
return sections.join("\n");
|
|
162
176
|
}
|
|
163
177
|
/**
|
|
164
178
|
* Write docs/use-cases.md from structured spec-derived use cases when available,
|
|
@@ -933,9 +947,9 @@ export function writeStatusMd(projectDir, projectName) {
|
|
|
933
947
|
`> Update this file at the end of each session. The Session Loop Invariant in CLAUDE.md`,
|
|
934
948
|
`> references this file for any unresolved items.`,
|
|
935
949
|
``,
|
|
936
|
-
`##
|
|
950
|
+
`## Completed (this session)`,
|
|
937
951
|
``,
|
|
938
|
-
`<!-- FILL:
|
|
952
|
+
`<!-- FILL: what was finished in the most recent session -->`,
|
|
939
953
|
``,
|
|
940
954
|
`## In Progress`,
|
|
941
955
|
``,
|
|
@@ -945,17 +959,139 @@ export function writeStatusMd(projectDir, projectName) {
|
|
|
945
959
|
``,
|
|
946
960
|
`<!-- FILL: first roadmap item or pending task — be specific enough to resume without re-reading everything -->`,
|
|
947
961
|
``,
|
|
948
|
-
`##
|
|
962
|
+
`## Decisions Made (this session)`,
|
|
949
963
|
``,
|
|
950
|
-
`<!-- FILL:
|
|
964
|
+
`<!-- FILL: key decisions made — link to ADRs where they exist -->`,
|
|
951
965
|
``,
|
|
952
|
-
`##
|
|
966
|
+
`## Blockers / Dependencies`,
|
|
953
967
|
``,
|
|
954
|
-
`<!-- FILL:
|
|
968
|
+
`<!-- FILL: known blockers, open questions, or external dependencies -->`,
|
|
955
969
|
].join("\n");
|
|
956
970
|
writeFileSync(statusPath, content, "utf-8");
|
|
957
971
|
return true;
|
|
958
972
|
}
|
|
973
|
+
// ── Architecture CNT stub writer ─────────────────────────────────────
|
|
974
|
+
/**
|
|
975
|
+
* Write docs/architecture/ CNT branch stubs — four scoped nodes for
|
|
976
|
+
* layers, modules, data-model, and integrations.
|
|
977
|
+
* Never overwrites existing files.
|
|
978
|
+
*
|
|
979
|
+
* @param projectDir - Project root
|
|
980
|
+
* @param projectName - Project name
|
|
981
|
+
* @returns Array of relative paths written
|
|
982
|
+
*/
|
|
983
|
+
export function writeArchitectureCntStubs(projectDir, projectName) {
|
|
984
|
+
const archDir = join(projectDir, "docs", "architecture");
|
|
985
|
+
mkdirSync(archDir, { recursive: true });
|
|
986
|
+
const written = [];
|
|
987
|
+
const stubs = [
|
|
988
|
+
{
|
|
989
|
+
file: "layers.md",
|
|
990
|
+
content: [
|
|
991
|
+
`# Architecture: Layer Diagram & Boundary Rules`,
|
|
992
|
+
``,
|
|
993
|
+
`> CNT node — read when: changing or reviewing layer structure, adding a new module, or diagnosing layer violations.`,
|
|
994
|
+
``,
|
|
995
|
+
`## Layers`,
|
|
996
|
+
``,
|
|
997
|
+
`<!-- FILL: document the layer stack (e.g. Entry → Dispatch → Handlers → Domain → Adapters) -->`,
|
|
998
|
+
``,
|
|
999
|
+
`## Boundary Rules`,
|
|
1000
|
+
``,
|
|
1001
|
+
`| From | To | Allowed | Rule |`,
|
|
1002
|
+
`|---|---|---|---|`,
|
|
1003
|
+
`| <!-- FILL --> | <!-- FILL --> | ✅/❌ | <!-- FILL --> |`,
|
|
1004
|
+
``,
|
|
1005
|
+
`## Key Invariants`,
|
|
1006
|
+
``,
|
|
1007
|
+
`<!-- FILL: list the non-negotiable structural invariants (e.g. "no circular imports", "domain has zero external imports") -->`,
|
|
1008
|
+
].join("\n"),
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
file: "modules.md",
|
|
1012
|
+
content: [
|
|
1013
|
+
`# Architecture: Module Registry`,
|
|
1014
|
+
``,
|
|
1015
|
+
`> CNT node — read when: adding a new module, understanding file ownership, or debugging an unexpected dependency.`,
|
|
1016
|
+
``,
|
|
1017
|
+
`## Core Modules`,
|
|
1018
|
+
``,
|
|
1019
|
+
`| Module | File | Owns | Does NOT own |`,
|
|
1020
|
+
`|---|---|---|---|`,
|
|
1021
|
+
`| <!-- FILL: module name --> | <!-- FILL: path --> | <!-- FILL: responsibility --> | <!-- FILL: what it delegates --> |`,
|
|
1022
|
+
``,
|
|
1023
|
+
`## Shared Utilities`,
|
|
1024
|
+
``,
|
|
1025
|
+
`<!-- FILL: list shared utility modules and their purpose -->`,
|
|
1026
|
+
``,
|
|
1027
|
+
`## Addition Protocol`,
|
|
1028
|
+
``,
|
|
1029
|
+
`When adding a new module: <!-- FILL: define the decision tree for where new code goes -->`,
|
|
1030
|
+
].join("\n"),
|
|
1031
|
+
},
|
|
1032
|
+
{
|
|
1033
|
+
file: "data-model.md",
|
|
1034
|
+
content: [
|
|
1035
|
+
`# Architecture: Data Model & Schema`,
|
|
1036
|
+
``,
|
|
1037
|
+
`> CNT node — read when: changing the data model, adding entities, modifying schema, or updating the ERD.`,
|
|
1038
|
+
``,
|
|
1039
|
+
`## Core Entities`,
|
|
1040
|
+
``,
|
|
1041
|
+
`<!-- FILL: describe primary entities with their fields and invariants -->`,
|
|
1042
|
+
``,
|
|
1043
|
+
`## Entity Relationships`,
|
|
1044
|
+
``,
|
|
1045
|
+
`\`\`\`mermaid`,
|
|
1046
|
+
`erDiagram`,
|
|
1047
|
+
` %% FILL: replace with actual entities and relationships`,
|
|
1048
|
+
` ENTITY_A ||--o{ ENTITY_B : "has"`,
|
|
1049
|
+
`\`\`\``,
|
|
1050
|
+
``,
|
|
1051
|
+
`## Schema Notes`,
|
|
1052
|
+
``,
|
|
1053
|
+
`<!-- FILL: naming conventions, migration strategy, DB / persistence approach -->`,
|
|
1054
|
+
``,
|
|
1055
|
+
`## DB / State`,
|
|
1056
|
+
``,
|
|
1057
|
+
`<!-- FILL: where does state live? (DB, file system, in-memory, external service) -->`,
|
|
1058
|
+
`<!-- If using a DB: describe the migration strategy and any ORM/query builder choices -->`,
|
|
1059
|
+
].join("\n"),
|
|
1060
|
+
},
|
|
1061
|
+
{
|
|
1062
|
+
file: "integrations.md",
|
|
1063
|
+
content: [
|
|
1064
|
+
`# Architecture: External Integrations`,
|
|
1065
|
+
``,
|
|
1066
|
+
`> CNT node — read when: adding a new external dependency, changing a protocol, or understanding network access.`,
|
|
1067
|
+
``,
|
|
1068
|
+
`## Integration Map`,
|
|
1069
|
+
``,
|
|
1070
|
+
`| Integration | Direction | When | Protocol |`,
|
|
1071
|
+
`|---|---|---|---|`,
|
|
1072
|
+
`| <!-- FILL: name --> | Inbound/Outbound | <!-- FILL: when --> | <!-- FILL: HTTP/gRPC/stdio/etc --> |`,
|
|
1073
|
+
``,
|
|
1074
|
+
`## File System Contract`,
|
|
1075
|
+
``,
|
|
1076
|
+
`<!-- FILL: what paths does this project read/write? what is out of bounds? -->`,
|
|
1077
|
+
``,
|
|
1078
|
+
`## Network Policy`,
|
|
1079
|
+
``,
|
|
1080
|
+
`<!-- FILL: which operations require network access? which must work offline? -->`,
|
|
1081
|
+
].join("\n"),
|
|
1082
|
+
},
|
|
1083
|
+
];
|
|
1084
|
+
for (const stub of stubs) {
|
|
1085
|
+
const filePath = join(archDir, stub.file);
|
|
1086
|
+
if (!existsSync(filePath)) {
|
|
1087
|
+
writeFileSync(filePath, stub.content, "utf-8");
|
|
1088
|
+
written.push(`docs/architecture/${stub.file}`);
|
|
1089
|
+
}
|
|
1090
|
+
}
|
|
1091
|
+
// Suppress unused variable warning
|
|
1092
|
+
void projectName;
|
|
1093
|
+
return written;
|
|
1094
|
+
}
|
|
959
1095
|
// ── Load cascade decisions ────────────────────────────────────────────
|
|
960
1096
|
/**
|
|
961
1097
|
* Load cascade decisions from forgecraft.yaml (convenience re-used in writers).
|