@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,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(d=>{const g=N(d.text,n).map((s,o)=>{const l=K(s,r);for(const h of l)q(i,h,d.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:d.id,originalText:d.text,weight:_(d.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),d=e.filter(g=>g.nonPinnedChars>0);for(;i>b&&d.length>0;){const g=d.reduce((s,o)=>s+o.weight,0);let m=0;const f=[];for(const s of d){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,d=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:d=4e3,pinFields:g,segmentation:m="paragraph"}=n,f={},s=M(g),o=U(r,m,s,f),l=r.reduce((c,u)=>c+u.text.length,0);if(l<=d){const c=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(c),fields:f,sourceStats:u,totalOriginalChars:l,totalCompressedChars:l,ratio:l===0?0:1}}const h=await e.embedQuery(i);for(const c of o)for(const u of c.segments){if(u.pinnedFields.length>0)continue;const a=await e.embed(u.text);u.score=I(h,a)}const x=o.reduce((c,u)=>c+u.pinnedChars,0),w=j(o,d-x),T=[],y=[];let P=0;for(const c of o){const u=w.get(c.id)??0,a=new Map;let C=0;const v=c.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=c.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:c.id,originalChars:c.originalText.length,keptChars:D,segmentsKept:E.length,segmentsTotal:c.segments.length}),P+=D,E.length!==0&&y.push({id:c.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};