ai-spector 0.1.4 → 0.1.6
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 +5 -2
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/graphify-update.d.ts +7 -0
- package/dist/commands/graphify-update.d.ts.map +1 -0
- package/dist/commands/graphify-update.js +86 -0
- package/dist/commands/graphify-update.js.map +1 -0
- package/dist/graph/InMemoryGraph.d.ts.map +1 -1
- package/dist/graph/InMemoryGraph.js +17 -4
- package/dist/graph/InMemoryGraph.js.map +1 -1
- package/dist/graph/merge.d.ts.map +1 -1
- package/dist/graph/merge.js +32 -4
- package/dist/graph/merge.js.map +1 -1
- package/package.json +5 -2
- package/scaffold/.ai-spector/.docflow/config/analyze.graphify.json +7 -0
- package/scaffold/.ai-spector/.docflow/config/dag.basic-design.graph-seeds.json +45 -0
- package/scaffold/.ai-spector/.docflow/config/dag.srs.graph-seeds.json +28 -0
- package/scaffold/.ai-spector/.docflow/extract/projection-patch.example.json +22 -0
- package/scaffold/.cursor/commands/_cli-failures.md +12 -0
- package/scaffold/.cursor/commands/_generate-graph.md +141 -0
- package/scaffold/.cursor/commands/_graph.md +6 -1
- package/scaffold/.cursor/commands/_workflow.md +3 -3
- package/scaffold/.cursor/commands/analyze.md +24 -10
- package/scaffold/.cursor/commands/generate-basic-design.md +141 -12
- package/scaffold/.cursor/commands/generate-detail-design.md +1 -1
- package/scaffold/.cursor/commands/generate-srs.md +137 -26
- package/scaffold/.cursor/commands/sync-graph.md +3 -0
- package/scaffold/.cursor/skills/ai-spector/SKILL.md +7 -4
- package/scaffold/docs/data-source/README.md +1 -1
package/README.md
CHANGED
|
@@ -26,8 +26,8 @@ Put your source files in `docs/data-source/`, open the folder in Cursor, turn on
|
|
|
26
26
|
| **`/analyze`** | Builds the graph skeleton, extracts knowledge (Graphify), merges use cases & features into the graph, validates |
|
|
27
27
|
| **`/visualize-graph`** | Opens a browser report to inspect the graph and `knowledge.json` |
|
|
28
28
|
| **`/validate-graph`** | Checks the graph before generation |
|
|
29
|
-
| **`/generate-srs`** |
|
|
30
|
-
| **`/generate-basic-design`** |
|
|
29
|
+
| **`/generate-srs`** | All SRS, listed files, or a short request (agent confirms scope) — graph-first, by DAG waves |
|
|
30
|
+
| **`/generate-basic-design`** | All, listed files, or request (confirm) — graph + SRS context, by waves |
|
|
31
31
|
| **`/generate-detail-design`** | Detail design from the graph |
|
|
32
32
|
| **`/graph-impact <id>`** | Shows what to regenerate after you change something |
|
|
33
33
|
|
|
@@ -121,11 +121,13 @@ The CLI is the engine; Cursor commands wrap it.
|
|
|
121
121
|
|-----|--------|
|
|
122
122
|
| [workflow-overview.md](docs/design/workflow-overview.md) | Graph-centric design |
|
|
123
123
|
| [traceability-graph-redesign.md](docs/design/traceability-graph-redesign.md) | Schema and roadmap |
|
|
124
|
+
| [testing.md](docs/testing.md) | Vitest layout, commands, mocking |
|
|
124
125
|
|
|
125
126
|
**Build from source:**
|
|
126
127
|
|
|
127
128
|
```bash
|
|
128
129
|
npm install && npm run build
|
|
130
|
+
npm test
|
|
129
131
|
npm run init:example
|
|
130
132
|
```
|
|
131
133
|
|
|
@@ -135,6 +137,7 @@ npm run init:example
|
|
|
135
137
|
|---------|---------|
|
|
136
138
|
| `ai-spector init` | Scaffold project |
|
|
137
139
|
| `ai-spector analyze` | Section tree in graph |
|
|
140
|
+
| `ai-spector graphify update` | Graphify code graph → `.ai-spector/.../graphify-out/` (sets `GRAPHIFY_OUT`) |
|
|
138
141
|
| `ai-spector graph merge --from-knowledge` | Domain nodes from staging |
|
|
139
142
|
| `ai-spector graph validate` | Rules check |
|
|
140
143
|
| `ai-spector graph visualize [--open]` | HTML report |
|
package/dist/cli.js
CHANGED
|
@@ -12,6 +12,7 @@ import { runGraphQuery } from "./commands/graph-query.js";
|
|
|
12
12
|
import { runGraphImpact } from "./commands/graph-impact.js";
|
|
13
13
|
import { runGraphMerge } from "./commands/graph-merge.js";
|
|
14
14
|
import { runGraphVisualize } from "./commands/graph-visualize.js";
|
|
15
|
+
import { runGraphifyUpdate } from "./commands/graphify-update.js";
|
|
15
16
|
const program = new Command();
|
|
16
17
|
program
|
|
17
18
|
.name("ai-spector")
|
|
@@ -42,6 +43,20 @@ program
|
|
|
42
43
|
.action(async (opts, cmd) => {
|
|
43
44
|
await runAnalyzePrep(projectRootOpt(cmd), { merge: opts.merge });
|
|
44
45
|
});
|
|
46
|
+
const graphify = program
|
|
47
|
+
.command("graphify")
|
|
48
|
+
.description("Graphify CLI wrappers (sets GRAPHIFY_OUT — do not use graphify update --graph)");
|
|
49
|
+
graphify
|
|
50
|
+
.command("update [path]")
|
|
51
|
+
.description("Run graphify update on data-source with output under .ai-spector/.docflow/graph/graphify-out")
|
|
52
|
+
.option("--keep-stale", "Do not delete docs/data-source/graphify-out if Graphify wrote it there by mistake")
|
|
53
|
+
.action(async (path, opts, cmd) => {
|
|
54
|
+
await runGraphifyUpdate({
|
|
55
|
+
root: projectRootOpt(cmd),
|
|
56
|
+
sourcePath: path,
|
|
57
|
+
removeStaleOutput: !opts.keepStale,
|
|
58
|
+
});
|
|
59
|
+
});
|
|
45
60
|
const graph = program.command("graph").description("Traceability graph operations");
|
|
46
61
|
graph
|
|
47
62
|
.command("registry")
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphify-update.d.ts","sourceRoot":"","sources":["../../src/commands/graphify-update.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,qBAAqB;IACpC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAgDD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6DlF"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { rm } from "node:fs/promises";
|
|
3
|
+
import { join, resolve } from "node:path";
|
|
4
|
+
import { loadDocflowConfig } from "../config/load.js";
|
|
5
|
+
import { pathExists, readJson } from "../util/fs.js";
|
|
6
|
+
function runCommand(command, args, cwd, env) {
|
|
7
|
+
return new Promise((resolvePromise, reject) => {
|
|
8
|
+
const child = spawn(command, args, {
|
|
9
|
+
cwd,
|
|
10
|
+
env,
|
|
11
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
12
|
+
});
|
|
13
|
+
let stdout = "";
|
|
14
|
+
let stderr = "";
|
|
15
|
+
child.stdout?.on("data", (chunk) => {
|
|
16
|
+
stdout += chunk.toString();
|
|
17
|
+
});
|
|
18
|
+
child.stderr?.on("data", (chunk) => {
|
|
19
|
+
stderr += chunk.toString();
|
|
20
|
+
});
|
|
21
|
+
child.on("error", reject);
|
|
22
|
+
child.on("close", (code) => {
|
|
23
|
+
resolvePromise({
|
|
24
|
+
exitCode: code ?? 1,
|
|
25
|
+
stdout,
|
|
26
|
+
stderr,
|
|
27
|
+
});
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
async function runGraphifyCli(args, cwd, env) {
|
|
32
|
+
try {
|
|
33
|
+
const direct = await runCommand("graphify", args, cwd, env);
|
|
34
|
+
return { ...direct, command: `graphify ${args.join(" ")}` };
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
const uvArgs = ["tool", "run", "--from", "graphifyy", "graphify", ...args];
|
|
38
|
+
const viaUv = await runCommand("uv", uvArgs, cwd, env);
|
|
39
|
+
return { ...viaUv, command: `uv ${uvArgs.join(" ")}` };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export async function runGraphifyUpdate(opts) {
|
|
43
|
+
const { root: projectRoot } = await loadDocflowConfig(opts.root);
|
|
44
|
+
const configPath = join(projectRoot, ".ai-spector/.docflow/config/analyze.graphify.json");
|
|
45
|
+
const config = await readJson(configPath);
|
|
46
|
+
const g = config.graphify ?? {};
|
|
47
|
+
const sourceRel = opts.sourcePath ?? g.defaultDataSource ?? "docs/data-source";
|
|
48
|
+
const sourcePath = resolve(projectRoot, sourceRel);
|
|
49
|
+
const outputPath = resolve(projectRoot, g.outputPath ?? ".ai-spector/.docflow/graph/graphify-out");
|
|
50
|
+
if (!(await pathExists(sourcePath))) {
|
|
51
|
+
throw new Error(`Data source not found: ${sourcePath}`);
|
|
52
|
+
}
|
|
53
|
+
const env = {
|
|
54
|
+
...process.env,
|
|
55
|
+
GRAPHIFY_OUT: outputPath,
|
|
56
|
+
};
|
|
57
|
+
console.log(`Graphify update: ${sourceRel}`);
|
|
58
|
+
console.log(` GRAPHIFY_OUT → ${g.outputPath ?? outputPath}`);
|
|
59
|
+
console.log(" (do not pass --graph to graphify update — use GRAPHIFY_OUT instead)");
|
|
60
|
+
console.log("");
|
|
61
|
+
const result = await runGraphifyCli(["update", sourceRel], projectRoot, env);
|
|
62
|
+
if (result.stdout.trim()) {
|
|
63
|
+
console.log(result.stdout.trimEnd());
|
|
64
|
+
}
|
|
65
|
+
if (result.stderr.trim()) {
|
|
66
|
+
console.error(result.stderr.trimEnd());
|
|
67
|
+
}
|
|
68
|
+
if (result.exitCode !== 0) {
|
|
69
|
+
console.error("");
|
|
70
|
+
console.error(`Failed: ${result.command} (exit ${result.exitCode})`);
|
|
71
|
+
throw new Error(`graphify update failed with exit code ${result.exitCode}`);
|
|
72
|
+
}
|
|
73
|
+
const graphJson = join(outputPath, "graph.json");
|
|
74
|
+
if (!(await pathExists(graphJson))) {
|
|
75
|
+
throw new Error(`Expected graph.json at ${g.graphJsonPath ?? graphJson} after update — check Graphify install (graphify or uv + graphifyy)`);
|
|
76
|
+
}
|
|
77
|
+
const staleOut = join(sourcePath, "graphify-out");
|
|
78
|
+
if (opts.removeStaleOutput !== false && (await pathExists(staleOut))) {
|
|
79
|
+
await rm(staleOut, { recursive: true, force: true });
|
|
80
|
+
console.log("");
|
|
81
|
+
console.log(`Removed stale ${sourceRel}/graphify-out/ (wrong default location)`);
|
|
82
|
+
}
|
|
83
|
+
console.log("");
|
|
84
|
+
console.log(`OK — ${g.graphJsonPath ?? ".ai-spector/.docflow/graph/graphify-out/graph.json"}`);
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=graphify-update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphify-update.js","sourceRoot":"","sources":["../../src/commands/graphify-update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAiBrD,SAAS,UAAU,CACjB,OAAe,EACf,IAAc,EACd,GAAW,EACX,GAAsB;IAEtB,OAAO,IAAI,OAAO,CAAC,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE;QAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE;YACjC,GAAG;YACH,GAAG;YACH,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QACH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YACzC,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC7B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC1B,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;YACzB,cAAc,CAAC;gBACb,QAAQ,EAAE,IAAI,IAAI,CAAC;gBACnB,MAAM;gBACN,MAAM;aACP,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,cAAc,CAC3B,IAAc,EACd,GAAW,EACX,GAAsB;IAEtB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAC5D,OAAO,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,YAAY,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC;QAC3E,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QACvD,OAAO,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;IACzD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAA2B;IACjE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACjE,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,mDAAmD,CAAC,CAAC;IAC1F,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAwB,UAAU,CAAC,CAAC;IACjE,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC;IAEhC,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC,iBAAiB,IAAI,kBAAkB,CAAC;IAC/E,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,OAAO,CACxB,WAAW,EACX,CAAC,CAAC,UAAU,IAAI,yCAAyC,CAC1D,CAAC;IAEF,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,0BAA0B,UAAU,EAAE,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,GAAG,GAAG;QACV,GAAG,OAAO,CAAC,GAAG;QACd,YAAY,EAAE,UAAU;KACzB,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,oBAAoB,SAAS,EAAE,CAAC,CAAC;IAC7C,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC,UAAU,IAAI,UAAU,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC;IACrF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,CAAC;IAE7E,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACvC,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,WAAW,MAAM,CAAC,OAAO,UAAU,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrE,MAAM,IAAI,KAAK,CAAC,yCAAyC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CACpB,UAAU,EACV,YAAY,CACb,CAAC;IACF,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,0BAA0B,CAAC,CAAC,aAAa,IAAI,SAAS,qEAAqE,CAC5H,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;IAClD,IAAI,IAAI,CAAC,iBAAiB,KAAK,KAAK,IAAI,CAAC,MAAM,UAAU,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QACrE,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,iBAAiB,SAAS,yCAAyC,CAAC,CAAC;IACnF,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,aAAa,IAAI,oDAAoD,EAAE,CAAC,CAAC;AACjG,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InMemoryGraph.d.ts","sourceRoot":"","sources":["../../src/graph/InMemoryGraph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE5F,qBAAa,aAAa;IACxB,QAAQ,CAAC,SAAS,yBAAgC;IAClD,QAAQ,CAAC,QAAQ,2BAAkC;IACnD,QAAQ,CAAC,OAAO,2BAAkC;IAElD,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,GAAG,aAAa;
|
|
1
|
+
{"version":3,"file":"InMemoryGraph.d.ts","sourceRoot":"","sources":["../../src/graph/InMemoryGraph.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE5F,qBAAa,aAAa;IACxB,QAAQ,CAAC,SAAS,yBAAgC;IAClD,QAAQ,CAAC,QAAQ,2BAAkC;IACnD,QAAQ,CAAC,OAAO,2BAAkC;IAElD,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,iBAAiB,GAAG,aAAa;IAiBnD,MAAM,IAAI,iBAAiB;IAQ3B,uEAAuE;IACvE,mBAAmB,IAAI,iBAAiB;IAmBxC,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAS9B,6EAA6E;IAC7E,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS;IAelD,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,MAAM;IAIhC,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO;IAYjC,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAU9B,eAAe,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO;IAezC,SAAS,CACP,EAAE,EAAE,MAAM,EACV,SAAS,EAAE,KAAK,GAAG,IAAI,GAAG,MAAM,EAChC,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EACvB,KAAK,SAAI,GACR,GAAG,CAAC,MAAM,CAAC;IAsCd,iBAAiB,IAAI,eAAe,EAAE;CA+DvC"}
|
|
@@ -8,7 +8,10 @@ export class InMemoryGraph {
|
|
|
8
8
|
g.addNode(node);
|
|
9
9
|
}
|
|
10
10
|
for (const edge of data.edges) {
|
|
11
|
-
if (!g.nodesById.has(edge.from)
|
|
11
|
+
if (!g.nodesById.has(edge.from)) {
|
|
12
|
+
throw new Error(`Edge references missing node: ${edge.from} -> ${edge.to}`);
|
|
13
|
+
}
|
|
14
|
+
if (edge.type !== "rendersTo" && !g.nodesById.has(edge.to)) {
|
|
12
15
|
throw new Error(`Edge references missing node: ${edge.from} -> ${edge.to}`);
|
|
13
16
|
}
|
|
14
17
|
g.addEdge(edge);
|
|
@@ -78,14 +81,24 @@ export class InMemoryGraph {
|
|
|
78
81
|
}
|
|
79
82
|
addEdge(edge) {
|
|
80
83
|
this.outEdges.get(edge.from).push(edge);
|
|
81
|
-
this.inEdges.get(edge.to)
|
|
84
|
+
const inbound = this.inEdges.get(edge.to);
|
|
85
|
+
if (inbound) {
|
|
86
|
+
inbound.push(edge);
|
|
87
|
+
}
|
|
88
|
+
else if (edge.type !== "rendersTo") {
|
|
89
|
+
throw new Error(`Edge references missing target node: ${edge.from} -> ${edge.to}`);
|
|
90
|
+
}
|
|
82
91
|
}
|
|
83
92
|
addEdgeIfAbsent(edge) {
|
|
84
93
|
if (this.hasEdge(edge)) {
|
|
85
94
|
return false;
|
|
86
95
|
}
|
|
87
|
-
if (!this.nodesById.has(edge.from)
|
|
88
|
-
throw new Error(`Edge references missing node: ${edge.from}
|
|
96
|
+
if (!this.nodesById.has(edge.from)) {
|
|
97
|
+
throw new Error(`Edge references missing source node: ${edge.from}`);
|
|
98
|
+
}
|
|
99
|
+
// rendersTo targets a markdown path, not a graph node id
|
|
100
|
+
if (edge.type !== "rendersTo" && !this.nodesById.has(edge.to)) {
|
|
101
|
+
throw new Error(`Edge references missing target node: ${edge.from} -> ${edge.to}`);
|
|
89
102
|
}
|
|
90
103
|
this.addEdge(edge);
|
|
91
104
|
return true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InMemoryGraph.js","sourceRoot":"","sources":["../../src/graph/InMemoryGraph.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,aAAa;IACf,SAAS,GAAG,IAAI,GAAG,EAAqB,CAAC;IACzC,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC1C,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IAElD,MAAM,CAAC,IAAI,CAAC,IAAuB;QACjC,MAAM,CAAC,GAAG,IAAI,aAAa,EAAE,CAAC;QAC9B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClB,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"InMemoryGraph.js","sourceRoot":"","sources":["../../src/graph/InMemoryGraph.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/graph/merge.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAWnD,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAMxF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../src/graph/merge.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAWnD,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,UAAU,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAMxF;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,GAAG,WAAW,CAyCjF"}
|
package/dist/graph/merge.js
CHANGED
|
@@ -21,10 +21,20 @@ export function mergePatch(graph, patch) {
|
|
|
21
21
|
nodesSkipped: 0,
|
|
22
22
|
};
|
|
23
23
|
for (const node of patch.nodes) {
|
|
24
|
-
if (
|
|
24
|
+
if (node.type === "section" || node.type === "table" || node.type === "diagram") {
|
|
25
25
|
stats.nodesSkipped++;
|
|
26
26
|
continue;
|
|
27
27
|
}
|
|
28
|
+
if (node.type === "document") {
|
|
29
|
+
const outcome = graph.upsertNode(node);
|
|
30
|
+
if (outcome === "created") {
|
|
31
|
+
stats.nodesCreated++;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
stats.nodesUpdated++;
|
|
35
|
+
}
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
28
38
|
if (!DOMAIN_TYPES.has(node.type)) {
|
|
29
39
|
throw new Error(`Patch node ${node.id} has unsupported type: ${node.type}`);
|
|
30
40
|
}
|
|
@@ -46,6 +56,16 @@ export function mergePatch(graph, patch) {
|
|
|
46
56
|
}
|
|
47
57
|
function assertMergeEdgeAllowed(graph, edge) {
|
|
48
58
|
const from = graph.nodesById.get(edge.from);
|
|
59
|
+
// rendersTo: document/section/domain -> repo-relative file path (to is not a node id)
|
|
60
|
+
if (edge.type === "rendersTo") {
|
|
61
|
+
if (!from) {
|
|
62
|
+
throw new Error(`rendersTo missing source node: ${edge.from}`);
|
|
63
|
+
}
|
|
64
|
+
if (from.type === "document" || from.type === "section" || DOMAIN_TYPES.has(from.type)) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
throw new Error(`rendersTo source must be document, section, or domain node: ${edge.from}`);
|
|
68
|
+
}
|
|
49
69
|
const to = graph.nodesById.get(edge.to);
|
|
50
70
|
if (!from) {
|
|
51
71
|
throw new Error(`Merge edge missing source node: ${edge.from}`);
|
|
@@ -54,9 +74,17 @@ function assertMergeEdgeAllowed(graph, edge) {
|
|
|
54
74
|
throw new Error(`Merge edge missing target node: ${edge.to}`);
|
|
55
75
|
}
|
|
56
76
|
if (STRUCTURE_TYPES.has(to.type)) {
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
77
|
+
const allowedToStructure = new Set([
|
|
78
|
+
"listedIn",
|
|
79
|
+
"definedIn",
|
|
80
|
+
"describedIn",
|
|
81
|
+
"references",
|
|
82
|
+
"dependsOn",
|
|
83
|
+
"contains",
|
|
84
|
+
"partOf",
|
|
85
|
+
]);
|
|
86
|
+
if (!allowedToStructure.has(edge.type)) {
|
|
87
|
+
throw new Error(`Edge ${edge.type} cannot target structure node ${edge.to}`);
|
|
60
88
|
}
|
|
61
89
|
}
|
|
62
90
|
}
|
package/dist/graph/merge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/graph/merge.ts"],"names":[],"mappings":"AAIA,MAAM,eAAe,GAAG,IAAI,GAAG,CAAW,CAAC,UAAU,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;AACvF,MAAM,YAAY,GAAG,IAAI,GAAG,CAAW;IACrC,OAAO;IACP,SAAS;IACT,SAAS;IACT,aAAa;IACb,YAAY;CACb,CAAC,CAAC;AAcH,MAAM,UAAU,cAAc,CAAC,KAA2C;IACxE,OAAO;QACL,OAAO,EAAE,CAAC;QACV,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;QACxB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;KACzB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAoB,EAAE,KAAmB;IAClE,MAAM,KAAK,GAAe;QACxB,YAAY,EAAE,CAAC;QACf,YAAY,EAAE,CAAC;QACf,UAAU,EAAE,CAAC;QACb,YAAY,EAAE,CAAC;KAChB,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,
|
|
1
|
+
{"version":3,"file":"merge.js","sourceRoot":"","sources":["../../src/graph/merge.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-spector",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Cursor-first documentation workflow: traceability graph, SRS/basic/detail design templates, and ai-spector CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -41,6 +41,8 @@
|
|
|
41
41
|
"ai-spector": "./dist/cli.js"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"test:watch": "vitest",
|
|
44
46
|
"build": "tsc",
|
|
45
47
|
"prepack": "npm run build",
|
|
46
48
|
"prepublishOnly": "npm run build",
|
|
@@ -60,6 +62,7 @@
|
|
|
60
62
|
},
|
|
61
63
|
"devDependencies": {
|
|
62
64
|
"@types/node": "^22.10.0",
|
|
63
|
-
"typescript": "^5.7.2"
|
|
65
|
+
"typescript": "^5.7.2",
|
|
66
|
+
"vitest": "^4.1.7"
|
|
64
67
|
}
|
|
65
68
|
}
|
|
@@ -5,6 +5,13 @@
|
|
|
5
5
|
"outputPath": ".ai-spector/.docflow/graph/graphify-out",
|
|
6
6
|
"graphJsonPath": ".ai-spector/.docflow/graph/graphify-out/graph.json",
|
|
7
7
|
"defaultDataSource": "docs/data-source",
|
|
8
|
+
"cli": {
|
|
9
|
+
"update": "ai-spector graphify update",
|
|
10
|
+
"env": {
|
|
11
|
+
"GRAPHIFY_OUT": ".ai-spector/.docflow/graph/graphify-out"
|
|
12
|
+
},
|
|
13
|
+
"forbidden": "Never use: graphify update <path> --graph <file> (unknown option). Use GRAPHIFY_OUT or ai-spector graphify update."
|
|
14
|
+
},
|
|
8
15
|
"include": [
|
|
9
16
|
"docs/data-source"
|
|
10
17
|
],
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"description": "Map dag.basic-design.json node ids to graph query seeds and projection document ids",
|
|
4
|
+
"seeds": {
|
|
5
|
+
"bd.db-design": "doc.srs.5-data-requirements",
|
|
6
|
+
"bd.list-api": "doc.srs.6-external-interfaces",
|
|
7
|
+
"bd.detail-api": "doc.srs.4-system-features",
|
|
8
|
+
"bd.list-screen": "doc.srs.4-system-features",
|
|
9
|
+
"bd.detail-screen": "doc.srs.4-system-features"
|
|
10
|
+
},
|
|
11
|
+
"perDomain": {
|
|
12
|
+
"perEndpoint": {
|
|
13
|
+
"parentDagId": "bd.detail-api",
|
|
14
|
+
"graphNodeType": "feature",
|
|
15
|
+
"seedFromDomainId": true,
|
|
16
|
+
"outputDir": "docs/basic-design/api/"
|
|
17
|
+
},
|
|
18
|
+
"perScreen": {
|
|
19
|
+
"parentDagId": "bd.detail-screen",
|
|
20
|
+
"graphNodeType": "feature",
|
|
21
|
+
"seedFromDomainId": true,
|
|
22
|
+
"outputDir": "docs/basic-design/screens/"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"documentNodes": {
|
|
26
|
+
"bd.db-design": {
|
|
27
|
+
"id": "doc.bd.db-design",
|
|
28
|
+
"type": "document",
|
|
29
|
+
"output": "docs/basic-design/db-design.md",
|
|
30
|
+
"template": "basic_design/db-design-template.md"
|
|
31
|
+
},
|
|
32
|
+
"bd.list-api": {
|
|
33
|
+
"id": "doc.bd.list-api",
|
|
34
|
+
"type": "document",
|
|
35
|
+
"output": "docs/basic-design/api-list.md",
|
|
36
|
+
"template": "basic_design/list-api-template.md"
|
|
37
|
+
},
|
|
38
|
+
"bd.list-screen": {
|
|
39
|
+
"id": "doc.bd.list-screen",
|
|
40
|
+
"type": "document",
|
|
41
|
+
"output": "docs/basic-design/screens/list-screens.md",
|
|
42
|
+
"template": "basic_design/list-screen-template.md"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"description": "Map dag.srs.json node ids to traceability graph document ids for /generate-srs",
|
|
4
|
+
"seeds": {
|
|
5
|
+
"srs.introduction": "doc.srs.1-introduction",
|
|
6
|
+
"srs.overall-description": "doc.srs.2-overall-description",
|
|
7
|
+
"srs.use-cases": "doc.srs.3-use-cases",
|
|
8
|
+
"srs.features-list": "doc.srs.4-system-features",
|
|
9
|
+
"srs.feature-details": "doc.srs.4-system-features",
|
|
10
|
+
"srs.data-requirements": "doc.srs.5-data-requirements",
|
|
11
|
+
"srs.external-interfaces": "doc.srs.6-external-interfaces",
|
|
12
|
+
"srs.quality-attributes": "doc.srs.7-quality-attributes",
|
|
13
|
+
"srs.internationalization": "doc.srs.8-internationalization",
|
|
14
|
+
"srs.other-requirements": "doc.srs.9-other-requirements"
|
|
15
|
+
},
|
|
16
|
+
"perDomain": {
|
|
17
|
+
"useCase": {
|
|
18
|
+
"graphNodeType": "useCase",
|
|
19
|
+
"documentPattern": "doc.srs.uc-{id}",
|
|
20
|
+
"seedFromDomainId": true
|
|
21
|
+
},
|
|
22
|
+
"feature": {
|
|
23
|
+
"graphNodeType": "feature",
|
|
24
|
+
"documentPattern": "doc.srs.f-{id}",
|
|
25
|
+
"seedFromDomainId": true
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"comment": "After one SRS file or a whole parallel wave — merge before the next wave",
|
|
4
|
+
"nodes": [],
|
|
5
|
+
"edges": [
|
|
6
|
+
{
|
|
7
|
+
"type": "rendersTo",
|
|
8
|
+
"from": "doc.srs.3-use-cases",
|
|
9
|
+
"to": "docs/srs/3-use-cases.md"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
"type": "dependsOn",
|
|
13
|
+
"from": "doc.srs.3-use-cases",
|
|
14
|
+
"to": "doc.srs.1-introduction"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"type": "dependsOn",
|
|
18
|
+
"from": "doc.srs.3-use-cases",
|
|
19
|
+
"to": "doc.srs.2-overall-description"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
@@ -95,6 +95,18 @@ When any `ai-spector` command **fails** (non-zero exit, throws, or empty/invalid
|
|
|
95
95
|
- **Means:** `/analyze` cannot extract.
|
|
96
96
|
- **Fix:** User enables Graphify in Cursor; do not fake `knowledge.json`; stop and document blocker.
|
|
97
97
|
|
|
98
|
+
### `graphify update` — `unknown option: --graph`
|
|
99
|
+
|
|
100
|
+
- **Means:** Agent used `graphify update <path> --graph <file>`. The `update` subcommand does **not** accept `--graph` (only `query`, `explain`, `path`, `cluster-only` do).
|
|
101
|
+
- **Fix:** Run **`ai-spector graphify update`** or
|
|
102
|
+
`GRAPHIFY_OUT=.ai-spector/.docflow/graph/graphify-out graphify update docs/data-source`
|
|
103
|
+
Then delete `docs/data-source/graphify-out/` if it exists.
|
|
104
|
+
|
|
105
|
+
### Graphify wrote `docs/data-source/graphify-out/`
|
|
106
|
+
|
|
107
|
+
- **Means:** `graphify update` ran without `GRAPHIFY_OUT`.
|
|
108
|
+
- **Fix:** Run **`ai-spector graphify update`** (sets env + removes stale folder). Do not copy files manually unless CLI failed.
|
|
109
|
+
|
|
98
110
|
---
|
|
99
111
|
|
|
100
112
|
## Agent may fix without asking (small, local)
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Graph-first generation (shared)
|
|
2
|
+
|
|
3
|
+
Used by **`/generate-srs`**, **`/generate-basic-design`**, **`/generate-detail-design`**.
|
|
4
|
+
|
|
5
|
+
Each command has its own `dag.*.json`, `dag.*.graph-seeds.json`, and § Case 3 intent tables in its command file.
|
|
6
|
+
|
|
7
|
+
**Principle:** Accuracy over speed. The graph is the planner, context loader, and registry of what was written.
|
|
8
|
+
|
|
9
|
+
**Parallelism:** Allowed **only inside a DAG wave** — targets that do not depend on each other (and whose dependencies are already ingested). Never parallelize across waves.
|
|
10
|
+
|
|
11
|
+
## Agent rules (non-negotiable)
|
|
12
|
+
|
|
13
|
+
1. **Plan from DAG + graph** — build **waves** from `dag.*.json` (see § Waves); map each node to a graph seed via `dag.*.graph-seeds.json`.
|
|
14
|
+
2. **Context before write** — for **every** target (batch or single), run CLI queries below; read `projectionPaths` and domain `nodes`/`edges`. No invented UC/F text.
|
|
15
|
+
3. **Dependencies before write** — for each target’s `dependsOn`, `graph query` dependency seeds and **read existing markdown** when `rendersTo` exists.
|
|
16
|
+
4. **Ingest before next wave** — after each file (or after a whole wave), merge `rendersTo` + `dependsOn` (see § Ingest), then `graph validate`. The next wave must see upstream `rendersTo` edges.
|
|
17
|
+
5. **No shortcuts** — no glob `docs/srs/**`, no skipping validate/query, no index-first generation, no batching targets that have a DAG dependency on each other.
|
|
18
|
+
|
|
19
|
+
## CLI workflow per target
|
|
20
|
+
|
|
21
|
+
### A. Gate (once per command)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
ai-spector graph validate
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### B. Plan
|
|
28
|
+
|
|
29
|
+
- Load `dag.srs.json` (or matching DAG).
|
|
30
|
+
- Load `dag.srs.graph-seeds.json` for `document` seeds.
|
|
31
|
+
- Build **waves** (below).
|
|
32
|
+
- Skip `good` files unless user asked to regenerate; use `graph impact` when replacing content.
|
|
33
|
+
|
|
34
|
+
#### Waves (when batch is allowed)
|
|
35
|
+
|
|
36
|
+
Assign each DAG node to wave `0`, `1`, `2`, …:
|
|
37
|
+
|
|
38
|
+
- **Wave 0:** nodes with empty `dependsOn`.
|
|
39
|
+
- **Wave k:** nodes whose `dependsOn` are all in waves `< k` (not in the same wave).
|
|
40
|
+
|
|
41
|
+
**Same wave = safe to generate in parallel** (no target in the wave depends on another target in that wave).
|
|
42
|
+
|
|
43
|
+
**Example** (`dag.srs.json`): after `srs.feature-details`, both `srs.data-requirements` and `srs.external-interfaces` are in the **same wave** (each depends on feature-details only, not on each other) → may generate both in one batch.
|
|
44
|
+
|
|
45
|
+
**Forbidden batch:** `srs.use-cases` + `srs.features-list` (features-list depends on use-cases).
|
|
46
|
+
|
|
47
|
+
**User asks for specific files** (case 2): map paths → DAG nodes; include dependency closure; batch only within same wave.
|
|
48
|
+
|
|
49
|
+
**User describes scope in words** (case 3): map intent → proposed DAG nodes + paths → **get user confirmation** before any `graph query` / write (see `generate-srs.md` § Case 3).
|
|
50
|
+
|
|
51
|
+
Present plan as:
|
|
52
|
+
|
|
53
|
+
| Wave | DAG ids (parallel OK within row) | Seeds | Blocked until |
|
|
54
|
+
|------|----------------------------------|-------|---------------|
|
|
55
|
+
| 0 | … | … | — |
|
|
56
|
+
| 1 | … | … | wave 0 merged + validate |
|
|
57
|
+
|
|
58
|
+
### C. Before writing file `T`
|
|
59
|
+
|
|
60
|
+
**1. Dependency context** (each DAG `dependsOn` id → graph seed):
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
ai-spector graph query <depSeedId> --direction both --depth 2 --edges rendersTo,dependsOn,listedIn,satisfies,definedIn,partOf,contains --json
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Open existing `projectionPaths` from the JSON (already-generated SRS chapters).
|
|
67
|
+
|
|
68
|
+
**2. Target neighborhood** (domain + structure):
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
ai-spector graph query <targetSeedId> --direction both --depth 4 --edges listedIn,definedIn,describedIn,satisfies,dependsOn,references,rendersTo,partOf,contains --json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**3. Impact scope** (when regenerating or unsure):
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
ai-spector graph impact <targetSeedId> --change content_change --json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Respect `regenerate` / `review` buckets; do not rewrite unrelated chapters.
|
|
81
|
+
|
|
82
|
+
**4. Data-source supplement** — only for gaps after graph query succeeds; cite paths in the doc.
|
|
83
|
+
|
|
84
|
+
### D. Write
|
|
85
|
+
|
|
86
|
+
- Fill the bundled template for that target only.
|
|
87
|
+
- Cross-check every UC/F reference against `nodes` from query JSON.
|
|
88
|
+
- Add section anchors `<!-- section:sec.... -->` where templates expect them.
|
|
89
|
+
|
|
90
|
+
### E. Ingest (mandatory — per file or per wave)
|
|
91
|
+
|
|
92
|
+
After **each file**, or once at **end of a parallel wave** (single patch listing all files in that wave):
|
|
93
|
+
|
|
94
|
+
Write `.ai-spector/.docflow/extract/projection-patch.json`:
|
|
95
|
+
|
|
96
|
+
```json
|
|
97
|
+
{
|
|
98
|
+
"version": 1,
|
|
99
|
+
"nodes": [],
|
|
100
|
+
"edges": [
|
|
101
|
+
{ "type": "rendersTo", "from": "doc.srs.3-use-cases", "to": "docs/srs/3-use-cases.md" },
|
|
102
|
+
{ "type": "dependsOn", "from": "doc.srs.3-use-cases", "to": "doc.srs.1-introduction" },
|
|
103
|
+
{ "type": "dependsOn", "from": "doc.srs.3-use-cases", "to": "doc.srs.2-overall-description" }
|
|
104
|
+
]
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Then:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
ai-spector graph merge .ai-spector/.docflow/extract/projection-patch.json
|
|
112
|
+
ai-spector graph validate
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
- `rendersTo`: `from` = graph `document` (or section) id, `to` = repo-relative markdown path.
|
|
116
|
+
- `dependsOn`: mirror DAG edges between **document** ids (downstream queries use these for context).
|
|
117
|
+
- Per-domain files (`UC-01`, `F-01`): also link `definedIn` from domain node to detail sections if applicable.
|
|
118
|
+
|
|
119
|
+
**Wave rule:** finish all writes in wave `k`, merge **all** `rendersTo` / `dependsOn` for that wave, `graph validate`, then start wave `k+1`.
|
|
120
|
+
|
|
121
|
+
Alternative repair: **`/sync-graph`** — not a substitute for merge between waves.
|
|
122
|
+
|
|
123
|
+
### F. Per-domain detail files
|
|
124
|
+
|
|
125
|
+
For `mode: perFeature` / `perDomain` DAG nodes:
|
|
126
|
+
|
|
127
|
+
- Seed = domain id (`UC-01`, `F-01`), not only chapter document.
|
|
128
|
+
- Query with `--depth 4`; include inbound `satisfies` / `dependsOn`.
|
|
129
|
+
- `rendersTo` from resolved output path (e.g. `docs/srs/03-use-cases/uc-01-....md`).
|
|
130
|
+
|
|
131
|
+
## Accuracy checklist (before marking target done)
|
|
132
|
+
|
|
133
|
+
- [ ] `graph query` run for target and every DAG dependency with existing files
|
|
134
|
+
- [ ] All UC/F ids in markdown exist as graph nodes
|
|
135
|
+
- [ ] `rendersTo` + `dependsOn` merged for this file
|
|
136
|
+
- [ ] `graph validate` passes
|
|
137
|
+
- [ ] No placeholder lorem / empty tables unless marked TBD in `gaps.json`
|
|
138
|
+
|
|
139
|
+
## On CLI failure
|
|
140
|
+
|
|
141
|
+
[_cli-failures.md](./_cli-failures.md) — stop; do not generate from memory.
|
|
@@ -14,6 +14,7 @@ Run from project root: `npx ai-spector …` if needed.
|
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
ai-spector analyze
|
|
17
|
+
ai-spector graphify update
|
|
17
18
|
ai-spector graph merge --from-knowledge
|
|
18
19
|
ai-spector graph validate
|
|
19
20
|
ai-spector graph visualize [--open]
|
|
@@ -24,9 +25,13 @@ ai-spector graph impact <nodeId> --json
|
|
|
24
25
|
## `graph query`
|
|
25
26
|
|
|
26
27
|
```bash
|
|
27
|
-
ai-spector graph query <seedId> --direction both --depth
|
|
28
|
+
ai-spector graph query <seedId> --direction both --depth 4 --json
|
|
29
|
+
ai-spector graph query <depDocId> --edges rendersTo,dependsOn,listedIn,satisfies --depth 2 --json
|
|
30
|
+
ai-spector graph impact <seedId> --change content_change --json
|
|
28
31
|
```
|
|
29
32
|
|
|
33
|
+
**Generate:** query **before** write; **`graph merge`** projection patch **after** each file (`rendersTo` + `dependsOn`). See `_generate-graph.md`.
|
|
34
|
+
|
|
30
35
|
Use `projectionPaths`, `nodes`, `edges` from JSON. **If command fails or JSON invalid:** stop — do not glob `docs/srs/**`.
|
|
31
36
|
|
|
32
37
|
**If success but empty domain nodes:** report to user; suggest `/analyze` — still no folder-wide SRS reads.
|
|
@@ -17,11 +17,11 @@ Add source material under `docs/data-source/`, open the project in Cursor, **rel
|
|
|
17
17
|
|
|
18
18
|
| Step | You run | Agent runs (CLI) |
|
|
19
19
|
|------|---------|------------------|
|
|
20
|
-
| 1 | **`/analyze`** | `ai-spector analyze` → Graphify extract → `graph merge --from-knowledge` → `graph validate` → optional `graph visualize --open` |
|
|
20
|
+
| 1 | **`/analyze`** | `ai-spector analyze` → `ai-spector graphify update` → Graphify MCP extract → `graph merge --from-knowledge` → `graph validate` → optional `graph visualize --open` |
|
|
21
21
|
| 2 | **`/validate-graph`** | `ai-spector graph validate` |
|
|
22
|
-
| 3 | **`/generate-srs`**
|
|
22
|
+
| 3 | **`/generate-srs`** [paths or request] — all, listed files, or described scope (**confirm** if described) → waves → merge (see `generate-srs.md`) |
|
|
23
23
|
| 4 | **`/index-docs srs`** (optional) | index update per command |
|
|
24
|
-
| 5 | **`/generate-basic-design`**
|
|
24
|
+
| 5 | **`/generate-basic-design`** [paths or request] — same targeting + waves as SRS (`generate-basic-design.md`) |
|
|
25
25
|
| 6 | **`/generate-detail-design`** | same `graph query` pattern |
|
|
26
26
|
| After edits | **`/graph-impact <nodeId>`** | `graph impact <id> --json` |
|
|
27
27
|
| Inspect graph | **`/visualize-graph`** | `graph visualize --open` |
|
|
@@ -26,19 +26,33 @@ ai-spector analyze
|
|
|
26
26
|
|
|
27
27
|
Creates section/document nodes from templates. Do not ask the user to run this separately.
|
|
28
28
|
|
|
29
|
-
### A. Extract (Graphify
|
|
29
|
+
### A. Extract (Graphify)
|
|
30
30
|
|
|
31
31
|
1. Load `data-source.json`, `analyze.graphify.json`.
|
|
32
|
-
2. **Graphify paths (
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
32
|
+
2. **Graphify paths (from `ai-spector init`):**
|
|
33
|
+
- Output dir: `.ai-spector/.docflow/graph/graphify-out` (`GRAPHIFY_OUT`)
|
|
34
|
+
- Graph file: `.ai-spector/.docflow/graph/graphify-out/graph.json` (MCP + queries use `--graph` only on `graphify query`, not on `update`)
|
|
35
|
+
3. **Code ingest (CLI — agent runs):**
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
ai-spector graphify update
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
This runs `graphify update docs/data-source` with `GRAPHIFY_OUT` set. **Forbidden:** `graphify update … --graph …` (`unknown option: --graph`).
|
|
42
|
+
|
|
43
|
+
Fallback if needed:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
GRAPHIFY_OUT=.ai-spector/.docflow/graph/graphify-out graphify update docs/data-source
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The command removes stale `docs/data-source/graphify-out/` if Graphify created it by mistake.
|
|
50
|
+
|
|
51
|
+
4. **Semantic extract (Graphify MCP)** — query profiles in `analyze.graphify.json`; use graph at `graphJsonPath` for `graphify query "…" --graph .ai-spector/.docflow/graph/graphify-out/graph.json`.
|
|
52
|
+
5. Resolve paths → `scope.json` → `sources`.
|
|
53
|
+
6. Query / fallback to extract:
|
|
40
54
|
- actors, useCases, features, functionalRequirements, nfrs, entities, interfaces, constraints, openQuestions
|
|
41
|
-
|
|
55
|
+
7. Persist staging (canonical for AI Spector):
|
|
42
56
|
- `.ai-spector/.docflow/analysis/knowledge.json` (see package `schemas/schema.knowledge.json`)
|
|
43
57
|
- `.ai-spector/.docflow/analysis/gaps.json`
|
|
44
58
|
- `.ai-spector/.docflow/analysis/scope.json`
|
|
@@ -1,26 +1,155 @@
|
|
|
1
1
|
# /generate-basic-design
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Generate basic design markdown **from the traceability graph** and upstream SRS — same discipline as `/generate-srs`.
|
|
4
|
+
|
|
5
|
+
**User runs this command;** the agent runs CLI. Shared rules: [**_generate-graph.md**](./_generate-graph.md). On CLI failure: [_cli-failures.md](./_cli-failures.md).
|
|
6
|
+
|
|
7
|
+
## Philosophy
|
|
8
|
+
|
|
9
|
+
- **Accuracy over speed** — query graph + SRS/basic-design neighbors before each write; ingest before the next wave.
|
|
10
|
+
- **SRS is upstream context** — query `rendersTo` paths to `docs/srs/**` for dependencies; do not invent APIs/screens not grounded in graph + SRS.
|
|
11
|
+
- **Parallel when safe** — same DAG wave only (see `dag.basic-design.json`).
|
|
12
|
+
|
|
13
|
+
## Usage — three ways to choose targets
|
|
14
|
+
|
|
15
|
+
| Case | User says | Agent behavior |
|
|
16
|
+
|------|-----------|----------------|
|
|
17
|
+
| **1 — All (default)** | `/generate-basic-design` | Plan **every** node in `dag.basic-design.json` (+ per-domain expansions). |
|
|
18
|
+
| **2 — Explicit files** | `/generate-basic-design docs/basic-design/api-list.md` | Map paths → DAG nodes → seeds. Include DAG `dependsOn` prerequisites. Same-wave batch OK. |
|
|
19
|
+
| **3 — Request in words** | `/generate-basic-design API list and DB design for checkout` | Resolve intent → **proposed scope table** → user confirms → generate. **Do not write until approved.** |
|
|
20
|
+
|
|
21
|
+
Arguments are **file paths** (case 2) or **free-text** (case 3). Paths are under `docs/basic-design/` unless the user gives a repo-relative path.
|
|
22
|
+
|
|
23
|
+
## Case 3 — resolve request and confirm (mandatory)
|
|
24
|
+
|
|
25
|
+
1. Parse against `dag.basic-design.json`, `dag.basic-design.graph-seeds.json`, and graph (`feature`, `useCase`, SRS `document` nodes with `rendersTo`).
|
|
26
|
+
2. Proposed scope table:
|
|
27
|
+
|
|
28
|
+
| # | DAG id | Output | Query seed | Reason | Prerequisites |
|
|
29
|
+
|---|--------|--------|------------|--------|---------------|
|
|
30
|
+
| 1 | `bd.list-api` | `docs/basic-design/api-list.md` | `doc.srs.6-external-interfaces` | “API list” | SRS §6 if missing |
|
|
31
|
+
| 2 | `bd.detail-api` | `docs/basic-design/api/…` | `F-01`, … | “APIs for feature X” | `bd.list-api`, SRS features |
|
|
32
|
+
|
|
33
|
+
3. Include **dependency closure** from `dag.basic-design.json` and missing SRS files (minimum: introduction + features per `workflow.dependencies.json`).
|
|
34
|
+
4. Ask:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
I plan to generate the following basic design artifacts (N items, waves X–Y).
|
|
38
|
+
Reply **yes** to proceed, **no** to cancel, or edit the list.
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
5. **Stop** without user confirmation.
|
|
42
|
+
6. Clarify ambiguity early (e.g. “all API details” = every `F-xx` vs one feature; “screens” = list vs all screen detail files).
|
|
43
|
+
|
|
44
|
+
### Intent → DAG hints
|
|
45
|
+
|
|
46
|
+
| User phrase (examples) | Typical DAG / outputs |
|
|
47
|
+
|------------------------|------------------------|
|
|
48
|
+
| database, DB, ERD, data model | `bd.db-design` → `db-design.md` |
|
|
49
|
+
| API list, endpoints overview | `bd.list-api` → `api-list.md` |
|
|
50
|
+
| API detail, per endpoint, REST | `bd.detail-api` → `docs/basic-design/api/` (per feature / endpoint) |
|
|
51
|
+
| screen list, UI list | `bd.list-screen` → `screens/list-screens.md` |
|
|
52
|
+
| screen detail, wireframe, per screen | `bd.detail-screen` → `docs/basic-design/screens/` |
|
|
53
|
+
| one feature, F-01, checkout | `F-01` seeds for api/screen detail under that feature |
|
|
54
|
+
| everything, full basic design | Case 1 — full DAG |
|
|
4
55
|
|
|
5
56
|
## Prerequisites
|
|
6
57
|
|
|
7
|
-
|
|
58
|
+
`workflow.dependencies.json` → `generate-basic-design`. Requires:
|
|
59
|
+
|
|
60
|
+
- Merged graph (`/analyze`), **`ai-spector graph validate`**
|
|
61
|
+
- Minimum SRS on disk (see workflow checks)
|
|
62
|
+
- Recommended: `/index-docs srs` for summaries; refresh `/index-docs basic-design` after this command
|
|
8
63
|
|
|
9
|
-
|
|
64
|
+
Config:
|
|
10
65
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
66
|
+
- `dag.basic-design.json` — order + `dependsOn`
|
|
67
|
+
- `dag.basic-design.graph-seeds.json` — DAG id → SRS/graph query seed + `documentNodes` for ingest
|
|
68
|
+
- `completeness-rules.basic-design.json`
|
|
69
|
+
|
|
70
|
+
## Required behavior
|
|
71
|
+
|
|
72
|
+
### 1. Gate
|
|
14
73
|
|
|
15
74
|
```bash
|
|
16
|
-
ai-spector graph
|
|
75
|
+
ai-spector graph validate
|
|
17
76
|
```
|
|
18
77
|
|
|
19
|
-
|
|
20
|
-
5. Generate; update graph edges (`tracesTo` / `references`); `ai-spector graph validate`.
|
|
78
|
+
### 2. Plan (graph + DAG)
|
|
21
79
|
|
|
22
|
-
|
|
80
|
+
1. **Select targets** (case 1 / 2 / 3; case 3 = confirm first).
|
|
81
|
+
2. Topological sort selected nodes + dependency ancestors (`bd.detail-api` after `bd.list-api`, etc.).
|
|
82
|
+
3. Map seeds via `dag.basic-design.graph-seeds.json`:
|
|
83
|
+
- Chapter artifacts → `documentNodes` id for ingest + SRS seed for **query**
|
|
84
|
+
- `perEndpoint` / `perScreen` → one target per `feature` (`F-xx`) from graph
|
|
85
|
+
4. Classify disk: `good` | `missing_content` | `missing_file`.
|
|
86
|
+
5. **Waves** — e.g. wave 0: `bd.db-design`, `bd.list-api`, `bd.list-screen` in parallel; wave 1: `bd.detail-api`; wave 2: `bd.detail-screen`.
|
|
87
|
+
|
|
88
|
+
### 3. Per wave, then per target
|
|
89
|
+
|
|
90
|
+
#### 3a. Load context (CLI)
|
|
23
91
|
|
|
24
|
-
|
|
92
|
+
- `graph query` each **DAG dependency** (SRS paths via `rendersTo`, prior basic-design `rendersTo`).
|
|
93
|
+
- `graph query` **target seed** (`doc.srs.*` or `F-xx`) — depth **4**, edges include `satisfies`, `tracesTo`, `references`, `rendersTo`, `dependsOn`.
|
|
94
|
+
- `graph impact` when regenerating.
|
|
95
|
+
- Read `projectionPaths` + relevant `docs/srs/**` and `docs/data-source/**` only as needed.
|
|
96
|
+
|
|
97
|
+
#### 3b. Write
|
|
98
|
+
|
|
99
|
+
- Templates: `node_modules/ai-spector/templates/basic_design/` (monorepo: `../templates/basic_design/`).
|
|
100
|
+
- Align API/screen names with graph `feature` titles and SRS feature detail files.
|
|
101
|
+
|
|
102
|
+
#### 3c. Ingest (mandatory before next wave)
|
|
103
|
+
|
|
104
|
+
Merge patch (include `documentNodes` from `dag.basic-design.graph-seeds.json` when first creating chapter-level docs):
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"version": 1,
|
|
109
|
+
"nodes": [
|
|
110
|
+
{ "id": "doc.bd.list-api", "type": "document", "output": "docs/basic-design/api-list.md", "template": "basic_design/list-api-template.md" }
|
|
111
|
+
],
|
|
112
|
+
"edges": [
|
|
113
|
+
{ "type": "rendersTo", "from": "doc.bd.list-api", "to": "docs/basic-design/api-list.md" },
|
|
114
|
+
{ "type": "dependsOn", "from": "doc.bd.list-api", "to": "doc.srs.6-external-interfaces" },
|
|
115
|
+
{ "type": "dependsOn", "from": "doc.bd.detail-api", "to": "doc.bd.list-api" },
|
|
116
|
+
{ "type": "tracesTo", "from": "F-01", "to": "doc.bd.list-api" }
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
ai-spector graph merge .ai-spector/.docflow/extract/projection-patch.json
|
|
123
|
+
ai-spector graph validate
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Per-domain file: `rendersTo` from `F-xx` or `doc.bd.*` to actual path; `tracesTo` / `references` to SRS or API list as appropriate.
|
|
127
|
+
|
|
128
|
+
#### 3d. Log
|
|
129
|
+
|
|
130
|
+
Append `.ai-spector/.docflow/logs/generate-basic-design.log`.
|
|
131
|
+
|
|
132
|
+
### 4. Finish
|
|
133
|
+
|
|
134
|
+
- Final `graph validate`.
|
|
135
|
+
- Suggest **`/index-docs basic-design`** (required by workflow before detail design).
|
|
136
|
+
|
|
137
|
+
## Waves (reference)
|
|
138
|
+
|
|
139
|
+
| Wave | DAG nodes (parallel within wave) |
|
|
140
|
+
|------|----------------------------------|
|
|
141
|
+
| 0 | `bd.db-design`, `bd.list-api`, `bd.list-screen` |
|
|
142
|
+
| 1 | `bd.detail-api` (+ per-feature API files) |
|
|
143
|
+
| 2 | `bd.detail-screen` (+ per-feature screen files) |
|
|
144
|
+
|
|
145
|
+
## Guardrails
|
|
146
|
+
|
|
147
|
+
- **Parallel only within a wave** — never `bd.detail-api` before `bd.list-api` is ingested.
|
|
148
|
+
- **Every target** gets `graph query` + dependency queries.
|
|
149
|
+
- **Case 3** requires explicit user **yes** before writes.
|
|
150
|
+
- Do not overwrite `good` without user intent.
|
|
151
|
+
- On CLI failure → [_cli-failures.md](./_cli-failures.md).
|
|
152
|
+
|
|
153
|
+
## If blocked
|
|
25
154
|
|
|
26
|
-
|
|
155
|
+
[_cli-failures.md](./_cli-failures.md). Often: run `/generate-srs` for missing SRS deps, then re-run **`/generate-basic-design`**.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# /generate-detail-design
|
|
2
2
|
|
|
3
|
-
Detail design via graph context. **User runs this command;** agent runs CLI.
|
|
3
|
+
Detail design via graph context. **User runs this command;** agent runs CLI. Graph-first: [_generate-graph.md](./_generate-graph.md). On CLI failure: [_cli-failures.md](./_cli-failures.md).
|
|
4
4
|
|
|
5
5
|
## Prerequisites
|
|
6
6
|
|
|
@@ -1,16 +1,72 @@
|
|
|
1
1
|
# /generate-srs
|
|
2
2
|
|
|
3
|
-
Generate SRS
|
|
3
|
+
Generate SRS markdown **from the traceability graph** — carefully, in DAG order, ingesting each file back into the graph.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
**User runs this command;** the agent runs CLI. Shared graph-first rules: [**_generate-graph.md**](./_generate-graph.md).
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Philosophy
|
|
8
|
+
|
|
9
|
+
- **Accuracy over speed** — full graph context before every write; ingest before the next wave.
|
|
10
|
+
- **Graph in, graph out** — query neighbors + dependencies before; `rendersTo` + `dependsOn` after.
|
|
11
|
+
- **Parallel when safe** — targets in the **same DAG wave** (no `dependsOn` between them) may be generated in one batch; never skip query/ingest per file.
|
|
12
|
+
|
|
13
|
+
## Usage — three ways to choose targets
|
|
14
|
+
|
|
15
|
+
| Case | User says | Agent behavior |
|
|
16
|
+
|------|-----------|----------------|
|
|
17
|
+
| **1 — All (default)** | `/generate-srs` | Plan **every** DAG node (respect `good` / skip unless regen requested). Full wave walk. |
|
|
18
|
+
| **2 — Explicit files** | `/generate-srs docs/srs/3-use-cases.md` or `/generate-srs file1.md file2.md` | Map paths → DAG nodes → seeds. Add **DAG dependencies** not on disk yet. Batch only within same wave. |
|
|
19
|
+
| **3 — Request in words** | `/generate-srs general use case chapter and features` | Resolve intent → proposed file list → **confirm with user** → then same as case 2. **Do not generate until user approves.** |
|
|
20
|
+
|
|
21
|
+
Arguments after the command are either **file paths** (case 2) or a **free-text request** (case 3). If mixed, treat paths as explicit and text as request.
|
|
22
|
+
|
|
23
|
+
## Case 3 — resolve request and confirm (mandatory)
|
|
24
|
+
|
|
25
|
+
1. Parse the user’s words against `dag.srs.json`, `dag.srs.graph-seeds.json`, and graph domain nodes (`useCase`, `feature`).
|
|
26
|
+
2. Build a **proposed scope** table:
|
|
27
|
+
|
|
28
|
+
| # | DAG id | Output path | Seed | Reason matched | Also generate deps? |
|
|
29
|
+
|---|--------|-------------|------|----------------|---------------------|
|
|
30
|
+
| 1 | `srs.use-cases` | `docs/srs/3-use-cases.md` | `doc.srs.3-use-cases` | “use case chapter” | yes — `srs.introduction`, `srs.overall-description` if missing |
|
|
31
|
+
|
|
32
|
+
3. Include **dependency closure**: any DAG `dependsOn` ancestor that is `missing_file` / `missing_content` must be listed (generated first in earlier waves) unless user says to skip deps.
|
|
33
|
+
4. Ask explicitly:
|
|
34
|
+
|
|
35
|
+
```text
|
|
36
|
+
I plan to generate the following (N files, waves X–Y). Dependencies marked “prerequisite” run first.
|
|
37
|
+
Reply **yes** to proceed, **no** to cancel, or edit the list (e.g. “skip introduction”, “add 5-data-requirements”).
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
5. **Stop** if the user does not confirm. Do not write SRS files on assumption.
|
|
41
|
+
6. If the request is ambiguous (e.g. “features” = list only vs all F-xx detail files), ask one clarifying question **before** the confirmation table.
|
|
42
|
+
|
|
43
|
+
### Intent → DAG hints (not exhaustive)
|
|
44
|
+
|
|
45
|
+
| User phrase (examples) | Typical DAG / outputs |
|
|
46
|
+
|------------------------|------------------------|
|
|
47
|
+
| introduction, purpose, scope | `srs.introduction` |
|
|
48
|
+
| overall, actors, users, §2 | `srs.overall-description` |
|
|
49
|
+
| use case(s), UC, §3, chapter 3 | `srs.use-cases` (+ optional `UC-xx` detail if “all UC details”) |
|
|
50
|
+
| feature list, §4.2, system features | `srs.features-list` |
|
|
51
|
+
| feature detail, per feature, F-xx | `srs.feature-details` (`F-01`, … from graph) |
|
|
52
|
+
| data, entities, §5 | `srs.data-requirements` |
|
|
53
|
+
| interfaces, API, §6 | `srs.external-interfaces` |
|
|
54
|
+
| NFR, quality, §7 | `srs.quality-attributes` |
|
|
55
|
+
| i18n, localization, §8 | `srs.internationalization` |
|
|
56
|
+
| legal, compliance, §9 | `srs.other-requirements` |
|
|
57
|
+
| “everything” / no filter | Case 1 — full DAG |
|
|
8
58
|
|
|
9
59
|
## Prerequisites
|
|
10
60
|
|
|
11
|
-
`workflow.dependencies.json` → `generate-srs`.
|
|
61
|
+
`workflow.dependencies.json` → `generate-srs`. Requires merged graph (`/analyze`), passing **`ai-spector graph validate`**.
|
|
62
|
+
|
|
63
|
+
Config:
|
|
12
64
|
|
|
13
|
-
|
|
65
|
+
- `dag.srs.json` — generation order + `dependsOn`
|
|
66
|
+
- `dag.srs.graph-seeds.json` — DAG id → `doc.srs.*` graph seed
|
|
67
|
+
- `completeness-rules.srs.json` — quality checks
|
|
68
|
+
|
|
69
|
+
## Required behavior
|
|
14
70
|
|
|
15
71
|
### 1. Gate
|
|
16
72
|
|
|
@@ -18,46 +74,101 @@ Generate SRS projections. **User runs this command;** agent runs CLI (`graph val
|
|
|
18
74
|
ai-spector graph validate
|
|
19
75
|
```
|
|
20
76
|
|
|
21
|
-
|
|
77
|
+
Stop if errors — [_cli-failures.md](./_cli-failures.md).
|
|
22
78
|
|
|
23
|
-
|
|
79
|
+
### 2. Plan (graph + DAG)
|
|
24
80
|
|
|
25
|
-
|
|
81
|
+
1. **Select targets** using Usage case 1, 2, or 3 above. For case 3, run § “confirm” first.
|
|
82
|
+
2. Topological sort **selected** nodes plus any required dependency ancestors.
|
|
83
|
+
3. Map each node with `dag.srs.graph-seeds.json` → `targetSeedId` (`doc.srs.*` or `UC-xx` / `F-xx` for per-domain).
|
|
84
|
+
4. Classify disk: `good` | `missing_content` | `missing_file` — do not overwrite `good` unless user asked to regenerate (explicit path or confirmed scope).
|
|
85
|
+
5. Group into **waves** (see _generate-graph.md § Waves). Present final wave table (cases 1–2: brief; case 3: already confirmed).
|
|
26
86
|
|
|
27
|
-
|
|
28
|
-
ai-spector graph query <seedId> --direction both --depth 3 --json
|
|
29
|
-
```
|
|
87
|
+
### 3. Per wave, then per target
|
|
30
88
|
|
|
31
|
-
|
|
89
|
+
For **each wave** in order:
|
|
32
90
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
- Supplement `docs/data-source/**` only when query + graph nodes are insufficient
|
|
91
|
+
1. All targets in this wave may run **in parallel** only if they do not depend on each other (true by wave definition).
|
|
92
|
+
2. For **each** target in the wave (parallel or serial):
|
|
36
93
|
|
|
37
|
-
|
|
94
|
+
#### 3a. Load context (CLI)
|
|
38
95
|
|
|
39
|
-
|
|
96
|
+
Per [_generate-graph.md](./_generate-graph.md):
|
|
40
97
|
|
|
41
|
-
|
|
98
|
+
- `graph query` each **DAG dependency** that should already exist (depth 2, include `rendersTo`).
|
|
99
|
+
- `graph query` **target** seed (depth **4**, full generate edge set).
|
|
100
|
+
- `graph impact <targetSeedId> --json` when replacing or ambiguous scope.
|
|
42
101
|
|
|
43
|
-
|
|
102
|
+
Read **only** paths from `projectionPaths` plus targeted `docs/data-source/**` for gaps.
|
|
44
103
|
|
|
45
|
-
|
|
104
|
+
#### 3b. Write one file
|
|
105
|
+
|
|
106
|
+
- Use template from `node_modules/ai-spector/templates/srs/` (or monorepo `../templates/srs/`).
|
|
107
|
+
- Content must match graph: UC list from `listedIn` on `useCase` nodes; features from `feature` + `satisfies`.
|
|
108
|
+
- No fabricated requirements.
|
|
109
|
+
|
|
110
|
+
#### 3c. Ingest into graph (mandatory before next wave)
|
|
111
|
+
|
|
112
|
+
After each file **or** once per wave (combine all edges in one patch):
|
|
46
113
|
|
|
47
114
|
```bash
|
|
115
|
+
ai-spector graph merge .ai-spector/.docflow/extract/projection-patch.json
|
|
48
116
|
ai-spector graph validate
|
|
49
117
|
```
|
|
50
118
|
|
|
51
|
-
|
|
119
|
+
Do not start the **next wave** until validate passes.
|
|
120
|
+
|
|
121
|
+
Patch must include at minimum:
|
|
122
|
+
|
|
123
|
+
- `rendersTo` — `from`: document id, `to`: actual file path
|
|
124
|
+
- `dependsOn` — `from`: downstream doc id, `to`: each upstream doc id from DAG (same generation wave)
|
|
125
|
+
|
|
126
|
+
Example for `srs.use-cases` → `doc.srs.3-use-cases`:
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{
|
|
130
|
+
"version": 1,
|
|
131
|
+
"nodes": [],
|
|
132
|
+
"edges": [
|
|
133
|
+
{ "type": "rendersTo", "from": "doc.srs.3-use-cases", "to": "docs/srs/3-use-cases.md" },
|
|
134
|
+
{ "type": "dependsOn", "from": "doc.srs.3-use-cases", "to": "doc.srs.1-introduction" },
|
|
135
|
+
{ "type": "dependsOn", "from": "doc.srs.3-use-cases", "to": "doc.srs.2-overall-description" }
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
```
|
|
52
139
|
|
|
53
|
-
|
|
140
|
+
**Forbidden:** finishing without `rendersTo` on all generated documents; skipping merge between **waves**; batching targets from different waves (e.g. use-cases + features-list together).
|
|
141
|
+
|
|
142
|
+
#### 3d. Log
|
|
143
|
+
|
|
144
|
+
Append to `.ai-spector/.docflow/logs/generate-srs.log` (create if needed): timestamp, seed, path, validate OK.
|
|
145
|
+
|
|
146
|
+
### 4. Finish
|
|
147
|
+
|
|
148
|
+
- Final `ai-spector graph validate`.
|
|
149
|
+
- Optional: `/visualize-graph` for user review.
|
|
150
|
+
- Suggest `/index-docs srs` only after graph ingest is complete.
|
|
151
|
+
|
|
152
|
+
## Waves (reference)
|
|
153
|
+
|
|
154
|
+
| Wave | DAG examples | Seed type |
|
|
155
|
+
|------|----------------|-----------|
|
|
156
|
+
| 0 | `srs.introduction`, `srs.overall-description` | `doc.srs.*` |
|
|
157
|
+
| 1 | `srs.use-cases` | `doc.srs.3-use-cases` + domain queries for §3.2 |
|
|
158
|
+
| 2 | `srs.features-list` | `doc.srs.4-system-features` |
|
|
159
|
+
| 3 | `srs.feature-details` | `F-xx` per file |
|
|
160
|
+
| 4 | data, interfaces, NFR chapters | `doc.srs.5-*` … with deps via `dependsOn` queries |
|
|
54
161
|
|
|
55
162
|
## Guardrails
|
|
56
163
|
|
|
57
|
-
-
|
|
58
|
-
-
|
|
59
|
-
-
|
|
164
|
+
- **Parallel only within a wave** — never across waves; never when A `dependsOn` B in the DAG.
|
|
165
|
+
- **Every target** gets its own `graph query` + dependency queries before write (parallel OK).
|
|
166
|
+
- **Every wave** ends with `graph merge` + `graph validate` before the next wave.
|
|
167
|
+
- On `graph query` / `merge` / `validate` failure → stop per _cli-failures.md.
|
|
168
|
+
- Prefer graph `nodes`/`edges` over `knowledge.json` for generation text.
|
|
60
169
|
|
|
61
170
|
## If blocked
|
|
62
171
|
|
|
63
|
-
|
|
172
|
+
[_cli-failures.md](./_cli-failures.md). User re-runs **`/generate-srs`** after fixes.
|
|
173
|
+
|
|
174
|
+
Common fix: run `/analyze` if domain nodes missing; run ingest merge if downstream query returns empty `rendersTo` for dependencies.
|
|
@@ -9,10 +9,13 @@ Reconcile **disk projections** (`docs/srs/`, etc.) with **graph nodes** — add
|
|
|
9
9
|
|
|
10
10
|
## When to run
|
|
11
11
|
|
|
12
|
+
- **Repair** when `/generate-srs` skipped per-file `graph merge` ingest
|
|
12
13
|
- After manual edits to markdown outside `/generate-*`
|
|
13
14
|
- Before `/validate-graph` when files exist but graph lacks `document` nodes
|
|
14
15
|
- After bulk import of SRS files
|
|
15
16
|
|
|
17
|
+
**Preferred during `/generate-srs`:** per-file `graph merge` with `projection-patch.json` (see `_generate-graph.md`) — not batch sync at the end.
|
|
18
|
+
|
|
16
19
|
## Required Behavior
|
|
17
20
|
|
|
18
21
|
1. Load `traceability.graph.json` + `section-registry.json`.
|
|
@@ -23,12 +23,13 @@ Never ignore CLI errors and “work around” with index files, manual BFS, or i
|
|
|
23
23
|
|
|
24
24
|
| Command | Agent runs CLI |
|
|
25
25
|
|---------|----------------|
|
|
26
|
-
| `/analyze` | `analyze` → Graphify → `graph merge
|
|
26
|
+
| `/analyze` | `analyze` → `graphify update` → Graphify MCP extract → `graph merge` → `graph validate` |
|
|
27
27
|
| `/validate-graph` | `graph validate` |
|
|
28
28
|
| `/visualize-graph` | `graph visualize --open` |
|
|
29
|
-
| `/generate-srs` |
|
|
29
|
+
| `/generate-srs` | All DAG, explicit paths, or natural-language scope (confirm before gen) → waves → query → write → merge |
|
|
30
30
|
| `/graph-impact` | `graph impact <id> --json` |
|
|
31
|
-
| `/generate-basic-design
|
|
31
|
+
| `/generate-basic-design` | Same as SRS: all / paths / request (**confirm**) → waves → query → merge (`dag.basic-design.*`) |
|
|
32
|
+
| `/generate-detail-design` | `graph query` per target |
|
|
32
33
|
|
|
33
34
|
Run CLI from **project workspace root**; prefer `npx ai-spector` if the binary is not on PATH.
|
|
34
35
|
|
|
@@ -36,6 +37,8 @@ Run CLI from **project workspace root**; prefer `npx ai-spector` if the binary i
|
|
|
36
37
|
|
|
37
38
|
`.ai-spector/graph/traceability.graph.json`
|
|
38
39
|
|
|
39
|
-
Context: **`ai-spector graph query <seedId> --json`** —
|
|
40
|
+
Context: **`ai-spector graph query <seedId> --json`** — depth 4 for targets, depth 2 for DAG deps; use `projectionPaths`. After each generated file: **`graph merge`** projection patch with `rendersTo` + `dependsOn`. Details: `_generate-graph.md`, `_graph.md`.
|
|
41
|
+
|
|
42
|
+
**Generate:** accuracy over speed — batch only same-wave independent targets; merge + validate after each wave.
|
|
40
43
|
|
|
41
44
|
Templates: `node_modules/ai-spector/templates/` (monorepo `example/`: `../templates/`).
|
|
@@ -4,7 +4,7 @@ Put **your** input files here (briefs, notes, exports, diagrams, legacy docs) be
|
|
|
4
4
|
|
|
5
5
|
## Not your inputs: `graphify-out/`
|
|
6
6
|
|
|
7
|
-
If you see `docs/data-source/graphify-out/`,
|
|
7
|
+
If you see `docs/data-source/graphify-out/`, **Graphify `update` ran without `GRAPHIFY_OUT`** (often after `graphify update --graph …`, which is invalid). Fix: run **`ai-spector graphify update`** from the project root.
|
|
8
8
|
|
|
9
9
|
| Location | What it is |
|
|
10
10
|
|----------|------------|
|