kibi-cli 0.6.2 → 0.7.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/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/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 +6 -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
|
@@ -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);
|
|
@@ -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"}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import { access, readFile } from "node:fs/promises";
|
|
19
19
|
import * as path from "node:path";
|
|
20
|
-
import { Project, } from "ts-morph";
|
|
20
|
+
import { Project, ScriptKind, } from "ts-morph";
|
|
21
21
|
const SUPPORTED_SOURCE_EXTENSIONS = new Set([
|
|
22
22
|
".ts",
|
|
23
23
|
".tsx",
|
|
@@ -28,6 +28,35 @@ const SUPPORTED_SOURCE_EXTENSIONS = new Set([
|
|
|
28
28
|
".mjs",
|
|
29
29
|
".cjs",
|
|
30
30
|
]);
|
|
31
|
+
// implements REQ-001
|
|
32
|
+
export function createTsMorphSourceAnalysisProvider() {
|
|
33
|
+
const project = new Project({
|
|
34
|
+
skipAddingFilesFromTsConfig: true,
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
id: "ts-morph",
|
|
38
|
+
supportsFile(filePath) {
|
|
39
|
+
return SUPPORTED_SOURCE_EXTENSIONS.has(path.extname(filePath).toLowerCase());
|
|
40
|
+
},
|
|
41
|
+
analyzeText(filePath, content) {
|
|
42
|
+
const sourceFile = project.createSourceFile(filePath, content, {
|
|
43
|
+
overwrite: true,
|
|
44
|
+
scriptKind: chooseScriptKind(filePath),
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
sourceFile: filePath,
|
|
48
|
+
language: inferSourceLanguage(filePath),
|
|
49
|
+
providerId: "ts-morph",
|
|
50
|
+
module: {
|
|
51
|
+
title: inferModuleTitle(filePath),
|
|
52
|
+
language: inferSourceLanguage(filePath),
|
|
53
|
+
analysisMode: "parser",
|
|
54
|
+
},
|
|
55
|
+
symbols: collectSourceSymbols(sourceFile),
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
}
|
|
31
60
|
export async function enrichSymbolCoordinatesWithTsMorph(entries, workspaceRoot) {
|
|
32
61
|
// implements REQ-vscode-traceability
|
|
33
62
|
const project = new Project({
|
|
@@ -142,6 +171,84 @@ async function enrichWithTextFallbackInternal(entry, absolutePath) {
|
|
|
142
171
|
return entry;
|
|
143
172
|
}
|
|
144
173
|
}
|
|
174
|
+
function collectSourceSymbols(sourceFile) {
|
|
175
|
+
const symbols = [];
|
|
176
|
+
for (const decl of sourceFile.getFunctions()) {
|
|
177
|
+
if (!decl.isExported())
|
|
178
|
+
continue;
|
|
179
|
+
symbols.push(toSourceSymbolAnalysis(sourceFile, decl.getName() ?? "<anonymous>", "function", decl.getNameNode() ?? decl, decl, `${decl.getFullText()}\n${decl
|
|
180
|
+
.getJsDocs()
|
|
181
|
+
.map((doc) => doc.getFullText())
|
|
182
|
+
.join("\n")}`));
|
|
183
|
+
}
|
|
184
|
+
for (const decl of sourceFile.getClasses()) {
|
|
185
|
+
if (!decl.isExported())
|
|
186
|
+
continue;
|
|
187
|
+
symbols.push(toSourceSymbolAnalysis(sourceFile, decl.getName() ?? "<anonymous>", "class", decl.getNameNode() ?? decl, decl, `${decl.getText()}\n${decl
|
|
188
|
+
.getJsDocs()
|
|
189
|
+
.map((doc) => doc.getFullText())
|
|
190
|
+
.join("\n")}`));
|
|
191
|
+
}
|
|
192
|
+
for (const decl of sourceFile.getInterfaces()) {
|
|
193
|
+
if (!decl.isExported())
|
|
194
|
+
continue;
|
|
195
|
+
symbols.push(toSourceSymbolAnalysis(sourceFile, decl.getName() ?? "<anonymous>", "interface", decl.getNameNode() ?? decl, decl, decl.getText()));
|
|
196
|
+
}
|
|
197
|
+
for (const decl of sourceFile.getTypeAliases()) {
|
|
198
|
+
if (!decl.isExported())
|
|
199
|
+
continue;
|
|
200
|
+
symbols.push(toSourceSymbolAnalysis(sourceFile, decl.getName() ?? "<anonymous>", "type", decl.getNameNode() ?? decl, decl, decl.getText()));
|
|
201
|
+
}
|
|
202
|
+
for (const decl of sourceFile.getEnums()) {
|
|
203
|
+
if (!decl.isExported())
|
|
204
|
+
continue;
|
|
205
|
+
symbols.push(toSourceSymbolAnalysis(sourceFile, decl.getName() ?? "<anonymous>", "enum", decl.getNameNode() ?? decl, decl, decl.getText()));
|
|
206
|
+
}
|
|
207
|
+
for (const statement of sourceFile.getVariableStatements()) {
|
|
208
|
+
if (!statement.isExported())
|
|
209
|
+
continue;
|
|
210
|
+
for (const declaration of statement.getDeclarations()) {
|
|
211
|
+
symbols.push(toSourceSymbolAnalysis(sourceFile, declaration.getName(), "variable", declaration.getNameNode() ?? declaration, declaration, declaration.getText()));
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return symbols;
|
|
215
|
+
}
|
|
216
|
+
function toSourceSymbolAnalysis(sourceFile, name, kind, startNode, endNode, directiveText) {
|
|
217
|
+
const start = sourceFile.getLineAndColumnAtPos(startNode.getStart());
|
|
218
|
+
const end = sourceFile.getLineAndColumnAtPos(endNode.getEnd());
|
|
219
|
+
return {
|
|
220
|
+
name,
|
|
221
|
+
kind,
|
|
222
|
+
startLine: start.line,
|
|
223
|
+
startColumn: Math.max(0, start.column - 1),
|
|
224
|
+
endLine: end.line,
|
|
225
|
+
endColumn: Math.max(0, end.column - 1),
|
|
226
|
+
directiveText,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function chooseScriptKind(filePath) {
|
|
230
|
+
const lower = filePath.toLowerCase();
|
|
231
|
+
if (lower.endsWith(".tsx"))
|
|
232
|
+
return ScriptKind.TSX;
|
|
233
|
+
if (lower.endsWith(".ts") || lower.endsWith(".mts") || lower.endsWith(".cts")) {
|
|
234
|
+
return ScriptKind.TS;
|
|
235
|
+
}
|
|
236
|
+
if (lower.endsWith(".jsx"))
|
|
237
|
+
return ScriptKind.JSX;
|
|
238
|
+
return ScriptKind.JS;
|
|
239
|
+
}
|
|
240
|
+
function inferSourceLanguage(filePath) {
|
|
241
|
+
const extension = path.extname(filePath).toLowerCase();
|
|
242
|
+
if ([".ts", ".tsx", ".mts", ".cts"].includes(extension)) {
|
|
243
|
+
return "typescript";
|
|
244
|
+
}
|
|
245
|
+
return "javascript";
|
|
246
|
+
}
|
|
247
|
+
function inferModuleTitle(filePath) {
|
|
248
|
+
const extension = path.extname(filePath);
|
|
249
|
+
const basename = path.basename(filePath, extension);
|
|
250
|
+
return basename.length > 0 ? basename : path.basename(filePath);
|
|
251
|
+
}
|
|
145
252
|
function findNamedDeclaration(sourceFile, title) {
|
|
146
253
|
const candidates = [];
|
|
147
254
|
for (const decl of sourceFile.getFunctions()) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brief-config.d.ts","sourceRoot":"","sources":["../../src/public/brief-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEnE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAsB,GAAG,YAAY,CAoBzE"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { loadConfig } from "../utils/config.js";
|
|
2
|
+
export function loadBriefConfig(cwd = process.cwd()) {
|
|
3
|
+
const briefs = loadConfig(cwd).briefs;
|
|
4
|
+
return {
|
|
5
|
+
enabled: briefs?.enabled ?? true,
|
|
6
|
+
retention: {
|
|
7
|
+
maxPerBranch: briefs?.retention?.maxPerBranch ?? 200,
|
|
8
|
+
maxAgeDays: briefs?.retention?.maxAgeDays ?? 14,
|
|
9
|
+
keepUnread: briefs?.retention?.keepUnread ?? true,
|
|
10
|
+
},
|
|
11
|
+
channels: {
|
|
12
|
+
vscode: briefs?.channels?.vscode ?? true,
|
|
13
|
+
tui: briefs?.channels?.tui ?? true,
|
|
14
|
+
},
|
|
15
|
+
tui: {
|
|
16
|
+
toast: briefs?.tui?.toast ?? true,
|
|
17
|
+
appendPrompt: briefs?.tui?.appendPrompt ?? true,
|
|
18
|
+
idleDelayMs: briefs?.tui?.idleDelayMs ?? 1500,
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { enrichSymbolCoordinates, type ManifestSymbolEntry, } from "../../extractors/symbols-coordinator.js";
|
|
1
|
+
export { analyzeSourceText, enrichSymbolCoordinates, type ManifestSymbolEntry, type AnalyzeSourceTextOptions, type SourceAnalysisProvider, type SourceAnalysisResult, type SourceModuleAnalysis, type SourceSymbolAnalysis, type SourceSymbolKind, } from "../../extractors/symbols-coordinator.js";
|
|
2
2
|
//# sourceMappingURL=symbols-coordinator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbols-coordinator.d.ts","sourceRoot":"","sources":["../../../src/public/extractors/symbols-coordinator.ts"],"names":[],"mappings":"AAkBA,OAAO,EACL,uBAAuB,EACvB,KAAK,mBAAmB,
|
|
1
|
+
{"version":3,"file":"symbols-coordinator.d.ts","sourceRoot":"","sources":["../../../src/public/extractors/symbols-coordinator.ts"],"names":[],"mappings":"AAkBA,OAAO,EACL,iBAAiB,EACjB,uBAAuB,EACvB,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,gBAAgB,GACtB,MAAM,yCAAyC,CAAC"}
|
|
@@ -15,4 +15,4 @@
|
|
|
15
15
|
You should have received a copy of the GNU Affero General Public License
|
|
16
16
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
17
|
*/
|
|
18
|
-
export { enrichSymbolCoordinates, } from "../../extractors/symbols-coordinator.js";
|
|
18
|
+
export { analyzeSourceText, enrichSymbolCoordinates, } from "../../extractors/symbols-coordinator.js";
|
package/dist/utils/config.d.ts
CHANGED
|
@@ -12,12 +12,30 @@ export interface KbConfigPaths {
|
|
|
12
12
|
facts?: string;
|
|
13
13
|
symbols?: string;
|
|
14
14
|
}
|
|
15
|
+
export interface BriefsConfig {
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
retention?: {
|
|
18
|
+
maxPerBranch?: number;
|
|
19
|
+
maxAgeDays?: number;
|
|
20
|
+
keepUnread?: boolean;
|
|
21
|
+
};
|
|
22
|
+
channels: {
|
|
23
|
+
vscode: boolean;
|
|
24
|
+
tui: boolean;
|
|
25
|
+
};
|
|
26
|
+
tui: {
|
|
27
|
+
toast: boolean;
|
|
28
|
+
appendPrompt: boolean;
|
|
29
|
+
idleDelayMs?: number;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
15
32
|
/**
|
|
16
33
|
* Shared configuration for Kibi.
|
|
17
34
|
* Stored in .kb/config.json
|
|
18
35
|
*/
|
|
19
36
|
export interface KbConfig {
|
|
20
37
|
paths: KbConfigPaths;
|
|
38
|
+
briefs?: BriefsConfig;
|
|
21
39
|
/**
|
|
22
40
|
* @deprecated defaultBranch is deprecated. Branch lifecycle now follows git naturally
|
|
23
41
|
* without requiring a configured default. This field is ignored but kept for compatibility.
|
|
@@ -26,9 +44,6 @@ export interface KbConfig {
|
|
|
26
44
|
checks?: ChecksConfig;
|
|
27
45
|
}
|
|
28
46
|
export type { ChecksConfig, SymbolTraceabilityOptions };
|
|
29
|
-
/**
|
|
30
|
-
* Default configuration values for new repositories.
|
|
31
|
-
*/
|
|
32
47
|
export declare const DEFAULT_CONFIG: KbConfig & {
|
|
33
48
|
$schema: string;
|
|
34
49
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAoBA,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,yBAAyB,EAC/B,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,aAAa,CAAC;IACrB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,YAAY,EAAE,YAAY,EAAE,yBAAyB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAoBA,OAAO,EACL,KAAK,YAAY,EAEjB,KAAK,yBAAyB,EAC/B,MAAM,oBAAoB,CAAC;AAE5B;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE;QACV,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,OAAO,CAAC;KACtB,CAAC;IACF,QAAQ,EAAE;QACR,MAAM,EAAE,OAAO,CAAC;QAChB,GAAG,EAAE,OAAO,CAAC;KACd,CAAC;IACF,GAAG,EAAE;QACH,KAAK,EAAE,OAAO,CAAC;QACf,YAAY,EAAE,OAAO,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,YAAY,EAAE,YAAY,EAAE,yBAAyB,EAAE,CAAC;AAwBxD,eAAO,MAAM,cAAc,EAAE,QAAQ,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAexD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,aAShC,CAAC;AAqBF;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,GAAG,GAAE,MAAsB,GAAG,QAAQ,CAqChE;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,GAAG,GAAE,MAAsB,GAAG,QAAQ,CAqCpE"}
|
package/dist/utils/config.js
CHANGED
|
@@ -21,6 +21,24 @@ import { DEFAULT_CHECKS_CONFIG, } from "./rule-registry.js";
|
|
|
21
21
|
/**
|
|
22
22
|
* Default configuration values for new repositories.
|
|
23
23
|
*/
|
|
24
|
+
const DEFAULT_BRIEFS_CONFIG = {
|
|
25
|
+
enabled: true,
|
|
26
|
+
retention: {
|
|
27
|
+
maxPerBranch: 200,
|
|
28
|
+
maxAgeDays: 14,
|
|
29
|
+
keepUnread: true,
|
|
30
|
+
},
|
|
31
|
+
channels: {
|
|
32
|
+
vscode: true,
|
|
33
|
+
tui: true,
|
|
34
|
+
},
|
|
35
|
+
tui: {
|
|
36
|
+
toast: true,
|
|
37
|
+
appendPrompt: true,
|
|
38
|
+
idleDelayMs: 1500,
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
// implements REQ-003
|
|
24
42
|
export const DEFAULT_CONFIG = {
|
|
25
43
|
$schema: "https://raw.githubusercontent.com/Looted/kibi/master/packages/cli/schema/config.json",
|
|
26
44
|
paths: {
|
|
@@ -33,6 +51,7 @@ export const DEFAULT_CONFIG = {
|
|
|
33
51
|
facts: "documentation/facts",
|
|
34
52
|
symbols: "documentation/symbols.yaml",
|
|
35
53
|
},
|
|
54
|
+
briefs: DEFAULT_BRIEFS_CONFIG,
|
|
36
55
|
checks: DEFAULT_CHECKS_CONFIG,
|
|
37
56
|
};
|
|
38
57
|
/**
|
|
@@ -48,6 +67,24 @@ export const DEFAULT_SYNC_PATHS = {
|
|
|
48
67
|
facts: "facts/**/*.md",
|
|
49
68
|
symbols: "symbols.yaml",
|
|
50
69
|
};
|
|
70
|
+
function mergeBriefsConfig(userBriefs) {
|
|
71
|
+
return {
|
|
72
|
+
...DEFAULT_BRIEFS_CONFIG,
|
|
73
|
+
...userBriefs,
|
|
74
|
+
channels: {
|
|
75
|
+
...DEFAULT_BRIEFS_CONFIG.channels,
|
|
76
|
+
...userBriefs?.channels,
|
|
77
|
+
},
|
|
78
|
+
tui: {
|
|
79
|
+
...DEFAULT_BRIEFS_CONFIG.tui,
|
|
80
|
+
...userBriefs?.tui,
|
|
81
|
+
},
|
|
82
|
+
retention: {
|
|
83
|
+
...DEFAULT_BRIEFS_CONFIG.retention,
|
|
84
|
+
...userBriefs?.retention,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
51
88
|
/**
|
|
52
89
|
* Load and parse the Kibi configuration from .kb/config.json.
|
|
53
90
|
* Falls back to DEFAULT_CONFIG if the file doesn't exist or is invalid.
|
|
@@ -74,6 +111,7 @@ export function loadConfig(cwd = process.cwd()) {
|
|
|
74
111
|
...DEFAULT_CONFIG.paths,
|
|
75
112
|
...userConfig.paths,
|
|
76
113
|
},
|
|
114
|
+
briefs: mergeBriefsConfig(userConfig.briefs),
|
|
77
115
|
...(userConfig.defaultBranch !== undefined
|
|
78
116
|
? { defaultBranch: userConfig.defaultBranch }
|
|
79
117
|
: {}),
|
|
@@ -118,6 +156,7 @@ export function loadSyncConfig(cwd = process.cwd()) {
|
|
|
118
156
|
...DEFAULT_SYNC_PATHS,
|
|
119
157
|
...userConfig.paths,
|
|
120
158
|
},
|
|
159
|
+
briefs: mergeBriefsConfig(userConfig.briefs),
|
|
121
160
|
...(userConfig.defaultBranch !== undefined
|
|
122
161
|
? { defaultBranch: userConfig.defaultBranch }
|
|
123
162
|
: {}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rule-registry.d.ts","sourceRoot":"","sources":["../../src/utils/rule-registry.ts"],"names":[],"mappings":"AAkBA;;;GAGG;AAEH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,UAAU,GAAG,WAAW,GAAG,WAAW,GAAG,cAAc,CAAC;CACnE;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,mCAAmC;AACnC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,kBAAkB,EAAE,yBAAyB,CAAC;CAC/C;AAED;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAE,SAAS,cAAc,
|
|
1
|
+
{"version":3,"file":"rule-registry.d.ts","sourceRoot":"","sources":["../../src/utils/rule-registry.ts"],"names":[],"mappings":"AAkBA;;;GAGG;AAEH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,UAAU,GAAG,WAAW,GAAG,WAAW,GAAG,cAAc,CAAC;CACnE;AAED,MAAM,WAAW,yBAAyB;IACxC,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,mCAAmC;AACnC,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,kBAAkB,EAAE,yBAAyB,CAAC;CAC/C;AAED;;;GAGG;AACH,eAAO,MAAM,KAAK,EAAE,SAAS,cAAc,EAqEjC,CAAC;AAEX;;GAEG;AACH,eAAO,MAAM,UAAU,aAAoC,CAAC;AAE5D;;GAEG;AACH,eAAO,MAAM,qBAAqB,EAAE,YAKnC,CAAC;AAEF;;;;;GAKG;AAEH,wBAAgB,iBAAiB,CAC/B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACrC,QAAQ,CAAC,EAAE,MAAM,GAChB,GAAG,CAAC,MAAM,CAAC,CAsBb;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK5D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAC9B,YAAY,CAWd"}
|
|
@@ -75,6 +75,12 @@ export const RULES = [
|
|
|
75
75
|
defaultEnabled: false,
|
|
76
76
|
category: "integrity",
|
|
77
77
|
},
|
|
78
|
+
{
|
|
79
|
+
name: "strict-req-fact-pairing",
|
|
80
|
+
description: "Detect requirements with incomplete strict subject/property fact pairing for contradiction-safe semantics",
|
|
81
|
+
defaultEnabled: false,
|
|
82
|
+
category: "integrity",
|
|
83
|
+
},
|
|
78
84
|
];
|
|
79
85
|
/**
|
|
80
86
|
* Set of all rule names for quick lookups.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kibi-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Kibi CLI for knowledge base management",
|
|
6
6
|
"engines": {
|
|
@@ -74,6 +74,10 @@
|
|
|
74
74
|
"./public/check-types": {
|
|
75
75
|
"types": "./dist/public/check-types.d.ts",
|
|
76
76
|
"default": "./dist/public/check-types.js"
|
|
77
|
+
},
|
|
78
|
+
"./brief-config": {
|
|
79
|
+
"types": "./dist/public/brief-config.d.ts",
|
|
80
|
+
"default": "./dist/public/brief-config.js"
|
|
77
81
|
}
|
|
78
82
|
},
|
|
79
83
|
"types": "./dist/cli.d.ts",
|
|
@@ -84,7 +88,7 @@
|
|
|
84
88
|
"fast-glob": "^3.2.12",
|
|
85
89
|
"gray-matter": "^4.0.3",
|
|
86
90
|
"js-yaml": "^4.1.0",
|
|
87
|
-
"kibi-core": "^0.5.
|
|
91
|
+
"kibi-core": "^0.5.2",
|
|
88
92
|
"ts-morph": "^23.0.0"
|
|
89
93
|
},
|
|
90
94
|
"devDependencies": {
|
package/schema/config.json
CHANGED
|
@@ -61,6 +61,74 @@
|
|
|
61
61
|
"description": "[DEPRECATED] No longer used. Branch lifecycle now follows git naturally without requiring a configured default. This field is ignored but kept for backward compatibility.",
|
|
62
62
|
"deprecated": true
|
|
63
63
|
},
|
|
64
|
+
"briefs": {
|
|
65
|
+
"type": "object",
|
|
66
|
+
"description": "Configuration for shared brief delivery defaults",
|
|
67
|
+
"properties": {
|
|
68
|
+
"enabled": {
|
|
69
|
+
"type": "boolean",
|
|
70
|
+
"default": true
|
|
71
|
+
},
|
|
72
|
+
"retention": {
|
|
73
|
+
"type": "object",
|
|
74
|
+
"properties": {
|
|
75
|
+
"maxPerBranch": {
|
|
76
|
+
"type": "integer",
|
|
77
|
+
"minimum": 1,
|
|
78
|
+
"maximum": 10000,
|
|
79
|
+
"default": 200
|
|
80
|
+
},
|
|
81
|
+
"maxAgeDays": {
|
|
82
|
+
"type": "integer",
|
|
83
|
+
"minimum": 1,
|
|
84
|
+
"maximum": 3650,
|
|
85
|
+
"default": 14
|
|
86
|
+
},
|
|
87
|
+
"keepUnread": {
|
|
88
|
+
"type": "boolean",
|
|
89
|
+
"default": true
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"additionalProperties": false
|
|
93
|
+
},
|
|
94
|
+
"channels": {
|
|
95
|
+
"type": "object",
|
|
96
|
+
"properties": {
|
|
97
|
+
"vscode": {
|
|
98
|
+
"type": "boolean",
|
|
99
|
+
"default": true
|
|
100
|
+
},
|
|
101
|
+
"tui": {
|
|
102
|
+
"type": "boolean",
|
|
103
|
+
"default": true
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
"additionalProperties": false
|
|
107
|
+
},
|
|
108
|
+
"tui": {
|
|
109
|
+
"type": "object",
|
|
110
|
+
"properties": {
|
|
111
|
+
"toast": {
|
|
112
|
+
"type": "boolean",
|
|
113
|
+
"default": true
|
|
114
|
+
},
|
|
115
|
+
"appendPrompt": {
|
|
116
|
+
"type": "boolean",
|
|
117
|
+
"default": true
|
|
118
|
+
},
|
|
119
|
+
"idleDelayMs": {
|
|
120
|
+
"type": "integer",
|
|
121
|
+
"minimum": 0,
|
|
122
|
+
"maximum": 60000,
|
|
123
|
+
"default": 1500,
|
|
124
|
+
"description": "Delay in milliseconds after session.idle before idle-brief generation is attempted"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"additionalProperties": false
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
"additionalProperties": false
|
|
131
|
+
},
|
|
64
132
|
"checks": {
|
|
65
133
|
"type": "object",
|
|
66
134
|
"description": "Configuration for KB validation rules",
|
|
@@ -113,6 +181,11 @@
|
|
|
113
181
|
"type": "boolean",
|
|
114
182
|
"description": "Detect malformed strict facts (facts with fact_kind that are missing required fields)",
|
|
115
183
|
"default": false
|
|
184
|
+
},
|
|
185
|
+
"strict-req-fact-pairing": {
|
|
186
|
+
"type": "boolean",
|
|
187
|
+
"description": "Detect requirements with incomplete strict subject/property fact pairing for contradiction-safe semantics",
|
|
188
|
+
"default": false
|
|
116
189
|
}
|
|
117
190
|
},
|
|
118
191
|
"additionalProperties": false
|
package/schema/entities.pl
CHANGED
|
@@ -20,6 +20,7 @@ entity_property(_, status, atom).
|
|
|
20
20
|
entity_property(_, created_at, datetime).
|
|
21
21
|
entity_property(_, updated_at, datetime).
|
|
22
22
|
entity_property(_, source, uri).
|
|
23
|
+
entity_property(_, sourceFile, uri).
|
|
23
24
|
|
|
24
25
|
% Optional properties
|
|
25
26
|
entity_property(_, tags, list).
|
package/schema/relationships.pl
CHANGED
|
@@ -9,6 +9,7 @@ relationship_type(verified_by).
|
|
|
9
9
|
relationship_type(validates).
|
|
10
10
|
relationship_type(implements).
|
|
11
11
|
relationship_type(covered_by).
|
|
12
|
+
relationship_type(executable_for).
|
|
12
13
|
relationship_type(constrained_by).
|
|
13
14
|
relationship_type(guards).
|
|
14
15
|
relationship_type(publishes).
|
|
@@ -25,6 +26,9 @@ valid_relationship(verified_by, req, test).
|
|
|
25
26
|
valid_relationship(validates, test, req).
|
|
26
27
|
valid_relationship(implements, symbol, req).
|
|
27
28
|
valid_relationship(covered_by, symbol, test).
|
|
29
|
+
valid_relationship(executable_for, symbol, test).
|
|
30
|
+
valid_relationship(verified_by, scenario, test).
|
|
31
|
+
valid_relationship(validates, test, scenario).
|
|
28
32
|
valid_relationship(constrained_by, symbol, adr).
|
|
29
33
|
% guards can target symbol, event, or req
|
|
30
34
|
valid_relationship(guards, flag, symbol).
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { loadConfig, type BriefsConfig } from "../utils/config.js";
|
|
2
|
+
|
|
3
|
+
export type { BriefsConfig } from "../utils/config.js";
|
|
4
|
+
|
|
5
|
+
export function loadBriefConfig(cwd: string = process.cwd()): BriefsConfig { // implements REQ-003
|
|
6
|
+
const briefs = loadConfig(cwd).briefs;
|
|
7
|
+
|
|
8
|
+
return {
|
|
9
|
+
enabled: briefs?.enabled ?? true,
|
|
10
|
+
retention: {
|
|
11
|
+
maxPerBranch: briefs?.retention?.maxPerBranch ?? 200,
|
|
12
|
+
maxAgeDays: briefs?.retention?.maxAgeDays ?? 14,
|
|
13
|
+
keepUnread: briefs?.retention?.keepUnread ?? true,
|
|
14
|
+
},
|
|
15
|
+
channels: {
|
|
16
|
+
vscode: briefs?.channels?.vscode ?? true,
|
|
17
|
+
tui: briefs?.channels?.tui ?? true,
|
|
18
|
+
},
|
|
19
|
+
tui: {
|
|
20
|
+
toast: briefs?.tui?.toast ?? true,
|
|
21
|
+
appendPrompt: briefs?.tui?.appendPrompt ?? true,
|
|
22
|
+
idleDelayMs: briefs?.tui?.idleDelayMs ?? 1500,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -17,6 +17,13 @@
|
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
19
|
export {
|
|
20
|
+
analyzeSourceText,
|
|
20
21
|
enrichSymbolCoordinates,
|
|
21
22
|
type ManifestSymbolEntry,
|
|
23
|
+
type AnalyzeSourceTextOptions,
|
|
24
|
+
type SourceAnalysisProvider,
|
|
25
|
+
type SourceAnalysisResult,
|
|
26
|
+
type SourceModuleAnalysis,
|
|
27
|
+
type SourceSymbolAnalysis,
|
|
28
|
+
type SourceSymbolKind,
|
|
22
29
|
} from "../../extractors/symbols-coordinator.js";
|