@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,130 +1,5 @@
1
- import { request } from "node:http";
2
- const DEFAULT_BASE_URL = "http://localhost:11434";
3
- const DEFAULT_TIMEOUT = 12e4;
4
- async function delegateListModels(baseUrl = DEFAULT_BASE_URL) {
5
- const body = await ollamaGet(`${baseUrl}/api/tags`);
6
- const parsed = JSON.parse(body);
7
- return (parsed.models ?? []).map((m) => m.name);
8
- }
9
- async function delegate(options) {
10
- const baseUrl = options.baseUrl ?? DEFAULT_BASE_URL;
11
- const timeout = options.timeout ?? DEFAULT_TIMEOUT;
12
- let models;
13
- try {
14
- models = await delegateListModels(baseUrl);
15
- } catch {
16
- return {
17
- model: options.model ?? "unknown",
18
- response: "",
19
- durationMs: 0,
20
- error: `Ollama is not running at ${baseUrl}. Start it with: ollama serve`
21
- };
22
- }
23
- if (models.length === 0) {
24
- return {
25
- model: "none",
26
- response: "",
27
- durationMs: 0,
28
- error: "No Ollama models available. Pull one with: ollama pull qwen2.5-coder:7b"
29
- };
30
- }
31
- const model = options.model ?? models[0];
32
- if (!models.includes(model)) {
33
- return {
34
- model,
35
- response: "",
36
- durationMs: 0,
37
- error: `Model "${model}" not found. Available: ${models.join(", ")}`
38
- };
39
- }
40
- let fullPrompt = "";
41
- if (options.context) {
42
- fullPrompt += `<context>
43
- ${options.context}
1
+ import{request as l}from"node:http";const c="http://localhost:11434",p=12e4;async function d(e=c){const o=await g(`${e}/api/tags`);return(JSON.parse(o).models??[]).map(r=>r.name)}async function w(e){const o=e.baseUrl??c,a=e.timeout??p;let r;try{r=await d(o)}catch{return{model:e.model??"unknown",response:"",durationMs:0,error:`Ollama is not running at ${o}. Start it with: ollama serve`}}if(r.length===0)return{model:"none",response:"",durationMs:0,error:"No Ollama models available. Pull one with: ollama pull qwen2.5-coder:7b"};const t=e.model??r[0];if(!r.includes(t))return{model:t,response:"",durationMs:0,error:`Model "${t}" not found. Available: ${r.join(", ")}`};let s="";e.context&&(s+=`<context>
2
+ ${e.context}
44
3
  </context>
45
4
 
46
- `;
47
- }
48
- fullPrompt += options.prompt;
49
- const start = Date.now();
50
- const payload = JSON.stringify({
51
- model,
52
- prompt: fullPrompt,
53
- system: options.system,
54
- stream: false,
55
- options: {
56
- temperature: options.temperature ?? 0.3
57
- }
58
- });
59
- try {
60
- const body = await ollamaPost(`${baseUrl}/api/generate`, payload, timeout);
61
- const parsed = JSON.parse(body);
62
- if (parsed.error) {
63
- return { model, response: "", durationMs: Date.now() - start, error: parsed.error };
64
- }
65
- return {
66
- model,
67
- response: (parsed.response ?? "").trim(),
68
- durationMs: Date.now() - start,
69
- tokenCount: parsed.eval_count
70
- };
71
- } catch (err) {
72
- return {
73
- model,
74
- response: "",
75
- durationMs: Date.now() - start,
76
- error: err instanceof Error ? err.message : String(err)
77
- };
78
- }
79
- }
80
- function ollamaGet(url) {
81
- return new Promise((resolve, reject) => {
82
- const u = new URL(url);
83
- const req = request(
84
- { hostname: u.hostname, port: u.port, path: u.pathname, method: "GET", timeout: 5e3 },
85
- (res) => {
86
- const chunks = [];
87
- res.on("data", (c) => chunks.push(c));
88
- res.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
89
- }
90
- );
91
- req.on("error", reject);
92
- req.on("timeout", () => {
93
- req.destroy();
94
- reject(new Error("Connection timeout"));
95
- });
96
- req.end();
97
- });
98
- }
99
- function ollamaPost(url, body, timeout) {
100
- return new Promise((resolve, reject) => {
101
- const u = new URL(url);
102
- const req = request(
103
- {
104
- hostname: u.hostname,
105
- port: u.port,
106
- path: u.pathname,
107
- method: "POST",
108
- headers: { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(body) },
109
- timeout
110
- },
111
- (res) => {
112
- const chunks = [];
113
- res.on("data", (c) => chunks.push(c));
114
- res.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
115
- }
116
- );
117
- req.on("error", reject);
118
- req.on("timeout", () => {
119
- req.destroy();
120
- reject(new Error(`Ollama request timed out after ${timeout}ms`));
121
- });
122
- req.write(body);
123
- req.end();
124
- });
125
- }
126
- export {
127
- delegate,
128
- delegateListModels
129
- };
130
- //# sourceMappingURL=delegate.js.map
5
+ `),s+=e.prompt;const n=Date.now(),u=JSON.stringify({model:t,prompt:s,system:e.system,stream:!1,options:{temperature:e.temperature??.3}});try{const i=await f(`${o}/api/generate`,u,a),m=JSON.parse(i);return m.error?{model:t,response:"",durationMs:Date.now()-n,error:m.error}:{model:t,response:(m.response??"").trim(),durationMs:Date.now()-n,tokenCount:m.eval_count}}catch(i){return{model:t,response:"",durationMs:Date.now()-n,error:i instanceof Error?i.message:String(i)}}}function g(e){return new Promise((o,a)=>{const r=new URL(e),t=l({hostname:r.hostname,port:r.port,path:r.pathname,method:"GET",timeout:5e3},s=>{const n=[];s.on("data",u=>n.push(u)),s.on("end",()=>o(Buffer.concat(n).toString("utf-8")))});t.on("error",a),t.on("timeout",()=>{t.destroy(),a(new Error("Connection timeout"))}),t.end()})}function f(e,o,a){return new Promise((r,t)=>{const s=new URL(e),n=l({hostname:s.hostname,port:s.port,path:s.pathname,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(o)},timeout:a},u=>{const i=[];u.on("data",m=>i.push(m)),u.on("end",()=>r(Buffer.concat(i).toString("utf-8")))});n.on("error",t),n.on("timeout",()=>{n.destroy(),t(new Error(`Ollama request timed out after ${a}ms`))}),n.write(o),n.end()})}export{w as delegate,d as delegateListModels};
@@ -1,153 +1,3 @@
1
- function diffParse(options) {
2
- const { diff } = options;
3
- const fileBlocks = diff.split(/^diff --git /m).filter(Boolean);
4
- if (fileBlocks.length > 0 && /^a\//.test(fileBlocks[0])) {
5
- return parseGitDiff(fileBlocks);
6
- }
7
- return parseUnifiedDiff(diff);
8
- }
9
- function parseGitDiff(fileBlocks) {
10
- const files = [];
11
- for (const block of fileBlocks) {
12
- const lines = block.split("\n");
13
- const headerMatch = lines[0]?.match(/a\/(.+?)\s+b\/(.+)/);
14
- if (!headerMatch) continue;
15
- const oldPath = headerMatch[1];
16
- const newPath = headerMatch[2];
17
- let status = "modified";
18
- if (block.includes("new file mode")) status = "added";
19
- else if (block.includes("deleted file mode")) status = "deleted";
20
- else if (oldPath !== newPath) status = "renamed";
21
- const hunks = [];
22
- let additions = 0;
23
- let deletions = 0;
24
- let currentHunk = null;
25
- let oldLine = 0;
26
- let newLine = 0;
27
- for (const line of lines) {
28
- const hunkMatch = line.match(/^@@\s+-(\d+)(?:,(\d+))?\s+\+(\d+)(?:,(\d+))?\s+@@(.*)$/);
29
- if (hunkMatch) {
30
- currentHunk = {
31
- oldStart: Number(hunkMatch[1]),
32
- oldLines: Number(hunkMatch[2] ?? 1),
33
- newStart: Number(hunkMatch[3]),
34
- newLines: Number(hunkMatch[4] ?? 1),
35
- header: hunkMatch[5]?.trim() ?? "",
36
- changes: []
37
- };
38
- hunks.push(currentHunk);
39
- oldLine = currentHunk.oldStart;
40
- newLine = currentHunk.newStart;
41
- continue;
42
- }
43
- if (!currentHunk || line.startsWith("\\")) continue;
44
- if (line.startsWith("+") && !line.startsWith("+++")) {
45
- currentHunk.changes.push({ type: "add", line: newLine, content: line.slice(1) });
46
- additions += 1;
47
- newLine += 1;
48
- continue;
49
- }
50
- if (line.startsWith("-") && !line.startsWith("---")) {
51
- currentHunk.changes.push({ type: "delete", line: oldLine, content: line.slice(1) });
52
- deletions += 1;
53
- oldLine += 1;
54
- continue;
55
- }
56
- if (line.startsWith(" ")) {
57
- currentHunk.changes.push({ type: "context", line: newLine, content: line.slice(1) });
58
- oldLine += 1;
59
- newLine += 1;
60
- }
61
- }
62
- files.push({
63
- path: newPath,
64
- oldPath: status === "renamed" ? oldPath : void 0,
65
- status,
66
- hunks,
67
- additions,
68
- deletions
69
- });
70
- }
71
- return files;
72
- }
73
- function parseUnifiedDiff(diff) {
74
- const files = [];
75
- const lines = diff.split("\n");
76
- let i = 0;
77
- while (i < lines.length) {
78
- const oldMatch = lines[i]?.match(/^---\s+(?:a\/)?(.+)/);
79
- const newMatch = lines[i + 1]?.match(/^\+\+\+\s+(?:b\/)?(.+)/);
80
- if (!oldMatch || !newMatch) {
81
- i++;
82
- continue;
83
- }
84
- const oldPath = oldMatch[1].trim();
85
- const newPath = newMatch[1].trim();
86
- let status = "modified";
87
- if (oldPath === "/dev/null") status = "added";
88
- else if (newPath === "/dev/null") status = "deleted";
89
- else if (oldPath !== newPath) status = "renamed";
90
- i += 2;
91
- const hunks = [];
92
- let additions = 0;
93
- let deletions = 0;
94
- while (i < lines.length && !lines[i]?.startsWith("--- ")) {
95
- const hunkMatch = lines[i]?.match(/^@@\s+-(\d+)(?:,(\d+))?\s+\+(\d+)(?:,(\d+))?\s+@@(.*)$/);
96
- if (hunkMatch) {
97
- const currentHunk = {
98
- oldStart: Number(hunkMatch[1]),
99
- oldLines: Number(hunkMatch[2] ?? 1),
100
- newStart: Number(hunkMatch[3]),
101
- newLines: Number(hunkMatch[4] ?? 1),
102
- header: hunkMatch[5]?.trim() ?? "",
103
- changes: []
104
- };
105
- hunks.push(currentHunk);
106
- let oldLine = currentHunk.oldStart;
107
- let newLine = currentHunk.newStart;
108
- i++;
109
- while (i < lines.length) {
110
- const line = lines[i];
111
- if (line?.startsWith("@@") || line?.startsWith("--- ") || line?.startsWith("diff "))
112
- break;
113
- if (line?.startsWith("\\")) {
114
- i++;
115
- continue;
116
- }
117
- if (line?.startsWith("+")) {
118
- currentHunk.changes.push({ type: "add", line: newLine, content: line.slice(1) });
119
- additions++;
120
- newLine++;
121
- } else if (line?.startsWith("-")) {
122
- currentHunk.changes.push({ type: "delete", line: oldLine, content: line.slice(1) });
123
- deletions++;
124
- oldLine++;
125
- } else if (line?.startsWith(" ")) {
126
- currentHunk.changes.push({ type: "context", line: newLine, content: line.slice(1) });
127
- oldLine++;
128
- newLine++;
129
- } else {
130
- break;
131
- }
132
- i++;
133
- }
134
- } else {
135
- i++;
136
- }
137
- }
138
- const effectivePath = status === "deleted" ? oldPath : newPath;
139
- files.push({
140
- path: effectivePath,
141
- oldPath: status === "renamed" ? oldPath : void 0,
142
- status,
143
- hunks,
144
- additions,
145
- deletions
146
- });
147
- }
148
- return files;
149
- }
150
- export {
151
- diffParse
152
- };
153
- //# sourceMappingURL=diff-parse.js.map
1
+ function w(u){const{diff:r}=u,n=r.split(/^diff --git /m).filter(Boolean);return n.length>0&&/^a\//.test(n[0])?D(n):k(r)}function D(u){const r=[];for(const n of u){const e=n.split(`
2
+ `),c=e[0]?.match(/a\/(.+?)\s+b\/(.+)/);if(!c)continue;const m=c[1],o=c[2];let a="modified";n.includes("new file mode")?a="added":n.includes("deleted file mode")?a="deleted":m!==o&&(a="renamed");const d=[];let p=0,g=0,s=null,h=0,i=0;for(const t of e){const l=t.match(/^@@\s+-(\d+)(?:,(\d+))?\s+\+(\d+)(?:,(\d+))?\s+@@(.*)$/);if(l){s={oldStart:Number(l[1]),oldLines:Number(l[2]??1),newStart:Number(l[3]),newLines:Number(l[4]??1),header:l[5]?.trim()??"",changes:[]},d.push(s),h=s.oldStart,i=s.newStart;continue}if(!(!s||t.startsWith("\\"))){if(t.startsWith("+")&&!t.startsWith("+++")){s.changes.push({type:"add",line:i,content:t.slice(1)}),p+=1,i+=1;continue}if(t.startsWith("-")&&!t.startsWith("---")){s.changes.push({type:"delete",line:h,content:t.slice(1)}),g+=1,h+=1;continue}t.startsWith(" ")&&(s.changes.push({type:"context",line:i,content:t.slice(1)}),h+=1,i+=1)}}r.push({path:o,oldPath:a==="renamed"?m:void 0,status:a,hunks:d,additions:p,deletions:g})}return r}function k(u){const r=[],n=u.split(`
3
+ `);let e=0;for(;e<n.length;){const c=n[e]?.match(/^---\s+(?:a\/)?(.+)/),m=n[e+1]?.match(/^\+\+\+\s+(?:b\/)?(.+)/);if(!c||!m){e++;continue}const o=c[1].trim(),a=m[1].trim();let d="modified";o==="/dev/null"?d="added":a==="/dev/null"?d="deleted":o!==a&&(d="renamed"),e+=2;const p=[];let g=0,s=0;for(;e<n.length&&!n[e]?.startsWith("--- ");){const i=n[e]?.match(/^@@\s+-(\d+)(?:,(\d+))?\s+\+(\d+)(?:,(\d+))?\s+@@(.*)$/);if(i){const t={oldStart:Number(i[1]),oldLines:Number(i[2]??1),newStart:Number(i[3]),newLines:Number(i[4]??1),header:i[5]?.trim()??"",changes:[]};p.push(t);let l=t.oldStart,b=t.newStart;for(e++;e<n.length;){const f=n[e];if(f?.startsWith("@@")||f?.startsWith("--- ")||f?.startsWith("diff "))break;if(f?.startsWith("\\")){e++;continue}if(f?.startsWith("+"))t.changes.push({type:"add",line:b,content:f.slice(1)}),g++,b++;else if(f?.startsWith("-"))t.changes.push({type:"delete",line:l,content:f.slice(1)}),s++,l++;else if(f?.startsWith(" "))t.changes.push({type:"context",line:b,content:f.slice(1)}),l++,b++;else break;e++}}else e++}const h=d==="deleted"?o:a;r.push({path:h,oldPath:d==="renamed"?o:void 0,status:d,hunks:p,additions:g,deletions:s})}return r}export{w as diffParse};
@@ -1,242 +1,7 @@
1
- import { cosineSimilarity, estimateTokens, segment } from "./text-utils.js";
2
- const DEFAULT_PIN_FIELDS = [
3
- "status",
4
- "files",
5
- "decisions",
6
- "blockers",
7
- "artifacts",
8
- "next"
9
- ];
10
- const PIN_PATTERNS = {
11
- status: /\b(?:status|result)\s*[:=]/i,
12
- files: /\b(?:files?|modified|created|deleted)\s*[:=]/i,
13
- artifacts: /\b(?:artifacts?)\s*[:=]/i,
14
- decisions: /\b(?:decisions?|decided|chose|selected)\s*[:=]/i,
15
- blockers: /\b(?:blockers?|blocked|blocking)\s*[:=]/i,
16
- next: /\b(?:next\s*(?:steps?|actions?)|todo|follow.up)\s*[:=]/i
17
- };
18
- const VALUE_PATTERNS = {
19
- status: /(?:^|\b)(?:status|result)\s*[:=]\s*(.+)$/i,
20
- files: /(?:^|\b)(?:files?|modified|created|deleted)\s*[:=]\s*(.+)$/i,
21
- artifacts: /(?:^|\b)(?:artifacts?)\s*[:=]\s*(.+)$/i,
22
- decisions: /(?:^|\b)(?:decisions?|decided|chose|selected)\s*[:=]\s*(.+)$/i,
23
- blockers: /(?:^|\b)(?:blockers?|blocked|blocking)\s*[:=]\s*(.+)$/i,
24
- next: /(?:^|\b)(?:next\s*(?:steps?|actions?)|todo|follow.up)\s*[:=]\s*(.+)$/i
25
- };
26
- const STATUS_MARKERS = /\b(?:APPROVED|NEEDS_REVISION|BLOCKED|SUCCESS|PARTIAL|FAILED|ESCALATE)\b/i;
27
- const EPSILON = 0.01;
28
- function normalizePinFields(pinFields) {
29
- const requested = pinFields ?? [...DEFAULT_PIN_FIELDS];
30
- return [...new Set(requested.map((field) => field.toLowerCase()))];
31
- }
32
- function resolveWeight(weight) {
33
- if (typeof weight !== "number" || !Number.isFinite(weight) || weight <= 0) {
34
- return 1;
35
- }
36
- return weight;
37
- }
38
- function findPinnedFields(text, pinFields) {
39
- const matched = /* @__PURE__ */ new Set();
40
- for (const field of pinFields) {
41
- const pattern = PIN_PATTERNS[field];
42
- if (pattern?.test(text)) {
43
- matched.add(field);
44
- }
45
- }
46
- if (pinFields.includes("status") && STATUS_MARKERS.test(text)) {
47
- matched.add("status");
48
- }
49
- return [...matched];
50
- }
51
- function extractFieldValue(field, text) {
52
- const lines = text.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
53
- for (const line of lines) {
54
- const pattern = VALUE_PATTERNS[field];
55
- const match = pattern?.exec(line);
56
- if (match?.[1]) {
57
- return match[1].trim();
58
- }
59
- if (field === "status") {
60
- const marker = line.match(STATUS_MARKERS);
61
- if (marker) {
62
- return marker[0];
63
- }
64
- }
65
- }
66
- return text.trim();
67
- }
68
- function addFieldEntry(fields, field, sourceId, value) {
69
- if (!fields[field]) {
70
- fields[field] = [];
71
- }
72
- fields[field].push({ sourceId, value });
73
- }
74
- function prepareSources(sources, strategy, pinFields, fields) {
75
- return sources.map((source) => {
76
- const segments = segment(source.text, strategy).map((text, index) => {
77
- const pinnedFields = findPinnedFields(text, pinFields);
78
- for (const field of pinnedFields) {
79
- addFieldEntry(fields, field, source.id, extractFieldValue(field, text));
80
- }
81
- return {
82
- index,
83
- text,
84
- pinnedFields,
85
- score: 0
86
- };
87
- });
88
- const pinnedChars = segments.filter((segment2) => segment2.pinnedFields.length > 0).reduce((total, segment2) => total + segment2.text.length, 0);
89
- const nonPinnedChars = segments.filter((segment2) => segment2.pinnedFields.length === 0).reduce((total, segment2) => total + segment2.text.length, 0);
90
- return {
91
- id: source.id,
92
- originalText: source.text,
93
- weight: resolveWeight(source.weight),
94
- segments,
95
- pinnedChars,
96
- nonPinnedChars
97
- };
98
- });
99
- }
100
- function allocateBudgets(sources, remainingChars) {
101
- const budgets = new Map(sources.map((source) => [source.id, 0]));
102
- let budgetLeft = Math.max(0, remainingChars);
103
- let active = sources.filter((source) => source.nonPinnedChars > 0);
104
- while (budgetLeft > EPSILON && active.length > 0) {
105
- const totalWeight = active.reduce((sum, source) => sum + source.weight, 0);
106
- let allocatedThisRound = 0;
107
- const nextActive = [];
108
- for (const source of active) {
109
- const alreadyAllocated = budgets.get(source.id) ?? 0;
110
- const remainingCapacity = source.nonPinnedChars - alreadyAllocated;
111
- if (remainingCapacity <= EPSILON) {
112
- continue;
113
- }
114
- const share = budgetLeft * (source.weight / totalWeight);
115
- const allocation = Math.min(share, remainingCapacity);
116
- budgets.set(source.id, alreadyAllocated + allocation);
117
- allocatedThisRound += allocation;
118
- if (remainingCapacity - allocation > EPSILON) {
119
- nextActive.push(source);
120
- }
121
- }
122
- if (allocatedThisRound <= EPSILON) {
123
- break;
124
- }
125
- budgetLeft -= allocatedThisRound;
126
- active = nextActive;
127
- }
128
- return budgets;
129
- }
130
- function formatDigestText(blocks) {
131
- return blocks.map((block) => `[${block.id}]
132
- ${block.text}`).join("\n\n");
133
- }
134
- function ratio(originalChars, compressedChars) {
135
- if (originalChars === 0) {
136
- return 0;
137
- }
138
- return compressedChars / originalChars;
139
- }
140
- async function digest(embedder, options) {
141
- const { sources, query, maxChars = 4e3, pinFields, segmentation = "paragraph" } = options;
142
- const fields = {};
143
- const effectivePinFields = normalizePinFields(pinFields);
144
- const preparedSources = prepareSources(sources, segmentation, effectivePinFields, fields);
145
- const totalOriginalChars = sources.reduce((total, source) => total + source.text.length, 0);
146
- if (totalOriginalChars <= maxChars) {
147
- const blocks2 = preparedSources.filter((source) => source.originalText.trim().length > 0).map((source) => ({ id: source.id, text: source.originalText }));
148
- const sourceStats2 = preparedSources.map((source) => ({
149
- id: source.id,
150
- originalChars: source.originalText.length,
151
- keptChars: source.originalText.length,
152
- segmentsKept: source.segments.length,
153
- segmentsTotal: source.segments.length
154
- }));
155
- return {
156
- text: formatDigestText(blocks2),
157
- fields,
158
- sourceStats: sourceStats2,
159
- totalOriginalChars,
160
- totalCompressedChars: totalOriginalChars,
161
- ratio: totalOriginalChars === 0 ? 0 : 1
162
- };
163
- }
164
- const queryVector = await embedder.embedQuery(query);
165
- for (const source of preparedSources) {
166
- for (const segment2 of source.segments) {
167
- if (segment2.pinnedFields.length > 0) {
168
- continue;
169
- }
170
- const vector = await embedder.embed(segment2.text);
171
- segment2.score = cosineSimilarity(queryVector, vector);
172
- }
173
- }
174
- const reservedChars = preparedSources.reduce((total, source) => total + source.pinnedChars, 0);
175
- const budgets = allocateBudgets(preparedSources, maxChars - reservedChars);
176
- const sourceStats = [];
177
- const blocks = [];
178
- let totalCompressedChars = 0;
179
- for (const source of preparedSources) {
180
- const budget = budgets.get(source.id) ?? 0;
181
- const selectedTexts = /* @__PURE__ */ new Map();
182
- let selectedNonPinnedChars = 0;
183
- const rankedSegments = source.segments.filter((segment2) => segment2.pinnedFields.length === 0).sort(
184
- (left, right) => right.score - left.score || estimateTokens(left.text) - estimateTokens(right.text) || left.index - right.index
185
- );
186
- let overflowCandidate;
187
- for (const segment2 of rankedSegments) {
188
- const available = budget - selectedNonPinnedChars;
189
- if (available <= EPSILON) {
190
- break;
191
- }
192
- if (segment2.text.length <= available + EPSILON) {
193
- selectedTexts.set(segment2.index, segment2.text);
194
- selectedNonPinnedChars += segment2.text.length;
195
- continue;
196
- }
197
- if (!overflowCandidate) {
198
- overflowCandidate = segment2;
199
- }
200
- }
201
- const leftover = Math.floor(budget - selectedNonPinnedChars);
202
- if (overflowCandidate && leftover > 0) {
203
- const truncated = overflowCandidate.text.slice(0, leftover).trimEnd();
204
- if (truncated.length > 0) {
205
- selectedTexts.set(overflowCandidate.index, truncated);
206
- selectedNonPinnedChars += truncated.length;
207
- }
208
- }
209
- const keptSegments = source.segments.filter((segment2) => segment2.pinnedFields.length > 0 || selectedTexts.has(segment2.index)).map((segment2) => ({
210
- index: segment2.index,
211
- text: selectedTexts.get(segment2.index) ?? segment2.text
212
- }));
213
- const keptChars = keptSegments.reduce((total, segment2) => total + segment2.text.length, 0);
214
- sourceStats.push({
215
- id: source.id,
216
- originalChars: source.originalText.length,
217
- keptChars,
218
- segmentsKept: keptSegments.length,
219
- segmentsTotal: source.segments.length
220
- });
221
- totalCompressedChars += keptChars;
222
- if (keptSegments.length === 0) {
223
- continue;
224
- }
225
- blocks.push({
226
- id: source.id,
227
- text: keptSegments.map((segment2) => segment2.text).join("\n\n")
228
- });
229
- }
230
- return {
231
- text: formatDigestText(blocks),
232
- fields,
233
- sourceStats,
234
- totalOriginalChars,
235
- totalCompressedChars,
236
- ratio: ratio(totalOriginalChars, totalCompressedChars)
237
- };
238
- }
239
- export {
240
- digest
241
- };
242
- //# sourceMappingURL=digest.js.map
1
+ import{cosineSimilarity as I,estimateTokens as k,segment as N}from"./text-utils.js";const L=["status","files","decisions","blockers","artifacts","next"],O={status:/\b(?:status|result)\s*[:=]/i,files:/\b(?:files?|modified|created|deleted)\s*[:=]/i,artifacts:/\b(?:artifacts?)\s*[:=]/i,decisions:/\b(?:decisions?|decided|chose|selected)\s*[:=]/i,blockers:/\b(?:blockers?|blocked|blocking)\s*[:=]/i,next:/\b(?:next\s*(?:steps?|actions?)|todo|follow.up)\s*[:=]/i},$={status:/(?:^|\b)(?:status|result)\s*[:=]\s*(.+)$/i,files:/(?:^|\b)(?:files?|modified|created|deleted)\s*[:=]\s*(.+)$/i,artifacts:/(?:^|\b)(?:artifacts?)\s*[:=]\s*(.+)$/i,decisions:/(?:^|\b)(?:decisions?|decided|chose|selected)\s*[:=]\s*(.+)$/i,blockers:/(?:^|\b)(?:blockers?|blocked|blocking)\s*[:=]\s*(.+)$/i,next:/(?:^|\b)(?:next\s*(?:steps?|actions?)|todo|follow.up)\s*[:=]\s*(.+)$/i},R=/\b(?:APPROVED|NEEDS_REVISION|BLOCKED|SUCCESS|PARTIAL|FAILED|ESCALATE)\b/i,b=.01;function M(e){const n=e??[...L];return[...new Set(n.map(r=>r.toLowerCase()))]}function _(e){return typeof e!="number"||!Number.isFinite(e)||e<=0?1:e}function K(e,n){const r=new Set;for(const i of n)O[i]?.test(e)&&r.add(i);return n.includes("status")&&R.test(e)&&r.add("status"),[...r]}function V(e,n){const r=n.split(`
2
+ `).map(i=>i.trim()).filter(i=>i.length>0);for(const i of r){const g=$[e]?.exec(i);if(g?.[1])return g[1].trim();if(e==="status"){const m=i.match(R);if(m)return m[0]}}return n.trim()}function q(e,n,r,i){e[n]||(e[n]=[]),e[n].push({sourceId:r,value:i})}function U(e,n,r,i){return e.map(c=>{const g=N(c.text,n).map((s,o)=>{const l=K(s,r);for(const h of l)q(i,h,c.id,V(h,s));return{index:o,text:s,pinnedFields:l,score:0}}),m=g.filter(s=>s.pinnedFields.length>0).reduce((s,o)=>s+o.text.length,0),f=g.filter(s=>s.pinnedFields.length===0).reduce((s,o)=>s+o.text.length,0);return{id:c.id,originalText:c.text,weight:_(c.weight),segments:g,pinnedChars:m,nonPinnedChars:f}})}function j(e,n){const r=new Map(e.map(g=>[g.id,0]));let i=Math.max(0,n),c=e.filter(g=>g.nonPinnedChars>0);for(;i>b&&c.length>0;){const g=c.reduce((s,o)=>s+o.weight,0);let m=0;const f=[];for(const s of c){const o=r.get(s.id)??0,l=s.nonPinnedChars-o;if(l<=b)continue;const h=i*(s.weight/g),x=Math.min(h,l);r.set(s.id,o+x),m+=x,l-x>b&&f.push(s)}if(m<=b)break;i-=m,c=f}return r}function A(e){return e.map(n=>`[${n.id}]
3
+ ${n.text}`).join(`
4
+
5
+ `)}function B(e,n){return e===0?0:n/e}async function z(e,n){const{sources:r,query:i,maxChars:c=4e3,pinFields:g,segmentation:m="paragraph"}=n,f={},s=M(g),o=U(r,m,s,f),l=r.reduce((d,u)=>d+u.text.length,0);if(l<=c){const d=o.filter(a=>a.originalText.trim().length>0).map(a=>({id:a.id,text:a.originalText})),u=o.map(a=>({id:a.id,originalChars:a.originalText.length,keptChars:a.originalText.length,segmentsKept:a.segments.length,segmentsTotal:a.segments.length}));return{text:A(d),fields:f,sourceStats:u,totalOriginalChars:l,totalCompressedChars:l,ratio:l===0?0:1}}const h=await e.embedQuery(i);for(const d of o)for(const u of d.segments){if(u.pinnedFields.length>0)continue;const a=await e.embed(u.text);u.score=I(h,a)}const x=o.reduce((d,u)=>d+u.pinnedChars,0),w=j(o,c-x),T=[],y=[];let P=0;for(const d of o){const u=w.get(d.id)??0,a=new Map;let C=0;const v=d.segments.filter(t=>t.pinnedFields.length===0).sort((t,p)=>p.score-t.score||k(t.text)-k(p.text)||t.index-p.index);let S;for(const t of v){const p=u-C;if(p<=b)break;if(t.text.length<=p+b){a.set(t.index,t.text),C+=t.text.length;continue}S||(S=t)}const F=Math.floor(u-C);if(S&&F>0){const t=S.text.slice(0,F).trimEnd();t.length>0&&(a.set(S.index,t),C+=t.length)}const E=d.segments.filter(t=>t.pinnedFields.length>0||a.has(t.index)).map(t=>({index:t.index,text:a.get(t.index)??t.text})),D=E.reduce((t,p)=>t+p.text.length,0);T.push({id:d.id,originalChars:d.originalText.length,keptChars:D,segmentsKept:E.length,segmentsTotal:d.segments.length}),P+=D,E.length!==0&&y.push({id:d.id,text:E.map(t=>t.text).join(`
6
+
7
+ `)})}return{text:A(y),fields:f,sourceStats:T,totalOriginalChars:l,totalCompressedChars:P,ratio:B(l,P)}}export{z as digest};
@@ -1,46 +1 @@
1
- import { createHash } from "node:crypto";
2
- function encode(options) {
3
- const { operation, input } = options;
4
- let output;
5
- switch (operation) {
6
- case "base64_encode":
7
- output = Buffer.from(input).toString("base64");
8
- break;
9
- case "base64_decode":
10
- output = Buffer.from(input, "base64").toString("utf8");
11
- break;
12
- case "url_encode":
13
- output = encodeURIComponent(input);
14
- break;
15
- case "url_decode":
16
- output = decodeURIComponent(input);
17
- break;
18
- case "sha256":
19
- output = createHash("sha256").update(input).digest("hex");
20
- break;
21
- case "md5":
22
- output = createHash("md5").update(input).digest("hex");
23
- break;
24
- case "jwt_decode": {
25
- const parts = input.split(".");
26
- if (parts.length !== 3) throw new Error("Invalid JWT: expected 3 dot-separated parts");
27
- const header = JSON.parse(Buffer.from(parts[0], "base64url").toString());
28
- const payload = JSON.parse(Buffer.from(parts[1], "base64url").toString());
29
- output = JSON.stringify({ header, payload }, null, 2);
30
- break;
31
- }
32
- case "hex_encode":
33
- output = Buffer.from(input).toString("hex");
34
- break;
35
- case "hex_decode":
36
- output = Buffer.from(input, "hex").toString("utf8");
37
- break;
38
- default:
39
- throw new Error(`Unknown operation: ${operation}`);
40
- }
41
- return { output, operation };
42
- }
43
- export {
44
- encode
45
- };
46
- //# sourceMappingURL=encode.js.map
1
+ import{createHash as n}from"node:crypto";function i(a){const{operation:t,input:o}=a;let e;switch(t){case"base64_encode":e=Buffer.from(o).toString("base64");break;case"base64_decode":e=Buffer.from(o,"base64").toString("utf8");break;case"url_encode":e=encodeURIComponent(o);break;case"url_decode":e=decodeURIComponent(o);break;case"sha256":e=n("sha256").update(o).digest("hex");break;case"md5":e=n("md5").update(o).digest("hex");break;case"jwt_decode":{const r=o.split(".");if(r.length!==3)throw new Error("Invalid JWT: expected 3 dot-separated parts");const d=JSON.parse(Buffer.from(r[0],"base64url").toString()),s=JSON.parse(Buffer.from(r[1],"base64url").toString());e=JSON.stringify({header:d,payload:s},null,2);break}case"hex_encode":e=Buffer.from(o).toString("hex");break;case"hex_decode":e=Buffer.from(o,"hex").toString("utf8");break;default:throw new Error(`Unknown operation: ${t}`)}return{output:e,operation:t}}export{i as encode};
@@ -1,58 +1 @@
1
- import {
2
- arch,
3
- cpus,
4
- freemem,
5
- hostname,
6
- type as osType,
7
- platform,
8
- release,
9
- totalmem
10
- } from "node:os";
11
- const SENSITIVE_PATTERNS = [
12
- /key/i,
13
- /secret/i,
14
- /token/i,
15
- /password/i,
16
- /passwd/i,
17
- /credential/i,
18
- /private/i,
19
- /certificate/i
20
- ];
21
- function envInfo(options = {}) {
22
- const { includeEnv = false, filterEnv, showSensitive = false } = options;
23
- const result = {
24
- system: {
25
- platform: platform(),
26
- arch: arch(),
27
- release: release(),
28
- hostname: hostname(),
29
- type: osType(),
30
- cpus: cpus().length,
31
- memoryTotalGb: Math.round(totalmem() / 1024 ** 3 * 10) / 10,
32
- memoryFreeGb: Math.round(freemem() / 1024 ** 3 * 10) / 10
33
- },
34
- runtime: {
35
- node: process.versions.node,
36
- v8: process.versions.v8
37
- },
38
- cwd: process.cwd()
39
- };
40
- if (includeEnv) {
41
- const env = {};
42
- for (const [key, value] of Object.entries(process.env)) {
43
- if (!value) continue;
44
- if (filterEnv && !key.toLowerCase().includes(filterEnv.toLowerCase())) continue;
45
- if (!showSensitive && SENSITIVE_PATTERNS.some((p) => p.test(key))) {
46
- env[key] = "[REDACTED]";
47
- } else {
48
- env[key] = value;
49
- }
50
- }
51
- result.env = env;
52
- }
53
- return result;
54
- }
55
- export {
56
- envInfo
57
- };
58
- //# sourceMappingURL=env-info.js.map
1
+ import{arch as m,cpus as l,freemem as f,hostname as p,type as v,platform as u,release as d,totalmem as g}from"node:os";const E=[/key/i,/secret/i,/token/i,/password/i,/passwd/i,/credential/i,/private/i,/certificate/i];function h(o={}){const{includeEnv:i=!1,filterEnv:t,showSensitive:c=!1}=o,s={system:{platform:u(),arch:m(),release:d(),hostname:p(),type:v(),cpus:l().length,memoryTotalGb:Math.round(g()/1024**3*10)/10,memoryFreeGb:Math.round(f()/1024**3*10)/10},runtime:{node:process.versions.node,v8:process.versions.v8},cwd:process.cwd()};if(i){const n={};for(const[e,r]of Object.entries(process.env))r&&(t&&!e.toLowerCase().includes(t.toLowerCase())||(!c&&E.some(a=>a.test(e))?n[e]="[REDACTED]":n[e]=r));s.env=n}return s}export{h as envInfo};