@brainervirus/workit-cli 8.40.8 → 8.41.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/index.js +745 -374
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -9417,7 +9417,7 @@ var package_default;
|
|
|
9417
9417
|
var init_package = __esm(() => {
|
|
9418
9418
|
package_default = {
|
|
9419
9419
|
name: "@brainervirus/workit-cli",
|
|
9420
|
-
version: "8.
|
|
9420
|
+
version: "8.41.1",
|
|
9421
9421
|
private: false,
|
|
9422
9422
|
description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
9423
9423
|
keywords: [
|
|
@@ -9455,13 +9455,13 @@ var init_package = __esm(() => {
|
|
|
9455
9455
|
},
|
|
9456
9456
|
dependencies: {
|
|
9457
9457
|
"@babel/parser": "7.29.9",
|
|
9458
|
-
"@brainervirus/workit-cursor": "^8.
|
|
9458
|
+
"@brainervirus/workit-cursor": "^8.41.1",
|
|
9459
9459
|
"@inkjs/ui": "2.0.0",
|
|
9460
9460
|
ink: "7.1.1",
|
|
9461
9461
|
react: "19.2.8"
|
|
9462
9462
|
},
|
|
9463
9463
|
devDependencies: {
|
|
9464
|
-
"@brainervirus/workit-core": "^8.
|
|
9464
|
+
"@brainervirus/workit-core": "^8.41.1"
|
|
9465
9465
|
},
|
|
9466
9466
|
engines: {
|
|
9467
9467
|
node: ">=24"
|
|
@@ -66193,7 +66193,7 @@ import path33 from "node:path";
|
|
|
66193
66193
|
function hostCommand(name, args, options = {}) {
|
|
66194
66194
|
const executable = findHostExecutable(name, options);
|
|
66195
66195
|
if (!executable)
|
|
66196
|
-
throw new Error(`${name} executable was not found on PATH or supported user bin directories`);
|
|
66196
|
+
throw new Error(path33.isAbsolute(name) || name.includes("/") || name.includes("\\") ? `${name} does not exist or is not executable` : `${name} executable was not found on PATH or supported user bin directories`);
|
|
66197
66197
|
if (process.platform === "win32" && /\.(?:cmd|bat)$/i.test(executable)) {
|
|
66198
66198
|
const node = findHostExecutable("node", options);
|
|
66199
66199
|
if (!node)
|
|
@@ -66217,6 +66217,17 @@ function resolveWindowsShimEntry(contents, shim, exists = existsSync13) {
|
|
|
66217
66217
|
return null;
|
|
66218
66218
|
}
|
|
66219
66219
|
function findHostExecutable(name, options = {}) {
|
|
66220
|
+
if (path33.isAbsolute(name) || name.includes("/") || name.includes("\\")) {
|
|
66221
|
+
try {
|
|
66222
|
+
if (!statSync2(name).isFile())
|
|
66223
|
+
return null;
|
|
66224
|
+
if (process.platform !== "win32")
|
|
66225
|
+
accessSync(name, constants2.X_OK);
|
|
66226
|
+
return name;
|
|
66227
|
+
} catch {
|
|
66228
|
+
return null;
|
|
66229
|
+
}
|
|
66230
|
+
}
|
|
66220
66231
|
const env = options.env ?? process.env;
|
|
66221
66232
|
const home = options.home ?? env.HOME ?? os9.homedir();
|
|
66222
66233
|
const suffixes = process.platform === "win32" ? ["", ".exe", ".cmd", ".bat"] : [""];
|
|
@@ -67761,7 +67772,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
67761
67772
|
return null;
|
|
67762
67773
|
dir = parent;
|
|
67763
67774
|
}
|
|
67764
|
-
},
|
|
67775
|
+
}, listProcessesMatching = (match) => {
|
|
67765
67776
|
const r = spawnSync16("ps", ["-eo", "pid=,lstart=,args="], {
|
|
67766
67777
|
encoding: "utf8",
|
|
67767
67778
|
timeout: 5000
|
|
@@ -67772,14 +67783,14 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
67772
67783
|
for (const row of r.stdout.split(`
|
|
67773
67784
|
`)) {
|
|
67774
67785
|
const m = /^\s*(\d+)\s+(\w{3}\s+\w{3}\s+\d+\s+[\d:]+\s+\d{4})\s+(.*)$/.exec(row);
|
|
67775
|
-
if (!m ||
|
|
67786
|
+
if (!m || !match(m[3]))
|
|
67776
67787
|
continue;
|
|
67777
67788
|
const startedMs = Date.parse(m[2]);
|
|
67778
67789
|
if (Number.isFinite(startedMs))
|
|
67779
67790
|
found.push({ pid: Number(m[1]), startedMs, args: m[3] });
|
|
67780
67791
|
}
|
|
67781
67792
|
return found;
|
|
67782
|
-
}, resolve = (options) => {
|
|
67793
|
+
}, listClaudeProcesses = () => listProcessesMatching((args) => /^(\S*\/)?claude(\s|$)/.test(args)), listCodexProcesses = () => listProcessesMatching((args) => /^(\S*\/)?codex(\.js)?(\s|$)|^(\S*\/)?node(js)?\s+(\S+\s+)*?\S*\/codex(\.js)?(\s|$)/.test(args) && !/\bdaemon\s+pid-update-loop\b/.test(args)), resolve = (options) => {
|
|
67783
67794
|
const env = options.env ?? process.env;
|
|
67784
67795
|
const home = options.home ?? env.HOME ?? os12.homedir();
|
|
67785
67796
|
const configDir = options.configDir ?? env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path39.join(home, ".config", "workit");
|
|
@@ -67807,7 +67818,8 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
67807
67818
|
installer: options.installer ?? false,
|
|
67808
67819
|
cliVersion: options.cliVersion ?? null,
|
|
67809
67820
|
scopeProbe: options.scopeProbe ?? probeScope,
|
|
67810
|
-
claudeProcesses: options.claudeProcesses ?? listClaudeProcesses
|
|
67821
|
+
claudeProcesses: options.claudeProcesses ?? listClaudeProcesses,
|
|
67822
|
+
codexProcesses: options.codexProcesses ?? listCodexProcesses
|
|
67811
67823
|
};
|
|
67812
67824
|
}, readJson = (p) => {
|
|
67813
67825
|
try {
|
|
@@ -68563,7 +68575,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68563
68575
|
id: "launcher",
|
|
68564
68576
|
status: "fail",
|
|
68565
68577
|
detail: `missing or invalid launcher entry: ${missing.join("; ")}`,
|
|
68566
|
-
fix: `Rebuild and reinstall the workit package (bun run build) — dist entries must be non-empty Node launchers`
|
|
68578
|
+
fix: dev ? `Rebuild and reinstall the workit package (bun run build) — dist entries must be non-empty Node launchers` : "workit upgrade --hosts=cursor — it reinstalls the plugin files and re-registers the MCP launcher"
|
|
68567
68579
|
};
|
|
68568
68580
|
}
|
|
68569
68581
|
if (!dev && res.host !== "cursor") {
|
|
@@ -69804,6 +69816,49 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69804
69816
|
status: "warn",
|
|
69805
69817
|
detail: `started before Workit ${latest.install.version} was installed: ${rows.join("; ")}; quit and start \`claude --resume ${first ?? "<session id>"}\` to load it (\`/resume\` keeps the old plugin)`
|
|
69806
69818
|
};
|
|
69819
|
+
}, checkCodexSessionPlugin = (res) => {
|
|
69820
|
+
const id = "codex_session_plugin";
|
|
69821
|
+
if (process.platform === "win32")
|
|
69822
|
+
return {
|
|
69823
|
+
id,
|
|
69824
|
+
status: "info",
|
|
69825
|
+
detail: "running Codex processes are not checked on Windows"
|
|
69826
|
+
};
|
|
69827
|
+
const installs = codexWorkitInstalls(res).filter((install) => install.root && install.version);
|
|
69828
|
+
const stamped = installs.flatMap((install) => {
|
|
69829
|
+
try {
|
|
69830
|
+
return [{ install, at: statSync6(install.root).mtimeMs }];
|
|
69831
|
+
} catch {
|
|
69832
|
+
return [];
|
|
69833
|
+
}
|
|
69834
|
+
});
|
|
69835
|
+
const latest = stamped.toSorted((a, b) => b.at - a.at)[0];
|
|
69836
|
+
if (!latest)
|
|
69837
|
+
return {
|
|
69838
|
+
id,
|
|
69839
|
+
status: "info",
|
|
69840
|
+
detail: "no Workit Codex plugin install recorded — skipping"
|
|
69841
|
+
};
|
|
69842
|
+
const running = res.codexProcesses();
|
|
69843
|
+
if (running === null)
|
|
69844
|
+
return {
|
|
69845
|
+
id,
|
|
69846
|
+
status: "info",
|
|
69847
|
+
detail: "could not list running codex processes (ps) — skipping"
|
|
69848
|
+
};
|
|
69849
|
+
const stale = running.filter((proc) => proc.startedMs < latest.at);
|
|
69850
|
+
if (stale.length === 0)
|
|
69851
|
+
return {
|
|
69852
|
+
id,
|
|
69853
|
+
status: "info",
|
|
69854
|
+
detail: `${running.length} running codex process(es), none started before Workit ${latest.install.version} was installed`
|
|
69855
|
+
};
|
|
69856
|
+
const rows = stale.map((proc) => `pid ${proc.pid} started ${new Date(proc.startedMs).toISOString()} (${proc.args.slice(0, 60)})`);
|
|
69857
|
+
return {
|
|
69858
|
+
id,
|
|
69859
|
+
status: "warn",
|
|
69860
|
+
detail: `started before Workit ${latest.install.version} was installed: ${rows.join("; ")}; they keep the old plugin until restarted, new Codex sessions load it`
|
|
69861
|
+
};
|
|
69807
69862
|
}, HOOK_ISSUED_MARKER = "workit-issued-sessions/3", hookRecordsIssued = (root) => {
|
|
69808
69863
|
let files;
|
|
69809
69864
|
try {
|
|
@@ -70095,6 +70150,7 @@ var init_doctor = __esm(() => {
|
|
|
70095
70150
|
checkOpencodeVersion,
|
|
70096
70151
|
checkClaudePlugin,
|
|
70097
70152
|
checkClaudeSessionPlugin,
|
|
70153
|
+
checkCodexSessionPlugin,
|
|
70098
70154
|
checkHookIssuedSessions,
|
|
70099
70155
|
checkWorkitOnPath,
|
|
70100
70156
|
checkAssets,
|
|
@@ -75218,38 +75274,204 @@ var init_setup2 = __esm(() => {
|
|
|
75218
75274
|
ALL_HOSTS = ["claude-code", "codex", "cursor", "opencode", "pi"];
|
|
75219
75275
|
});
|
|
75220
75276
|
|
|
75277
|
+
// packages/workit-cli/src/progress.ts
|
|
75278
|
+
import { spawn } from "node:child_process";
|
|
75279
|
+
import path44 from "node:path";
|
|
75280
|
+
function createProgress(options = {}) {
|
|
75281
|
+
const env = options.env ?? process.env;
|
|
75282
|
+
const mode = modeFor(options, env);
|
|
75283
|
+
const stream = options.stream;
|
|
75284
|
+
const now = options.now ?? Date.now;
|
|
75285
|
+
const every = options.setInterval ?? ((tick, ms) => setInterval(tick, ms));
|
|
75286
|
+
const stop = options.clearInterval ?? ((timer) => clearInterval(timer));
|
|
75287
|
+
const proc = options.proc ?? process;
|
|
75288
|
+
const ascii = env.TERM === "dumb";
|
|
75289
|
+
const glyphs = mode === "spinner" ? { done: "\x1B[32m✓\x1B[0m", failed: "\x1B[31m✗\x1B[0m", skipped: "–" } : ascii ? { done: "ok", failed: "x", skipped: "-" } : { done: "✓", failed: "✗", skipped: "–" };
|
|
75290
|
+
const start = (initial) => {
|
|
75291
|
+
if (mode === "off" || !stream)
|
|
75292
|
+
return NOOP_STEP;
|
|
75293
|
+
let text = initial;
|
|
75294
|
+
let finished = false;
|
|
75295
|
+
const began = now();
|
|
75296
|
+
let frame = 0;
|
|
75297
|
+
const draw = () => {
|
|
75298
|
+
const seconds = Math.floor((now() - began) / 1000);
|
|
75299
|
+
let line = `${FRAMES[frame % FRAMES.length]} ${text} (${seconds}s)`;
|
|
75300
|
+
if (stream.columns && line.length >= stream.columns)
|
|
75301
|
+
line = `${line.slice(0, Math.max(1, stream.columns - 2))}…`;
|
|
75302
|
+
stream.write(`${CLEAR}${line}`);
|
|
75303
|
+
};
|
|
75304
|
+
let timer;
|
|
75305
|
+
if (mode === "spinner") {
|
|
75306
|
+
draw();
|
|
75307
|
+
timer = every(() => {
|
|
75308
|
+
frame += 1;
|
|
75309
|
+
draw();
|
|
75310
|
+
}, FRAME_MS);
|
|
75311
|
+
}
|
|
75312
|
+
const handlers = [];
|
|
75313
|
+
const release = () => {
|
|
75314
|
+
for (const [event, handler] of handlers)
|
|
75315
|
+
proc.off(event, handler);
|
|
75316
|
+
handlers.length = 0;
|
|
75317
|
+
};
|
|
75318
|
+
if (mode === "spinner") {
|
|
75319
|
+
const onSignal = (signal) => () => {
|
|
75320
|
+
if (!finished) {
|
|
75321
|
+
finished = true;
|
|
75322
|
+
if (timer !== undefined)
|
|
75323
|
+
stop(timer);
|
|
75324
|
+
stream.write(CLEAR);
|
|
75325
|
+
}
|
|
75326
|
+
release();
|
|
75327
|
+
proc.kill(proc.pid, signal);
|
|
75328
|
+
};
|
|
75329
|
+
const onExit = () => {
|
|
75330
|
+
if (!finished)
|
|
75331
|
+
stream.write(CLEAR);
|
|
75332
|
+
};
|
|
75333
|
+
handlers.push(["SIGINT", onSignal("SIGINT")], ["SIGTERM", onSignal("SIGTERM")]);
|
|
75334
|
+
handlers.push(["exit", onExit]);
|
|
75335
|
+
for (const [event, handler] of handlers)
|
|
75336
|
+
proc.on(event, handler);
|
|
75337
|
+
}
|
|
75338
|
+
return {
|
|
75339
|
+
label: (next) => {
|
|
75340
|
+
text = next;
|
|
75341
|
+
if (mode === "spinner" && !finished)
|
|
75342
|
+
draw();
|
|
75343
|
+
},
|
|
75344
|
+
end: (status, note) => {
|
|
75345
|
+
if (finished)
|
|
75346
|
+
return;
|
|
75347
|
+
finished = true;
|
|
75348
|
+
if (timer !== undefined)
|
|
75349
|
+
stop(timer);
|
|
75350
|
+
release();
|
|
75351
|
+
stream.write(`${mode === "spinner" ? CLEAR : ""}${glyphs[status]} ${text}${note ? `: ${note}` : ""}
|
|
75352
|
+
`);
|
|
75353
|
+
}
|
|
75354
|
+
};
|
|
75355
|
+
};
|
|
75356
|
+
return {
|
|
75357
|
+
mode,
|
|
75358
|
+
start,
|
|
75359
|
+
async run(label, fn, classify) {
|
|
75360
|
+
const step = start(label);
|
|
75361
|
+
try {
|
|
75362
|
+
const value = await fn();
|
|
75363
|
+
step.end(classify ? classify(value) : "done");
|
|
75364
|
+
return value;
|
|
75365
|
+
} catch (error) {
|
|
75366
|
+
step.end("failed");
|
|
75367
|
+
throw error;
|
|
75368
|
+
}
|
|
75369
|
+
},
|
|
75370
|
+
runSync(label, fn, classify) {
|
|
75371
|
+
const step = start(label);
|
|
75372
|
+
const ticker = mode === "spinner" && stream ? (options.spawnTicker ?? ((text, began) => defaultTicker(text, began, stream)))(label, now()) : undefined;
|
|
75373
|
+
try {
|
|
75374
|
+
const value = fn();
|
|
75375
|
+
ticker?.stop();
|
|
75376
|
+
step.end(classify ? classify(value) : "done");
|
|
75377
|
+
return value;
|
|
75378
|
+
} catch (error) {
|
|
75379
|
+
ticker?.stop();
|
|
75380
|
+
step.end("failed");
|
|
75381
|
+
throw error;
|
|
75382
|
+
}
|
|
75383
|
+
}
|
|
75384
|
+
};
|
|
75385
|
+
}
|
|
75386
|
+
var FRAMES, FRAME_MS = 120, CLEAR = "\r\x1B[2K", TICKER_SOURCE, defaultTicker = (label, began, stream) => {
|
|
75387
|
+
if (stream !== process.stderr)
|
|
75388
|
+
return;
|
|
75389
|
+
if (!/^(?:node|nodejs|bun)(?:\.exe)?$/i.test(path44.basename(process.execPath)))
|
|
75390
|
+
return;
|
|
75391
|
+
try {
|
|
75392
|
+
const child = spawn(process.execPath, ["-e", TICKER_SOURCE], {
|
|
75393
|
+
env: {
|
|
75394
|
+
...process.env,
|
|
75395
|
+
WORKIT_TICK_LABEL: label,
|
|
75396
|
+
WORKIT_TICK_BEGAN: String(began),
|
|
75397
|
+
WORKIT_TICK_COLS: String(stream.columns ?? 0)
|
|
75398
|
+
},
|
|
75399
|
+
stdio: ["ignore", "ignore", "inherit"],
|
|
75400
|
+
windowsHide: true
|
|
75401
|
+
});
|
|
75402
|
+
child.on("error", () => {});
|
|
75403
|
+
child.unref();
|
|
75404
|
+
return { stop: () => void child.kill("SIGKILL") };
|
|
75405
|
+
} catch {
|
|
75406
|
+
return;
|
|
75407
|
+
}
|
|
75408
|
+
}, truthy = (value) => value !== undefined && value !== "" && value !== "0" && value.toLowerCase() !== "false", modeFor = (options, env) => {
|
|
75409
|
+
if (options.json || !options.stream?.isTTY || truthy(env.CI))
|
|
75410
|
+
return "off";
|
|
75411
|
+
if (truthy(env.NO_COLOR) || env.TERM === "dumb")
|
|
75412
|
+
return "plain";
|
|
75413
|
+
return "spinner";
|
|
75414
|
+
}, NOOP_STEP;
|
|
75415
|
+
var init_progress = __esm(() => {
|
|
75416
|
+
FRAMES = ["·", "✢", "✳", "∗", "✻", "✽"];
|
|
75417
|
+
TICKER_SOURCE = `
|
|
75418
|
+
const frames = ${JSON.stringify(FRAMES)};
|
|
75419
|
+
const { WORKIT_TICK_LABEL: label, WORKIT_TICK_BEGAN: began, WORKIT_TICK_COLS: cols } = process.env;
|
|
75420
|
+
const parent = process.ppid;
|
|
75421
|
+
let frame = 0;
|
|
75422
|
+
const timer = setInterval(() => {
|
|
75423
|
+
let alive = process.ppid === parent;
|
|
75424
|
+
if (alive) try { process.kill(parent, 0); } catch { alive = false; }
|
|
75425
|
+
if (!alive || Date.now() - Number(began) > 600000) process.exit(0);
|
|
75426
|
+
frame += 1;
|
|
75427
|
+
const seconds = Math.floor((Date.now() - Number(began)) / 1000);
|
|
75428
|
+
let line = frames[frame % frames.length] + " " + label + " (" + seconds + "s)";
|
|
75429
|
+
if (Number(cols) && line.length >= Number(cols)) line = line.slice(0, Math.max(1, Number(cols) - 2)) + "…";
|
|
75430
|
+
process.stderr.write(${JSON.stringify(CLEAR)} + line);
|
|
75431
|
+
}, ${FRAME_MS});
|
|
75432
|
+
`;
|
|
75433
|
+
NOOP_STEP = { label: () => {}, end: () => {} };
|
|
75434
|
+
});
|
|
75435
|
+
|
|
75221
75436
|
// packages/workit-cli/src/upgrade/shared.ts
|
|
75437
|
+
import { spawn as spawn2 } from "node:child_process";
|
|
75222
75438
|
import { existsSync as existsSync21, readFileSync as readFileSync22 } from "node:fs";
|
|
75223
|
-
import
|
|
75439
|
+
import path45 from "node:path";
|
|
75224
75440
|
import os16 from "node:os";
|
|
75225
75441
|
import { createHash as createHash15 } from "node:crypto";
|
|
75226
|
-
|
|
75442
|
+
function errorText(error) {
|
|
75443
|
+
return error instanceof Error ? error.message : "installed source could not be read";
|
|
75444
|
+
}
|
|
75445
|
+
var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-opencode", OPENCODE_UPDATE, CODEX_MARKETPLACE = "workflow-toolkit", CLI_FIX = "npm install --global @brainervirus/workit-cli@latest", stderrTail = (text, lines = 5) => (text ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).slice(-lines).join(" | "), failureReason = (command, result) => {
|
|
75446
|
+
const tail = stderrTail(result.stderr);
|
|
75447
|
+
return `\`${command.command} ${command.args.join(" ")}\` failed${tail ? `: ${tail}` : ""}`;
|
|
75448
|
+
}, fixFor = (host, selector = "") => host === "pi" ? `pi update --extension ${selector || "npm:@brainervirus/workit-pi"}` : host === "codex" ? `codex plugin marketplace upgrade ${CODEX_MARKETPLACE} && codex plugin add workit@${CODEX_MARKETPLACE}` : host === "claude-code" ? "claude plugin marketplace update workit && claude plugin update workit@workit" : host === "opencode" ? OPENCODE_UPDATE : host === "cursor" ? "workit upgrade --hosts=cursor" : CLI_FIX, upgradePaths = (deps) => {
|
|
75227
75449
|
const home = deps.home ?? deps.env?.HOME ?? os16.homedir();
|
|
75228
75450
|
const env = {
|
|
75229
75451
|
...process.env,
|
|
75230
75452
|
...deps.home || deps.env?.HOME ? {
|
|
75231
75453
|
HOME: home,
|
|
75232
|
-
CODEX_HOME:
|
|
75233
|
-
CLAUDE_CONFIG_DIR:
|
|
75234
|
-
PI_CODING_AGENT_DIR:
|
|
75235
|
-
XDG_CONFIG_HOME:
|
|
75454
|
+
CODEX_HOME: path45.join(home, ".codex"),
|
|
75455
|
+
CLAUDE_CONFIG_DIR: path45.join(home, ".claude"),
|
|
75456
|
+
PI_CODING_AGENT_DIR: path45.join(home, ".pi/agent"),
|
|
75457
|
+
XDG_CONFIG_HOME: path45.join(home, ".config"),
|
|
75236
75458
|
WORKFLOW_TOOLKIT_CONFIG: undefined,
|
|
75237
75459
|
WORKFLOW_TOOLKIT_CONFIG_DIR: undefined
|
|
75238
75460
|
} : {},
|
|
75239
75461
|
...deps.env,
|
|
75240
75462
|
HOME: home
|
|
75241
75463
|
};
|
|
75242
|
-
const xdg = env.XDG_CONFIG_HOME ||
|
|
75243
|
-
const codexHome = env.CODEX_HOME ??
|
|
75464
|
+
const xdg = env.XDG_CONFIG_HOME || path45.join(home, ".config");
|
|
75465
|
+
const codexHome = env.CODEX_HOME ?? path45.join(home, ".codex");
|
|
75244
75466
|
return {
|
|
75245
75467
|
home,
|
|
75246
75468
|
env,
|
|
75247
|
-
configDir: env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ??
|
|
75248
|
-
opencodeConfig:
|
|
75249
|
-
piSettings:
|
|
75469
|
+
configDir: env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path45.join(xdg, "workit"),
|
|
75470
|
+
opencodeConfig: path45.join(xdg, "opencode/opencode.json"),
|
|
75471
|
+
piSettings: path45.join(env.PI_CODING_AGENT_DIR ?? path45.join(home, ".pi/agent"), "settings.json"),
|
|
75250
75472
|
codexHome,
|
|
75251
|
-
codexConfig:
|
|
75252
|
-
cursorRoot:
|
|
75473
|
+
codexConfig: path45.join(codexHome, "config.toml"),
|
|
75474
|
+
cursorRoot: path45.join(home, ".cursor/plugins/local/workit")
|
|
75253
75475
|
};
|
|
75254
75476
|
}, object2 = (file) => {
|
|
75255
75477
|
if (!existsSync21(file))
|
|
@@ -75274,17 +75496,81 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75274
75496
|
let step;
|
|
75275
75497
|
try {
|
|
75276
75498
|
step = hostCommand(command, args, { home, env });
|
|
75277
|
-
} catch {
|
|
75278
|
-
return { status: 1, stdout: "" };
|
|
75499
|
+
} catch (error) {
|
|
75500
|
+
return { status: 1, stdout: "", stderr: errorText(error) };
|
|
75279
75501
|
}
|
|
75280
75502
|
const result = runHostCommand(step, { home, env });
|
|
75281
|
-
return { status: result.exitCode, stdout: result.stdout };
|
|
75282
|
-
}),
|
|
75503
|
+
return { status: result.exitCode, stdout: result.stdout, stderr: result.stderr };
|
|
75504
|
+
}), COMMAND_TIMEOUT_MS = 60000, asyncRunner = (deps) => {
|
|
75505
|
+
if (deps.runAsync)
|
|
75506
|
+
return deps.runAsync;
|
|
75507
|
+
const injected = deps.run;
|
|
75508
|
+
if (injected)
|
|
75509
|
+
return async (command, args) => injected(command, args);
|
|
75510
|
+
return (command, args) => {
|
|
75511
|
+
const { home, env } = upgradePaths(deps);
|
|
75512
|
+
let step;
|
|
75513
|
+
try {
|
|
75514
|
+
step = hostCommand(command, args, { home, env });
|
|
75515
|
+
} catch (error) {
|
|
75516
|
+
return Promise.resolve({ status: 1, stdout: "", stderr: errorText(error) });
|
|
75517
|
+
}
|
|
75518
|
+
if (process.platform === "win32" && /\.(?:cmd|bat)$/i.test(step.command))
|
|
75519
|
+
return Promise.resolve({
|
|
75520
|
+
status: 1,
|
|
75521
|
+
stdout: "",
|
|
75522
|
+
stderr: `Cannot safely execute batch shim ${step.command}`
|
|
75523
|
+
});
|
|
75524
|
+
const childEnv = { ...process.env, ...env, HOME: home };
|
|
75525
|
+
childEnv.CODEX_HOME = env.CODEX_HOME ?? path45.join(home, ".codex");
|
|
75526
|
+
childEnv.PI_CODING_AGENT_DIR = env.PI_CODING_AGENT_DIR ?? path45.join(home, ".pi", "agent");
|
|
75527
|
+
childEnv.CLAUDE_CONFIG_DIR = env.CLAUDE_CONFIG_DIR ?? path45.join(home, ".claude");
|
|
75528
|
+
childEnv.XDG_CONFIG_HOME = env.XDG_CONFIG_HOME ?? path45.join(home, ".config");
|
|
75529
|
+
return new Promise((resolve) => {
|
|
75530
|
+
let stdout = "";
|
|
75531
|
+
let stderr = "";
|
|
75532
|
+
let settled = false;
|
|
75533
|
+
const finish = (status) => {
|
|
75534
|
+
if (settled)
|
|
75535
|
+
return;
|
|
75536
|
+
settled = true;
|
|
75537
|
+
clearTimeout(timer);
|
|
75538
|
+
resolve({ status, stdout, stderr });
|
|
75539
|
+
};
|
|
75540
|
+
let child;
|
|
75541
|
+
try {
|
|
75542
|
+
child = spawn2(step.command, step.args, {
|
|
75543
|
+
cwd: step.cwd,
|
|
75544
|
+
env: childEnv,
|
|
75545
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
75546
|
+
windowsHide: true,
|
|
75547
|
+
shell: false
|
|
75548
|
+
});
|
|
75549
|
+
} catch (error) {
|
|
75550
|
+
resolve({ status: 1, stdout: "", stderr: errorText(error) });
|
|
75551
|
+
return;
|
|
75552
|
+
}
|
|
75553
|
+
const timer = setTimeout(() => {
|
|
75554
|
+
child.kill("SIGKILL");
|
|
75555
|
+
finish(1);
|
|
75556
|
+
}, COMMAND_TIMEOUT_MS);
|
|
75557
|
+
child.stdout?.setEncoding("utf8");
|
|
75558
|
+
child.stdout?.on("data", (chunk) => stdout += chunk);
|
|
75559
|
+
child.stderr?.setEncoding("utf8");
|
|
75560
|
+
child.stderr?.on("data", (chunk) => stderr = (stderr + chunk).slice(-4000));
|
|
75561
|
+
child.on("error", (error) => {
|
|
75562
|
+
stderr += error.message;
|
|
75563
|
+
finish(1);
|
|
75564
|
+
});
|
|
75565
|
+
child.on("close", (code) => finish(code ?? 1));
|
|
75566
|
+
});
|
|
75567
|
+
};
|
|
75568
|
+
}, piInstalledVersion = (listing, selector) => {
|
|
75283
75569
|
const lines = listing.split(/\r?\n/).map((line) => line.trim());
|
|
75284
75570
|
const index = lines.indexOf(selector);
|
|
75285
|
-
if (index < 0 || !lines[index + 1] || !
|
|
75571
|
+
if (index < 0 || !lines[index + 1] || !path45.isAbsolute(lines[index + 1]))
|
|
75286
75572
|
return;
|
|
75287
|
-
const found = objectOrNull(
|
|
75573
|
+
const found = objectOrNull(path45.join(lines[index + 1], "package.json"));
|
|
75288
75574
|
return found?.name === "@brainervirus/workit-pi" ? found.version : undefined;
|
|
75289
75575
|
}, versionAtLeast = (installed, latest) => {
|
|
75290
75576
|
if (!/^\d+\.\d+\.\d+$/.test(installed))
|
|
@@ -75310,12 +75596,12 @@ var init_shared = __esm(() => {
|
|
|
75310
75596
|
});
|
|
75311
75597
|
|
|
75312
75598
|
// packages/workit-cli/src/upgrade/processes.ts
|
|
75313
|
-
import
|
|
75599
|
+
import path46 from "node:path";
|
|
75314
75600
|
var PROCESS_HOSTS, SCRIPT_RUNTIMES, classifyProcess = (proc) => {
|
|
75315
75601
|
if (proc.state.startsWith("Z") || proc.args.includes("<defunct>"))
|
|
75316
75602
|
return null;
|
|
75317
75603
|
const argv0 = proc.args.trim().split(/\s+/)[0] ?? "";
|
|
75318
|
-
const baseName = (value) =>
|
|
75604
|
+
const baseName = (value) => path46.basename(value.replaceAll("\\", "/")).replace(/^\[|\]$/g, "").replace(/\.exe$/i, "").toLowerCase();
|
|
75319
75605
|
let host = PROCESS_HOSTS[baseName(argv0)];
|
|
75320
75606
|
if (!host && SCRIPT_RUNTIMES.has(baseName(argv0))) {
|
|
75321
75607
|
const script = proc.args.trim().split(/\s+/).slice(1).find((arg) => !arg.startsWith("-"));
|
|
@@ -75366,9 +75652,9 @@ var init_processes = __esm(() => {
|
|
|
75366
75652
|
|
|
75367
75653
|
// packages/workit-cli/src/upgrade/apply.ts
|
|
75368
75654
|
import { existsSync as existsSync22, readdirSync as readdirSync12, mkdirSync as mkdirSync11, copyFileSync as copyFileSync6, chmodSync as chmodSync2, cpSync as cpSync5 } from "node:fs";
|
|
75369
|
-
import
|
|
75655
|
+
import path47 from "node:path";
|
|
75370
75656
|
import { createHash as createHash16 } from "node:crypto";
|
|
75371
|
-
function applyUpgrade(plan, deps = {}) {
|
|
75657
|
+
async function applyUpgrade(plan, deps = {}) {
|
|
75372
75658
|
const hosts = [...plan.failed];
|
|
75373
75659
|
const done = (backup) => {
|
|
75374
75660
|
const failures = hosts.filter((entry) => entry.status === "failed");
|
|
@@ -75401,11 +75687,11 @@ function applyUpgrade(plan, deps = {}) {
|
|
|
75401
75687
|
};
|
|
75402
75688
|
const paths = upgradePaths(deps);
|
|
75403
75689
|
const { home, configDir } = paths;
|
|
75404
|
-
const backup =
|
|
75690
|
+
const backup = path47.join(home, ".local/state/workit/upgrades", new Date().toISOString().replaceAll(":", "-"));
|
|
75405
75691
|
mkdirSync11(backup, { recursive: true, mode: 448 });
|
|
75406
75692
|
for (const file of Object.keys(plan.configDigests))
|
|
75407
75693
|
if (existsSync22(file)) {
|
|
75408
|
-
const target =
|
|
75694
|
+
const target = path47.join(backup, createHash16("sha256").update(file).digest("hex").slice(0, 12) + "-" + path47.basename(file));
|
|
75409
75695
|
copyFileSync6(file, target);
|
|
75410
75696
|
chmodSync2(target, 384);
|
|
75411
75697
|
}
|
|
@@ -75422,11 +75708,13 @@ function applyUpgrade(plan, deps = {}) {
|
|
|
75422
75708
|
writeFileAtomic(migration.file, JSON.stringify(value, null, 2) + `
|
|
75423
75709
|
`, 384);
|
|
75424
75710
|
}
|
|
75425
|
-
const
|
|
75711
|
+
const runAsync = asyncRunner(deps);
|
|
75712
|
+
const progress = deps.progress ?? createProgress({ json: true });
|
|
75713
|
+
const statusOf = (outcome) => outcome?.status === "failed" ? "failed" : outcome?.status === "updated" ? "done" : "skipped";
|
|
75426
75714
|
let cursorBackupError = null;
|
|
75427
75715
|
if (plan.entries.some((entry) => entry.host === "cursor") && existsSync22(paths.cursorRoot))
|
|
75428
75716
|
try {
|
|
75429
|
-
cpSync5(paths.cursorRoot,
|
|
75717
|
+
cpSync5(paths.cursorRoot, path47.join(backup, "cursor-package"), {
|
|
75430
75718
|
recursive: true
|
|
75431
75719
|
});
|
|
75432
75720
|
} catch (error) {
|
|
@@ -75435,96 +75723,107 @@ function applyUpgrade(plan, deps = {}) {
|
|
|
75435
75723
|
const listed = plan.entries.length ? listProcesses(deps) : [];
|
|
75436
75724
|
const running = (listed ?? []).flatMap((entry) => classifyProcess(entry) ?? []);
|
|
75437
75725
|
for (const entry of plan.entries) {
|
|
75438
|
-
|
|
75439
|
-
|
|
75440
|
-
|
|
75441
|
-
|
|
75442
|
-
reason: cursorBackupError,
|
|
75443
|
-
fix: entry.fix
|
|
75444
|
-
});
|
|
75445
|
-
continue;
|
|
75446
|
-
}
|
|
75447
|
-
if (!LIVE_HOSTS.has(entry.host)) {
|
|
75448
|
-
if (listed === null) {
|
|
75726
|
+
const before = hosts.length;
|
|
75727
|
+
const step = progress.start(`Updating ${entry.host}`);
|
|
75728
|
+
try {
|
|
75729
|
+
if (entry.host === "cursor" && cursorBackupError) {
|
|
75449
75730
|
hosts.push({
|
|
75450
|
-
host:
|
|
75451
|
-
status: "
|
|
75452
|
-
reason:
|
|
75453
|
-
fix:
|
|
75731
|
+
host: "cursor",
|
|
75732
|
+
status: "failed",
|
|
75733
|
+
reason: cursorBackupError,
|
|
75734
|
+
fix: entry.fix
|
|
75454
75735
|
});
|
|
75455
75736
|
continue;
|
|
75456
75737
|
}
|
|
75457
|
-
|
|
75458
|
-
|
|
75738
|
+
if (!LIVE_HOSTS.has(entry.host)) {
|
|
75739
|
+
if (listed === null) {
|
|
75740
|
+
hosts.push({
|
|
75741
|
+
host: entry.host,
|
|
75742
|
+
status: "skipped",
|
|
75743
|
+
reason: `running processes could not be listed; close ${entry.host} and rerun`,
|
|
75744
|
+
fix: `workit upgrade --hosts=${entry.host}`
|
|
75745
|
+
});
|
|
75746
|
+
continue;
|
|
75747
|
+
}
|
|
75748
|
+
const sessions = running.filter((proc) => proc.host === entry.host && proc.kind === "session");
|
|
75749
|
+
if (sessions.length) {
|
|
75750
|
+
hosts.push({
|
|
75751
|
+
host: entry.host,
|
|
75752
|
+
status: "skipped",
|
|
75753
|
+
reason: `close ${entry.host} (${sessions.map(describe2).join("; ")}), then rerun`,
|
|
75754
|
+
fix: `workit upgrade --hosts=${entry.host}`
|
|
75755
|
+
});
|
|
75756
|
+
continue;
|
|
75757
|
+
}
|
|
75758
|
+
}
|
|
75759
|
+
const daemons = running.filter((proc) => proc.host === "codex" && proc.kind === "daemon");
|
|
75760
|
+
const stopDaemon = entry.host === "codex" && daemons.length > 0;
|
|
75761
|
+
const stopped = stopDaemon ? await progress.run("Stopping the Codex app-server daemon", () => runAsync("codex", ["app-server", "daemon", "stop"]), (result) => result.status === 0 ? "done" : "failed") : null;
|
|
75762
|
+
if (stopped && stopped.status !== 0) {
|
|
75459
75763
|
hosts.push({
|
|
75460
|
-
host:
|
|
75461
|
-
status: "
|
|
75462
|
-
reason: `
|
|
75463
|
-
fix:
|
|
75764
|
+
host: "codex",
|
|
75765
|
+
status: "failed",
|
|
75766
|
+
reason: `could not stop the Codex app-server daemon (${daemons.map(describe2).join("; ")})${stderrTail(stopped.stderr) ? `: ${stderrTail(stopped.stderr)}` : ""}`,
|
|
75767
|
+
fix: "codex app-server daemon stop && workit upgrade --hosts=codex"
|
|
75464
75768
|
});
|
|
75465
75769
|
continue;
|
|
75466
75770
|
}
|
|
75467
|
-
|
|
75468
|
-
|
|
75469
|
-
|
|
75470
|
-
|
|
75471
|
-
|
|
75472
|
-
|
|
75473
|
-
|
|
75474
|
-
|
|
75475
|
-
|
|
75476
|
-
|
|
75477
|
-
|
|
75478
|
-
|
|
75479
|
-
|
|
75480
|
-
|
|
75481
|
-
|
|
75482
|
-
|
|
75483
|
-
|
|
75484
|
-
|
|
75771
|
+
let outcome;
|
|
75772
|
+
try {
|
|
75773
|
+
outcome = await applyEntry(entry, { runAsync, paths, configDir });
|
|
75774
|
+
if (entry.host === "codex" && outcome.status === "updated") {
|
|
75775
|
+
const agents = await refreshCodexAgents(runAsync, paths.codexHome);
|
|
75776
|
+
if (!agents.ok)
|
|
75777
|
+
outcome = {
|
|
75778
|
+
...outcome,
|
|
75779
|
+
status: "failed",
|
|
75780
|
+
reason: `${outcome.reason}; ${agents.note}`,
|
|
75781
|
+
fix: agents.fix
|
|
75782
|
+
};
|
|
75783
|
+
else if (agents.note)
|
|
75784
|
+
outcome = {
|
|
75785
|
+
...outcome,
|
|
75786
|
+
reason: `${outcome.reason}; ${agents.note}`
|
|
75787
|
+
};
|
|
75788
|
+
}
|
|
75789
|
+
} catch (error) {
|
|
75790
|
+
outcome = {
|
|
75791
|
+
host: entry.host,
|
|
75792
|
+
status: "failed",
|
|
75793
|
+
reason: errorText(error),
|
|
75794
|
+
fix: entry.fix
|
|
75795
|
+
};
|
|
75796
|
+
}
|
|
75797
|
+
if (stopDaemon) {
|
|
75798
|
+
const started = (await progress.run("Restarting the Codex app-server daemon", () => runAsync("codex", ["app-server", "daemon", "start"]), (result) => result.status === 0 ? "done" : "failed")).status === 0;
|
|
75799
|
+
outcome = started ? {
|
|
75800
|
+
...outcome,
|
|
75801
|
+
reason: `${outcome.reason}; app-server daemon stopped and started again`
|
|
75802
|
+
} : {
|
|
75803
|
+
...outcome,
|
|
75804
|
+
status: "failed",
|
|
75805
|
+
reason: `${outcome.reason}; the app-server daemon did not start again`,
|
|
75806
|
+
fix: "codex app-server daemon start"
|
|
75807
|
+
};
|
|
75808
|
+
}
|
|
75809
|
+
if (entry.host === "opencode") {
|
|
75810
|
+
const servers = running.filter((proc) => proc.host === "opencode" && proc.kind === "daemon");
|
|
75811
|
+
if (servers.length && outcome.status === "updated")
|
|
75485
75812
|
outcome = {
|
|
75486
75813
|
...outcome,
|
|
75487
|
-
|
|
75488
|
-
reason: `${outcome.reason}; ${agents.note}`,
|
|
75489
|
-
fix: agents.fix
|
|
75814
|
+
reason: `${outcome.reason}; restart opencode serve (${servers.map(describe2).join("; ")}) to load it`
|
|
75490
75815
|
};
|
|
75491
|
-
else if (agents.note)
|
|
75492
|
-
outcome = { ...outcome, reason: `${outcome.reason}; ${agents.note}` };
|
|
75493
75816
|
}
|
|
75494
|
-
|
|
75495
|
-
|
|
75496
|
-
|
|
75497
|
-
|
|
75498
|
-
reason: errorText(error),
|
|
75499
|
-
fix: entry.fix
|
|
75500
|
-
};
|
|
75501
|
-
}
|
|
75502
|
-
if (stopDaemon) {
|
|
75503
|
-
const started = run("codex", ["app-server", "daemon", "start"]).status === 0;
|
|
75504
|
-
outcome = started ? {
|
|
75505
|
-
...outcome,
|
|
75506
|
-
reason: `${outcome.reason}; app-server daemon stopped and started again`
|
|
75507
|
-
} : {
|
|
75508
|
-
...outcome,
|
|
75509
|
-
status: "failed",
|
|
75510
|
-
reason: `${outcome.reason}; the app-server daemon did not start again`,
|
|
75511
|
-
fix: "codex app-server daemon start"
|
|
75512
|
-
};
|
|
75513
|
-
}
|
|
75514
|
-
if (entry.host === "opencode") {
|
|
75515
|
-
const servers = running.filter((proc) => proc.host === "opencode" && proc.kind === "daemon");
|
|
75516
|
-
if (servers.length && outcome.status === "updated")
|
|
75517
|
-
outcome = {
|
|
75518
|
-
...outcome,
|
|
75519
|
-
reason: `${outcome.reason}; restart opencode serve (${servers.map(describe2).join("; ")}) to load it`
|
|
75520
|
-
};
|
|
75817
|
+
hosts.push(outcome);
|
|
75818
|
+
} finally {
|
|
75819
|
+
const added = hosts.length > before ? hosts[hosts.length - 1] : undefined;
|
|
75820
|
+
step.end(statusOf(added), added && added.status !== "updated" ? added.reason : undefined);
|
|
75521
75821
|
}
|
|
75522
|
-
hosts.push(outcome);
|
|
75523
75822
|
}
|
|
75524
75823
|
if (hosts.some((entry) => entry.host === "codex" && entry.status === "current")) {
|
|
75525
75824
|
let agents;
|
|
75526
75825
|
try {
|
|
75527
|
-
agents = refreshCodexAgents(
|
|
75826
|
+
agents = await refreshCodexAgents(runAsync, paths.codexHome);
|
|
75528
75827
|
} catch (error) {
|
|
75529
75828
|
agents = {
|
|
75530
75829
|
ok: false,
|
|
@@ -75548,7 +75847,7 @@ function applyUpgrade(plan, deps = {}) {
|
|
|
75548
75847
|
}
|
|
75549
75848
|
if (plan.cli)
|
|
75550
75849
|
try {
|
|
75551
|
-
hosts.push(applyCli(plan.cli,
|
|
75850
|
+
hosts.push(await progress.run("Updating the CLI", () => applyCli(plan.cli, runAsync, backup), statusOf));
|
|
75552
75851
|
} catch (error) {
|
|
75553
75852
|
hosts.push({
|
|
75554
75853
|
host: "cli",
|
|
@@ -75559,8 +75858,11 @@ function applyUpgrade(plan, deps = {}) {
|
|
|
75559
75858
|
}
|
|
75560
75859
|
return done(backup);
|
|
75561
75860
|
}
|
|
75562
|
-
var
|
|
75563
|
-
const
|
|
75861
|
+
var briefDetail = (detail) => {
|
|
75862
|
+
const lines = detail.split(/\r?\n/).filter((line) => line.trim());
|
|
75863
|
+
return (lines.length > 6 ? [lines[0], ...lines.slice(-5)] : lines).join(" | ");
|
|
75864
|
+
}, codexPluginRoot = (codexHome) => {
|
|
75865
|
+
const dir = path47.join(codexHome, "plugins", "cache", CODEX_MARKETPLACE, "workit");
|
|
75564
75866
|
let versions = [];
|
|
75565
75867
|
try {
|
|
75566
75868
|
versions = readdirSync12(dir).filter((version) => /^\d+\.\d+\.\d+$/.test(version));
|
|
@@ -75568,9 +75870,9 @@ var codexPluginRoot = (codexHome) => {
|
|
|
75568
75870
|
return null;
|
|
75569
75871
|
}
|
|
75570
75872
|
const newest = versions.reduce((best, version) => best && versionAtLeast(best, version) ? best : version, null);
|
|
75571
|
-
return newest ?
|
|
75572
|
-
}, opencodeVersion = (run) => {
|
|
75573
|
-
const listing = run("opencode", ["plugin", "list"]);
|
|
75873
|
+
return newest ? path47.join(dir, newest) : null;
|
|
75874
|
+
}, opencodeVersion = async (run) => {
|
|
75875
|
+
const listing = await run("opencode", ["plugin", "list"]);
|
|
75574
75876
|
if (listing.status !== 0)
|
|
75575
75877
|
return;
|
|
75576
75878
|
for (const line of listing.stdout.split(/\r?\n/)) {
|
|
@@ -75583,8 +75885,8 @@ var codexPluginRoot = (codexHome) => {
|
|
|
75583
75885
|
return version;
|
|
75584
75886
|
}
|
|
75585
75887
|
return;
|
|
75586
|
-
}, applyEntry = (entry, context) => {
|
|
75587
|
-
const {
|
|
75888
|
+
}, applyEntry = async (entry, context) => {
|
|
75889
|
+
const { runAsync, paths, configDir } = context;
|
|
75588
75890
|
const { home, env } = paths;
|
|
75589
75891
|
const fail = (reason) => ({
|
|
75590
75892
|
host: entry.host,
|
|
@@ -75593,6 +75895,30 @@ var codexPluginRoot = (codexHome) => {
|
|
|
75593
75895
|
fix: entry.fix
|
|
75594
75896
|
});
|
|
75595
75897
|
if (entry.host === "cursor") {
|
|
75898
|
+
const commands = entry.commands.map((command) => ({
|
|
75899
|
+
...command,
|
|
75900
|
+
purpose: command.purpose ?? "Upgrade Cursor"
|
|
75901
|
+
}));
|
|
75902
|
+
const recorded = new Map;
|
|
75903
|
+
let history = "";
|
|
75904
|
+
for (const command of commands) {
|
|
75905
|
+
if (command.skipWhenOutputIncludes && history.includes(command.skipWhenOutputIncludes))
|
|
75906
|
+
continue;
|
|
75907
|
+
const outcome = await runAsync(command.command, command.args);
|
|
75908
|
+
const result = {
|
|
75909
|
+
exitCode: outcome.status ?? 1,
|
|
75910
|
+
stdout: outcome.stdout,
|
|
75911
|
+
stderr: outcome.stderr ?? ""
|
|
75912
|
+
};
|
|
75913
|
+
recorded.set(command, result);
|
|
75914
|
+
history += `
|
|
75915
|
+
${result.stdout}
|
|
75916
|
+
${result.stderr}`;
|
|
75917
|
+
if (result.exitCode !== 0)
|
|
75918
|
+
break;
|
|
75919
|
+
}
|
|
75920
|
+
const cursorSettings = path47.join(home, ".cursor", "settings.json");
|
|
75921
|
+
const cursorMcp = path47.join(home, ".cursor", "mcp.json");
|
|
75596
75922
|
const preview = {
|
|
75597
75923
|
ok: true,
|
|
75598
75924
|
blocked: [],
|
|
@@ -75604,13 +75930,12 @@ var codexPluginRoot = (codexHome) => {
|
|
|
75604
75930
|
{
|
|
75605
75931
|
type: "install-host",
|
|
75606
75932
|
platform: "cursor",
|
|
75607
|
-
path:
|
|
75608
|
-
commands
|
|
75609
|
-
...command,
|
|
75610
|
-
purpose: command.purpose ?? "Upgrade Cursor"
|
|
75611
|
-
}))
|
|
75933
|
+
path: path47.join(home, ".cursor/plugins/local/.workit-package-bootstrap"),
|
|
75934
|
+
commands
|
|
75612
75935
|
},
|
|
75613
|
-
{ type: "install-adapter", platform: "cursor", path: paths.cursorRoot }
|
|
75936
|
+
{ type: "install-adapter", platform: "cursor", path: paths.cursorRoot },
|
|
75937
|
+
{ type: "register-platform", platform: "cursor", path: cursorSettings },
|
|
75938
|
+
{ type: "register-platform", platform: "cursor", path: cursorMcp }
|
|
75614
75939
|
]
|
|
75615
75940
|
};
|
|
75616
75941
|
const result = applySetupPreview(preview, {
|
|
@@ -75618,16 +75943,16 @@ var codexPluginRoot = (codexHome) => {
|
|
|
75618
75943
|
env,
|
|
75619
75944
|
cwd: home,
|
|
75620
75945
|
preferInstalledAdapter: true,
|
|
75621
|
-
runHostCommand: (command) => {
|
|
75622
|
-
|
|
75623
|
-
|
|
75624
|
-
|
|
75625
|
-
stdout: outcome.stdout,
|
|
75626
|
-
stderr: ""
|
|
75627
|
-
};
|
|
75946
|
+
runHostCommand: (command) => recorded.get(command) ?? {
|
|
75947
|
+
exitCode: 1,
|
|
75948
|
+
stdout: "",
|
|
75949
|
+
stderr: "command did not run"
|
|
75628
75950
|
}
|
|
75629
75951
|
});
|
|
75630
|
-
const installed = objectOrNull(
|
|
75952
|
+
const installed = objectOrNull(path47.join(paths.cursorRoot, "package.json"));
|
|
75953
|
+
const problems = result.entries.filter((one) => one.status === "Failed").map((one) => one.detail ?? `${one.file} failed`);
|
|
75954
|
+
if (problems.length)
|
|
75955
|
+
return fail(`Cursor install failed: ${problems.map(briefDetail).join("; ")}`);
|
|
75631
75956
|
if (!result.ok || installed?.version !== entry.latest)
|
|
75632
75957
|
return fail("Cursor install did not verify the requested package version; inspect the installer before retrying");
|
|
75633
75958
|
return {
|
|
@@ -75636,12 +75961,16 @@ var codexPluginRoot = (codexHome) => {
|
|
|
75636
75961
|
reason: entry.repair ? `reinstalled missing plugin files (${entry.latest})` : `${entry.installedVersion ?? "?"} -> ${entry.latest}`
|
|
75637
75962
|
};
|
|
75638
75963
|
}
|
|
75639
|
-
const before = entry.host === "opencode" ? opencodeVersion(
|
|
75640
|
-
for (const command of entry.commands)
|
|
75641
|
-
|
|
75642
|
-
|
|
75964
|
+
const before = entry.host === "opencode" ? await opencodeVersion(runAsync) : undefined;
|
|
75965
|
+
for (const command of entry.commands) {
|
|
75966
|
+
let result = await runAsync(command.command, command.args);
|
|
75967
|
+
if (result.status !== 0 && entry.host === "opencode")
|
|
75968
|
+
result = await runAsync(command.command, command.args);
|
|
75969
|
+
if (result.status !== 0)
|
|
75970
|
+
return fail(failureReason(command, result));
|
|
75971
|
+
}
|
|
75643
75972
|
if (entry.host === "opencode") {
|
|
75644
|
-
const after = opencodeVersion(
|
|
75973
|
+
const after = await opencodeVersion(runAsync);
|
|
75645
75974
|
if (before && after)
|
|
75646
75975
|
return after === before ? {
|
|
75647
75976
|
host: "opencode",
|
|
@@ -75670,9 +75999,9 @@ var codexPluginRoot = (codexHome) => {
|
|
|
75670
75999
|
reason: `${entry.installedVersion ?? "?"} -> ${after ?? "?"}; new sessions load it`
|
|
75671
76000
|
};
|
|
75672
76001
|
}
|
|
75673
|
-
const verify = entry.host === "codex" ?
|
|
76002
|
+
const verify = entry.host === "codex" ? await runAsync("codex", ["plugin", "list", "--json"]) : await runAsync("pi", ["list"]);
|
|
75674
76003
|
if (verify.status !== 0)
|
|
75675
|
-
return fail(
|
|
76004
|
+
return fail(`update verification failed${stderrTail(verify.stderr) ? `: ${stderrTail(verify.stderr)}` : ""}`);
|
|
75676
76005
|
if (entry.host === "codex") {
|
|
75677
76006
|
let installed = [];
|
|
75678
76007
|
try {
|
|
@@ -75688,30 +76017,40 @@ var codexPluginRoot = (codexHome) => {
|
|
|
75688
76017
|
status: "updated",
|
|
75689
76018
|
reason: entry.repair ? `reinstalled missing plugin files (${entry.latest})` : `${entry.installedVersion ?? "?"} -> ${entry.latest}`
|
|
75690
76019
|
};
|
|
75691
|
-
}, refreshCodexAgents = (run, codexHome) => {
|
|
76020
|
+
}, refreshCodexAgents = async (run, codexHome) => {
|
|
75692
76021
|
const root = codexPluginRoot(codexHome);
|
|
75693
|
-
const launcher = root &&
|
|
76022
|
+
const launcher = root && path47.join(root, "dist", "launch-mcp.js");
|
|
75694
76023
|
if (!launcher || !existsSync22(launcher))
|
|
75695
76024
|
return { ok: true, note: "" };
|
|
75696
76025
|
const fix = `node ${JSON.stringify(launcher)} --install-agents`;
|
|
75697
|
-
|
|
75698
|
-
|
|
76026
|
+
const refreshed = await run("node", [launcher, "--install-agents"]);
|
|
76027
|
+
return refreshed.status === 0 ? { ok: true, note: "agents refreshed" } : {
|
|
76028
|
+
ok: false,
|
|
76029
|
+
note: `agent refresh failed${stderrTail(refreshed.stderr) ? `: ${stderrTail(refreshed.stderr)}` : ""}`,
|
|
76030
|
+
fix
|
|
76031
|
+
};
|
|
76032
|
+
}, applyCli = async (cli, run, backup) => {
|
|
75699
76033
|
const fail = (reason) => ({
|
|
75700
76034
|
host: "cli",
|
|
75701
76035
|
status: "failed",
|
|
75702
76036
|
reason,
|
|
75703
76037
|
fix: CLI_FIX
|
|
75704
76038
|
});
|
|
75705
|
-
const currentRoot = run("npm", ["root", "--global"]);
|
|
76039
|
+
const currentRoot = await run("npm", ["root", "--global"]);
|
|
75706
76040
|
if (currentRoot.status !== 0 || currentRoot.stdout.trim() !== cli.root)
|
|
75707
76041
|
return fail("Global npm location changed; preview again");
|
|
75708
|
-
const cliBackup =
|
|
75709
|
-
cpSync5(
|
|
76042
|
+
const cliBackup = path47.join(backup, "cli-package");
|
|
76043
|
+
cpSync5(path47.join(cli.root, "@brainervirus/workit-cli"), cliBackup, {
|
|
75710
76044
|
recursive: true
|
|
75711
76045
|
});
|
|
75712
|
-
|
|
75713
|
-
|
|
75714
|
-
|
|
76046
|
+
const install = await run("npm", [
|
|
76047
|
+
"install",
|
|
76048
|
+
"--global",
|
|
76049
|
+
`@brainervirus/workit-cli@${cli.latest}`
|
|
76050
|
+
]);
|
|
76051
|
+
if (install.status !== 0)
|
|
76052
|
+
return fail(`CLI update failed${stderrTail(install.stderr) ? ` (${stderrTail(install.stderr)})` : ""}; preserved package at ${cliBackup}; use npm to repair or run node ${path47.join(cliBackup, "dist/index.js")}`);
|
|
76053
|
+
const installed = objectOrNull(path47.join(cli.root, "@brainervirus/workit-cli/package.json"));
|
|
75715
76054
|
if (installed?.name !== "@brainervirus/workit-cli" || installed.version !== cli.latest)
|
|
75716
76055
|
return fail(`CLI update did not verify the requested version; preserved package at ${cliBackup}`);
|
|
75717
76056
|
return {
|
|
@@ -75725,13 +76064,14 @@ var init_apply = __esm(() => {
|
|
|
75725
76064
|
init_setup_state();
|
|
75726
76065
|
init_setup();
|
|
75727
76066
|
init_safe_write();
|
|
76067
|
+
init_progress();
|
|
75728
76068
|
init_processes();
|
|
75729
76069
|
init_shared();
|
|
75730
76070
|
});
|
|
75731
76071
|
|
|
75732
76072
|
// packages/workit-cli/src/upgrade/plan.ts
|
|
75733
76073
|
import { existsSync as existsSync23, mkdtempSync as mkdtempSync3, rmSync as rmSync8, lstatSync as lstatSync8, readFileSync as readFileSync23 } from "node:fs";
|
|
75734
|
-
import
|
|
76074
|
+
import path48 from "node:path";
|
|
75735
76075
|
import os17 from "node:os";
|
|
75736
76076
|
function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
75737
76077
|
const paths = upgradePaths(deps);
|
|
@@ -75755,9 +76095,9 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
|
75755
76095
|
for (const file of [
|
|
75756
76096
|
paths.opencodeConfig,
|
|
75757
76097
|
paths.opencodeConfig + "c",
|
|
75758
|
-
|
|
75759
|
-
|
|
75760
|
-
|
|
76098
|
+
path48.join(home, ".cursor/settings.json"),
|
|
76099
|
+
path48.join(home, ".cursor/mcp.json"),
|
|
76100
|
+
path48.join(paths.cursorRoot, "package.json"),
|
|
75761
76101
|
paths.codexConfig,
|
|
75762
76102
|
paths.piSettings
|
|
75763
76103
|
])
|
|
@@ -75927,8 +76267,8 @@ var codexRegistered = (configFile) => {
|
|
|
75927
76267
|
result.push(classify("opencode", pin));
|
|
75928
76268
|
});
|
|
75929
76269
|
guard("cursor", () => {
|
|
75930
|
-
const cursor = objectOrNull(
|
|
75931
|
-
const mcp = objectOrNull(
|
|
76270
|
+
const cursor = objectOrNull(path48.join(paths.cursorRoot, "package.json"));
|
|
76271
|
+
const mcp = objectOrNull(path48.join(home, ".cursor/mcp.json"));
|
|
75932
76272
|
const args = mcp?.mcpServers?.workit?.args ?? [];
|
|
75933
76273
|
const arg = args.find((value) => typeof value === "string" && value.startsWith("--package="));
|
|
75934
76274
|
const selector = typeof arg === "string" ? arg.slice(10) : "local";
|
|
@@ -75939,7 +76279,7 @@ var codexRegistered = (configFile) => {
|
|
|
75939
76279
|
});
|
|
75940
76280
|
return;
|
|
75941
76281
|
}
|
|
75942
|
-
const settings = objectOrNull(
|
|
76282
|
+
const settings = objectOrNull(path48.join(home, ".cursor/settings.json"));
|
|
75943
76283
|
const dirs = Array.isArray(settings?.plugin_dirs) ? settings.plugin_dirs : [];
|
|
75944
76284
|
const registered = mcp?.mcpServers?.workit !== undefined || dirs.some((dir) => String(dir).replaceAll("\\", "/").replace(/\/+$/, "").endsWith("local/workit"));
|
|
75945
76285
|
if (registered)
|
|
@@ -75954,7 +76294,7 @@ var codexRegistered = (configFile) => {
|
|
|
75954
76294
|
if (typeof source !== "string")
|
|
75955
76295
|
continue;
|
|
75956
76296
|
const npm = /^(?:npm:)?@brainervirus\/workit-pi(?:@[^/]+)?$/.test(source);
|
|
75957
|
-
const local =
|
|
76297
|
+
const local = path48.isAbsolute(source) && source.replaceAll("\\", "/").endsWith("/packages/workit-pi") && object2(path48.join(source, "package.json"))?.name === "@brainervirus/workit-pi";
|
|
75958
76298
|
if (!npm && !local)
|
|
75959
76299
|
continue;
|
|
75960
76300
|
const found = classify("pi", source);
|
|
@@ -76014,15 +76354,15 @@ var codexRegistered = (configFile) => {
|
|
|
76014
76354
|
});
|
|
76015
76355
|
return result;
|
|
76016
76356
|
}, opencodeProbe = (deps, args) => {
|
|
76017
|
-
const scratch = mkdtempSync3(
|
|
76357
|
+
const scratch = mkdtempSync3(path48.join(os17.tmpdir(), "workit-upgrade-opencode-"));
|
|
76018
76358
|
try {
|
|
76019
76359
|
return runner({
|
|
76020
76360
|
...deps,
|
|
76021
76361
|
env: {
|
|
76022
76362
|
...deps.env,
|
|
76023
|
-
XDG_DATA_HOME:
|
|
76024
|
-
XDG_STATE_HOME:
|
|
76025
|
-
XDG_CACHE_HOME:
|
|
76363
|
+
XDG_DATA_HOME: path48.join(scratch, "data"),
|
|
76364
|
+
XDG_STATE_HOME: path48.join(scratch, "state"),
|
|
76365
|
+
XDG_CACHE_HOME: path48.join(scratch, "cache")
|
|
76026
76366
|
}
|
|
76027
76367
|
})("opencode", args);
|
|
76028
76368
|
} finally {
|
|
@@ -76030,7 +76370,7 @@ var codexRegistered = (configFile) => {
|
|
|
76030
76370
|
}
|
|
76031
76371
|
}, planCli = (plan, run) => {
|
|
76032
76372
|
const root = run("npm", ["root", "--global"]);
|
|
76033
|
-
if (root.status !== 0 || !
|
|
76373
|
+
if (root.status !== 0 || !path48.isAbsolute(root.stdout.trim())) {
|
|
76034
76374
|
plan.skipped.push({
|
|
76035
76375
|
host: "cli",
|
|
76036
76376
|
reason: "global npm location could not be verified",
|
|
@@ -76038,9 +76378,9 @@ var codexRegistered = (configFile) => {
|
|
|
76038
76378
|
});
|
|
76039
76379
|
return;
|
|
76040
76380
|
}
|
|
76041
|
-
const packageFile =
|
|
76381
|
+
const packageFile = path48.join(root.stdout.trim(), "@brainervirus/workit-cli/package.json");
|
|
76042
76382
|
const installed = objectOrNull(packageFile);
|
|
76043
|
-
if (installed?.name !== "@brainervirus/workit-cli" || lstatSync8(
|
|
76383
|
+
if (installed?.name !== "@brainervirus/workit-cli" || lstatSync8(path48.dirname(packageFile)).isSymbolicLink()) {
|
|
76044
76384
|
plan.skipped.push({
|
|
76045
76385
|
host: "cli",
|
|
76046
76386
|
reason: "no managed global CLI install (local links preserved); use npx @brainervirus/workit-cli@latest"
|
|
@@ -76101,9 +76441,13 @@ var pad2 = (text) => text.padEnd(12), summary = (plan, permissions) => {
|
|
|
76101
76441
|
return lines.join(`
|
|
76102
76442
|
`) + `
|
|
76103
76443
|
`;
|
|
76104
|
-
}, LABEL,
|
|
76444
|
+
}, LABEL, reasonFor = (entry) => {
|
|
76445
|
+
const label = LABEL[entry.status];
|
|
76446
|
+
const head = entry.reason.slice(0, label.length);
|
|
76447
|
+
return entry.status !== "failed" && head.toLowerCase() === label.toLowerCase() && !/^[a-z]/i.test(entry.reason[label.length] ?? "") ? entry.reason.slice(label.length).replace(/^[\s:;,-]+/, "") : entry.reason;
|
|
76448
|
+
}, table = (hosts) => [
|
|
76105
76449
|
"Result:",
|
|
76106
|
-
...hosts.map((entry) => ` ${pad2(entry.host)}${LABEL[entry.status].padEnd(16)}${entry
|
|
76450
|
+
...hosts.map((entry) => ` ${pad2(entry.host)}${LABEL[entry.status].padEnd(16)}${reasonFor(entry)}${entry.fix && entry.status !== "updated" && entry.status !== "current" ? `
|
|
76107
76451
|
${pad2("")}${"".padEnd(16)}fix: ${entry.fix}` : ""}`)
|
|
76108
76452
|
].join(`
|
|
76109
76453
|
`) + `
|
|
@@ -76145,9 +76489,13 @@ async function runUpgradeCommand(argv, deps = {}) {
|
|
|
76145
76489
|
const legacy = flags.has("--apply");
|
|
76146
76490
|
const json = flags.has("--json") || legacy;
|
|
76147
76491
|
const run = runner(deps);
|
|
76148
|
-
const
|
|
76149
|
-
|
|
76150
|
-
|
|
76492
|
+
const progress = deps.progress ?? createProgress({ stream: process.stderr, json });
|
|
76493
|
+
const plan = progress.runSync("Planning the upgrade", () => {
|
|
76494
|
+
const planned = previewUpgrade(raw, deps);
|
|
76495
|
+
if (hostFlag === undefined || flags.has("--cli"))
|
|
76496
|
+
planCli(planned, run);
|
|
76497
|
+
return planned;
|
|
76498
|
+
});
|
|
76151
76499
|
plan.ok = plan.blocked.length === 0 && plan.failed.length === 0;
|
|
76152
76500
|
const { home, env } = upgradePaths(deps);
|
|
76153
76501
|
const permissions = planHostPermissions({
|
|
@@ -76198,23 +76546,23 @@ Nothing changed.
|
|
|
76198
76546
|
for (const warning of plan.warnings ?? [])
|
|
76199
76547
|
out.write(`warning: ${warning}
|
|
76200
76548
|
`);
|
|
76201
|
-
const result = applyUpgrade(plan, deps);
|
|
76549
|
+
const result = await applyUpgrade(plan, { ...deps, progress });
|
|
76202
76550
|
let permissionsOk = true;
|
|
76203
76551
|
let written;
|
|
76204
76552
|
if (permissions.changes.length && !permissions.refused && !result.error?.startsWith("configuration changed")) {
|
|
76205
|
-
written = applyHostPermissions(permissions, { home, env });
|
|
76553
|
+
written = progress.runSync("Refreshing the permission block", () => applyHostPermissions(permissions, { home, env }), (entries) => entries.every((entry) => entry.status === "written") ? "done" : "failed");
|
|
76206
76554
|
permissionsOk = written.every((entry) => entry.status === "written");
|
|
76207
76555
|
for (const entry of written)
|
|
76208
76556
|
result.hosts.push({
|
|
76209
|
-
host:
|
|
76557
|
+
host: "permissions",
|
|
76210
76558
|
status: entry.status === "written" ? "updated" : "failed",
|
|
76211
|
-
reason:
|
|
76559
|
+
reason: `${entry.host} block ${entry.status === "written" ? "refreshed" : entry.status} in ${entry.file}`,
|
|
76212
76560
|
...entry.status === "written" ? {} : { fix: `workit setup --hosts=${entry.host}` }
|
|
76213
76561
|
});
|
|
76214
76562
|
}
|
|
76215
76563
|
const failed = !result.ok || !permissionsOk;
|
|
76216
76564
|
const cliVersion = result.hosts.some((h) => h.host === "cli" && h.status === "updated") ? plan.cli.latest : package_default.version;
|
|
76217
|
-
const report = (deps.doctor ?? ((version) => runDoctor({ home, env, cliVersion: version, only: "upgrade" })))(cliVersion);
|
|
76565
|
+
const report = progress.runSync("Checking the result with workit doctor", () => (deps.doctor ?? ((version) => runDoctor({ home, env, cliVersion: version, only: "upgrade" })))(cliVersion));
|
|
76218
76566
|
const left = report.checks.filter((check) => check.status === "warn" || check.status === "fail");
|
|
76219
76567
|
if (json) {
|
|
76220
76568
|
out.write(JSON.stringify({
|
|
@@ -76272,7 +76620,7 @@ async function runLaunchCommand(argv, deps = {}) {
|
|
|
76272
76620
|
for (const skipped of plan.skipped)
|
|
76273
76621
|
(deps.out ?? process.stderr).write(`${skipped.host}: ${skipped.reason}${skipped.fix ? ` (run: ${skipped.fix})` : ""}
|
|
76274
76622
|
`);
|
|
76275
|
-
const result = applyUpgrade(plan, deps);
|
|
76623
|
+
const result = await applyUpgrade(plan, deps);
|
|
76276
76624
|
if (!result.ok) {
|
|
76277
76625
|
(deps.out ?? process.stdout).write(`${result.error}
|
|
76278
76626
|
`);
|
|
@@ -76301,6 +76649,7 @@ var init_upgrade = __esm(() => {
|
|
|
76301
76649
|
init_host_install();
|
|
76302
76650
|
init_doctor();
|
|
76303
76651
|
init_host_permissions();
|
|
76652
|
+
init_progress();
|
|
76304
76653
|
init_apply();
|
|
76305
76654
|
init_plan();
|
|
76306
76655
|
init_report();
|
|
@@ -76333,7 +76682,7 @@ var init_launch = __esm(() => {
|
|
|
76333
76682
|
// packages/workit-core/src/knowledge.ts
|
|
76334
76683
|
import { spawnSync as spawnSync18 } from "node:child_process";
|
|
76335
76684
|
import fs20 from "node:fs";
|
|
76336
|
-
import
|
|
76685
|
+
import path49 from "node:path";
|
|
76337
76686
|
function lintKnowledge(root) {
|
|
76338
76687
|
const seen = new Set;
|
|
76339
76688
|
const unreadable = [];
|
|
@@ -76437,7 +76786,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
76437
76786
|
const end = lines.indexOf("---", 1);
|
|
76438
76787
|
return end === -1 ? lines : [...lines.slice(0, end + 1).map(() => ""), ...lines.slice(end + 1)];
|
|
76439
76788
|
}, read = (root, file) => {
|
|
76440
|
-
const full =
|
|
76789
|
+
const full = path49.join(root, file);
|
|
76441
76790
|
try {
|
|
76442
76791
|
fs20.lstatSync(full);
|
|
76443
76792
|
} catch {
|
|
@@ -76478,7 +76827,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
76478
76827
|
}
|
|
76479
76828
|
}, brokenLinks = (root, doc, tracked) => {
|
|
76480
76829
|
const findings = [];
|
|
76481
|
-
const base =
|
|
76830
|
+
const base = path49.dirname(path49.join(root, doc.file));
|
|
76482
76831
|
const missing = (target, line, how) => findings.push({
|
|
76483
76832
|
rule: "broken-link",
|
|
76484
76833
|
file: doc.file,
|
|
@@ -76497,7 +76846,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
76497
76846
|
const local = localTarget(target);
|
|
76498
76847
|
if (!local)
|
|
76499
76848
|
continue;
|
|
76500
|
-
const resolved = local.startsWith("/") ?
|
|
76849
|
+
const resolved = local.startsWith("/") ? path49.join(root, local) : path49.resolve(base, local);
|
|
76501
76850
|
if (!exists2(resolved))
|
|
76502
76851
|
missing(target, index + 1, "link");
|
|
76503
76852
|
}
|
|
@@ -76507,9 +76856,9 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
76507
76856
|
continue;
|
|
76508
76857
|
const relative = /^\.\.?\//.test(candidate);
|
|
76509
76858
|
const first = candidate.split("/")[0];
|
|
76510
|
-
if (!relative && !(tracked ? tracked.has(first) : exists2(
|
|
76859
|
+
if (!relative && !(tracked ? tracked.has(first) : exists2(path49.join(root, first))))
|
|
76511
76860
|
continue;
|
|
76512
|
-
const resolved = relative ?
|
|
76861
|
+
const resolved = relative ? path49.resolve(base, candidate) : path49.join(root, candidate);
|
|
76513
76862
|
if (!exists2(resolved))
|
|
76514
76863
|
missing(span, index + 1, "pointer");
|
|
76515
76864
|
}
|
|
@@ -76661,12 +77010,12 @@ async function run7(argv, io) {
|
|
|
76661
77010
|
};
|
|
76662
77011
|
}
|
|
76663
77012
|
}
|
|
76664
|
-
const report = runDoctor({
|
|
77013
|
+
const report = createProgress({ stream: process.stderr, json: io.json }).runSync("Checking Workit (workit doctor)", () => runDoctor({
|
|
76665
77014
|
host: "cli",
|
|
76666
77015
|
cwd: io.cwd,
|
|
76667
77016
|
workspaceRoot: root,
|
|
76668
77017
|
cliVersion: package_default.version
|
|
76669
|
-
});
|
|
77018
|
+
}), (done) => done.ok ? "done" : "failed");
|
|
76670
77019
|
let knowledge = null;
|
|
76671
77020
|
try {
|
|
76672
77021
|
knowledge = lintKnowledge(root);
|
|
@@ -76722,6 +77071,7 @@ var init_doctor2 = __esm(() => {
|
|
|
76722
77071
|
init_knowledge();
|
|
76723
77072
|
init_store_lock();
|
|
76724
77073
|
init_output();
|
|
77074
|
+
init_progress();
|
|
76725
77075
|
init_prompt();
|
|
76726
77076
|
init_task();
|
|
76727
77077
|
});
|
|
@@ -76831,11 +77181,11 @@ var init_redact = __esm(() => {
|
|
|
76831
77181
|
});
|
|
76832
77182
|
|
|
76833
77183
|
// packages/workit-core/src/checks.ts
|
|
76834
|
-
import { spawn, spawnSync as spawnSync19 } from "node:child_process";
|
|
77184
|
+
import { spawn as spawn3, spawnSync as spawnSync19 } from "node:child_process";
|
|
76835
77185
|
import { createHash as createHash17 } from "node:crypto";
|
|
76836
77186
|
import fs21 from "node:fs";
|
|
76837
77187
|
import os18 from "node:os";
|
|
76838
|
-
import
|
|
77188
|
+
import path50 from "node:path";
|
|
76839
77189
|
import { StringDecoder } from "node:string_decoder";
|
|
76840
77190
|
function tailLines(text, lines = TAIL_LINES) {
|
|
76841
77191
|
const all = text.replace(/\r\n?/gu, `
|
|
@@ -76955,7 +77305,7 @@ function planSpawn(argv, options) {
|
|
|
76955
77305
|
return { file: argv[0], args: [], verbatim: false, shell: true };
|
|
76956
77306
|
if (options.platform !== "win32")
|
|
76957
77307
|
return { file: argv[0], args: argv.slice(1), verbatim: false, shell: false };
|
|
76958
|
-
const win =
|
|
77308
|
+
const win = path50.win32;
|
|
76959
77309
|
const isFile = options.isFile ?? ((file) => {
|
|
76960
77310
|
try {
|
|
76961
77311
|
return fs21.statSync(file).isFile();
|
|
@@ -77060,7 +77410,7 @@ function runCheckCommand(argv, options) {
|
|
|
77060
77410
|
shell: plan.shell
|
|
77061
77411
|
};
|
|
77062
77412
|
try {
|
|
77063
|
-
child =
|
|
77413
|
+
child = spawn3(plan.file, plan.args, spawnOptions);
|
|
77064
77414
|
} catch (error) {
|
|
77065
77415
|
finish(null, null, error.code ?? error.message);
|
|
77066
77416
|
return;
|
|
@@ -77117,10 +77467,10 @@ function runCheckCommand(argv, options) {
|
|
|
77117
77467
|
function storeLog(storeRoot, log) {
|
|
77118
77468
|
const digest = logDigest(log);
|
|
77119
77469
|
const ref = `blobs/logs/${digest.slice("sha256:".length)}.log`;
|
|
77120
|
-
const file =
|
|
77470
|
+
const file = path50.join(storeRoot, ref);
|
|
77121
77471
|
try {
|
|
77122
77472
|
if (!fs21.existsSync(file)) {
|
|
77123
|
-
fs21.mkdirSync(
|
|
77473
|
+
fs21.mkdirSync(path50.dirname(file), { recursive: true });
|
|
77124
77474
|
const temp = `${file}.${process.pid}.${Date.now()}.tmp`;
|
|
77125
77475
|
fs21.writeFileSync(temp, log, { mode: 384 });
|
|
77126
77476
|
fs21.renameSync(temp, file);
|
|
@@ -77133,7 +77483,7 @@ function storeLog(storeRoot, log) {
|
|
|
77133
77483
|
function pruneCheckLogs(storeRoot, options = {}) {
|
|
77134
77484
|
const limits = { ...LOG_RETENTION, ...options.retention };
|
|
77135
77485
|
const now = options.now ?? Date.now();
|
|
77136
|
-
const dir =
|
|
77486
|
+
const dir = path50.join(storeRoot, "blobs", "logs");
|
|
77137
77487
|
const report = { removed: 0, removedBytes: 0, kept: 0 };
|
|
77138
77488
|
let names;
|
|
77139
77489
|
try {
|
|
@@ -77143,7 +77493,7 @@ function pruneCheckLogs(storeRoot, options = {}) {
|
|
|
77143
77493
|
}
|
|
77144
77494
|
const files = names.flatMap((name) => {
|
|
77145
77495
|
try {
|
|
77146
|
-
const stat = fs21.statSync(
|
|
77496
|
+
const stat = fs21.statSync(path50.join(dir, name));
|
|
77147
77497
|
return stat.isFile() ? [{ name, size: stat.size, mtimeMs: stat.mtimeMs }] : [];
|
|
77148
77498
|
} catch {
|
|
77149
77499
|
return [];
|
|
@@ -77162,7 +77512,7 @@ function pruneCheckLogs(storeRoot, options = {}) {
|
|
|
77162
77512
|
continue;
|
|
77163
77513
|
if (!options.dryRun)
|
|
77164
77514
|
try {
|
|
77165
|
-
fs21.rmSync(
|
|
77515
|
+
fs21.rmSync(path50.join(dir, file.name), { force: true });
|
|
77166
77516
|
} catch {
|
|
77167
77517
|
continue;
|
|
77168
77518
|
}
|
|
@@ -77814,12 +78164,12 @@ var init_workspace = __esm(() => {
|
|
|
77814
78164
|
|
|
77815
78165
|
// packages/workit-core/src/core/heavy-rules.ts
|
|
77816
78166
|
import fs22 from "node:fs";
|
|
77817
|
-
import
|
|
78167
|
+
import path51 from "node:path";
|
|
77818
78168
|
function gitTop(cwd) {
|
|
77819
|
-
for (let dir =
|
|
77820
|
-
if (fs22.existsSync(
|
|
78169
|
+
for (let dir = path51.resolve(cwd);; dir = path51.dirname(dir)) {
|
|
78170
|
+
if (fs22.existsSync(path51.join(dir, ".git")))
|
|
77821
78171
|
return dir;
|
|
77822
|
-
if (
|
|
78172
|
+
if (path51.dirname(dir) === dir)
|
|
77823
78173
|
return null;
|
|
77824
78174
|
}
|
|
77825
78175
|
}
|
|
@@ -77861,18 +78211,18 @@ var init_heavy_rules = () => {};
|
|
|
77861
78211
|
// packages/workit-core/src/core/heavy.ts
|
|
77862
78212
|
import fs23 from "node:fs";
|
|
77863
78213
|
import os19 from "node:os";
|
|
77864
|
-
import
|
|
78214
|
+
import path52 from "node:path";
|
|
77865
78215
|
function stateDir2(env, platform = process.platform) {
|
|
77866
78216
|
if (env.WORKFLOW_TOOLKIT_STATE)
|
|
77867
78217
|
return env.WORKFLOW_TOOLKIT_STATE;
|
|
77868
78218
|
if (env.XDG_STATE_HOME)
|
|
77869
|
-
return
|
|
78219
|
+
return path52.join(env.XDG_STATE_HOME, "workit");
|
|
77870
78220
|
const home = env.HOME || os19.homedir();
|
|
77871
78221
|
if (platform === "darwin")
|
|
77872
|
-
return
|
|
78222
|
+
return path52.join(home, "Library", "Application Support", "workit");
|
|
77873
78223
|
if (platform === "win32")
|
|
77874
|
-
return
|
|
77875
|
-
return
|
|
78224
|
+
return path52.join(env.LOCALAPPDATA ?? path52.join(home, "AppData", "Local"), "workit");
|
|
78225
|
+
return path52.join(home, ".local", "state", "workit");
|
|
77876
78226
|
}
|
|
77877
78227
|
function positional(words, from, values = PM_VALUES) {
|
|
77878
78228
|
let index = from;
|
|
@@ -78012,7 +78362,7 @@ function machinePatterns(env) {
|
|
|
78012
78362
|
return isRecord8(value) ? stringList2(value.patterns) : [];
|
|
78013
78363
|
}
|
|
78014
78364
|
function repoPatterns(cwd) {
|
|
78015
|
-
return repoHeavyCommands(gitTop(cwd) ??
|
|
78365
|
+
return repoHeavyCommands(gitTop(cwd) ?? path52.resolve(cwd));
|
|
78016
78366
|
}
|
|
78017
78367
|
function heavyLines(lines, options) {
|
|
78018
78368
|
const found = [];
|
|
@@ -78091,7 +78441,7 @@ function leaseRewrite(command) {
|
|
|
78091
78441
|
return null;
|
|
78092
78442
|
return `${prefix}workit check --heavy -- ${rest}`;
|
|
78093
78443
|
}
|
|
78094
|
-
var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) =>
|
|
78444
|
+
var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) => path52.join(stateDir2(env), HEAVY_COMMANDS_FILE), HEAVY_SCRIPT, INFO_FLAGS, WATCH_FLAG, WATCH_SCRIPT, sub = (...names) => new Set(names), TOOLS, PM_VALUES, baseName2 = (word) => (word?.split(/[\\/]/u).at(-1) ?? "").toLowerCase().replace(/\.(?:exe|cmd|bat|ps1)$/u, ""), WORKIT, PYTHONS, NPM_INSTALL, NPM_RUN, NPM_TEST, EXEC, globWord = (word) => new RegExp(`^${word.replace(/[.+?^${}()|[\]\\]/gu, "\\$&").replaceAll("*", ".*")}$`, "u"), matches2 = (matchers, words) => matchers.length <= words.length && matchers.every((matcher, index) => index === 0 ? matcher.test(words[0]) || matcher.test(baseName2(words[0])) : matcher.test(words[index])), readJson2 = (file) => {
|
|
78095
78445
|
try {
|
|
78096
78446
|
return JSON.parse(fs23.readFileSync(file, "utf8"));
|
|
78097
78447
|
} catch {
|
|
@@ -78238,7 +78588,7 @@ var init_heavy = __esm(() => {
|
|
|
78238
78588
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
78239
78589
|
import fs24 from "node:fs";
|
|
78240
78590
|
import os20 from "node:os";
|
|
78241
|
-
import
|
|
78591
|
+
import path53 from "node:path";
|
|
78242
78592
|
function memoryValue(value, host) {
|
|
78243
78593
|
const text = typeof value === "number" ? String(value) : typeof value === "string" ? value : "";
|
|
78244
78594
|
const percent = PERCENT.exec(text.trim());
|
|
@@ -78434,7 +78784,7 @@ function tryOnce(options, record, reclaimed) {
|
|
|
78434
78784
|
const text = `${JSON.stringify(record)}
|
|
78435
78785
|
`;
|
|
78436
78786
|
for (let slot = 0;slot < options.slots; slot += 1) {
|
|
78437
|
-
const file =
|
|
78787
|
+
const file = path53.join(options.dir, `slot-${slot}.json`);
|
|
78438
78788
|
for (let attempt = 0;attempt < 2; attempt += 1) {
|
|
78439
78789
|
try {
|
|
78440
78790
|
const fd = fs24.openSync(file, "wx", 384);
|
|
@@ -78479,7 +78829,7 @@ function leaseQueue(dir, probe = {}) {
|
|
|
78479
78829
|
}
|
|
78480
78830
|
const entries = [];
|
|
78481
78831
|
for (const name of names.filter((item) => item.endsWith(".json")).toSorted()) {
|
|
78482
|
-
const file =
|
|
78832
|
+
const file = path53.join(queueDir(dir), name);
|
|
78483
78833
|
const record = parseLease(readText5(file));
|
|
78484
78834
|
if (!record)
|
|
78485
78835
|
continue;
|
|
@@ -78495,9 +78845,9 @@ function leaseQueue(dir, probe = {}) {
|
|
|
78495
78845
|
function waitersAhead(options, own) {
|
|
78496
78846
|
let ahead = 0;
|
|
78497
78847
|
for (const entry of leaseQueue(options.dir, options.probe)) {
|
|
78498
|
-
if (
|
|
78848
|
+
if (path53.basename(entry.file) >= own)
|
|
78499
78849
|
break;
|
|
78500
|
-
if (!TICKET.test(
|
|
78850
|
+
if (!TICKET.test(path53.basename(entry.file)))
|
|
78501
78851
|
continue;
|
|
78502
78852
|
if (entry.stale && reclaim(entry.file, (current) => !current || staleReason(current, options.probe) !== null))
|
|
78503
78853
|
continue;
|
|
@@ -78509,7 +78859,7 @@ function liveHolders(options) {
|
|
|
78509
78859
|
return leaseSlots(options.dir, options.slots, options.probe).filter((slot) => slot.holder && !slot.stale).map((slot) => slot.holder);
|
|
78510
78860
|
}
|
|
78511
78861
|
function writeTicket(file, record) {
|
|
78512
|
-
fs24.mkdirSync(
|
|
78862
|
+
fs24.mkdirSync(path53.dirname(file), { recursive: true, mode: 448 });
|
|
78513
78863
|
fs24.writeFileSync(file, `${JSON.stringify(record)}
|
|
78514
78864
|
`, { mode: 384 });
|
|
78515
78865
|
}
|
|
@@ -78554,7 +78904,7 @@ async function acquireLease(options) {
|
|
|
78554
78904
|
const reclaimed = [];
|
|
78555
78905
|
let waitedOn = [];
|
|
78556
78906
|
const name = ticketName(started, record.id);
|
|
78557
|
-
const ticket =
|
|
78907
|
+
const ticket = path53.join(queueDir(options.dir), name);
|
|
78558
78908
|
const ticketRecord = {
|
|
78559
78909
|
...record,
|
|
78560
78910
|
maxAgeMs: options.waitMs + 60000
|
|
@@ -78675,7 +79025,7 @@ function heldLease(dir, id, options = {}) {
|
|
|
78675
79025
|
for (const name of names) {
|
|
78676
79026
|
if (!/^slot-\d+\.json$/u.test(name))
|
|
78677
79027
|
continue;
|
|
78678
|
-
const lease = parseLease(readText5(
|
|
79028
|
+
const lease = parseLease(readText5(path53.join(dir, name)));
|
|
78679
79029
|
if (lease?.id === id && !staleReason(lease, options.probe) && (options.ancestor ?? isAncestor)(lease.pid))
|
|
78680
79030
|
return lease;
|
|
78681
79031
|
}
|
|
@@ -78730,10 +79080,10 @@ async function runScoped(run, wrapper, sinks) {
|
|
|
78730
79080
|
}
|
|
78731
79081
|
function firstNotice(env, session, key, now = Date.now()) {
|
|
78732
79082
|
const id = (session ?? `ppid-${process.ppid}`).replace(/[^A-Za-z0-9_.-]/gu, "_").slice(0, 120);
|
|
78733
|
-
const dir =
|
|
79083
|
+
const dir = path53.join(stateDir2(env), "notices");
|
|
78734
79084
|
try {
|
|
78735
79085
|
fs24.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
78736
|
-
fs24.writeFileSync(
|
|
79086
|
+
fs24.writeFileSync(path53.join(dir, `${key}-${id}`), `${new Date(now).toISOString()}
|
|
78737
79087
|
`, {
|
|
78738
79088
|
flag: "wx",
|
|
78739
79089
|
mode: 384
|
|
@@ -78743,7 +79093,7 @@ function firstNotice(env, session, key, now = Date.now()) {
|
|
|
78743
79093
|
}
|
|
78744
79094
|
try {
|
|
78745
79095
|
for (const name of fs24.readdirSync(dir)) {
|
|
78746
|
-
const file =
|
|
79096
|
+
const file = path53.join(dir, name);
|
|
78747
79097
|
if (now - fs24.statSync(file).mtimeMs > NOTICE_TTL_MS)
|
|
78748
79098
|
fs24.rmSync(file, { force: true });
|
|
78749
79099
|
}
|
|
@@ -78753,7 +79103,7 @@ function firstNotice(env, session, key, now = Date.now()) {
|
|
|
78753
79103
|
function leaseSlots(dir, slots, probe = {}) {
|
|
78754
79104
|
const states = [];
|
|
78755
79105
|
for (let slot = 0;slot < slots; slot += 1) {
|
|
78756
|
-
const lease = parseLease(readText5(
|
|
79106
|
+
const lease = parseLease(readText5(path53.join(dir, `slot-${slot}.json`)));
|
|
78757
79107
|
states.push({
|
|
78758
79108
|
slot,
|
|
78759
79109
|
holder: lease ? holderOf(lease) : null,
|
|
@@ -78765,7 +79115,7 @@ function leaseSlots(dir, slots, probe = {}) {
|
|
|
78765
79115
|
var DEFAULT_HEAVY_CHECKS, DEFAULT_LIGHT_CHECKS, DEFAULT_SLOTS = 1, DEFAULT_WAIT_S = 1800, DEFAULT_MEMORY_SHARE = 0.4, DEFAULT_CPU_SHARE = 0.7, MAX_SLOTS = 64, UNREADABLE_TTL_MS = 30000, GUARD_TTL_MS = 30000, hostShape = () => ({
|
|
78766
79116
|
totalMemBytes: os20.totalmem(),
|
|
78767
79117
|
cpus: Math.max(1, os20.availableParallelism?.() ?? os20.cpus().length)
|
|
78768
|
-
}), isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), SIZE, PERCENT, UNITS, leaseDir = (env) =>
|
|
79118
|
+
}), isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), SIZE, PERCENT, UNITS, leaseDir = (env) => path53.join(stateDir2(env), "leases"), readText5 = (file) => {
|
|
78769
79119
|
try {
|
|
78770
79120
|
return fs24.readFileSync(file, "utf8");
|
|
78771
79121
|
} catch {
|
|
@@ -78796,7 +79146,7 @@ var DEFAULT_HEAVY_CHECKS, DEFAULT_LIGHT_CHECKS, DEFAULT_SLOTS = 1, DEFAULT_WAIT_
|
|
|
78796
79146
|
cwd: lease.cwd,
|
|
78797
79147
|
session: lease.session,
|
|
78798
79148
|
startedAt: lease.startedAt
|
|
78799
|
-
}), realClock, queueDir = (dir) =>
|
|
79149
|
+
}), realClock, queueDir = (dir) => path53.join(dir, "queue"), TICKET, ticketName = (now, id) => `${String(now).padStart(15, "0")}-${String(process.hrtime.bigint() % 10n ** 16n).padStart(16, "0")}-${id}.json`, SCOPE_START_FAILURE, NOTICE_TTL_MS;
|
|
78800
79150
|
var init_resources = __esm(() => {
|
|
78801
79151
|
init_checks3();
|
|
78802
79152
|
init_heavy();
|
|
@@ -78826,7 +79176,7 @@ __export(exports_check, {
|
|
|
78826
79176
|
workspaceResources: () => workspaceResources
|
|
78827
79177
|
});
|
|
78828
79178
|
import os21 from "node:os";
|
|
78829
|
-
import
|
|
79179
|
+
import path54 from "node:path";
|
|
78830
79180
|
function parse6(argv) {
|
|
78831
79181
|
const split = argv.indexOf("--");
|
|
78832
79182
|
const head = split >= 0 ? argv.slice(0, split) : [...argv];
|
|
@@ -79057,7 +79407,7 @@ ${footer}`;
|
|
|
79057
79407
|
}
|
|
79058
79408
|
async function workspaceResources(io) {
|
|
79059
79409
|
const env = io.env;
|
|
79060
|
-
const dir = env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ??
|
|
79410
|
+
const dir = env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path54.join(env.XDG_CONFIG_HOME || path54.join(env.HOME || os21.homedir(), ".config"), "workit");
|
|
79061
79411
|
try {
|
|
79062
79412
|
await Promise.resolve().then(() => init_workspaces());
|
|
79063
79413
|
const workspace = resolveWorkspaceFrom(io.cwd, dir, env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined);
|
|
@@ -79078,6 +79428,8 @@ async function prepareHeavy(io, settings, label, runCwd, timeoutMs) {
|
|
|
79078
79428
|
wrapper: null,
|
|
79079
79429
|
env: io.env
|
|
79080
79430
|
};
|
|
79431
|
+
const progress = createProgress({ stream: process.stderr, json: io.json });
|
|
79432
|
+
let waiting = null;
|
|
79081
79433
|
const acquired = await acquireLease({
|
|
79082
79434
|
dir,
|
|
79083
79435
|
slots: settings.slots,
|
|
@@ -79090,11 +79442,20 @@ async function prepareHeavy(io, settings, label, runCwd, timeoutMs) {
|
|
|
79090
79442
|
onStatus: (status) => {
|
|
79091
79443
|
const slots = `${settings.slots} slot${settings.slots === 1 ? "" : "s"}`;
|
|
79092
79444
|
const holders = status.holders.map((holder) => describeHolder(holder)).join("; ");
|
|
79445
|
+
if (progress.mode === "spinner") {
|
|
79446
|
+
const text = `Waiting for the heavy-check lease: held by ${holders || "nobody; waiters ahead"}, queue position ${status.position}`;
|
|
79447
|
+
if (waiting)
|
|
79448
|
+
waiting.label(text);
|
|
79449
|
+
else
|
|
79450
|
+
waiting = progress.start(text);
|
|
79451
|
+
return;
|
|
79452
|
+
}
|
|
79093
79453
|
io.stderr(status.first ? `workit: waiting for the heavy-check lease (${slots}): held by ${holders || "nobody; waiters ahead"}; queued at position ${status.position}, waiting up to ${formatWait(settings.waitMs)} (--wait <dur> sets it)
|
|
79094
79454
|
` : `workit: still queued for the heavy-check lease: position ${status.position}, ${formatWait(status.waitedMs)} of ${formatWait(settings.waitMs)} waited; held by ${holders || "nobody; waiters ahead"}
|
|
79095
79455
|
`);
|
|
79096
79456
|
}
|
|
79097
79457
|
});
|
|
79458
|
+
waiting?.end(acquired.ok ? "done" : "failed");
|
|
79098
79459
|
if (!acquired.ok && acquired.reason === "timeout") {
|
|
79099
79460
|
const holders = acquired.holders.map((holder) => describeHolder(holder)).join("; ");
|
|
79100
79461
|
const waited = formatWait(acquired.waitedMs);
|
|
@@ -79188,7 +79549,7 @@ async function run12(argv, io) {
|
|
|
79188
79549
|
if (options.shell && command.length !== 1)
|
|
79189
79550
|
return emit(io, fail2("invalid_input", '--shell takes the command as one string: workit check --shell -- "<cmd>"'));
|
|
79190
79551
|
}
|
|
79191
|
-
const relCwd = posix(
|
|
79552
|
+
const relCwd = posix(path54.relative(top, runCwd));
|
|
79192
79553
|
const configured = !options.shell && matchesNamedCheck(config, name, command, relCwd);
|
|
79193
79554
|
const shadowed = !configured && name !== null ? config.checks.find((item) => item.name === name) : undefined;
|
|
79194
79555
|
if (shadowed)
|
|
@@ -79253,7 +79614,7 @@ async function run12(argv, io) {
|
|
|
79253
79614
|
const modifiedWorktree = key.tree !== null && treeAfter !== key.tree;
|
|
79254
79615
|
const store = storeRoot(io.cwd);
|
|
79255
79616
|
const blob = store.ok ? storeLog(store.value.root, result.log) : null;
|
|
79256
|
-
const logPath = store.ok && blob ?
|
|
79617
|
+
const logPath = store.ok && blob ? path54.join(store.value.root, blob.ref) : null;
|
|
79257
79618
|
const tail = tailLines(result.log, TAIL_LINES);
|
|
79258
79619
|
const passed = result.exitCode === 0 && !result.timedOut;
|
|
79259
79620
|
const bounded = boundedArgv(command);
|
|
@@ -79368,7 +79729,7 @@ async function run12(argv, io) {
|
|
|
79368
79729
|
return recordError.code === "busy" ? 4 : recordError.code === "invalid_input" ? 2 : 5;
|
|
79369
79730
|
return 0;
|
|
79370
79731
|
}
|
|
79371
|
-
var USAGE6 = 'workit check <name> [--full] [--wait <dur> | --no-wait] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--heavy] [--full] [--wait <dur> | --no-wait] [--timeout <s>] [--task <id>] [--json] -- <cmd…>', OUTPUT_LINES = 60, MAX_UNVERIFIED_RUN_MS, RECORD_TAIL_LINES = 20, RECORD_TAIL_CHARS = 200, posix = (value) => value.split(
|
|
79732
|
+
var USAGE6 = 'workit check <name> [--full] [--wait <dur> | --no-wait] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--heavy] [--full] [--wait <dur> | --no-wait] [--timeout <s>] [--task <id>] [--json] -- <cmd…>', OUTPUT_LINES = 60, MAX_UNVERIFIED_RUN_MS, RECORD_TAIL_LINES = 20, RECORD_TAIL_CHARS = 200, posix = (value) => value.split(path54.sep).join("/") || ".", ENGINE_CODES2, FINGERPRINT_VARS, ANSI_COLOR, WARNING_LINE, NO_WARNINGS, STDERR_TAIL_LINES = 10, STDERR_KEEP_CHARS = 65536, FAILURE_LINE, MAX_FAILURE_LINES = 15;
|
|
79372
79733
|
var init_check = __esm(() => {
|
|
79373
79734
|
init_check_config();
|
|
79374
79735
|
init_checks3();
|
|
@@ -79376,6 +79737,7 @@ var init_check = __esm(() => {
|
|
|
79376
79737
|
init_package();
|
|
79377
79738
|
init_ledger();
|
|
79378
79739
|
init_output();
|
|
79740
|
+
init_progress();
|
|
79379
79741
|
init_host_session();
|
|
79380
79742
|
init_resources();
|
|
79381
79743
|
MAX_UNVERIFIED_RUN_MS = 6 * 3600000;
|
|
@@ -79398,7 +79760,7 @@ __export(exports_lock, {
|
|
|
79398
79760
|
run: () => run13
|
|
79399
79761
|
});
|
|
79400
79762
|
import fs25 from "node:fs";
|
|
79401
|
-
import
|
|
79763
|
+
import path55 from "node:path";
|
|
79402
79764
|
async function settingsFor(io) {
|
|
79403
79765
|
const workspace = await workspaceResources(io);
|
|
79404
79766
|
const config = loadCheckConfig(io.cwd);
|
|
@@ -79490,7 +79852,7 @@ function readPatterns(file) {
|
|
|
79490
79852
|
return { patterns: [] };
|
|
79491
79853
|
}
|
|
79492
79854
|
function writePatterns(file, value) {
|
|
79493
|
-
fs25.mkdirSync(
|
|
79855
|
+
fs25.mkdirSync(path55.dirname(file), { recursive: true, mode: 448 });
|
|
79494
79856
|
const temp = `${file}.${process.pid}.tmp`;
|
|
79495
79857
|
fs25.writeFileSync(temp, `${JSON.stringify(value, null, 2)}
|
|
79496
79858
|
`, { mode: 384 });
|
|
@@ -79578,7 +79940,7 @@ __export(exports_models, {
|
|
|
79578
79940
|
});
|
|
79579
79941
|
import { existsSync as existsSync25, readdirSync as readdirSync13, readFileSync as readFileSync24, statSync as statSync9 } from "node:fs";
|
|
79580
79942
|
import os22 from "node:os";
|
|
79581
|
-
import
|
|
79943
|
+
import path56 from "node:path";
|
|
79582
79944
|
async function run14(argv, io) {
|
|
79583
79945
|
const [sub, ...args] = argv.filter((arg) => arg !== "--json");
|
|
79584
79946
|
if (sub !== "show")
|
|
@@ -79653,20 +80015,20 @@ var USAGE8 = "workit models show [--role <role>] [--tier <tier>] [--host <host>]
|
|
|
79653
80015
|
} catch {}
|
|
79654
80016
|
return found;
|
|
79655
80017
|
}, matches3 = (ran, configured) => ran.toLowerCase().includes(configured.toLowerCase()), usageReport = (cwd, env, days) => {
|
|
79656
|
-
const projects =
|
|
80018
|
+
const projects = path56.join(env.CLAUDE_CONFIG_DIR || path56.join(env.HOME || os22.homedir(), ".claude"), "projects");
|
|
79657
80019
|
const since = Date.now() - days * 86400000;
|
|
79658
80020
|
const types = {};
|
|
79659
80021
|
let agents = 0;
|
|
79660
80022
|
const dirs = (dir) => {
|
|
79661
80023
|
try {
|
|
79662
|
-
return readdirSync13(dir).map((name) =>
|
|
80024
|
+
return readdirSync13(dir).map((name) => path56.join(dir, name));
|
|
79663
80025
|
} catch {
|
|
79664
80026
|
return [];
|
|
79665
80027
|
}
|
|
79666
80028
|
};
|
|
79667
80029
|
for (const project of dirs(projects))
|
|
79668
80030
|
for (const session of dirs(project))
|
|
79669
|
-
for (const meta of dirs(
|
|
80031
|
+
for (const meta of dirs(path56.join(session, "subagents")).filter((f) => f.endsWith(".meta.json"))) {
|
|
79670
80032
|
try {
|
|
79671
80033
|
if (statSync9(meta).mtimeMs < since)
|
|
79672
80034
|
continue;
|
|
@@ -79812,7 +80174,7 @@ var success2 = (data) => ({ ok: true, data }), failure3 = (code, error, unblock)
|
|
|
79812
80174
|
// packages/workit-core/src/git/ops.ts
|
|
79813
80175
|
import { spawnSync as spawnSync20 } from "node:child_process";
|
|
79814
80176
|
import { existsSync as existsSync26, readFileSync as readFileSync25 } from "node:fs";
|
|
79815
|
-
import
|
|
80177
|
+
import path57 from "node:path";
|
|
79816
80178
|
function operationInProgress(cwd) {
|
|
79817
80179
|
const markers = [
|
|
79818
80180
|
["rebase-merge", "rebase"],
|
|
@@ -79825,18 +80187,18 @@ function operationInProgress(cwd) {
|
|
|
79825
80187
|
if (!run.ok)
|
|
79826
80188
|
return null;
|
|
79827
80189
|
const found = run.stdout.split(`
|
|
79828
|
-
`).map((line) =>
|
|
80190
|
+
`).map((line) => path57.resolve(cwd, line.trim()));
|
|
79829
80191
|
const conflicted = () => git5(cwd, ["ls-files", "-u"]).stdout.trim() !== "";
|
|
79830
80192
|
for (const [index, [, operation]] of markers.entries()) {
|
|
79831
80193
|
const marker = found[index];
|
|
79832
80194
|
if (!marker || !existsSync26(marker))
|
|
79833
80195
|
continue;
|
|
79834
|
-
if (index === 1 && existsSync26(
|
|
80196
|
+
if (index === 1 && existsSync26(path57.join(marker, "applying")))
|
|
79835
80197
|
return { operation: "am", commitAllowed: false, branch: null };
|
|
79836
|
-
if (index === 0 && existsSync26(
|
|
80198
|
+
if (index === 0 && existsSync26(path57.join(marker, "amend")) && !conflicted()) {
|
|
79837
80199
|
let headName = "";
|
|
79838
80200
|
try {
|
|
79839
|
-
headName = readFileSync25(
|
|
80201
|
+
headName = readFileSync25(path57.join(marker, "head-name"), "utf8").trim();
|
|
79840
80202
|
} catch {}
|
|
79841
80203
|
const branch = headName.startsWith("refs/heads/") ? headName.slice("refs/heads/".length) : null;
|
|
79842
80204
|
return { operation, commitAllowed: branch !== null, branch };
|
|
@@ -80164,7 +80526,7 @@ function gitCommit(cwd, input) {
|
|
|
80164
80526
|
if (paths.some((value) => value.startsWith("-") || !value.trim()))
|
|
80165
80527
|
return failure3("invalid_input", "paths must not be empty or start with -");
|
|
80166
80528
|
const tracked = new Set(nulList(git5(cwd, ["ls-files", "-z", "--", ...paths]).stdout));
|
|
80167
|
-
const addable = paths.filter((value) => existsSync26(
|
|
80529
|
+
const addable = paths.filter((value) => existsSync26(path57.resolve(cwd, value)) || [...tracked].some((file) => file === value || file.startsWith(`${value}/`)));
|
|
80168
80530
|
if (addable.length) {
|
|
80169
80531
|
const added = git5(cwd, ["add", "-A", "--", ...addable]);
|
|
80170
80532
|
if (!added.ok)
|
|
@@ -80703,12 +81065,12 @@ var init_ops = __esm(() => {
|
|
|
80703
81065
|
|
|
80704
81066
|
// packages/workit-core/src/verdict-cover.ts
|
|
80705
81067
|
import fs26 from "node:fs";
|
|
80706
|
-
import
|
|
81068
|
+
import path58 from "node:path";
|
|
80707
81069
|
function chainsAbove(cwd, branch) {
|
|
80708
81070
|
const root = storeRoot(cwd);
|
|
80709
81071
|
if (!root.ok)
|
|
80710
81072
|
return [];
|
|
80711
|
-
const dir =
|
|
81073
|
+
const dir = path58.join(root.value.root, "stacks");
|
|
80712
81074
|
let names = [];
|
|
80713
81075
|
try {
|
|
80714
81076
|
names = fs26.readdirSync(dir).filter((name) => name.endsWith(".json"));
|
|
@@ -80719,7 +81081,7 @@ function chainsAbove(cwd, branch) {
|
|
|
80719
81081
|
for (const name of names.toSorted()) {
|
|
80720
81082
|
let parsed;
|
|
80721
81083
|
try {
|
|
80722
|
-
parsed = JSON.parse(fs26.readFileSync(
|
|
81084
|
+
parsed = JSON.parse(fs26.readFileSync(path58.join(dir, name), "utf8"));
|
|
80723
81085
|
} catch {
|
|
80724
81086
|
continue;
|
|
80725
81087
|
}
|
|
@@ -80875,10 +81237,10 @@ var init_check_evidence = __esm(() => {
|
|
|
80875
81237
|
|
|
80876
81238
|
// packages/workit-core/src/forge/reruns.ts
|
|
80877
81239
|
import fs27 from "node:fs";
|
|
80878
|
-
import
|
|
81240
|
+
import path59 from "node:path";
|
|
80879
81241
|
function rerunLogPath(cwd) {
|
|
80880
81242
|
const common = gitCommonDir(cwd);
|
|
80881
|
-
return common ?
|
|
81243
|
+
return common ? path59.join(common, "workit", "ci-reruns.jsonl") : null;
|
|
80882
81244
|
}
|
|
80883
81245
|
function rerunCounts(cwd, key) {
|
|
80884
81246
|
const counts = new Map;
|
|
@@ -80913,7 +81275,7 @@ function recordReruns(cwd, rows) {
|
|
|
80913
81275
|
if (!file)
|
|
80914
81276
|
return false;
|
|
80915
81277
|
try {
|
|
80916
|
-
fs27.mkdirSync(
|
|
81278
|
+
fs27.mkdirSync(path59.dirname(file), { recursive: true });
|
|
80917
81279
|
fs27.appendFileSync(file, rows.map((row) => `${JSON.stringify(row)}
|
|
80918
81280
|
`).join(""));
|
|
80919
81281
|
return true;
|
|
@@ -80926,7 +81288,7 @@ function withRerunLock(cwd, fn) {
|
|
|
80926
81288
|
if (!file)
|
|
80927
81289
|
return fn();
|
|
80928
81290
|
const lock = `${file.slice(0, -".jsonl".length)}.lock`;
|
|
80929
|
-
fs27.mkdirSync(
|
|
81291
|
+
fs27.mkdirSync(path59.dirname(lock), { recursive: true });
|
|
80930
81292
|
const until = Date.now() + LOCK_WAIT_MS2;
|
|
80931
81293
|
for (;; ) {
|
|
80932
81294
|
try {
|
|
@@ -81922,7 +82284,7 @@ var init_pr_ops = __esm(() => {
|
|
|
81922
82284
|
import { spawnSync as spawnSync22 } from "node:child_process";
|
|
81923
82285
|
import { createHash as createHash18, randomBytes as randomBytes4 } from "node:crypto";
|
|
81924
82286
|
import fs28 from "node:fs";
|
|
81925
|
-
import
|
|
82287
|
+
import path60 from "node:path";
|
|
81926
82288
|
function worktreeOf(cwd, branch) {
|
|
81927
82289
|
const list = gitRun3(cwd, ["worktree", "list", "--porcelain"]);
|
|
81928
82290
|
if (!list.ok)
|
|
@@ -81971,7 +82333,7 @@ function gitRestack(cwd, input) {
|
|
|
81971
82333
|
error: "no store root"
|
|
81972
82334
|
};
|
|
81973
82335
|
fs28.mkdirSync(scratch, { recursive: true });
|
|
81974
|
-
dir =
|
|
82336
|
+
dir = path60.join(scratch, `${input.branch.replace(/[^A-Za-z0-9._-]+/gu, "_").slice(0, 40)}-${randomBytes4(4).toString("hex")}`);
|
|
81975
82337
|
const added = gitRun3(cwd, ["worktree", "add", "-q", dir, input.branch], GIT_TIMEOUTS.worktree);
|
|
81976
82338
|
if (!added.ok)
|
|
81977
82339
|
return {
|
|
@@ -82027,7 +82389,7 @@ function pruneScratch(cwd) {
|
|
|
82027
82389
|
if (!scratch || !fs28.existsSync(scratch))
|
|
82028
82390
|
return;
|
|
82029
82391
|
for (const name of fs28.readdirSync(scratch)) {
|
|
82030
|
-
const dir =
|
|
82392
|
+
const dir = path60.join(scratch, name);
|
|
82031
82393
|
if (!rebaseInProgress(dir) && !trackedDirt(dir))
|
|
82032
82394
|
gitRun3(cwd, ["worktree", "remove", "--force", dir]);
|
|
82033
82395
|
}
|
|
@@ -82037,7 +82399,7 @@ function stacksDir(cwd) {
|
|
|
82037
82399
|
const root = storeRoot(cwd);
|
|
82038
82400
|
if (!root.ok)
|
|
82039
82401
|
return stackFail(root.code, root.error, root.unblock);
|
|
82040
|
-
return { ok: true, data:
|
|
82402
|
+
return { ok: true, data: path60.join(root.value.root, "stacks") };
|
|
82041
82403
|
}
|
|
82042
82404
|
function parseStack(raw) {
|
|
82043
82405
|
if (!isRecord12(raw) || !Array.isArray(raw.branches))
|
|
@@ -82089,7 +82451,7 @@ function readStack(cwd, name) {
|
|
|
82089
82451
|
const dir = stacksDir(cwd);
|
|
82090
82452
|
if (!dir.ok)
|
|
82091
82453
|
return dir;
|
|
82092
|
-
const file =
|
|
82454
|
+
const file = path60.join(dir.data, fileFor(name));
|
|
82093
82455
|
let text;
|
|
82094
82456
|
try {
|
|
82095
82457
|
text = fs28.readFileSync(file, "utf8");
|
|
@@ -82110,7 +82472,7 @@ function writeStack(cwd, stack, now = new Date) {
|
|
|
82110
82472
|
const dir = stacksDir(cwd);
|
|
82111
82473
|
if (!dir.ok)
|
|
82112
82474
|
return dir;
|
|
82113
|
-
const file =
|
|
82475
|
+
const file = path60.join(dir.data, fileFor(stack.name));
|
|
82114
82476
|
const temp = `${file}.${process.pid}.tmp`;
|
|
82115
82477
|
try {
|
|
82116
82478
|
fs28.mkdirSync(dir.data, { recursive: true });
|
|
@@ -82138,7 +82500,7 @@ function listStacks(cwd) {
|
|
|
82138
82500
|
for (const name of names) {
|
|
82139
82501
|
let parsed = null;
|
|
82140
82502
|
try {
|
|
82141
|
-
parsed = parseStack(JSON.parse(fs28.readFileSync(
|
|
82503
|
+
parsed = parseStack(JSON.parse(fs28.readFileSync(path60.join(dir.data, name), "utf8")));
|
|
82142
82504
|
} catch {
|
|
82143
82505
|
parsed = null;
|
|
82144
82506
|
}
|
|
@@ -82200,7 +82562,7 @@ function takeLock(lock) {
|
|
|
82200
82562
|
host: localLockHost(),
|
|
82201
82563
|
nonce: randomBytes4(8).toString("hex")
|
|
82202
82564
|
};
|
|
82203
|
-
fs28.writeFileSync(
|
|
82565
|
+
fs28.writeFileSync(path60.join(lock, OWNER), JSON.stringify(owner));
|
|
82204
82566
|
return owner;
|
|
82205
82567
|
}
|
|
82206
82568
|
function reapLock(lock, observed) {
|
|
@@ -82237,7 +82599,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
|
|
|
82237
82599
|
return dir;
|
|
82238
82600
|
if (!validName(name))
|
|
82239
82601
|
return stackFail("invalid_input", "a stack name must be 1-200 printable characters");
|
|
82240
|
-
const lock =
|
|
82602
|
+
const lock = path60.join(dir.data, `${fileFor(name)}.lock`);
|
|
82241
82603
|
try {
|
|
82242
82604
|
fs28.mkdirSync(dir.data, { recursive: true });
|
|
82243
82605
|
} catch (error) {
|
|
@@ -82267,7 +82629,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
|
|
|
82267
82629
|
const touch = () => {
|
|
82268
82630
|
try {
|
|
82269
82631
|
const now = new Date;
|
|
82270
|
-
fs28.utimesSync(
|
|
82632
|
+
fs28.utimesSync(path60.join(lock, OWNER), now, now);
|
|
82271
82633
|
} catch {}
|
|
82272
82634
|
};
|
|
82273
82635
|
const beat = setInterval(touch, HEARTBEAT_MS);
|
|
@@ -83236,7 +83598,7 @@ var STACK_VERSION = 1, stackFail = (code, error, unblock, data) => ({
|
|
|
83236
83598
|
return !status.ok || status.stdout.trim() !== "";
|
|
83237
83599
|
}, scratchDir = (cwd) => {
|
|
83238
83600
|
const dir = stacksDir(cwd);
|
|
83239
|
-
return dir.ok ?
|
|
83601
|
+
return dir.ok ? path60.join(dir.data, "worktrees") : null;
|
|
83240
83602
|
}, firstLine = (run) => (`${run.stderr}
|
|
83241
83603
|
${run.stdout}`.split(`
|
|
83242
83604
|
`).find((line) => line.trim()) ?? "git failed").trim().slice(0, 300), stackFileName = (name) => `${name.replace(/[^A-Za-z0-9._-]+/gu, "_").replace(/^[._]+/u, "").slice(0, 48).toLowerCase()}-${createHash18("sha256").update(name).digest("hex").slice(0, 12)}.json`, fileFor, validName = (name) => {
|
|
@@ -83251,12 +83613,12 @@ ${run.stdout}`.split(`
|
|
|
83251
83613
|
}, isRecord12 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), str3 = (value) => typeof value === "string" && value ? value : null, LOCK_WAIT_MS3 = 2000, HEARTBEAT_MS = 20000, HEARTBEAT_STALE_MS, OWNERLESS_STALE_MS = 30000, OWNER = "owner", readOwner = (lock) => {
|
|
83252
83614
|
let raw = null;
|
|
83253
83615
|
try {
|
|
83254
|
-
raw = fs28.readFileSync(
|
|
83616
|
+
raw = fs28.readFileSync(path60.join(lock, OWNER), "utf8");
|
|
83255
83617
|
} catch {
|
|
83256
83618
|
raw = null;
|
|
83257
83619
|
}
|
|
83258
83620
|
let age = null;
|
|
83259
|
-
for (const target of [
|
|
83621
|
+
for (const target of [path60.join(lock, OWNER), lock])
|
|
83260
83622
|
try {
|
|
83261
83623
|
age = Date.now() - fs28.statSync(target).mtimeMs;
|
|
83262
83624
|
break;
|
|
@@ -83300,7 +83662,7 @@ var init_stack = __esm(() => {
|
|
|
83300
83662
|
import { spawnSync as spawnSync23 } from "node:child_process";
|
|
83301
83663
|
import { createHash as createHash19 } from "node:crypto";
|
|
83302
83664
|
import fs29 from "node:fs";
|
|
83303
|
-
import
|
|
83665
|
+
import path61 from "node:path";
|
|
83304
83666
|
function expandBraces2(pattern, limit = 64) {
|
|
83305
83667
|
for (let index = 0;index < pattern.length; index += 1) {
|
|
83306
83668
|
if (pattern[index] === "\\") {
|
|
@@ -83546,7 +83908,7 @@ function parsePlan(raw, defaults, name) {
|
|
|
83546
83908
|
id,
|
|
83547
83909
|
branch,
|
|
83548
83910
|
base: optional("base") ?? "",
|
|
83549
|
-
worktree:
|
|
83911
|
+
worktree: path61.resolve(defaults.root, optional("worktree") ?? path61.join(defaults.worktreeRoot, id)),
|
|
83550
83912
|
tier,
|
|
83551
83913
|
reason,
|
|
83552
83914
|
dependsOn: [...new Set(dependsOn ?? [])],
|
|
@@ -83675,12 +84037,12 @@ function regeneratedFiles(root, tracked) {
|
|
|
83675
84037
|
const found = new Map;
|
|
83676
84038
|
let scripts;
|
|
83677
84039
|
try {
|
|
83678
|
-
const manifest = JSON.parse(fs29.readFileSync(
|
|
84040
|
+
const manifest = JSON.parse(fs29.readFileSync(path61.join(root, "package.json"), "utf8"));
|
|
83679
84041
|
scripts = manifest.scripts ?? {};
|
|
83680
84042
|
} catch {
|
|
83681
84043
|
return found;
|
|
83682
84044
|
}
|
|
83683
|
-
const runner = fs29.existsSync(
|
|
84045
|
+
const runner = fs29.existsSync(path61.join(root, "bun.lock")) ? "bun run" : fs29.existsSync(path61.join(root, "pnpm-lock.yaml")) ? "pnpm run" : fs29.existsSync(path61.join(root, "yarn.lock")) ? "yarn run" : "npm run";
|
|
83684
84046
|
const outputs = tracked.filter((file) => !CODE.test(file));
|
|
83685
84047
|
for (const [name, command] of Object.entries(scripts)) {
|
|
83686
84048
|
if (!name.startsWith("write:") || typeof command !== "string")
|
|
@@ -83688,7 +84050,7 @@ function regeneratedFiles(root, tracked) {
|
|
|
83688
84050
|
for (const file of command.match(/[\w./-]+\.[cm]?[jt]s\b/gu) ?? []) {
|
|
83689
84051
|
let source;
|
|
83690
84052
|
try {
|
|
83691
|
-
source = fs29.readFileSync(
|
|
84053
|
+
source = fs29.readFileSync(path61.join(root, file), "utf8");
|
|
83692
84054
|
} catch {
|
|
83693
84055
|
continue;
|
|
83694
84056
|
}
|
|
@@ -83810,11 +84172,11 @@ function defaultTrunk(cwd) {
|
|
|
83810
84172
|
}
|
|
83811
84173
|
function mainCheckout(cwd) {
|
|
83812
84174
|
const common = gitCommonDir(cwd);
|
|
83813
|
-
return common &&
|
|
84175
|
+
return common && path61.basename(common) === ".git" ? path61.dirname(common) : path61.resolve(cwd);
|
|
83814
84176
|
}
|
|
83815
84177
|
function worktreeRoot(cwd) {
|
|
83816
84178
|
const main = mainCheckout(cwd);
|
|
83817
|
-
return
|
|
84179
|
+
return path61.join(path61.dirname(main), `${path61.basename(main)}-wt`);
|
|
83818
84180
|
}
|
|
83819
84181
|
function sliceHash(slice) {
|
|
83820
84182
|
const {
|
|
@@ -83834,7 +84196,7 @@ function fanoutsDir(cwd) {
|
|
|
83834
84196
|
const root = storeRoot(cwd);
|
|
83835
84197
|
if (!root.ok)
|
|
83836
84198
|
return fanoutFail(root.code, root.error, root.unblock);
|
|
83837
|
-
return { ok: true, data:
|
|
84199
|
+
return { ok: true, data: path61.join(root.value.root, "fanouts") };
|
|
83838
84200
|
}
|
|
83839
84201
|
function parseStored(raw) {
|
|
83840
84202
|
if (!isRecord13(raw) || typeof raw.name !== "string" || typeof raw.trunk !== "string")
|
|
@@ -83902,7 +84264,7 @@ function readFanout(cwd, name) {
|
|
|
83902
84264
|
const dir = fanoutsDir(cwd);
|
|
83903
84265
|
if (!dir.ok)
|
|
83904
84266
|
return dir;
|
|
83905
|
-
const file =
|
|
84267
|
+
const file = path61.join(dir.data, stackFileName(name));
|
|
83906
84268
|
let parsed = null;
|
|
83907
84269
|
try {
|
|
83908
84270
|
parsed = parseStored(JSON.parse(fs29.readFileSync(file, "utf8")));
|
|
@@ -83927,7 +84289,7 @@ function listFanouts(cwd) {
|
|
|
83927
84289
|
for (const entry of names) {
|
|
83928
84290
|
let parsed = null;
|
|
83929
84291
|
try {
|
|
83930
|
-
parsed = parseStored(JSON.parse(fs29.readFileSync(
|
|
84292
|
+
parsed = parseStored(JSON.parse(fs29.readFileSync(path61.join(dir.data, entry), "utf8")));
|
|
83931
84293
|
} catch {
|
|
83932
84294
|
parsed = null;
|
|
83933
84295
|
}
|
|
@@ -83966,7 +84328,7 @@ function writeFanout(cwd, plan) {
|
|
|
83966
84328
|
const dir = fanoutsDir(cwd);
|
|
83967
84329
|
if (!dir.ok)
|
|
83968
84330
|
return dir;
|
|
83969
|
-
const file =
|
|
84331
|
+
const file = path61.join(dir.data, stackFileName(plan.name));
|
|
83970
84332
|
const temp = `${file}.${process.pid}.tmp`;
|
|
83971
84333
|
try {
|
|
83972
84334
|
fs29.mkdirSync(dir.data, { recursive: true });
|
|
@@ -84177,13 +84539,13 @@ var init_fanout = __esm(() => {
|
|
|
84177
84539
|
// packages/workit-core/src/forge/exec.ts
|
|
84178
84540
|
import { spawnSync as spawnSync24 } from "node:child_process";
|
|
84179
84541
|
import fs30 from "node:fs";
|
|
84180
|
-
import
|
|
84542
|
+
import path62 from "node:path";
|
|
84181
84543
|
function findExecutable(bin, env) {
|
|
84182
|
-
const dirs = (env.PATH ?? env.Path ?? "").split(
|
|
84544
|
+
const dirs = (env.PATH ?? env.Path ?? "").split(path62.delimiter).filter(Boolean);
|
|
84183
84545
|
const exts = process.platform === "win32" ? [".exe"] : [""];
|
|
84184
84546
|
for (const dir of dirs)
|
|
84185
84547
|
for (const ext of exts) {
|
|
84186
|
-
const candidate =
|
|
84548
|
+
const candidate = path62.join(dir, `${bin}${ext}`);
|
|
84187
84549
|
try {
|
|
84188
84550
|
const stat = fs30.statSync(candidate);
|
|
84189
84551
|
if (stat.isFile())
|
|
@@ -85973,7 +86335,7 @@ var init_live_session = __esm(() => {
|
|
|
85973
86335
|
});
|
|
85974
86336
|
|
|
85975
86337
|
// packages/workit-core/src/hooks/write-gate.ts
|
|
85976
|
-
import
|
|
86338
|
+
import path63 from "node:path";
|
|
85977
86339
|
var CASE_INSENSITIVE, PREFIXES2, SCRIPT_SHELLS, cache3, MUTATING_GIT, DRY_N, MUTATING_WORKIT_GIT, CD2, PUSHD2, POPD2, UNKNOWN_DIR;
|
|
85978
86340
|
var init_write_gate = __esm(() => {
|
|
85979
86341
|
init_task_store();
|
|
@@ -86013,7 +86375,7 @@ var init_write_gate = __esm(() => {
|
|
|
86013
86375
|
CD2 = new Set(["cd", "chdir", "set-location", "sl"]);
|
|
86014
86376
|
PUSHD2 = new Set(["pushd", "push-location"]);
|
|
86015
86377
|
POPD2 = new Set(["popd", "pop-location"]);
|
|
86016
|
-
UNKNOWN_DIR =
|
|
86378
|
+
UNKNOWN_DIR = path63.resolve(path63.parse(process.cwd()).root, ".workit-unknown-dir");
|
|
86017
86379
|
});
|
|
86018
86380
|
|
|
86019
86381
|
// packages/workit-core/src/hooks/worktree-confine.ts
|
|
@@ -86038,20 +86400,20 @@ var init_worktree_confine = __esm(() => {
|
|
|
86038
86400
|
|
|
86039
86401
|
// packages/workit-core/src/worktree-deps.ts
|
|
86040
86402
|
import fs31 from "node:fs";
|
|
86041
|
-
import
|
|
86403
|
+
import path64 from "node:path";
|
|
86042
86404
|
function moduleDirs(main) {
|
|
86043
86405
|
const out = [];
|
|
86044
86406
|
const walk = (relative, depth) => {
|
|
86045
86407
|
let entries;
|
|
86046
86408
|
try {
|
|
86047
|
-
entries = fs31.readdirSync(
|
|
86409
|
+
entries = fs31.readdirSync(path64.join(main, relative), { withFileTypes: true });
|
|
86048
86410
|
} catch {
|
|
86049
86411
|
return;
|
|
86050
86412
|
}
|
|
86051
86413
|
for (const entry of entries) {
|
|
86052
86414
|
if (!entry.isDirectory())
|
|
86053
86415
|
continue;
|
|
86054
|
-
const child =
|
|
86416
|
+
const child = path64.join(relative, entry.name);
|
|
86055
86417
|
if (entry.name === MODULES)
|
|
86056
86418
|
out.push(child);
|
|
86057
86419
|
else if (depth < MAX_DEPTH2 && !entry.name.startsWith("."))
|
|
@@ -86065,8 +86427,8 @@ function linkEntry(main, worktree, source, target) {
|
|
|
86065
86427
|
const stat = fs31.lstatSync(source);
|
|
86066
86428
|
if (stat.isSymbolicLink()) {
|
|
86067
86429
|
const link = fs31.readlinkSync(source);
|
|
86068
|
-
const outside =
|
|
86069
|
-
const to = outside ?
|
|
86430
|
+
const outside = path64.isAbsolute(link) && within(link, main) && !path64.relative(main, link).split(path64.sep).includes(MODULES);
|
|
86431
|
+
const to = outside ? path64.join(worktree, path64.relative(main, link)) : link;
|
|
86070
86432
|
fs31.symlinkSync(to, target, process.platform === "win32" ? "junction" : undefined);
|
|
86071
86433
|
return;
|
|
86072
86434
|
}
|
|
@@ -86076,8 +86438,8 @@ function mirror(main, worktree, source, target, top) {
|
|
|
86076
86438
|
fs31.mkdirSync(target);
|
|
86077
86439
|
let count = 0;
|
|
86078
86440
|
for (const entry of fs31.readdirSync(source, { withFileTypes: true })) {
|
|
86079
|
-
const from =
|
|
86080
|
-
const to =
|
|
86441
|
+
const from = path64.join(source, entry.name);
|
|
86442
|
+
const to = path64.join(target, entry.name);
|
|
86081
86443
|
if (top && entry.isDirectory() && (entry.name.startsWith("@") || entry.name === ".bin"))
|
|
86082
86444
|
count += mirror(main, worktree, from, to, false);
|
|
86083
86445
|
else {
|
|
@@ -86093,16 +86455,16 @@ function linkWorktreeDependencies(main, worktree) {
|
|
|
86093
86455
|
const dirs = [];
|
|
86094
86456
|
let entries = 0;
|
|
86095
86457
|
for (const relative of moduleDirs(main)) {
|
|
86096
|
-
const target =
|
|
86097
|
-
if (!fs31.existsSync(
|
|
86458
|
+
const target = path64.join(worktree, relative);
|
|
86459
|
+
if (!fs31.existsSync(path64.dirname(target)) || fs31.existsSync(target))
|
|
86098
86460
|
continue;
|
|
86099
|
-
if (!gitRun4(worktree, ["check-ignore", "-q", `${relative.split(
|
|
86100
|
-
notes.push(`${relative.split(
|
|
86461
|
+
if (!gitRun4(worktree, ["check-ignore", "-q", `${relative.split(path64.sep).join("/")}/`]).ok) {
|
|
86462
|
+
notes.push(`${relative.split(path64.sep).join("/")} is not ignored by git, so it was not linked from ${main}; install dependencies in the worktree yourself`);
|
|
86101
86463
|
continue;
|
|
86102
86464
|
}
|
|
86103
86465
|
try {
|
|
86104
|
-
entries += mirror(main, worktree,
|
|
86105
|
-
dirs.push(relative.split(
|
|
86466
|
+
entries += mirror(main, worktree, path64.join(main, relative), target, true);
|
|
86467
|
+
dirs.push(relative.split(path64.sep).join("/"));
|
|
86106
86468
|
} catch (error) {
|
|
86107
86469
|
fs31.rmSync(target, { recursive: true, force: true });
|
|
86108
86470
|
notes.push(`could not link ${relative} from ${main} (${error.message}); install dependencies in the worktree yourself`);
|
|
@@ -86115,8 +86477,8 @@ function linkWorktreeDependencies(main, worktree) {
|
|
|
86115
86477
|
return { linked: { from: main, dirs, entries, ms }, notes };
|
|
86116
86478
|
}
|
|
86117
86479
|
var MODULES = "node_modules", MAX_DEPTH2 = 2, within = (child, parent) => {
|
|
86118
|
-
const relative =
|
|
86119
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
86480
|
+
const relative = path64.relative(parent, child);
|
|
86481
|
+
return relative === "" || !relative.startsWith("..") && !path64.isAbsolute(relative);
|
|
86120
86482
|
};
|
|
86121
86483
|
var init_worktree_deps = __esm(() => {
|
|
86122
86484
|
init_fanout();
|
|
@@ -86125,7 +86487,7 @@ var init_worktree_deps = __esm(() => {
|
|
|
86125
86487
|
// packages/workit-core/src/fanout-worktree.ts
|
|
86126
86488
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
86127
86489
|
import fs32 from "node:fs";
|
|
86128
|
-
import
|
|
86490
|
+
import path65 from "node:path";
|
|
86129
86491
|
function rowSample(lines) {
|
|
86130
86492
|
const out = [];
|
|
86131
86493
|
let bytes = 0;
|
|
@@ -86185,7 +86547,7 @@ function adminDir(worktree) {
|
|
|
86185
86547
|
const file = dir.stdout.trim();
|
|
86186
86548
|
let token = null;
|
|
86187
86549
|
try {
|
|
86188
|
-
token = fs32.readFileSync(
|
|
86550
|
+
token = fs32.readFileSync(path65.join(file, FANOUT_TOKEN_FILE), "utf8").trim() || null;
|
|
86189
86551
|
} catch {
|
|
86190
86552
|
token = null;
|
|
86191
86553
|
}
|
|
@@ -86193,7 +86555,7 @@ function adminDir(worktree) {
|
|
|
86193
86555
|
const stat = worktreeDeps.stat(file);
|
|
86194
86556
|
return {
|
|
86195
86557
|
path: file,
|
|
86196
|
-
id:
|
|
86558
|
+
id: path65.basename(file),
|
|
86197
86559
|
ino: stat.ino.toString(),
|
|
86198
86560
|
token,
|
|
86199
86561
|
birthMs: stat.birthtimeNs > 0n ? Number(stat.birthtimeMs) : null,
|
|
@@ -86209,7 +86571,7 @@ function markAdminDir(worktree) {
|
|
|
86209
86571
|
return null;
|
|
86210
86572
|
const token = randomBytes5(16).toString("hex");
|
|
86211
86573
|
try {
|
|
86212
|
-
fs32.writeFileSync(
|
|
86574
|
+
fs32.writeFileSync(path65.join(admin.path, FANOUT_TOKEN_FILE), `${token}
|
|
86213
86575
|
`);
|
|
86214
86576
|
} catch {
|
|
86215
86577
|
return null;
|
|
@@ -86224,7 +86586,7 @@ function excludeScratch(cwd) {
|
|
|
86224
86586
|
const common = gitCommonDir(cwd);
|
|
86225
86587
|
if (!common)
|
|
86226
86588
|
return;
|
|
86227
|
-
const file =
|
|
86589
|
+
const file = path65.join(common, "info", "exclude");
|
|
86228
86590
|
let text = "";
|
|
86229
86591
|
try {
|
|
86230
86592
|
text = fs32.readFileSync(file, "utf8");
|
|
@@ -86233,7 +86595,7 @@ function excludeScratch(cwd) {
|
|
|
86233
86595
|
}
|
|
86234
86596
|
if (text.split(/\r?\n/u).includes(EXCLUDE_LINE))
|
|
86235
86597
|
return;
|
|
86236
|
-
fs32.mkdirSync(
|
|
86598
|
+
fs32.mkdirSync(path65.dirname(file), { recursive: true });
|
|
86237
86599
|
fs32.appendFileSync(file, `${text && !text.endsWith(`
|
|
86238
86600
|
`) ? `
|
|
86239
86601
|
` : ""}# workit fanout: per-worker scratch dirs
|
|
@@ -86242,13 +86604,13 @@ ${EXCLUDE_LINE}
|
|
|
86242
86604
|
}
|
|
86243
86605
|
function worktreeDependencies(main, worktree) {
|
|
86244
86606
|
for (const [name, install] of LOCKFILES2) {
|
|
86245
|
-
const ours = readBytes(
|
|
86246
|
-
const theirs = readBytes(
|
|
86607
|
+
const ours = readBytes(path65.join(main, name));
|
|
86608
|
+
const theirs = readBytes(path65.join(worktree, name));
|
|
86247
86609
|
if (ours === null && theirs === null)
|
|
86248
86610
|
continue;
|
|
86249
86611
|
if (ours !== null && theirs !== null && ours.equals(theirs))
|
|
86250
86612
|
continue;
|
|
86251
|
-
if (fs32.existsSync(
|
|
86613
|
+
if (fs32.existsSync(path65.join(worktree, "node_modules")))
|
|
86252
86614
|
break;
|
|
86253
86615
|
const command = install(worktree);
|
|
86254
86616
|
return {
|
|
@@ -86260,7 +86622,7 @@ function worktreeDependencies(main, worktree) {
|
|
|
86260
86622
|
};
|
|
86261
86623
|
}
|
|
86262
86624
|
const stale = staleBunInstall(main);
|
|
86263
|
-
if (stale && !fs32.existsSync(
|
|
86625
|
+
if (stale && !fs32.existsSync(path65.join(worktree, "node_modules"))) {
|
|
86264
86626
|
const command = `bun install --frozen-lockfile --cwd ${worktree}`;
|
|
86265
86627
|
return {
|
|
86266
86628
|
linked: null,
|
|
@@ -86273,9 +86635,9 @@ function worktreeDependencies(main, worktree) {
|
|
|
86273
86635
|
return { ...linkWorktreeDependencies(main, worktree), install: null };
|
|
86274
86636
|
}
|
|
86275
86637
|
function staleBunInstall(main) {
|
|
86276
|
-
if (!fs32.existsSync(
|
|
86638
|
+
if (!fs32.existsSync(path65.join(main, "node_modules")))
|
|
86277
86639
|
return null;
|
|
86278
|
-
const text = readBytes(
|
|
86640
|
+
const text = readBytes(path65.join(main, "bun.lock"))?.toString("utf8");
|
|
86279
86641
|
if (!text)
|
|
86280
86642
|
return null;
|
|
86281
86643
|
let packages;
|
|
@@ -86302,7 +86664,7 @@ function staleBunInstall(main) {
|
|
|
86302
86664
|
const version = spec.slice(at + 1);
|
|
86303
86665
|
if (name !== key || version.includes(":"))
|
|
86304
86666
|
continue;
|
|
86305
|
-
const manifest = readBytes(
|
|
86667
|
+
const manifest = readBytes(path65.join(main, "node_modules", key, "package.json"));
|
|
86306
86668
|
if (!manifest) {
|
|
86307
86669
|
problems.push(`${key} missing`);
|
|
86308
86670
|
continue;
|
|
@@ -86319,7 +86681,7 @@ function staleBunInstall(main) {
|
|
|
86319
86681
|
return problems.length ? problems.join("; ") : null;
|
|
86320
86682
|
}
|
|
86321
86683
|
function ensureScratch(worktree) {
|
|
86322
|
-
const scratch =
|
|
86684
|
+
const scratch = path65.join(worktree, SCRATCH_DIR);
|
|
86323
86685
|
fs32.mkdirSync(scratch, { recursive: true });
|
|
86324
86686
|
return scratch;
|
|
86325
86687
|
}
|
|
@@ -86593,7 +86955,7 @@ function unpushedCount(cwd, branch) {
|
|
|
86593
86955
|
return count.ok ? Number(count.stdout.trim()) : null;
|
|
86594
86956
|
}
|
|
86595
86957
|
function removeScratch(worktree) {
|
|
86596
|
-
const scratch =
|
|
86958
|
+
const scratch = path65.join(worktree, SCRATCH_DIR);
|
|
86597
86959
|
let stat;
|
|
86598
86960
|
try {
|
|
86599
86961
|
stat = fs32.lstatSync(scratch);
|
|
@@ -86609,16 +86971,16 @@ var SLOW, SCRATCH_DIR = ".workit-scratch", EXCLUDE_LINE, DIRTY_ROW_BYTES = 2000,
|
|
|
86609
86971
|
try {
|
|
86610
86972
|
return fs32.realpathSync.native(target);
|
|
86611
86973
|
} catch {
|
|
86612
|
-
return
|
|
86974
|
+
return path65.resolve(target);
|
|
86613
86975
|
}
|
|
86614
86976
|
}, samePath = (a, b) => {
|
|
86615
86977
|
const left = canonical2(a);
|
|
86616
86978
|
const right = canonical2(b);
|
|
86617
86979
|
return process.platform === "win32" || process.platform === "darwin" ? left.toLowerCase() === right.toLowerCase() : left === right;
|
|
86618
86980
|
}, inside3 = (child, parent) => {
|
|
86619
|
-
const relative =
|
|
86620
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
86621
|
-
}, slicePath = (cwd, slice) =>
|
|
86981
|
+
const relative = path65.relative(canonical2(parent), canonical2(child));
|
|
86982
|
+
return relative === "" || !relative.startsWith("..") && !path65.isAbsolute(relative);
|
|
86983
|
+
}, slicePath = (cwd, slice) => path65.isAbsolute(slice.worktree) ? slice.worktree : path65.resolve(mainCheckout(cwd), slice.worktree), CLOCK_SLACK_MS = 2000, worktreeDeps, LOCKFILES2, readBytes = (file) => {
|
|
86622
86984
|
try {
|
|
86623
86985
|
return fs32.readFileSync(file);
|
|
86624
86986
|
} catch {
|
|
@@ -86650,7 +87012,7 @@ var init_fanout_worktree = __esm(() => {
|
|
|
86650
87012
|
|
|
86651
87013
|
// packages/workit-core/src/forge/merge-cleanup.ts
|
|
86652
87014
|
import fs33 from "node:fs";
|
|
86653
|
-
import
|
|
87015
|
+
import path66 from "node:path";
|
|
86654
87016
|
function cleanupMergedBranch(cwd, branch, mergedHead) {
|
|
86655
87017
|
const out = { branchDeleted: false, worktreeRemoved: null, notes: [] };
|
|
86656
87018
|
if (!branch || branch.startsWith("-"))
|
|
@@ -86710,13 +87072,13 @@ var SLOW2, isFanoutWorktree = (worktree) => {
|
|
|
86710
87072
|
if (!dir.ok)
|
|
86711
87073
|
return false;
|
|
86712
87074
|
try {
|
|
86713
|
-
return fs33.readFileSync(
|
|
87075
|
+
return fs33.readFileSync(path66.join(dir.stdout.trim(), FANOUT_TOKEN_FILE), "utf8").trim() !== "";
|
|
86714
87076
|
} catch {
|
|
86715
87077
|
return false;
|
|
86716
87078
|
}
|
|
86717
87079
|
}, inside4 = (child, parent) => {
|
|
86718
|
-
const relative =
|
|
86719
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
87080
|
+
const relative = path66.relative(fs33.realpathSync.native(parent), fs33.realpathSync.native(child));
|
|
87081
|
+
return relative === "" || !relative.startsWith("..") && !path66.isAbsolute(relative);
|
|
86720
87082
|
};
|
|
86721
87083
|
var init_merge_cleanup = __esm(() => {
|
|
86722
87084
|
init_fanout();
|
|
@@ -87168,7 +87530,7 @@ __export(exports_pr, {
|
|
|
87168
87530
|
run: () => run15
|
|
87169
87531
|
});
|
|
87170
87532
|
import { existsSync as existsSync27, readFileSync as readFileSync27 } from "node:fs";
|
|
87171
|
-
import
|
|
87533
|
+
import path67 from "node:path";
|
|
87172
87534
|
function titleRules(cwd) {
|
|
87173
87535
|
let root;
|
|
87174
87536
|
try {
|
|
@@ -87179,7 +87541,7 @@ function titleRules(cwd) {
|
|
|
87179
87541
|
let text = null;
|
|
87180
87542
|
let name = "";
|
|
87181
87543
|
for (const candidate of COMMITLINT_FILES) {
|
|
87182
|
-
const full =
|
|
87544
|
+
const full = path67.join(root, candidate);
|
|
87183
87545
|
if (!existsSync27(full))
|
|
87184
87546
|
continue;
|
|
87185
87547
|
text = readFileSync27(full, "utf8");
|
|
@@ -87188,7 +87550,7 @@ function titleRules(cwd) {
|
|
|
87188
87550
|
}
|
|
87189
87551
|
if (text === null) {
|
|
87190
87552
|
try {
|
|
87191
|
-
const pkg = JSON.parse(readFileSync27(
|
|
87553
|
+
const pkg = JSON.parse(readFileSync27(path67.join(root, "package.json"), "utf8"));
|
|
87192
87554
|
if (pkg.commitlint === undefined)
|
|
87193
87555
|
return { rules: null, note: null };
|
|
87194
87556
|
text = JSON.stringify(pkg.commitlint);
|
|
@@ -87285,7 +87647,7 @@ function refuseTitle(io, title, line) {
|
|
|
87285
87647
|
function readBodyFile(io, file) {
|
|
87286
87648
|
try {
|
|
87287
87649
|
return {
|
|
87288
|
-
body: file === "-" ? forgeDeps.readStdin() : readFileSync27(
|
|
87650
|
+
body: file === "-" ? forgeDeps.readStdin() : readFileSync27(path67.resolve(io.cwd, file), "utf8")
|
|
87289
87651
|
};
|
|
87290
87652
|
} catch {
|
|
87291
87653
|
return `cannot read --body-file ${file}`;
|
|
@@ -87930,6 +88292,11 @@ async function wait2(argv, io) {
|
|
|
87930
88292
|
let verdict = { state: "waiting", reason: "not_polled" };
|
|
87931
88293
|
let baseContexts = null;
|
|
87932
88294
|
let expectedMissing = [];
|
|
88295
|
+
const waiting = createProgress({ stream: process.stderr, json: io.json }).start("Waiting for CI");
|
|
88296
|
+
const abort = (...args) => {
|
|
88297
|
+
waiting.end("failed");
|
|
88298
|
+
return forgeFail(io, ...args);
|
|
88299
|
+
};
|
|
87933
88300
|
for (;; ) {
|
|
87934
88301
|
const read = resolved.forge.prStatus(number.data);
|
|
87935
88302
|
polls += 1;
|
|
@@ -87939,7 +88306,7 @@ async function wait2(argv, io) {
|
|
|
87939
88306
|
status = read.data;
|
|
87940
88307
|
const doc = buildStatusDoc(io.cwd, resolved, status, { logLines: 0, behind: false });
|
|
87941
88308
|
if (!doc.ok)
|
|
87942
|
-
return
|
|
88309
|
+
return abort(doc);
|
|
87943
88310
|
recordPrStatus(io.cwd, doc.data, actor);
|
|
87944
88311
|
if (status.requiredContexts === null && baseContexts === null) {
|
|
87945
88312
|
const base = resolved.forge.branchChecks(status.base);
|
|
@@ -87950,12 +88317,14 @@ async function wait2(argv, io) {
|
|
|
87950
88317
|
verdict = waitVerdict(doc.data, { head, elapsedMs, expectedMissing });
|
|
87951
88318
|
if (verdict.state !== "waiting")
|
|
87952
88319
|
break;
|
|
88320
|
+
const pending = doc.data.checks.pending;
|
|
88321
|
+
waiting.label(`Waiting for CI: ${pending.length} check${pending.length === 1 ? "" : "s"} pending${pending.length ? ` (${pending.slice(0, 3).join(", ")}${pending.length > 3 ? ", …" : ""})` : ""}`);
|
|
87953
88322
|
} else {
|
|
87954
88323
|
errors += 1;
|
|
87955
88324
|
if (read.code !== "unavailable" && read.code !== "failed")
|
|
87956
|
-
return
|
|
88325
|
+
return abort(read);
|
|
87957
88326
|
if (errors >= MAX_POLL_ERRORS)
|
|
87958
|
-
return
|
|
88327
|
+
return abort(read, { polls });
|
|
87959
88328
|
}
|
|
87960
88329
|
const remaining = deadline - forgeDeps.now();
|
|
87961
88330
|
if (remaining <= 0)
|
|
@@ -87963,6 +88332,7 @@ async function wait2(argv, io) {
|
|
|
87963
88332
|
await forgeDeps.sleep(Math.min(pollDelay(intervalMs, polls - 1), remaining));
|
|
87964
88333
|
}
|
|
87965
88334
|
const elapsedMs = forgeDeps.now() - started;
|
|
88335
|
+
waiting.end(verdict.state === "ready" ? "done" : verdict.state === "waiting" ? "skipped" : "failed");
|
|
87966
88336
|
if (!status)
|
|
87967
88337
|
return emit(io, fail2("unavailable", "no successful poll before the timeout", { data: { polls } }));
|
|
87968
88338
|
const left = deadline - forgeDeps.now();
|
|
@@ -88129,6 +88499,7 @@ var init_ci = __esm(() => {
|
|
|
88129
88499
|
init_ledger();
|
|
88130
88500
|
init_autonomy();
|
|
88131
88501
|
init_output();
|
|
88502
|
+
init_progress();
|
|
88132
88503
|
init_forge_common();
|
|
88133
88504
|
});
|
|
88134
88505
|
|
|
@@ -88165,7 +88536,7 @@ __export(exports_git, {
|
|
|
88165
88536
|
run: () => run17
|
|
88166
88537
|
});
|
|
88167
88538
|
import { readFileSync as readFileSync28 } from "node:fs";
|
|
88168
|
-
import
|
|
88539
|
+
import path68 from "node:path";
|
|
88169
88540
|
function kindHint(cwd, kind) {
|
|
88170
88541
|
let kinds = [...BRANCH_KINDS];
|
|
88171
88542
|
try {
|
|
@@ -88269,7 +88640,7 @@ function commitMessage(parsed, io) {
|
|
|
88269
88640
|
|
|
88270
88641
|
`);
|
|
88271
88642
|
try {
|
|
88272
|
-
return file === "-" ? readFileSync28(0, "utf8") : readFileSync28(
|
|
88643
|
+
return file === "-" ? readFileSync28(0, "utf8") : readFileSync28(path68.resolve(io.cwd, file), "utf8");
|
|
88273
88644
|
} catch (error) {
|
|
88274
88645
|
return {
|
|
88275
88646
|
error: `cannot read -F ${file}: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -89727,7 +90098,7 @@ var init_stack2 = __esm(() => {
|
|
|
89727
90098
|
// packages/workit-core/src/fanout-brief.ts
|
|
89728
90099
|
import { createHash as createHash20 } from "node:crypto";
|
|
89729
90100
|
import fs35 from "node:fs";
|
|
89730
|
-
import
|
|
90101
|
+
import path69 from "node:path";
|
|
89731
90102
|
function workerSession(lead, slice, attempt) {
|
|
89732
90103
|
const tail = attempt === null ? "" : `+try${attempt}`;
|
|
89733
90104
|
const full = `${lead}-w-${slice}${tail}`;
|
|
@@ -89810,7 +90181,7 @@ function renderBrief(cwd, plan, input) {
|
|
|
89810
90181
|
"STANDING:",
|
|
89811
90182
|
...standing.length ? standing.map((order) => ` - ${order.what}`) : [" - none recorded beyond this brief"],
|
|
89812
90183
|
exists ? `WORKTREE: ${planned} (made by \`workit fanout worktree create ${slice.id}\`; yours alone)` : `WORKTREE: ${planned} (not made yet: the lead runs \`workit fanout worktree create ${slice.id}\` before spawning, then renders this brief again)`,
|
|
89813
|
-
...exists && typeof made?.install === "string" && !fs35.existsSync(
|
|
90184
|
+
...exists && typeof made?.install === "string" && !fs35.existsSync(path69.join(planned, "node_modules")) ? [`INSTALL: \`${made.install}\` first: the main checkout's node_modules was not linked here`] : [],
|
|
89814
90185
|
...identityLines(identity, minted),
|
|
89815
90186
|
...rules(mode, branch, sliceBase, exists ? planned : null)
|
|
89816
90187
|
];
|
|
@@ -90352,7 +90723,7 @@ __export(exports_fanout, {
|
|
|
90352
90723
|
run: () => run21
|
|
90353
90724
|
});
|
|
90354
90725
|
import fs36 from "node:fs";
|
|
90355
|
-
import
|
|
90726
|
+
import path70 from "node:path";
|
|
90356
90727
|
function forgeFor(io, offline) {
|
|
90357
90728
|
if (offline)
|
|
90358
90729
|
return { forge: null, error: "--offline" };
|
|
@@ -90413,7 +90784,7 @@ function plan2(argv, io) {
|
|
|
90413
90784
|
return usage4(io, "pass --trunk or --track, not both (--track picks the trunk)", PLAN_USAGE2);
|
|
90414
90785
|
if (flags.positionals.length !== 1)
|
|
90415
90786
|
return usage4(io, flags.positionals.length ? `unexpected argument ${flags.positionals[1]}` : "missing <plan.json>", PLAN_USAGE2);
|
|
90416
|
-
const file =
|
|
90787
|
+
const file = path70.resolve(io.cwd, flags.positionals[0]);
|
|
90417
90788
|
let raw;
|
|
90418
90789
|
try {
|
|
90419
90790
|
raw = JSON.parse(fs36.readFileSync(file, "utf8"));
|
|
@@ -105988,7 +106359,7 @@ var init_ast = __esm(() => {
|
|
|
105988
106359
|
|
|
105989
106360
|
// packages/workit-cli/src/test-audit/rules.ts
|
|
105990
106361
|
import { builtinModules } from "node:module";
|
|
105991
|
-
import
|
|
106362
|
+
import path71 from "node:path";
|
|
105992
106363
|
function testCallee(call) {
|
|
105993
106364
|
let callee = call.callee;
|
|
105994
106365
|
if (callee.type === "CallExpression")
|
|
@@ -106481,12 +106852,12 @@ function checkConstantsOnly(ctx, emit) {
|
|
|
106481
106852
|
}
|
|
106482
106853
|
function checkOverMocking(ctx, emit) {
|
|
106483
106854
|
const { program } = ctx.parsed;
|
|
106484
|
-
const unit =
|
|
106855
|
+
const unit = path71.basename(ctx.file).replace(/\.(?:[cm]?[jt]sx?)$/, "").replace(/\.(?:test|spec)$/, "");
|
|
106485
106856
|
const mocked = find2(program, (node) => node.type === "CallExpression" && MODULE_MOCK.test(calleeName(node.callee) ?? "") && node.arguments[0]?.type === "StringLiteral");
|
|
106486
106857
|
const internal = mocked.filter((call) => /^(?:\.|@\/|~\/)/.test(call.arguments[0].value));
|
|
106487
106858
|
for (const call of mocked) {
|
|
106488
106859
|
const spec = call.arguments[0].value;
|
|
106489
|
-
const base =
|
|
106860
|
+
const base = path71.basename(spec.replace(/\/index(?:\.[cm]?[jt]sx?)?$/, "")).replace(/\.(?:[cm]?[jt]sx?)$/, "");
|
|
106490
106861
|
if (base === unit)
|
|
106491
106862
|
emit({
|
|
106492
106863
|
rule: "over-mocking",
|
|
@@ -106876,7 +107247,7 @@ var init_rules = __esm(() => {
|
|
|
106876
107247
|
// packages/workit-cli/src/test-audit/audit.ts
|
|
106877
107248
|
import { spawnSync as spawnSync29 } from "node:child_process";
|
|
106878
107249
|
import { existsSync as existsSync28, readdirSync as readdirSync14, readFileSync as readFileSync29, statSync as statSync10 } from "node:fs";
|
|
106879
|
-
import
|
|
107250
|
+
import path72 from "node:path";
|
|
106880
107251
|
function git7(cwd, args) {
|
|
106881
107252
|
const run = spawnSync29("git", ["-c", "core.quotepath=off", ...args], {
|
|
106882
107253
|
cwd,
|
|
@@ -106889,7 +107260,7 @@ function walkTests(dir, out) {
|
|
|
106889
107260
|
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
106890
107261
|
if (entry.name.startsWith(".") && entry.name !== "." && entry.isDirectory())
|
|
106891
107262
|
continue;
|
|
106892
|
-
const full =
|
|
107263
|
+
const full = path72.join(dir, entry.name);
|
|
106893
107264
|
if (entry.isDirectory()) {
|
|
106894
107265
|
if (!SKIP_DIRS.has(entry.name))
|
|
106895
107266
|
walkTests(full, out);
|
|
@@ -106901,7 +107272,7 @@ function expandPaths(cwd, inputs) {
|
|
|
106901
107272
|
const files = [];
|
|
106902
107273
|
const missing = [];
|
|
106903
107274
|
for (const input of inputs.length > 0 ? inputs : ["."]) {
|
|
106904
|
-
const full =
|
|
107275
|
+
const full = path72.resolve(cwd, input);
|
|
106905
107276
|
if (!existsSync28(full))
|
|
106906
107277
|
missing.push(input);
|
|
106907
107278
|
else if (statSync10(full).isDirectory())
|
|
@@ -106938,11 +107309,11 @@ function changedLines(cwd, base) {
|
|
|
106938
107309
|
for (let offset = 0;offset < count; offset += 1)
|
|
106939
107310
|
lines.add(start + offset);
|
|
106940
107311
|
}
|
|
106941
|
-
changed.set(
|
|
107312
|
+
changed.set(path72.join(root, file), lines);
|
|
106942
107313
|
}
|
|
106943
107314
|
const untracked = git7(root, ["ls-files", "--others", "--exclude-standard", "-z"]);
|
|
106944
107315
|
for (const file of untracked.stdout.split("\x00").filter(Boolean))
|
|
106945
|
-
changed.set(
|
|
107316
|
+
changed.set(path72.join(root, file), "all");
|
|
106946
107317
|
return changed;
|
|
106947
107318
|
}
|
|
106948
107319
|
function auditFiles(files, display) {
|
|
@@ -107004,7 +107375,7 @@ function auditFiles(files, display) {
|
|
|
107004
107375
|
durationMs: Math.round(performance.now() - started)
|
|
107005
107376
|
};
|
|
107006
107377
|
}
|
|
107007
|
-
var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(
|
|
107378
|
+
var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(path72.sep).join("/"), SEVERITY_ORDER, ruleIds;
|
|
107008
107379
|
var init_audit = __esm(() => {
|
|
107009
107380
|
init_ast();
|
|
107010
107381
|
init_rules();
|
|
@@ -107016,7 +107387,7 @@ var init_audit = __esm(() => {
|
|
|
107016
107387
|
});
|
|
107017
107388
|
|
|
107018
107389
|
// packages/workit-cli/src/test-audit/mutate.ts
|
|
107019
|
-
import { spawn as
|
|
107390
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
107020
107391
|
import {
|
|
107021
107392
|
existsSync as existsSync29,
|
|
107022
107393
|
lstatSync as lstatSync9,
|
|
@@ -107034,7 +107405,7 @@ import {
|
|
|
107034
107405
|
copyFileSync as copyFileSync8
|
|
107035
107406
|
} from "node:fs";
|
|
107036
107407
|
import os23 from "node:os";
|
|
107037
|
-
import
|
|
107408
|
+
import path73 from "node:path";
|
|
107038
107409
|
function mutantsFor(source, file, lines) {
|
|
107039
107410
|
const parsed = parseSource(source, file);
|
|
107040
107411
|
const out = [];
|
|
@@ -107107,7 +107478,7 @@ function relatedTests(source, testFiles) {
|
|
|
107107
107478
|
for (const match of text.matchAll(SPECIFIER)) {
|
|
107108
107479
|
const spec = match[1];
|
|
107109
107480
|
if (spec.startsWith(".")) {
|
|
107110
|
-
if (stripExt(
|
|
107481
|
+
if (stripExt(path73.posix.join(path73.posix.dirname(file), spec)) === target)
|
|
107111
107482
|
return true;
|
|
107112
107483
|
} else if (spec.includes("/") && stripExt(spec).split("/").slice(-2).join("/") === tail)
|
|
107113
107484
|
return true;
|
|
@@ -107127,12 +107498,12 @@ function removeStaleCopies(tmp = os23.tmpdir()) {
|
|
|
107127
107498
|
for (const name of names) {
|
|
107128
107499
|
if (!name.startsWith(TEMP_PREFIX))
|
|
107129
107500
|
continue;
|
|
107130
|
-
const dir =
|
|
107501
|
+
const dir = path73.join(tmp, name);
|
|
107131
107502
|
try {
|
|
107132
107503
|
const stat = lstatSync9(dir);
|
|
107133
107504
|
if (!stat.isDirectory() || uid !== undefined && stat.uid !== uid)
|
|
107134
107505
|
continue;
|
|
107135
|
-
const pid = Number(readFileSync30(
|
|
107506
|
+
const pid = Number(readFileSync30(path73.join(dir, PID_FILE), "utf8"));
|
|
107136
107507
|
if (Number.isInteger(pid) && pid > 0 && alive(pid))
|
|
107137
107508
|
continue;
|
|
107138
107509
|
} catch (error) {
|
|
@@ -107149,8 +107520,8 @@ function removeStaleCopies(tmp = os23.tmpdir()) {
|
|
|
107149
107520
|
function linkNodeModules(origin, target, repo, copy) {
|
|
107150
107521
|
mkdirSync12(target, { recursive: true });
|
|
107151
107522
|
for (const entry of readdirSync15(origin, { withFileTypes: true })) {
|
|
107152
|
-
const from =
|
|
107153
|
-
const to =
|
|
107523
|
+
const from = path73.join(origin, entry.name);
|
|
107524
|
+
const to = path73.join(target, entry.name);
|
|
107154
107525
|
if (entry.name.startsWith("@") && entry.isDirectory()) {
|
|
107155
107526
|
linkNodeModules(from, to, repo, copy);
|
|
107156
107527
|
continue;
|
|
@@ -107166,9 +107537,9 @@ function linkNodeModules(origin, target, repo, copy) {
|
|
|
107166
107537
|
} catch {
|
|
107167
107538
|
continue;
|
|
107168
107539
|
}
|
|
107169
|
-
const relative =
|
|
107170
|
-
if (!relative.startsWith("..") && !
|
|
107171
|
-
symlinkSync(
|
|
107540
|
+
const relative = path73.relative(repo, real);
|
|
107541
|
+
if (!relative.startsWith("..") && !path73.isAbsolute(relative) && !relative.split(path73.sep).includes("node_modules")) {
|
|
107542
|
+
symlinkSync(path73.join(copy, relative), to, "junction");
|
|
107172
107543
|
continue;
|
|
107173
107544
|
}
|
|
107174
107545
|
}
|
|
@@ -107184,7 +107555,7 @@ function copySymlink(repo, tree, from, to) {
|
|
|
107184
107555
|
}
|
|
107185
107556
|
const realRepo = realpathSync11(repo);
|
|
107186
107557
|
if (real && inside5(realRepo, real)) {
|
|
107187
|
-
symlinkSync(
|
|
107558
|
+
symlinkSync(path73.relative(path73.dirname(to), path73.join(tree, path73.relative(realRepo, real))), to);
|
|
107188
107559
|
return;
|
|
107189
107560
|
}
|
|
107190
107561
|
if (real && statSync11(real).isFile())
|
|
@@ -107193,10 +107564,10 @@ function copySymlink(repo, tree, from, to) {
|
|
|
107193
107564
|
symlinkSync(readlinkSync3(from), to);
|
|
107194
107565
|
}
|
|
107195
107566
|
function writeInside(copy, file, content) {
|
|
107196
|
-
const target =
|
|
107567
|
+
const target = path73.join(copy, file);
|
|
107197
107568
|
try {
|
|
107198
107569
|
const stat = lstatSync9(target);
|
|
107199
|
-
if (!stat.isFile() || !inside5(realpathSync11(copy), realpathSync11(
|
|
107570
|
+
if (!stat.isFile() || !inside5(realpathSync11(copy), realpathSync11(path73.dirname(target))))
|
|
107200
107571
|
return false;
|
|
107201
107572
|
} catch {
|
|
107202
107573
|
return false;
|
|
@@ -107207,9 +107578,9 @@ function writeInside(copy, file, content) {
|
|
|
107207
107578
|
return true;
|
|
107208
107579
|
}
|
|
107209
107580
|
function copyWorkingTree(repo) {
|
|
107210
|
-
const dir = mkdtempSync4(
|
|
107211
|
-
writeFileSync13(
|
|
107212
|
-
const tree =
|
|
107581
|
+
const dir = mkdtempSync4(path73.join(os23.tmpdir(), TEMP_PREFIX));
|
|
107582
|
+
writeFileSync13(path73.join(dir, PID_FILE), String(process.pid));
|
|
107583
|
+
const tree = path73.join(dir, "tree");
|
|
107213
107584
|
const head = git7(repo, ["rev-parse", "--verify", "--quiet", "HEAD"]).stdout.trim();
|
|
107214
107585
|
if (head && git7(dir, ["clone", "-q", "--shared", "--no-checkout", repo, tree]).ok) {
|
|
107215
107586
|
const branch = git7(repo, ["symbolic-ref", "--quiet", "--short", "HEAD"]).stdout.trim();
|
|
@@ -107226,36 +107597,36 @@ function copyWorkingTree(repo) {
|
|
|
107226
107597
|
for (const relative of listed) {
|
|
107227
107598
|
if (!relative)
|
|
107228
107599
|
continue;
|
|
107229
|
-
const from =
|
|
107600
|
+
const from = path73.join(repo, relative);
|
|
107230
107601
|
let stat;
|
|
107231
107602
|
try {
|
|
107232
107603
|
stat = lstatSync9(from);
|
|
107233
107604
|
} catch {
|
|
107234
107605
|
continue;
|
|
107235
107606
|
}
|
|
107236
|
-
const to =
|
|
107237
|
-
mkdirSync12(
|
|
107607
|
+
const to = path73.join(tree, relative);
|
|
107608
|
+
mkdirSync12(path73.dirname(to), { recursive: true });
|
|
107238
107609
|
if (stat.isSymbolicLink())
|
|
107239
107610
|
copySymlink(repo, tree, from, to);
|
|
107240
107611
|
else if (stat.isFile())
|
|
107241
107612
|
copyFileSync8(from, to);
|
|
107242
|
-
let parent =
|
|
107613
|
+
let parent = path73.dirname(relative);
|
|
107243
107614
|
while (parent !== "." && !dirs.has(parent)) {
|
|
107244
107615
|
dirs.add(parent);
|
|
107245
|
-
parent =
|
|
107616
|
+
parent = path73.dirname(parent);
|
|
107246
107617
|
}
|
|
107247
107618
|
}
|
|
107248
107619
|
for (const parent of dirs) {
|
|
107249
|
-
const modules =
|
|
107250
|
-
if (existsSync29(modules) && !existsSync29(
|
|
107251
|
-
linkNodeModules(modules,
|
|
107620
|
+
const modules = path73.join(repo, parent, "node_modules");
|
|
107621
|
+
if (existsSync29(modules) && !existsSync29(path73.join(tree, parent, "node_modules")))
|
|
107622
|
+
linkNodeModules(modules, path73.join(tree, parent, "node_modules"), repo, tree);
|
|
107252
107623
|
}
|
|
107253
107624
|
return { dir, tree };
|
|
107254
107625
|
}
|
|
107255
107626
|
function runCommand(command, cwd, timeoutMs, env) {
|
|
107256
107627
|
const started = performance.now();
|
|
107257
107628
|
return new Promise((resolve) => {
|
|
107258
|
-
const child =
|
|
107629
|
+
const child = spawn4(command, {
|
|
107259
107630
|
cwd,
|
|
107260
107631
|
env,
|
|
107261
107632
|
shell: true,
|
|
@@ -107287,14 +107658,14 @@ async function runMutation(options) {
|
|
|
107287
107658
|
const tracked = git7(repo, ["ls-files", "-co", "--exclude-standard", "-z"]).stdout.split("\x00").filter(Boolean);
|
|
107288
107659
|
const testFiles = tracked.filter((file) => TEST_FILE.test(file)).map((file) => {
|
|
107289
107660
|
try {
|
|
107290
|
-
return { file, text: readFileSync30(
|
|
107661
|
+
return { file, text: readFileSync30(path73.join(repo, file), "utf8") };
|
|
107291
107662
|
} catch {
|
|
107292
107663
|
return { file, text: "" };
|
|
107293
107664
|
}
|
|
107294
107665
|
});
|
|
107295
107666
|
const candidates = [];
|
|
107296
107667
|
for (const [absolute, lines] of [...options.changed].toSorted(([a], [b]) => a.localeCompare(b))) {
|
|
107297
|
-
const relative = toPosix(
|
|
107668
|
+
const relative = toPosix(path73.relative(repo, absolute));
|
|
107298
107669
|
if (!CODE_FILE.test(relative) || TEST_FILE.test(relative) || relative.endsWith(".d.ts"))
|
|
107299
107670
|
continue;
|
|
107300
107671
|
if (NOT_SOURCE.test(relative) || !existsSync29(absolute))
|
|
@@ -107308,9 +107679,9 @@ async function runMutation(options) {
|
|
|
107308
107679
|
for (const mutant of mutants)
|
|
107309
107680
|
if (!related.has(mutant.file))
|
|
107310
107681
|
related.set(mutant.file, relatedTests(mutant.file, testFiles));
|
|
107311
|
-
const cwdRelative =
|
|
107682
|
+
const cwdRelative = path73.relative(repo, options.cwd);
|
|
107312
107683
|
const asArg = (file) => {
|
|
107313
|
-
const relative = toPosix(
|
|
107684
|
+
const relative = toPosix(path73.relative(cwdRelative, file));
|
|
107314
107685
|
return shellQuote(relative.startsWith(".") ? relative : `./${relative}`);
|
|
107315
107686
|
};
|
|
107316
107687
|
const commandFor = (tests) => options.command.replaceAll("{files}", () => tests.map(asArg).join(" "));
|
|
@@ -107346,7 +107717,7 @@ async function runMutation(options) {
|
|
|
107346
107717
|
return finish3(options, 0, results, counts, started);
|
|
107347
107718
|
removeStaleCopies();
|
|
107348
107719
|
const { dir: copyDir, tree: copy } = copyWorkingTree(repo);
|
|
107349
|
-
const copyCwd =
|
|
107720
|
+
const copyCwd = path73.join(copy, cwdRelative);
|
|
107350
107721
|
let current = null;
|
|
107351
107722
|
const restore = () => {
|
|
107352
107723
|
if (current)
|
|
@@ -107381,7 +107752,7 @@ async function runMutation(options) {
|
|
|
107381
107752
|
record({ ...mutant, status: "skipped", durationMs: 0, tests, reason: "budget" });
|
|
107382
107753
|
continue;
|
|
107383
107754
|
}
|
|
107384
|
-
const original = readFileSync30(
|
|
107755
|
+
const original = readFileSync30(path73.join(copy, mutant.file), "utf8");
|
|
107385
107756
|
const mutated = original.slice(0, mutant.start) + mutant.replacement + original.slice(mutant.end);
|
|
107386
107757
|
current = { file: mutant.file, original };
|
|
107387
107758
|
if (!writeInside(copy, mutant.file, mutated)) {
|
|
@@ -107438,8 +107809,8 @@ var NOT_SOURCE, FLIPS, isStringy = (node) => node.type === "StringLiteral" || no
|
|
|
107438
107809
|
return error.code === "EPERM";
|
|
107439
107810
|
}
|
|
107440
107811
|
}, inside5 = (root, file) => {
|
|
107441
|
-
const relative =
|
|
107442
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
107812
|
+
const relative = path73.relative(root, file);
|
|
107813
|
+
return relative === "" || !relative.startsWith("..") && !path73.isAbsolute(relative);
|
|
107443
107814
|
}, active, killTree = (child) => {
|
|
107444
107815
|
try {
|
|
107445
107816
|
if (child.pid && process.platform !== "win32")
|
|
@@ -107488,7 +107859,7 @@ __export(exports_test_audit, {
|
|
|
107488
107859
|
run: () => run23
|
|
107489
107860
|
});
|
|
107490
107861
|
import { existsSync as existsSync30 } from "node:fs";
|
|
107491
|
-
import
|
|
107862
|
+
import path74 from "node:path";
|
|
107492
107863
|
function parse8(argv) {
|
|
107493
107864
|
const options = {
|
|
107494
107865
|
paths: [],
|
|
@@ -107593,8 +107964,8 @@ async function run23(argv, io) {
|
|
|
107593
107964
|
return emit(io, fail2("invalid_input", `${options}
|
|
107594
107965
|
usage: ${USAGE16}`));
|
|
107595
107966
|
const top = git7(io.cwd, ["rev-parse", "--show-toplevel"]);
|
|
107596
|
-
const repo = top.ok ?
|
|
107597
|
-
const display = (file) => toPosix(
|
|
107967
|
+
const repo = top.ok ? path74.resolve(top.stdout.trim()) : null;
|
|
107968
|
+
const display = (file) => toPosix(path74.relative(io.cwd, file) || file);
|
|
107598
107969
|
let base = null;
|
|
107599
107970
|
let changed = null;
|
|
107600
107971
|
if (options.diff || options.mutate) {
|
|
@@ -107733,7 +108104,7 @@ __export(exports_youtrack, {
|
|
|
107733
108104
|
run: () => run25
|
|
107734
108105
|
});
|
|
107735
108106
|
import { readFileSync as readFileSync31 } from "node:fs";
|
|
107736
|
-
import
|
|
108107
|
+
import path75 from "node:path";
|
|
107737
108108
|
async function run25(argv, io) {
|
|
107738
108109
|
const [sub, ...rest] = argv;
|
|
107739
108110
|
if (sub !== "note" && sub !== "time" && sub !== "meeting")
|
|
@@ -107779,7 +108150,7 @@ async function run25(argv, io) {
|
|
|
107779
108150
|
let markdown = flags.values.markdown ?? "";
|
|
107780
108151
|
if (flags.values.file)
|
|
107781
108152
|
try {
|
|
107782
|
-
markdown = readFileSync31(
|
|
108153
|
+
markdown = readFileSync31(path75.resolve(io.cwd, flags.values.file), "utf8");
|
|
107783
108154
|
} catch (error) {
|
|
107784
108155
|
return usage4(io, `cannot read ${flags.values.file}: ${String(error)}`, USAGE18);
|
|
107785
108156
|
}
|
|
@@ -107848,7 +108219,7 @@ __export(exports_changelog, {
|
|
|
107848
108219
|
run: () => run26
|
|
107849
108220
|
});
|
|
107850
108221
|
import { readFileSync as readFileSync32 } from "node:fs";
|
|
107851
|
-
import
|
|
108222
|
+
import path76 from "node:path";
|
|
107852
108223
|
async function run26(argv, io) {
|
|
107853
108224
|
const [sub, ...rest] = argv;
|
|
107854
108225
|
if (sub !== "apply")
|
|
@@ -107894,7 +108265,7 @@ async function run26(argv, io) {
|
|
|
107894
108265
|
]);
|
|
107895
108266
|
}
|
|
107896
108267
|
var USAGE19 = "workit changelog apply (--entries <JSON|@file|-> | --normalize-only) [--path CHANGELOG.md] [--preview]", readEntries = (raw, cwd) => {
|
|
107897
|
-
const text = raw === "-" ? readFileSync32(0, "utf8") : raw.startsWith("@") ? readFileSync32(
|
|
108268
|
+
const text = raw === "-" ? readFileSync32(0, "utf8") : raw.startsWith("@") ? readFileSync32(path76.resolve(cwd, raw.slice(1)), "utf8") : raw;
|
|
107898
108269
|
return JSON.parse(text);
|
|
107899
108270
|
};
|
|
107900
108271
|
var init_changelog2 = __esm(() => {
|
|
@@ -107910,7 +108281,7 @@ __export(exports_handoff, {
|
|
|
107910
108281
|
run: () => run27
|
|
107911
108282
|
});
|
|
107912
108283
|
import fs37 from "node:fs";
|
|
107913
|
-
import
|
|
108284
|
+
import path77 from "node:path";
|
|
107914
108285
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
107915
108286
|
function render3(brief) {
|
|
107916
108287
|
const lines = [
|
|
@@ -107950,9 +108321,9 @@ function bounded(brief, cwd) {
|
|
|
107950
108321
|
let file = null;
|
|
107951
108322
|
if (store.ok)
|
|
107952
108323
|
try {
|
|
107953
|
-
const dir =
|
|
108324
|
+
const dir = path77.join(store.value.root, "handoff");
|
|
107954
108325
|
fs37.mkdirSync(dir, { recursive: true });
|
|
107955
|
-
file =
|
|
108326
|
+
file = path77.join(dir, `${(brief.branch ?? "detached").replaceAll(/[^\w.-]+/gu, "-")}.txt`);
|
|
107956
108327
|
fs37.writeFileSync(file, `${[...body, ...tail].join(`
|
|
107957
108328
|
`)}
|
|
107958
108329
|
`, {
|
|
@@ -108027,7 +108398,7 @@ var init_handoff = __esm(() => {
|
|
|
108027
108398
|
});
|
|
108028
108399
|
|
|
108029
108400
|
// packages/workit-cli/src/main.ts
|
|
108030
|
-
import
|
|
108401
|
+
import path78 from "node:path";
|
|
108031
108402
|
|
|
108032
108403
|
// packages/workit-core/src/git/env-redirect.ts
|
|
108033
108404
|
var GIT_REDIRECT_ENV = [
|
|
@@ -108976,7 +109347,7 @@ var defaultIo = (json) => ({
|
|
|
108976
109347
|
});
|
|
108977
109348
|
async function main(argv, overrides = {}, options = {}) {
|
|
108978
109349
|
const parsed = parseGlobals(argv);
|
|
108979
|
-
const cwd =
|
|
109350
|
+
const cwd = path78.resolve(overrides.cwd ?? process.cwd(), parsed.cwd ?? ".");
|
|
108980
109351
|
const io = { ...defaultIo(parsed.json), ...overrides, json: parsed.json, cwd };
|
|
108981
109352
|
if (parsed.error)
|
|
108982
109353
|
return emit(io, fail2("invalid_input", parsed.error));
|