kibi-cli 0.6.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +18 -0
- package/dist/commands/init-helpers.d.ts +1 -0
- package/dist/commands/init-helpers.d.ts.map +1 -1
- package/dist/commands/init-helpers.js +39 -6
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +2 -1
- package/dist/commands/sync/manifest.d.ts +1 -0
- package/dist/commands/sync/manifest.d.ts.map +1 -1
- package/dist/commands/sync/manifest.js +1 -1
- package/dist/commands/sync/persistence.d.ts.map +1 -1
- package/dist/commands/sync/persistence.js +4 -2
- package/dist/commands/sync/staging.d.ts +3 -0
- package/dist/commands/sync/staging.d.ts.map +1 -1
- package/dist/commands/sync/staging.js +58 -1
- package/dist/commands/sync.d.ts +18 -1
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +19 -4
- package/dist/extractors/markdown.d.ts +2 -0
- package/dist/extractors/markdown.d.ts.map +1 -1
- package/dist/extractors/symbols-coordinator.d.ts +34 -0
- package/dist/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/extractors/symbols-coordinator.js +70 -1
- package/dist/extractors/symbols-ts.d.ts +2 -0
- package/dist/extractors/symbols-ts.d.ts.map +1 -1
- package/dist/extractors/symbols-ts.js +108 -1
- package/dist/public/brief-config.d.ts +4 -0
- package/dist/public/brief-config.d.ts.map +1 -0
- package/dist/public/brief-config.js +21 -0
- package/dist/public/extractors/symbols-coordinator.d.ts +1 -1
- package/dist/public/extractors/symbols-coordinator.d.ts.map +1 -1
- package/dist/public/extractors/symbols-coordinator.js +1 -1
- package/dist/public/operational-artifacts.d.ts +2 -0
- package/dist/public/operational-artifacts.d.ts.map +1 -0
- package/dist/public/operational-artifacts.js +4 -0
- package/dist/search-ranking.d.ts.map +1 -1
- package/dist/search-ranking.js +132 -25
- package/dist/utils/config.d.ts +18 -3
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +39 -0
- package/dist/utils/rule-registry.d.ts.map +1 -1
- package/dist/utils/rule-registry.js +6 -0
- package/package.json +10 -2
- package/schema/config.json +73 -0
- package/schema/entities.pl +1 -0
- package/schema/relationships.pl +4 -0
- package/src/public/brief-config.ts +25 -0
- package/src/public/extractors/symbols-coordinator.ts +7 -0
- package/src/public/operational-artifacts.ts +5 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAuDA,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,SAAS,EAAE,CAAC;AAI1B,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA+GD,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAuDA,OAAO,EAGL,KAAK,SAAS,EAEf,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EAAE,SAAS,EAAE,CAAC;AAI1B,MAAM,WAAW,YAAY;IAC3B,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AA+GD,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAkR/B"}
|
package/dist/commands/check.js
CHANGED
|
@@ -277,6 +277,7 @@ export async function checkCommand(options) {
|
|
|
277
277
|
"deprecated-adr-no-successor",
|
|
278
278
|
"domain-contradictions",
|
|
279
279
|
"strict-fact-shape",
|
|
280
|
+
"strict-req-fact-pairing",
|
|
280
281
|
];
|
|
281
282
|
const canUseAggregated = Array.from(effectiveRules).every((r) => supportedRules.includes(r));
|
|
282
283
|
if (canUseAggregated) {
|
|
@@ -300,6 +301,7 @@ export async function checkCommand(options) {
|
|
|
300
301
|
await runCheck("deprecated-adr-no-successor", checkDeprecatedAdrs);
|
|
301
302
|
await runCheck("domain-contradictions", checkDomainContradictions);
|
|
302
303
|
await runCheck("strict-fact-shape", checkStrictFactShape);
|
|
304
|
+
await runCheck("strict-req-fact-pairing", checkStrictReqFactPairing);
|
|
303
305
|
}
|
|
304
306
|
if (violations.length === 0) {
|
|
305
307
|
console.log("✓ No violations found. KB is valid.");
|
|
@@ -640,6 +642,22 @@ async function checkStrictFactShape(prolog) {
|
|
|
640
642
|
}
|
|
641
643
|
return violations;
|
|
642
644
|
}
|
|
645
|
+
async function checkStrictReqFactPairing(prolog) {
|
|
646
|
+
const violations = [];
|
|
647
|
+
const result = await prolog.query(`findall(violation(Rule, EntityId, Desc, Sugg, Src),
|
|
648
|
+
checks:strict_req_fact_pairing_violation(violation(Rule, EntityId, Desc, Sugg, Src)),
|
|
649
|
+
Violations)`);
|
|
650
|
+
if (!result.success || !result.bindings.Violations) {
|
|
651
|
+
return violations;
|
|
652
|
+
}
|
|
653
|
+
const violationsStr = result.bindings.Violations;
|
|
654
|
+
if (violationsStr && violationsStr !== "[]") {
|
|
655
|
+
for (const v of parseViolationRows(violationsStr)) {
|
|
656
|
+
violations.push(v);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
return violations;
|
|
660
|
+
}
|
|
643
661
|
async function checkSymbolCoverage(prolog) {
|
|
644
662
|
const violations = [];
|
|
645
663
|
const uncoveredResult = await prolog.query("setof(Symbol, symbol_no_req_coverage(Symbol, _), Symbols)");
|
|
@@ -2,6 +2,7 @@ export declare function getCurrentBranch(cwd?: string): Promise<string>;
|
|
|
2
2
|
export declare function createKbDirectoryStructure(kbDir: string, currentBranch: string): void;
|
|
3
3
|
export declare function createConfigFile(kbDir: string): void;
|
|
4
4
|
export declare function updateGitIgnore(cwd: string): void;
|
|
5
|
+
export declare function ensureSymbolsManifestFile(cwd: string): void;
|
|
5
6
|
export declare function copySchemaFiles(kbDir: string, schemaSourceDir: string): Promise<void>;
|
|
6
7
|
export declare function installHook(hookPath: string, content: string): void;
|
|
7
8
|
export declare function installGitHooks(gitDir: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init-helpers.d.ts","sourceRoot":"","sources":["../../src/commands/init-helpers.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init-helpers.d.ts","sourceRoot":"","sources":["../../src/commands/init-helpers.ts"],"names":[],"mappings":"AAuGA,wBAAsB,gBAAgB,CACpC,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,MAAM,EACb,aAAa,EAAE,MAAM,GACpB,IAAI,CAQN;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAMpD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAsBjD;AAGD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAU3D;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,IAAI,CAAC,CAYf;AASD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAkCnE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAiBpD"}
|
|
@@ -20,6 +20,7 @@ import * as path from "node:path";
|
|
|
20
20
|
import fg from "fast-glob";
|
|
21
21
|
import { getBranchDiagnostic, resolveActiveBranch, } from "../utils/branch-resolver.js";
|
|
22
22
|
import { DEFAULT_CONFIG } from "../utils/config.js";
|
|
23
|
+
import { SYMBOLS_MANIFEST_COMMENT_BLOCK } from "./sync/manifest.js";
|
|
23
24
|
const POST_CHECKOUT_HOOK = `#!/bin/sh
|
|
24
25
|
# post-checkout hook for kibi
|
|
25
26
|
# Parameters: old_ref new_ref branch_flag
|
|
@@ -67,6 +68,21 @@ const PRE_COMMIT_HOOK = `#!/bin/sh
|
|
|
67
68
|
# The OpenCode plugin remains advisory and must not replace this gate.
|
|
68
69
|
|
|
69
70
|
set -e
|
|
71
|
+
|
|
72
|
+
symbols_manifest="documentation/symbols.yaml"
|
|
73
|
+
|
|
74
|
+
if [ ! -f "$symbols_manifest" ]; then
|
|
75
|
+
echo "Kibi symbols manifest is missing: $symbols_manifest" >&2
|
|
76
|
+
echo "Run 'kibi init' to create it, then stage and commit it." >&2
|
|
77
|
+
exit 1
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
if ! git diff --quiet -- "$symbols_manifest"; then
|
|
81
|
+
echo "Kibi symbols manifest has unstaged changes: $symbols_manifest" >&2
|
|
82
|
+
echo "Stage and commit documentation/symbols.yaml with the code changes that refreshed it." >&2
|
|
83
|
+
exit 1
|
|
84
|
+
fi
|
|
85
|
+
|
|
70
86
|
kibi check --staged
|
|
71
87
|
`;
|
|
72
88
|
export async function getCurrentBranch(cwd = process.cwd()) {
|
|
@@ -91,17 +107,34 @@ export function createConfigFile(kbDir) {
|
|
|
91
107
|
console.log("✓ Created config.json with default paths");
|
|
92
108
|
}
|
|
93
109
|
export function updateGitIgnore(cwd) {
|
|
110
|
+
// implements REQ-001
|
|
94
111
|
const gitignorePath = path.join(cwd, ".gitignore");
|
|
95
112
|
const gitignoreContent = existsSync(gitignorePath)
|
|
96
113
|
? readFileSync(gitignorePath, "utf8")
|
|
97
114
|
: "";
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
115
|
+
const ensureEntry = (current, entry) => {
|
|
116
|
+
if (current.includes(entry)) {
|
|
117
|
+
return current;
|
|
118
|
+
}
|
|
119
|
+
return current ? `${current.trimEnd()}\n${entry}\n` : `${entry}\n`;
|
|
120
|
+
};
|
|
121
|
+
const updatedWithKb = ensureEntry(gitignoreContent, ".kb/");
|
|
122
|
+
const updatedContent = ensureEntry(updatedWithKb, ".kb/briefs/");
|
|
123
|
+
if (updatedContent !== gitignoreContent) {
|
|
124
|
+
writeFileSync(gitignorePath, updatedContent);
|
|
125
|
+
console.log("✓ Added .kb/ and .kb/briefs/ to .gitignore");
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// implements REQ-003
|
|
129
|
+
export function ensureSymbolsManifestFile(cwd) {
|
|
130
|
+
const symbolsRelPath = DEFAULT_CONFIG.paths.symbols ?? "documentation/symbols.yaml";
|
|
131
|
+
const symbolsPath = path.join(cwd, symbolsRelPath);
|
|
132
|
+
if (existsSync(symbolsPath)) {
|
|
133
|
+
return;
|
|
104
134
|
}
|
|
135
|
+
mkdirSync(path.dirname(symbolsPath), { recursive: true });
|
|
136
|
+
writeFileSync(symbolsPath, `${SYMBOLS_MANIFEST_COMMENT_BLOCK}symbols: []\n`);
|
|
137
|
+
console.log(`✓ Created ${symbolsRelPath}`);
|
|
105
138
|
}
|
|
106
139
|
export async function copySchemaFiles(kbDir, schemaSourceDir) {
|
|
107
140
|
const schemaFiles = await fg("*.pl", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAkCA,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAGD,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CA+D/B"}
|
package/dist/commands/init.js
CHANGED
|
@@ -19,7 +19,7 @@ import { existsSync } from "node:fs";
|
|
|
19
19
|
import * as path from "node:path";
|
|
20
20
|
import { fileURLToPath } from "node:url";
|
|
21
21
|
import { resolveActiveBranch } from "../utils/branch-resolver.js";
|
|
22
|
-
import { copySchemaFiles, createConfigFile, createKbDirectoryStructure, installGitHooks, updateGitIgnore, } from "./init-helpers.js";
|
|
22
|
+
import { copySchemaFiles, createConfigFile, createKbDirectoryStructure, ensureSymbolsManifestFile, installGitHooks, updateGitIgnore, } from "./init-helpers.js";
|
|
23
23
|
const __filename = fileURLToPath(import.meta.url);
|
|
24
24
|
const __dirname = path.dirname(__filename);
|
|
25
25
|
// implements REQ-003
|
|
@@ -58,6 +58,7 @@ export async function initCommand(options) {
|
|
|
58
58
|
else {
|
|
59
59
|
console.log("✓ .kb/ directory already exists, skipping creation");
|
|
60
60
|
}
|
|
61
|
+
ensureSymbolsManifestFile(process.cwd());
|
|
61
62
|
if (options.hooks) {
|
|
62
63
|
const gitDir = path.join(process.cwd(), ".git");
|
|
63
64
|
if (!existsSync(gitDir)) {
|
|
@@ -9,6 +9,7 @@ interface ManifestDeps {
|
|
|
9
9
|
readFileSync: typeof readFileSync;
|
|
10
10
|
writeFileSync: typeof writeFileSync;
|
|
11
11
|
}
|
|
12
|
+
export declare const SYMBOLS_MANIFEST_COMMENT_BLOCK = "# symbols.yaml\n# AUTHORED fields (edit freely):\n# id, title, sourceFile, links, status, tags, owner, priority\n# GENERATED fields (never edit manually \u2014 overwritten by kibi sync and kb.symbols.refresh):\n# sourceLine, sourceColumn, sourceEndLine, sourceEndColumn, coordinatesGeneratedAt\n# Run `kibi sync` or call the `kb.symbols.refresh` MCP tool to refresh coordinates.\n";
|
|
12
13
|
export declare function refreshManifestCoordinates(manifestPath: string, workspaceRoot: string, deps?: Partial<ManifestDeps>): Promise<void>;
|
|
13
14
|
export declare function hasAllGeneratedCoordinates(entry: ManifestSymbolEntry): boolean;
|
|
14
15
|
export declare function isEligibleForCoordinateRefresh(sourceFile: string | undefined, workspaceRoot: string, deps?: Partial<ManifestDeps>): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/manifest.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAElE,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EACL,KAAK,mBAAmB,EACxB,uBAAuB,EACxB,MAAM,yCAAyC,CAAC;AAEjD,UAAU,YAAY;IACpB,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,aAAa,EAAE,OAAO,aAAa,CAAC;CACrC;
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/manifest.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAElE,OAAO,EAAE,IAAI,IAAI,QAAQ,EAAE,IAAI,IAAI,SAAS,EAAE,MAAM,SAAS,CAAC;AAC9D,OAAO,EACL,KAAK,mBAAmB,EACxB,uBAAuB,EACxB,MAAM,yCAAyC,CAAC;AAEjD,UAAU,YAAY;IACpB,QAAQ,EAAE,OAAO,QAAQ,CAAC;IAC1B,uBAAuB,EAAE,OAAO,uBAAuB,CAAC;IACxD,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,aAAa,EAAE,OAAO,aAAa,CAAC;CACrC;AAcD,eAAO,MAAM,8BAA8B,qYAM1C,CAAC;AAqBF,wBAAsB,0BAA0B,CAE9C,YAAY,EAAE,MAAM,EACpB,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC3B,OAAO,CAAC,IAAI,CAAC,CA8Ef;AAED,wBAAgB,0BAA0B,CAExC,KAAK,EAAE,mBAAmB,GACzB,OAAO,CAST;AAED,wBAAgB,8BAA8B,CAE5C,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC3B,OAAO,CAUT"}
|
|
@@ -30,7 +30,7 @@ function resolveDeps(overrides) {
|
|
|
30
30
|
...overrides,
|
|
31
31
|
};
|
|
32
32
|
}
|
|
33
|
-
const SYMBOLS_MANIFEST_COMMENT_BLOCK = `# symbols.yaml
|
|
33
|
+
export const SYMBOLS_MANIFEST_COMMENT_BLOCK = `# symbols.yaml
|
|
34
34
|
# AUTHORED fields (edit freely):
|
|
35
35
|
# id, title, sourceFile, links, status, tags, owner, priority
|
|
36
36
|
# GENERATED fields (never edit manually — overwritten by kibi sync and kb.symbols.refresh):
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/persistence.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAEV,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA0ErD,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,wBAAsB,eAAe,CAEnC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GACrB,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"persistence.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/persistence.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAEV,qBAAqB,EACrB,gBAAgB,EACjB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AA0ErD,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,wBAAsB,eAAe,CAEnC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,SAAS,EAAE,GAAG,CAAC,MAAM,CAAC,GACrB,OAAO,CAAC;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAqEvD;AAED,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,OAAO,EAAE,gBAAgB,EAAE,EAC3B,kBAAkB,EAAE,qBAAqB,EAAE,GAC1C,OAAO,CAAC;IAAE,iBAAiB,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAAC,CAiI7D"}
|
|
@@ -98,10 +98,10 @@ prolog, results, entityIds) {
|
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
|
-
for (const { entity } of results) {
|
|
101
|
+
for (const { entity, sourceFile } of results) {
|
|
102
102
|
entityIds.add(entity.id);
|
|
103
103
|
}
|
|
104
|
-
for (const { entity } of results) {
|
|
104
|
+
for (const { entity, sourceFile } of results) {
|
|
105
105
|
try {
|
|
106
106
|
const props = [
|
|
107
107
|
`id=${toPrologAtom(entity.id)}`,
|
|
@@ -123,6 +123,8 @@ prolog, results, entityIds) {
|
|
|
123
123
|
props.push(`severity=${toPrologAtom(entity.severity)}`);
|
|
124
124
|
if (entity.text_ref)
|
|
125
125
|
props.push(`text_ref=${toPrologString(entity.text_ref)}`);
|
|
126
|
+
if (sourceFile)
|
|
127
|
+
props.push(`sourceFile=${toPrologString(sourceFile)}`);
|
|
126
128
|
// Add typed fact fields for fact entities
|
|
127
129
|
if (entity.type === "fact") {
|
|
128
130
|
const factFields = serializeTypedFactFields(entity);
|
|
@@ -8,11 +8,14 @@ interface StagingDeps {
|
|
|
8
8
|
cwd: () => string;
|
|
9
9
|
existsSync: typeof existsSync;
|
|
10
10
|
fg: typeof fg;
|
|
11
|
+
isProcessAlive: (pid: number) => boolean;
|
|
11
12
|
mkdirSync: typeof mkdirSync;
|
|
12
13
|
moduleDir: string;
|
|
13
14
|
renameSync: typeof renameSync;
|
|
14
15
|
rmSync: typeof rmSync;
|
|
15
16
|
}
|
|
17
|
+
export declare function createUniqueStagingPath(currentBranch: string, rootDir: string, pid?: number, now?: number): string;
|
|
18
|
+
export declare function cleanupAbandonedStagingDirectories(stagingPath: string, deps?: Partial<StagingDeps>): Promise<void>;
|
|
16
19
|
export declare function prepareStagingEnvironment(stagingPath: string, livePath: string, rebuild: boolean, deps?: Partial<StagingDeps>): Promise<void>;
|
|
17
20
|
export declare function atomicPublish(stagingPath: string, livePath: string, deps?: Partial<StagingDeps>): void;
|
|
18
21
|
export declare function cleanupStaging(stagingPath: string, deps?: Partial<StagingDeps>): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staging.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/staging.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,MAAM,WAAW,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,UAAU,WAAW;IACnB,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,EAAE,EAAE,OAAO,EAAE,CAAC;IACd,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,MAAM,EAAE,OAAO,MAAM,CAAC;CACvB;
|
|
1
|
+
{"version":3,"file":"staging.d.ts","sourceRoot":"","sources":["../../../src/commands/sync/staging.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,OAAO,EAAE,MAAM,WAAW,CAAC;AAC3B,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAEnE,UAAU,WAAW;IACnB,iBAAiB,EAAE,OAAO,iBAAiB,CAAC;IAC5C,YAAY,EAAE,OAAO,YAAY,CAAC;IAClC,GAAG,EAAE,MAAM,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,EAAE,EAAE,OAAO,EAAE,CAAC;IACd,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC,SAAS,EAAE,OAAO,SAAS,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,OAAO,UAAU,CAAC;IAC9B,MAAM,EAAE,OAAO,MAAM,CAAC;CACvB;AA8BD,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,GAAG,SAAc,EACjB,GAAG,SAAa,GACf,MAAM,CAOR;AAGD,wBAAsB,kCAAkC,CACtD,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAC1B,OAAO,CAAC,IAAI,CAAC,CAkDf;AAED,wBAAsB,yBAAyB,CAE7C,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,IAAI,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAC1B,OAAO,CAAC,IAAI,CAAC,CAaf;AA0CD,wBAAgB,aAAa,CAE3B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAC1B,IAAI,CAeN;AAED,wBAAgB,cAAc,CAE5B,WAAW,EAAE,MAAM,EACnB,IAAI,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAC1B,IAAI,CAKN"}
|
|
@@ -27,6 +27,17 @@ function resolveDeps(overrides) {
|
|
|
27
27
|
cwd: () => process.cwd(),
|
|
28
28
|
existsSync,
|
|
29
29
|
fg,
|
|
30
|
+
isProcessAlive: (pid) => {
|
|
31
|
+
try {
|
|
32
|
+
process.kill(pid, 0);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
return !(error instanceof Error &&
|
|
37
|
+
"code" in error &&
|
|
38
|
+
error.code === "ESRCH");
|
|
39
|
+
}
|
|
40
|
+
},
|
|
30
41
|
mkdirSync,
|
|
31
42
|
moduleDir: import.meta.dirname,
|
|
32
43
|
renameSync,
|
|
@@ -34,11 +45,54 @@ function resolveDeps(overrides) {
|
|
|
34
45
|
...overrides,
|
|
35
46
|
};
|
|
36
47
|
}
|
|
48
|
+
// implements REQ-003
|
|
49
|
+
export function createUniqueStagingPath(currentBranch, rootDir, pid = process.pid, now = Date.now()) {
|
|
50
|
+
return path.join(rootDir, ".kb", "branches", `${currentBranch}.staging.${pid}.${now}`);
|
|
51
|
+
}
|
|
52
|
+
// implements REQ-003
|
|
53
|
+
export async function cleanupAbandonedStagingDirectories(stagingPath, deps) {
|
|
54
|
+
const resolved = resolveDeps(deps);
|
|
55
|
+
const stagingDir = path.dirname(stagingPath);
|
|
56
|
+
const stagingBase = path.basename(stagingPath);
|
|
57
|
+
const match = /^(?<branch>.+)\.staging\.(?<pid>\d+)\.(?<timestamp>\d+)$/.exec(stagingBase);
|
|
58
|
+
if (!match?.groups) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const branch = match.groups.branch;
|
|
62
|
+
if (!branch) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
const candidates = await resolved.fg(`${branch}.staging.*`, {
|
|
66
|
+
cwd: stagingDir,
|
|
67
|
+
absolute: true,
|
|
68
|
+
onlyDirectories: true,
|
|
69
|
+
suppressErrors: true,
|
|
70
|
+
});
|
|
71
|
+
for (const candidate of candidates) {
|
|
72
|
+
if (candidate === stagingPath) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
const candidateBase = path.basename(candidate);
|
|
76
|
+
const candidateMatch = new RegExp(`^${escapeRegex(branch)}\\.staging\\.(\\d+)\\.(\\d+)$`).exec(candidateBase);
|
|
77
|
+
if (!candidateMatch) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const candidatePidText = candidateMatch[1];
|
|
81
|
+
if (!candidatePidText) {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
const candidatePid = Number.parseInt(candidatePidText, 10);
|
|
85
|
+
if (!Number.isFinite(candidatePid) || resolved.isProcessAlive(candidatePid)) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
cleanupStaging(candidate, resolved);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
37
91
|
export async function prepareStagingEnvironment(
|
|
38
92
|
// implements REQ-003
|
|
39
93
|
stagingPath, livePath, rebuild, deps) {
|
|
40
94
|
const resolved = resolveDeps(deps);
|
|
41
|
-
|
|
95
|
+
await cleanupAbandonedStagingDirectories(stagingPath, resolved);
|
|
42
96
|
cleanupStaging(stagingPath, resolved);
|
|
43
97
|
resolved.mkdirSync(stagingPath, { recursive: true });
|
|
44
98
|
if (!rebuild && resolved.existsSync(livePath)) {
|
|
@@ -107,3 +161,6 @@ stagingPath, deps) {
|
|
|
107
161
|
resolved.rmSync(stagingPath, { recursive: true, force: true });
|
|
108
162
|
}
|
|
109
163
|
}
|
|
164
|
+
function escapeRegex(value) {
|
|
165
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
166
|
+
}
|
package/dist/commands/sync.d.ts
CHANGED
|
@@ -1,13 +1,30 @@
|
|
|
1
1
|
import type { SyncSummary } from "../diagnostics.js";
|
|
2
|
+
import { PrologProcess } from "../prolog.js";
|
|
2
3
|
export declare class SyncError extends Error {
|
|
3
4
|
constructor(message: string);
|
|
4
5
|
}
|
|
5
6
|
export interface SyncResult extends SyncSummary {
|
|
6
7
|
exitCode?: number;
|
|
7
8
|
}
|
|
9
|
+
interface SyncCommandRuntimeContext {
|
|
10
|
+
currentBranch: string;
|
|
11
|
+
livePath: string;
|
|
12
|
+
rebuild: boolean;
|
|
13
|
+
stagingPath: string;
|
|
14
|
+
validateOnly: boolean;
|
|
15
|
+
}
|
|
16
|
+
interface SyncCommandRuntime {
|
|
17
|
+
afterAttach?: (context: SyncCommandRuntimeContext) => Promise<void> | void;
|
|
18
|
+
beforeSave?: (context: SyncCommandRuntimeContext & {
|
|
19
|
+
kbModified: boolean;
|
|
20
|
+
}) => Promise<void> | void;
|
|
21
|
+
createProlog?: (options: {
|
|
22
|
+
timeout: number;
|
|
23
|
+
}) => PrologProcess;
|
|
24
|
+
}
|
|
8
25
|
export declare function syncCommand(options?: {
|
|
9
26
|
validateOnly?: boolean;
|
|
10
27
|
rebuild?: boolean;
|
|
11
|
-
}): Promise<SyncResult>;
|
|
28
|
+
}, runtime?: SyncCommandRuntime): Promise<SyncResult>;
|
|
12
29
|
export { normalizeMarkdownPath } from "./sync/discovery.js";
|
|
13
30
|
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAc,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAejE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AA4B7C,qBAAa,SAAU,SAAQ,KAAK;gBACtB,OAAO,EAAE,MAAM;CAI5B;AAGD,MAAM,WAAW,UAAW,SAAQ,WAAW;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,yBAAyB;IACjC,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,UAAU,kBAAkB;IAC1B,WAAW,CAAC,EAAE,CACZ,OAAO,EAAE,yBAAyB,KAC/B,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,yBAAyB,GAAG;QAAE,UAAU,EAAE,OAAO,CAAA;KAAE,KACzD,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,aAAa,CAAC;CAChE;AAGD,wBAAsB,WAAW,CAC/B,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAO,EAC3D,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,UAAU,CAAC,CAmbrB;AAED,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC"}
|
package/dist/commands/sync.js
CHANGED
|
@@ -29,7 +29,7 @@ import { discoverSourceFiles, } from "./sync/discovery.js";
|
|
|
29
29
|
import { processExtractions } from "./sync/extraction.js";
|
|
30
30
|
import { refreshManifestCoordinates } from "./sync/manifest.js";
|
|
31
31
|
import { persistEntities, persistRelationships } from "./sync/persistence.js";
|
|
32
|
-
import { atomicPublish, cleanupStaging, prepareStagingEnvironment, } from "./sync/staging.js";
|
|
32
|
+
import { atomicPublish, cleanupStaging, createUniqueStagingPath, prepareStagingEnvironment, } from "./sync/staging.js";
|
|
33
33
|
export class SyncError extends Error {
|
|
34
34
|
constructor(message) {
|
|
35
35
|
super(message);
|
|
@@ -37,7 +37,7 @@ export class SyncError extends Error {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
// implements REQ-003, REQ-007
|
|
40
|
-
export async function syncCommand(options = {}) {
|
|
40
|
+
export async function syncCommand(options = {}, runtime = {}) {
|
|
41
41
|
const validateOnly = options.validateOnly ?? false;
|
|
42
42
|
const rebuild = options.rebuild ?? false;
|
|
43
43
|
const startTime = Date.now();
|
|
@@ -45,6 +45,7 @@ export async function syncCommand(options = {}) {
|
|
|
45
45
|
const entityCounts = {};
|
|
46
46
|
let published = false;
|
|
47
47
|
let currentBranch;
|
|
48
|
+
let stagingPath;
|
|
48
49
|
const getCurrentCommit = () => {
|
|
49
50
|
try {
|
|
50
51
|
return execSync("git rev-parse HEAD", {
|
|
@@ -199,16 +200,25 @@ export async function syncCommand(options = {}) {
|
|
|
199
200
|
if (!kbExists && !rebuild) {
|
|
200
201
|
diagnostics.push(createKbMissingDiagnostic(currentBranch, livePath));
|
|
201
202
|
}
|
|
202
|
-
|
|
203
|
+
stagingPath = createUniqueStagingPath(currentBranch, process.cwd());
|
|
204
|
+
const runtimeContext = {
|
|
205
|
+
currentBranch,
|
|
206
|
+
livePath,
|
|
207
|
+
rebuild,
|
|
208
|
+
stagingPath,
|
|
209
|
+
validateOnly,
|
|
210
|
+
};
|
|
203
211
|
await prepareStagingEnvironment(stagingPath, livePath, rebuild);
|
|
204
212
|
try {
|
|
205
|
-
const prolog =
|
|
213
|
+
const prolog = runtime.createProlog?.({ timeout: 120000 }) ??
|
|
214
|
+
new PrologProcess({ timeout: 120000 });
|
|
206
215
|
await prolog.start();
|
|
207
216
|
const attachResult = await prolog.query(`kb_attach('${stagingPath}')`);
|
|
208
217
|
if (!attachResult.success) {
|
|
209
218
|
await prolog.terminate();
|
|
210
219
|
throw new SyncError(`Failed to attach to staging KB: ${attachResult.error || "Unknown error"}`);
|
|
211
220
|
}
|
|
221
|
+
await runtime.afterAttach?.(runtimeContext);
|
|
212
222
|
const entityIds = new Set();
|
|
213
223
|
for (const { entity } of results) {
|
|
214
224
|
entityCounts[entity.type] = (entityCounts[entity.type] || 0) + 1;
|
|
@@ -263,6 +273,7 @@ export async function syncCommand(options = {}) {
|
|
|
263
273
|
if (kbModified) {
|
|
264
274
|
prolog.invalidateCache();
|
|
265
275
|
}
|
|
276
|
+
await runtime.beforeSave?.({ ...runtimeContext, kbModified });
|
|
266
277
|
const saveResult = await prolog.query("kb_save");
|
|
267
278
|
if (!saveResult.success) {
|
|
268
279
|
throw new SyncError(`Failed to save staging KB: ${saveResult.error || "Unknown error"}`);
|
|
@@ -270,6 +281,7 @@ export async function syncCommand(options = {}) {
|
|
|
270
281
|
await prolog.query("kb_detach");
|
|
271
282
|
await prolog.terminate();
|
|
272
283
|
atomicPublish(stagingPath, livePath);
|
|
284
|
+
cleanupStaging(stagingPath);
|
|
273
285
|
const evictedHashes = {};
|
|
274
286
|
const evictedSeenAt = {};
|
|
275
287
|
for (const [key, hash] of Object.entries(nextHashes)) {
|
|
@@ -312,6 +324,9 @@ export async function syncCommand(options = {}) {
|
|
|
312
324
|
}
|
|
313
325
|
}
|
|
314
326
|
catch (error) {
|
|
327
|
+
if (stagingPath) {
|
|
328
|
+
cleanupStaging(stagingPath);
|
|
329
|
+
}
|
|
315
330
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
316
331
|
console.error(`Error: ${errorMessage}`);
|
|
317
332
|
const commit = getCurrentCommit();
|
|
@@ -38,6 +38,8 @@ export interface ExtractedRelationship {
|
|
|
38
38
|
export interface ExtractionResult {
|
|
39
39
|
entity: ExtractedEntity;
|
|
40
40
|
relationships: ExtractedRelationship[];
|
|
41
|
+
/** The per-symbol source code file, distinct from the manifest file path. */
|
|
42
|
+
sourceFile?: string;
|
|
41
43
|
}
|
|
42
44
|
export declare class FrontmatterError extends Error {
|
|
43
45
|
filePath: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/extractors/markdown.ts"],"names":[],"mappings":"AAwDA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,YAAY,CAAC;IAC3D,wBAAwB,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IAEnD,SAAS,CAAC,EAAE,SAAS,GAAG,gBAAgB,GAAG,aAAa,GAAG,MAAM,CAAC;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;IACtD,UAAU,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,EAAE,qBAAqB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/extractors/markdown.ts"],"names":[],"mappings":"AAwDA,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,YAAY,CAAC;IAC3D,wBAAwB,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IAEnD,SAAS,CAAC,EAAE,SAAS,GAAG,gBAAgB,GAAG,aAAa,GAAG,MAAM,CAAC;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,CAAC;IACtD,UAAU,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC;IACxB,aAAa,EAAE,qBAAqB,EAAE,CAAC;IACvC,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA2BD,qBAAa,gBAAiB,SAAQ,KAAK;IAOhC,QAAQ,EAAE,MAAM;IANlB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;gBAG5B,OAAO,EAAE,MAAM,EACR,QAAQ,EAAE,MAAM,EACvB,OAAO,CAAC,EAAE;QACR,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB;IAYM,QAAQ;CAUlB;AA8DD,wBAAgB,sBAAsB,CAEpC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,UAAU,EAAE,MAAM,GACjB,MAAM,EAAE,CAkDV;AAmRD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GACf,gBAAgB,CAElB;AAGD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,gBAAgB,CAatE;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASjE;AASD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAQpE"}
|
|
@@ -1,7 +1,41 @@
|
|
|
1
1
|
import { type ManifestSymbolEntry, enrichSymbolCoordinatesWithTsMorph } from "./symbols-ts.js";
|
|
2
2
|
export type { ManifestSymbolEntry };
|
|
3
|
+
export type SourceAnalysisMode = "parser" | "fallback";
|
|
4
|
+
export type SourceSymbolKind = "function" | "class" | "interface" | "type" | "enum" | "variable" | "unknown";
|
|
5
|
+
export interface SourceSymbolAnalysis {
|
|
6
|
+
name: string;
|
|
7
|
+
kind: SourceSymbolKind;
|
|
8
|
+
startLine: number;
|
|
9
|
+
startColumn: number;
|
|
10
|
+
endLine: number;
|
|
11
|
+
endColumn: number;
|
|
12
|
+
directiveText?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface SourceModuleAnalysis {
|
|
15
|
+
title: string;
|
|
16
|
+
language: string;
|
|
17
|
+
analysisMode: SourceAnalysisMode;
|
|
18
|
+
fallbackReason?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface SourceAnalysisResult {
|
|
21
|
+
sourceFile: string;
|
|
22
|
+
language: string;
|
|
23
|
+
providerId: string | null;
|
|
24
|
+
module: SourceModuleAnalysis;
|
|
25
|
+
symbols: SourceSymbolAnalysis[];
|
|
26
|
+
}
|
|
27
|
+
export interface SourceAnalysisProvider {
|
|
28
|
+
id: string;
|
|
29
|
+
supportsFile(filePath: string): boolean;
|
|
30
|
+
analyzeText(filePath: string, content: string): SourceAnalysisResult;
|
|
31
|
+
}
|
|
32
|
+
export interface AnalyzeSourceTextOptions {
|
|
33
|
+
providers?: SourceAnalysisProvider[];
|
|
34
|
+
}
|
|
3
35
|
interface EnrichSymbolCoordinatesDeps {
|
|
4
36
|
enrichTsCoordinates: typeof enrichSymbolCoordinatesWithTsMorph;
|
|
5
37
|
}
|
|
38
|
+
export declare function analyzeSourceText(entries: ManifestSymbolEntry[], workspaceRoot: string, deps?: Partial<EnrichSymbolCoordinatesDeps>): Promise<ManifestSymbolEntry[]>;
|
|
39
|
+
export declare function analyzeSourceText(filePath: string, content: string, options?: AnalyzeSourceTextOptions): SourceAnalysisResult;
|
|
6
40
|
export declare function enrichSymbolCoordinates(entries: ManifestSymbolEntry[], workspaceRoot: string, deps?: Partial<EnrichSymbolCoordinatesDeps>): Promise<ManifestSymbolEntry[]>;
|
|
7
41
|
//# sourceMappingURL=symbols-coordinator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbols-coordinator.d.ts","sourceRoot":"","sources":["../../src/extractors/symbols-coordinator.ts"],"names":[],"mappings":"AAoBA,OAAO,
|
|
1
|
+
{"version":3,"file":"symbols-coordinator.d.ts","sourceRoot":"","sources":["../../src/extractors/symbols-coordinator.ts"],"names":[],"mappings":"AAoBA,OAAO,EAEL,KAAK,mBAAmB,EACxB,kCAAkC,EACnC,MAAM,iBAAiB,CAAC;AAazB,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,MAAM,MAAM,kBAAkB,GAAG,QAAQ,GAAG,UAAU,CAAC;AAEvD,MAAM,MAAM,gBAAgB,GACxB,UAAU,GACV,OAAO,GACP,WAAW,GACX,MAAM,GACN,MAAM,GACN,UAAU,GACV,SAAS,CAAC;AAEd,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,gBAAgB,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,kBAAkB,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,OAAO,EAAE,oBAAoB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IACxC,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,oBAAoB,CAAC;CACtE;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,sBAAsB,EAAE,CAAC;CACtC;AAED,UAAU,2BAA2B;IACnC,mBAAmB,EAAE,OAAO,kCAAkC,CAAC;CAChE;AA+BD,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,mBAAmB,EAAE,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAC1C,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;AAClC,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,wBAAwB,GACjC,oBAAoB,CAAC;AAgCxB,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,mBAAmB,EAAE,EAC9B,aAAa,EAAE,MAAM,EACrB,IAAI,CAAC,EAAE,OAAO,CAAC,2BAA2B,CAAC,GAC1C,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAqChC"}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import * as fs from "node:fs";
|
|
19
19
|
import * as path from "node:path";
|
|
20
|
-
import { enrichSymbolCoordinatesWithTsMorph, } from "./symbols-ts.js";
|
|
20
|
+
import { createTsMorphSourceAnalysisProvider, enrichSymbolCoordinatesWithTsMorph, } from "./symbols-ts.js";
|
|
21
21
|
const TS_JS_EXTENSIONS = new Set([
|
|
22
22
|
".ts",
|
|
23
23
|
".tsx",
|
|
@@ -28,6 +28,52 @@ const TS_JS_EXTENSIONS = new Set([
|
|
|
28
28
|
".mjs",
|
|
29
29
|
".cjs",
|
|
30
30
|
]);
|
|
31
|
+
const SOURCE_LANGUAGE_EXTENSIONS = {
|
|
32
|
+
".c": "c",
|
|
33
|
+
".cc": "cpp",
|
|
34
|
+
".cjs": "javascript",
|
|
35
|
+
".cpp": "cpp",
|
|
36
|
+
".cs": "csharp",
|
|
37
|
+
".cts": "typescript",
|
|
38
|
+
".go": "go",
|
|
39
|
+
".h": "c",
|
|
40
|
+
".hpp": "cpp",
|
|
41
|
+
".java": "java",
|
|
42
|
+
".js": "javascript",
|
|
43
|
+
".jsx": "javascript",
|
|
44
|
+
".kt": "kotlin",
|
|
45
|
+
".mjs": "javascript",
|
|
46
|
+
".mts": "typescript",
|
|
47
|
+
".php": "php",
|
|
48
|
+
".py": "python",
|
|
49
|
+
".rb": "ruby",
|
|
50
|
+
".rs": "rust",
|
|
51
|
+
".swift": "swift",
|
|
52
|
+
".ts": "typescript",
|
|
53
|
+
".tsx": "typescript",
|
|
54
|
+
};
|
|
55
|
+
const DEFAULT_SOURCE_ANALYSIS_PROVIDERS = [
|
|
56
|
+
createTsMorphSourceAnalysisProvider(),
|
|
57
|
+
];
|
|
58
|
+
// implements REQ-001
|
|
59
|
+
export function analyzeSourceText(filePathOrEntries, contentOrWorkspaceRoot, optionsOrDeps) {
|
|
60
|
+
if (Array.isArray(filePathOrEntries)) {
|
|
61
|
+
return enrichSymbolCoordinates(filePathOrEntries, contentOrWorkspaceRoot, optionsOrDeps);
|
|
62
|
+
}
|
|
63
|
+
const providers = optionsOrDeps?.providers ??
|
|
64
|
+
DEFAULT_SOURCE_ANALYSIS_PROVIDERS;
|
|
65
|
+
for (const provider of providers) {
|
|
66
|
+
if (!provider.supportsFile(filePathOrEntries))
|
|
67
|
+
continue;
|
|
68
|
+
try {
|
|
69
|
+
return provider.analyzeText(filePathOrEntries, contentOrWorkspaceRoot);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return createFallbackAnalysis(filePathOrEntries, "provider_error");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return createFallbackAnalysis(filePathOrEntries, "unsupported_language");
|
|
76
|
+
}
|
|
31
77
|
export async function enrichSymbolCoordinates(entries, workspaceRoot, deps) {
|
|
32
78
|
// implements REQ-vscode-traceability
|
|
33
79
|
const enrichTsCoordinates = deps?.enrichTsCoordinates ?? enrichSymbolCoordinatesWithTsMorph;
|
|
@@ -106,3 +152,26 @@ function resolveSourcePath(sourceFile, workspaceRoot) {
|
|
|
106
152
|
function escapeRegex(value) {
|
|
107
153
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
108
154
|
}
|
|
155
|
+
function createFallbackAnalysis(filePath, fallbackReason) {
|
|
156
|
+
const language = detectSourceLanguage(filePath);
|
|
157
|
+
return {
|
|
158
|
+
sourceFile: filePath,
|
|
159
|
+
language,
|
|
160
|
+
providerId: null,
|
|
161
|
+
module: {
|
|
162
|
+
title: inferModuleTitle(filePath),
|
|
163
|
+
language,
|
|
164
|
+
analysisMode: "fallback",
|
|
165
|
+
fallbackReason,
|
|
166
|
+
},
|
|
167
|
+
symbols: [],
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function detectSourceLanguage(filePath) {
|
|
171
|
+
return SOURCE_LANGUAGE_EXTENSIONS[path.extname(filePath).toLowerCase()] ?? "unknown";
|
|
172
|
+
}
|
|
173
|
+
function inferModuleTitle(filePath) {
|
|
174
|
+
const extension = path.extname(filePath);
|
|
175
|
+
const basename = path.basename(filePath, extension);
|
|
176
|
+
return basename.length > 0 ? basename : path.basename(filePath);
|
|
177
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { SourceAnalysisProvider } from "./symbols-coordinator.js";
|
|
1
2
|
export interface SymbolCoordinates {
|
|
2
3
|
sourceLine: number;
|
|
3
4
|
sourceColumn: number;
|
|
@@ -17,5 +18,6 @@ export interface ManifestSymbolEntry {
|
|
|
17
18
|
links?: string[];
|
|
18
19
|
[key: string]: unknown;
|
|
19
20
|
}
|
|
21
|
+
export declare function createTsMorphSourceAnalysisProvider(): SourceAnalysisProvider;
|
|
20
22
|
export declare function enrichSymbolCoordinatesWithTsMorph(entries: ManifestSymbolEntry[], workspaceRoot: string): Promise<ManifestSymbolEntry[]>;
|
|
21
23
|
//# sourceMappingURL=symbols-ts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbols-ts.d.ts","sourceRoot":"","sources":["../../src/extractors/symbols-ts.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;
|
|
1
|
+
{"version":3,"file":"symbols-ts.d.ts","sourceRoot":"","sources":["../../src/extractors/symbols-ts.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EACV,sBAAsB,EAIvB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAcD,wBAAgB,mCAAmC,IAAI,sBAAsB,CA6B5E;AAED,wBAAsB,kCAAkC,CACtD,OAAO,EAAE,mBAAmB,EAAE,EAC9B,aAAa,EAAE,MAAM,GACpB,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAuEhC"}
|