@vpxa/kb 0.1.1 → 0.1.2
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/package.json +1 -1
- package/packages/analyzers/dist/blast-radius-analyzer.js +13 -114
- package/packages/analyzers/dist/dependency-analyzer.js +11 -425
- package/packages/analyzers/dist/diagram-generator.js +4 -86
- package/packages/analyzers/dist/entry-point-analyzer.js +5 -239
- package/packages/analyzers/dist/index.js +1 -23
- package/packages/analyzers/dist/knowledge-producer.js +24 -113
- package/packages/analyzers/dist/pattern-analyzer.js +5 -359
- package/packages/analyzers/dist/regex-call-graph.js +1 -428
- package/packages/analyzers/dist/structure-analyzer.js +4 -258
- package/packages/analyzers/dist/symbol-analyzer.js +13 -442
- package/packages/analyzers/dist/ts-call-graph.js +1 -160
- package/packages/analyzers/dist/types.js +0 -1
- package/packages/chunker/dist/call-graph-extractor.js +1 -90
- package/packages/chunker/dist/chunker-factory.js +1 -36
- package/packages/chunker/dist/chunker.interface.js +0 -1
- package/packages/chunker/dist/code-chunker.js +14 -134
- package/packages/chunker/dist/generic-chunker.js +5 -72
- package/packages/chunker/dist/index.js +1 -21
- package/packages/chunker/dist/markdown-chunker.js +7 -119
- package/packages/chunker/dist/treesitter-chunker.js +8 -234
- package/packages/cli/dist/commands/analyze.js +3 -112
- package/packages/cli/dist/commands/context-cmds.js +1 -155
- package/packages/cli/dist/commands/environment.js +2 -204
- package/packages/cli/dist/commands/execution.js +1 -137
- package/packages/cli/dist/commands/graph.js +7 -81
- package/packages/cli/dist/commands/init.js +9 -87
- package/packages/cli/dist/commands/knowledge.js +1 -139
- package/packages/cli/dist/commands/search.js +8 -267
- package/packages/cli/dist/commands/system.js +4 -241
- package/packages/cli/dist/commands/workspace.js +2 -388
- package/packages/cli/dist/context.js +1 -14
- package/packages/cli/dist/helpers.js +3 -458
- package/packages/cli/dist/index.js +3 -69
- package/packages/cli/dist/kb-init.js +1 -82
- package/packages/cli/dist/types.js +0 -1
- package/packages/core/dist/constants.js +1 -43
- package/packages/core/dist/content-detector.js +1 -79
- package/packages/core/dist/errors.js +1 -40
- package/packages/core/dist/index.js +1 -9
- package/packages/core/dist/logger.js +1 -34
- package/packages/core/dist/types.js +0 -1
- package/packages/embeddings/dist/embedder.interface.js +0 -1
- package/packages/embeddings/dist/index.js +1 -5
- package/packages/embeddings/dist/onnx-embedder.js +1 -82
- package/packages/indexer/dist/file-hasher.js +1 -13
- package/packages/indexer/dist/filesystem-crawler.js +1 -125
- package/packages/indexer/dist/graph-extractor.js +1 -111
- package/packages/indexer/dist/incremental-indexer.js +1 -278
- package/packages/indexer/dist/index.js +1 -14
- package/packages/server/dist/api.js +1 -9
- package/packages/server/dist/config.js +1 -75
- package/packages/server/dist/curated-manager.js +9 -356
- package/packages/server/dist/index.js +1 -134
- package/packages/server/dist/replay-interceptor.js +1 -38
- package/packages/server/dist/resources/resources.js +2 -40
- package/packages/server/dist/server.js +1 -247
- package/packages/server/dist/tools/analyze.tools.js +1 -288
- package/packages/server/dist/tools/forge.tools.js +11 -499
- package/packages/server/dist/tools/forget.tool.js +3 -39
- package/packages/server/dist/tools/graph.tool.js +5 -110
- package/packages/server/dist/tools/list.tool.js +5 -53
- package/packages/server/dist/tools/lookup.tool.js +8 -51
- package/packages/server/dist/tools/onboard.tool.js +2 -112
- package/packages/server/dist/tools/produce.tool.js +4 -74
- package/packages/server/dist/tools/read.tool.js +4 -47
- package/packages/server/dist/tools/reindex.tool.js +2 -70
- package/packages/server/dist/tools/remember.tool.js +3 -42
- package/packages/server/dist/tools/replay.tool.js +6 -88
- package/packages/server/dist/tools/search.tool.js +17 -327
- package/packages/server/dist/tools/status.tool.js +3 -68
- package/packages/server/dist/tools/toolkit.tools.js +20 -1673
- package/packages/server/dist/tools/update.tool.js +3 -39
- package/packages/server/dist/tools/utility.tools.js +19 -456
- package/packages/store/dist/graph-store.interface.js +0 -1
- package/packages/store/dist/index.js +1 -9
- package/packages/store/dist/lance-store.js +1 -258
- package/packages/store/dist/sqlite-graph-store.js +8 -309
- package/packages/store/dist/store-factory.js +1 -14
- package/packages/store/dist/store.interface.js +0 -1
- package/packages/tools/dist/batch.js +1 -45
- package/packages/tools/dist/changelog.js +2 -112
- package/packages/tools/dist/check.js +2 -59
- package/packages/tools/dist/checkpoint.js +2 -43
- package/packages/tools/dist/codemod.js +2 -69
- package/packages/tools/dist/compact.js +3 -60
- package/packages/tools/dist/data-transform.js +1 -124
- package/packages/tools/dist/dead-symbols.js +2 -71
- package/packages/tools/dist/delegate.js +3 -128
- package/packages/tools/dist/diff-parse.js +3 -153
- package/packages/tools/dist/digest.js +7 -242
- package/packages/tools/dist/encode.js +1 -46
- package/packages/tools/dist/env-info.js +1 -58
- package/packages/tools/dist/eval.js +3 -79
- package/packages/tools/dist/evidence-map.js +3 -203
- package/packages/tools/dist/file-summary.js +2 -106
- package/packages/tools/dist/file-walk.js +1 -75
- package/packages/tools/dist/find-examples.js +3 -48
- package/packages/tools/dist/find.js +1 -120
- package/packages/tools/dist/forge-classify.js +2 -319
- package/packages/tools/dist/forge-ground.js +1 -184
- package/packages/tools/dist/git-context.js +3 -46
- package/packages/tools/dist/graph-query.js +1 -194
- package/packages/tools/dist/health.js +1 -118
- package/packages/tools/dist/http-request.js +1 -58
- package/packages/tools/dist/index.js +1 -273
- package/packages/tools/dist/lane.js +7 -227
- package/packages/tools/dist/measure.js +2 -119
- package/packages/tools/dist/onboard.js +42 -1136
- package/packages/tools/dist/parse-output.js +2 -158
- package/packages/tools/dist/process-manager.js +1 -69
- package/packages/tools/dist/queue.js +2 -126
- package/packages/tools/dist/regex-test.js +1 -39
- package/packages/tools/dist/rename.js +2 -70
- package/packages/tools/dist/replay.js +6 -108
- package/packages/tools/dist/schema-validate.js +1 -141
- package/packages/tools/dist/scope-map.js +1 -72
- package/packages/tools/dist/snippet.js +1 -80
- package/packages/tools/dist/stash.js +2 -60
- package/packages/tools/dist/stratum-card.js +5 -238
- package/packages/tools/dist/symbol.js +3 -87
- package/packages/tools/dist/test-run.js +2 -55
- package/packages/tools/dist/text-utils.js +2 -31
- package/packages/tools/dist/time-utils.js +1 -135
- package/packages/tools/dist/trace.js +2 -114
- package/packages/tools/dist/truncation.js +10 -41
- package/packages/tools/dist/watch.js +1 -61
- package/packages/tools/dist/web-fetch.js +9 -244
- package/packages/tools/dist/web-search.js +1 -46
- package/packages/tools/dist/workset.js +2 -77
- package/packages/tui/dist/App.js +260 -52468
- package/packages/tui/dist/index.js +286 -54551
- package/packages/tui/dist/panels/CuratedPanel.js +211 -34291
- package/packages/tui/dist/panels/LogPanel.js +259 -51703
- package/packages/tui/dist/panels/SearchPanel.js +212 -34824
- package/packages/tui/dist/panels/StatusPanel.js +211 -34304
|
@@ -1,158 +1,2 @@
|
|
|
1
|
-
function
|
|
2
|
-
|
|
3
|
-
const parenRegex = /^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+(TS\d+):\s+(.+)$/gm;
|
|
4
|
-
for (const match of output.matchAll(parenRegex)) {
|
|
5
|
-
errors.push({
|
|
6
|
-
file: match[1],
|
|
7
|
-
line: Number.parseInt(match[2], 10),
|
|
8
|
-
column: Number.parseInt(match[3], 10),
|
|
9
|
-
severity: match[4],
|
|
10
|
-
code: match[5],
|
|
11
|
-
message: match[6]
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
if (errors.length === 0) {
|
|
15
|
-
const colonRegex = /^(.+?):(\d+):(\d+)\s+-\s+(error|warning)\s+(TS\d+):\s+(.+)$/gm;
|
|
16
|
-
for (const match of output.matchAll(colonRegex)) {
|
|
17
|
-
errors.push({
|
|
18
|
-
file: match[1],
|
|
19
|
-
line: Number.parseInt(match[2], 10),
|
|
20
|
-
column: Number.parseInt(match[3], 10),
|
|
21
|
-
severity: match[4],
|
|
22
|
-
code: match[5],
|
|
23
|
-
message: match[6]
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
return errors;
|
|
28
|
-
}
|
|
29
|
-
function parseVitest(output) {
|
|
30
|
-
const tests = [];
|
|
31
|
-
const testRegex = /^\s*([✓✕×-])\s+(.+?)(?:\s+(\d+)ms)?$/gm;
|
|
32
|
-
for (const match of output.matchAll(testRegex)) {
|
|
33
|
-
const symbol = match[1];
|
|
34
|
-
const status = symbol === "\u2713" ? "pass" : symbol === "-" ? "skip" : "fail";
|
|
35
|
-
tests.push({
|
|
36
|
-
name: match[2].trim(),
|
|
37
|
-
status,
|
|
38
|
-
duration: match[3] ? Number.parseInt(match[3], 10) : void 0
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
const fileRegex = /^\s*([✓✕×])\s+(\S+\.test\.\w+)\s+\((\d+)\s+tests?\)\s*(\d+ms)?$/gm;
|
|
42
|
-
for (const match of output.matchAll(fileRegex)) {
|
|
43
|
-
const symbol = match[1];
|
|
44
|
-
const status = symbol === "\u2713" ? "pass" : "fail";
|
|
45
|
-
tests.push({
|
|
46
|
-
name: match[2],
|
|
47
|
-
file: match[2],
|
|
48
|
-
status,
|
|
49
|
-
duration: match[4] ? Number.parseInt(match[4], 10) : void 0
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
const summaryRegex = /Tests\s+(?:(\d+)\s+passed)?(?:\s*\|\s*)?(?:(\d+)\s+failed)?(?:\s*\|\s*)?(?:(\d+)\s+skipped)?\s*\((\d+)\)/;
|
|
53
|
-
const summaryMatch = summaryRegex.exec(output);
|
|
54
|
-
const passed = summaryMatch ? Number.parseInt(summaryMatch[1] ?? "0", 10) : tests.filter((t) => t.status === "pass").length;
|
|
55
|
-
const failed = summaryMatch ? Number.parseInt(summaryMatch[2] ?? "0", 10) : tests.filter((t) => t.status === "fail").length;
|
|
56
|
-
const skipped = summaryMatch ? Number.parseInt(summaryMatch[3] ?? "0", 10) : tests.filter((t) => t.status === "skip").length;
|
|
57
|
-
const durationRegex = /Duration\s+(\d+(?:\.\d+)?)(?:ms|s)/;
|
|
58
|
-
const durationMatch = durationRegex.exec(output);
|
|
59
|
-
const duration = durationMatch ? durationMatch[0].includes("s") && !durationMatch[0].includes("ms") ? Number.parseFloat(durationMatch[1]) * 1e3 : Number.parseFloat(durationMatch[1]) : void 0;
|
|
60
|
-
const suitesRegex = /Test Files\s+(\d+)\s+passed/;
|
|
61
|
-
const suitesMatch = suitesRegex.exec(output);
|
|
62
|
-
return {
|
|
63
|
-
tests,
|
|
64
|
-
passed,
|
|
65
|
-
failed,
|
|
66
|
-
skipped,
|
|
67
|
-
duration,
|
|
68
|
-
suites: suitesMatch ? Number.parseInt(suitesMatch[1], 10) : void 0
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
function parseBiome(output) {
|
|
72
|
-
const errors = [];
|
|
73
|
-
const blockRegex = /^(.+?):(\d+):(\d+)\s+([\w/]+)\s+━+$/gm;
|
|
74
|
-
for (const match of output.matchAll(blockRegex)) {
|
|
75
|
-
const file = match[1];
|
|
76
|
-
const line = Number.parseInt(match[2], 10);
|
|
77
|
-
const column = Number.parseInt(match[3], 10);
|
|
78
|
-
const code = match[4];
|
|
79
|
-
const afterBlock = output.slice(
|
|
80
|
-
(match.index ?? 0) + match[0].length,
|
|
81
|
-
(match.index ?? 0) + match[0].length + 500
|
|
82
|
-
);
|
|
83
|
-
const msgMatch = /^\s*[×!i]\s+(.+)$/m.exec(afterBlock);
|
|
84
|
-
const message = msgMatch ? msgMatch[1].trim() : code;
|
|
85
|
-
const severity = code.includes("lint") ? "warning" : "error";
|
|
86
|
-
errors.push({ file, line, column, severity, code, message });
|
|
87
|
-
}
|
|
88
|
-
return errors;
|
|
89
|
-
}
|
|
90
|
-
function parseGitStatus(output) {
|
|
91
|
-
const staged = [];
|
|
92
|
-
const unstaged = [];
|
|
93
|
-
const untracked = [];
|
|
94
|
-
let branch;
|
|
95
|
-
for (const line of output.split("\n")) {
|
|
96
|
-
if (!line) continue;
|
|
97
|
-
if (line.startsWith("## ")) {
|
|
98
|
-
branch = line.slice(3).split("...")[0];
|
|
99
|
-
continue;
|
|
100
|
-
}
|
|
101
|
-
const x = line[0];
|
|
102
|
-
const y = line[1];
|
|
103
|
-
const file = line.slice(3).trim();
|
|
104
|
-
if (x === "?" && y === "?") {
|
|
105
|
-
untracked.push(file);
|
|
106
|
-
} else {
|
|
107
|
-
if (x !== " " && x !== "?") {
|
|
108
|
-
staged.push({ status: statusLabel(x), file });
|
|
109
|
-
}
|
|
110
|
-
if (y !== " " && y !== "?") {
|
|
111
|
-
unstaged.push({ status: statusLabel(y), file });
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return { staged, unstaged, untracked, branch };
|
|
116
|
-
}
|
|
117
|
-
function statusLabel(code) {
|
|
118
|
-
const labels = {
|
|
119
|
-
M: "modified",
|
|
120
|
-
A: "added",
|
|
121
|
-
D: "deleted",
|
|
122
|
-
R: "renamed",
|
|
123
|
-
C: "copied",
|
|
124
|
-
U: "unmerged"
|
|
125
|
-
};
|
|
126
|
-
return labels[code] ?? code;
|
|
127
|
-
}
|
|
128
|
-
function parseOutput(output, tool) {
|
|
129
|
-
const detected = tool ?? detectTool(output);
|
|
130
|
-
switch (detected) {
|
|
131
|
-
case "tsc":
|
|
132
|
-
return { tool: "tsc", errors: parseTsc(output) };
|
|
133
|
-
case "vitest":
|
|
134
|
-
return { tool: "vitest", summary: parseVitest(output) };
|
|
135
|
-
case "biome":
|
|
136
|
-
return { tool: "biome", errors: parseBiome(output) };
|
|
137
|
-
case "git-status":
|
|
138
|
-
return { tool: "git-status", status: parseGitStatus(output) };
|
|
139
|
-
default:
|
|
140
|
-
throw new Error(`Unknown tool: ${detected}. Supported: tsc, vitest, biome, git-status`);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
function detectTool(output) {
|
|
144
|
-
if (output.includes("error TS") || /\(\d+,\d+\):\s+error/.test(output)) return "tsc";
|
|
145
|
-
if (output.includes("vitest") || output.includes("Test Files") || output.includes("\u2713"))
|
|
146
|
-
return "vitest";
|
|
147
|
-
if (output.includes("biome") || /\w+\/\w+\s+━+/.test(output)) return "biome";
|
|
148
|
-
if (/^##\s/.test(output) || /^[MADRCU?! ]{2}\s/.test(output)) return "git-status";
|
|
149
|
-
return "unknown";
|
|
150
|
-
}
|
|
151
|
-
export {
|
|
152
|
-
parseBiome,
|
|
153
|
-
parseGitStatus,
|
|
154
|
-
parseOutput,
|
|
155
|
-
parseTsc,
|
|
156
|
-
parseVitest
|
|
157
|
-
};
|
|
158
|
-
//# sourceMappingURL=parse-output.js.map
|
|
1
|
+
function h(s){const t=[],a=/^(.+?)\((\d+),(\d+)\):\s+(error|warning)\s+(TS\d+):\s+(.+)$/gm;for(const e of s.matchAll(a))t.push({file:e[1],line:Number.parseInt(e[2],10),column:Number.parseInt(e[3],10),severity:e[4],code:e[5],message:e[6]});if(t.length===0){const e=/^(.+?):(\d+):(\d+)\s+-\s+(error|warning)\s+(TS\d+):\s+(.+)$/gm;for(const i of s.matchAll(e))t.push({file:i[1],line:Number.parseInt(i[2],10),column:Number.parseInt(i[3],10),severity:i[4],code:i[5],message:i[6]})}return t}function x(s){const t=[],a=/^\s*([✓✕×-])\s+(.+?)(?:\s+(\d+)ms)?$/gm;for(const r of s.matchAll(a)){const g=r[1],f=g==="\u2713"?"pass":g==="-"?"skip":"fail";t.push({name:r[2].trim(),status:f,duration:r[3]?Number.parseInt(r[3],10):void 0})}const e=/^\s*([✓✕×])\s+(\S+\.test\.\w+)\s+\((\d+)\s+tests?\)\s*(\d+ms)?$/gm;for(const r of s.matchAll(e)){const f=r[1]==="\u2713"?"pass":"fail";t.push({name:r[2],file:r[2],status:f,duration:r[4]?Number.parseInt(r[4],10):void 0})}const n=/Tests\s+(?:(\d+)\s+passed)?(?:\s*\|\s*)?(?:(\d+)\s+failed)?(?:\s*\|\s*)?(?:(\d+)\s+skipped)?\s*\((\d+)\)/.exec(s),c=n?Number.parseInt(n[1]??"0",10):t.filter(r=>r.status==="pass").length,o=n?Number.parseInt(n[2]??"0",10):t.filter(r=>r.status==="fail").length,d=n?Number.parseInt(n[3]??"0",10):t.filter(r=>r.status==="skip").length,u=/Duration\s+(\d+(?:\.\d+)?)(?:ms|s)/.exec(s),m=u?u[0].includes("s")&&!u[0].includes("ms")?Number.parseFloat(u[1])*1e3:Number.parseFloat(u[1]):void 0,p=/Test Files\s+(\d+)\s+passed/.exec(s);return{tests:t,passed:c,failed:o,skipped:d,duration:m,suites:p?Number.parseInt(p[1],10):void 0}}function P(s){const t=[],a=/^(.+?):(\d+):(\d+)\s+([\w/]+)\s+━+$/gm;for(const e of s.matchAll(a)){const i=e[1],n=Number.parseInt(e[2],10),c=Number.parseInt(e[3],10),o=e[4],d=s.slice((e.index??0)+e[0].length,(e.index??0)+e[0].length+500),l=/^\s*[×!i]\s+(.+)$/m.exec(d),u=l?l[1].trim():o,m=o.includes("lint")?"warning":"error";t.push({file:i,line:n,column:c,severity:m,code:o,message:u})}return t}function y(s){const t=[],a=[],e=[];let i;for(const n of s.split(`
|
|
2
|
+
`)){if(!n)continue;if(n.startsWith("## ")){i=n.slice(3).split("...")[0];continue}const c=n[0],o=n[1],d=n.slice(3).trim();c==="?"&&o==="?"?e.push(d):(c!==" "&&c!=="?"&&t.push({status:b(c),file:d}),o!==" "&&o!=="?"&&a.push({status:b(o),file:d}))}return{staged:t,unstaged:a,untracked:e,branch:i}}function b(s){return{M:"modified",A:"added",D:"deleted",R:"renamed",C:"copied",U:"unmerged"}[s]??s}function w(s,t){const a=t??R(s);switch(a){case"tsc":return{tool:"tsc",errors:h(s)};case"vitest":return{tool:"vitest",summary:x(s)};case"biome":return{tool:"biome",errors:P(s)};case"git-status":return{tool:"git-status",status:y(s)};default:throw new Error(`Unknown tool: ${a}. Supported: tsc, vitest, biome, git-status`)}}function R(s){return s.includes("error TS")||/\(\d+,\d+\):\s+error/.test(s)?"tsc":s.includes("vitest")||s.includes("Test Files")||s.includes("\u2713")?"vitest":s.includes("biome")||/\w+\/\w+\s+━+/.test(s)?"biome":/^##\s/.test(s)||/^[MADRCU?! ]{2}\s/.test(s)?"git-status":"unknown"}export{P as parseBiome,y as parseGitStatus,w as parseOutput,h as parseTsc,x as parseVitest};
|
|
@@ -1,69 +1 @@
|
|
|
1
|
-
import
|
|
2
|
-
const processes = /* @__PURE__ */ new Map();
|
|
3
|
-
const MAX_LOG_LINES = 200;
|
|
4
|
-
function processStart(id, command, args = [], options) {
|
|
5
|
-
if (processes.has(id)) {
|
|
6
|
-
throw new Error(`Process "${id}" is already running. Stop it first.`);
|
|
7
|
-
}
|
|
8
|
-
const proc = spawn(command, args, {
|
|
9
|
-
cwd: options?.cwd ?? process.cwd(),
|
|
10
|
-
shell: true,
|
|
11
|
-
stdio: ["ignore", "pipe", "pipe"]
|
|
12
|
-
});
|
|
13
|
-
const info = {
|
|
14
|
-
id,
|
|
15
|
-
command,
|
|
16
|
-
args,
|
|
17
|
-
pid: proc.pid ?? void 0,
|
|
18
|
-
status: "running",
|
|
19
|
-
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
20
|
-
logs: []
|
|
21
|
-
};
|
|
22
|
-
const appendLog = (data) => {
|
|
23
|
-
const lines = data.toString().split(/\r?\n/).filter(Boolean);
|
|
24
|
-
info.logs.push(...lines);
|
|
25
|
-
if (info.logs.length > MAX_LOG_LINES) {
|
|
26
|
-
info.logs = info.logs.slice(-MAX_LOG_LINES);
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
proc.stdout?.on("data", appendLog);
|
|
30
|
-
proc.stderr?.on("data", appendLog);
|
|
31
|
-
proc.on("exit", (code) => {
|
|
32
|
-
info.status = code === 0 ? "stopped" : "error";
|
|
33
|
-
info.exitCode = code ?? void 0;
|
|
34
|
-
});
|
|
35
|
-
proc.on("error", (err) => {
|
|
36
|
-
info.status = "error";
|
|
37
|
-
info.logs.push(`[error] ${err.message}`);
|
|
38
|
-
});
|
|
39
|
-
processes.set(id, { proc, info });
|
|
40
|
-
return info;
|
|
41
|
-
}
|
|
42
|
-
function processStop(id) {
|
|
43
|
-
const entry = processes.get(id);
|
|
44
|
-
if (!entry) return void 0;
|
|
45
|
-
entry.proc.kill("SIGTERM");
|
|
46
|
-
entry.info.status = "stopped";
|
|
47
|
-
processes.delete(id);
|
|
48
|
-
return entry.info;
|
|
49
|
-
}
|
|
50
|
-
function processStatus(id) {
|
|
51
|
-
return processes.get(id)?.info;
|
|
52
|
-
}
|
|
53
|
-
function processList() {
|
|
54
|
-
return [...processes.values()].map((entry) => entry.info);
|
|
55
|
-
}
|
|
56
|
-
function processLogs(id, tail) {
|
|
57
|
-
const entry = processes.get(id);
|
|
58
|
-
if (!entry) return [];
|
|
59
|
-
if (tail) return entry.info.logs.slice(-tail);
|
|
60
|
-
return entry.info.logs;
|
|
61
|
-
}
|
|
62
|
-
export {
|
|
63
|
-
processList,
|
|
64
|
-
processLogs,
|
|
65
|
-
processStart,
|
|
66
|
-
processStatus,
|
|
67
|
-
processStop
|
|
68
|
-
};
|
|
69
|
-
//# sourceMappingURL=process-manager.js.map
|
|
1
|
+
import{spawn as d}from"node:child_process";const t=new Map,p=200;function f(s,r,n=[],c){if(t.has(s))throw new Error(`Process "${s}" is already running. Stop it first.`);const o=d(r,n,{cwd:c?.cwd??process.cwd(),shell:!0,stdio:["ignore","pipe","pipe"]}),e={id:s,command:r,args:n,pid:o.pid??void 0,status:"running",startedAt:new Date().toISOString(),logs:[]},g=i=>{const a=i.toString().split(/\r?\n/).filter(Boolean);e.logs.push(...a),e.logs.length>p&&(e.logs=e.logs.slice(-p))};return o.stdout?.on("data",g),o.stderr?.on("data",g),o.on("exit",i=>{e.status=i===0?"stopped":"error",e.exitCode=i??void 0}),o.on("error",i=>{e.status="error",e.logs.push(`[error] ${i.message}`)}),t.set(s,{proc:o,info:e}),e}function l(s){const r=t.get(s);if(r)return r.proc.kill("SIGTERM"),r.info.status="stopped",t.delete(s),r.info}function M(s){return t.get(s)?.info}function P(){return[...t.values()].map(s=>s.info)}function w(s,r){const n=t.get(s);return n?r?n.info.logs.slice(-r):n.info.logs:[]}export{P as processList,w as processLogs,f as processStart,M as processStatus,l as processStop};
|
|
@@ -1,126 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
const QUEUE_DIR = ".kb-state";
|
|
4
|
-
const QUEUE_FILE = "queue.json";
|
|
5
|
-
function queuePath(cwd) {
|
|
6
|
-
return resolve(cwd ?? process.cwd(), QUEUE_DIR, QUEUE_FILE);
|
|
7
|
-
}
|
|
8
|
-
function loadQueues(cwd) {
|
|
9
|
-
const path = queuePath(cwd);
|
|
10
|
-
if (!existsSync(path)) return {};
|
|
11
|
-
return JSON.parse(readFileSync(path, "utf-8"));
|
|
12
|
-
}
|
|
13
|
-
function saveQueues(data, cwd) {
|
|
14
|
-
const path = queuePath(cwd);
|
|
15
|
-
const dir = dirname(path);
|
|
16
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
17
|
-
writeFileSync(path, `${JSON.stringify(data, null, 2)}
|
|
18
|
-
`, "utf-8");
|
|
19
|
-
}
|
|
20
|
-
function generateId() {
|
|
21
|
-
return `q_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 6)}`;
|
|
22
|
-
}
|
|
23
|
-
function queueCreate(name, cwd) {
|
|
24
|
-
const queues = loadQueues(cwd);
|
|
25
|
-
if (queues[name]) {
|
|
26
|
-
throw new Error(`Queue "${name}" already exists`);
|
|
27
|
-
}
|
|
28
|
-
const queue = { name, items: [] };
|
|
29
|
-
queues[name] = queue;
|
|
30
|
-
saveQueues(queues, cwd);
|
|
31
|
-
return queue;
|
|
32
|
-
}
|
|
33
|
-
function queuePush(name, title, data, cwd) {
|
|
34
|
-
const queues = loadQueues(cwd);
|
|
35
|
-
if (!queues[name]) {
|
|
36
|
-
queues[name] = { name, items: [] };
|
|
37
|
-
}
|
|
38
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
39
|
-
const item = {
|
|
40
|
-
id: generateId(),
|
|
41
|
-
title,
|
|
42
|
-
status: "pending",
|
|
43
|
-
data,
|
|
44
|
-
createdAt: now,
|
|
45
|
-
updatedAt: now
|
|
46
|
-
};
|
|
47
|
-
queues[name].items.push(item);
|
|
48
|
-
saveQueues(queues, cwd);
|
|
49
|
-
return item;
|
|
50
|
-
}
|
|
51
|
-
function queueNext(name, cwd) {
|
|
52
|
-
const queues = loadQueues(cwd);
|
|
53
|
-
const queue = queues[name];
|
|
54
|
-
if (!queue) throw new Error(`Queue "${name}" does not exist`);
|
|
55
|
-
const item = queue.items.find((i) => i.status === "pending");
|
|
56
|
-
if (!item) return null;
|
|
57
|
-
item.status = "in-progress";
|
|
58
|
-
item.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
59
|
-
saveQueues(queues, cwd);
|
|
60
|
-
return item;
|
|
61
|
-
}
|
|
62
|
-
function queueDone(name, id, cwd) {
|
|
63
|
-
const queues = loadQueues(cwd);
|
|
64
|
-
const queue = queues[name];
|
|
65
|
-
if (!queue) throw new Error(`Queue "${name}" does not exist`);
|
|
66
|
-
const item = queue.items.find((i) => i.id === id);
|
|
67
|
-
if (!item) throw new Error(`Item "${id}" not found in queue "${name}"`);
|
|
68
|
-
item.status = "done";
|
|
69
|
-
item.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
70
|
-
saveQueues(queues, cwd);
|
|
71
|
-
return item;
|
|
72
|
-
}
|
|
73
|
-
function queueFail(name, id, error, cwd) {
|
|
74
|
-
const queues = loadQueues(cwd);
|
|
75
|
-
const queue = queues[name];
|
|
76
|
-
if (!queue) throw new Error(`Queue "${name}" does not exist`);
|
|
77
|
-
const item = queue.items.find((i) => i.id === id);
|
|
78
|
-
if (!item) throw new Error(`Item "${id}" not found in queue "${name}"`);
|
|
79
|
-
item.status = "failed";
|
|
80
|
-
item.error = error;
|
|
81
|
-
item.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
82
|
-
saveQueues(queues, cwd);
|
|
83
|
-
return item;
|
|
84
|
-
}
|
|
85
|
-
function queueGet(name, cwd) {
|
|
86
|
-
return loadQueues(cwd)[name] ?? null;
|
|
87
|
-
}
|
|
88
|
-
function queueList(cwd) {
|
|
89
|
-
const queues = loadQueues(cwd);
|
|
90
|
-
return Object.values(queues).map((q) => ({
|
|
91
|
-
name: q.name,
|
|
92
|
-
pending: q.items.filter((i) => i.status === "pending").length,
|
|
93
|
-
done: q.items.filter((i) => i.status === "done").length,
|
|
94
|
-
failed: q.items.filter((i) => i.status === "failed").length,
|
|
95
|
-
total: q.items.length
|
|
96
|
-
}));
|
|
97
|
-
}
|
|
98
|
-
function queueClear(name, cwd) {
|
|
99
|
-
const queues = loadQueues(cwd);
|
|
100
|
-
const queue = queues[name];
|
|
101
|
-
if (!queue) throw new Error(`Queue "${name}" does not exist`);
|
|
102
|
-
const before = queue.items.length;
|
|
103
|
-
queue.items = queue.items.filter((i) => i.status === "pending" || i.status === "in-progress");
|
|
104
|
-
const removed = before - queue.items.length;
|
|
105
|
-
saveQueues(queues, cwd);
|
|
106
|
-
return removed;
|
|
107
|
-
}
|
|
108
|
-
function queueDelete(name, cwd) {
|
|
109
|
-
const queues = loadQueues(cwd);
|
|
110
|
-
if (!queues[name]) return false;
|
|
111
|
-
delete queues[name];
|
|
112
|
-
saveQueues(queues, cwd);
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
export {
|
|
116
|
-
queueClear,
|
|
117
|
-
queueCreate,
|
|
118
|
-
queueDelete,
|
|
119
|
-
queueDone,
|
|
120
|
-
queueFail,
|
|
121
|
-
queueGet,
|
|
122
|
-
queueList,
|
|
123
|
-
queueNext,
|
|
124
|
-
queuePush
|
|
125
|
-
};
|
|
126
|
-
//# sourceMappingURL=queue.js.map
|
|
1
|
+
import{existsSync as a,mkdirSync as c,readFileSync as l,writeFileSync as p}from"node:fs";import{dirname as m,resolve as q}from"node:path";const Q=".kb-state",S="queue.json";function d(e){return q(e??process.cwd(),Q,S)}function o(e){const r=d(e);return a(r)?JSON.parse(l(r,"utf-8")):{}}function g(e,r){const t=d(r),n=m(t);a(n)||c(n,{recursive:!0}),p(t,`${JSON.stringify(e,null,2)}
|
|
2
|
+
`,"utf-8")}function h(){return`q_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,6)}`}function I(e,r){const t=o(r);if(t[e])throw new Error(`Queue "${e}" already exists`);const n={name:e,items:[]};return t[e]=n,g(t,r),n}function E(e,r,t,n){const u=o(n);u[e]||(u[e]={name:e,items:[]});const s=new Date().toISOString(),i={id:h(),title:r,status:"pending",data:t,createdAt:s,updatedAt:s};return u[e].items.push(i),g(u,n),i}function $(e,r){const t=o(r),n=t[e];if(!n)throw new Error(`Queue "${e}" does not exist`);const u=n.items.find(s=>s.status==="pending");return u?(u.status="in-progress",u.updatedAt=new Date().toISOString(),g(t,r),u):null}function b(e,r,t){const n=o(t),u=n[e];if(!u)throw new Error(`Queue "${e}" does not exist`);const s=u.items.find(i=>i.id===r);if(!s)throw new Error(`Item "${r}" not found in queue "${e}"`);return s.status="done",s.updatedAt=new Date().toISOString(),g(n,t),s}function A(e,r,t,n){const u=o(n),s=u[e];if(!s)throw new Error(`Queue "${e}" does not exist`);const i=s.items.find(f=>f.id===r);if(!i)throw new Error(`Item "${r}" not found in queue "${e}"`);return i.status="failed",i.error=t,i.updatedAt=new Date().toISOString(),g(u,n),i}function D(e,r){return o(r)[e]??null}function y(e){const r=o(e);return Object.values(r).map(t=>({name:t.name,pending:t.items.filter(n=>n.status==="pending").length,done:t.items.filter(n=>n.status==="done").length,failed:t.items.filter(n=>n.status==="failed").length,total:t.items.length}))}function O(e,r){const t=o(r),n=t[e];if(!n)throw new Error(`Queue "${e}" does not exist`);const u=n.items.length;n.items=n.items.filter(i=>i.status==="pending"||i.status==="in-progress");const s=u-n.items.length;return g(t,r),s}function v(e,r){const t=o(r);return t[e]?(delete t[e],g(t,r),!0):!1}export{O as queueClear,I as queueCreate,v as queueDelete,b as queueDone,A as queueFail,D as queueGet,y as queueList,$ as queueNext,E as queuePush};
|
|
@@ -1,39 +1 @@
|
|
|
1
|
-
function
|
|
2
|
-
const { pattern, flags = "", testStrings, mode = "match", replacement = "" } = options;
|
|
3
|
-
try {
|
|
4
|
-
const regex = new RegExp(pattern, flags);
|
|
5
|
-
const results = testStrings.map((input) => {
|
|
6
|
-
const matched = regex.test(input);
|
|
7
|
-
switch (mode) {
|
|
8
|
-
case "match": {
|
|
9
|
-
const globalFlags = flags.includes("g") ? flags : `${flags}g`;
|
|
10
|
-
const allMatches = [...input.matchAll(new RegExp(pattern, globalFlags))];
|
|
11
|
-
return {
|
|
12
|
-
input,
|
|
13
|
-
matched,
|
|
14
|
-
matches: allMatches.map((m) => ({
|
|
15
|
-
full: m[0],
|
|
16
|
-
groups: [...m.slice(1)],
|
|
17
|
-
index: m.index ?? 0
|
|
18
|
-
}))
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
case "replace":
|
|
22
|
-
return {
|
|
23
|
-
input,
|
|
24
|
-
matched,
|
|
25
|
-
replaced: input.replace(new RegExp(pattern, flags), replacement)
|
|
26
|
-
};
|
|
27
|
-
default:
|
|
28
|
-
return { input, matched, split: input.split(new RegExp(pattern, flags)) };
|
|
29
|
-
}
|
|
30
|
-
});
|
|
31
|
-
return { pattern, flags, results, valid: true };
|
|
32
|
-
} catch (err) {
|
|
33
|
-
return { pattern, flags, results: [], valid: false, error: err.message };
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
export {
|
|
37
|
-
regexTest
|
|
38
|
-
};
|
|
39
|
-
//# sourceMappingURL=regex-test.js.map
|
|
1
|
+
function u(g){const{pattern:r,flags:e="",testStrings:l,mode:c="match",replacement:i=""}=g;try{const s=new RegExp(r,e),o=l.map(t=>{const n=s.test(t);switch(c){case"match":{const p=e.includes("g")?e:`${e}g`,x=[...t.matchAll(new RegExp(r,p))];return{input:t,matched:n,matches:x.map(a=>({full:a[0],groups:[...a.slice(1)],index:a.index??0}))}}case"replace":return{input:t,matched:n,replaced:t.replace(new RegExp(r,e),i)};default:return{input:t,matched:n,split:t.split(new RegExp(r,e))}}});return{pattern:r,flags:e,results:o,valid:!0}}catch(s){return{pattern:r,flags:e,results:[],valid:!1,error:s.message}}}export{u as regexTest};
|
|
@@ -1,70 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
import { DEFAULT_TOOL_EXTENSIONS, walkFiles } from "./file-walk.js";
|
|
4
|
-
function escapeRegex(value) {
|
|
5
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6
|
-
}
|
|
7
|
-
function normalizePath(path) {
|
|
8
|
-
return path.replace(/\\/g, "/");
|
|
9
|
-
}
|
|
10
|
-
function createWholeWordPattern(name) {
|
|
11
|
-
return new RegExp(`(^|[^A-Za-z0-9_$])(${escapeRegex(name)})(?=[^A-Za-z0-9_$]|$)`, "g");
|
|
12
|
-
}
|
|
13
|
-
async function rename(options) {
|
|
14
|
-
const {
|
|
15
|
-
oldName,
|
|
16
|
-
newName,
|
|
17
|
-
rootPath,
|
|
18
|
-
extensions = DEFAULT_TOOL_EXTENSIONS,
|
|
19
|
-
exclude = [],
|
|
20
|
-
dryRun = false
|
|
21
|
-
} = options;
|
|
22
|
-
if (!oldName.trim()) {
|
|
23
|
-
throw new Error("oldName must not be empty");
|
|
24
|
-
}
|
|
25
|
-
const pattern = createWholeWordPattern(oldName);
|
|
26
|
-
const filePaths = await walkFiles(rootPath, extensions, exclude);
|
|
27
|
-
const changes = [];
|
|
28
|
-
let filesModified = 0;
|
|
29
|
-
for (const filePath of filePaths) {
|
|
30
|
-
const originalContent = await readFile(filePath, "utf-8");
|
|
31
|
-
const lines = originalContent.split(/\r?\n/);
|
|
32
|
-
let fileChanged = false;
|
|
33
|
-
for (let index = 0; index < lines.length; index++) {
|
|
34
|
-
const before = lines[index];
|
|
35
|
-
pattern.lastIndex = 0;
|
|
36
|
-
const after = before.replace(pattern, (_match, prefix) => {
|
|
37
|
-
fileChanged = true;
|
|
38
|
-
return `${prefix}${newName}`;
|
|
39
|
-
});
|
|
40
|
-
if (before === after) {
|
|
41
|
-
continue;
|
|
42
|
-
}
|
|
43
|
-
lines[index] = after;
|
|
44
|
-
changes.push({
|
|
45
|
-
path: normalizePath(relative(rootPath, filePath)),
|
|
46
|
-
line: index + 1,
|
|
47
|
-
before,
|
|
48
|
-
after
|
|
49
|
-
});
|
|
50
|
-
}
|
|
51
|
-
if (!fileChanged) {
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
filesModified += 1;
|
|
55
|
-
if (!dryRun) {
|
|
56
|
-
await writeFile(filePath, lines.join("\n"), "utf-8");
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return {
|
|
60
|
-
oldName,
|
|
61
|
-
newName,
|
|
62
|
-
changes,
|
|
63
|
-
filesModified,
|
|
64
|
-
dryRun
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
export {
|
|
68
|
-
rename
|
|
69
|
-
};
|
|
70
|
-
//# sourceMappingURL=rename.js.map
|
|
1
|
+
import{readFile as x,writeFile as w}from"node:fs/promises";import{relative as N}from"node:path";import{DEFAULT_TOOL_EXTENSIONS as $,walkFiles as b}from"./file-walk.js";function P(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function C(e){return e.replace(/\\/g,"/")}function E(e){return new RegExp(`(^|[^A-Za-z0-9_$])(${P(e)})(?=[^A-Za-z0-9_$]|$)`,"g")}async function A(e){const{oldName:r,newName:s,rootPath:l,extensions:p=$,exclude:d=[],dryRun:f=!1}=e;if(!r.trim())throw new Error("oldName must not be empty");const g=E(r),h=await b(l,p,d),c=[];let m=0;for(const i of h){const t=(await x(i,"utf-8")).split(/\r?\n/);let u=!1;for(let n=0;n<t.length;n++){const a=t[n];g.lastIndex=0;const o=a.replace(g,(O,R)=>(u=!0,`${R}${s}`));a!==o&&(t[n]=o,c.push({path:C(N(l,i)),line:n+1,before:a,after:o}))}u&&(m+=1,f||await w(i,t.join(`
|
|
2
|
+
`),"utf-8"))}return{oldName:r,newName:s,changes:c,filesModified:m,dryRun:f}}export{A as rename};
|
|
@@ -1,108 +1,6 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
}
|
|
8
|
-
function truncate(s, maxLen) {
|
|
9
|
-
if (s.length <= maxLen) return s;
|
|
10
|
-
return `${s.slice(0, maxLen - 1)}\u2026`;
|
|
11
|
-
}
|
|
12
|
-
function replayAppend(entry) {
|
|
13
|
-
const p = getReplayPath();
|
|
14
|
-
mkdirSync(dirname(p), { recursive: true });
|
|
15
|
-
const safe = {
|
|
16
|
-
...entry,
|
|
17
|
-
input: truncate(entry.input, SUMMARY_LEN),
|
|
18
|
-
output: truncate(entry.output, SUMMARY_LEN)
|
|
19
|
-
};
|
|
20
|
-
appendFileSync(p, `${JSON.stringify(safe)}
|
|
21
|
-
`, "utf-8");
|
|
22
|
-
}
|
|
23
|
-
function replayList(opts = {}) {
|
|
24
|
-
const p = getReplayPath();
|
|
25
|
-
let raw;
|
|
26
|
-
try {
|
|
27
|
-
raw = readFileSync(p, "utf-8");
|
|
28
|
-
} catch {
|
|
29
|
-
return [];
|
|
30
|
-
}
|
|
31
|
-
const lines = raw.trim().split("\n").filter(Boolean);
|
|
32
|
-
let entries = [];
|
|
33
|
-
for (const line of lines) {
|
|
34
|
-
try {
|
|
35
|
-
entries.push(JSON.parse(line));
|
|
36
|
-
} catch {
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
if (opts.tool) {
|
|
40
|
-
entries = entries.filter((e) => e.tool === opts.tool);
|
|
41
|
-
}
|
|
42
|
-
if (opts.source) {
|
|
43
|
-
entries = entries.filter((e) => e.source === opts.source);
|
|
44
|
-
}
|
|
45
|
-
if (opts.since) {
|
|
46
|
-
const since = opts.since;
|
|
47
|
-
entries = entries.filter((e) => e.ts >= since);
|
|
48
|
-
}
|
|
49
|
-
const last = opts.last ?? 20;
|
|
50
|
-
return entries.slice(-last);
|
|
51
|
-
}
|
|
52
|
-
function replayTrim() {
|
|
53
|
-
const p = getReplayPath();
|
|
54
|
-
let raw;
|
|
55
|
-
try {
|
|
56
|
-
raw = readFileSync(p, "utf-8");
|
|
57
|
-
} catch {
|
|
58
|
-
return 0;
|
|
59
|
-
}
|
|
60
|
-
const lines = raw.trim().split("\n").filter(Boolean);
|
|
61
|
-
if (lines.length <= MAX_ENTRIES) return 0;
|
|
62
|
-
const trimmed = lines.length - MAX_ENTRIES;
|
|
63
|
-
const kept = lines.slice(-MAX_ENTRIES);
|
|
64
|
-
writeFileSync(p, `${kept.join("\n")}
|
|
65
|
-
`, "utf-8");
|
|
66
|
-
return trimmed;
|
|
67
|
-
}
|
|
68
|
-
function replayClear() {
|
|
69
|
-
const p = getReplayPath();
|
|
70
|
-
try {
|
|
71
|
-
writeFileSync(p, "", "utf-8");
|
|
72
|
-
} catch {
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
function replayCapture(source, tool, input, fn) {
|
|
76
|
-
const start = Date.now();
|
|
77
|
-
return fn().then((result) => {
|
|
78
|
-
replayAppend({
|
|
79
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
80
|
-
source,
|
|
81
|
-
tool,
|
|
82
|
-
input: typeof input === "string" ? input : JSON.stringify(input),
|
|
83
|
-
durationMs: Date.now() - start,
|
|
84
|
-
status: "ok",
|
|
85
|
-
output: typeof result === "string" ? result : JSON.stringify(result ?? "")
|
|
86
|
-
});
|
|
87
|
-
return result;
|
|
88
|
-
}).catch((err) => {
|
|
89
|
-
replayAppend({
|
|
90
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
91
|
-
source,
|
|
92
|
-
tool,
|
|
93
|
-
input: typeof input === "string" ? input : JSON.stringify(input),
|
|
94
|
-
durationMs: Date.now() - start,
|
|
95
|
-
status: "error",
|
|
96
|
-
output: err instanceof Error ? err.message : String(err)
|
|
97
|
-
});
|
|
98
|
-
throw err;
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
export {
|
|
102
|
-
replayAppend,
|
|
103
|
-
replayCapture,
|
|
104
|
-
replayClear,
|
|
105
|
-
replayList,
|
|
106
|
-
replayTrim
|
|
107
|
-
};
|
|
108
|
-
//# sourceMappingURL=replay.js.map
|
|
1
|
+
import{appendFileSync as m,mkdirSync as S,readFileSync as u,writeFileSync as l}from"node:fs";import{dirname as w,resolve as d}from"node:path";const a=5e3,p=200;function c(){return d(process.cwd(),".kb-state","replay.jsonl")}function f(t,r){return t.length<=r?t:`${t.slice(0,r-1)}\u2026`}function y(t){const r=c();S(w(r),{recursive:!0});const n={...t,input:f(t.input,p),output:f(t.output,p)};m(r,`${JSON.stringify(n)}
|
|
2
|
+
`,"utf-8")}function E(t={}){const r=c();let n;try{n=u(r,"utf-8")}catch{return[]}const s=n.trim().split(`
|
|
3
|
+
`).filter(Boolean);let e=[];for(const o of s)try{e.push(JSON.parse(o))}catch{}if(t.tool&&(e=e.filter(o=>o.tool===t.tool)),t.source&&(e=e.filter(o=>o.source===t.source)),t.since){const o=t.since;e=e.filter(g=>g.ts>=o)}const i=t.last??20;return e.slice(-i)}function k(){const t=c();let r;try{r=u(t,"utf-8")}catch{return 0}const n=r.trim().split(`
|
|
4
|
+
`).filter(Boolean);if(n.length<=a)return 0;const s=n.length-a,e=n.slice(-a);return l(t,`${e.join(`
|
|
5
|
+
`)}
|
|
6
|
+
`,"utf-8"),s}function O(){const t=c();try{l(t,"","utf-8")}catch{}}function N(t,r,n,s){const e=Date.now();return s().then(i=>(y({ts:new Date().toISOString(),source:t,tool:r,input:typeof n=="string"?n:JSON.stringify(n),durationMs:Date.now()-e,status:"ok",output:typeof i=="string"?i:JSON.stringify(i??"")}),i)).catch(i=>{throw y({ts:new Date().toISOString(),source:t,tool:r,input:typeof n=="string"?n:JSON.stringify(n),durationMs:Date.now()-e,status:"error",output:i instanceof Error?i.message:String(i)}),i})}export{y as replayAppend,N as replayCapture,O as replayClear,E as replayList,k as replayTrim};
|