@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.
Files changed (136) hide show
  1. package/package.json +1 -1
  2. package/packages/analyzers/dist/blast-radius-analyzer.js +13 -114
  3. package/packages/analyzers/dist/dependency-analyzer.js +11 -425
  4. package/packages/analyzers/dist/diagram-generator.js +4 -86
  5. package/packages/analyzers/dist/entry-point-analyzer.js +5 -239
  6. package/packages/analyzers/dist/index.js +1 -23
  7. package/packages/analyzers/dist/knowledge-producer.js +24 -113
  8. package/packages/analyzers/dist/pattern-analyzer.js +5 -359
  9. package/packages/analyzers/dist/regex-call-graph.js +1 -428
  10. package/packages/analyzers/dist/structure-analyzer.js +4 -258
  11. package/packages/analyzers/dist/symbol-analyzer.js +13 -442
  12. package/packages/analyzers/dist/ts-call-graph.js +1 -160
  13. package/packages/analyzers/dist/types.js +0 -1
  14. package/packages/chunker/dist/call-graph-extractor.js +1 -90
  15. package/packages/chunker/dist/chunker-factory.js +1 -36
  16. package/packages/chunker/dist/chunker.interface.js +0 -1
  17. package/packages/chunker/dist/code-chunker.js +14 -134
  18. package/packages/chunker/dist/generic-chunker.js +5 -72
  19. package/packages/chunker/dist/index.js +1 -21
  20. package/packages/chunker/dist/markdown-chunker.js +7 -119
  21. package/packages/chunker/dist/treesitter-chunker.js +8 -234
  22. package/packages/cli/dist/commands/analyze.js +3 -112
  23. package/packages/cli/dist/commands/context-cmds.js +1 -155
  24. package/packages/cli/dist/commands/environment.js +2 -204
  25. package/packages/cli/dist/commands/execution.js +1 -137
  26. package/packages/cli/dist/commands/graph.js +7 -81
  27. package/packages/cli/dist/commands/init.js +9 -87
  28. package/packages/cli/dist/commands/knowledge.js +1 -139
  29. package/packages/cli/dist/commands/search.js +8 -267
  30. package/packages/cli/dist/commands/system.js +4 -241
  31. package/packages/cli/dist/commands/workspace.js +2 -388
  32. package/packages/cli/dist/context.js +1 -14
  33. package/packages/cli/dist/helpers.js +3 -458
  34. package/packages/cli/dist/index.js +3 -69
  35. package/packages/cli/dist/kb-init.js +1 -82
  36. package/packages/cli/dist/types.js +0 -1
  37. package/packages/core/dist/constants.js +1 -43
  38. package/packages/core/dist/content-detector.js +1 -79
  39. package/packages/core/dist/errors.js +1 -40
  40. package/packages/core/dist/index.js +1 -9
  41. package/packages/core/dist/logger.js +1 -34
  42. package/packages/core/dist/types.js +0 -1
  43. package/packages/embeddings/dist/embedder.interface.js +0 -1
  44. package/packages/embeddings/dist/index.js +1 -5
  45. package/packages/embeddings/dist/onnx-embedder.js +1 -82
  46. package/packages/indexer/dist/file-hasher.js +1 -13
  47. package/packages/indexer/dist/filesystem-crawler.js +1 -125
  48. package/packages/indexer/dist/graph-extractor.js +1 -111
  49. package/packages/indexer/dist/incremental-indexer.js +1 -278
  50. package/packages/indexer/dist/index.js +1 -14
  51. package/packages/server/dist/api.js +1 -9
  52. package/packages/server/dist/config.js +1 -75
  53. package/packages/server/dist/curated-manager.js +9 -356
  54. package/packages/server/dist/index.js +1 -134
  55. package/packages/server/dist/replay-interceptor.js +1 -38
  56. package/packages/server/dist/resources/resources.js +2 -40
  57. package/packages/server/dist/server.js +1 -247
  58. package/packages/server/dist/tools/analyze.tools.js +1 -288
  59. package/packages/server/dist/tools/forge.tools.js +11 -499
  60. package/packages/server/dist/tools/forget.tool.js +3 -39
  61. package/packages/server/dist/tools/graph.tool.js +5 -110
  62. package/packages/server/dist/tools/list.tool.js +5 -53
  63. package/packages/server/dist/tools/lookup.tool.js +8 -51
  64. package/packages/server/dist/tools/onboard.tool.js +2 -112
  65. package/packages/server/dist/tools/produce.tool.js +4 -74
  66. package/packages/server/dist/tools/read.tool.js +4 -47
  67. package/packages/server/dist/tools/reindex.tool.js +2 -70
  68. package/packages/server/dist/tools/remember.tool.js +3 -42
  69. package/packages/server/dist/tools/replay.tool.js +6 -88
  70. package/packages/server/dist/tools/search.tool.js +17 -327
  71. package/packages/server/dist/tools/status.tool.js +3 -68
  72. package/packages/server/dist/tools/toolkit.tools.js +20 -1673
  73. package/packages/server/dist/tools/update.tool.js +3 -39
  74. package/packages/server/dist/tools/utility.tools.js +19 -456
  75. package/packages/store/dist/graph-store.interface.js +0 -1
  76. package/packages/store/dist/index.js +1 -9
  77. package/packages/store/dist/lance-store.js +1 -258
  78. package/packages/store/dist/sqlite-graph-store.js +8 -309
  79. package/packages/store/dist/store-factory.js +1 -14
  80. package/packages/store/dist/store.interface.js +0 -1
  81. package/packages/tools/dist/batch.js +1 -45
  82. package/packages/tools/dist/changelog.js +2 -112
  83. package/packages/tools/dist/check.js +2 -59
  84. package/packages/tools/dist/checkpoint.js +2 -43
  85. package/packages/tools/dist/codemod.js +2 -69
  86. package/packages/tools/dist/compact.js +3 -60
  87. package/packages/tools/dist/data-transform.js +1 -124
  88. package/packages/tools/dist/dead-symbols.js +2 -71
  89. package/packages/tools/dist/delegate.js +3 -128
  90. package/packages/tools/dist/diff-parse.js +3 -153
  91. package/packages/tools/dist/digest.js +7 -242
  92. package/packages/tools/dist/encode.js +1 -46
  93. package/packages/tools/dist/env-info.js +1 -58
  94. package/packages/tools/dist/eval.js +3 -79
  95. package/packages/tools/dist/evidence-map.js +3 -203
  96. package/packages/tools/dist/file-summary.js +2 -106
  97. package/packages/tools/dist/file-walk.js +1 -75
  98. package/packages/tools/dist/find-examples.js +3 -48
  99. package/packages/tools/dist/find.js +1 -120
  100. package/packages/tools/dist/forge-classify.js +2 -319
  101. package/packages/tools/dist/forge-ground.js +1 -184
  102. package/packages/tools/dist/git-context.js +3 -46
  103. package/packages/tools/dist/graph-query.js +1 -194
  104. package/packages/tools/dist/health.js +1 -118
  105. package/packages/tools/dist/http-request.js +1 -58
  106. package/packages/tools/dist/index.js +1 -273
  107. package/packages/tools/dist/lane.js +7 -227
  108. package/packages/tools/dist/measure.js +2 -119
  109. package/packages/tools/dist/onboard.js +42 -1136
  110. package/packages/tools/dist/parse-output.js +2 -158
  111. package/packages/tools/dist/process-manager.js +1 -69
  112. package/packages/tools/dist/queue.js +2 -126
  113. package/packages/tools/dist/regex-test.js +1 -39
  114. package/packages/tools/dist/rename.js +2 -70
  115. package/packages/tools/dist/replay.js +6 -108
  116. package/packages/tools/dist/schema-validate.js +1 -141
  117. package/packages/tools/dist/scope-map.js +1 -72
  118. package/packages/tools/dist/snippet.js +1 -80
  119. package/packages/tools/dist/stash.js +2 -60
  120. package/packages/tools/dist/stratum-card.js +5 -238
  121. package/packages/tools/dist/symbol.js +3 -87
  122. package/packages/tools/dist/test-run.js +2 -55
  123. package/packages/tools/dist/text-utils.js +2 -31
  124. package/packages/tools/dist/time-utils.js +1 -135
  125. package/packages/tools/dist/trace.js +2 -114
  126. package/packages/tools/dist/truncation.js +10 -41
  127. package/packages/tools/dist/watch.js +1 -61
  128. package/packages/tools/dist/web-fetch.js +9 -244
  129. package/packages/tools/dist/web-search.js +1 -46
  130. package/packages/tools/dist/workset.js +2 -77
  131. package/packages/tui/dist/App.js +260 -52468
  132. package/packages/tui/dist/index.js +286 -54551
  133. package/packages/tui/dist/panels/CuratedPanel.js +211 -34291
  134. package/packages/tui/dist/panels/LogPanel.js +259 -51703
  135. package/packages/tui/dist/panels/SearchPanel.js +212 -34824
  136. package/packages/tui/dist/panels/StatusPanel.js +211 -34304
@@ -1,158 +1,2 @@
1
- function parseTsc(output) {
2
- const errors = [];
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 { spawn } from "node:child_process";
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 { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
- import { dirname, resolve } from "node:path";
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 regexTest(options) {
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 { readFile, writeFile } from "node:fs/promises";
2
- import { relative } from "node:path";
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 { appendFileSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
- import { dirname, resolve } from "node:path";
3
- const MAX_ENTRIES = 5e3;
4
- const SUMMARY_LEN = 200;
5
- function getReplayPath() {
6
- return resolve(process.cwd(), ".kb-state", "replay.jsonl");
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};