@wrongstack/tools 0.272.2 → 0.273.0
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/bash.js +32 -10
- package/dist/bash.js.map +1 -1
- package/dist/builtin.js +55 -25
- package/dist/builtin.js.map +1 -1
- package/dist/codebase-index/index.js +9 -5
- package/dist/codebase-index/index.js.map +1 -1
- package/dist/codebase-index/worker.js +9 -5
- package/dist/codebase-index/worker.js.map +1 -1
- package/dist/index.js +49 -19
- package/dist/index.js.map +1 -1
- package/dist/pack.js +55 -25
- package/dist/pack.js.map +1 -1
- package/dist/replace.js +2 -2
- package/dist/replace.js.map +1 -1
- package/package.json +2 -2
package/dist/pack.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { spawn, execFileSync } from 'node:child_process';
|
|
2
2
|
import * as Core from '@wrongstack/core';
|
|
3
|
-
import { buildChildEnv, detectNewlineStyle, normalizeToLf, toStyle, atomicWrite, unifiedDiff, isPrivateIPv4, isPrivateIPv6, assessCommitSafety, compileGlob, expectDefined, recordPackageAction, detectPackageEcosystem, mutatePlan, clearPlan, getPlanTemplate, addPlanItem, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, mutateTasks, formatTaskList, formatPlan, toErrorMessage, computeTaskItemProgress, loadPlan, savePlan, loadTasks, saveTasks, wstackGlobalRoot, resolveWstackPaths, truncate } from '@wrongstack/core';
|
|
3
|
+
import { buildChildEnv, detectNewlineStyle, normalizeToLf, toStyle, atomicWrite, unifiedDiff, isPrivateIPv4, isPrivateIPv6, assessCommitSafety, compileGlob, expectDefined, recordPackageAction, detectPackageEcosystem, mutatePlan, clearPlan, getPlanTemplate, addPlanItem, deriveTodosFromPlanItem, removePlanItem, setPlanItemStatus, mutateTasks, formatTaskList, formatPlan, toErrorMessage as toErrorMessage$1, computeTaskItemProgress, loadPlan, savePlan, loadTasks, saveTasks, wstackGlobalRoot, resolveWstackPaths, truncate } from '@wrongstack/core';
|
|
4
4
|
import * as fs from 'node:fs';
|
|
5
5
|
import { statSync, mkdirSync, createWriteStream } from 'node:fs';
|
|
6
6
|
import * as fs2 from 'node:fs/promises';
|
|
7
7
|
import * as path3 from 'node:path';
|
|
8
8
|
import { resolve, sep, dirname, join } from 'node:path';
|
|
9
9
|
import * as os2 from 'node:os';
|
|
10
|
-
import { toErrorMessage as toErrorMessage$
|
|
10
|
+
import { toErrorMessage as toErrorMessage$2 } from '@wrongstack/core/utils';
|
|
11
11
|
import { createRequire } from 'node:module';
|
|
12
12
|
import { fileURLToPath } from 'node:url';
|
|
13
13
|
import { Worker } from 'node:worker_threads';
|
|
@@ -1084,6 +1084,21 @@ function parseAuditOutput(json, exitCode) {
|
|
|
1084
1084
|
}
|
|
1085
1085
|
}
|
|
1086
1086
|
var REGISTRY_FILE = ".wrongstack/process-registry.json";
|
|
1087
|
+
function toErrorMessage(err) {
|
|
1088
|
+
return err instanceof Error ? err.message : String(err);
|
|
1089
|
+
}
|
|
1090
|
+
function emitStructuredLog(level, event, message, error) {
|
|
1091
|
+
const payload = {
|
|
1092
|
+
level,
|
|
1093
|
+
event,
|
|
1094
|
+
message,
|
|
1095
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1096
|
+
};
|
|
1097
|
+
if (error !== void 0) {
|
|
1098
|
+
payload.error = toErrorMessage(error);
|
|
1099
|
+
}
|
|
1100
|
+
console.log(JSON.stringify(payload));
|
|
1101
|
+
}
|
|
1087
1102
|
var HEARTBEAT_INTERVAL_MS = 5e3;
|
|
1088
1103
|
var STALE_THRESHOLD_MS = 3e4;
|
|
1089
1104
|
var LOCKFILE = ".wrongstack/.process-registry.lock";
|
|
@@ -1093,6 +1108,9 @@ function generateInstanceId() {
|
|
|
1093
1108
|
const random = Math.random().toString(36).slice(2, 8);
|
|
1094
1109
|
return `${hostname2}:${pid}:${random}`;
|
|
1095
1110
|
}
|
|
1111
|
+
function isNodeError(err) {
|
|
1112
|
+
return typeof err === "object" && err !== null && "code" in err;
|
|
1113
|
+
}
|
|
1096
1114
|
async function acquireLock(lockfilePath, timeoutMs = 5e3) {
|
|
1097
1115
|
const start = Date.now();
|
|
1098
1116
|
const pidStr = String(process.pid);
|
|
@@ -1107,7 +1125,7 @@ async function acquireLock(lockfilePath, timeoutMs = 5e3) {
|
|
|
1107
1125
|
}
|
|
1108
1126
|
};
|
|
1109
1127
|
} catch (err) {
|
|
1110
|
-
if (err.code === "EEXIST") {
|
|
1128
|
+
if (isNodeError(err) && err.code === "EEXIST") {
|
|
1111
1129
|
try {
|
|
1112
1130
|
const content = await fs2.readFile(lockfilePath, "utf-8");
|
|
1113
1131
|
const parts = content.split(":");
|
|
@@ -1144,7 +1162,7 @@ async function readRegistryFile(filePath) {
|
|
|
1144
1162
|
}
|
|
1145
1163
|
return parsed;
|
|
1146
1164
|
} catch (err) {
|
|
1147
|
-
if (err.code === "ENOENT") {
|
|
1165
|
+
if (isNodeError(err) && err.code === "ENOENT") {
|
|
1148
1166
|
return {
|
|
1149
1167
|
version: 1,
|
|
1150
1168
|
instances: /* @__PURE__ */ new Map(),
|
|
@@ -1180,7 +1198,7 @@ var PersistentProcessRegistry = class {
|
|
|
1180
1198
|
this.lockPath = path3.join(homeDir, LOCKFILE);
|
|
1181
1199
|
this.baseRegistry = baseRegistry ?? getProcessRegistry();
|
|
1182
1200
|
this.ensureDirectory().catch((err) => {
|
|
1183
|
-
|
|
1201
|
+
emitStructuredLog("warn", "process_registry.dir_create_failed", "PersistentProcessRegistry: failed to create .wrongstack directory", err);
|
|
1184
1202
|
});
|
|
1185
1203
|
}
|
|
1186
1204
|
async ensureDirectory() {
|
|
@@ -1188,7 +1206,7 @@ var PersistentProcessRegistry = class {
|
|
|
1188
1206
|
try {
|
|
1189
1207
|
await fs2.mkdir(dir, { recursive: true });
|
|
1190
1208
|
} catch (err) {
|
|
1191
|
-
if (err.code !== "EEXIST") throw err;
|
|
1209
|
+
if (!isNodeError(err) || err.code !== "EEXIST") throw err;
|
|
1192
1210
|
}
|
|
1193
1211
|
}
|
|
1194
1212
|
/**
|
|
@@ -1268,6 +1286,7 @@ var PersistentProcessRegistry = class {
|
|
|
1268
1286
|
try {
|
|
1269
1287
|
const data = await readRegistryFile(this.registryPath);
|
|
1270
1288
|
data.instances.set(String(entry.pid), entry);
|
|
1289
|
+
const child = null;
|
|
1271
1290
|
this.baseRegistry.register({
|
|
1272
1291
|
pid: entry.pid,
|
|
1273
1292
|
name: entry.name,
|
|
@@ -1275,8 +1294,7 @@ var PersistentProcessRegistry = class {
|
|
|
1275
1294
|
startedAt: entry.startedAt,
|
|
1276
1295
|
sessionId: entry.sessionId,
|
|
1277
1296
|
protected: entry.protected,
|
|
1278
|
-
child
|
|
1279
|
-
// Main process has no child handle
|
|
1297
|
+
child
|
|
1280
1298
|
});
|
|
1281
1299
|
await writeRegistryFile(this.registryPath, data);
|
|
1282
1300
|
} finally {
|
|
@@ -1324,7 +1342,7 @@ var PersistentProcessRegistry = class {
|
|
|
1324
1342
|
data.lastCleanup = now;
|
|
1325
1343
|
await writeRegistryFile(this.registryPath, data);
|
|
1326
1344
|
} catch (err) {
|
|
1327
|
-
|
|
1345
|
+
emitStructuredLog("warn", "process_registry.sync_failed", "PersistentProcessRegistry: sync failed", err);
|
|
1328
1346
|
} finally {
|
|
1329
1347
|
await release();
|
|
1330
1348
|
}
|
|
@@ -1345,7 +1363,11 @@ var PersistentProcessRegistry = class {
|
|
|
1345
1363
|
if (process.platform !== "win32") {
|
|
1346
1364
|
process.kill(entry.pid, 0);
|
|
1347
1365
|
} else {
|
|
1348
|
-
|
|
1366
|
+
emitStructuredLog(
|
|
1367
|
+
"debug",
|
|
1368
|
+
"process_registry.stale_pid_check",
|
|
1369
|
+
`PersistentProcessRegistry: checking stale pid ${entry.pid} (${age}ms old)`
|
|
1370
|
+
);
|
|
1349
1371
|
}
|
|
1350
1372
|
} catch {
|
|
1351
1373
|
stalePids.push(_pidStr);
|
|
@@ -1359,7 +1381,7 @@ var PersistentProcessRegistry = class {
|
|
|
1359
1381
|
await writeRegistryFile(this.registryPath, data);
|
|
1360
1382
|
}
|
|
1361
1383
|
} catch (err) {
|
|
1362
|
-
|
|
1384
|
+
emitStructuredLog("warn", "process_registry.cleanup_failed", "PersistentProcessRegistry: cleanup failed", err);
|
|
1363
1385
|
} finally {
|
|
1364
1386
|
await release();
|
|
1365
1387
|
}
|
|
@@ -1582,7 +1604,7 @@ async function isKillProtected(kill) {
|
|
|
1582
1604
|
const entries = await getProtectedEntries();
|
|
1583
1605
|
const killNameLower = kill.name.toLowerCase();
|
|
1584
1606
|
for (const entry of entries) {
|
|
1585
|
-
if (entry.name
|
|
1607
|
+
if (entry.name?.toLowerCase().includes(killNameLower)) {
|
|
1586
1608
|
return true;
|
|
1587
1609
|
}
|
|
1588
1610
|
}
|
|
@@ -2346,7 +2368,7 @@ function loadDatabaseSync() {
|
|
|
2346
2368
|
DatabaseSyncCtor = req("node:sqlite").DatabaseSync;
|
|
2347
2369
|
} catch (err) {
|
|
2348
2370
|
throw new Error(
|
|
2349
|
-
`The codebase index needs Node's built-in SQLite (node:sqlite), available since Node 22.5. This runtime doesn't provide it: ${toErrorMessage$
|
|
2371
|
+
`The codebase index needs Node's built-in SQLite (node:sqlite), available since Node 22.5. This runtime doesn't provide it: ${toErrorMessage$2(err)}`
|
|
2350
2372
|
);
|
|
2351
2373
|
}
|
|
2352
2374
|
return DatabaseSyncCtor;
|
|
@@ -3683,11 +3705,15 @@ async function tryNativeParse(file, content) {
|
|
|
3683
3705
|
const crateDir = path3.join(toolsDir, "syn-parser");
|
|
3684
3706
|
const tmpFile = path3.join(crateDir, "src", "input.rs");
|
|
3685
3707
|
await fs2.writeFile(tmpFile, content, "utf8");
|
|
3686
|
-
const proc = spawn(
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
|
|
3690
|
-
|
|
3708
|
+
const proc = spawn(
|
|
3709
|
+
"cargo",
|
|
3710
|
+
["run", "--manifest-path", path3.join(toolsDir, "Cargo.toml")],
|
|
3711
|
+
{
|
|
3712
|
+
cwd: process.cwd(),
|
|
3713
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
3714
|
+
windowsHide: true
|
|
3715
|
+
}
|
|
3716
|
+
);
|
|
3691
3717
|
let stdout = "";
|
|
3692
3718
|
proc.stdout?.on("data", (chunk) => {
|
|
3693
3719
|
stdout += chunk.toString();
|
|
@@ -7842,7 +7868,7 @@ var readTool = {
|
|
|
7842
7868
|
} catch (err) {
|
|
7843
7869
|
const code = err.code;
|
|
7844
7870
|
if (code === "ENOENT") throw new Error(`read: file not found "${input.path}"`);
|
|
7845
|
-
throw new Error(`read: failed to stat "${input.path}": ${toErrorMessage(err)}`);
|
|
7871
|
+
throw new Error(`read: failed to stat "${input.path}": ${toErrorMessage$1(err)}`);
|
|
7846
7872
|
}
|
|
7847
7873
|
if (!stat11.isFile()) throw new Error(`read: "${input.path}" is not a regular file`);
|
|
7848
7874
|
if (stat11.size > MAX_BYTES2) {
|
|
@@ -8017,7 +8043,7 @@ var replaceTool = {
|
|
|
8017
8043
|
if (err.code === "ENOENT") return null;
|
|
8018
8044
|
throw err;
|
|
8019
8045
|
});
|
|
8020
|
-
if (!lstat2
|
|
8046
|
+
if (!lstat2?.isFile()) continue;
|
|
8021
8047
|
if (lstat2.isSymbolicLink()) continue;
|
|
8022
8048
|
let realPath;
|
|
8023
8049
|
try {
|
|
@@ -8028,7 +8054,7 @@ var replaceTool = {
|
|
|
8028
8054
|
const rel = path3.relative(realRoot, realPath);
|
|
8029
8055
|
if (rel.startsWith("..") || path3.isAbsolute(rel)) continue;
|
|
8030
8056
|
const stat11 = await fs2.stat(realPath).catch(() => null);
|
|
8031
|
-
if (!stat11
|
|
8057
|
+
if (!stat11?.isFile()) continue;
|
|
8032
8058
|
let content;
|
|
8033
8059
|
try {
|
|
8034
8060
|
const buf = await fs2.readFile(realPath);
|
|
@@ -8438,7 +8464,7 @@ async function duckduckgoSearch(query2, num, signal) {
|
|
|
8438
8464
|
truncated: results.length >= num
|
|
8439
8465
|
};
|
|
8440
8466
|
} catch (err) {
|
|
8441
|
-
console.log(JSON.stringify({ level: "debug", event: "search_failed", query: query2, error: toErrorMessage$
|
|
8467
|
+
console.log(JSON.stringify({ level: "debug", event: "search_failed", query: query2, error: toErrorMessage$2(err) }));
|
|
8442
8468
|
return {
|
|
8443
8469
|
query: query2,
|
|
8444
8470
|
results: [{ title: "Search unavailable", url: "", snippet: "Could not reach DuckDuckGo" }],
|
|
@@ -8602,7 +8628,7 @@ var setWorkingDirTool = {
|
|
|
8602
8628
|
} catch (err) {
|
|
8603
8629
|
return {
|
|
8604
8630
|
current: ctx.workingDir,
|
|
8605
|
-
error: toErrorMessage$
|
|
8631
|
+
error: toErrorMessage$2(err)
|
|
8606
8632
|
};
|
|
8607
8633
|
}
|
|
8608
8634
|
try {
|
|
@@ -8752,7 +8778,11 @@ var taskTool = {
|
|
|
8752
8778
|
const newIds = new Set(input.tasks.map((t) => t.id));
|
|
8753
8779
|
if (newIds.size !== input.tasks.length) {
|
|
8754
8780
|
const seen = /* @__PURE__ */ new Set();
|
|
8755
|
-
const dupes = [...new Set(input.tasks.map((t) => t.id).filter((id) =>
|
|
8781
|
+
const dupes = [...new Set(input.tasks.map((t) => t.id).filter((id) => {
|
|
8782
|
+
if (seen.has(id)) return true;
|
|
8783
|
+
seen.add(id);
|
|
8784
|
+
return false;
|
|
8785
|
+
}))];
|
|
8756
8786
|
early = {
|
|
8757
8787
|
ok: false,
|
|
8758
8788
|
message: `action=replace has duplicate task IDs: ${dupes.join(", ")}. Each task id must be unique.`,
|
|
@@ -8787,7 +8817,7 @@ var taskTool = {
|
|
|
8787
8817
|
}
|
|
8788
8818
|
case "add": {
|
|
8789
8819
|
const t = input.task;
|
|
8790
|
-
if (!t
|
|
8820
|
+
if (!t?.title) {
|
|
8791
8821
|
early = { ok: false, message: "action=add requires `task` with at least `title`.", count: 0, completed: 0, inProgress: 0 };
|
|
8792
8822
|
return f;
|
|
8793
8823
|
}
|