openlore 2.0.7 → 2.0.9
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 +160 -25
- package/dist/api/init.d.ts.map +1 -1
- package/dist/api/init.js +9 -2
- package/dist/api/init.js.map +1 -1
- package/dist/cli/commands/analyze.d.ts.map +1 -1
- package/dist/cli/commands/analyze.js +5 -3
- package/dist/cli/commands/analyze.js.map +1 -1
- package/dist/cli/commands/decisions.d.ts +0 -1
- package/dist/cli/commands/decisions.d.ts.map +1 -1
- package/dist/cli/commands/decisions.js +19 -31
- package/dist/cli/commands/decisions.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +85 -23
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +16 -3
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/mcp.d.ts +766 -0
- package/dist/cli/commands/mcp.d.ts.map +1 -1
- package/dist/cli/commands/mcp.js +444 -244
- package/dist/cli/commands/mcp.js.map +1 -1
- package/dist/cli/commands/orient.d.ts.map +1 -1
- package/dist/cli/commands/orient.js +14 -2
- package/dist/cli/commands/orient.js.map +1 -1
- package/dist/cli/commands/prove.d.ts +29 -0
- package/dist/cli/commands/prove.d.ts.map +1 -0
- package/dist/cli/commands/prove.js +160 -0
- package/dist/cli/commands/prove.js.map +1 -0
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +5 -3
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/index.js +2 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/install/adapters/claude-code.d.ts +8 -2
- package/dist/cli/install/adapters/claude-code.d.ts.map +1 -1
- package/dist/cli/install/adapters/claude-code.js +99 -35
- package/dist/cli/install/adapters/claude-code.js.map +1 -1
- package/dist/cli/install/detect.d.ts.map +1 -1
- package/dist/cli/install/detect.js +14 -0
- package/dist/cli/install/detect.js.map +1 -1
- package/dist/cli/install/templates/agent-instructions.md +4 -2
- package/dist/constants.d.ts +16 -3
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +24 -3
- package/dist/constants.js.map +1 -1
- package/dist/core/agent-eval/measure.d.ts +57 -0
- package/dist/core/agent-eval/measure.d.ts.map +1 -0
- package/dist/core/agent-eval/measure.js +85 -0
- package/dist/core/agent-eval/measure.js.map +1 -0
- package/dist/core/agent-eval/scorecard.d.ts +37 -0
- package/dist/core/agent-eval/scorecard.d.ts.map +1 -0
- package/dist/core/agent-eval/scorecard.js +70 -0
- package/dist/core/agent-eval/scorecard.js.map +1 -0
- package/dist/core/agent-eval/tasks.d.ts +37 -0
- package/dist/core/agent-eval/tasks.d.ts.map +1 -0
- package/dist/core/agent-eval/tasks.js +76 -0
- package/dist/core/agent-eval/tasks.js.map +1 -0
- package/dist/core/analyzer/architecture-writer.d.ts +5 -3
- package/dist/core/analyzer/architecture-writer.d.ts.map +1 -1
- package/dist/core/analyzer/architecture-writer.js +6 -4
- package/dist/core/analyzer/architecture-writer.js.map +1 -1
- package/dist/core/analyzer/artifact-generator.d.ts.map +1 -1
- package/dist/core/analyzer/artifact-generator.js +59 -4
- package/dist/core/analyzer/artifact-generator.js.map +1 -1
- package/dist/core/analyzer/call-graph.d.ts +19 -1
- package/dist/core/analyzer/call-graph.d.ts.map +1 -1
- package/dist/core/analyzer/call-graph.js +130 -28
- package/dist/core/analyzer/call-graph.js.map +1 -1
- package/dist/core/analyzer/spec-vector-index.d.ts.map +1 -1
- package/dist/core/analyzer/spec-vector-index.js +6 -2
- package/dist/core/analyzer/spec-vector-index.js.map +1 -1
- package/dist/core/architecture/check.d.ts +63 -0
- package/dist/core/architecture/check.d.ts.map +1 -0
- package/dist/core/architecture/check.js +192 -0
- package/dist/core/architecture/check.js.map +1 -0
- package/dist/core/architecture/rules.d.ts +73 -0
- package/dist/core/architecture/rules.d.ts.map +1 -0
- package/dist/core/architecture/rules.js +201 -0
- package/dist/core/architecture/rules.js.map +1 -0
- package/dist/core/decisions/project.d.ts +59 -0
- package/dist/core/decisions/project.d.ts.map +1 -0
- package/dist/core/decisions/project.js +68 -0
- package/dist/core/decisions/project.js.map +1 -0
- package/dist/core/decisions/verifier.d.ts +10 -0
- package/dist/core/decisions/verifier.d.ts.map +1 -1
- package/dist/core/decisions/verifier.js +48 -5
- package/dist/core/decisions/verifier.js.map +1 -1
- package/dist/core/provenance/change-coupling.d.ts +68 -0
- package/dist/core/provenance/change-coupling.d.ts.map +1 -0
- package/dist/core/provenance/change-coupling.js +134 -0
- package/dist/core/provenance/change-coupling.js.map +1 -0
- package/dist/core/provenance/git-provenance.d.ts +67 -0
- package/dist/core/provenance/git-provenance.d.ts.map +1 -0
- package/dist/core/provenance/git-provenance.js +177 -0
- package/dist/core/provenance/git-provenance.js.map +1 -0
- package/dist/core/provenance/project.d.ts +37 -0
- package/dist/core/provenance/project.d.ts.map +1 -0
- package/dist/core/provenance/project.js +46 -0
- package/dist/core/provenance/project.js.map +1 -0
- package/dist/core/services/config-manager.d.ts +17 -0
- package/dist/core/services/config-manager.d.ts.map +1 -1
- package/dist/core/services/config-manager.js +35 -1
- package/dist/core/services/config-manager.js.map +1 -1
- package/dist/core/services/edge-store.d.ts +41 -0
- package/dist/core/services/edge-store.d.ts.map +1 -1
- package/dist/core/services/edge-store.js +251 -3
- package/dist/core/services/edge-store.js.map +1 -1
- package/dist/core/services/llm-service.d.ts +9 -0
- package/dist/core/services/llm-service.d.ts.map +1 -1
- package/dist/core/services/llm-service.js +15 -4
- package/dist/core/services/llm-service.js.map +1 -1
- package/dist/core/services/mcp-handlers/architecture.d.ts +19 -0
- package/dist/core/services/mcp-handlers/architecture.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/architecture.js +104 -0
- package/dist/core/services/mcp-handlers/architecture.js.map +1 -0
- package/dist/core/services/mcp-handlers/change-coupling.d.ts +16 -0
- package/dist/core/services/mcp-handlers/change-coupling.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/change-coupling.js +57 -0
- package/dist/core/services/mcp-handlers/change-coupling.js.map +1 -0
- package/dist/core/services/mcp-handlers/graph.d.ts +27 -0
- package/dist/core/services/mcp-handlers/graph.d.ts.map +1 -1
- package/dist/core/services/mcp-handlers/graph.js +98 -16
- package/dist/core/services/mcp-handlers/graph.js.map +1 -1
- package/dist/core/services/mcp-handlers/orient.d.ts +1 -1
- package/dist/core/services/mcp-handlers/orient.d.ts.map +1 -1
- package/dist/core/services/mcp-handlers/orient.js +196 -39
- package/dist/core/services/mcp-handlers/orient.js.map +1 -1
- package/dist/core/services/mcp-handlers/progressive.d.ts +46 -0
- package/dist/core/services/mcp-handlers/progressive.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/progressive.js +0 -0
- package/dist/core/services/mcp-handlers/progressive.js.map +1 -0
- package/dist/core/services/mcp-handlers/reachability.d.ts +30 -0
- package/dist/core/services/mcp-handlers/reachability.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/reachability.js +222 -0
- package/dist/core/services/mcp-handlers/reachability.js.map +1 -0
- package/dist/core/services/mcp-handlers/semantic.d.ts +1 -1
- package/dist/core/services/mcp-handlers/semantic.d.ts.map +1 -1
- package/dist/core/services/mcp-handlers/semantic.js +39 -26
- package/dist/core/services/mcp-handlers/semantic.js.map +1 -1
- package/dist/core/services/mcp-handlers/structural-diff.d.ts +31 -0
- package/dist/core/services/mcp-handlers/structural-diff.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/structural-diff.js +268 -0
- package/dist/core/services/mcp-handlers/structural-diff.js.map +1 -0
- package/dist/core/services/mcp-handlers/test-impact.d.ts +34 -0
- package/dist/core/services/mcp-handlers/test-impact.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/test-impact.js +221 -0
- package/dist/core/services/mcp-handlers/test-impact.js.map +1 -0
- package/dist/core/services/mcp-handlers/tool-guard.d.ts +45 -0
- package/dist/core/services/mcp-handlers/tool-guard.d.ts.map +1 -0
- package/dist/core/services/mcp-handlers/tool-guard.js +81 -0
- package/dist/core/services/mcp-handlers/tool-guard.js.map +1 -0
- package/dist/core/services/mcp-handlers/utils.d.ts.map +1 -1
- package/dist/core/services/mcp-handlers/utils.js +15 -1
- package/dist/core/services/mcp-handlers/utils.js.map +1 -1
- package/dist/core/services/mcp-watcher.d.ts +7 -0
- package/dist/core/services/mcp-watcher.d.ts.map +1 -1
- package/dist/core/services/mcp-watcher.js +46 -0
- package/dist/core/services/mcp-watcher.js.map +1 -1
- package/dist/core/services/project-detector.d.ts.map +1 -1
- package/dist/core/services/project-detector.js +45 -2
- package/dist/core/services/project-detector.js.map +1 -1
- package/package.json +8 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-provenance.js","sourceRoot":"","sources":["../../../src/core/provenance/git-provenance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projection: per-file provenance → typed `authored_by` / `changed_in_pr` graph
|
|
3
|
+
* edges (spec-18). The decisions/IaC analogue: git history is the authored source;
|
|
4
|
+
* this projection is derived and regenerable. Edges hang off existing file nodes —
|
|
5
|
+
* no person/PR nodes are added to the call graph, keeping it un-bloated (the cap is
|
|
6
|
+
* applied upstream in the extractor).
|
|
7
|
+
*
|
|
8
|
+
* Edge direction is code → context: a file is `authored_by` a person and
|
|
9
|
+
* `changed_in_pr` a pull request.
|
|
10
|
+
*/
|
|
11
|
+
import type { FileProvenance } from './git-provenance.js';
|
|
12
|
+
/** file → person. `role: 'last'` marks the last-touch author. */
|
|
13
|
+
export interface AuthoredByEdge {
|
|
14
|
+
kind: 'authored_by';
|
|
15
|
+
filePath: string;
|
|
16
|
+
name: string;
|
|
17
|
+
email: string;
|
|
18
|
+
/** Author date of the last-touch commit (only meaningful for role 'last'). */
|
|
19
|
+
lastDate?: string;
|
|
20
|
+
role: 'last' | 'recent';
|
|
21
|
+
}
|
|
22
|
+
/** file → pull request. `title`/`state` present only when `gh` enrichment succeeded. */
|
|
23
|
+
export interface ChangedInPrEdge {
|
|
24
|
+
kind: 'changed_in_pr';
|
|
25
|
+
filePath: string;
|
|
26
|
+
pr: number;
|
|
27
|
+
title?: string;
|
|
28
|
+
state?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface ProjectedProvenance {
|
|
31
|
+
authoredBy: AuthoredByEdge[];
|
|
32
|
+
changedInPr: ChangedInPrEdge[];
|
|
33
|
+
}
|
|
34
|
+
/** "Name <email>" display key for a person (stable identity). */
|
|
35
|
+
export declare function personKey(name: string, email: string): string;
|
|
36
|
+
export declare function projectProvenance(records: FileProvenance[]): ProjectedProvenance;
|
|
37
|
+
//# sourceMappingURL=project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../../src/core/provenance/project.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,iEAAiE;AACjE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;CACzB;AAED,wFAAwF;AACxF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,eAAe,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,WAAW,EAAE,eAAe,EAAE,CAAC;CAChC;AAED,iEAAiE;AACjE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAE7D;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,mBAAmB,CAgChF"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projection: per-file provenance → typed `authored_by` / `changed_in_pr` graph
|
|
3
|
+
* edges (spec-18). The decisions/IaC analogue: git history is the authored source;
|
|
4
|
+
* this projection is derived and regenerable. Edges hang off existing file nodes —
|
|
5
|
+
* no person/PR nodes are added to the call graph, keeping it un-bloated (the cap is
|
|
6
|
+
* applied upstream in the extractor).
|
|
7
|
+
*
|
|
8
|
+
* Edge direction is code → context: a file is `authored_by` a person and
|
|
9
|
+
* `changed_in_pr` a pull request.
|
|
10
|
+
*/
|
|
11
|
+
/** "Name <email>" display key for a person (stable identity). */
|
|
12
|
+
export function personKey(name, email) {
|
|
13
|
+
return email ? `${name} <${email}>` : name;
|
|
14
|
+
}
|
|
15
|
+
export function projectProvenance(records) {
|
|
16
|
+
const authoredBy = [];
|
|
17
|
+
const changedInPr = [];
|
|
18
|
+
for (const r of [...records].sort((a, b) => a.filePath.localeCompare(b.filePath))) {
|
|
19
|
+
// Last-touch author first, then the remaining recent authors (deduped).
|
|
20
|
+
authoredBy.push({
|
|
21
|
+
kind: 'authored_by',
|
|
22
|
+
filePath: r.filePath,
|
|
23
|
+
name: r.lastAuthor.name,
|
|
24
|
+
email: r.lastAuthor.email,
|
|
25
|
+
lastDate: r.lastDate,
|
|
26
|
+
role: 'last',
|
|
27
|
+
});
|
|
28
|
+
const lastKey = personKey(r.lastAuthor.name, r.lastAuthor.email);
|
|
29
|
+
for (const a of r.recentAuthors) {
|
|
30
|
+
if (personKey(a.name, a.email) === lastKey)
|
|
31
|
+
continue;
|
|
32
|
+
authoredBy.push({ kind: 'authored_by', filePath: r.filePath, name: a.name, email: a.email, role: 'recent' });
|
|
33
|
+
}
|
|
34
|
+
for (const pr of r.prs) {
|
|
35
|
+
changedInPr.push({
|
|
36
|
+
kind: 'changed_in_pr',
|
|
37
|
+
filePath: r.filePath,
|
|
38
|
+
pr: pr.number,
|
|
39
|
+
...(pr.title ? { title: pr.title } : {}),
|
|
40
|
+
...(pr.state ? { state: pr.state } : {}),
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return { authoredBy, changedInPr };
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/core/provenance/project.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AA6BH,iEAAiE;AACjE,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,KAAa;IACnD,OAAO,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAyB;IACzD,MAAM,UAAU,GAAqB,EAAE,CAAC;IACxC,MAAM,WAAW,GAAsB,EAAE,CAAC;IAE1C,KAAK,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;QAClF,wEAAwE;QACxE,UAAU,CAAC,IAAI,CAAC;YACd,IAAI,EAAE,aAAa;YACnB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,IAAI;YACvB,KAAK,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK;YACzB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,IAAI,EAAE,MAAM;SACb,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACjE,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,CAAC;YAChC,IAAI,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,OAAO;gBAAE,SAAS;YACrD,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC/G,CAAC;QAED,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;YACvB,WAAW,CAAC,IAAI,CAAC;gBACf,IAAI,EAAE,eAAe;gBACrB,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,EAAE,EAAE,EAAE,CAAC,MAAM;gBACb,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACxC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACzC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;AACrC,CAAC"}
|
|
@@ -54,6 +54,23 @@ export declare function openspecConfigExists(openspecPath: string): Promise<bool
|
|
|
54
54
|
* Create minimal OpenSpec directory structure
|
|
55
55
|
*/
|
|
56
56
|
export declare function createOpenSpecStructure(openspecPath: string): Promise<void>;
|
|
57
|
+
/** A spec directory discovered on disk before `init` decides where to point. */
|
|
58
|
+
export interface DetectedSpecDir {
|
|
59
|
+
/** openspec-root, relative to the project root (config `openspecPath`). */
|
|
60
|
+
root: string;
|
|
61
|
+
/** The `<root>/specs` directory, relative to the project root. */
|
|
62
|
+
specsRel: string;
|
|
63
|
+
/** Count of `*.md` files found beneath the specs dir. */
|
|
64
|
+
count: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Detect an existing specs directory so `init` does not create an empty
|
|
68
|
+
* `openspec/` blind to specs that already live in `docs/specs/` or `specs/`
|
|
69
|
+
* (Spec 26 B5). Candidate openspec-roots are scanned in priority order; the
|
|
70
|
+
* first whose `<root>/specs` contains at least one `*.md` wins. Returns null
|
|
71
|
+
* when nothing is found.
|
|
72
|
+
*/
|
|
73
|
+
export declare function detectExistingSpecDir(rootPath: string): Promise<DetectedSpecDir | null>;
|
|
57
74
|
/**
|
|
58
75
|
* Merge existing OpenSpec config with openlore metadata
|
|
59
76
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-manager.d.ts","sourceRoot":"","sources":["../../../src/core/services/config-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAYxE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE;QACX,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAgBD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,cAAc,CAiB/F;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAezF;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE7E;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAc7F;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE9E;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEjF;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,cAAc,GAAG,IAAI,EAC/B,YAAY,EAAE,cAAc,CAAC,UAAU,CAAC,GACvC,cAAc,CAgBhB"}
|
|
1
|
+
{"version":3,"file":"config-manager.d.ts","sourceRoot":"","sources":["../../../src/core/services/config-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAYxE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE;QACX,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QACnB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAgBD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,GAAG,cAAc,CAiB/F;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAezF;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE7E;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAc7F;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,cAAc,GACrB,OAAO,CAAC,IAAI,CAAC,CAKf;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE9E;AAED;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAEjF;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGjF;AAED,gFAAgF;AAChF,MAAM,WAAW,eAAe;IAC9B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAsB7F;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,cAAc,GAAG,IAAI,EAC/B,YAAY,EAAE,cAAc,CAAC,UAAU,CAAC,GACvC,cAAc,CAgBhB"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Handles reading/writing .openlore/config.json and openspec/config.yaml
|
|
5
5
|
*/
|
|
6
|
-
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
6
|
+
import { mkdir, readFile, writeFile, readdir } from 'node:fs/promises';
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import YAML from 'yaml';
|
|
9
9
|
import { logger } from '../../utils/logger.js';
|
|
@@ -127,6 +127,40 @@ export async function createOpenSpecStructure(openspecPath) {
|
|
|
127
127
|
await ensureDir(openspecPath);
|
|
128
128
|
await ensureDir(join(openspecPath, 'specs'));
|
|
129
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Detect an existing specs directory so `init` does not create an empty
|
|
132
|
+
* `openspec/` blind to specs that already live in `docs/specs/` or `specs/`
|
|
133
|
+
* (Spec 26 B5). Candidate openspec-roots are scanned in priority order; the
|
|
134
|
+
* first whose `<root>/specs` contains at least one `*.md` wins. Returns null
|
|
135
|
+
* when nothing is found.
|
|
136
|
+
*/
|
|
137
|
+
export async function detectExistingSpecDir(rootPath) {
|
|
138
|
+
// root (relative) → specs live at `<root>/specs`. '.' covers a bare `specs/`.
|
|
139
|
+
const candidateRoots = ['openspec', 'docs', '.'];
|
|
140
|
+
for (const root of candidateRoots) {
|
|
141
|
+
const specsRel = root === '.' ? 'specs' : `${root}/specs`;
|
|
142
|
+
const specsDir = join(rootPath, specsRel);
|
|
143
|
+
let count = 0;
|
|
144
|
+
try {
|
|
145
|
+
const stack = [specsDir];
|
|
146
|
+
while (stack.length) {
|
|
147
|
+
const dir = stack.pop();
|
|
148
|
+
for (const d of await readdir(dir, { withFileTypes: true })) {
|
|
149
|
+
if (d.isDirectory())
|
|
150
|
+
stack.push(join(dir, d.name));
|
|
151
|
+
else if (d.name.endsWith('.md'))
|
|
152
|
+
count++;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
continue; // specs dir doesn't exist — try the next candidate
|
|
158
|
+
}
|
|
159
|
+
if (count > 0)
|
|
160
|
+
return { root, specsRel, count };
|
|
161
|
+
}
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
130
164
|
/**
|
|
131
165
|
* Merge existing OpenSpec config with openlore metadata
|
|
132
166
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../../src/core/services/config-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../../../src/core/services/config-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
import type { CallEdge, FunctionNode, ClassNode, InheritanceEdge } from '../analyzer/call-graph.js';
|
|
2
|
+
import type { DecisionNode, DecisionAffectsEdge } from '../decisions/project.js';
|
|
3
|
+
import type { FileProvenance } from '../provenance/git-provenance.js';
|
|
4
|
+
import type { FileChangeCoupling, ChangeCouplingResult } from '../provenance/change-coupling.js';
|
|
2
5
|
export declare class EdgeStore {
|
|
3
6
|
private readonly db;
|
|
7
|
+
/**
|
|
8
|
+
* True when opening this DB found a stale SCHEMA_VERSION and wiped it (rebuild-on-bump).
|
|
9
|
+
* The data is gone until the next analyze repopulates it — callers that READ
|
|
10
|
+
* (vs. analyze, which repopulates) should treat the store as unavailable so they
|
|
11
|
+
* can tell the user to re-run analyze instead of serving an empty graph.
|
|
12
|
+
*/
|
|
13
|
+
private _wasReset;
|
|
14
|
+
get wasReset(): boolean;
|
|
4
15
|
private constructor();
|
|
5
16
|
private initSchema;
|
|
6
17
|
/** All distinct files that call into calleeFile (reverse lookup before delete). */
|
|
@@ -49,6 +60,36 @@ export declare class EdgeStore {
|
|
|
49
60
|
getClassesForFile(file: string): ClassNode[];
|
|
50
61
|
deleteClassesForFile(file: string): void;
|
|
51
62
|
insertClasses(classes: ClassNode[]): void;
|
|
63
|
+
/** Replace the projected decision graph wholesale (idempotent re-projection). */
|
|
64
|
+
insertDecisions(nodes: DecisionNode[], edges: DecisionAffectsEdge[]): void;
|
|
65
|
+
/** Every projected decision node (deterministic order). */
|
|
66
|
+
getAllDecisions(): DecisionNode[];
|
|
67
|
+
countDecisions(): number;
|
|
68
|
+
/**
|
|
69
|
+
* Governing decisions for a set of files — the deterministic graph join that
|
|
70
|
+
* replaces orient's runtime affectedFiles set-membership filter (spec-16).
|
|
71
|
+
*
|
|
72
|
+
* Path forms differ across callers (edge-store nodes are repo-relative; some
|
|
73
|
+
* callers pass absolute paths), and decisions are few, so we match in JS with a
|
|
74
|
+
* tolerant suffix comparator rather than relying on exact SQL equality.
|
|
75
|
+
*/
|
|
76
|
+
getDecisionsForFiles(files: string[]): DecisionNode[];
|
|
77
|
+
/** Replace the per-file provenance wholesale (idempotent re-extraction). */
|
|
78
|
+
insertProvenance(records: FileProvenance[]): void;
|
|
79
|
+
countProvenance(): number;
|
|
80
|
+
/**
|
|
81
|
+
* Provenance for a set of files. Path forms differ across callers (edge-store
|
|
82
|
+
* nodes are repo-relative; some callers pass absolute paths), so match with the
|
|
83
|
+
* same tolerant comparator used for decisions (spec-18).
|
|
84
|
+
*/
|
|
85
|
+
getProvenanceForFiles(files: string[]): FileProvenance[];
|
|
86
|
+
/** Replace the per-file change-coupling snapshot wholesale (idempotent re-mine). */
|
|
87
|
+
insertChangeCoupling(result: ChangeCouplingResult): void;
|
|
88
|
+
countChangeCoupling(): number;
|
|
89
|
+
/** Change-coupling records for a set of files (tolerant path match, spec-22). */
|
|
90
|
+
getChangeCouplingForFiles(files: string[]): FileChangeCoupling[];
|
|
91
|
+
/** Top-churn (most volatile) files, descending. */
|
|
92
|
+
getTopVolatile(limit?: number): FileChangeCoupling[];
|
|
52
93
|
getFileHash(filePath: string): string | null;
|
|
53
94
|
setFileHash(filePath: string, hash: string): void;
|
|
54
95
|
/** Drop all graph data — used by full analyze rebuild. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"edge-store.d.ts","sourceRoot":"","sources":["../../../src/core/services/edge-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"edge-store.d.ts","sourceRoot":"","sources":["../../../src/core/services/edge-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACpG,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAe,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AA8C9G,qBAAa,SAAS;IAUA,OAAO,CAAC,QAAQ,CAAC,EAAE;IATvC;;;;;OAKG;IACH,OAAO,CAAC,SAAS,CAAS;IAC1B,IAAI,QAAQ,IAAI,OAAO,CAA2B;IAElD,OAAO;IAIP,OAAO,CAAC,UAAU;IA8IlB,mFAAmF;IACnF,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE;IAO5C,qDAAqD;IACrD,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;QAAC,QAAQ,EAAE,QAAQ,EAAE,CAAA;KAAE;IAU7E,0DAA0D;IAC1D,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE;IAMtC,wDAAwD;IACxD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE;IAMtC,8EAA8E;IAC9E,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE;IAQjD,8EAA8E;IAC9E,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE;IAUjD,4DAA4D;IAC5D,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAItC,yEAAyE;IACzE,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI9C,iDAAiD;IACjD,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,IAAI;IAwBpC,6DAA6D;IAC7D,sBAAsB,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,IAAI;IAatD,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAKxC,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,EAAE;IAM7C;;;;OAIG;IACH,mBAAmB,IAAI,YAAY,EAAE;IAMrC,0GAA0G;IAC1G,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,YAAY,EAAE;IAwBxD,OAAO,CAAC,KAAK,SAAK,GAAG,YAAY,EAAE;IAQnC,cAAc,CAAC,KAAK,SAAK,GAAG,YAAY,EAAE;IAQ1C,UAAU,IAAI,MAAM;IAOpB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAWtC;;;OAGG;IACH,WAAW,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,IAAI;IAqCtF,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI;IAKtC,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE;IAQ5C,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxC,aAAa,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI;IA2BzC,iFAAiF;IACjF,eAAe,CAAC,KAAK,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,GAAG,IAAI;IA8B1E,2DAA2D;IAC3D,eAAe,IAAI,YAAY,EAAE;IAMjC,cAAc,IAAI,MAAM;IAKxB;;;;;;;OAOG;IACH,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,YAAY,EAAE;IAmBrD,4EAA4E;IAC5E,gBAAgB,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI;IAuBjD,eAAe,IAAI,MAAM;IAKzB;;;;OAIG;IACH,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE;IAYxD,oFAAoF;IACpF,oBAAoB,CAAC,MAAM,EAAE,oBAAoB,GAAG,IAAI;IAiBxD,mBAAmB,IAAI,MAAM;IAK7B,iFAAiF;IACjF,yBAAyB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,kBAAkB,EAAE;IAQhE,mDAAmD;IACnD,cAAc,CAAC,KAAK,SAAK,GAAG,kBAAkB,EAAE;IAShD,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAO5C,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAQjD,0DAA0D;IAC1D,QAAQ,IAAI,IAAI;IAIhB,iDAAiD;IACjD,WAAW,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,IAAI;IAIjC,KAAK,IAAI,IAAI;IAMb,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;IAItC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAIzC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;CAGzC"}
|
|
@@ -43,9 +43,17 @@ function runTransaction(db, fn) {
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
/** Bump when schema changes. Old DBs are dropped and rebuilt on next analyze --force. */
|
|
46
|
-
const SCHEMA_VERSION =
|
|
46
|
+
const SCHEMA_VERSION = 5;
|
|
47
47
|
export class EdgeStore {
|
|
48
48
|
db;
|
|
49
|
+
/**
|
|
50
|
+
* True when opening this DB found a stale SCHEMA_VERSION and wiped it (rebuild-on-bump).
|
|
51
|
+
* The data is gone until the next analyze repopulates it — callers that READ
|
|
52
|
+
* (vs. analyze, which repopulates) should treat the store as unavailable so they
|
|
53
|
+
* can tell the user to re-run analyze instead of serving an empty graph.
|
|
54
|
+
*/
|
|
55
|
+
_wasReset = false;
|
|
56
|
+
get wasReset() { return this._wasReset; }
|
|
49
57
|
constructor(db) {
|
|
50
58
|
this.db = db;
|
|
51
59
|
this.initSchema();
|
|
@@ -58,12 +66,17 @@ export class EdgeStore {
|
|
|
58
66
|
this.db.prepare('INSERT INTO schema_version (version) VALUES (?)').run(SCHEMA_VERSION);
|
|
59
67
|
}
|
|
60
68
|
else if (row.version !== SCHEMA_VERSION) {
|
|
69
|
+
this._wasReset = true;
|
|
61
70
|
this.db.exec(`
|
|
62
71
|
DROP TABLE IF EXISTS edges;
|
|
63
72
|
DROP TABLE IF EXISTS inheritance_edges;
|
|
64
73
|
DROP TABLE IF EXISTS nodes;
|
|
65
74
|
DROP TABLE IF EXISTS classes;
|
|
66
75
|
DROP TABLE IF EXISTS file_hashes;
|
|
76
|
+
DROP TABLE IF EXISTS decisions;
|
|
77
|
+
DROP TABLE IF EXISTS decision_edges;
|
|
78
|
+
DROP TABLE IF EXISTS provenance;
|
|
79
|
+
DROP TABLE IF EXISTS change_coupling;
|
|
67
80
|
DROP TABLE IF EXISTS schema_version;
|
|
68
81
|
CREATE TABLE schema_version (version INTEGER NOT NULL);
|
|
69
82
|
`);
|
|
@@ -137,6 +150,51 @@ export class EdgeStore {
|
|
|
137
150
|
);
|
|
138
151
|
|
|
139
152
|
CREATE VIRTUAL TABLE IF NOT EXISTS nodes_fts USING fts5(node_id UNINDEXED, name, tokenize='trigram');
|
|
153
|
+
|
|
154
|
+
-- Architectural decisions projected as first-class graph nodes (spec-16).
|
|
155
|
+
-- Derived from .openlore/decisions/pending.json; the JSON store stays
|
|
156
|
+
-- authoritative. Held in dedicated tables so code-node stats (hubs,
|
|
157
|
+
-- entry points, countNodes) and call-edge BFS are untouched.
|
|
158
|
+
CREATE TABLE IF NOT EXISTS decisions (
|
|
159
|
+
id TEXT PRIMARY KEY, -- graph node id "decision::<id>"
|
|
160
|
+
decision_id TEXT NOT NULL, -- original 8-char store id
|
|
161
|
+
title TEXT NOT NULL,
|
|
162
|
+
status TEXT NOT NULL,
|
|
163
|
+
rationale TEXT NOT NULL DEFAULT '',
|
|
164
|
+
consequences TEXT NOT NULL DEFAULT '',
|
|
165
|
+
affected_domains TEXT NOT NULL DEFAULT '[]',
|
|
166
|
+
affected_files TEXT NOT NULL DEFAULT '[]',
|
|
167
|
+
confidence TEXT,
|
|
168
|
+
supersedes TEXT
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
-- affects edges: decision node -> governed file path.
|
|
172
|
+
CREATE TABLE IF NOT EXISTS decision_edges (
|
|
173
|
+
decision_id TEXT NOT NULL, -- graph node id "decision::<id>"
|
|
174
|
+
file_path TEXT NOT NULL
|
|
175
|
+
);
|
|
176
|
+
CREATE INDEX IF NOT EXISTS idx_decision_edge_file ON decision_edges(file_path);
|
|
177
|
+
CREATE INDEX IF NOT EXISTS idx_decision_edge_dec ON decision_edges(decision_id);
|
|
178
|
+
|
|
179
|
+
-- Local provenance (spec-18): per-file last-author + recent authors + PRs,
|
|
180
|
+
-- derived from local git/gh. Capped upstream; one row per file, no graph bloat.
|
|
181
|
+
CREATE TABLE IF NOT EXISTS provenance (
|
|
182
|
+
file_path TEXT PRIMARY KEY,
|
|
183
|
+
last_author TEXT NOT NULL, -- JSON {name,email}
|
|
184
|
+
last_date TEXT,
|
|
185
|
+
last_commit TEXT,
|
|
186
|
+
last_subject TEXT,
|
|
187
|
+
recent_authors TEXT NOT NULL DEFAULT '[]', -- JSON Author[]
|
|
188
|
+
prs TEXT NOT NULL DEFAULT '[]' -- JSON PullRequest[]
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
-- Change coupling & volatility (spec-22): per-file churn + co-change pairs,
|
|
192
|
+
-- mined from local git history. One row per file; advisory caution signals.
|
|
193
|
+
CREATE TABLE IF NOT EXISTS change_coupling (
|
|
194
|
+
file_path TEXT PRIMARY KEY,
|
|
195
|
+
churn INTEGER NOT NULL DEFAULT 0,
|
|
196
|
+
coupled_with TEXT NOT NULL DEFAULT '[]' -- JSON CoupledFile[]
|
|
197
|
+
);
|
|
140
198
|
`);
|
|
141
199
|
}
|
|
142
200
|
// ── Edge queries ──────────────────────────────────────────────────────────────
|
|
@@ -236,6 +294,10 @@ export class EdgeStore {
|
|
|
236
294
|
/** Case-insensitive substring search on node name. FTS5 trigram for ≥3 chars, LIKE fallback otherwise. */
|
|
237
295
|
searchNodes(pattern, limit = 50) {
|
|
238
296
|
if (pattern.length >= 3) {
|
|
297
|
+
// Wrap as an FTS5 phrase so special characters in the symbol are literal —
|
|
298
|
+
// IaC resource names contain ':' (e.g. "Bucket:logs") and '.' which FTS5
|
|
299
|
+
// would otherwise read as column filters / operators (spec-17).
|
|
300
|
+
const phrase = `"${pattern.replace(/"/g, '""')}"`;
|
|
239
301
|
return this.db
|
|
240
302
|
.prepare(`
|
|
241
303
|
SELECT n.* FROM nodes_fts f
|
|
@@ -243,7 +305,7 @@ export class EdgeStore {
|
|
|
243
305
|
WHERE nodes_fts MATCH ? AND n.is_external = 0
|
|
244
306
|
LIMIT ?
|
|
245
307
|
`)
|
|
246
|
-
.all(
|
|
308
|
+
.all(phrase, limit).map(rawToFunctionNode);
|
|
247
309
|
}
|
|
248
310
|
return this.db
|
|
249
311
|
.prepare('SELECT * FROM nodes WHERE name LIKE ? AND is_external = 0 LIMIT ?')
|
|
@@ -347,6 +409,149 @@ export class EdgeStore {
|
|
|
347
409
|
}
|
|
348
410
|
});
|
|
349
411
|
}
|
|
412
|
+
// ── Decision queries / mutations (spec-16) ─────────────────────────────────────
|
|
413
|
+
/** Replace the projected decision graph wholesale (idempotent re-projection). */
|
|
414
|
+
insertDecisions(nodes, edges) {
|
|
415
|
+
const nodeStmt = this.db.prepare(`
|
|
416
|
+
INSERT OR REPLACE INTO decisions
|
|
417
|
+
(id, decision_id, title, status, rationale, consequences, affected_domains, affected_files, confidence, supersedes)
|
|
418
|
+
VALUES
|
|
419
|
+
(@id, @decisionId, @title, @status, @rationale, @consequences, @affectedDomains, @affectedFiles, @confidence, @supersedes)
|
|
420
|
+
`);
|
|
421
|
+
const edgeStmt = this.db.prepare('INSERT INTO decision_edges (decision_id, file_path) VALUES (?, ?)');
|
|
422
|
+
runTransaction(this.db, () => {
|
|
423
|
+
this.db.exec('DELETE FROM decisions; DELETE FROM decision_edges;');
|
|
424
|
+
for (const n of nodes) {
|
|
425
|
+
nodeStmt.run({
|
|
426
|
+
'@id': n.id,
|
|
427
|
+
'@decisionId': n.decisionId,
|
|
428
|
+
'@title': n.title,
|
|
429
|
+
'@status': n.status,
|
|
430
|
+
'@rationale': n.rationale,
|
|
431
|
+
'@consequences': n.consequences,
|
|
432
|
+
'@affectedDomains': JSON.stringify(n.affectedDomains),
|
|
433
|
+
'@affectedFiles': JSON.stringify(n.affectedFiles),
|
|
434
|
+
'@confidence': n.confidence ?? null,
|
|
435
|
+
'@supersedes': n.supersedes ?? null,
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
for (const e of edges)
|
|
439
|
+
edgeStmt.run(e.decisionNodeId, e.filePath);
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
/** Every projected decision node (deterministic order). */
|
|
443
|
+
getAllDecisions() {
|
|
444
|
+
return this.db.prepare('SELECT * FROM decisions ORDER BY id').all().map(rawToDecisionNode);
|
|
445
|
+
}
|
|
446
|
+
countDecisions() {
|
|
447
|
+
const row = this.db.prepare('SELECT COUNT(*) as n FROM decisions').get();
|
|
448
|
+
return row.n;
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Governing decisions for a set of files — the deterministic graph join that
|
|
452
|
+
* replaces orient's runtime affectedFiles set-membership filter (spec-16).
|
|
453
|
+
*
|
|
454
|
+
* Path forms differ across callers (edge-store nodes are repo-relative; some
|
|
455
|
+
* callers pass absolute paths), and decisions are few, so we match in JS with a
|
|
456
|
+
* tolerant suffix comparator rather than relying on exact SQL equality.
|
|
457
|
+
*/
|
|
458
|
+
getDecisionsForFiles(files) {
|
|
459
|
+
if (files.length === 0)
|
|
460
|
+
return [];
|
|
461
|
+
const edgeRows = this.db
|
|
462
|
+
.prepare('SELECT decision_id, file_path FROM decision_edges')
|
|
463
|
+
.all();
|
|
464
|
+
if (edgeRows.length === 0)
|
|
465
|
+
return [];
|
|
466
|
+
const wanted = files.filter(Boolean);
|
|
467
|
+
const matchedIds = new Set();
|
|
468
|
+
for (const row of edgeRows) {
|
|
469
|
+
if (wanted.some(f => pathsMatch(f, row.file_path)))
|
|
470
|
+
matchedIds.add(row.decision_id);
|
|
471
|
+
}
|
|
472
|
+
if (matchedIds.size === 0)
|
|
473
|
+
return [];
|
|
474
|
+
return this.getAllDecisions().filter(d => matchedIds.has(d.id));
|
|
475
|
+
}
|
|
476
|
+
// ── Provenance queries / mutations (spec-18) ───────────────────────────────────
|
|
477
|
+
/** Replace the per-file provenance wholesale (idempotent re-extraction). */
|
|
478
|
+
insertProvenance(records) {
|
|
479
|
+
const stmt = this.db.prepare(`
|
|
480
|
+
INSERT OR REPLACE INTO provenance
|
|
481
|
+
(file_path, last_author, last_date, last_commit, last_subject, recent_authors, prs)
|
|
482
|
+
VALUES
|
|
483
|
+
(@filePath, @lastAuthor, @lastDate, @lastCommit, @lastSubject, @recentAuthors, @prs)
|
|
484
|
+
`);
|
|
485
|
+
runTransaction(this.db, () => {
|
|
486
|
+
this.db.exec('DELETE FROM provenance;');
|
|
487
|
+
for (const r of records) {
|
|
488
|
+
stmt.run({
|
|
489
|
+
'@filePath': r.filePath,
|
|
490
|
+
'@lastAuthor': JSON.stringify(r.lastAuthor),
|
|
491
|
+
'@lastDate': r.lastDate ?? null,
|
|
492
|
+
'@lastCommit': r.lastCommit ?? null,
|
|
493
|
+
'@lastSubject': r.lastSubject ?? null,
|
|
494
|
+
'@recentAuthors': JSON.stringify(r.recentAuthors),
|
|
495
|
+
'@prs': JSON.stringify(r.prs),
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
countProvenance() {
|
|
501
|
+
const row = this.db.prepare('SELECT COUNT(*) as n FROM provenance').get();
|
|
502
|
+
return row.n;
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Provenance for a set of files. Path forms differ across callers (edge-store
|
|
506
|
+
* nodes are repo-relative; some callers pass absolute paths), so match with the
|
|
507
|
+
* same tolerant comparator used for decisions (spec-18).
|
|
508
|
+
*/
|
|
509
|
+
getProvenanceForFiles(files) {
|
|
510
|
+
if (files.length === 0)
|
|
511
|
+
return [];
|
|
512
|
+
const rows = this.db.prepare('SELECT * FROM provenance').all();
|
|
513
|
+
if (rows.length === 0)
|
|
514
|
+
return [];
|
|
515
|
+
const wanted = files.filter(Boolean);
|
|
516
|
+
return rows
|
|
517
|
+
.filter(r => wanted.some(f => pathsMatch(f, r.file_path)))
|
|
518
|
+
.map(rawToProvenance);
|
|
519
|
+
}
|
|
520
|
+
// ── Change coupling & volatility (spec-22) ─────────────────────────────────────
|
|
521
|
+
/** Replace the per-file change-coupling snapshot wholesale (idempotent re-mine). */
|
|
522
|
+
insertChangeCoupling(result) {
|
|
523
|
+
const stmt = this.db.prepare('INSERT OR REPLACE INTO change_coupling (file_path, churn, coupled_with) VALUES (@filePath, @churn, @coupledWith)');
|
|
524
|
+
runTransaction(this.db, () => {
|
|
525
|
+
this.db.exec('DELETE FROM change_coupling;');
|
|
526
|
+
// Persist every file that has churn (coupling may be empty for some).
|
|
527
|
+
for (const [filePath, churn] of result.churn) {
|
|
528
|
+
stmt.run({
|
|
529
|
+
'@filePath': filePath,
|
|
530
|
+
'@churn': churn,
|
|
531
|
+
'@coupledWith': JSON.stringify(result.coupling.get(filePath) ?? []),
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
countChangeCoupling() {
|
|
537
|
+
const row = this.db.prepare('SELECT COUNT(*) as n FROM change_coupling').get();
|
|
538
|
+
return row.n;
|
|
539
|
+
}
|
|
540
|
+
/** Change-coupling records for a set of files (tolerant path match, spec-22). */
|
|
541
|
+
getChangeCouplingForFiles(files) {
|
|
542
|
+
if (files.length === 0)
|
|
543
|
+
return [];
|
|
544
|
+
const rows = this.db.prepare('SELECT * FROM change_coupling').all();
|
|
545
|
+
if (rows.length === 0)
|
|
546
|
+
return [];
|
|
547
|
+
const wanted = files.filter(Boolean);
|
|
548
|
+
return rows.filter(r => wanted.some(f => pathsMatch(f, r.file_path))).map(rawToCoupling);
|
|
549
|
+
}
|
|
550
|
+
/** Top-churn (most volatile) files, descending. */
|
|
551
|
+
getTopVolatile(limit = 20) {
|
|
552
|
+
return this.db.prepare('SELECT * FROM change_coupling ORDER BY churn DESC, file_path ASC LIMIT ?')
|
|
553
|
+
.all(limit).map(rawToCoupling);
|
|
554
|
+
}
|
|
350
555
|
// ── Content-hash cache ────────────────────────────────────────────────────────
|
|
351
556
|
getFileHash(filePath) {
|
|
352
557
|
const row = this.db
|
|
@@ -361,7 +566,7 @@ export class EdgeStore {
|
|
|
361
566
|
}
|
|
362
567
|
/** Drop all graph data — used by full analyze rebuild. */
|
|
363
568
|
clearAll() {
|
|
364
|
-
this.db.exec('DELETE FROM edges; DELETE FROM inheritance_edges; DELETE FROM nodes; DELETE FROM classes; DELETE FROM nodes_fts; DELETE FROM file_hashes;');
|
|
569
|
+
this.db.exec('DELETE FROM edges; DELETE FROM inheritance_edges; DELETE FROM nodes; DELETE FROM classes; DELETE FROM nodes_fts; DELETE FROM file_hashes; DELETE FROM decisions; DELETE FROM decision_edges; DELETE FROM provenance; DELETE FROM change_coupling;');
|
|
365
570
|
}
|
|
366
571
|
/** Run fn inside a single SQLite transaction. */
|
|
367
572
|
transaction(fn) {
|
|
@@ -381,6 +586,49 @@ export class EdgeStore {
|
|
|
381
586
|
return join(outputDir, ARTIFACT_CALL_GRAPH_DB);
|
|
382
587
|
}
|
|
383
588
|
}
|
|
589
|
+
function rawToCoupling(r) {
|
|
590
|
+
return {
|
|
591
|
+
filePath: r.file_path,
|
|
592
|
+
churn: r.churn,
|
|
593
|
+
coupledWith: JSON.parse(r.coupled_with),
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
function rawToProvenance(r) {
|
|
597
|
+
return {
|
|
598
|
+
filePath: r.file_path,
|
|
599
|
+
lastAuthor: JSON.parse(r.last_author),
|
|
600
|
+
lastDate: r.last_date ?? '',
|
|
601
|
+
lastCommit: r.last_commit ?? '',
|
|
602
|
+
lastSubject: r.last_subject ?? '',
|
|
603
|
+
recentAuthors: JSON.parse(r.recent_authors),
|
|
604
|
+
prs: JSON.parse(r.prs),
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
/** Tolerant path equality: exact, or one path is a suffix of the other. */
|
|
608
|
+
function pathsMatch(a, b) {
|
|
609
|
+
if (a === b)
|
|
610
|
+
return true;
|
|
611
|
+
const na = a.replace(/^\/+/, '');
|
|
612
|
+
const nb = b.replace(/^\/+/, '');
|
|
613
|
+
if (na === nb)
|
|
614
|
+
return true;
|
|
615
|
+
return na.endsWith('/' + nb) || nb.endsWith('/' + na);
|
|
616
|
+
}
|
|
617
|
+
function rawToDecisionNode(r) {
|
|
618
|
+
return {
|
|
619
|
+
id: r.id,
|
|
620
|
+
decisionId: r.decision_id,
|
|
621
|
+
kind: 'decision',
|
|
622
|
+
title: r.title,
|
|
623
|
+
status: r.status,
|
|
624
|
+
rationale: r.rationale,
|
|
625
|
+
consequences: r.consequences,
|
|
626
|
+
affectedDomains: JSON.parse(r.affected_domains),
|
|
627
|
+
affectedFiles: JSON.parse(r.affected_files),
|
|
628
|
+
confidence: (r.confidence ?? 'medium'),
|
|
629
|
+
...(r.supersedes ? { supersedes: r.supersedes } : {}),
|
|
630
|
+
};
|
|
631
|
+
}
|
|
384
632
|
function rawToCallEdge(r) {
|
|
385
633
|
return {
|
|
386
634
|
callerId: r.caller_id,
|