@wrongstack/tools 0.318.0 → 0.319.1
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.
- package/dist/_edit-match.d.ts +1 -3
- package/dist/_util.d.ts +20 -0
- package/dist/audit.js +4 -4
- package/dist/bash.js +2 -2
- package/dist/builtin.d.ts +10 -0
- package/dist/builtin.js +46 -44
- package/dist/{chunk-TKA4VEX2.js → chunk-2OXHS3KZ.js} +17 -5
- package/dist/{chunk-X5K3U6GI.js → chunk-3M7LLN7W.js} +71 -7
- package/dist/{chunk-4AEZIFOW.js → chunk-5EUJF3WC.js} +36 -8
- package/dist/{chunk-CVALEVGA.js → chunk-64VIJPFV.js} +34 -13
- package/dist/{chunk-ZE6KLBUO.js → chunk-6AAOT4PW.js} +58 -10
- package/dist/{chunk-A6BRWIXN.js → chunk-6IEBD27U.js} +20 -5
- package/dist/{chunk-HTYEO67J.js → chunk-AKHYMB4V.js} +36 -12
- package/dist/{chunk-4E42D7UF.js → chunk-ATSKPZUK.js} +2 -2
- package/dist/{chunk-H6AWAZ2Y.js → chunk-B4HTSV6Z.js} +57 -6
- package/dist/{chunk-5ZYEGP2P.js → chunk-BK732J7I.js} +72 -27
- package/dist/{chunk-WI3VDXHD.js → chunk-BSJSNVGA.js} +108 -19
- package/dist/{chunk-UKGMDCXT.js → chunk-C2DQKVLO.js} +61 -28
- package/dist/{chunk-CIFAIIHI.js → chunk-CFLJFDYV.js} +100 -58
- package/dist/{chunk-JJQB6R7Y.js → chunk-CMOUCKGC.js} +6 -6
- package/dist/{chunk-MX25MTDJ.js → chunk-DC4KMPJO.js} +2 -2
- package/dist/{chunk-VZLX2JZG.js → chunk-DP6CXMJZ.js} +3 -3
- package/dist/{chunk-3QQSBUXR.js → chunk-EADULOZV.js} +36 -12
- package/dist/{chunk-6RNIFLG4.js → chunk-ELRRTWNP.js} +38 -6
- package/dist/{chunk-CPSAF2AU.js → chunk-FQNXYA6W.js} +45 -6
- package/dist/{chunk-ZZT45EHF.js → chunk-GMZYW52L.js} +3 -3
- package/dist/{chunk-ZLTFLC25.js → chunk-IIF5HIVF.js} +2 -2
- package/dist/{chunk-EMRGN4KM.js → chunk-IU4DV2PA.js} +18 -8
- package/dist/{chunk-AGUSOFNI.js → chunk-IWS56OY7.js} +30 -7
- package/dist/{chunk-MRZOVQ5D.js → chunk-IYKXK356.js} +98 -11
- package/dist/{chunk-6GZPSWP3.js → chunk-JDPQOR7C.js} +14 -7
- package/dist/{chunk-BLCSYKNN.js → chunk-KY4PXYSO.js} +10 -15
- package/dist/{chunk-WJYXMB2R.js → chunk-LOBRWKCR.js} +63 -14
- package/dist/{chunk-J5SKD6LN.js → chunk-MNP3GE7H.js} +38 -27
- package/dist/{chunk-S2GBLQ5S.js → chunk-O44IMQCN.js} +31 -7
- package/dist/{chunk-P7ZQ2FAJ.js → chunk-OG2BEUBY.js} +69 -34
- package/dist/{chunk-K23JNFE3.js → chunk-OTINMOKK.js} +233 -45
- package/dist/{chunk-PQTONQ4P.js → chunk-QPNYDH5B.js} +19 -5
- package/dist/{chunk-UE3UBMCP.js → chunk-RLMX75EM.js} +19 -8
- package/dist/{chunk-3U4H6ZRF.js → chunk-RNWUCZ2U.js} +53 -25
- package/dist/{chunk-YF3D5INN.js → chunk-RTZWBNTY.js} +121 -91
- package/dist/{chunk-SOG7XIRF.js → chunk-TTZOK6IY.js} +2 -2
- package/dist/{chunk-6GVXZCQV.js → chunk-UDVKRX5R.js} +2 -2
- package/dist/{chunk-CPVLVQYT.js → chunk-UQQS3VNT.js} +43 -9
- package/dist/{chunk-VB3MJGCV.js → chunk-VD2LV5WO.js} +82 -13
- package/dist/{chunk-5WNDJHT6.js → chunk-VPALDFYM.js} +2 -2
- package/dist/{chunk-FJEQZHZN.js → chunk-W2CECGTG.js} +24 -14
- package/dist/{chunk-CISOLTOP.js → chunk-X5FOFGXX.js} +72 -33
- package/dist/{chunk-CWALNI6K.js → chunk-X6KXNHUO.js} +1 -1
- package/dist/{chunk-EEOFQDT6.js → chunk-XRNN44QY.js} +46 -2
- package/dist/{chunk-EOOFNYIT.js → chunk-YOKD4GWJ.js} +67 -27
- package/dist/{chunk-D33S4RQG.js → chunk-ZUFHAHTE.js} +18 -6
- package/dist/codebase-index/generic-parser.d.ts +8 -1
- package/dist/codebase-index/index.js +9 -9
- package/dist/codebase-index/parser-worker-script.js +3 -3
- package/dist/codebase-index/project-server.js +5 -5
- package/dist/codebase-index/worker.js +4 -4
- package/dist/codebase-index/writer-refs.d.ts +1 -1
- package/dist/design.d.ts +1 -1
- package/dist/design.js +1 -1
- package/dist/diff.js +3 -2
- package/dist/document.js +2 -2
- package/dist/e2e.js +2 -2
- package/dist/edit.js +8 -8
- package/dist/exec.js +2 -2
- package/dist/fetch.js +2 -2
- package/dist/format.js +4 -4
- package/dist/{generic-parser-VUXDIAOZ.js → generic-parser-WFMIRHBX.js} +2 -2
- package/dist/git.js +2 -2
- package/dist/glob.js +2 -2
- package/dist/grep.d.ts +2 -0
- package/dist/grep.js +4 -2
- package/dist/index.js +46 -46
- package/dist/install.js +4 -4
- package/dist/json.js +2 -2
- package/dist/kanban-tool-types.d.ts +2 -0
- package/dist/kanban.js +2 -2
- package/dist/languages/index.js +2 -2
- package/dist/{legacy-bridge-SFNXIRAP.js → legacy-bridge-3T7SR4SK.js} +4 -4
- package/dist/lint.js +4 -4
- package/dist/logs.js +2 -2
- package/dist/outdated.js +4 -2
- package/dist/pack.js +45 -45
- package/dist/{parser-dispatch-X62UWXJS.js → parser-dispatch-QGC4HSP5.js} +4 -4
- package/dist/patch.js +8 -8
- package/dist/plan.js +4 -4
- package/dist/{py-parser-TDXSQZBC.js → py-parser-RFWG2HYI.js} +3 -3
- package/dist/read.js +8 -8
- package/dist/replace.js +9 -8
- package/dist/scaffold.js +2 -2
- package/dist/search.js +1 -1
- package/dist/session-kanban.js +1 -1
- package/dist/task.js +4 -4
- package/dist/test.js +4 -4
- package/dist/todo.js +3 -3
- package/dist/tool-tier.js +46 -46
- package/dist/{tree-sitter-parser-AIERW3YI.js → tree-sitter-parser-GILYQLS4.js} +2 -2
- package/dist/tree.js +2 -2
- package/dist/typecheck.js +4 -4
- package/dist/write.js +8 -8
- package/package.json +5 -5
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getProcessRegistry,
|
|
3
|
+
redactCommand
|
|
4
|
+
} from "./chunk-3PVYQFRQ.js";
|
|
1
5
|
import {
|
|
2
6
|
buildWin32CmdShimInvocation,
|
|
3
7
|
resolveWin32Command
|
|
@@ -7,10 +11,12 @@ import {
|
|
|
7
11
|
detectPackageManager,
|
|
8
12
|
normalizeCommandOutput,
|
|
9
13
|
safeResolveReal
|
|
10
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-ZUFHAHTE.js";
|
|
11
15
|
|
|
12
16
|
// src/outdated.ts
|
|
13
17
|
import { spawn } from "node:child_process";
|
|
18
|
+
import { StringDecoder } from "node:string_decoder";
|
|
19
|
+
import { ToolValidationError } from "@wrongstack/core/types";
|
|
14
20
|
import { buildChildEnv } from "@wrongstack/core/utils";
|
|
15
21
|
var outdatedTool = {
|
|
16
22
|
name: "outdated",
|
|
@@ -48,12 +54,19 @@ var outdatedTool = {
|
|
|
48
54
|
}
|
|
49
55
|
},
|
|
50
56
|
async execute(input, ctx, opts) {
|
|
57
|
+
if (input.cwd !== void 0 && (typeof input.cwd !== "string" || !input.cwd.trim())) {
|
|
58
|
+
throw new ToolValidationError({
|
|
59
|
+
message: "outdated: cwd must be a non-empty string when provided.",
|
|
60
|
+
field: "cwd"
|
|
61
|
+
});
|
|
62
|
+
}
|
|
51
63
|
const cwd = input.cwd ? await safeResolveReal(input.cwd, ctx) : ctx.cwd;
|
|
52
64
|
const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
|
|
65
|
+
signal.throwIfAborted();
|
|
53
66
|
const manager = await detectPackageManager(cwd, ctx.projectRoot);
|
|
54
67
|
if (manager === "npm") {
|
|
55
68
|
try {
|
|
56
|
-
const { detectNonJsEcosystem } = await import("./legacy-bridge-
|
|
69
|
+
const { detectNonJsEcosystem } = await import("./legacy-bridge-3T7SR4SK.js");
|
|
57
70
|
const nonJs = await detectNonJsEcosystem(cwd, ctx.projectRoot);
|
|
58
71
|
if (nonJs) {
|
|
59
72
|
const { planLanguageOperation, executePackagePlan } = await import("./languages/index.js");
|
|
@@ -107,10 +120,23 @@ var outdatedTool = {
|
|
|
107
120
|
}
|
|
108
121
|
};
|
|
109
122
|
function runOutdated(manager, args, cwd, signal) {
|
|
123
|
+
if (signal.aborted) {
|
|
124
|
+
return Promise.resolve({
|
|
125
|
+
exit_code: 124,
|
|
126
|
+
packages: [],
|
|
127
|
+
total: 0,
|
|
128
|
+
output: "Aborted",
|
|
129
|
+
truncated: false
|
|
130
|
+
});
|
|
131
|
+
}
|
|
110
132
|
return new Promise((resolve) => {
|
|
111
133
|
let stdout = "";
|
|
112
134
|
let stderr = "";
|
|
135
|
+
let stdoutBytes = 0;
|
|
136
|
+
let stderrBytes = 0;
|
|
113
137
|
const MAX = 1e5;
|
|
138
|
+
const stdoutDecoder = new StringDecoder("utf8");
|
|
139
|
+
const stderrDecoder = new StringDecoder("utf8");
|
|
114
140
|
const resolved = resolveWin32Command(manager);
|
|
115
141
|
const needsShell = process.platform === "win32" && (resolved.endsWith(".cmd") || resolved.endsWith(".bat"));
|
|
116
142
|
const shim = needsShell ? buildWin32CmdShimInvocation(resolved, args) : null;
|
|
@@ -124,17 +150,78 @@ function runOutdated(manager, args, cwd, signal) {
|
|
|
124
150
|
windowsHide: true,
|
|
125
151
|
...shim ? { windowsVerbatimArguments: shim.windowsVerbatimArguments } : {}
|
|
126
152
|
});
|
|
153
|
+
const registry = getProcessRegistry();
|
|
154
|
+
if (typeof child.pid === "number") {
|
|
155
|
+
registry.register({
|
|
156
|
+
pid: child.pid,
|
|
157
|
+
name: manager,
|
|
158
|
+
command: redactCommand(`${spawnCmd} ${args.join(" ")}`),
|
|
159
|
+
startedAt: Date.now(),
|
|
160
|
+
child
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
const onAbort = () => {
|
|
164
|
+
if (typeof child.pid === "number") {
|
|
165
|
+
registry.kill(child.pid, { force: true });
|
|
166
|
+
} else {
|
|
167
|
+
try {
|
|
168
|
+
child.kill("SIGKILL");
|
|
169
|
+
} catch {
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
if (signal) {
|
|
174
|
+
if (signal.aborted) onAbort();
|
|
175
|
+
else signal.addEventListener("abort", onAbort, { once: true });
|
|
176
|
+
}
|
|
127
177
|
child.stdout?.on("data", (c) => {
|
|
128
|
-
|
|
178
|
+
stdoutBytes += c.byteLength;
|
|
179
|
+
if (stdout.length < MAX) {
|
|
180
|
+
const text = stdoutDecoder.write(c);
|
|
181
|
+
stdout += text.slice(0, MAX - stdout.length);
|
|
182
|
+
}
|
|
129
183
|
});
|
|
130
184
|
child.stderr?.on("data", (c) => {
|
|
131
|
-
|
|
185
|
+
stderrBytes += c.byteLength;
|
|
186
|
+
if (stderr.length < MAX) {
|
|
187
|
+
const text = stderrDecoder.write(c);
|
|
188
|
+
stderr += text.slice(0, MAX - stderr.length);
|
|
189
|
+
}
|
|
132
190
|
});
|
|
133
191
|
child.on("close", (code) => {
|
|
134
|
-
|
|
192
|
+
if (signal) signal.removeEventListener("abort", onAbort);
|
|
193
|
+
if (typeof child.pid === "number") registry.unregister(child.pid);
|
|
194
|
+
if (signal.aborted) {
|
|
195
|
+
resolve({
|
|
196
|
+
exit_code: 124,
|
|
197
|
+
packages: [],
|
|
198
|
+
total: 0,
|
|
199
|
+
output: "Aborted",
|
|
200
|
+
truncated: false
|
|
201
|
+
});
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
const restOut = stdoutDecoder.end();
|
|
205
|
+
if (restOut && stdout.length < MAX) {
|
|
206
|
+
stdout += restOut.slice(0, MAX - stdout.length);
|
|
207
|
+
}
|
|
208
|
+
const isTruncated = stdoutBytes > MAX || stderrBytes > MAX || Buffer.byteLength(stdout, "utf8") > COMMAND_OUTPUT_MAX_BYTES;
|
|
209
|
+
const result = parseOutdatedOutput(stdout, code ?? 0, stderr, isTruncated);
|
|
135
210
|
resolve(result);
|
|
136
211
|
});
|
|
137
212
|
child.on("error", (e) => {
|
|
213
|
+
if (signal) signal.removeEventListener("abort", onAbort);
|
|
214
|
+
if (typeof child.pid === "number") registry.unregister(child.pid);
|
|
215
|
+
if (signal.aborted || e.name === "AbortError") {
|
|
216
|
+
resolve({
|
|
217
|
+
exit_code: 124,
|
|
218
|
+
packages: [],
|
|
219
|
+
total: 0,
|
|
220
|
+
output: "Aborted",
|
|
221
|
+
truncated: false
|
|
222
|
+
});
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
138
225
|
resolve({
|
|
139
226
|
exit_code: 1,
|
|
140
227
|
packages: [],
|
|
@@ -145,18 +232,18 @@ function runOutdated(manager, args, cwd, signal) {
|
|
|
145
232
|
});
|
|
146
233
|
});
|
|
147
234
|
}
|
|
148
|
-
function parseOutdatedOutput(json, exitCode) {
|
|
235
|
+
function parseOutdatedOutput(json, exitCode, stderr = "", truncated = false) {
|
|
149
236
|
const packages = [];
|
|
150
237
|
if (!json) {
|
|
151
238
|
return {
|
|
152
239
|
exit_code: exitCode,
|
|
153
240
|
packages: [],
|
|
154
241
|
total: 0,
|
|
155
|
-
output: exitCode === 0 ? "All packages up to date" : "Could not check outdated packages",
|
|
156
|
-
truncated
|
|
242
|
+
output: stderr || (exitCode === 0 ? "All packages up to date" : "Could not check outdated packages"),
|
|
243
|
+
truncated
|
|
157
244
|
};
|
|
158
245
|
}
|
|
159
|
-
const
|
|
246
|
+
const isTruncated = truncated || json.length >= 1e5 || Buffer.byteLength(json, "utf8") > COMMAND_OUTPUT_MAX_BYTES;
|
|
160
247
|
let parsedOk = false;
|
|
161
248
|
try {
|
|
162
249
|
const data = JSON.parse(json);
|
|
@@ -188,11 +275,11 @@ Note: exit code 1 from \`outdated\` means outdated packages were found (expected
|
|
|
188
275
|
packages,
|
|
189
276
|
total: packages.length,
|
|
190
277
|
output,
|
|
191
|
-
truncated
|
|
278
|
+
truncated: isTruncated
|
|
192
279
|
};
|
|
193
280
|
}
|
|
194
281
|
|
|
195
282
|
export {
|
|
196
283
|
outdatedTool
|
|
197
284
|
};
|
|
198
|
-
//# sourceMappingURL=chunk-
|
|
285
|
+
//# sourceMappingURL=chunk-IYKXK356.js.map
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
import {
|
|
8
8
|
assertRealInsideRoot,
|
|
9
9
|
safeResolveReal
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ZUFHAHTE.js";
|
|
11
11
|
|
|
12
12
|
// src/glob.ts
|
|
13
13
|
import * as fs from "node:fs/promises";
|
|
@@ -52,9 +52,9 @@ var globTool = {
|
|
|
52
52
|
required: ["pattern"]
|
|
53
53
|
},
|
|
54
54
|
async execute(input, ctx, opts) {
|
|
55
|
-
if (!input?.pattern) {
|
|
55
|
+
if (!input?.pattern || typeof input.pattern !== "string" || !input.pattern.trim()) {
|
|
56
56
|
throw new ToolValidationError({
|
|
57
|
-
message: "glob: pattern is required",
|
|
57
|
+
message: "glob: pattern is required and cannot be empty",
|
|
58
58
|
field: "pattern"
|
|
59
59
|
});
|
|
60
60
|
}
|
|
@@ -63,10 +63,12 @@ var globTool = {
|
|
|
63
63
|
return { files: [], truncated: true };
|
|
64
64
|
}
|
|
65
65
|
const base = input.path ? await safeResolveReal(input.path, ctx) : ctx.cwd;
|
|
66
|
-
const
|
|
66
|
+
const rawLimit = typeof input.limit === "number" && !Number.isNaN(input.limit) ? input.limit : 1e3;
|
|
67
|
+
const limit = Math.max(1, Math.min(Math.floor(rawLimit), 5e3));
|
|
67
68
|
const isGitIgnored = await loadGitignoreMatcher(base);
|
|
68
69
|
const re = compileGlob(input.pattern);
|
|
69
70
|
const results = [];
|
|
71
|
+
const visitedRealDirs = /* @__PURE__ */ new Set();
|
|
70
72
|
let truncated = false;
|
|
71
73
|
const pushResult = async (full) => {
|
|
72
74
|
if (signal?.aborted || truncated || results.length >= limit) {
|
|
@@ -89,6 +91,9 @@ var globTool = {
|
|
|
89
91
|
truncated = true;
|
|
90
92
|
return;
|
|
91
93
|
}
|
|
94
|
+
const realDir = await fs.realpath(dir).catch(() => dir);
|
|
95
|
+
if (visitedRealDirs.has(realDir)) return;
|
|
96
|
+
visitedRealDirs.add(realDir);
|
|
92
97
|
if (results.length >= limit) {
|
|
93
98
|
truncated = true;
|
|
94
99
|
return;
|
|
@@ -111,7 +116,8 @@ var globTool = {
|
|
|
111
116
|
subdirs.push({ full, rel });
|
|
112
117
|
} else if (e.isFile()) {
|
|
113
118
|
if (isGitIgnored(rel, false)) continue;
|
|
114
|
-
|
|
119
|
+
re.lastIndex = 0;
|
|
120
|
+
if (re.test(rel) || (re.lastIndex = 0, re.test(name))) {
|
|
115
121
|
matchedFiles.push(full);
|
|
116
122
|
}
|
|
117
123
|
} else if (e.isSymbolicLink()) {
|
|
@@ -126,7 +132,8 @@ var globTool = {
|
|
|
126
132
|
if (isGitIgnored(rel, false)) continue;
|
|
127
133
|
const real = await fs.realpath(full);
|
|
128
134
|
await assertRealInsideRoot(real, ctx);
|
|
129
|
-
|
|
135
|
+
re.lastIndex = 0;
|
|
136
|
+
if (re.test(rel) || (re.lastIndex = 0, re.test(name))) matchedFiles.push(full);
|
|
130
137
|
}
|
|
131
138
|
} catch {
|
|
132
139
|
}
|
|
@@ -151,4 +158,4 @@ var globTool = {
|
|
|
151
158
|
export {
|
|
152
159
|
globTool
|
|
153
160
|
};
|
|
154
|
-
//# sourceMappingURL=chunk-
|
|
161
|
+
//# sourceMappingURL=chunk-JDPQOR7C.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
parseFilesContent
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-CMOUCKGC.js";
|
|
4
4
|
import {
|
|
5
5
|
INDEXABLE_EXTENSIONS,
|
|
6
6
|
LANG_FAMILY_ENTRIES,
|
|
@@ -514,7 +514,9 @@ function encodeVector(vec) {
|
|
|
514
514
|
function decodeVector(buf) {
|
|
515
515
|
if (buf.byteLength === 0) return new Float32Array(0);
|
|
516
516
|
if (buf.byteLength % 4 !== 0) {
|
|
517
|
-
throw new Error(
|
|
517
|
+
throw new Error(
|
|
518
|
+
`decodeVector: invalid vector byteLength ${buf.byteLength} (must be a multiple of 4)`
|
|
519
|
+
);
|
|
518
520
|
}
|
|
519
521
|
const copy = new Float32Array(buf.byteLength / 4);
|
|
520
522
|
new Uint8Array(copy.buffer).set(buf);
|
|
@@ -636,10 +638,7 @@ function bulkInsertSymbolsWithStatement(stmt, maxSqlVars, rows) {
|
|
|
636
638
|
for (const take of ladder) {
|
|
637
639
|
const chunk = rows.slice(cursor, cursor + take);
|
|
638
640
|
cursor += take;
|
|
639
|
-
const placeholders2 = getRowPlaceholders(
|
|
640
|
-
"(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
|
641
|
-
chunk.length
|
|
642
|
-
);
|
|
641
|
+
const placeholders2 = getRowPlaceholders("(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", chunk.length);
|
|
643
642
|
const insert = stmt(
|
|
644
643
|
`INSERT INTO symbols(id, lang, kind, name, file, line, col, signature, doc_comment, scope)
|
|
645
644
|
VALUES ${placeholders2}`
|
|
@@ -697,10 +696,7 @@ function bulkInsertRefsWithStatement(stmt, maxSqlVars, refs) {
|
|
|
697
696
|
for (const take of ladder) {
|
|
698
697
|
const chunk = refs.slice(cursor, cursor + take);
|
|
699
698
|
cursor += take;
|
|
700
|
-
const placeholders2 = getRowPlaceholders(
|
|
701
|
-
"(?, ?, ?, ?, ?, ?, ?, ?)",
|
|
702
|
-
chunk.length
|
|
703
|
-
);
|
|
699
|
+
const placeholders2 = getRowPlaceholders("(?, ?, ?, ?, ?, ?, ?, ?)", chunk.length);
|
|
704
700
|
const insert = stmt(
|
|
705
701
|
`INSERT INTO refs(from_id, to_name, to_id, call_type, line, lang, module, to_file)
|
|
706
702
|
VALUES ${placeholders2}`
|
|
@@ -1769,9 +1765,7 @@ function commitBatchWithStatement(stmtFn, maxSqlVars, ftsAvailable, vectorsAvail
|
|
|
1769
1765
|
if (vectorsAvailable) {
|
|
1770
1766
|
vectorRows.push({
|
|
1771
1767
|
id,
|
|
1772
|
-
vector: encodeVector(
|
|
1773
|
-
embedText(buildIndexableText(s.name, s.signature, s.docComment))
|
|
1774
|
-
)
|
|
1768
|
+
vector: encodeVector(embedText(buildIndexableText(s.name, s.signature, s.docComment)))
|
|
1775
1769
|
});
|
|
1776
1770
|
}
|
|
1777
1771
|
const inserted = { ...s, id };
|
|
@@ -1923,6 +1917,7 @@ var SYMBOL_VECTORS_TABLE_SQL = `
|
|
|
1923
1917
|
// src/codebase-index/writer-refs.ts
|
|
1924
1918
|
var FAMILY_MATCH_SQL = `(
|
|
1925
1919
|
sym.lang = refs.lang
|
|
1920
|
+
OR refs.lang = ''
|
|
1926
1921
|
OR EXISTS (
|
|
1927
1922
|
SELECT 1 FROM lang_family lf1
|
|
1928
1923
|
JOIN lang_family lf2 ON lf1.family = lf2.family
|
|
@@ -3824,7 +3819,7 @@ var ParserWorkerPool = class {
|
|
|
3824
3819
|
*/
|
|
3825
3820
|
async reparseInline(batch, orphaned, workerId) {
|
|
3826
3821
|
try {
|
|
3827
|
-
const { parseFileContent } = await import("./parser-dispatch-
|
|
3822
|
+
const { parseFileContent } = await import("./parser-dispatch-QGC4HSP5.js");
|
|
3828
3823
|
for (const item of orphaned) {
|
|
3829
3824
|
if (batch.settled) return;
|
|
3830
3825
|
try {
|
|
@@ -4613,4 +4608,4 @@ export {
|
|
|
4613
4608
|
incomingCallsService,
|
|
4614
4609
|
outgoingCallsService
|
|
4615
4610
|
};
|
|
4616
|
-
//# sourceMappingURL=chunk-
|
|
4611
|
+
//# sourceMappingURL=chunk-KY4PXYSO.js.map
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
tryLegacyCodeOperation
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ATSKPZUK.js";
|
|
4
4
|
import {
|
|
5
5
|
spawnStream
|
|
6
6
|
} from "./chunk-ZHH3BEWU.js";
|
|
7
7
|
import {
|
|
8
8
|
normalizeCommandOutput,
|
|
9
9
|
safeResolveReal
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-ZUFHAHTE.js";
|
|
11
11
|
|
|
12
12
|
// src/lint.ts
|
|
13
|
+
import { ToolValidationError } from "@wrongstack/core/types";
|
|
13
14
|
var lintTool = {
|
|
14
15
|
name: "lint",
|
|
15
16
|
category: "Code Quality",
|
|
@@ -49,6 +50,14 @@ var lintTool = {
|
|
|
49
50
|
async *executeStream(input, ctx, opts) {
|
|
50
51
|
const cwd = input.cwd ? await safeResolveReal(input.cwd, ctx) : ctx.cwd;
|
|
51
52
|
const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
|
|
53
|
+
signal.throwIfAborted();
|
|
54
|
+
const VALID_LINTERS = /* @__PURE__ */ new Set(["biome", "eslint", "tslint", "auto"]);
|
|
55
|
+
if (input.linter !== void 0 && !VALID_LINTERS.has(input.linter)) {
|
|
56
|
+
throw new ToolValidationError({
|
|
57
|
+
message: `lint: unsupported linter "${input.linter}". Allowed linters: biome, eslint, tslint, auto`,
|
|
58
|
+
field: "linter"
|
|
59
|
+
});
|
|
60
|
+
}
|
|
52
61
|
const linter = input.linter ?? "auto";
|
|
53
62
|
if (linter === "auto" && !input.files) {
|
|
54
63
|
const bridge = await tryLegacyCodeOperation("lint", {
|
|
@@ -90,24 +99,49 @@ var lintTool = {
|
|
|
90
99
|
return;
|
|
91
100
|
}
|
|
92
101
|
yield { type: "log", text: `Running ${detected}\u2026`, data: { linter: detected } };
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
if (
|
|
96
|
-
|
|
97
|
-
|
|
102
|
+
const files = input.files ? (Array.isArray(input.files) ? input.files : input.files.split(",")).map((f) => f.trim().replace(/\\/g, "/")).filter(Boolean) : [];
|
|
103
|
+
const args = [];
|
|
104
|
+
if (detected === "eslint") {
|
|
105
|
+
if (input.fix) args.push("--fix");
|
|
106
|
+
if (files.length) args.push(...files);
|
|
107
|
+
} else {
|
|
108
|
+
args.push("lint");
|
|
109
|
+
if (input.fix) args.push("--write");
|
|
110
|
+
if (files.length) args.push("--", ...files);
|
|
98
111
|
}
|
|
99
112
|
const cmd = detected === "biome" ? "biome" : detected;
|
|
100
113
|
const result = yield* spawnStream({ cmd, args, cwd, signal, maxBytes: 1e5 });
|
|
101
|
-
const
|
|
102
|
-
|
|
114
|
+
const combined = `${result.stdout}
|
|
115
|
+
${result.stderr}`;
|
|
116
|
+
let errors = 0;
|
|
117
|
+
let warnings = 0;
|
|
118
|
+
const biomeSummary = combined.match(/Found\s+(\d+)\s+errors?(?:\s+and\s+(\d+)\s+warnings?)?/i);
|
|
119
|
+
const eslintSummary = combined.match(
|
|
120
|
+
/(\d+)\s+problems?\s+\((\d+)\s+errors?,\s*(\d+)\s+warnings?\)/i
|
|
121
|
+
);
|
|
122
|
+
if (biomeSummary) {
|
|
123
|
+
errors = Number.parseInt(biomeSummary[1] ?? "0", 10);
|
|
124
|
+
warnings = Number.parseInt(biomeSummary[2] ?? "0", 10);
|
|
125
|
+
} else if (eslintSummary) {
|
|
126
|
+
errors = Number.parseInt(eslintSummary[2] ?? "0", 10);
|
|
127
|
+
warnings = Number.parseInt(eslintSummary[3] ?? "0", 10);
|
|
128
|
+
} else {
|
|
129
|
+
errors = [...combined.matchAll(/\berror\b/gi)].length;
|
|
130
|
+
warnings = [...combined.matchAll(/\bwarning\b/gi)].length;
|
|
131
|
+
}
|
|
132
|
+
if (errors === 0 && result.exitCode !== 0) {
|
|
133
|
+
errors = 1;
|
|
134
|
+
}
|
|
135
|
+
const rawOutput = result.stdout && result.stderr ? `${result.stdout}
|
|
136
|
+
${result.stderr}` : result.stdout || result.stderr || result.error || "";
|
|
103
137
|
yield {
|
|
104
138
|
type: "final",
|
|
105
139
|
output: {
|
|
106
140
|
linter: detected,
|
|
107
|
-
files_checked:
|
|
141
|
+
files_checked: files.length,
|
|
108
142
|
errors,
|
|
109
143
|
warnings,
|
|
110
|
-
output: normalizeCommandOutput(
|
|
144
|
+
output: normalizeCommandOutput(rawOutput),
|
|
111
145
|
fix_applied: input.fix ?? false,
|
|
112
146
|
truncated: result.truncated
|
|
113
147
|
}
|
|
@@ -116,10 +150,25 @@ var lintTool = {
|
|
|
116
150
|
};
|
|
117
151
|
async function detectLinter(cwd) {
|
|
118
152
|
const { stat } = await import("node:fs/promises");
|
|
119
|
-
const checks = [
|
|
153
|
+
const checks = [
|
|
154
|
+
"biome.json",
|
|
155
|
+
"biome.jsonc",
|
|
156
|
+
"eslint.config.js",
|
|
157
|
+
"eslint.config.mjs",
|
|
158
|
+
"eslint.config.cjs",
|
|
159
|
+
"eslint.config.ts",
|
|
160
|
+
".eslintrc.json",
|
|
161
|
+
".eslintrc.js",
|
|
162
|
+
".eslintrc.cjs",
|
|
163
|
+
".eslintrc.yaml",
|
|
164
|
+
".eslintrc.yml",
|
|
165
|
+
"tslint.json",
|
|
166
|
+
"tsconfig.json"
|
|
167
|
+
];
|
|
120
168
|
for (const f of checks) {
|
|
121
169
|
try {
|
|
122
|
-
await
|
|
170
|
+
const { join } = await import("node:path");
|
|
171
|
+
await stat(join(cwd, f));
|
|
123
172
|
if (f.includes("biome")) return "biome";
|
|
124
173
|
if (f.includes("eslint")) return "eslint";
|
|
125
174
|
if (f.includes("tslint")) return "tslint";
|
|
@@ -132,4 +181,4 @@ async function detectLinter(cwd) {
|
|
|
132
181
|
export {
|
|
133
182
|
lintTool
|
|
134
183
|
};
|
|
135
|
-
//# sourceMappingURL=chunk-
|
|
184
|
+
//# sourceMappingURL=chunk-LOBRWKCR.js.map
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
safeResolveReal
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-ZUFHAHTE.js";
|
|
4
4
|
|
|
5
5
|
// src/tree.ts
|
|
6
6
|
import * as fs from "node:fs/promises";
|
|
7
7
|
import * as path from "node:path";
|
|
8
|
-
import {
|
|
8
|
+
import { compileGlob, DEFAULT_WALK_IGNORE_DIRS, expectDefined } from "@wrongstack/core/utils";
|
|
9
9
|
var DEFAULT_IGNORE = /* @__PURE__ */ new Set([
|
|
10
10
|
...DEFAULT_WALK_IGNORE_DIRS,
|
|
11
11
|
".wrongstack",
|
|
@@ -80,14 +80,20 @@ var treeTool = {
|
|
|
80
80
|
},
|
|
81
81
|
async *executeStream(input, ctx, opts) {
|
|
82
82
|
const basePath = input.path ? await safeResolveReal(input.path, ctx) : ctx.cwd;
|
|
83
|
-
const maxDepth = input.depth
|
|
83
|
+
const maxDepth = typeof input.depth === "number" && Number.isFinite(input.depth) && input.depth >= 0 ? Math.floor(input.depth) : 3;
|
|
84
84
|
const showFiles = input.show_files ?? true;
|
|
85
85
|
const showDirs = input.show_dirs ?? true;
|
|
86
86
|
const showHidden = input.show_hidden ?? false;
|
|
87
|
-
const exclude = /* @__PURE__ */ new Set([
|
|
87
|
+
const exclude = /* @__PURE__ */ new Set([
|
|
88
|
+
...DEFAULT_IGNORE,
|
|
89
|
+
...(input.exclude ?? []).map(
|
|
90
|
+
(s) => s.trim().replace(/[\\/]+$/, "").replace(/^\.\//, "")
|
|
91
|
+
).filter(Boolean)
|
|
92
|
+
]);
|
|
88
93
|
const globRe = input.glob ? compileGlob(input.glob) : void 0;
|
|
89
|
-
const maxEntries = input.max_entries
|
|
94
|
+
const maxEntries = typeof input.max_entries === "number" && Number.isFinite(input.max_entries) && input.max_entries > 0 ? Math.floor(input.max_entries) : DEFAULT_MAX_ENTRIES;
|
|
90
95
|
const signal = opts?.signal ?? ctx.signal ?? new AbortController().signal;
|
|
96
|
+
signal.throwIfAborted();
|
|
91
97
|
const lines = [basePath];
|
|
92
98
|
const totals = { totalFiles: { value: 0 }, totalDirs: { value: 0 } };
|
|
93
99
|
const retention = {
|
|
@@ -100,6 +106,7 @@ var treeTool = {
|
|
|
100
106
|
const queue = [];
|
|
101
107
|
const FLUSH_EVERY = 200;
|
|
102
108
|
let lastEmittedTotal = 0;
|
|
109
|
+
let wakeWaiter;
|
|
103
110
|
const tickProgress = () => {
|
|
104
111
|
const seen = totals.totalFiles.value + totals.totalDirs.value;
|
|
105
112
|
if (seen - lastEmittedTotal >= FLUSH_EVERY) {
|
|
@@ -109,6 +116,7 @@ var treeTool = {
|
|
|
109
116
|
data: { files: totals.totalFiles.value, dirs: totals.totalDirs.value }
|
|
110
117
|
});
|
|
111
118
|
lastEmittedTotal = seen;
|
|
119
|
+
wakeWaiter?.();
|
|
112
120
|
}
|
|
113
121
|
};
|
|
114
122
|
const walkPromise = walkDir(basePath, 0, {
|
|
@@ -129,27 +137,20 @@ var treeTool = {
|
|
|
129
137
|
signal
|
|
130
138
|
});
|
|
131
139
|
let walkDone = false;
|
|
132
|
-
void walkPromise.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
walkDone = true;
|
|
138
|
-
}
|
|
139
|
-
);
|
|
140
|
+
void walkPromise.catch(() => {
|
|
141
|
+
}).finally(() => {
|
|
142
|
+
walkDone = true;
|
|
143
|
+
wakeWaiter?.();
|
|
144
|
+
});
|
|
140
145
|
while (!walkDone || queue.length > 0) {
|
|
141
146
|
if (queue.length > 0) {
|
|
142
147
|
yield expectDefined(queue.shift());
|
|
143
148
|
} else {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
149
|
+
await new Promise((resolve) => {
|
|
150
|
+
wakeWaiter = resolve;
|
|
151
|
+
if (walkDone || queue.length > 0) resolve();
|
|
147
152
|
});
|
|
148
|
-
|
|
149
|
-
await Promise.race([walkPromise, poll]).catch(() => void 0);
|
|
150
|
-
} finally {
|
|
151
|
-
if (pollTimer) clearTimeout(pollTimer);
|
|
152
|
-
}
|
|
153
|
+
wakeWaiter = void 0;
|
|
153
154
|
}
|
|
154
155
|
}
|
|
155
156
|
await walkPromise;
|
|
@@ -166,10 +167,17 @@ var treeTool = {
|
|
|
166
167
|
}
|
|
167
168
|
};
|
|
168
169
|
function matchesTreeGlob(globRe, fileName, absPath, basePath) {
|
|
169
|
-
|
|
170
|
+
globRe.lastIndex = 0;
|
|
171
|
+
if (globRe.test(fileName)) {
|
|
172
|
+
globRe.lastIndex = 0;
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
globRe.lastIndex = 0;
|
|
170
176
|
const rel = path.relative(basePath, absPath);
|
|
171
177
|
const posixRel = !rel || rel.startsWith("..") || path.isAbsolute(rel) ? absPath.split(path.sep).join("/") : rel.split(path.sep).join("/");
|
|
172
|
-
|
|
178
|
+
const matches = globRe.test(posixRel);
|
|
179
|
+
globRe.lastIndex = 0;
|
|
180
|
+
return matches;
|
|
173
181
|
}
|
|
174
182
|
async function walkDir(dir, depth, opts) {
|
|
175
183
|
opts.signal.throwIfAborted();
|
|
@@ -178,6 +186,8 @@ async function walkDir(dir, depth, opts) {
|
|
|
178
186
|
const filtered = entries.filter((e) => {
|
|
179
187
|
if (!opts.showHidden && e.name.startsWith(".")) return false;
|
|
180
188
|
if (opts.exclude.has(e.name)) return false;
|
|
189
|
+
const rel = path.relative(opts.basePath, path.join(dir, e.name)).split(path.sep).join("/");
|
|
190
|
+
if (opts.exclude.has(rel)) return false;
|
|
181
191
|
if (e.isFile() && opts.globRe) {
|
|
182
192
|
const abs = path.join(dir, e.name);
|
|
183
193
|
if (!matchesTreeGlob(opts.globRe, e.name, abs, opts.basePath)) return false;
|
|
@@ -204,11 +214,12 @@ async function walkDir(dir, depth, opts) {
|
|
|
204
214
|
const entry = items[i];
|
|
205
215
|
if (!entry) continue;
|
|
206
216
|
const isLast = i === items.length - 1;
|
|
207
|
-
const connector =
|
|
217
|
+
const connector = isLast ? " " : "\u2502 ";
|
|
208
218
|
const branch = isLast ? "\u2514\u2500\u2500 " : "\u251C\u2500\u2500 ";
|
|
209
219
|
const displayName = entry.name + (entry.isDirectory() ? "/" : "");
|
|
210
|
-
|
|
211
|
-
if (!opts.
|
|
220
|
+
const isDir = entry.isDirectory();
|
|
221
|
+
if (!opts.showDirs && isDir) continue;
|
|
222
|
+
if (!opts.showFiles && !isDir) continue;
|
|
212
223
|
const line = opts.prefix + branch + displayName;
|
|
213
224
|
const lineBytes = Buffer.byteLength(line, "utf8") + 1;
|
|
214
225
|
if (opts.retention.entries >= opts.retention.maxEntries || opts.retention.outputBytes + lineBytes > opts.retention.maxOutputBytes) {
|
|
@@ -232,4 +243,4 @@ async function walkDir(dir, depth, opts) {
|
|
|
232
243
|
export {
|
|
233
244
|
treeTool
|
|
234
245
|
};
|
|
235
|
-
//# sourceMappingURL=chunk-
|
|
246
|
+
//# sourceMappingURL=chunk-MNP3GE7H.js.map
|
|
@@ -3,16 +3,16 @@ import {
|
|
|
3
3
|
} from "./chunk-FQZOHLG3.js";
|
|
4
4
|
import {
|
|
5
5
|
enqueueReindex
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-DP6CXMJZ.js";
|
|
7
7
|
import {
|
|
8
8
|
safeResolveReal,
|
|
9
9
|
sha256hex,
|
|
10
10
|
truncateDiffPayload
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-ZUFHAHTE.js";
|
|
12
12
|
|
|
13
13
|
// src/write.ts
|
|
14
14
|
import * as fs from "node:fs/promises";
|
|
15
|
-
import { ToolValidationError } from "@wrongstack/core/types";
|
|
15
|
+
import { FsError, ToolValidationError } from "@wrongstack/core/types";
|
|
16
16
|
import {
|
|
17
17
|
atomicWrite,
|
|
18
18
|
detectNewlineStyle,
|
|
@@ -72,6 +72,15 @@ var writeTool = {
|
|
|
72
72
|
yield { type: "final", output: await finishWrite(input, ctx, prepared, signal) };
|
|
73
73
|
}
|
|
74
74
|
};
|
|
75
|
+
function countLines(text) {
|
|
76
|
+
if (!text) return 0;
|
|
77
|
+
const trimmed = text.endsWith("\n") ? text.slice(0, -1) : text;
|
|
78
|
+
let count = 1;
|
|
79
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
80
|
+
if (trimmed.charCodeAt(i) === 10) count++;
|
|
81
|
+
}
|
|
82
|
+
return count;
|
|
83
|
+
}
|
|
75
84
|
async function writeFile(input, ctx, signal) {
|
|
76
85
|
signal?.throwIfAborted();
|
|
77
86
|
return finishWrite(input, ctx, await prepareWrite(input, ctx), signal);
|
|
@@ -94,6 +103,14 @@ async function prepareWrite(input, ctx) {
|
|
|
94
103
|
let prev = "";
|
|
95
104
|
try {
|
|
96
105
|
const stat2 = await fs.stat(absPath);
|
|
106
|
+
if (stat2.isDirectory()) {
|
|
107
|
+
throw new FsError({
|
|
108
|
+
message: `write: "${input.path}" is an existing directory and cannot be overwritten`,
|
|
109
|
+
code: "FS_WRITE_FAILED",
|
|
110
|
+
path: absPath,
|
|
111
|
+
context: { reason: "is-directory" }
|
|
112
|
+
});
|
|
113
|
+
}
|
|
97
114
|
existed = stat2.isFile();
|
|
98
115
|
if (existed) {
|
|
99
116
|
prev = await fs.readFile(absPath, "utf8");
|
|
@@ -116,11 +133,13 @@ async function finishWrite(input, ctx, prepared, signal) {
|
|
|
116
133
|
enqueueReindex({ projectRoot: ctx.projectRoot, files: [prepared.absPath] });
|
|
117
134
|
} catch {
|
|
118
135
|
}
|
|
119
|
-
const
|
|
120
|
-
|
|
136
|
+
const isIdentical = prepared.existed && prepared.prev === content;
|
|
137
|
+
const rawDiff = prepared.existed ? isIdentical ? "(no-op: file content is identical to existing content)" : unifiedDiff(prepared.prev, content, { fromFile: input.path, toFile: input.path }) : `+++ ${input.path}
|
|
138
|
+
+ (new file, ${countLines(content)} lines)`;
|
|
121
139
|
const { text: diff, truncated: diffTruncated } = truncateDiffPayload(rawDiff, MAX_DIFF_BYTES);
|
|
140
|
+
const contentHash = sha256hex(content);
|
|
122
141
|
const stat2 = await fs.stat(prepared.absPath);
|
|
123
|
-
ctx.recordRead(prepared.absPath, stat2.mtimeMs, "write",
|
|
142
|
+
ctx.recordRead(prepared.absPath, stat2.mtimeMs, "write", contentHash);
|
|
124
143
|
ctx.session?.recordFileChange?.({
|
|
125
144
|
path: prepared.absPath,
|
|
126
145
|
action: prepared.existed ? "modified" : "created",
|
|
@@ -134,6 +153,11 @@ async function finishWrite(input, ctx, prepared, signal) {
|
|
|
134
153
|
).catch(() => void 0);
|
|
135
154
|
const hasSyntaxErrors = syntax !== void 0 && syntax.errors.length > 0;
|
|
136
155
|
const notes = [];
|
|
156
|
+
if (isIdentical) {
|
|
157
|
+
notes.push(
|
|
158
|
+
"Write completed with no content changes (new content is identical to existing content)."
|
|
159
|
+
);
|
|
160
|
+
}
|
|
137
161
|
if (diffTruncated) {
|
|
138
162
|
notes.push("Diff truncated to the 256 KiB output budget \u2014 the full write is on disk.");
|
|
139
163
|
}
|
|
@@ -155,4 +179,4 @@ async function finishWrite(input, ctx, prepared, signal) {
|
|
|
155
179
|
export {
|
|
156
180
|
writeTool
|
|
157
181
|
};
|
|
158
|
-
//# sourceMappingURL=chunk-
|
|
182
|
+
//# sourceMappingURL=chunk-O44IMQCN.js.map
|