@vpxa/kb 0.1.1 → 0.1.3

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