kibi-mcp 0.2.3 → 0.3.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/env.js +0 -27
- package/dist/server/docs.js +260 -0
- package/dist/server/session.js +218 -0
- package/dist/server/tools.js +199 -0
- package/dist/server/transport.js +71 -0
- package/dist/server.js +13 -846
- package/dist/tools/branch.js +0 -27
- package/dist/tools/check.js +32 -27
- package/dist/tools/context.js +1 -207
- package/dist/tools/coverage-report.js +0 -17
- package/dist/tools/delete.js +1 -20
- package/dist/tools/derive.js +1 -20
- package/dist/tools/impact.js +1 -20
- package/dist/tools/list-types.js +0 -17
- package/dist/tools/prolog-list.js +0 -27
- package/dist/tools/query-relationships.js +0 -17
- package/dist/tools/query.js +31 -249
- package/dist/tools/suggest-shared-facts.js +2 -19
- package/dist/tools/symbols.js +0 -27
- package/dist/tools/upsert.js +9 -11
- package/dist/tools-config.js +8 -32
- package/dist/workspace.js +0 -27
- package/package.json +3 -3
package/dist/tools/branch.js
CHANGED
|
@@ -15,33 +15,6 @@
|
|
|
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
|
-
/*
|
|
19
|
-
How to apply this header to source files (examples)
|
|
20
|
-
|
|
21
|
-
1) Prepend header to a single file (POSIX shells):
|
|
22
|
-
|
|
23
|
-
cat LICENSE_HEADER.txt "$FILE" > "$FILE".with-header && mv "$FILE".with-header "$FILE"
|
|
24
|
-
|
|
25
|
-
2) Apply to multiple files (example: the project's main entry files):
|
|
26
|
-
|
|
27
|
-
for f in packages/cli/bin/kibi packages/mcp/bin/kibi-mcp packages/cli/src/*.ts packages/mcp/src/*.ts; do
|
|
28
|
-
if [ -f "$f" ]; then
|
|
29
|
-
cp "$f" "$f".bak
|
|
30
|
-
(cat LICENSE_HEADER.txt; echo; cat "$f" ) > "$f".new && mv "$f".new "$f"
|
|
31
|
-
fi
|
|
32
|
-
done
|
|
33
|
-
|
|
34
|
-
3) Avoid duplicating the header: run a quick guard to only add if missing
|
|
35
|
-
|
|
36
|
-
for f in packages/cli/bin/kibi packages/mcp/bin/kibi-mcp; do
|
|
37
|
-
if [ -f "$f" ]; then
|
|
38
|
-
if ! head -n 5 "$f" | grep -q "Copyright (C) 2026 Piotr Franczyk"; then
|
|
39
|
-
cp "$f" "$f".bak
|
|
40
|
-
(cat LICENSE_HEADER.txt; echo; cat "$f" ) > "$f".new && mv "$f".new "$f"
|
|
41
|
-
fi
|
|
42
|
-
fi
|
|
43
|
-
done
|
|
44
|
-
*/
|
|
45
18
|
import { execSync } from "node:child_process";
|
|
46
19
|
import * as fs from "node:fs";
|
|
47
20
|
import * as path from "node:path";
|
package/dist/tools/check.js
CHANGED
|
@@ -15,33 +15,6 @@
|
|
|
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
|
-
/*
|
|
19
|
-
How to apply this header to source files (examples)
|
|
20
|
-
|
|
21
|
-
1) Prepend header to a single file (POSIX shells):
|
|
22
|
-
|
|
23
|
-
cat LICENSE_HEADER.txt "$FILE" > "$FILE".with-header && mv "$FILE".with-header "$FILE"
|
|
24
|
-
|
|
25
|
-
2) Apply to multiple files (example: the project's main entry files):
|
|
26
|
-
|
|
27
|
-
for f in packages/cli/bin/kibi packages/mcp/bin/kibi-mcp packages/cli/src/*.ts packages/mcp/src/*.ts; do
|
|
28
|
-
if [ -f "$f" ]; then
|
|
29
|
-
cp "$f" "$f".bak
|
|
30
|
-
(cat LICENSE_HEADER.txt; echo; cat "$f" ) > "$f".new && mv "$f".new "$f"
|
|
31
|
-
fi
|
|
32
|
-
done
|
|
33
|
-
|
|
34
|
-
3) Avoid duplicating the header: run a quick guard to only add if missing
|
|
35
|
-
|
|
36
|
-
for f in packages/cli/bin/kibi packages/mcp/bin/kibi-mcp; do
|
|
37
|
-
if [ -f "$f" ]; then
|
|
38
|
-
if ! head -n 5 "$f" | grep -q "Copyright (C) 2026 Piotr Franczyk"; then
|
|
39
|
-
cp "$f" "$f".bak
|
|
40
|
-
(cat LICENSE_HEADER.txt; echo; cat "$f" ) > "$f".new && mv "$f".new "$f"
|
|
41
|
-
fi
|
|
42
|
-
fi
|
|
43
|
-
done
|
|
44
|
-
*/
|
|
45
18
|
import { existsSync } from "node:fs";
|
|
46
19
|
import { createRequire } from "node:module";
|
|
47
20
|
import * as path from "node:path";
|
|
@@ -90,6 +63,9 @@ export async function handleKbCheck(prolog, args) {
|
|
|
90
63
|
"no-cycles",
|
|
91
64
|
"required-fields",
|
|
92
65
|
"symbol-coverage",
|
|
66
|
+
"symbol-traceability",
|
|
67
|
+
"deprecated-adr-no-successor",
|
|
68
|
+
"domain-contradictions",
|
|
93
69
|
];
|
|
94
70
|
const rulesToRun = rules && rules.length > 0 ? rules : allRules;
|
|
95
71
|
const rulesAllowlist = new Set(rulesToRun);
|
|
@@ -137,6 +113,9 @@ export async function handleKbCheck(prolog, args) {
|
|
|
137
113
|
if (rulesToRun.includes("symbol-coverage")) {
|
|
138
114
|
violations.push(...(await checkSymbolCoverage(prolog)));
|
|
139
115
|
}
|
|
116
|
+
if (rulesToRun.includes("symbol-traceability")) {
|
|
117
|
+
violations.push(...(await checkSymbolTraceability(prolog, false)));
|
|
118
|
+
}
|
|
140
119
|
const diagnostics = violations.map((v) => ({
|
|
141
120
|
category: "SYNC_ERROR",
|
|
142
121
|
severity: "error",
|
|
@@ -232,6 +211,32 @@ async function runAggregatedChecks(prolog, rulesAllowlist) {
|
|
|
232
211
|
}
|
|
233
212
|
return violations;
|
|
234
213
|
}
|
|
214
|
+
async function checkSymbolTraceability(prolog, requireAdr) {
|
|
215
|
+
const violations = [];
|
|
216
|
+
const requireAdrStr = requireAdr ? "true" : "false";
|
|
217
|
+
const result = await prolog.query(`findall(violation(Rule, EntityId, Desc, Sugg, Src), checks:symbol_traceability_violation(${requireAdrStr}, violation(Rule, EntityId, Desc, Sugg, Src)), Violations)`);
|
|
218
|
+
if (!result.success || !result.bindings.Violations) {
|
|
219
|
+
return violations;
|
|
220
|
+
}
|
|
221
|
+
const violationsStr = result.bindings.Violations;
|
|
222
|
+
if (violationsStr && violationsStr !== "[]") {
|
|
223
|
+
const violationRegex = /violation\(([^,]+),'?([^',]+)'?,([^,]+),([^,]+),'?([^']*)'?\)/g;
|
|
224
|
+
let match;
|
|
225
|
+
do {
|
|
226
|
+
match = violationRegex.exec(violationsStr);
|
|
227
|
+
if (match) {
|
|
228
|
+
violations.push({
|
|
229
|
+
rule: match[1].trim().replace(/^'|'$/g, ""),
|
|
230
|
+
entityId: match[2].trim(),
|
|
231
|
+
description: match[3].trim().replace(/^"|"$/g, ""),
|
|
232
|
+
suggestion: match[4].trim().replace(/^"|"$/g, ""),
|
|
233
|
+
source: match[5].trim() || undefined,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
} while (match);
|
|
237
|
+
}
|
|
238
|
+
return violations;
|
|
239
|
+
}
|
|
235
240
|
async function checkMustPriorityCoverage(prolog) {
|
|
236
241
|
const violations = [];
|
|
237
242
|
const gapsResult = await prolog.query("setof([Req,Reason], coverage_gap(Req, Reason), Rows)");
|
package/dist/tools/context.js
CHANGED
|
@@ -1,20 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Kibi — repo-local, per-branch, queryable long-term memory for software projects
|
|
3
|
-
Copyright (C) 2026 Piotr Franczyk
|
|
4
|
-
|
|
5
|
-
This program is free software: you can redistribute it and/or modify
|
|
6
|
-
it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
(at your option) any later version.
|
|
9
|
-
|
|
10
|
-
This program is distributed in the hope that it will be useful,
|
|
11
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
GNU Affero General Public License for more details.
|
|
14
|
-
|
|
15
|
-
You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
*/
|
|
1
|
+
import { parseEntityFromList, parseListOfLists, } from "kibi-cli/prolog/codec";
|
|
18
2
|
export async function handleKbContext(prolog, args) {
|
|
19
3
|
const { sourceFile } = args;
|
|
20
4
|
try {
|
|
@@ -78,193 +62,3 @@ export async function handleKbContext(prolog, args) {
|
|
|
78
62
|
throw new Error(`Context query failed: ${message}`);
|
|
79
63
|
}
|
|
80
64
|
}
|
|
81
|
-
function parseListOfLists(listStr) {
|
|
82
|
-
const cleaned = listStr.trim().replace(/^\[/, "").replace(/\]$/, "");
|
|
83
|
-
if (cleaned === "") {
|
|
84
|
-
return [];
|
|
85
|
-
}
|
|
86
|
-
const results = [];
|
|
87
|
-
let depth = 0;
|
|
88
|
-
let current = "";
|
|
89
|
-
let currentList = [];
|
|
90
|
-
for (let i = 0; i < cleaned.length; i++) {
|
|
91
|
-
const char = cleaned[i];
|
|
92
|
-
if (char === "[") {
|
|
93
|
-
depth++;
|
|
94
|
-
if (depth > 1)
|
|
95
|
-
current += char;
|
|
96
|
-
}
|
|
97
|
-
else if (char === "]") {
|
|
98
|
-
depth--;
|
|
99
|
-
if (depth === 0) {
|
|
100
|
-
if (current) {
|
|
101
|
-
currentList.push(current.trim());
|
|
102
|
-
current = "";
|
|
103
|
-
}
|
|
104
|
-
if (currentList.length > 0) {
|
|
105
|
-
results.push(currentList);
|
|
106
|
-
currentList = [];
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
current += char;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
else if (char === "," && depth === 1) {
|
|
114
|
-
if (current) {
|
|
115
|
-
currentList.push(current.trim());
|
|
116
|
-
current = "";
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
else if (char === "," && depth === 0) {
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
current += char;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return results;
|
|
126
|
-
}
|
|
127
|
-
function parseEntityFromList(data) {
|
|
128
|
-
if (data.length < 3) {
|
|
129
|
-
return {};
|
|
130
|
-
}
|
|
131
|
-
const id = data[0].trim();
|
|
132
|
-
const type = data[1].trim();
|
|
133
|
-
const propsStr = data[2].trim();
|
|
134
|
-
const props = parsePropertyList(propsStr);
|
|
135
|
-
return { ...props, id: normalizeEntityId(stripOuterQuotes(id)), type };
|
|
136
|
-
}
|
|
137
|
-
function parsePropertyList(propsStr) {
|
|
138
|
-
const props = {};
|
|
139
|
-
let cleaned = propsStr.trim();
|
|
140
|
-
if (cleaned.startsWith("[")) {
|
|
141
|
-
cleaned = cleaned.substring(1);
|
|
142
|
-
}
|
|
143
|
-
if (cleaned.endsWith("]")) {
|
|
144
|
-
cleaned = cleaned.substring(0, cleaned.length - 1);
|
|
145
|
-
}
|
|
146
|
-
const pairs = splitTopLevel(cleaned, ",");
|
|
147
|
-
for (const pair of pairs) {
|
|
148
|
-
const eqIndex = pair.indexOf("=");
|
|
149
|
-
if (eqIndex === -1)
|
|
150
|
-
continue;
|
|
151
|
-
const key = pair.substring(0, eqIndex).trim();
|
|
152
|
-
const value = pair.substring(eqIndex + 1).trim();
|
|
153
|
-
if (key === "..." || value === "..." || value === "...|...") {
|
|
154
|
-
continue;
|
|
155
|
-
}
|
|
156
|
-
const parsed = parsePrologValue(value);
|
|
157
|
-
props[key] = parsed;
|
|
158
|
-
}
|
|
159
|
-
return props;
|
|
160
|
-
}
|
|
161
|
-
function parsePrologValue(valueInput) {
|
|
162
|
-
const value = valueInput.trim();
|
|
163
|
-
if (value.startsWith("^^(")) {
|
|
164
|
-
const innerStart = value.indexOf("(") + 1;
|
|
165
|
-
let depth = 1;
|
|
166
|
-
let innerEnd = innerStart;
|
|
167
|
-
for (let i = innerStart; i < value.length; i++) {
|
|
168
|
-
if (value[i] === "(")
|
|
169
|
-
depth++;
|
|
170
|
-
if (value[i] === ")") {
|
|
171
|
-
depth--;
|
|
172
|
-
if (depth === 0) {
|
|
173
|
-
innerEnd = i;
|
|
174
|
-
break;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
const innerContent = value.substring(innerStart, innerEnd);
|
|
179
|
-
const parts = splitTopLevel(innerContent, ",");
|
|
180
|
-
if (parts.length >= 2) {
|
|
181
|
-
let literalValue = parts[0].trim();
|
|
182
|
-
if (literalValue.startsWith('"') && literalValue.endsWith('"')) {
|
|
183
|
-
literalValue = literalValue.substring(1, literalValue.length - 1);
|
|
184
|
-
}
|
|
185
|
-
if (literalValue.startsWith("[") && literalValue.endsWith("]")) {
|
|
186
|
-
const listContent = literalValue.substring(1, literalValue.length - 1);
|
|
187
|
-
if (listContent === "") {
|
|
188
|
-
return [];
|
|
189
|
-
}
|
|
190
|
-
return listContent.split(",").map((item) => item.trim());
|
|
191
|
-
}
|
|
192
|
-
return literalValue;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
if (value.startsWith("file:///")) {
|
|
196
|
-
const lastSlash = value.lastIndexOf("/");
|
|
197
|
-
if (lastSlash !== -1) {
|
|
198
|
-
return value.substring(lastSlash + 1);
|
|
199
|
-
}
|
|
200
|
-
return value;
|
|
201
|
-
}
|
|
202
|
-
if (value.startsWith('"') && value.endsWith('"')) {
|
|
203
|
-
return value.substring(1, value.length - 1);
|
|
204
|
-
}
|
|
205
|
-
if (value.startsWith("'") && value.endsWith("'")) {
|
|
206
|
-
return value.substring(1, value.length - 1);
|
|
207
|
-
}
|
|
208
|
-
if (value.startsWith("[") && value.endsWith("]")) {
|
|
209
|
-
const listContent = value.substring(1, value.length - 1);
|
|
210
|
-
if (listContent === "") {
|
|
211
|
-
return [];
|
|
212
|
-
}
|
|
213
|
-
const items = listContent.split(",").map((item) => {
|
|
214
|
-
return parsePrologValue(item.trim());
|
|
215
|
-
});
|
|
216
|
-
return items;
|
|
217
|
-
}
|
|
218
|
-
return value;
|
|
219
|
-
}
|
|
220
|
-
function splitTopLevel(str, delimiter) {
|
|
221
|
-
const results = [];
|
|
222
|
-
let current = "";
|
|
223
|
-
let depth = 0;
|
|
224
|
-
let inQuotes = false;
|
|
225
|
-
for (let i = 0; i < str.length; i++) {
|
|
226
|
-
const char = str[i];
|
|
227
|
-
const prevChar = i > 0 ? str[i - 1] : "";
|
|
228
|
-
if (char === '"' && prevChar !== "\\") {
|
|
229
|
-
inQuotes = !inQuotes;
|
|
230
|
-
current += char;
|
|
231
|
-
}
|
|
232
|
-
else if (!inQuotes && (char === "[" || char === "(")) {
|
|
233
|
-
depth++;
|
|
234
|
-
current += char;
|
|
235
|
-
}
|
|
236
|
-
else if (!inQuotes && (char === "]" || char === ")")) {
|
|
237
|
-
depth--;
|
|
238
|
-
current += char;
|
|
239
|
-
}
|
|
240
|
-
else if (!inQuotes && depth === 0 && char === delimiter) {
|
|
241
|
-
if (current) {
|
|
242
|
-
results.push(current);
|
|
243
|
-
current = "";
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
else {
|
|
247
|
-
current += char;
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
if (current) {
|
|
251
|
-
results.push(current);
|
|
252
|
-
}
|
|
253
|
-
return results;
|
|
254
|
-
}
|
|
255
|
-
function stripOuterQuotes(value) {
|
|
256
|
-
if (value.startsWith("'") && value.endsWith("'")) {
|
|
257
|
-
return value.slice(1, -1);
|
|
258
|
-
}
|
|
259
|
-
if (value.startsWith('"') && value.endsWith('"')) {
|
|
260
|
-
return value.slice(1, -1);
|
|
261
|
-
}
|
|
262
|
-
return value;
|
|
263
|
-
}
|
|
264
|
-
function normalizeEntityId(value) {
|
|
265
|
-
if (!value.startsWith("file:///")) {
|
|
266
|
-
return value;
|
|
267
|
-
}
|
|
268
|
-
const idx = value.lastIndexOf("/");
|
|
269
|
-
return idx === -1 ? value : value.slice(idx + 1);
|
|
270
|
-
}
|
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Kibi — repo-local, per-branch, queryable long-term memory for software projects
|
|
3
|
-
Copyright (C) 2026 Piotr Franczyk
|
|
4
|
-
|
|
5
|
-
This program is free software: you can redistribute it and/or modify
|
|
6
|
-
it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
(at your option) any later version.
|
|
9
|
-
|
|
10
|
-
This program is distributed in the hope that it will be useful,
|
|
11
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
GNU Affero General Public License for more details.
|
|
14
|
-
|
|
15
|
-
You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
*/
|
|
18
1
|
import { parseAtomList, parsePairList } from "./prolog-list.js";
|
|
19
2
|
export async function handleKbCoverageReport(prolog, args) {
|
|
20
3
|
const requested = args.type ?? "all";
|
package/dist/tools/delete.js
CHANGED
|
@@ -1,23 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Kibi — repo-local, per-branch, queryable long-term memory for software projects
|
|
3
|
-
Copyright (C) 2026 Piotr Franczyk
|
|
4
|
-
|
|
5
|
-
This program is free software: you can redistribute it and/or modify
|
|
6
|
-
it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
(at your option) any later version.
|
|
9
|
-
|
|
10
|
-
This program is distributed in the hope that it will be useful,
|
|
11
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
GNU Affero General Public License for more details.
|
|
14
|
-
|
|
15
|
-
You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
*/
|
|
18
|
-
function escapeAtom(value) {
|
|
19
|
-
return value.replace(/'/g, "''");
|
|
20
|
-
}
|
|
1
|
+
import { escapeAtom } from "kibi-cli/prolog/codec";
|
|
21
2
|
/**
|
|
22
3
|
* Handle kb.delete tool calls
|
|
23
4
|
* Prevents deletion of entities with dependents (referential integrity)
|
package/dist/tools/derive.js
CHANGED
|
@@ -1,20 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Kibi — repo-local, per-branch, queryable long-term memory for software projects
|
|
3
|
-
Copyright (C) 2026 Piotr Franczyk
|
|
4
|
-
|
|
5
|
-
This program is free software: you can redistribute it and/or modify
|
|
6
|
-
it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
(at your option) any later version.
|
|
9
|
-
|
|
10
|
-
This program is distributed in the hope that it will be useful,
|
|
11
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
GNU Affero General Public License for more details.
|
|
14
|
-
|
|
15
|
-
You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
*/
|
|
1
|
+
import { escapeAtom } from "kibi-cli/prolog/codec";
|
|
18
2
|
import { parseAtomList, parsePairList } from "./prolog-list.js";
|
|
19
3
|
const RULES = [
|
|
20
4
|
"transitively_implements",
|
|
@@ -234,9 +218,6 @@ function makeConjunction(parts) {
|
|
|
234
218
|
}
|
|
235
219
|
return `, ${filtered.join(", ")}`;
|
|
236
220
|
}
|
|
237
|
-
function escapeAtom(value) {
|
|
238
|
-
return value.replace(/'/g, "\\'");
|
|
239
|
-
}
|
|
240
221
|
async function deriveCurrentAdr(prolog) {
|
|
241
222
|
// Query for all current ADRs and their titles
|
|
242
223
|
const result = await prolog.query("setof([Id,TitleAtom], (kb_entity(Id, adr, Props), memberchk(title=Title, Props), normalize_term_atom(Title, TitleAtom), current_adr(Id)), Rows)");
|
package/dist/tools/impact.js
CHANGED
|
@@ -1,20 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Kibi — repo-local, per-branch, queryable long-term memory for software projects
|
|
3
|
-
Copyright (C) 2026 Piotr Franczyk
|
|
4
|
-
|
|
5
|
-
This program is free software: you can redistribute it and/or modify
|
|
6
|
-
it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
(at your option) any later version.
|
|
9
|
-
|
|
10
|
-
This program is distributed in the hope that it will be useful,
|
|
11
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
GNU Affero General Public License for more details.
|
|
14
|
-
|
|
15
|
-
You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
*/
|
|
1
|
+
import { escapeAtom } from "kibi-cli/prolog/codec";
|
|
18
2
|
import { parseAtomList } from "./prolog-list.js";
|
|
19
3
|
export async function handleKbImpact(prolog, args) {
|
|
20
4
|
if (!args.entity || typeof args.entity !== "string") {
|
|
@@ -65,6 +49,3 @@ async function getEntityType(prolog, id) {
|
|
|
65
49
|
}
|
|
66
50
|
return result.bindings.Type;
|
|
67
51
|
}
|
|
68
|
-
function escapeAtom(value) {
|
|
69
|
-
return value.replace(/'/g, "\\'");
|
|
70
|
-
}
|
package/dist/tools/list-types.js
CHANGED
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Kibi — repo-local, per-branch, queryable long-term memory for software projects
|
|
3
|
-
Copyright (C) 2026 Piotr Franczyk
|
|
4
|
-
|
|
5
|
-
This program is free software: you can redistribute it and/or modify
|
|
6
|
-
it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
(at your option) any later version.
|
|
9
|
-
|
|
10
|
-
This program is distributed in the hope that it will be useful,
|
|
11
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
GNU Affero General Public License for more details.
|
|
14
|
-
|
|
15
|
-
You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
*/
|
|
18
1
|
/**
|
|
19
2
|
* Handle kb_list_entity_types tool calls
|
|
20
3
|
* Returns the static list of supported KB entity type names (req, scenario, test, adr, flag, event, symbol, fact).
|
|
@@ -15,33 +15,6 @@
|
|
|
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
|
-
/*
|
|
19
|
-
How to apply this header to source files (examples)
|
|
20
|
-
|
|
21
|
-
1) Prepend header to a single file (POSIX shells):
|
|
22
|
-
|
|
23
|
-
cat LICENSE_HEADER.txt "$FILE" > "$FILE".with-header && mv "$FILE".with-header "$FILE"
|
|
24
|
-
|
|
25
|
-
2) Apply to multiple files (example: the project's main entry files):
|
|
26
|
-
|
|
27
|
-
for f in packages/cli/bin/kibi packages/mcp/bin/kibi-mcp packages/cli/src/*.ts packages/mcp/src/*.ts; do
|
|
28
|
-
if [ -f "$f" ]; then
|
|
29
|
-
cp "$f" "$f".bak
|
|
30
|
-
(cat LICENSE_HEADER.txt; echo; cat "$f" ) > "$f".new && mv "$f".new "$f"
|
|
31
|
-
fi
|
|
32
|
-
done
|
|
33
|
-
|
|
34
|
-
3) Avoid duplicating the header: run a quick guard to only add if missing
|
|
35
|
-
|
|
36
|
-
for f in packages/cli/bin/kibi packages/mcp/bin/kibi-mcp; do
|
|
37
|
-
if [ -f "$f" ]; then
|
|
38
|
-
if ! head -n 5 "$f" | grep -q "Copyright (C) 2026 Piotr Franczyk"; then
|
|
39
|
-
cp "$f" "$f".bak
|
|
40
|
-
(cat LICENSE_HEADER.txt; echo; cat "$f" ) > "$f".new && mv "$f".new "$f"
|
|
41
|
-
fi
|
|
42
|
-
fi
|
|
43
|
-
done
|
|
44
|
-
*/
|
|
45
18
|
export function parseAtomList(raw) {
|
|
46
19
|
const trimmed = raw.trim();
|
|
47
20
|
if (trimmed === "[]" || trimmed.length === 0) {
|
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Kibi — repo-local, per-branch, queryable long-term memory for software projects
|
|
3
|
-
Copyright (C) 2026 Piotr Franczyk
|
|
4
|
-
|
|
5
|
-
This program is free software: you can redistribute it and/or modify
|
|
6
|
-
it under the terms of the GNU Affero General Public License as published by
|
|
7
|
-
the Free Software Foundation, either version 3 of the License, or
|
|
8
|
-
(at your option) any later version.
|
|
9
|
-
|
|
10
|
-
This program is distributed in the hope that it will be useful,
|
|
11
|
-
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
-
GNU Affero General Public License for more details.
|
|
14
|
-
|
|
15
|
-
You should have received a copy of the GNU Affero General Public License
|
|
16
|
-
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
-
*/
|
|
18
1
|
const VALID_REL_TYPES = [
|
|
19
2
|
"depends_on",
|
|
20
3
|
"specified_by",
|