@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,87 +1,3 @@
1
- function escapeRegex(value) {
2
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
3
- }
4
- async function symbol(embedder, store, options) {
5
- const { name, limit = 20 } = options;
6
- const embedQuery = embedder.embedQuery?.bind(embedder) ?? embedder.embed.bind(embedder);
7
- const definitionQuery = [
8
- `export function ${name}`,
9
- `export class ${name}`,
10
- `export const ${name}`,
11
- `export interface ${name}`,
12
- `export type ${name}`,
13
- `export enum ${name}`
14
- ].join(" | ");
15
- const definitionResults = await store.search(await embedQuery(definitionQuery), {
16
- limit: limit * 2
17
- });
18
- const exportPattern = new RegExp(
19
- `^export\\s+(?:default\\s+)?(?:async\\s+)?(?:function|class|const|let|interface|type|enum)\\s+${escapeRegex(name)}\\b`,
20
- "m"
21
- );
22
- let definedIn;
23
- for (const result of definitionResults) {
24
- if (!exportPattern.test(result.record.content)) continue;
25
- const kind = result.record.content.match(/export\s+(?:default\s+)?(?:async\s+)?(\w+)/)?.[1] ?? "unknown";
26
- definedIn = {
27
- path: result.record.sourcePath,
28
- line: result.record.startLine,
29
- kind
30
- };
31
- break;
32
- }
33
- const importPattern = new RegExp(`import\\s+.*\\b${escapeRegex(name)}\\b.*from\\s+`, "m");
34
- const importResults = await store.search(await embedQuery(`import ${name} from`), {
35
- limit: limit * 3
36
- });
37
- const importedBy = [];
38
- const seenImports = /* @__PURE__ */ new Set();
39
- for (const result of importResults) {
40
- const lines = result.record.content.split("\n");
41
- for (let index = 0; index < lines.length; index++) {
42
- const line = lines[index];
43
- if (!importPattern.test(line)) continue;
44
- const key = `${result.record.sourcePath}:${line.trim()}`;
45
- if (seenImports.has(key)) continue;
46
- seenImports.add(key);
47
- importedBy.push({
48
- path: result.record.sourcePath,
49
- line: result.record.startLine + index,
50
- importStatement: line.trim()
51
- });
52
- }
53
- }
54
- const referencePattern = new RegExp(`\\b${escapeRegex(name)}\\b`);
55
- const referenceResults = await store.search(await embedQuery(name), {
56
- limit: limit * 3
57
- });
58
- const referencedIn = [];
59
- const seenReferences = /* @__PURE__ */ new Set();
60
- for (const result of referenceResults) {
61
- if (definedIn && result.record.sourcePath === definedIn.path) continue;
62
- const lines = result.record.content.split("\n");
63
- for (let index = 0; index < lines.length; index++) {
64
- const line = lines[index];
65
- if (!referencePattern.test(line) || importPattern.test(line)) continue;
66
- const key = `${result.record.sourcePath}:${result.record.startLine + index}`;
67
- if (seenReferences.has(key)) continue;
68
- seenReferences.add(key);
69
- referencedIn.push({
70
- path: result.record.sourcePath,
71
- line: result.record.startLine + index,
72
- context: line.trim().slice(0, 120)
73
- });
74
- break;
75
- }
76
- }
77
- return {
78
- name,
79
- definedIn,
80
- importedBy: importedBy.slice(0, limit),
81
- referencedIn: referencedIn.slice(0, limit)
82
- };
83
- }
84
- export {
85
- symbol
86
- };
87
- //# sourceMappingURL=symbol.js.map
1
+ function l(i){return i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}async function P(i,d,h){const{name:t,limit:s=20}=h,m=i.embedQuery?.bind(i)??i.embed.bind(i),g=[`export function ${t}`,`export class ${t}`,`export const ${t}`,`export interface ${t}`,`export type ${t}`,`export enum ${t}`].join(" | "),x=await d.search(await m(g),{limit:s*2}),I=new RegExp(`^export\\s+(?:default\\s+)?(?:async\\s+)?(?:function|class|const|let|interface|type|enum)\\s+${l(t)}\\b`,"m");let a;for(const e of x){if(!I.test(e.record.content))continue;const r=e.record.content.match(/export\s+(?:default\s+)?(?:async\s+)?(\w+)/)?.[1]??"unknown";a={path:e.record.sourcePath,line:e.record.startLine,kind:r};break}const p=new RegExp(`import\\s+.*\\b${l(t)}\\b.*from\\s+`,"m"),$=await d.search(await m(`import ${t} from`),{limit:s*3}),f=[],u=new Set;for(const e of $){const r=e.record.content.split(`
2
+ `);for(let n=0;n<r.length;n++){const o=r[n];if(!p.test(o))continue;const c=`${e.record.sourcePath}:${o.trim()}`;u.has(c)||(u.add(c),f.push({path:e.record.sourcePath,line:e.record.startLine+n,importStatement:o.trim()}))}}const w=new RegExp(`\\b${l(t)}\\b`),S=await d.search(await m(t),{limit:s*3}),y=[],b=new Set;for(const e of S){if(a&&e.record.sourcePath===a.path)continue;const r=e.record.content.split(`
3
+ `);for(let n=0;n<r.length;n++){const o=r[n];if(!w.test(o)||p.test(o))continue;const c=`${e.record.sourcePath}:${e.record.startLine+n}`;if(!b.has(c)){b.add(c),y.push({path:e.record.sourcePath,line:e.record.startLine+n,context:o.trim().slice(0,120)});break}}}return{name:t,definedIn:a,importedBy:f.slice(0,s),referencedIn:y.slice(0,s)}}export{P as symbol};
@@ -1,55 +1,2 @@
1
- import { execFile } from "node:child_process";
2
- import { promisify } from "node:util";
3
- import { parseVitest } from "./parse-output.js";
4
- const execFileAsync = promisify(execFile);
5
- async function testRun(options = {}) {
6
- const cwd = options.cwd ?? process.cwd();
7
- const timeout = options.timeout ?? 6e4;
8
- const start = Date.now();
9
- const args = ["vitest", "run", "--reporter=verbose"];
10
- if (options.files?.length) args.push(...options.files);
11
- if (options.grep) args.push("--testNamePattern", options.grep);
12
- try {
13
- const { stdout } = await execFileAsync("npx", args, { cwd, shell: true, timeout });
14
- const raw = stdout.toString();
15
- const summary = parseVitest(raw);
16
- return {
17
- summary,
18
- passed: summary.failed === 0,
19
- raw,
20
- durationMs: Date.now() - start
21
- };
22
- } catch (error) {
23
- const raw = getProcessOutput(error);
24
- const summary = parseVitest(raw);
25
- return {
26
- summary,
27
- passed: false,
28
- raw,
29
- durationMs: Date.now() - start
30
- };
31
- }
32
- }
33
- function getProcessOutput(error) {
34
- const details = error;
35
- const stdout = details.stdout?.toString() ?? "";
36
- const stderr = details.stderr?.toString() ?? "";
37
- return [stdout, stderr].filter(Boolean).join("\n").trim() || details.message || "Test run failed";
38
- }
39
- function classifyExitCode(exitCode, _stdout, command) {
40
- if (exitCode === 0) return { isError: false };
41
- if (exitCode === 1 && command) {
42
- if (/\b(grep|rg|ripgrep|ag|ack|findstr)\b/i.test(command)) {
43
- return { isError: false, reason: "grep: no matches (exit 1 is normal)" };
44
- }
45
- if (/\bdiff\b/i.test(command)) {
46
- return { isError: false, reason: "diff: files differ (exit 1 is normal)" };
47
- }
48
- }
49
- return { isError: true };
50
- }
51
- export {
52
- classifyExitCode,
53
- testRun
54
- };
55
- //# sourceMappingURL=test-run.js.map
1
+ import{execFile as f}from"node:child_process";import{promisify as c}from"node:util";import{parseVitest as u}from"./parse-output.js";const m=c(f);async function w(r={}){const e=r.cwd??process.cwd(),t=r.timeout??6e4,n=Date.now(),i=["vitest","run","--reporter=verbose"];r.files?.length&&i.push(...r.files),r.grep&&i.push("--testNamePattern",r.grep);try{const{stdout:o}=await m("npx",i,{cwd:e,shell:!0,timeout:t}),s=o.toString(),a=u(s);return{summary:a,passed:a.failed===0,raw:s,durationMs:Date.now()-n}}catch(o){const s=g(o);return{summary:u(s),passed:!1,raw:s,durationMs:Date.now()-n}}}function g(r){const e=r,t=e.stdout?.toString()??"",n=e.stderr?.toString()??"";return[t,n].filter(Boolean).join(`
2
+ `).trim()||e.message||"Test run failed"}function y(r,e,t){if(r===0)return{isError:!1};if(r===1&&t){if(/\b(grep|rg|ripgrep|ag|ack|findstr)\b/i.test(t))return{isError:!1,reason:"grep: no matches (exit 1 is normal)"};if(/\bdiff\b/i.test(t))return{isError:!1,reason:"diff: files differ (exit 1 is normal)"}}return{isError:!0}}export{y as classifyExitCode,w as testRun};
@@ -1,31 +1,2 @@
1
- function estimateTokens(text) {
2
- return Math.ceil(text.length / 4);
3
- }
4
- function segment(text, strategy) {
5
- switch (strategy) {
6
- case "paragraph":
7
- return text.split(/\n\s*\n/).map((s) => s.trim()).filter((s) => s.length > 0);
8
- case "sentence":
9
- return text.split(/(?<=[.!?])\s+/).map((s) => s.trim()).filter((s) => s.length > 0);
10
- case "line":
11
- return text.split("\n").map((s) => s.trim()).filter((s) => s.length > 0);
12
- }
13
- }
14
- function cosineSimilarity(a, b) {
15
- let dot = 0;
16
- let normA = 0;
17
- let normB = 0;
18
- for (let i = 0; i < a.length; i++) {
19
- dot += a[i] * b[i];
20
- normA += a[i] * a[i];
21
- normB += b[i] * b[i];
22
- }
23
- const denom = Math.sqrt(normA) * Math.sqrt(normB);
24
- return denom === 0 ? 0 : dot / denom;
25
- }
26
- export {
27
- cosineSimilarity,
28
- estimateTokens,
29
- segment
30
- };
31
- //# sourceMappingURL=text-utils.js.map
1
+ function a(e){return Math.ceil(e.length/4)}function o(e,n){switch(n){case"paragraph":return e.split(/\n\s*\n/).map(t=>t.trim()).filter(t=>t.length>0);case"sentence":return e.split(/(?<=[.!?])\s+/).map(t=>t.trim()).filter(t=>t.length>0);case"line":return e.split(`
2
+ `).map(t=>t.trim()).filter(t=>t.length>0)}}function m(e,n){let t=0,i=0,l=0;for(let r=0;r<e.length;r++)t+=e[r]*n[r],i+=e[r]*e[r],l+=n[r]*n[r];const s=Math.sqrt(i)*Math.sqrt(l);return s===0?0:t/s}export{m as cosineSimilarity,a as estimateTokens,o as segment};
@@ -1,135 +1 @@
1
- function timeUtils(options) {
2
- const { operation, input, timezone } = options;
3
- switch (operation) {
4
- case "now":
5
- return formatTimeResult(/* @__PURE__ */ new Date(), timezone);
6
- case "parse": {
7
- if (!input) throw new Error("input required for parse");
8
- return formatTimeResult(parseInput(input), timezone);
9
- }
10
- case "convert": {
11
- if (!input) throw new Error("input required for convert");
12
- if (!timezone) throw new Error("timezone required for convert");
13
- return formatTimeResult(parseInput(input), timezone);
14
- }
15
- case "diff": {
16
- if (!input) throw new Error("input required for diff (two comma-separated dates)");
17
- const parts = input.split(",").map((s) => s.trim());
18
- if (parts.length < 2) throw new Error("diff requires two comma-separated dates");
19
- const a = parseInput(parts[0]);
20
- const b = parseInput(parts[1]);
21
- const diffMs = Math.abs(b.getTime() - a.getTime());
22
- return {
23
- output: formatDuration(diffMs),
24
- iso: `PT${Math.floor(diffMs / 1e3)}S`,
25
- unix: diffMs,
26
- details: {
27
- milliseconds: diffMs,
28
- seconds: Math.floor(diffMs / 1e3),
29
- minutes: Math.floor(diffMs / 6e4),
30
- hours: Math.floor(diffMs / 36e5),
31
- days: Math.floor(diffMs / 864e5)
32
- }
33
- };
34
- }
35
- case "add": {
36
- if (!input) throw new Error("input required for add");
37
- const { duration } = options;
38
- if (!duration) throw new Error('duration required for add (e.g., "2h30m")');
39
- const date = parseInput(input);
40
- const ms = parseDuration(duration);
41
- return formatTimeResult(new Date(date.getTime() + ms), timezone);
42
- }
43
- default:
44
- throw new Error(`Unknown operation: ${operation}`);
45
- }
46
- }
47
- function parseInput(input) {
48
- const num = Number(input);
49
- if (!Number.isNaN(num)) {
50
- return new Date(num > 1e12 ? num : num * 1e3);
51
- }
52
- const d = new Date(input);
53
- if (Number.isNaN(d.getTime())) throw new Error(`Cannot parse date: ${input}`);
54
- return d;
55
- }
56
- function formatTimeResult(date, timezone) {
57
- const tz = timezone ?? "UTC";
58
- const formatted = date.toLocaleString("en-US", {
59
- timeZone: tz,
60
- dateStyle: "full",
61
- timeStyle: "long"
62
- });
63
- const parts = new Intl.DateTimeFormat("en-US", {
64
- timeZone: tz,
65
- year: "numeric",
66
- month: "numeric",
67
- day: "numeric",
68
- hour: "numeric",
69
- minute: "numeric",
70
- second: "numeric",
71
- hour12: false
72
- }).formatToParts(date).reduce(
73
- (acc, part) => {
74
- if (part.type !== "literal") acc[part.type] = Number.parseInt(part.value, 10);
75
- return acc;
76
- },
77
- {}
78
- );
79
- return {
80
- output: formatted,
81
- iso: date.toISOString(),
82
- unix: Math.floor(date.getTime() / 1e3),
83
- details: {
84
- timezone: tz,
85
- year: parts.year,
86
- month: parts.month,
87
- day: parts.day,
88
- hour: parts.hour === 24 ? 0 : parts.hour,
89
- minute: parts.minute,
90
- second: parts.second
91
- }
92
- };
93
- }
94
- function formatDuration(ms) {
95
- const parts = [];
96
- const d = Math.floor(ms / 864e5);
97
- if (d) parts.push(`${d}d`);
98
- const h = Math.floor(ms % 864e5 / 36e5);
99
- if (h) parts.push(`${h}h`);
100
- const m = Math.floor(ms % 36e5 / 6e4);
101
- if (m) parts.push(`${m}m`);
102
- const s = Math.floor(ms % 6e4 / 1e3);
103
- if (s || parts.length === 0) parts.push(`${s}s`);
104
- return parts.join(" ");
105
- }
106
- function parseDuration(duration) {
107
- let ms = 0;
108
- const matches = duration.matchAll(/(\d+)\s*(d|h|m|s|ms)/gi);
109
- for (const match of matches) {
110
- const val = Number(match[1]);
111
- switch (match[2].toLowerCase()) {
112
- case "d":
113
- ms += val * 864e5;
114
- break;
115
- case "h":
116
- ms += val * 36e5;
117
- break;
118
- case "m":
119
- ms += val * 6e4;
120
- break;
121
- case "s":
122
- ms += val * 1e3;
123
- break;
124
- case "ms":
125
- ms += val;
126
- break;
127
- }
128
- }
129
- if (ms === 0) throw new Error(`Cannot parse duration: ${duration}`);
130
- return ms;
131
- }
132
- export {
133
- timeUtils
134
- };
135
- //# sourceMappingURL=time-utils.js.map
1
+ function h(o){const{operation:e,input:t,timezone:n}=o;switch(e){case"now":return m(new Date,n);case"parse":{if(!t)throw new Error("input required for parse");return m(u(t),n)}case"convert":{if(!t)throw new Error("input required for convert");if(!n)throw new Error("timezone required for convert");return m(u(t),n)}case"diff":{if(!t)throw new Error("input required for diff (two comma-separated dates)");const r=t.split(",").map(c=>c.trim());if(r.length<2)throw new Error("diff requires two comma-separated dates");const i=u(r[0]),a=u(r[1]),s=Math.abs(a.getTime()-i.getTime());return{output:f(s),iso:`PT${Math.floor(s/1e3)}S`,unix:s,details:{milliseconds:s,seconds:Math.floor(s/1e3),minutes:Math.floor(s/6e4),hours:Math.floor(s/36e5),days:Math.floor(s/864e5)}}}case"add":{if(!t)throw new Error("input required for add");const{duration:r}=o;if(!r)throw new Error('duration required for add (e.g., "2h30m")');const i=u(t),a=d(r);return m(new Date(i.getTime()+a),n)}default:throw new Error(`Unknown operation: ${e}`)}}function u(o){const e=Number(o);if(!Number.isNaN(e))return new Date(e>1e12?e:e*1e3);const t=new Date(o);if(Number.isNaN(t.getTime()))throw new Error(`Cannot parse date: ${o}`);return t}function m(o,e){const t=e??"UTC",n=o.toLocaleString("en-US",{timeZone:t,dateStyle:"full",timeStyle:"long"}),r=new Intl.DateTimeFormat("en-US",{timeZone:t,year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",second:"numeric",hour12:!1}).formatToParts(o).reduce((i,a)=>(a.type!=="literal"&&(i[a.type]=Number.parseInt(a.value,10)),i),{});return{output:n,iso:o.toISOString(),unix:Math.floor(o.getTime()/1e3),details:{timezone:t,year:r.year,month:r.month,day:r.day,hour:r.hour===24?0:r.hour,minute:r.minute,second:r.second}}}function f(o){const e=[],t=Math.floor(o/864e5);t&&e.push(`${t}d`);const n=Math.floor(o%864e5/36e5);n&&e.push(`${n}h`);const r=Math.floor(o%36e5/6e4);r&&e.push(`${r}m`);const i=Math.floor(o%6e4/1e3);return(i||e.length===0)&&e.push(`${i}s`),e.join(" ")}function d(o){let e=0;const t=o.matchAll(/(\d+)\s*(d|h|m|s|ms)/gi);for(const n of t){const r=Number(n[1]);switch(n[2].toLowerCase()){case"d":e+=r*864e5;break;case"h":e+=r*36e5;break;case"m":e+=r*6e4;break;case"s":e+=r*1e3;break;case"ms":e+=r;break}}if(e===0)throw new Error(`Cannot parse duration: ${o}`);return e}export{h as timeUtils};
@@ -1,114 +1,2 @@
1
- async function trace(embedder, store, options) {
2
- const { start, direction, maxDepth = 3 } = options;
3
- const nodes = [];
4
- const visitedTargets = /* @__PURE__ */ new Set();
5
- const seenNodes = /* @__PURE__ */ new Set();
6
- const startVector = await embedder.embed(start);
7
- const startResults = await store.search(startVector, { limit: 10 });
8
- if (startResults.length === 0) {
9
- return { start, direction, nodes, depth: 0 };
10
- }
11
- const queue = [{ target: start, depth: 0 }];
12
- let maxObservedDepth = 0;
13
- while (queue.length > 0) {
14
- const current = queue.shift();
15
- if (!current) break;
16
- if (current.depth >= maxDepth) continue;
17
- if (visitedTargets.has(current.target)) continue;
18
- visitedTargets.add(current.target);
19
- const vector = await embedder.embed(current.target);
20
- const results = await store.search(vector, { limit: 20 });
21
- const escapedTarget = escapeRegExp(current.target);
22
- const targetLooksLikeModule = isModuleSpecifier(current.target);
23
- for (const result of results) {
24
- const lines = result.record.content.split("\n");
25
- for (let index = 0; index < lines.length; index += 1) {
26
- const line = lines[index];
27
- const lineNum = result.record.startLine + index;
28
- const path = result.record.sourcePath;
29
- if (direction !== "forward") {
30
- const importPattern = targetLooksLikeModule ? new RegExp(`from\\s+['"]${escapedTarget}['"]`) : new RegExp(`import\\s+.*\\b${escapedTarget}\\b.*from\\s+`);
31
- if (importPattern.test(line)) {
32
- addNode(seenNodes, nodes, {
33
- path,
34
- symbol: current.target,
35
- line: lineNum,
36
- relationship: "imported-by"
37
- });
38
- maxObservedDepth = Math.max(maxObservedDepth, current.depth + 1);
39
- const fromMatch = line.match(/from\s+['"]([^'"]+)['"]/);
40
- if (!targetLooksLikeModule && fromMatch) {
41
- queue.push({ target: fromMatch[1], depth: current.depth + 1 });
42
- }
43
- }
44
- }
45
- if (direction !== "backward") {
46
- if (targetLooksLikeModule) {
47
- const moduleImportPattern = new RegExp(`from\\s+['"]${escapedTarget}['"]`);
48
- if (moduleImportPattern.test(line)) {
49
- addNode(seenNodes, nodes, {
50
- path,
51
- symbol: current.target,
52
- line: lineNum,
53
- relationship: "imports"
54
- });
55
- maxObservedDepth = Math.max(maxObservedDepth, current.depth + 1);
56
- }
57
- } else {
58
- const callPattern = new RegExp(`\\b${escapedTarget}\\s*\\(`);
59
- if (callPattern.test(line) && !/^\s*(?:export\s+)?(?:async\s+)?function\s/.test(line)) {
60
- addNode(seenNodes, nodes, {
61
- path,
62
- symbol: current.target,
63
- line: lineNum,
64
- relationship: "calls"
65
- });
66
- maxObservedDepth = Math.max(maxObservedDepth, current.depth + 1);
67
- }
68
- }
69
- }
70
- const refPattern = targetLooksLikeModule ? new RegExp(`['"]${escapedTarget}['"]`) : new RegExp(`\\b${escapedTarget}\\b`);
71
- if (refPattern.test(line) && !/^\s*import\s/.test(line) && !/^\s*(?:export\s+)?(?:async\s+)?function\s/.test(line)) {
72
- addNode(seenNodes, nodes, {
73
- path,
74
- symbol: current.target,
75
- line: lineNum,
76
- relationship: "references"
77
- });
78
- maxObservedDepth = Math.max(maxObservedDepth, current.depth + 1);
79
- }
80
- }
81
- }
82
- }
83
- return {
84
- start,
85
- direction,
86
- nodes: deduplicateNodes(nodes),
87
- depth: maxObservedDepth
88
- };
89
- }
90
- function addNode(seenNodes, nodes, node) {
91
- const key = `${node.path}:${node.line}:${node.relationship}`;
92
- if (seenNodes.has(key)) return;
93
- seenNodes.add(key);
94
- nodes.push(node);
95
- }
96
- function escapeRegExp(value) {
97
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
98
- }
99
- function isModuleSpecifier(value) {
100
- return /[./\\]/.test(value);
101
- }
102
- function deduplicateNodes(nodes) {
103
- const seen = /* @__PURE__ */ new Set();
104
- return nodes.filter((node) => {
105
- const key = `${node.path}:${node.line}:${node.relationship}`;
106
- if (seen.has(key)) return false;
107
- seen.add(key);
108
- return true;
109
- });
110
- }
111
- export {
112
- trace
113
- };
114
- //# sourceMappingURL=trace.js.map
1
+ async function v(e,a,r){const{start:s,direction:d,maxDepth:T=3}=r,i=[],x=new Set,p=new Set,R=await e.embed(s);if((await a.search(R,{limit:10})).length===0)return{start:s,direction:d,nodes:i,depth:0};const u=[{target:s,depth:0}];let n=0;for(;u.length>0;){const t=u.shift();if(!t)break;if(t.depth>=T||x.has(t.target))continue;x.add(t.target);const N=await e.embed(t.target),P=await a.search(N,{limit:20}),c=E(t.target),l=k(t.target);for(const b of P){const w=b.record.content.split(`
2
+ `);for(let h=0;h<w.length;h+=1){const o=w[h],m=b.record.startLine+h,f=b.record.sourcePath;if(d!=="forward"&&(l?new RegExp(`from\\s+['"]${c}['"]`):new RegExp(`import\\s+.*\\b${c}\\b.*from\\s+`)).test(o)){g(p,i,{path:f,symbol:t.target,line:m,relationship:"imported-by"}),n=Math.max(n,t.depth+1);const $=o.match(/from\s+['"]([^'"]+)['"]/);!l&&$&&u.push({target:$[1],depth:t.depth+1})}d!=="backward"&&(l?new RegExp(`from\\s+['"]${c}['"]`).test(o)&&(g(p,i,{path:f,symbol:t.target,line:m,relationship:"imports"}),n=Math.max(n,t.depth+1)):new RegExp(`\\b${c}\\s*\\(`).test(o)&&!/^\s*(?:export\s+)?(?:async\s+)?function\s/.test(o)&&(g(p,i,{path:f,symbol:t.target,line:m,relationship:"calls"}),n=Math.max(n,t.depth+1))),(l?new RegExp(`['"]${c}['"]`):new RegExp(`\\b${c}\\b`)).test(o)&&!/^\s*import\s/.test(o)&&!/^\s*(?:export\s+)?(?:async\s+)?function\s/.test(o)&&(g(p,i,{path:f,symbol:t.target,line:m,relationship:"references"}),n=Math.max(n,t.depth+1))}}}return{start:s,direction:d,nodes:M(i),depth:n}}function g(e,a,r){const s=`${r.path}:${r.line}:${r.relationship}`;e.has(s)||(e.add(s),a.push(r))}function E(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function k(e){return/[./\\]/.test(e)}function M(e){const a=new Set;return e.filter(r=>{const s=`${r.path}:${r.line}:${r.relationship}`;return a.has(s)?!1:(a.add(s),!0)})}export{v as trace};
@@ -1,45 +1,14 @@
1
- const HEAD_RATIO = 0.6;
2
- function headTailTruncate(text, maxLen, headRatio = HEAD_RATIO) {
3
- if (text.length <= maxLen) return text;
4
- const separatorBudget = 120;
5
- const contentBudget = Math.max(0, maxLen - separatorBudget);
6
- const headBudget = Math.floor(contentBudget * headRatio);
7
- const tailBudget = contentBudget - headBudget;
8
- const headRegion = text.slice(0, headBudget);
9
- const headCut = headRegion.lastIndexOf("\n");
10
- const head = headCut > 0 ? headRegion.slice(0, headCut) : headRegion;
11
- const tailStart = text.length - tailBudget;
12
- const tailRegion = text.slice(tailStart);
13
- const tailCut = tailRegion.indexOf("\n");
14
- const tail = tailCut >= 0 ? tailRegion.slice(tailCut + 1) : tailRegion;
15
- const omittedChars = text.length - head.length - tail.length;
16
- let omittedLines = 1;
17
- const omittedStart = head.length;
18
- const omittedEnd = text.length - tail.length;
19
- for (let i = omittedStart; i < omittedEnd; i++) {
20
- if (text.charCodeAt(i) === 10) omittedLines++;
21
- }
22
- return `${head}
1
+ const T=.6;function m(t,n,c=.6){if(t.length<=n)return t;const o=Math.max(0,n-120),e=Math.floor(o*c),a=o-e,s=t.slice(0,e),h=s.lastIndexOf(`
2
+ `),i=h>0?s.slice(0,h):s,p=t.length-a,l=t.slice(p),d=l.indexOf(`
3
+ `),r=d>=0?l.slice(d+1):l,$=t.length-i.length-r.length;let u=1;const B=i.length,R=t.length-r.length;for(let g=B;g<R;g++)t.charCodeAt(g)===10&&u++;return`${i}
23
4
 
24
- [\u2026 ${omittedLines} lines / ${(omittedChars / 1024).toFixed(1)}KB truncated \u2014 showing first ${head.split("\n").length} + last ${tail.split("\n").length} lines]
5
+ [\u2026 ${u} lines / ${($/1024).toFixed(1)}KB truncated \u2014 showing first ${i.split(`
6
+ `).length} + last ${r.split(`
7
+ `).length} lines]
25
8
 
26
- ${tail}`;
27
- }
28
- function paragraphTruncate(text, maxLen) {
29
- if (text.length <= maxLen) return text;
30
- const searchStart = Math.max(0, maxLen - 200);
31
- const searchRegion = text.slice(searchStart, maxLen);
32
- const lastBreak = searchRegion.lastIndexOf("\n\n");
33
- const cutPoint = lastBreak >= 0 ? searchStart + lastBreak : maxLen;
34
- const truncated = text.slice(0, cutPoint).trimEnd();
35
- const pct = Math.round(cutPoint / text.length * 100);
36
- return `${truncated}
9
+ ${r}`}function A(t,n){if(t.length<=n)return t;const c=Math.max(0,n-200),o=t.slice(c,n).lastIndexOf(`
10
+
11
+ `),e=o>=0?c+o:n,a=t.slice(0,e).trimEnd(),s=Math.round(e/t.length*100);return`${a}
37
12
 
38
13
  ---
39
- *[Truncated at ${cutPoint.toLocaleString()} chars \u2014 ${pct}% of original content]*`;
40
- }
41
- export {
42
- headTailTruncate,
43
- paragraphTruncate
44
- };
45
- //# sourceMappingURL=truncation.js.map
14
+ *[Truncated at ${e.toLocaleString()} chars \u2014 ${s}% of original content]*`}export{m as headTailTruncate,A as paragraphTruncate};
@@ -1,61 +1 @@
1
- import { watch } from "node:fs";
2
- const watchers = /* @__PURE__ */ new Map();
3
- const DEFAULT_EXCLUDES = ["node_modules", ".git", "dist", ".turbo", ".kb-data", "cdk.out"];
4
- function watchStart(options) {
5
- const { path: watchPath, maxEvents = 100 } = options;
6
- const excludes = options.exclude ?? DEFAULT_EXCLUDES;
7
- const id = `watch-${Date.now()}`;
8
- const events = [];
9
- const shouldExclude = (filePath) => excludes.some((pattern) => normalizePath(filePath).includes(normalizePath(pattern)));
10
- const watcher = watch(watchPath, { recursive: true }, (eventType, filename) => {
11
- if (filename == null) return;
12
- const filePath = String(filename);
13
- if (!filePath || shouldExclude(filePath)) return;
14
- events.push({
15
- type: eventType,
16
- path: normalizePath(filePath),
17
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
18
- });
19
- if (events.length > maxEvents) events.shift();
20
- });
21
- const handle = {
22
- id,
23
- path: watchPath,
24
- events,
25
- status: "watching",
26
- stop: () => {
27
- watcher.close();
28
- handle.status = "stopped";
29
- watchers.delete(id);
30
- },
31
- getEvents: (since) => {
32
- if (!since) return events;
33
- return events.filter((event) => event.timestamp > since);
34
- }
35
- };
36
- watchers.set(id, { watcher, handle });
37
- return handle;
38
- }
39
- function watchStop(id) {
40
- const entry = watchers.get(id);
41
- if (!entry) return false;
42
- entry.handle.stop();
43
- return true;
44
- }
45
- function watchList() {
46
- return [...watchers.values()].map((entry) => ({
47
- id: entry.handle.id,
48
- path: entry.handle.path,
49
- status: entry.handle.status,
50
- eventCount: entry.handle.events.length
51
- }));
52
- }
53
- function normalizePath(value) {
54
- return value.replace(/\\/g, "/");
55
- }
56
- export {
57
- watchList,
58
- watchStart,
59
- watchStop
60
- };
61
- //# sourceMappingURL=watch.js.map
1
+ import{watch as g}from"node:fs";const r=new Map,m=["node_modules",".git","dist",".turbo",".kb-data","cdk.out"];function v(t){const{path:s,maxEvents:p=100}=t,d=t.exclude??m,c=`watch-${Date.now()}`,e=[],l=n=>d.some(a=>o(n).includes(o(a))),u=g(s,{recursive:!0},(n,a)=>{if(a==null)return;const h=String(a);!h||l(h)||(e.push({type:n,path:o(h),timestamp:new Date().toISOString()}),e.length>p&&e.shift())}),i={id:c,path:s,events:e,status:"watching",stop:()=>{u.close(),i.status="stopped",r.delete(c)},getEvents:n=>n?e.filter(a=>a.timestamp>n):e};return r.set(c,{watcher:u,handle:i}),i}function w(t){const s=r.get(t);return s?(s.handle.stop(),!0):!1}function x(){return[...r.values()].map(t=>({id:t.handle.id,path:t.handle.path,status:t.handle.status,eventCount:t.handle.events.length}))}function o(t){return t.replace(/\\/g,"/")}export{x as watchList,v as watchStart,w as watchStop};