ai-spector 0.1.6 → 0.1.7
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 +7 -2
- package/dist/cli.js +35 -2
- package/dist/cli.js.map +1 -1
- package/dist/commands/graph-impact.d.ts +12 -1
- package/dist/commands/graph-impact.d.ts.map +1 -1
- package/dist/commands/graph-impact.js +108 -2
- package/dist/commands/graph-impact.js.map +1 -1
- package/dist/commands/index-refresh.d.ts +22 -0
- package/dist/commands/index-refresh.d.ts.map +1 -0
- package/dist/commands/index-refresh.js +315 -0
- package/dist/commands/index-refresh.js.map +1 -0
- package/dist/commands/index.d.ts +22 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +315 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/graph/impact.d.ts +15 -0
- package/dist/graph/impact.d.ts.map +1 -1
- package/dist/graph/impact.js +41 -0
- package/dist/graph/impact.js.map +1 -1
- package/dist/graph/resolve.d.ts +42 -0
- package/dist/graph/resolve.d.ts.map +1 -0
- package/dist/graph/resolve.js +320 -0
- package/dist/graph/resolve.js.map +1 -0
- package/dist/index/docs-build.d.ts +40 -0
- package/dist/index/docs-build.d.ts.map +1 -0
- package/dist/index/docs-build.js +136 -0
- package/dist/index/docs-build.js.map +1 -0
- package/dist/index/docs-config.d.ts +19 -0
- package/dist/index/docs-config.d.ts.map +1 -0
- package/dist/index/docs-config.js +5 -0
- package/dist/index/docs-config.js.map +1 -0
- package/dist/util/git-diff.d.ts +12 -0
- package/dist/util/git-diff.d.ts.map +1 -0
- package/dist/util/git-diff.js +58 -0
- package/dist/util/git-diff.js.map +1 -0
- package/package.json +1 -1
- package/scaffold/.ai-spector/.docflow/config/workflow.dependencies.json +18 -18
- package/scaffold/.ai-spector/index/README.md +2 -2
- package/scaffold/.ai-spector/index/basic-design.md +1 -1
- package/scaffold/.ai-spector/index/srs.md +1 -1
- package/scaffold/.cursor/commands/_cli-failures.md +15 -0
- package/scaffold/.cursor/commands/_graph.md +16 -0
- package/scaffold/.cursor/commands/_workflow.md +4 -3
- package/scaffold/.cursor/commands/generate-basic-design.md +2 -2
- package/scaffold/.cursor/commands/generate-srs.md +1 -1
- package/scaffold/.cursor/commands/graph-impact.md +3 -43
- package/scaffold/.cursor/commands/impact.md +144 -0
- package/scaffold/.cursor/commands/index.md +52 -0
- package/scaffold/.cursor/commands/{index-docs.md → summary.md} +8 -6
- package/scaffold/.cursor/skills/ai-spector/SKILL.md +3 -1
- package/schemas/rules.impact.json +1 -1
package/README.md
CHANGED
|
@@ -29,7 +29,9 @@ Put your source files in `docs/data-source/`, open the folder in Cursor, turn on
|
|
|
29
29
|
| **`/generate-srs`** | All SRS, listed files, or a short request (agent confirms scope) — graph-first, by DAG waves |
|
|
30
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
|
+
| **`/impact`** [what changed] | Shows what to regenerate after you change something (agent resolves graph seed) |
|
|
33
|
+
| **`/index`** (or `ai-spector index`) | Rebuild graph structure, re-merge knowledge, Graphify storage, doc indexes after manual file edits |
|
|
34
|
+
| **`/summary`** (optional) | Build `.ai-spector/index/*.md` doc summaries — not the same as full `/index` |
|
|
33
35
|
|
|
34
36
|
**Typical path:**
|
|
35
37
|
|
|
@@ -142,7 +144,10 @@ npm run init:example
|
|
|
142
144
|
| `ai-spector graph validate` | Rules check |
|
|
143
145
|
| `ai-spector graph visualize [--open]` | HTML report |
|
|
144
146
|
| `ai-spector graph query <id> --json` | Context for generation |
|
|
145
|
-
| `ai-spector graph impact <id> --json` | Regen scope |
|
|
147
|
+
| `ai-spector graph impact <id> --json` | Regen scope (or `--file` / `--heading` / `--git` for current diff) |
|
|
148
|
+
| `ai-spector index` | Refresh graph + knowledge merge + Graphify + `.ai-spector/index/` (see flags below) |
|
|
149
|
+
|
|
150
|
+
**`ai-spector index` flags:** `--graph-only`, `--docs-only`, `--skip-graphify`, `--skip-docs`, `--skip-merge`, `--skip-validate`
|
|
146
151
|
|
|
147
152
|
Option: `-r <path>` to point at another project root.
|
|
148
153
|
|
package/dist/cli.js
CHANGED
|
@@ -13,6 +13,7 @@ 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
15
|
import { runGraphifyUpdate } from "./commands/graphify-update.js";
|
|
16
|
+
import { runIndex } from "./commands/index.js";
|
|
16
17
|
const program = new Command();
|
|
17
18
|
program
|
|
18
19
|
.name("ai-spector")
|
|
@@ -36,6 +37,26 @@ program
|
|
|
36
37
|
force: opts.force,
|
|
37
38
|
});
|
|
38
39
|
});
|
|
40
|
+
program
|
|
41
|
+
.command("index")
|
|
42
|
+
.description("Refresh graph, knowledge merge, Graphify storage, and doc indexes from current project files")
|
|
43
|
+
.option("--graph-only", "Only registry + bootstrap + merge + validate (no Graphify, no doc indexes)")
|
|
44
|
+
.option("--docs-only", "Only rebuild .ai-spector/index/*.md and state hashes")
|
|
45
|
+
.option("--skip-graphify", "Skip Graphify update (code graph / graphify-index)")
|
|
46
|
+
.option("--skip-docs", "Skip .ai-spector/index document indexes")
|
|
47
|
+
.option("--skip-merge", "Skip merging knowledge.json into graph")
|
|
48
|
+
.option("--skip-validate", "Skip graph validate after refresh")
|
|
49
|
+
.action(async (opts, cmd) => {
|
|
50
|
+
await runIndex({
|
|
51
|
+
root: projectRootOpt(cmd),
|
|
52
|
+
graphOnly: opts.graphOnly,
|
|
53
|
+
docsOnly: opts.docsOnly,
|
|
54
|
+
skipGraphify: opts.skipGraphify,
|
|
55
|
+
skipDocs: opts.skipDocs,
|
|
56
|
+
skipMerge: opts.skipMerge,
|
|
57
|
+
skipValidate: opts.skipValidate,
|
|
58
|
+
});
|
|
59
|
+
});
|
|
39
60
|
program
|
|
40
61
|
.command("analyze")
|
|
41
62
|
.description("Prepare graph structure (registry + bootstrap). Normally invoked by /analyze, not the user.")
|
|
@@ -101,17 +122,29 @@ graph
|
|
|
101
122
|
});
|
|
102
123
|
});
|
|
103
124
|
graph
|
|
104
|
-
.command("impact
|
|
105
|
-
.description("Impact analysis: regenerate / review / downstream buckets")
|
|
125
|
+
.command("impact [id]")
|
|
126
|
+
.description("Impact analysis: regenerate / review / downstream buckets (id optional with --file / --heading / --git)")
|
|
127
|
+
.option("--file <path>", "Resolve origin from repo-relative doc path")
|
|
128
|
+
.option("--heading <text>", "Resolve section by heading (optionally scoped with --file)")
|
|
129
|
+
.option("--git", "Resolve seeds from current git diff (staged + unstaged) and merge impact")
|
|
106
130
|
.option("--change <type>", "Change type", "content_change")
|
|
107
131
|
.option("-o, --output <path>", "Write impact report JSON")
|
|
108
132
|
.option("--json", "Print JSON")
|
|
109
133
|
.action(async (id, opts, cmd) => {
|
|
110
134
|
const paths = await getPaths(cmd);
|
|
135
|
+
if (!id && !opts.file && !opts.heading && !opts.git) {
|
|
136
|
+
console.error("Provide <nodeId>, --file <path>, --heading <text>, or --git to resolve the change origin.");
|
|
137
|
+
process.exitCode = 1;
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
111
140
|
await runGraphImpact({
|
|
112
141
|
graphPath: paths.graph,
|
|
113
142
|
rulesPath: paths.rulesImpact,
|
|
143
|
+
projectRoot: paths.root,
|
|
114
144
|
originId: id,
|
|
145
|
+
file: opts.file,
|
|
146
|
+
heading: opts.heading,
|
|
147
|
+
git: opts.git,
|
|
115
148
|
change: opts.change,
|
|
116
149
|
output: opts.output,
|
|
117
150
|
json: opts.json,
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,21 @@
|
|
|
1
|
+
import { loadInMemoryGraph } from "../graph/loadGraph.js";
|
|
2
|
+
import { type ResolvedOrigin } from "../graph/resolve.js";
|
|
1
3
|
export interface GraphImpactCliOptions {
|
|
2
4
|
graphPath: string;
|
|
3
5
|
rulesPath: string;
|
|
4
|
-
|
|
6
|
+
projectRoot: string;
|
|
7
|
+
originId?: string;
|
|
8
|
+
file?: string;
|
|
9
|
+
heading?: string;
|
|
10
|
+
git?: boolean;
|
|
5
11
|
change: string;
|
|
6
12
|
output?: string;
|
|
7
13
|
json?: boolean;
|
|
8
14
|
}
|
|
15
|
+
export declare function resolveImpactOriginId(g: Awaited<ReturnType<typeof loadInMemoryGraph>>, opts: Pick<GraphImpactCliOptions, "originId" | "file" | "heading">): {
|
|
16
|
+
originId: string;
|
|
17
|
+
resolved?: ResolvedOrigin;
|
|
18
|
+
};
|
|
19
|
+
export declare function runGraphImpactFromGit(g: Awaited<ReturnType<typeof loadInMemoryGraph>>, opts: GraphImpactCliOptions): Promise<void>;
|
|
9
20
|
export declare function runGraphImpact(opts: GraphImpactCliOptions): Promise<void>;
|
|
10
21
|
//# sourceMappingURL=graph-impact.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-impact.d.ts","sourceRoot":"","sources":["../../src/commands/graph-impact.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"graph-impact.d.ts","sourceRoot":"","sources":["../../src/commands/graph-impact.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAC;AAE7B,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAgB,qBAAqB,CACnC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,EAChD,IAAI,EAAE,IAAI,CAAC,qBAAqB,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC,GACjE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE,CAqBjD;AAED,wBAAsB,qBAAqB,CACzC,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC,EAChD,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAgGf;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqC/E"}
|
|
@@ -1,12 +1,118 @@
|
|
|
1
1
|
import { mkdir } from "node:fs/promises";
|
|
2
2
|
import { dirname } from "node:path";
|
|
3
3
|
import { writeJson } from "../util/fs.js";
|
|
4
|
+
import { collectGitDiff } from "../util/git-diff.js";
|
|
4
5
|
import { loadInMemoryGraph } from "../graph/loadGraph.js";
|
|
5
|
-
import { computeImpact, loadImpactRules } from "../graph/impact.js";
|
|
6
|
+
import { computeImpact, loadImpactRules, mergeImpactResults } from "../graph/impact.js";
|
|
7
|
+
import { parseGitDiffRegions, pickPrimaryImpactOrigin, resolveFromGitDiff, resolveImpactOrigins, } from "../graph/resolve.js";
|
|
8
|
+
export function resolveImpactOriginId(g, opts) {
|
|
9
|
+
if (opts.originId?.trim()) {
|
|
10
|
+
const id = opts.originId.trim();
|
|
11
|
+
if (!g.nodesById.has(id)) {
|
|
12
|
+
throw new Error(`Unknown node id: ${id}`);
|
|
13
|
+
}
|
|
14
|
+
return { originId: id };
|
|
15
|
+
}
|
|
16
|
+
const origins = resolveImpactOrigins(g, {
|
|
17
|
+
file: opts.file,
|
|
18
|
+
heading: opts.heading,
|
|
19
|
+
nodeId: opts.originId,
|
|
20
|
+
});
|
|
21
|
+
const primary = pickPrimaryImpactOrigin(origins);
|
|
22
|
+
if (!primary) {
|
|
23
|
+
throw new Error("Could not resolve impact origin. Provide <nodeId>, or --file <path>, or --heading <text>.");
|
|
24
|
+
}
|
|
25
|
+
return { originId: primary.id, resolved: primary };
|
|
26
|
+
}
|
|
27
|
+
export async function runGraphImpactFromGit(g, opts) {
|
|
28
|
+
const collected = await collectGitDiff(opts.projectRoot);
|
|
29
|
+
if (collected.notRepo) {
|
|
30
|
+
throw new Error("Not a git repository. Describe the change (/impact <description>) or select text in the editor.");
|
|
31
|
+
}
|
|
32
|
+
if (collected.empty) {
|
|
33
|
+
throw new Error("No unstaged or staged changes. Describe the change (/impact <description>) or select text in the editor.");
|
|
34
|
+
}
|
|
35
|
+
const origins = resolveFromGitDiff(g, collected.diff);
|
|
36
|
+
if (origins.length === 0) {
|
|
37
|
+
const files = parseGitDiffRegions(collected.diff).map((r) => r.file);
|
|
38
|
+
throw new Error(`Could not map git diff to graph seeds. Changed files: ${files.join(", ") || "(none)"}. ` +
|
|
39
|
+
"Try /impact with a path or short description.");
|
|
40
|
+
}
|
|
41
|
+
const rules = await loadImpactRules(opts.rulesPath);
|
|
42
|
+
const regions = parseGitDiffRegions(collected.diff);
|
|
43
|
+
const seedsByRegion = [];
|
|
44
|
+
for (const region of regions) {
|
|
45
|
+
const regionOrigins = resolveImpactOrigins(g, {
|
|
46
|
+
file: region.file,
|
|
47
|
+
heading: region.heading,
|
|
48
|
+
sectionAnchor: region.sectionAnchor,
|
|
49
|
+
});
|
|
50
|
+
const primary = pickPrimaryImpactOrigin(regionOrigins);
|
|
51
|
+
if (primary) {
|
|
52
|
+
seedsByRegion.push(primary);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
const uniqueSeeds = new Map();
|
|
56
|
+
for (const o of seedsByRegion.length > 0 ? seedsByRegion : origins) {
|
|
57
|
+
if (!uniqueSeeds.has(o.id)) {
|
|
58
|
+
uniqueSeeds.set(o.id, o);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const results = [...uniqueSeeds.values()].map((seed) => {
|
|
62
|
+
const result = computeImpact(g, seed.id, opts.change, rules);
|
|
63
|
+
result.resolvedFrom = seed;
|
|
64
|
+
return result;
|
|
65
|
+
});
|
|
66
|
+
const gitSeeds = [...uniqueSeeds.values()].map((s) => {
|
|
67
|
+
const region = regions.find((r) => resolveImpactOrigins(g, {
|
|
68
|
+
file: r.file,
|
|
69
|
+
heading: r.heading,
|
|
70
|
+
sectionAnchor: r.sectionAnchor,
|
|
71
|
+
}).some((o) => o.id === s.id));
|
|
72
|
+
return {
|
|
73
|
+
id: s.id,
|
|
74
|
+
type: s.type,
|
|
75
|
+
reason: s.reason,
|
|
76
|
+
file: region?.file,
|
|
77
|
+
heading: region?.heading,
|
|
78
|
+
};
|
|
79
|
+
});
|
|
80
|
+
const result = results.length === 1
|
|
81
|
+
? { ...results[0], gitSeeds }
|
|
82
|
+
: mergeImpactResults(results, gitSeeds);
|
|
83
|
+
if (opts.output) {
|
|
84
|
+
await mkdir(dirname(opts.output), { recursive: true });
|
|
85
|
+
await writeJson(opts.output, result);
|
|
86
|
+
}
|
|
87
|
+
if (opts.json || opts.output) {
|
|
88
|
+
console.log(JSON.stringify(result, null, 2));
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
console.log(`Impact from git diff (${uniqueSeeds.size} seed(s))`);
|
|
92
|
+
for (const [bucket, entries] of Object.entries(result.affected)) {
|
|
93
|
+
console.log(`\n${bucket}:`);
|
|
94
|
+
if (entries.length === 0) {
|
|
95
|
+
console.log(" (none)");
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
for (const e of entries) {
|
|
99
|
+
const path = e.projectionPath ? ` → ${e.projectionPath}` : "";
|
|
100
|
+
console.log(` - ${e.id} (${e.type})${path}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
6
104
|
export async function runGraphImpact(opts) {
|
|
7
105
|
const g = await loadInMemoryGraph(opts.graphPath);
|
|
106
|
+
if (opts.git) {
|
|
107
|
+
await runGraphImpactFromGit(g, opts);
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const { originId, resolved } = resolveImpactOriginId(g, opts);
|
|
8
111
|
const rules = await loadImpactRules(opts.rulesPath);
|
|
9
|
-
const result = computeImpact(g,
|
|
112
|
+
const result = computeImpact(g, originId, opts.change, rules);
|
|
113
|
+
if (resolved) {
|
|
114
|
+
result.resolvedFrom = resolved;
|
|
115
|
+
}
|
|
10
116
|
if (opts.output) {
|
|
11
117
|
await mkdir(dirname(opts.output), { recursive: true });
|
|
12
118
|
await writeJson(opts.output, result);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graph-impact.js","sourceRoot":"","sources":["../../src/commands/graph-impact.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"graph-impact.js","sourceRoot":"","sources":["../../src/commands/graph-impact.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type IndexStepStatus = "ok" | "skipped" | "failed";
|
|
2
|
+
export interface IndexStepResult {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
status: IndexStepStatus;
|
|
6
|
+
detail?: string;
|
|
7
|
+
}
|
|
8
|
+
export interface IndexRefreshOptions {
|
|
9
|
+
root?: string;
|
|
10
|
+
graphOnly?: boolean;
|
|
11
|
+
docsOnly?: boolean;
|
|
12
|
+
skipGraphify?: boolean;
|
|
13
|
+
skipDocs?: boolean;
|
|
14
|
+
skipMerge?: boolean;
|
|
15
|
+
skipValidate?: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface IndexRefreshReport {
|
|
18
|
+
steps: IndexStepResult[];
|
|
19
|
+
failed: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function runIndexRefresh(opts?: IndexRefreshOptions): Promise<IndexRefreshReport>;
|
|
22
|
+
//# sourceMappingURL=index-refresh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index-refresh.d.ts","sourceRoot":"","sources":["../../src/commands/index-refresh.ts"],"names":[],"mappings":"AA4BA,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE1D,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,eAAe,CACnC,IAAI,GAAE,mBAAwB,GAC7B,OAAO,CAAC,kBAAkB,CAAC,CA+R7B"}
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { buildSectionRegistry } from "../registry/build.js";
|
|
4
|
+
import { bootstrapFromRegistry } from "./bootstrap.js";
|
|
5
|
+
import { validateGraph, formatIssues } from "./validate.js";
|
|
6
|
+
import { runGraphMerge } from "./graph-merge.js";
|
|
7
|
+
import { runGraphifyUpdate } from "./graphify-update.js";
|
|
8
|
+
import { resolveProjectPaths } from "../util/paths.js";
|
|
9
|
+
import { pathExists, readJson, writeJson } from "../util/fs.js";
|
|
10
|
+
import { loadDocflowConfig } from "../config/load.js";
|
|
11
|
+
import { knowledgeHasDomainEntries, isKnowledgePayload, } from "../graph/knowledge.js";
|
|
12
|
+
import { computeKnowledgeStats } from "../visualize/stats.js";
|
|
13
|
+
import { loadInMemoryGraph } from "../graph/loadGraph.js";
|
|
14
|
+
import { indexDocsConfigPath, } from "../index/docs-config.js";
|
|
15
|
+
import { buildDocIndex, computeIndexSourceHash, discoverMarkdownFiles, } from "../index/docs-build.js";
|
|
16
|
+
export async function runIndexRefresh(opts = {}) {
|
|
17
|
+
const paths = await resolveProjectPaths(opts.root);
|
|
18
|
+
const { root: projectRoot } = await loadDocflowConfig(opts.root);
|
|
19
|
+
const steps = [];
|
|
20
|
+
let failed = false;
|
|
21
|
+
const record = (step) => {
|
|
22
|
+
steps.push(step);
|
|
23
|
+
if (step.status === "failed") {
|
|
24
|
+
failed = true;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const graphOnly = opts.graphOnly === true;
|
|
28
|
+
const docsOnly = opts.docsOnly === true;
|
|
29
|
+
if (graphOnly && docsOnly) {
|
|
30
|
+
throw new Error("Use only one of --graph-only or --docs-only");
|
|
31
|
+
}
|
|
32
|
+
const runGraph = !docsOnly;
|
|
33
|
+
const runDocs = !graphOnly && !opts.skipDocs;
|
|
34
|
+
const runGraphify = runGraph && !graphOnly && !opts.skipGraphify;
|
|
35
|
+
let graphJson = null;
|
|
36
|
+
if (runGraph) {
|
|
37
|
+
try {
|
|
38
|
+
const registry = await buildSectionRegistry(projectRoot);
|
|
39
|
+
await writeJson(paths.registry, registry);
|
|
40
|
+
const total = registry.documents.reduce((n, d) => n + d.sections.length, 0);
|
|
41
|
+
const graph = bootstrapFromRegistry(registry);
|
|
42
|
+
await writeJson(paths.graph, graph.toTraceabilityGraph());
|
|
43
|
+
graphJson = graph.toTraceabilityGraph();
|
|
44
|
+
const statePath = join(projectRoot, ".ai-spector/.docflow/state.json");
|
|
45
|
+
const state = await readJson(statePath).catch(() => ({
|
|
46
|
+
version: 1,
|
|
47
|
+
analysis: {},
|
|
48
|
+
index: {},
|
|
49
|
+
}));
|
|
50
|
+
const analysis = state.analysis ?? {};
|
|
51
|
+
analysis.graphPreparedAt = new Date().toISOString();
|
|
52
|
+
analysis.indexRefreshedAt = new Date().toISOString();
|
|
53
|
+
state.analysis = analysis;
|
|
54
|
+
await writeJson(statePath, state);
|
|
55
|
+
record({
|
|
56
|
+
id: "graph-structure",
|
|
57
|
+
label: "Traceability graph structure",
|
|
58
|
+
status: "ok",
|
|
59
|
+
detail: `${registry.documents.length} documents, ${total} sections → ${paths.graph}`,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
record({
|
|
64
|
+
id: "graph-structure",
|
|
65
|
+
label: "Traceability graph structure",
|
|
66
|
+
status: "failed",
|
|
67
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (!opts.skipMerge && !failed) {
|
|
71
|
+
const knowledgePath = join(projectRoot, ".ai-spector/.docflow/analysis/knowledge.json");
|
|
72
|
+
try {
|
|
73
|
+
if (!(await pathExists(knowledgePath))) {
|
|
74
|
+
record({
|
|
75
|
+
id: "knowledge-merge",
|
|
76
|
+
label: "Knowledge → graph merge",
|
|
77
|
+
status: "skipped",
|
|
78
|
+
detail: `No ${knowledgePath} — run /analyze in Cursor to extract knowledge first`,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
const raw = await readJson(knowledgePath);
|
|
83
|
+
if (!isKnowledgePayload(raw) || !knowledgeHasDomainEntries(raw)) {
|
|
84
|
+
record({
|
|
85
|
+
id: "knowledge-merge",
|
|
86
|
+
label: "Knowledge → graph merge",
|
|
87
|
+
status: "skipped",
|
|
88
|
+
detail: "knowledge.json has no domain entries yet",
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
await runGraphMerge({
|
|
93
|
+
root: projectRoot,
|
|
94
|
+
fromKnowledge: true,
|
|
95
|
+
graphPath: paths.graph,
|
|
96
|
+
validate: false,
|
|
97
|
+
});
|
|
98
|
+
graphJson = await readJson(paths.graph);
|
|
99
|
+
const ks = computeKnowledgeStats(raw);
|
|
100
|
+
record({
|
|
101
|
+
id: "knowledge-merge",
|
|
102
|
+
label: "Knowledge → graph merge",
|
|
103
|
+
status: "ok",
|
|
104
|
+
detail: `${ks.useCases} use cases, ${ks.features} features, ${ks.actors} actors merged`,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
record({
|
|
111
|
+
id: "knowledge-merge",
|
|
112
|
+
label: "Knowledge → graph merge",
|
|
113
|
+
status: "failed",
|
|
114
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
else if (opts.skipMerge) {
|
|
119
|
+
record({
|
|
120
|
+
id: "knowledge-merge",
|
|
121
|
+
label: "Knowledge → graph merge",
|
|
122
|
+
status: "skipped",
|
|
123
|
+
detail: "--skip-merge",
|
|
124
|
+
});
|
|
125
|
+
if (!failed) {
|
|
126
|
+
try {
|
|
127
|
+
graphJson = (await loadInMemoryGraph(paths.graph)).toTraceabilityGraph();
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
graphJson = null;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (runGraphify && !failed) {
|
|
135
|
+
try {
|
|
136
|
+
await runGraphifyUpdate({ root: projectRoot });
|
|
137
|
+
record({
|
|
138
|
+
id: "graphify-storage",
|
|
139
|
+
label: "Graphify index & graph.json",
|
|
140
|
+
status: "ok",
|
|
141
|
+
detail: ".ai-spector/.docflow/graph/graphify-out/",
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
catch (err) {
|
|
145
|
+
record({
|
|
146
|
+
id: "graphify-storage",
|
|
147
|
+
label: "Graphify index & graph.json",
|
|
148
|
+
status: "failed",
|
|
149
|
+
detail: (err instanceof Error ? err.message : String(err)) +
|
|
150
|
+
" (retry with graphify installed, or use --skip-graphify)",
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else if (!runGraphify) {
|
|
155
|
+
record({
|
|
156
|
+
id: "graphify-storage",
|
|
157
|
+
label: "Graphify index & graph.json",
|
|
158
|
+
status: "skipped",
|
|
159
|
+
detail: opts.skipGraphify ? "--skip-graphify" : "graph-only / docs-only",
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
if (!opts.skipValidate && !failed) {
|
|
163
|
+
try {
|
|
164
|
+
const issues = await validateGraph({
|
|
165
|
+
graphPath: paths.graph,
|
|
166
|
+
schemaPath: paths.schema,
|
|
167
|
+
registryPath: paths.registry,
|
|
168
|
+
rulesPath: paths.rulesTraceability,
|
|
169
|
+
});
|
|
170
|
+
const errors = issues.filter((i) => i.severity === "error");
|
|
171
|
+
if (errors.length > 0) {
|
|
172
|
+
record({
|
|
173
|
+
id: "graph-validate",
|
|
174
|
+
label: "Graph validate",
|
|
175
|
+
status: "failed",
|
|
176
|
+
detail: formatIssues(errors).trim(),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
const warns = issues.filter((i) => i.severity === "warn").length;
|
|
181
|
+
record({
|
|
182
|
+
id: "graph-validate",
|
|
183
|
+
label: "Graph validate",
|
|
184
|
+
status: "ok",
|
|
185
|
+
detail: warns > 0 ? `OK (${warns} warnings)` : "OK",
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch (err) {
|
|
190
|
+
record({
|
|
191
|
+
id: "graph-validate",
|
|
192
|
+
label: "Graph validate",
|
|
193
|
+
status: "failed",
|
|
194
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
record({
|
|
200
|
+
id: "graph-validate",
|
|
201
|
+
label: "Graph validate",
|
|
202
|
+
status: "skipped",
|
|
203
|
+
detail: opts.skipValidate ? "--skip-validate" : "prior step failed",
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (runDocs) {
|
|
208
|
+
const configPath = indexDocsConfigPath(projectRoot);
|
|
209
|
+
try {
|
|
210
|
+
if (!(await pathExists(configPath))) {
|
|
211
|
+
record({
|
|
212
|
+
id: "docs-index",
|
|
213
|
+
label: "Document indexes (.ai-spector/index/)",
|
|
214
|
+
status: "skipped",
|
|
215
|
+
detail: `Missing ${configPath} — run ai-spector init`,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
const config = await readJson(configPath);
|
|
220
|
+
if (!graphJson) {
|
|
221
|
+
try {
|
|
222
|
+
graphJson = (await loadInMemoryGraph(paths.graph)).toTraceabilityGraph();
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
graphJson = null;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
const indexedAt = new Date().toISOString();
|
|
229
|
+
const hashes = {};
|
|
230
|
+
for (const kind of ["srs", "basicDesign"]) {
|
|
231
|
+
const sourceKey = kind === "srs" ? "srs" : "basicDesign";
|
|
232
|
+
const source = config.sources[sourceKey];
|
|
233
|
+
if (!source) {
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
const files = await discoverMarkdownFiles(projectRoot, source.root, source.glob ?? "**/*.md");
|
|
237
|
+
hashes[sourceKey] = computeIndexSourceHash(files);
|
|
238
|
+
const built = await buildDocIndex({
|
|
239
|
+
kind,
|
|
240
|
+
config,
|
|
241
|
+
projectRoot,
|
|
242
|
+
files,
|
|
243
|
+
graph: graphJson,
|
|
244
|
+
indexedAt,
|
|
245
|
+
});
|
|
246
|
+
const outPath = join(projectRoot, config.outputs[sourceKey]);
|
|
247
|
+
await mkdir(dirname(outPath), { recursive: true });
|
|
248
|
+
await writeFile(outPath, built.markdown, "utf8");
|
|
249
|
+
}
|
|
250
|
+
const statePath = join(projectRoot, ".ai-spector/.docflow/state.json");
|
|
251
|
+
const state = await readJson(statePath).catch(() => ({
|
|
252
|
+
version: 1,
|
|
253
|
+
index: {},
|
|
254
|
+
}));
|
|
255
|
+
const indexState = state.index ?? {};
|
|
256
|
+
indexState.lastRunAt = indexedAt;
|
|
257
|
+
indexState.sourceHashes = hashes;
|
|
258
|
+
state.index = indexState;
|
|
259
|
+
await writeJson(statePath, state);
|
|
260
|
+
record({
|
|
261
|
+
id: "docs-index",
|
|
262
|
+
label: "Document indexes (.ai-spector/index/)",
|
|
263
|
+
status: "ok",
|
|
264
|
+
detail: `srs hash ${hashes.srs ?? "—"}, basic-design hash ${hashes.basicDesign ?? "—"}`,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
catch (err) {
|
|
269
|
+
record({
|
|
270
|
+
id: "docs-index",
|
|
271
|
+
label: "Document indexes (.ai-spector/index/)",
|
|
272
|
+
status: "failed",
|
|
273
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
else {
|
|
278
|
+
record({
|
|
279
|
+
id: "docs-index",
|
|
280
|
+
label: "Document indexes (.ai-spector/index/)",
|
|
281
|
+
status: "skipped",
|
|
282
|
+
detail: graphOnly || opts.skipDocs ? "--graph-only or --skip-docs" : "docs-only graph skipped",
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
printIndexSummary(steps, failed);
|
|
286
|
+
if (failed) {
|
|
287
|
+
const first = steps.find((s) => s.status === "failed");
|
|
288
|
+
throw new Error(`Index refresh incomplete${first ? ` (${first.label})` : ""}. Fix errors above and re-run: ai-spector index`);
|
|
289
|
+
}
|
|
290
|
+
return { steps, failed };
|
|
291
|
+
}
|
|
292
|
+
function printIndexSummary(steps, failed) {
|
|
293
|
+
console.log("");
|
|
294
|
+
console.log("Index refresh summary");
|
|
295
|
+
console.log("─────────────────────");
|
|
296
|
+
for (const s of steps) {
|
|
297
|
+
const icon = s.status === "ok" ? "✓" : s.status === "skipped" ? "○" : "✗";
|
|
298
|
+
console.log(` ${icon} ${s.label}: ${s.status}`);
|
|
299
|
+
if (s.detail) {
|
|
300
|
+
for (const line of s.detail.split("\n")) {
|
|
301
|
+
console.log(` ${line}`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
console.log("");
|
|
306
|
+
if (failed) {
|
|
307
|
+
console.log("Some steps failed. Graph/knowledge may be partially updated.");
|
|
308
|
+
console.log("Re-run after fixing, or use flags: --skip-graphify, --skip-merge, --graph-only");
|
|
309
|
+
}
|
|
310
|
+
else {
|
|
311
|
+
console.log("All requested steps completed.");
|
|
312
|
+
console.log("Semantic knowledge re-extract still requires /analyze in Cursor (Graphify MCP).");
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
//# sourceMappingURL=index-refresh.js.map
|