@brainervirus/workit-claude-code 8.44.0 → 8.44.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/.claude-plugin/plugin.json +1 -1
- package/dist/workit.js +569 -336
- package/package.json +3 -3
package/dist/workit.js
CHANGED
|
@@ -9431,7 +9431,7 @@ var package_default;
|
|
|
9431
9431
|
var init_package = __esm(() => {
|
|
9432
9432
|
package_default = {
|
|
9433
9433
|
name: "@brainervirus/workit-cli",
|
|
9434
|
-
version: "8.44.
|
|
9434
|
+
version: "8.44.1",
|
|
9435
9435
|
private: false,
|
|
9436
9436
|
description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
9437
9437
|
keywords: [
|
|
@@ -9469,13 +9469,13 @@ var init_package = __esm(() => {
|
|
|
9469
9469
|
},
|
|
9470
9470
|
dependencies: {
|
|
9471
9471
|
"@babel/parser": "7.29.9",
|
|
9472
|
-
"@brainervirus/workit-cursor": "^8.44.
|
|
9472
|
+
"@brainervirus/workit-cursor": "^8.44.1",
|
|
9473
9473
|
"@inkjs/ui": "2.0.0",
|
|
9474
9474
|
ink: "7.1.1",
|
|
9475
9475
|
react: "19.2.8"
|
|
9476
9476
|
},
|
|
9477
9477
|
devDependencies: {
|
|
9478
|
-
"@brainervirus/workit-core": "^8.44.
|
|
9478
|
+
"@brainervirus/workit-core": "^8.44.1"
|
|
9479
9479
|
},
|
|
9480
9480
|
engines: {
|
|
9481
9481
|
node: ">=24"
|
|
@@ -68214,7 +68214,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68214
68214
|
found.push({ pid: Number(m[1]), startedMs, args: m[3] });
|
|
68215
68215
|
}
|
|
68216
68216
|
return found;
|
|
68217
|
-
}, 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) => {
|
|
68217
|
+
}, PS_START_SLACK_MS = 2000, startedBefore = (proc, installedMs) => proc.startedMs + PS_START_SLACK_MS < installedMs, 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) => {
|
|
68218
68218
|
const env = options.env ?? process.env;
|
|
68219
68219
|
const home = options.home ?? env.HOME ?? os13.homedir();
|
|
68220
68220
|
const configDir = options.configDir ?? env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path40.join(home, ".config", "workit");
|
|
@@ -68230,7 +68230,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68230
68230
|
cwd,
|
|
68231
68231
|
workspaceRoot: options.workspaceRoot ?? env.WORKFLOW_WORKSPACE_ROOT ?? cwd,
|
|
68232
68232
|
dev,
|
|
68233
|
-
opencodeConfig: options.opencodeConfig ?? path40.join(home, ".config", "opencode", "opencode.json"),
|
|
68233
|
+
opencodeConfig: options.opencodeConfig ?? path40.join(env.XDG_CONFIG_HOME || path40.join(home, ".config"), "opencode", "opencode.json"),
|
|
68234
68234
|
opencodePackageCacheDir: options.opencodePackageCacheDir ?? null,
|
|
68235
68235
|
cursorSettings: options.cursorSettings ?? path40.join(home, ".cursor", "settings.json"),
|
|
68236
68236
|
cursorMcp: options.cursorMcp ?? path40.join(home, ".cursor", "mcp.json"),
|
|
@@ -69369,9 +69369,25 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69369
69369
|
detail: `OpenCode @latest cache workit-opencode ${installed} matches published ${expected}`
|
|
69370
69370
|
};
|
|
69371
69371
|
}, checkStaleInstall = (res) => {
|
|
69372
|
-
if (res.host === "opencode")
|
|
69372
|
+
if (res.host === "opencode")
|
|
69373
69373
|
return checkOpenCodePackageCache(res);
|
|
69374
|
-
|
|
69374
|
+
const cursor = checkCursorStaleInstall(res);
|
|
69375
|
+
if (res.host !== "cli")
|
|
69376
|
+
return cursor;
|
|
69377
|
+
const oc = checkOpenCodePackageCache(res);
|
|
69378
|
+
if (oc.status === "pass")
|
|
69379
|
+
return cursor;
|
|
69380
|
+
if (cursor.status === "pass")
|
|
69381
|
+
return oc;
|
|
69382
|
+
if (oc.id !== "stale_install")
|
|
69383
|
+
return cursor;
|
|
69384
|
+
return {
|
|
69385
|
+
...cursor,
|
|
69386
|
+
registryProbed: Boolean(cursor.registryProbed || oc.registryProbed),
|
|
69387
|
+
detail: `${cursor.detail}; ${oc.detail}`,
|
|
69388
|
+
fix: [cursor.fix, oc.fix].filter(Boolean).join("; ")
|
|
69389
|
+
};
|
|
69390
|
+
}, checkCursorStaleInstall = (res) => {
|
|
69375
69391
|
if (res.host !== "cursor" && res.host !== "cli") {
|
|
69376
69392
|
return {
|
|
69377
69393
|
id: "stale_install",
|
|
@@ -69479,11 +69495,6 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69479
69495
|
registryProbed: true,
|
|
69480
69496
|
detail: `installed local-dist workit-cursor ${installed} matches the published runtime ${expected}`
|
|
69481
69497
|
};
|
|
69482
|
-
if (res.host === "cli") {
|
|
69483
|
-
const oc = checkOpenCodePackageCache(res);
|
|
69484
|
-
if (oc.status !== "pass")
|
|
69485
|
-
return oc;
|
|
69486
|
-
}
|
|
69487
69498
|
return cursorOk;
|
|
69488
69499
|
}
|
|
69489
69500
|
const cursorOk = {
|
|
@@ -69491,11 +69502,6 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69491
69502
|
status: "pass",
|
|
69492
69503
|
detail: installed === null ? "installed workit-cursor selectors are canonical" : `installed workit-cursor ${installed} on canonical selectors (hooks run this version through the pinned launcher; MCP resolves @latest at launch)`
|
|
69493
69504
|
};
|
|
69494
|
-
if (res.host === "cli") {
|
|
69495
|
-
const oc = checkOpenCodePackageCache(res);
|
|
69496
|
-
if (oc.status !== "pass")
|
|
69497
|
-
return oc;
|
|
69498
|
-
}
|
|
69499
69505
|
return cursorOk;
|
|
69500
69506
|
}, checkDuplicateRegistration = (res) => {
|
|
69501
69507
|
const problems = [];
|
|
@@ -70223,7 +70229,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
70223
70229
|
status: "info",
|
|
70224
70230
|
detail: "could not list running claude processes (ps) — skipping"
|
|
70225
70231
|
};
|
|
70226
|
-
const stale = running.filter((proc) => proc
|
|
70232
|
+
const stale = running.filter((proc) => startedBefore(proc, latest.at));
|
|
70227
70233
|
if (stale.length === 0)
|
|
70228
70234
|
return {
|
|
70229
70235
|
id,
|
|
@@ -70271,7 +70277,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
70271
70277
|
status: "info",
|
|
70272
70278
|
detail: "could not list running codex processes (ps) — skipping"
|
|
70273
70279
|
};
|
|
70274
|
-
const stale = running.filter((proc) => proc
|
|
70280
|
+
const stale = running.filter((proc) => startedBefore(proc, latest.at));
|
|
70275
70281
|
if (stale.length === 0)
|
|
70276
70282
|
return {
|
|
70277
70283
|
id,
|
|
@@ -75828,7 +75834,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75828
75834
|
}
|
|
75829
75835
|
const result = runHostCommand(step, { home, env });
|
|
75830
75836
|
return { status: result.exitCode, stdout: result.stdout, stderr: result.stderr };
|
|
75831
|
-
}), COMMAND_TIMEOUT_MS = 60000, asyncRunner = (deps) => {
|
|
75837
|
+
}), COMMAND_TIMEOUT_MS = 60000, asyncRunner = (deps, timeoutMs = COMMAND_TIMEOUT_MS) => {
|
|
75832
75838
|
if (deps.runAsync)
|
|
75833
75839
|
return deps.runAsync;
|
|
75834
75840
|
const injected = deps.run;
|
|
@@ -75880,7 +75886,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75880
75886
|
const timer = setTimeout(() => {
|
|
75881
75887
|
child.kill("SIGKILL");
|
|
75882
75888
|
finish(1);
|
|
75883
|
-
},
|
|
75889
|
+
}, timeoutMs);
|
|
75884
75890
|
child.stdout?.setEncoding("utf8");
|
|
75885
75891
|
child.stdout?.on("data", (chunk) => stdout += chunk);
|
|
75886
75892
|
child.stderr?.setEncoding("utf8");
|
|
@@ -75982,7 +75988,7 @@ var init_processes = __esm(() => {
|
|
|
75982
75988
|
import { existsSync as existsSync22, readdirSync as readdirSync12, mkdirSync as mkdirSync12, copyFileSync as copyFileSync6, chmodSync as chmodSync2, cpSync as cpSync5 } from "node:fs";
|
|
75983
75989
|
import path48 from "node:path";
|
|
75984
75990
|
import { createHash as createHash16 } from "node:crypto";
|
|
75985
|
-
async function applyUpgrade(plan, deps = {}) {
|
|
75991
|
+
async function applyUpgrade(plan, deps = {}, options = {}) {
|
|
75986
75992
|
const hosts = [...plan.failed];
|
|
75987
75993
|
const done = (backup) => {
|
|
75988
75994
|
const failures = hosts.filter((entry) => entry.status === "failed");
|
|
@@ -76039,6 +76045,26 @@ async function applyUpgrade(plan, deps = {}) {
|
|
|
76039
76045
|
const runAsync = asyncRunner(deps);
|
|
76040
76046
|
const progress = deps.progress ?? createProgress({ json: true });
|
|
76041
76047
|
const statusOf = (outcome) => outcome?.status === "failed" ? "failed" : outcome?.status === "updated" ? "done" : "skipped";
|
|
76048
|
+
if (plan.cli) {
|
|
76049
|
+
let cli;
|
|
76050
|
+
try {
|
|
76051
|
+
cli = await progress.run("Updating the CLI", () => applyCli(plan.cli, runAsync, backup), statusOf, { signals: true });
|
|
76052
|
+
} catch (error) {
|
|
76053
|
+
cli = { host: "cli", status: "failed", reason: errorText(error), fix: CLI_FIX };
|
|
76054
|
+
}
|
|
76055
|
+
if (cli.status === "updated" && options.handoff) {
|
|
76056
|
+
const code = await options.handoff(cli);
|
|
76057
|
+
if (code !== undefined)
|
|
76058
|
+
return { ...done(backup), hosts: [...hosts, cli], handedOff: code };
|
|
76059
|
+
if (plan.entries.length)
|
|
76060
|
+
cli = {
|
|
76061
|
+
...cli,
|
|
76062
|
+
reason: `${cli.reason}; the new CLI could not be started, hosts upgraded with workit ${package_default.version}`
|
|
76063
|
+
};
|
|
76064
|
+
} else if (cli.status === "failed" && plan.entries.length)
|
|
76065
|
+
cli = { ...cli, reason: `${cli.reason}; hosts upgraded with workit ${package_default.version}` };
|
|
76066
|
+
hosts.push(cli);
|
|
76067
|
+
}
|
|
76042
76068
|
let cursorBackupError = null;
|
|
76043
76069
|
if (plan.entries.some((entry) => entry.host === "cursor") && existsSync22(paths.cursorRoot))
|
|
76044
76070
|
try {
|
|
@@ -76173,17 +76199,6 @@ async function applyUpgrade(plan, deps = {}) {
|
|
|
76173
76199
|
reason: `${hosts[index].reason}; ${agents.note}`
|
|
76174
76200
|
};
|
|
76175
76201
|
}
|
|
76176
|
-
if (plan.cli)
|
|
76177
|
-
try {
|
|
76178
|
-
hosts.push(await progress.run("Updating the CLI", () => applyCli(plan.cli, runAsync, backup), statusOf, { signals: true }));
|
|
76179
|
-
} catch (error) {
|
|
76180
|
-
hosts.push({
|
|
76181
|
-
host: "cli",
|
|
76182
|
-
status: "failed",
|
|
76183
|
-
reason: errorText(error),
|
|
76184
|
-
fix: CLI_FIX
|
|
76185
|
-
});
|
|
76186
|
-
}
|
|
76187
76202
|
return done(backup);
|
|
76188
76203
|
}
|
|
76189
76204
|
var briefDetail = (detail) => {
|
|
@@ -76213,6 +76228,31 @@ var briefDetail = (detail) => {
|
|
|
76213
76228
|
return version;
|
|
76214
76229
|
}
|
|
76215
76230
|
return;
|
|
76231
|
+
}, opencodeOutcome = async (before, target, runAsync) => {
|
|
76232
|
+
const below = (version) => target !== undefined && (version === undefined || !versionAtLeast(version, target));
|
|
76233
|
+
let after = await opencodeVersion(runAsync);
|
|
76234
|
+
if (below(after))
|
|
76235
|
+
after = await opencodeVersion(runAsync) ?? after;
|
|
76236
|
+
const live = "OpenCode V2 loads it live";
|
|
76237
|
+
if (before && target && versionAtLeast(before, target))
|
|
76238
|
+
return { host: "opencode", status: "current", reason: `already current (${before})` };
|
|
76239
|
+
if (after && below(after))
|
|
76240
|
+
return {
|
|
76241
|
+
host: "opencode",
|
|
76242
|
+
status: "updated",
|
|
76243
|
+
reason: `update ran, but OpenCode still lists ${after} (published ${target}); the doctor below checks its package cache`
|
|
76244
|
+
};
|
|
76245
|
+
if (before && after && after !== before)
|
|
76246
|
+
return { host: "opencode", status: "updated", reason: `${before} -> ${after}; ${live}` };
|
|
76247
|
+
if (before && after)
|
|
76248
|
+
return {
|
|
76249
|
+
host: "opencode",
|
|
76250
|
+
status: "current",
|
|
76251
|
+
reason: `unchanged (${after}); the published version could not be read`
|
|
76252
|
+
};
|
|
76253
|
+
if (after)
|
|
76254
|
+
return { host: "opencode", status: "updated", reason: `now ${after}; ${live}` };
|
|
76255
|
+
return { host: "opencode", status: "updated", reason: `scoped update ran; ${live}` };
|
|
76216
76256
|
}, applyEntry = async (entry, context) => {
|
|
76217
76257
|
const { runAsync, paths, configDir } = context;
|
|
76218
76258
|
const { home, env } = paths;
|
|
@@ -76297,24 +76337,8 @@ ${result.stderr}`;
|
|
|
76297
76337
|
if (result.status !== 0)
|
|
76298
76338
|
return fail(failureReason(command, result));
|
|
76299
76339
|
}
|
|
76300
|
-
if (entry.host === "opencode")
|
|
76301
|
-
|
|
76302
|
-
if (before && after)
|
|
76303
|
-
return after === before ? {
|
|
76304
|
-
host: "opencode",
|
|
76305
|
-
status: "current",
|
|
76306
|
-
reason: `already current (${after})`
|
|
76307
|
-
} : {
|
|
76308
|
-
host: "opencode",
|
|
76309
|
-
status: "updated",
|
|
76310
|
-
reason: `${before} -> ${after}; OpenCode V2 loads it live`
|
|
76311
|
-
};
|
|
76312
|
-
return {
|
|
76313
|
-
host: "opencode",
|
|
76314
|
-
status: "updated",
|
|
76315
|
-
reason: "scoped update ran; OpenCode V2 loads it live"
|
|
76316
|
-
};
|
|
76317
|
-
}
|
|
76340
|
+
if (entry.host === "opencode")
|
|
76341
|
+
return opencodeOutcome(before, entry.published, runAsync);
|
|
76318
76342
|
if (entry.host === "claude-code") {
|
|
76319
76343
|
const after = claudeWorkitInstalls(home, env, null).find((install) => install.id === entry.selector)?.version;
|
|
76320
76344
|
return after && after === entry.installedVersion ? {
|
|
@@ -76388,6 +76412,7 @@ ${result.stderr}`;
|
|
|
76388
76412
|
};
|
|
76389
76413
|
};
|
|
76390
76414
|
var init_apply = __esm(() => {
|
|
76415
|
+
init_package();
|
|
76391
76416
|
init_host_install();
|
|
76392
76417
|
init_setup_state();
|
|
76393
76418
|
init_setup();
|
|
@@ -76558,14 +76583,86 @@ var init_update_check = __esm(() => {
|
|
|
76558
76583
|
]);
|
|
76559
76584
|
});
|
|
76560
76585
|
|
|
76561
|
-
// packages/workit-cli/src/upgrade/
|
|
76562
|
-
import { existsSync as existsSync23, mkdtempSync as mkdtempSync3, rmSync as rmSync8
|
|
76563
|
-
import path50 from "node:path";
|
|
76586
|
+
// packages/workit-cli/src/upgrade/probes.ts
|
|
76587
|
+
import { existsSync as existsSync23, mkdtempSync as mkdtempSync3, rmSync as rmSync8 } from "node:fs";
|
|
76564
76588
|
import os18 from "node:os";
|
|
76565
|
-
|
|
76589
|
+
import path50 from "node:path";
|
|
76590
|
+
var PROBE_TIMEOUT_MS = 20000, probeKey = (command, args) => [command, ...args].join(" "), opencodeScratchEnv = (deps, scratch) => ({
|
|
76591
|
+
...deps.env,
|
|
76592
|
+
XDG_DATA_HOME: path50.join(scratch, "data"),
|
|
76593
|
+
XDG_STATE_HOME: path50.join(scratch, "state"),
|
|
76594
|
+
XDG_CACHE_HOME: path50.join(scratch, "cache")
|
|
76595
|
+
}), registry2 = (name) => ["npm", ["view", name, "version"]], runProbes = async (hosts, cli, deps) => {
|
|
76596
|
+
const paths = upgradePaths(deps);
|
|
76597
|
+
const timeoutMs = deps.probeTimeoutMs ?? PROBE_TIMEOUT_MS;
|
|
76598
|
+
const run = asyncRunner(deps, timeoutMs);
|
|
76599
|
+
const probes = [];
|
|
76600
|
+
const add = (command, args, runner = run) => probes.push([command, args, runner]);
|
|
76601
|
+
const scratch = mkdtempSync3(path50.join(os18.tmpdir(), "workit-upgrade-opencode-"));
|
|
76602
|
+
try {
|
|
76603
|
+
if (hosts.includes("opencode") && existsSync23(paths.opencodeConfig)) {
|
|
76604
|
+
const opencode = asyncRunner({ ...deps, env: opencodeScratchEnv(deps, scratch) }, timeoutMs);
|
|
76605
|
+
add("opencode", ["--version"], opencode);
|
|
76606
|
+
add("opencode", ["plugin", "--help"], opencode);
|
|
76607
|
+
add(...registry2(OPENCODE_PACKAGE));
|
|
76608
|
+
}
|
|
76609
|
+
if (hosts.includes("cursor"))
|
|
76610
|
+
add(...registry2("@brainervirus/workit-cursor"));
|
|
76611
|
+
if (hosts.includes("codex")) {
|
|
76612
|
+
add("codex", ["plugin", "list", "--json"]);
|
|
76613
|
+
add(...registry2("@brainervirus/workit-codex"));
|
|
76614
|
+
}
|
|
76615
|
+
if (hosts.includes("pi")) {
|
|
76616
|
+
if (existsSync23(paths.piSettings))
|
|
76617
|
+
add("pi", ["list"]);
|
|
76618
|
+
add(...registry2("@brainervirus/workit-pi"));
|
|
76619
|
+
}
|
|
76620
|
+
if (cli) {
|
|
76621
|
+
add("npm", ["root", "--global"]);
|
|
76622
|
+
add(...registry2(CLI_PACKAGE2));
|
|
76623
|
+
}
|
|
76624
|
+
const results = await Promise.all(probes.map(async ([command, args, runner]) => {
|
|
76625
|
+
let timer;
|
|
76626
|
+
const timedOut = new Promise((resolve) => {
|
|
76627
|
+
timer = setTimeout(() => resolve({
|
|
76628
|
+
status: null,
|
|
76629
|
+
stdout: "",
|
|
76630
|
+
stderr: `\`${probeKey(command, args)}\` timed out after ${Math.round(timeoutMs / 1000)} s`,
|
|
76631
|
+
timedOut: true
|
|
76632
|
+
}), timeoutMs);
|
|
76633
|
+
});
|
|
76634
|
+
try {
|
|
76635
|
+
const result = await Promise.race([
|
|
76636
|
+
runner(command, args).catch((error) => ({
|
|
76637
|
+
status: 1,
|
|
76638
|
+
stdout: "",
|
|
76639
|
+
stderr: error instanceof Error ? error.message : String(error)
|
|
76640
|
+
})),
|
|
76641
|
+
timedOut
|
|
76642
|
+
]);
|
|
76643
|
+
return [probeKey(command, args), result];
|
|
76644
|
+
} finally {
|
|
76645
|
+
clearTimeout(timer);
|
|
76646
|
+
}
|
|
76647
|
+
}));
|
|
76648
|
+
return new Map(results);
|
|
76649
|
+
} finally {
|
|
76650
|
+
rmSync8(scratch, { recursive: true, force: true });
|
|
76651
|
+
}
|
|
76652
|
+
};
|
|
76653
|
+
var init_probes = __esm(() => {
|
|
76654
|
+
init_update_check();
|
|
76655
|
+
init_shared();
|
|
76656
|
+
});
|
|
76657
|
+
|
|
76658
|
+
// packages/workit-cli/src/upgrade/plan.ts
|
|
76659
|
+
import { existsSync as existsSync24, mkdtempSync as mkdtempSync4, rmSync as rmSync9, lstatSync as lstatSync8, readFileSync as readFileSync25 } from "node:fs";
|
|
76660
|
+
import path51 from "node:path";
|
|
76661
|
+
import os19 from "node:os";
|
|
76662
|
+
function previewUpgrade(hosts = HOSTS2, deps = {}, probes) {
|
|
76566
76663
|
const paths = upgradePaths(deps);
|
|
76567
76664
|
const { home, configDir } = paths;
|
|
76568
|
-
const run =
|
|
76665
|
+
const run = probedRunner(deps, probes);
|
|
76569
76666
|
const state = readSetupState(configDir);
|
|
76570
76667
|
const plan = {
|
|
76571
76668
|
ok: true,
|
|
@@ -76584,9 +76681,9 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
|
76584
76681
|
for (const file of [
|
|
76585
76682
|
paths.opencodeConfig,
|
|
76586
76683
|
paths.opencodeConfig + "c",
|
|
76587
|
-
|
|
76588
|
-
|
|
76589
|
-
|
|
76684
|
+
path51.join(home, ".cursor/settings.json"),
|
|
76685
|
+
path51.join(home, ".cursor/mcp.json"),
|
|
76686
|
+
path51.join(paths.cursorRoot, "package.json"),
|
|
76590
76687
|
paths.codexConfig,
|
|
76591
76688
|
paths.piSettings
|
|
76592
76689
|
])
|
|
@@ -76605,7 +76702,7 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
|
76605
76702
|
const installedSources = sources(paths, run, hosts, plan.failed);
|
|
76606
76703
|
let opencodeHelp;
|
|
76607
76704
|
if (installedSources.some((source) => source.host === "opencode")) {
|
|
76608
|
-
const probe = opencodeProbe(deps, ["--version"]);
|
|
76705
|
+
const probe = opencodeProbe(deps, ["--version"], probes);
|
|
76609
76706
|
const installed = probe.status === 0 ? probe.stdout.match(/\d+\.\d+\.\d+/)?.[0] : undefined;
|
|
76610
76707
|
if (installed && !versionAtLeast(installed, SUPPORT_MATRIX.opencode.minimum))
|
|
76611
76708
|
(plan.warnings ??= []).push(`opencode ${installed}: ${OPENCODE_V1_FIX}`);
|
|
@@ -76646,7 +76743,17 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
|
76646
76743
|
continue;
|
|
76647
76744
|
}
|
|
76648
76745
|
if (source.host === "opencode") {
|
|
76649
|
-
|
|
76746
|
+
const help = opencodeProbe(deps, ["plugin", "--help"], probes);
|
|
76747
|
+
if (help.timedOut) {
|
|
76748
|
+
plan.failed.push({
|
|
76749
|
+
host: "opencode",
|
|
76750
|
+
status: "failed",
|
|
76751
|
+
reason: `could not check: ${help.stderr}`,
|
|
76752
|
+
fix: OPENCODE_UPDATE
|
|
76753
|
+
});
|
|
76754
|
+
continue;
|
|
76755
|
+
}
|
|
76756
|
+
opencodeHelp ??= help.stdout;
|
|
76650
76757
|
if (!/^\s*(?:opencode\s+plugin\s+)?update\b/m.test(opencodeHelp)) {
|
|
76651
76758
|
plan.skipped.push({
|
|
76652
76759
|
host: "opencode",
|
|
@@ -76655,10 +76762,12 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
|
76655
76762
|
});
|
|
76656
76763
|
continue;
|
|
76657
76764
|
}
|
|
76765
|
+
const published = registryVersion(run, OPENCODE_PACKAGE);
|
|
76658
76766
|
plan.entries.push({
|
|
76659
76767
|
host: "opencode",
|
|
76660
76768
|
selector: source.selector,
|
|
76661
76769
|
latest: "",
|
|
76770
|
+
...published ? { published } : {},
|
|
76662
76771
|
commands: [{ command: "opencode", args: ["plugin", "update", OPENCODE_PACKAGE] }],
|
|
76663
76772
|
fix: OPENCODE_UPDATE
|
|
76664
76773
|
});
|
|
@@ -76746,7 +76855,7 @@ var codexRegistered = (configFile) => {
|
|
|
76746
76855
|
}
|
|
76747
76856
|
};
|
|
76748
76857
|
guard("opencode", () => {
|
|
76749
|
-
if (
|
|
76858
|
+
if (existsSync24(paths.opencodeConfig + "c"))
|
|
76750
76859
|
throw new Error("OpenCode JSONC config is present; inspect effective native configuration before updating");
|
|
76751
76860
|
const oc = object2(paths.opencodeConfig);
|
|
76752
76861
|
if (oc && [oc.plugins, oc.plugin].some((value) => value !== undefined && !Array.isArray(value)))
|
|
@@ -76756,8 +76865,8 @@ var codexRegistered = (configFile) => {
|
|
|
76756
76865
|
result.push(classify("opencode", pin));
|
|
76757
76866
|
});
|
|
76758
76867
|
guard("cursor", () => {
|
|
76759
|
-
const cursor = objectOrNull(
|
|
76760
|
-
const mcp = objectOrNull(
|
|
76868
|
+
const cursor = objectOrNull(path51.join(paths.cursorRoot, "package.json"));
|
|
76869
|
+
const mcp = objectOrNull(path51.join(home, ".cursor/mcp.json"));
|
|
76761
76870
|
const args = mcp?.mcpServers?.workit?.args ?? [];
|
|
76762
76871
|
const arg = args.find((value) => typeof value === "string" && value.startsWith("--package="));
|
|
76763
76872
|
const selector = typeof arg === "string" ? arg.slice(10) : "local";
|
|
@@ -76768,7 +76877,7 @@ var codexRegistered = (configFile) => {
|
|
|
76768
76877
|
});
|
|
76769
76878
|
return;
|
|
76770
76879
|
}
|
|
76771
|
-
const settings = objectOrNull(
|
|
76880
|
+
const settings = objectOrNull(path51.join(home, ".cursor/settings.json"));
|
|
76772
76881
|
const dirs = Array.isArray(settings?.plugin_dirs) ? settings.plugin_dirs : [];
|
|
76773
76882
|
const registered = mcp?.mcpServers?.workit !== undefined || dirs.some((dir) => String(dir).replaceAll("\\", "/").replace(/\/+$/, "").endsWith("local/workit"));
|
|
76774
76883
|
if (registered)
|
|
@@ -76783,12 +76892,14 @@ var codexRegistered = (configFile) => {
|
|
|
76783
76892
|
if (typeof source !== "string")
|
|
76784
76893
|
continue;
|
|
76785
76894
|
const npm = /^(?:npm:)?@brainervirus\/workit-pi(?:@[^/]+)?$/.test(source);
|
|
76786
|
-
const local =
|
|
76895
|
+
const local = path51.isAbsolute(source) && source.replaceAll("\\", "/").endsWith("/packages/workit-pi") && object2(path51.join(source, "package.json"))?.name === "@brainervirus/workit-pi";
|
|
76787
76896
|
if (!npm && !local)
|
|
76788
76897
|
continue;
|
|
76789
76898
|
const found = classify("pi", source);
|
|
76790
76899
|
if (found.kind === "floating") {
|
|
76791
76900
|
const inventory = run("pi", ["list"]);
|
|
76901
|
+
if (inventory.timedOut)
|
|
76902
|
+
throw new Error(`could not check: ${inventory.stderr}`);
|
|
76792
76903
|
if (inventory.status === 0)
|
|
76793
76904
|
found.installedVersion = piInstalledVersion(inventory.stdout, source);
|
|
76794
76905
|
}
|
|
@@ -76797,13 +76908,15 @@ var codexRegistered = (configFile) => {
|
|
|
76797
76908
|
});
|
|
76798
76909
|
guard("codex", () => {
|
|
76799
76910
|
const listing = run("codex", ["plugin", "list", "--json"]);
|
|
76911
|
+
if (listing.timedOut)
|
|
76912
|
+
throw new Error(`could not check: ${listing.stderr}`);
|
|
76800
76913
|
if (listing.status !== 0) {
|
|
76801
76914
|
let available = false;
|
|
76802
76915
|
try {
|
|
76803
76916
|
hostCommand("codex", [], { home, env: paths.env });
|
|
76804
76917
|
available = true;
|
|
76805
76918
|
} catch {}
|
|
76806
|
-
if (available ||
|
|
76919
|
+
if (available || existsSync24(paths.codexConfig))
|
|
76807
76920
|
throw new Error("Codex plugin inventory failed; inspect the native host before upgrading");
|
|
76808
76921
|
return;
|
|
76809
76922
|
}
|
|
@@ -76842,24 +76955,22 @@ var codexRegistered = (configFile) => {
|
|
|
76842
76955
|
});
|
|
76843
76956
|
});
|
|
76844
76957
|
return result;
|
|
76845
|
-
}, opencodeProbe = (deps, args) => {
|
|
76846
|
-
const
|
|
76958
|
+
}, opencodeProbe = (deps, args, probes) => {
|
|
76959
|
+
const cached = probes?.get(probeKey("opencode", args));
|
|
76960
|
+
if (cached)
|
|
76961
|
+
return cached;
|
|
76962
|
+
const scratch = mkdtempSync4(path51.join(os19.tmpdir(), "workit-upgrade-opencode-"));
|
|
76847
76963
|
try {
|
|
76848
|
-
return runner({
|
|
76849
|
-
...deps,
|
|
76850
|
-
env: {
|
|
76851
|
-
...deps.env,
|
|
76852
|
-
XDG_DATA_HOME: path50.join(scratch, "data"),
|
|
76853
|
-
XDG_STATE_HOME: path50.join(scratch, "state"),
|
|
76854
|
-
XDG_CACHE_HOME: path50.join(scratch, "cache")
|
|
76855
|
-
}
|
|
76856
|
-
})("opencode", args);
|
|
76964
|
+
return runner({ ...deps, env: opencodeScratchEnv(deps, scratch) })("opencode", args);
|
|
76857
76965
|
} finally {
|
|
76858
|
-
|
|
76966
|
+
rmSync9(scratch, { recursive: true, force: true });
|
|
76859
76967
|
}
|
|
76968
|
+
}, probedRunner = (deps, probes) => {
|
|
76969
|
+
const run = runner(deps);
|
|
76970
|
+
return probes ? (command, args) => probes.get(probeKey(command, args)) ?? run(command, args) : run;
|
|
76860
76971
|
}, planCli = (plan, run) => {
|
|
76861
76972
|
const root = run("npm", ["root", "--global"]);
|
|
76862
|
-
if (root.status !== 0 || !
|
|
76973
|
+
if (root.status !== 0 || !path51.isAbsolute(root.stdout.trim())) {
|
|
76863
76974
|
plan.skipped.push({
|
|
76864
76975
|
host: "cli",
|
|
76865
76976
|
reason: "global npm location could not be verified",
|
|
@@ -76867,9 +76978,9 @@ var codexRegistered = (configFile) => {
|
|
|
76867
76978
|
});
|
|
76868
76979
|
return;
|
|
76869
76980
|
}
|
|
76870
|
-
const packageFile =
|
|
76981
|
+
const packageFile = path51.join(root.stdout.trim(), "@brainervirus/workit-cli/package.json");
|
|
76871
76982
|
const installed = objectOrNull(packageFile);
|
|
76872
|
-
if (installed?.name !== "@brainervirus/workit-cli" || lstatSync8(
|
|
76983
|
+
if (installed?.name !== "@brainervirus/workit-cli" || lstatSync8(path51.dirname(packageFile)).isSymbolicLink()) {
|
|
76873
76984
|
plan.skipped.push({
|
|
76874
76985
|
host: "cli",
|
|
76875
76986
|
reason: "no managed global CLI install (local links preserved); use npx @brainervirus/workit-cli@latest"
|
|
@@ -76898,6 +77009,7 @@ var codexRegistered = (configFile) => {
|
|
|
76898
77009
|
});
|
|
76899
77010
|
};
|
|
76900
77011
|
var init_plan = __esm(() => {
|
|
77012
|
+
init_probes();
|
|
76901
77013
|
init_registration();
|
|
76902
77014
|
init_setup_state();
|
|
76903
77015
|
init_host_install();
|
|
@@ -76907,7 +77019,7 @@ var init_plan = __esm(() => {
|
|
|
76907
77019
|
});
|
|
76908
77020
|
|
|
76909
77021
|
// packages/workit-cli/src/upgrade/check.ts
|
|
76910
|
-
import
|
|
77022
|
+
import path52 from "node:path";
|
|
76911
77023
|
function runUpdateCheck(json, deps) {
|
|
76912
77024
|
const out = deps.out ?? process.stdout;
|
|
76913
77025
|
const paths = upgradePaths(deps);
|
|
@@ -77009,7 +77121,7 @@ function runSetUpdates(value, deps) {
|
|
|
77009
77121
|
`);
|
|
77010
77122
|
return 1;
|
|
77011
77123
|
}
|
|
77012
|
-
out.write(`updates: ${value} (saved in ${
|
|
77124
|
+
out.write(`updates: ${value} (saved in ${path52.join(configDir, "config.json")})
|
|
77013
77125
|
`);
|
|
77014
77126
|
return 0;
|
|
77015
77127
|
}
|
|
@@ -77106,7 +77218,24 @@ __export(exports_upgrade, {
|
|
|
77106
77218
|
runUpgradeCommand: () => runUpgradeCommand
|
|
77107
77219
|
});
|
|
77108
77220
|
import { spawnSync as spawnSync18 } from "node:child_process";
|
|
77221
|
+
import { mkdtempSync as mkdtempSync5, readFileSync as readFileSync26, rmSync as rmSync10, writeFileSync as writeFileSync14 } from "node:fs";
|
|
77222
|
+
import os20 from "node:os";
|
|
77223
|
+
import path53 from "node:path";
|
|
77109
77224
|
async function runUpgradeCommand(argv, deps = {}) {
|
|
77225
|
+
const { env } = upgradePaths(deps);
|
|
77226
|
+
const handBack = env[CONTINUE_ENV] !== undefined ? env[ROWS_ENV] : undefined;
|
|
77227
|
+
const handed = {};
|
|
77228
|
+
const code = await upgradeOnce(argv, deps, handed);
|
|
77229
|
+
if (!handBack)
|
|
77230
|
+
return code;
|
|
77231
|
+
try {
|
|
77232
|
+
writeFileSync14(handBack, JSON.stringify({ code, rows: handed.rows ?? [] }));
|
|
77233
|
+
return 0;
|
|
77234
|
+
} catch {
|
|
77235
|
+
return code;
|
|
77236
|
+
}
|
|
77237
|
+
}
|
|
77238
|
+
async function upgradeOnce(argv, deps, handed) {
|
|
77110
77239
|
const out = deps.out ?? process.stdout;
|
|
77111
77240
|
const setting = argv.find((arg) => arg.startsWith("--set-updates="));
|
|
77112
77241
|
if (argv.includes("--check") || setting) {
|
|
@@ -77132,16 +77261,19 @@ async function runUpgradeCommand(argv, deps = {}) {
|
|
|
77132
77261
|
}
|
|
77133
77262
|
const legacy = flags.has("--apply");
|
|
77134
77263
|
const json = flags.has("--json") || legacy;
|
|
77135
|
-
const
|
|
77264
|
+
const { home, env } = upgradePaths(deps);
|
|
77265
|
+
const continued = env[CONTINUE_ENV] !== undefined ? priorRows(env[CONTINUE_ENV]) : undefined;
|
|
77136
77266
|
const progress = deps.progress ?? createProgress({ stream: process.stderr, json });
|
|
77137
|
-
const
|
|
77138
|
-
|
|
77139
|
-
|
|
77140
|
-
|
|
77267
|
+
const withCli = !continued && (hostFlag === undefined || flags.has("--cli"));
|
|
77268
|
+
const checking = raw.length + (withCli ? 1 : 0);
|
|
77269
|
+
const plan = await progress.run(`Checking ${checking} ${checking === 1 ? "host" : "hosts"}`, async () => {
|
|
77270
|
+
const probes = await runProbes(raw, withCli, deps);
|
|
77271
|
+
const planned = previewUpgrade(raw, deps, probes);
|
|
77272
|
+
if (withCli)
|
|
77273
|
+
planCli(planned, probedRunner(deps, probes));
|
|
77141
77274
|
return planned;
|
|
77142
77275
|
});
|
|
77143
77276
|
plan.ok = plan.blocked.length === 0 && plan.failed.length === 0;
|
|
77144
|
-
const { home, env } = upgradePaths(deps);
|
|
77145
77277
|
const style = createStyle({
|
|
77146
77278
|
stream: out === process.stdout ? process.stdout : out === process.stderr ? process.stderr : undefined,
|
|
77147
77279
|
env,
|
|
@@ -77172,7 +77304,8 @@ async function runUpgradeCommand(argv, deps = {}) {
|
|
|
77172
77304
|
return plan.blocked.length ? 1 : 0;
|
|
77173
77305
|
}
|
|
77174
77306
|
if (!json)
|
|
77175
|
-
out.write(
|
|
77307
|
+
out.write(continued ? `Continuing the upgrade with the new CLI (workit ${package_default.version}).
|
|
77308
|
+
` : summary(plan, permissions.changes, style));
|
|
77176
77309
|
if (flags.has("--preview")) {
|
|
77177
77310
|
out.write(nothingChanged);
|
|
77178
77311
|
return plan.blocked.length ? 1 : 0;
|
|
@@ -77195,7 +77328,44 @@ Nothing changed.
|
|
|
77195
77328
|
for (const warning of plan.warnings ?? [])
|
|
77196
77329
|
out.write(`warning: ${warning}
|
|
77197
77330
|
`);
|
|
77198
|
-
const
|
|
77331
|
+
const reexec = deps.reexec ?? (deps.run && !deps.cliEntry ? undefined : spawnUpgrade({
|
|
77332
|
+
entry: deps.cliEntry ?? process.argv[1],
|
|
77333
|
+
out,
|
|
77334
|
+
toStderr: out === process.stderr,
|
|
77335
|
+
json
|
|
77336
|
+
}));
|
|
77337
|
+
const handoff = async (cli) => {
|
|
77338
|
+
if (!reexec || (deps.cliOnDisk ?? runningCliVersion)() !== plan.cli?.latest)
|
|
77339
|
+
return;
|
|
77340
|
+
const scratch = mkdtempSync5(path53.join(os20.tmpdir(), "workit-upgrade-"));
|
|
77341
|
+
const rowsFile = path53.join(scratch, "rows.json");
|
|
77342
|
+
try {
|
|
77343
|
+
const code = await reexec([
|
|
77344
|
+
...legacy ? ["--apply", "--confirm"] : ["--yes"],
|
|
77345
|
+
...flags.has("--json") ? ["--json"] : [],
|
|
77346
|
+
`--hosts=${raw.length ? raw.join(",") : "none"}`
|
|
77347
|
+
], {
|
|
77348
|
+
[CONTINUE_ENV]: JSON.stringify([cli]),
|
|
77349
|
+
[ROWS_ENV]: rowsFile,
|
|
77350
|
+
WORKIT_UPDATE_CHECK: "0"
|
|
77351
|
+
});
|
|
77352
|
+
if (code === undefined)
|
|
77353
|
+
return;
|
|
77354
|
+
const back = handedBack(readText5(rowsFile));
|
|
77355
|
+
deps.onResult?.(back?.rows.length ? back.rows : [cli]);
|
|
77356
|
+
return back?.code ?? code;
|
|
77357
|
+
} finally {
|
|
77358
|
+
rmSync10(scratch, { recursive: true, force: true });
|
|
77359
|
+
}
|
|
77360
|
+
};
|
|
77361
|
+
const result = await applyUpgrade(plan, { ...deps, progress }, continued || !reexec ? {} : { handoff });
|
|
77362
|
+
if (result.handedOff !== undefined)
|
|
77363
|
+
return result.handedOff;
|
|
77364
|
+
if (continued?.length) {
|
|
77365
|
+
result.hosts.unshift(...continued);
|
|
77366
|
+
if (continued.some((row) => row.status === "failed"))
|
|
77367
|
+
result.ok = false;
|
|
77368
|
+
}
|
|
77199
77369
|
let permissionsOk = true;
|
|
77200
77370
|
let written;
|
|
77201
77371
|
if (permissions.changes.length && !permissions.refused && !result.error?.startsWith("configuration changed")) {
|
|
@@ -77210,8 +77380,9 @@ Nothing changed.
|
|
|
77210
77380
|
});
|
|
77211
77381
|
}
|
|
77212
77382
|
deps.onResult?.(result.hosts);
|
|
77383
|
+
handed.rows = result.hosts;
|
|
77213
77384
|
const failed = !result.ok || !permissionsOk;
|
|
77214
|
-
const cliVersion = result.hosts.some((h) => h.host === "cli" && h.status === "updated") ? plan.cli.latest : package_default.version;
|
|
77385
|
+
const cliVersion = plan.cli && result.hosts.some((h) => h.host === "cli" && h.status === "updated") ? plan.cli.latest : package_default.version;
|
|
77215
77386
|
const report = progress.runSync("Checking the result with workit doctor", () => (deps.doctor ?? ((version) => runDoctor({ home, env, cliVersion: version, only: "upgrade" })))(cliVersion));
|
|
77216
77387
|
const left = report.checks.filter((check) => check.status === "warn" || check.status === "fail");
|
|
77217
77388
|
if (json) {
|
|
@@ -77234,7 +77405,7 @@ Nothing changed.
|
|
|
77234
77405
|
if (result.backup)
|
|
77235
77406
|
out.write(`Backup: ${style.path(result.backup)}
|
|
77236
77407
|
`);
|
|
77237
|
-
out.write(left.length === 0 ? `${style.ok("Verified:")} workit doctor is clean for versions, assets, agents and permissions.
|
|
77408
|
+
out.write(left.length === 0 ? `${style.ok("Verified:")} workit doctor is clean for versions, assets, agents, stale installs and permissions.
|
|
77238
77409
|
` : `${style.warn("Left after upgrade (workit doctor):")}
|
|
77239
77410
|
${left.map((check) => ` ${style.bold(check.id)}: ${check.detail}${check.fix ? `
|
|
77240
77411
|
fix: ${style.command(check.fix)}` : ""}`).join(`
|
|
@@ -77295,7 +77466,68 @@ async function runLaunchCommand(argv, deps = {}) {
|
|
|
77295
77466
|
var USAGE3 = `Usage: workit upgrade [--hosts=opencode,cursor,codex,pi,claude-code|none] [--cli] [--preview | --yes | --apply --confirm] [--json]
|
|
77296
77467
|
workit upgrade --check [--json]
|
|
77297
77468
|
workit upgrade --set-updates=prompt|auto|off
|
|
77298
|
-
|
|
77469
|
+
`, CONTINUE_ENV = "WORKIT_UPGRADE_CONTINUE", ROWS_ENV = "WORKIT_UPGRADE_ROWS", readText5 = (file) => {
|
|
77470
|
+
try {
|
|
77471
|
+
return readFileSync26(file, "utf8");
|
|
77472
|
+
} catch {
|
|
77473
|
+
return;
|
|
77474
|
+
}
|
|
77475
|
+
}, priorRows = (text) => {
|
|
77476
|
+
if (text === undefined)
|
|
77477
|
+
return;
|
|
77478
|
+
try {
|
|
77479
|
+
const rows = JSON.parse(text);
|
|
77480
|
+
return Array.isArray(rows) ? rows.filter((row) => typeof row?.host === "string" && typeof row?.status === "string" && typeof row?.reason === "string") : [];
|
|
77481
|
+
} catch {
|
|
77482
|
+
return [];
|
|
77483
|
+
}
|
|
77484
|
+
}, handedBack = (text) => {
|
|
77485
|
+
if (text === undefined)
|
|
77486
|
+
return;
|
|
77487
|
+
try {
|
|
77488
|
+
const value = JSON.parse(text);
|
|
77489
|
+
return {
|
|
77490
|
+
code: typeof value.code === "number" ? value.code : undefined,
|
|
77491
|
+
rows: priorRows(JSON.stringify(value.rows ?? [])) ?? []
|
|
77492
|
+
};
|
|
77493
|
+
} catch {
|
|
77494
|
+
return;
|
|
77495
|
+
}
|
|
77496
|
+
}, runningCliVersion = () => {
|
|
77497
|
+
const script = process.argv[1];
|
|
77498
|
+
if (!script)
|
|
77499
|
+
return;
|
|
77500
|
+
let dir = path53.dirname(script);
|
|
77501
|
+
for (let depth = 0;depth < 4; depth += 1, dir = path53.dirname(dir)) {
|
|
77502
|
+
const found = cliPackageVersion(readText5(path53.join(dir, "package.json")));
|
|
77503
|
+
if (found)
|
|
77504
|
+
return found;
|
|
77505
|
+
}
|
|
77506
|
+
return;
|
|
77507
|
+
}, cliPackageVersion = (text) => {
|
|
77508
|
+
if (text === undefined)
|
|
77509
|
+
return;
|
|
77510
|
+
try {
|
|
77511
|
+
const found = JSON.parse(text);
|
|
77512
|
+
return found.name === package_default.name && typeof found.version === "string" ? found.version : undefined;
|
|
77513
|
+
} catch {
|
|
77514
|
+
return;
|
|
77515
|
+
}
|
|
77516
|
+
}, spawnUpgrade = (options) => (argv, extra) => {
|
|
77517
|
+
if (!options.entry)
|
|
77518
|
+
return;
|
|
77519
|
+
const result = spawnSync18(process.execPath, [options.entry, "upgrade", ...argv], {
|
|
77520
|
+
stdio: ["inherit", options.json ? "pipe" : options.toStderr ? 2 : "inherit", "inherit"],
|
|
77521
|
+
encoding: "utf8",
|
|
77522
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
77523
|
+
env: { ...process.env, ...extra }
|
|
77524
|
+
});
|
|
77525
|
+
if (result.error)
|
|
77526
|
+
return;
|
|
77527
|
+
if (options.json && result.stdout)
|
|
77528
|
+
options.out.write(result.stdout);
|
|
77529
|
+
return result.status ?? 1;
|
|
77530
|
+
};
|
|
77299
77531
|
var init_upgrade = __esm(() => {
|
|
77300
77532
|
init_package();
|
|
77301
77533
|
init_host_install();
|
|
@@ -77306,6 +77538,7 @@ var init_upgrade = __esm(() => {
|
|
|
77306
77538
|
init_apply();
|
|
77307
77539
|
init_check();
|
|
77308
77540
|
init_plan();
|
|
77541
|
+
init_probes();
|
|
77309
77542
|
init_report();
|
|
77310
77543
|
init_shared();
|
|
77311
77544
|
init_apply();
|
|
@@ -77336,7 +77569,7 @@ var init_launch = __esm(() => {
|
|
|
77336
77569
|
// packages/workit-core/src/knowledge.ts
|
|
77337
77570
|
import { spawnSync as spawnSync19 } from "node:child_process";
|
|
77338
77571
|
import fs20 from "node:fs";
|
|
77339
|
-
import
|
|
77572
|
+
import path54 from "node:path";
|
|
77340
77573
|
function lintKnowledge(root) {
|
|
77341
77574
|
const seen = new Set;
|
|
77342
77575
|
const unreadable = [];
|
|
@@ -77440,7 +77673,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
77440
77673
|
const end = lines.indexOf("---", 1);
|
|
77441
77674
|
return end === -1 ? lines : [...lines.slice(0, end + 1).map(() => ""), ...lines.slice(end + 1)];
|
|
77442
77675
|
}, read = (root, file) => {
|
|
77443
|
-
const full =
|
|
77676
|
+
const full = path54.join(root, file);
|
|
77444
77677
|
try {
|
|
77445
77678
|
fs20.lstatSync(full);
|
|
77446
77679
|
} catch {
|
|
@@ -77481,7 +77714,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
77481
77714
|
}
|
|
77482
77715
|
}, brokenLinks = (root, doc, tracked) => {
|
|
77483
77716
|
const findings = [];
|
|
77484
|
-
const base =
|
|
77717
|
+
const base = path54.dirname(path54.join(root, doc.file));
|
|
77485
77718
|
const missing = (target, line, how) => findings.push({
|
|
77486
77719
|
rule: "broken-link",
|
|
77487
77720
|
file: doc.file,
|
|
@@ -77500,7 +77733,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
77500
77733
|
const local = localTarget(target);
|
|
77501
77734
|
if (!local)
|
|
77502
77735
|
continue;
|
|
77503
|
-
const resolved = local.startsWith("/") ?
|
|
77736
|
+
const resolved = local.startsWith("/") ? path54.join(root, local) : path54.resolve(base, local);
|
|
77504
77737
|
if (!exists2(resolved))
|
|
77505
77738
|
missing(target, index + 1, "link");
|
|
77506
77739
|
}
|
|
@@ -77510,9 +77743,9 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
77510
77743
|
continue;
|
|
77511
77744
|
const relative = /^\.\.?\//.test(candidate);
|
|
77512
77745
|
const first = candidate.split("/")[0];
|
|
77513
|
-
if (!relative && !(tracked ? tracked.has(first) : exists2(
|
|
77746
|
+
if (!relative && !(tracked ? tracked.has(first) : exists2(path54.join(root, first))))
|
|
77514
77747
|
continue;
|
|
77515
|
-
const resolved = relative ?
|
|
77748
|
+
const resolved = relative ? path54.resolve(base, candidate) : path54.join(root, candidate);
|
|
77516
77749
|
if (!exists2(resolved))
|
|
77517
77750
|
missing(span, index + 1, "pointer");
|
|
77518
77751
|
}
|
|
@@ -77881,8 +78114,8 @@ var init_redact = __esm(() => {
|
|
|
77881
78114
|
import { spawn as spawn4, spawnSync as spawnSync20 } from "node:child_process";
|
|
77882
78115
|
import { createHash as createHash17 } from "node:crypto";
|
|
77883
78116
|
import fs21 from "node:fs";
|
|
77884
|
-
import
|
|
77885
|
-
import
|
|
78117
|
+
import os21 from "node:os";
|
|
78118
|
+
import path55 from "node:path";
|
|
77886
78119
|
import { StringDecoder } from "node:string_decoder";
|
|
77887
78120
|
function tailLines(text, lines = TAIL_LINES) {
|
|
77888
78121
|
const all = text.replace(/\r\n?/gu, `
|
|
@@ -78002,7 +78235,7 @@ function planSpawn(argv, options) {
|
|
|
78002
78235
|
return { file: argv[0], args: [], verbatim: false, shell: true };
|
|
78003
78236
|
if (options.platform !== "win32")
|
|
78004
78237
|
return { file: argv[0], args: argv.slice(1), verbatim: false, shell: false };
|
|
78005
|
-
const win =
|
|
78238
|
+
const win = path55.win32;
|
|
78006
78239
|
const isFile = options.isFile ?? ((file) => {
|
|
78007
78240
|
try {
|
|
78008
78241
|
return fs21.statSync(file).isFile();
|
|
@@ -78087,7 +78320,7 @@ function runCheckCommand(argv, options) {
|
|
|
78087
78320
|
`);
|
|
78088
78321
|
redactor.end();
|
|
78089
78322
|
resolve({
|
|
78090
|
-
exitCode: spawnError ? 127 : code !== null ? code : 128 + (signal ?
|
|
78323
|
+
exitCode: spawnError ? 127 : code !== null ? code : 128 + (signal ? os21.constants.signals[signal] ?? 1 : 1),
|
|
78091
78324
|
signal: signal ?? null,
|
|
78092
78325
|
timedOut,
|
|
78093
78326
|
durationMs: Date.now() - started,
|
|
@@ -78164,10 +78397,10 @@ function runCheckCommand(argv, options) {
|
|
|
78164
78397
|
function storeLog(storeRoot, log) {
|
|
78165
78398
|
const digest = logDigest(log);
|
|
78166
78399
|
const ref = `blobs/logs/${digest.slice("sha256:".length)}.log`;
|
|
78167
|
-
const file =
|
|
78400
|
+
const file = path55.join(storeRoot, ref);
|
|
78168
78401
|
try {
|
|
78169
78402
|
if (!fs21.existsSync(file)) {
|
|
78170
|
-
fs21.mkdirSync(
|
|
78403
|
+
fs21.mkdirSync(path55.dirname(file), { recursive: true });
|
|
78171
78404
|
const temp = `${file}.${process.pid}.${Date.now()}.tmp`;
|
|
78172
78405
|
fs21.writeFileSync(temp, log, { mode: 384 });
|
|
78173
78406
|
fs21.renameSync(temp, file);
|
|
@@ -78180,7 +78413,7 @@ function storeLog(storeRoot, log) {
|
|
|
78180
78413
|
function pruneCheckLogs(storeRoot, options = {}) {
|
|
78181
78414
|
const limits = { ...LOG_RETENTION, ...options.retention };
|
|
78182
78415
|
const now = options.now ?? Date.now();
|
|
78183
|
-
const dir =
|
|
78416
|
+
const dir = path55.join(storeRoot, "blobs", "logs");
|
|
78184
78417
|
const report = { removed: 0, removedBytes: 0, kept: 0 };
|
|
78185
78418
|
let names;
|
|
78186
78419
|
try {
|
|
@@ -78190,7 +78423,7 @@ function pruneCheckLogs(storeRoot, options = {}) {
|
|
|
78190
78423
|
}
|
|
78191
78424
|
const files = names.flatMap((name) => {
|
|
78192
78425
|
try {
|
|
78193
|
-
const stat = fs21.statSync(
|
|
78426
|
+
const stat = fs21.statSync(path55.join(dir, name));
|
|
78194
78427
|
return stat.isFile() ? [{ name, size: stat.size, mtimeMs: stat.mtimeMs }] : [];
|
|
78195
78428
|
} catch {
|
|
78196
78429
|
return [];
|
|
@@ -78209,7 +78442,7 @@ function pruneCheckLogs(storeRoot, options = {}) {
|
|
|
78209
78442
|
continue;
|
|
78210
78443
|
if (!options.dryRun)
|
|
78211
78444
|
try {
|
|
78212
|
-
fs21.rmSync(
|
|
78445
|
+
fs21.rmSync(path55.join(dir, file.name), { force: true });
|
|
78213
78446
|
} catch {
|
|
78214
78447
|
continue;
|
|
78215
78448
|
}
|
|
@@ -78479,7 +78712,7 @@ __export(exports_workspace, {
|
|
|
78479
78712
|
run: () => run11,
|
|
78480
78713
|
runWorkspace: () => runWorkspace
|
|
78481
78714
|
});
|
|
78482
|
-
import { copyFileSync as copyFileSync7, existsSync as
|
|
78715
|
+
import { copyFileSync as copyFileSync7, existsSync as existsSync25 } from "node:fs";
|
|
78483
78716
|
function list2(argv, io) {
|
|
78484
78717
|
if (argv.length)
|
|
78485
78718
|
return usage3(io, `unexpected argument ${argv[0]}`);
|
|
@@ -78788,7 +79021,7 @@ usage: ${USAGE5}`)), load = (io) => {
|
|
|
78788
79021
|
return { ok: false, error: `${current.path} changed; retry` };
|
|
78789
79022
|
let backup = null;
|
|
78790
79023
|
try {
|
|
78791
|
-
if (
|
|
79024
|
+
if (existsSync25(current.path)) {
|
|
78792
79025
|
backup = `${current.path}.bak`;
|
|
78793
79026
|
copyFileSync7(current.path, backup);
|
|
78794
79027
|
}
|
|
@@ -78862,12 +79095,12 @@ var init_workspace = __esm(() => {
|
|
|
78862
79095
|
|
|
78863
79096
|
// packages/workit-core/src/core/heavy-rules.ts
|
|
78864
79097
|
import fs22 from "node:fs";
|
|
78865
|
-
import
|
|
79098
|
+
import path56 from "node:path";
|
|
78866
79099
|
function gitTop(cwd) {
|
|
78867
|
-
for (let dir =
|
|
78868
|
-
if (fs22.existsSync(
|
|
79100
|
+
for (let dir = path56.resolve(cwd);; dir = path56.dirname(dir)) {
|
|
79101
|
+
if (fs22.existsSync(path56.join(dir, ".git")))
|
|
78869
79102
|
return dir;
|
|
78870
|
-
if (
|
|
79103
|
+
if (path56.dirname(dir) === dir)
|
|
78871
79104
|
return null;
|
|
78872
79105
|
}
|
|
78873
79106
|
}
|
|
@@ -78908,19 +79141,19 @@ var init_heavy_rules = () => {};
|
|
|
78908
79141
|
|
|
78909
79142
|
// packages/workit-core/src/core/heavy.ts
|
|
78910
79143
|
import fs23 from "node:fs";
|
|
78911
|
-
import
|
|
78912
|
-
import
|
|
79144
|
+
import os22 from "node:os";
|
|
79145
|
+
import path57 from "node:path";
|
|
78913
79146
|
function stateDir2(env, platform = process.platform) {
|
|
78914
79147
|
if (env.WORKFLOW_TOOLKIT_STATE)
|
|
78915
79148
|
return env.WORKFLOW_TOOLKIT_STATE;
|
|
78916
79149
|
if (env.XDG_STATE_HOME)
|
|
78917
|
-
return
|
|
78918
|
-
const home = env.HOME ||
|
|
79150
|
+
return path57.join(env.XDG_STATE_HOME, "workit");
|
|
79151
|
+
const home = env.HOME || os22.homedir();
|
|
78919
79152
|
if (platform === "darwin")
|
|
78920
|
-
return
|
|
79153
|
+
return path57.join(home, "Library", "Application Support", "workit");
|
|
78921
79154
|
if (platform === "win32")
|
|
78922
|
-
return
|
|
78923
|
-
return
|
|
79155
|
+
return path57.join(env.LOCALAPPDATA ?? path57.join(home, "AppData", "Local"), "workit");
|
|
79156
|
+
return path57.join(home, ".local", "state", "workit");
|
|
78924
79157
|
}
|
|
78925
79158
|
function positional(words, from, values = PM_VALUES) {
|
|
78926
79159
|
let index = from;
|
|
@@ -79060,7 +79293,7 @@ function machinePatterns(env) {
|
|
|
79060
79293
|
return isRecord8(value) ? stringList2(value.patterns) : [];
|
|
79061
79294
|
}
|
|
79062
79295
|
function repoPatterns(cwd) {
|
|
79063
|
-
return repoHeavyCommands(gitTop(cwd) ??
|
|
79296
|
+
return repoHeavyCommands(gitTop(cwd) ?? path57.resolve(cwd));
|
|
79064
79297
|
}
|
|
79065
79298
|
function heavyLines(lines, options) {
|
|
79066
79299
|
const found = [];
|
|
@@ -79139,7 +79372,7 @@ function leaseRewrite(command) {
|
|
|
79139
79372
|
return null;
|
|
79140
79373
|
return `${prefix}workit check --heavy -- ${rest}`;
|
|
79141
79374
|
}
|
|
79142
|
-
var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) =>
|
|
79375
|
+
var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) => path57.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) => {
|
|
79143
79376
|
try {
|
|
79144
79377
|
return JSON.parse(fs23.readFileSync(file, "utf8"));
|
|
79145
79378
|
} catch {
|
|
@@ -79285,8 +79518,8 @@ var init_heavy = __esm(() => {
|
|
|
79285
79518
|
// packages/workit-core/src/core/resources.ts
|
|
79286
79519
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
79287
79520
|
import fs24 from "node:fs";
|
|
79288
|
-
import
|
|
79289
|
-
import
|
|
79521
|
+
import os23 from "node:os";
|
|
79522
|
+
import path58 from "node:path";
|
|
79290
79523
|
function memoryValue(value, host) {
|
|
79291
79524
|
const text = typeof value === "number" ? String(value) : typeof value === "string" ? value : "";
|
|
79292
79525
|
const percent = PERCENT.exec(text.trim());
|
|
@@ -79412,7 +79645,7 @@ function scopeBusy(unit) {
|
|
|
79412
79645
|
return false;
|
|
79413
79646
|
const uid = process.getuid?.() ?? 0;
|
|
79414
79647
|
const manager = `/sys/fs/cgroup/user.slice/user-${uid}.slice/user@${uid}.service`;
|
|
79415
|
-
return [`${manager}/app.slice/${unit}`, `${manager}/${unit}`].some((dir) => (
|
|
79648
|
+
return [`${manager}/app.slice/${unit}`, `${manager}/${unit}`].some((dir) => (readText6(`${dir}/cgroup.procs`) ?? "").trim() !== "");
|
|
79416
79649
|
}
|
|
79417
79650
|
function isAncestor(pid) {
|
|
79418
79651
|
if (process.platform !== "linux")
|
|
@@ -79469,7 +79702,7 @@ function reclaim(file, stale) {
|
|
|
79469
79702
|
} catch {
|
|
79470
79703
|
return true;
|
|
79471
79704
|
}
|
|
79472
|
-
if (!stale(parseLease(
|
|
79705
|
+
if (!stale(parseLease(readText6(file)), ageMs))
|
|
79473
79706
|
return false;
|
|
79474
79707
|
fs24.rmSync(file, { force: true });
|
|
79475
79708
|
return true;
|
|
@@ -79482,7 +79715,7 @@ function tryOnce(options, record, reclaimed) {
|
|
|
79482
79715
|
const text = `${JSON.stringify(record)}
|
|
79483
79716
|
`;
|
|
79484
79717
|
for (let slot = 0;slot < options.slots; slot += 1) {
|
|
79485
|
-
const file =
|
|
79718
|
+
const file = path58.join(options.dir, `slot-${slot}.json`);
|
|
79486
79719
|
for (let attempt = 0;attempt < 2; attempt += 1) {
|
|
79487
79720
|
try {
|
|
79488
79721
|
const fd = fs24.openSync(file, "wx", 384);
|
|
@@ -79496,7 +79729,7 @@ function tryOnce(options, record, reclaimed) {
|
|
|
79496
79729
|
if (error.code !== "EEXIST")
|
|
79497
79730
|
throw error;
|
|
79498
79731
|
}
|
|
79499
|
-
const lease = parseLease(
|
|
79732
|
+
const lease = parseLease(readText6(file));
|
|
79500
79733
|
let reason = null;
|
|
79501
79734
|
const removed = reclaim(file, (current, ageMs) => {
|
|
79502
79735
|
reason = current ? staleReason(current, options.probe) : ageMs > UNREADABLE_TTL_MS ? "unreadable" : null;
|
|
@@ -79515,7 +79748,7 @@ function tryOnce(options, record, reclaimed) {
|
|
|
79515
79748
|
return { holders };
|
|
79516
79749
|
}
|
|
79517
79750
|
function removeOwn(file, id) {
|
|
79518
|
-
if (parseLease(
|
|
79751
|
+
if (parseLease(readText6(file))?.id === id)
|
|
79519
79752
|
fs24.rmSync(file, { force: true });
|
|
79520
79753
|
}
|
|
79521
79754
|
function leaseQueue(dir, probe = {}) {
|
|
@@ -79527,8 +79760,8 @@ function leaseQueue(dir, probe = {}) {
|
|
|
79527
79760
|
}
|
|
79528
79761
|
const entries = [];
|
|
79529
79762
|
for (const name of names.filter((item) => item.endsWith(".json")).toSorted()) {
|
|
79530
|
-
const file =
|
|
79531
|
-
const record = parseLease(
|
|
79763
|
+
const file = path58.join(queueDir(dir), name);
|
|
79764
|
+
const record = parseLease(readText6(file));
|
|
79532
79765
|
if (!record)
|
|
79533
79766
|
continue;
|
|
79534
79767
|
entries.push({
|
|
@@ -79543,9 +79776,9 @@ function leaseQueue(dir, probe = {}) {
|
|
|
79543
79776
|
function waitersAhead(options, own) {
|
|
79544
79777
|
let ahead = 0;
|
|
79545
79778
|
for (const entry of leaseQueue(options.dir, options.probe)) {
|
|
79546
|
-
if (
|
|
79779
|
+
if (path58.basename(entry.file) >= own)
|
|
79547
79780
|
break;
|
|
79548
|
-
if (!TICKET.test(
|
|
79781
|
+
if (!TICKET.test(path58.basename(entry.file)))
|
|
79549
79782
|
continue;
|
|
79550
79783
|
if (entry.stale && reclaim(entry.file, (current) => !current || staleReason(current, options.probe) !== null))
|
|
79551
79784
|
continue;
|
|
@@ -79557,7 +79790,7 @@ function liveHolders(options) {
|
|
|
79557
79790
|
return leaseSlots(options.dir, options.slots, options.probe).filter((slot) => slot.holder && !slot.stale).map((slot) => slot.holder);
|
|
79558
79791
|
}
|
|
79559
79792
|
function writeTicket(file, record) {
|
|
79560
|
-
fs24.mkdirSync(
|
|
79793
|
+
fs24.mkdirSync(path58.dirname(file), { recursive: true, mode: 448 });
|
|
79561
79794
|
fs24.writeFileSync(file, `${JSON.stringify(record)}
|
|
79562
79795
|
`, { mode: 384 });
|
|
79563
79796
|
}
|
|
@@ -79602,7 +79835,7 @@ async function acquireLease(options) {
|
|
|
79602
79835
|
const reclaimed = [];
|
|
79603
79836
|
let waitedOn = [];
|
|
79604
79837
|
const name = ticketName(started, record.id);
|
|
79605
|
-
const ticket =
|
|
79838
|
+
const ticket = path58.join(queueDir(options.dir), name);
|
|
79606
79839
|
const ticketRecord = {
|
|
79607
79840
|
...record,
|
|
79608
79841
|
maxAgeMs: options.waitMs + 60000
|
|
@@ -79703,7 +79936,7 @@ async function acquireLease(options) {
|
|
|
79703
79936
|
function updateLease(lease, patch) {
|
|
79704
79937
|
Object.assign(lease.record, patch);
|
|
79705
79938
|
try {
|
|
79706
|
-
if (parseLease(
|
|
79939
|
+
if (parseLease(readText6(lease.file))?.id !== lease.record.id)
|
|
79707
79940
|
return;
|
|
79708
79941
|
const temp = `${lease.file}.${process.pid}.tmp`;
|
|
79709
79942
|
fs24.writeFileSync(temp, `${JSON.stringify(lease.record)}
|
|
@@ -79723,7 +79956,7 @@ function heldLease(dir, id, options = {}) {
|
|
|
79723
79956
|
for (const name of names) {
|
|
79724
79957
|
if (!/^slot-\d+\.json$/u.test(name))
|
|
79725
79958
|
continue;
|
|
79726
|
-
const lease = parseLease(
|
|
79959
|
+
const lease = parseLease(readText6(path58.join(dir, name)));
|
|
79727
79960
|
if (lease?.id === id && !staleReason(lease, options.probe) && (options.ancestor ?? isAncestor)(lease.pid))
|
|
79728
79961
|
return lease;
|
|
79729
79962
|
}
|
|
@@ -79778,10 +80011,10 @@ async function runScoped(run, wrapper, sinks) {
|
|
|
79778
80011
|
}
|
|
79779
80012
|
function firstNotice(env, session, key, now = Date.now()) {
|
|
79780
80013
|
const id = (session ?? `ppid-${process.ppid}`).replace(/[^A-Za-z0-9_.-]/gu, "_").slice(0, 120);
|
|
79781
|
-
const dir =
|
|
80014
|
+
const dir = path58.join(stateDir2(env), "notices");
|
|
79782
80015
|
try {
|
|
79783
80016
|
fs24.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
79784
|
-
fs24.writeFileSync(
|
|
80017
|
+
fs24.writeFileSync(path58.join(dir, `${key}-${id}`), `${new Date(now).toISOString()}
|
|
79785
80018
|
`, {
|
|
79786
80019
|
flag: "wx",
|
|
79787
80020
|
mode: 384
|
|
@@ -79791,7 +80024,7 @@ function firstNotice(env, session, key, now = Date.now()) {
|
|
|
79791
80024
|
}
|
|
79792
80025
|
try {
|
|
79793
80026
|
for (const name of fs24.readdirSync(dir)) {
|
|
79794
|
-
const file =
|
|
80027
|
+
const file = path58.join(dir, name);
|
|
79795
80028
|
if (now - fs24.statSync(file).mtimeMs > NOTICE_TTL_MS)
|
|
79796
80029
|
fs24.rmSync(file, { force: true });
|
|
79797
80030
|
}
|
|
@@ -79801,7 +80034,7 @@ function firstNotice(env, session, key, now = Date.now()) {
|
|
|
79801
80034
|
function leaseSlots(dir, slots, probe = {}) {
|
|
79802
80035
|
const states = [];
|
|
79803
80036
|
for (let slot = 0;slot < slots; slot += 1) {
|
|
79804
|
-
const lease = parseLease(
|
|
80037
|
+
const lease = parseLease(readText6(path58.join(dir, `slot-${slot}.json`)));
|
|
79805
80038
|
states.push({
|
|
79806
80039
|
slot,
|
|
79807
80040
|
holder: lease ? holderOf(lease) : null,
|
|
@@ -79811,16 +80044,16 @@ function leaseSlots(dir, slots, probe = {}) {
|
|
|
79811
80044
|
return states;
|
|
79812
80045
|
}
|
|
79813
80046
|
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 = () => ({
|
|
79814
|
-
totalMemBytes:
|
|
79815
|
-
cpus: Math.max(1,
|
|
79816
|
-
}), isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), SIZE, PERCENT, UNITS, leaseDir = (env) =>
|
|
80047
|
+
totalMemBytes: os23.totalmem(),
|
|
80048
|
+
cpus: Math.max(1, os23.availableParallelism?.() ?? os23.cpus().length)
|
|
80049
|
+
}), isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), SIZE, PERCENT, UNITS, leaseDir = (env) => path58.join(stateDir2(env), "leases"), readText6 = (file) => {
|
|
79817
80050
|
try {
|
|
79818
80051
|
return fs24.readFileSync(file, "utf8");
|
|
79819
80052
|
} catch {
|
|
79820
80053
|
return null;
|
|
79821
80054
|
}
|
|
79822
|
-
}, bootId = () =>
|
|
79823
|
-
const stat =
|
|
80055
|
+
}, bootId = () => readText6("/proc/sys/kernel/random/boot_id")?.trim() || null, bootTime = () => Math.round((Date.now() - os23.uptime() * 1000) / 1000) * 1000, BOOT_SLACK_MS = 120000, statFields = (pid) => {
|
|
80056
|
+
const stat = readText6(`/proc/${pid}/stat`);
|
|
79824
80057
|
return stat ? stat.slice(stat.lastIndexOf(")") + 2).split(" ") : null;
|
|
79825
80058
|
}, processStart = (pid) => statFields(pid)?.[19] ?? null, pidAlive2 = (pid) => {
|
|
79826
80059
|
try {
|
|
@@ -79844,7 +80077,7 @@ var DEFAULT_HEAVY_CHECKS, DEFAULT_LIGHT_CHECKS, DEFAULT_SLOTS = 1, DEFAULT_WAIT_
|
|
|
79844
80077
|
cwd: lease.cwd,
|
|
79845
80078
|
session: lease.session,
|
|
79846
80079
|
startedAt: lease.startedAt
|
|
79847
|
-
}), realClock, queueDir = (dir) =>
|
|
80080
|
+
}), realClock, queueDir = (dir) => path58.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;
|
|
79848
80081
|
var init_resources = __esm(() => {
|
|
79849
80082
|
init_checks3();
|
|
79850
80083
|
init_heavy();
|
|
@@ -79873,8 +80106,8 @@ __export(exports_check, {
|
|
|
79873
80106
|
run: () => run12,
|
|
79874
80107
|
workspaceResources: () => workspaceResources
|
|
79875
80108
|
});
|
|
79876
|
-
import
|
|
79877
|
-
import
|
|
80109
|
+
import os24 from "node:os";
|
|
80110
|
+
import path59 from "node:path";
|
|
79878
80111
|
function parse6(argv) {
|
|
79879
80112
|
const split = argv.indexOf("--");
|
|
79880
80113
|
const head = split >= 0 ? argv.slice(0, split) : [...argv];
|
|
@@ -80105,7 +80338,7 @@ ${footer}`;
|
|
|
80105
80338
|
}
|
|
80106
80339
|
async function workspaceResources(io) {
|
|
80107
80340
|
const env = io.env;
|
|
80108
|
-
const dir = env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ??
|
|
80341
|
+
const dir = env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path59.join(env.XDG_CONFIG_HOME || path59.join(env.HOME || os24.homedir(), ".config"), "workit");
|
|
80109
80342
|
try {
|
|
80110
80343
|
await Promise.resolve().then(() => init_workspaces());
|
|
80111
80344
|
const workspace = resolveWorkspaceFrom(io.cwd, dir, env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined);
|
|
@@ -80247,7 +80480,7 @@ async function run12(argv, io) {
|
|
|
80247
80480
|
if (options.shell && command.length !== 1)
|
|
80248
80481
|
return emit(io, fail2("invalid_input", '--shell takes the command as one string: workit check --shell -- "<cmd>"'));
|
|
80249
80482
|
}
|
|
80250
|
-
const relCwd = posix(
|
|
80483
|
+
const relCwd = posix(path59.relative(top, runCwd));
|
|
80251
80484
|
const configured = !options.shell && matchesNamedCheck(config, name, command, relCwd);
|
|
80252
80485
|
const shadowed = !configured && name !== null ? config.checks.find((item) => item.name === name) : undefined;
|
|
80253
80486
|
if (shadowed)
|
|
@@ -80312,7 +80545,7 @@ async function run12(argv, io) {
|
|
|
80312
80545
|
const modifiedWorktree = key.tree !== null && treeAfter !== key.tree;
|
|
80313
80546
|
const store = storeRoot(io.cwd);
|
|
80314
80547
|
const blob = store.ok ? storeLog(store.value.root, result.log) : null;
|
|
80315
|
-
const logPath = store.ok && blob ?
|
|
80548
|
+
const logPath = store.ok && blob ? path59.join(store.value.root, blob.ref) : null;
|
|
80316
80549
|
const tail = tailLines(result.log, TAIL_LINES);
|
|
80317
80550
|
const passed = result.exitCode === 0 && !result.timedOut;
|
|
80318
80551
|
const bounded = boundedArgv(command);
|
|
@@ -80427,7 +80660,7 @@ async function run12(argv, io) {
|
|
|
80427
80660
|
return recordError.code === "busy" ? 4 : recordError.code === "invalid_input" ? 2 : 5;
|
|
80428
80661
|
return 0;
|
|
80429
80662
|
}
|
|
80430
|
-
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(
|
|
80663
|
+
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(path59.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;
|
|
80431
80664
|
var init_check2 = __esm(() => {
|
|
80432
80665
|
init_check_config();
|
|
80433
80666
|
init_checks3();
|
|
@@ -80458,7 +80691,7 @@ __export(exports_lock, {
|
|
|
80458
80691
|
run: () => run13
|
|
80459
80692
|
});
|
|
80460
80693
|
import fs25 from "node:fs";
|
|
80461
|
-
import
|
|
80694
|
+
import path60 from "node:path";
|
|
80462
80695
|
async function settingsFor(io) {
|
|
80463
80696
|
const workspace = await workspaceResources(io);
|
|
80464
80697
|
const config = loadCheckConfig(io.cwd);
|
|
@@ -80550,7 +80783,7 @@ function readPatterns(file) {
|
|
|
80550
80783
|
return { patterns: [] };
|
|
80551
80784
|
}
|
|
80552
80785
|
function writePatterns(file, value) {
|
|
80553
|
-
fs25.mkdirSync(
|
|
80786
|
+
fs25.mkdirSync(path60.dirname(file), { recursive: true, mode: 448 });
|
|
80554
80787
|
const temp = `${file}.${process.pid}.tmp`;
|
|
80555
80788
|
fs25.writeFileSync(temp, `${JSON.stringify(value, null, 2)}
|
|
80556
80789
|
`, { mode: 384 });
|
|
@@ -80636,9 +80869,9 @@ var exports_models = {};
|
|
|
80636
80869
|
__export(exports_models, {
|
|
80637
80870
|
run: () => run14
|
|
80638
80871
|
});
|
|
80639
|
-
import { existsSync as
|
|
80640
|
-
import
|
|
80641
|
-
import
|
|
80872
|
+
import { existsSync as existsSync26, readdirSync as readdirSync13, readFileSync as readFileSync27, statSync as statSync9 } from "node:fs";
|
|
80873
|
+
import os25 from "node:os";
|
|
80874
|
+
import path61 from "node:path";
|
|
80642
80875
|
async function run14(argv, io) {
|
|
80643
80876
|
const [sub, ...args] = argv.filter((arg) => arg !== "--json");
|
|
80644
80877
|
if (sub !== "show")
|
|
@@ -80699,7 +80932,7 @@ var USAGE8 = "workit models show [--role <role>] [--tier <tier>] [--host <host>]
|
|
|
80699
80932
|
const found = new Set;
|
|
80700
80933
|
let text = "";
|
|
80701
80934
|
try {
|
|
80702
|
-
text =
|
|
80935
|
+
text = readFileSync27(file, "utf8");
|
|
80703
80936
|
} catch {
|
|
80704
80937
|
return found;
|
|
80705
80938
|
}
|
|
@@ -80713,26 +80946,26 @@ var USAGE8 = "workit models show [--role <role>] [--tier <tier>] [--host <host>]
|
|
|
80713
80946
|
} catch {}
|
|
80714
80947
|
return found;
|
|
80715
80948
|
}, matches3 = (ran, configured) => ran.toLowerCase().includes(configured.toLowerCase()), usageReport = (cwd, env, days) => {
|
|
80716
|
-
const projects =
|
|
80949
|
+
const projects = path61.join(env.CLAUDE_CONFIG_DIR || path61.join(env.HOME || os25.homedir(), ".claude"), "projects");
|
|
80717
80950
|
const since = Date.now() - days * 86400000;
|
|
80718
80951
|
const types = {};
|
|
80719
80952
|
let agents = 0;
|
|
80720
80953
|
const dirs = (dir) => {
|
|
80721
80954
|
try {
|
|
80722
|
-
return readdirSync13(dir).map((name) =>
|
|
80955
|
+
return readdirSync13(dir).map((name) => path61.join(dir, name));
|
|
80723
80956
|
} catch {
|
|
80724
80957
|
return [];
|
|
80725
80958
|
}
|
|
80726
80959
|
};
|
|
80727
80960
|
for (const project of dirs(projects))
|
|
80728
80961
|
for (const session of dirs(project))
|
|
80729
|
-
for (const meta of dirs(
|
|
80962
|
+
for (const meta of dirs(path61.join(session, "subagents")).filter((f) => f.endsWith(".meta.json"))) {
|
|
80730
80963
|
try {
|
|
80731
80964
|
if (statSync9(meta).mtimeMs < since)
|
|
80732
80965
|
continue;
|
|
80733
|
-
const agentType = JSON.parse(
|
|
80966
|
+
const agentType = JSON.parse(readFileSync27(meta, "utf8")).agentType;
|
|
80734
80967
|
const transcript = meta.replace(/\.meta\.json$/, ".jsonl");
|
|
80735
|
-
if (typeof agentType !== "string" || !
|
|
80968
|
+
if (typeof agentType !== "string" || !existsSync26(transcript))
|
|
80736
80969
|
continue;
|
|
80737
80970
|
const ran = modelsOf(transcript);
|
|
80738
80971
|
if (!ran.size)
|
|
@@ -80871,8 +81104,8 @@ var success2 = (data) => ({ ok: true, data }), failure3 = (code, error, unblock)
|
|
|
80871
81104
|
|
|
80872
81105
|
// packages/workit-core/src/git/ops.ts
|
|
80873
81106
|
import { spawnSync as spawnSync21 } from "node:child_process";
|
|
80874
|
-
import { existsSync as
|
|
80875
|
-
import
|
|
81107
|
+
import { existsSync as existsSync27, readFileSync as readFileSync28 } from "node:fs";
|
|
81108
|
+
import path62 from "node:path";
|
|
80876
81109
|
function operationInProgress(cwd) {
|
|
80877
81110
|
const markers = [
|
|
80878
81111
|
["rebase-merge", "rebase"],
|
|
@@ -80885,18 +81118,18 @@ function operationInProgress(cwd) {
|
|
|
80885
81118
|
if (!run.ok)
|
|
80886
81119
|
return null;
|
|
80887
81120
|
const found = run.stdout.split(`
|
|
80888
|
-
`).map((line) =>
|
|
81121
|
+
`).map((line) => path62.resolve(cwd, line.trim()));
|
|
80889
81122
|
const conflicted = () => git5(cwd, ["ls-files", "-u"]).stdout.trim() !== "";
|
|
80890
81123
|
for (const [index, [, operation]] of markers.entries()) {
|
|
80891
81124
|
const marker = found[index];
|
|
80892
|
-
if (!marker || !
|
|
81125
|
+
if (!marker || !existsSync27(marker))
|
|
80893
81126
|
continue;
|
|
80894
|
-
if (index === 1 &&
|
|
81127
|
+
if (index === 1 && existsSync27(path62.join(marker, "applying")))
|
|
80895
81128
|
return { operation: "am", commitAllowed: false, branch: null };
|
|
80896
|
-
if (index === 0 &&
|
|
81129
|
+
if (index === 0 && existsSync27(path62.join(marker, "amend")) && !conflicted()) {
|
|
80897
81130
|
let headName = "";
|
|
80898
81131
|
try {
|
|
80899
|
-
headName =
|
|
81132
|
+
headName = readFileSync28(path62.join(marker, "head-name"), "utf8").trim();
|
|
80900
81133
|
} catch {}
|
|
80901
81134
|
const branch = headName.startsWith("refs/heads/") ? headName.slice("refs/heads/".length) : null;
|
|
80902
81135
|
return { operation, commitAllowed: branch !== null, branch };
|
|
@@ -81231,7 +81464,7 @@ function gitCommit(cwd, input) {
|
|
|
81231
81464
|
if (paths.some((value) => value.startsWith("-") || !value.trim()))
|
|
81232
81465
|
return failure3("invalid_input", "paths must not be empty or start with -");
|
|
81233
81466
|
const tracked = new Set(nulList(git5(cwd, ["ls-files", "-z", "--", ...paths]).stdout));
|
|
81234
|
-
const addable = paths.filter((value) =>
|
|
81467
|
+
const addable = paths.filter((value) => existsSync27(path62.resolve(cwd, value)) || [...tracked].some((file) => file === value || file.startsWith(`${value}/`)));
|
|
81235
81468
|
if (addable.length) {
|
|
81236
81469
|
const added = git5(cwd, ["add", "-A", "--", ...addable]);
|
|
81237
81470
|
if (!added.ok)
|
|
@@ -81772,12 +82005,12 @@ var init_ops = __esm(() => {
|
|
|
81772
82005
|
|
|
81773
82006
|
// packages/workit-core/src/verdict-cover.ts
|
|
81774
82007
|
import fs26 from "node:fs";
|
|
81775
|
-
import
|
|
82008
|
+
import path63 from "node:path";
|
|
81776
82009
|
function chainsAbove(cwd, branch) {
|
|
81777
82010
|
const root = storeRoot(cwd);
|
|
81778
82011
|
if (!root.ok)
|
|
81779
82012
|
return [];
|
|
81780
|
-
const dir =
|
|
82013
|
+
const dir = path63.join(root.value.root, "stacks");
|
|
81781
82014
|
let names = [];
|
|
81782
82015
|
try {
|
|
81783
82016
|
names = fs26.readdirSync(dir).filter((name) => name.endsWith(".json"));
|
|
@@ -81788,7 +82021,7 @@ function chainsAbove(cwd, branch) {
|
|
|
81788
82021
|
for (const name of names.toSorted()) {
|
|
81789
82022
|
let parsed;
|
|
81790
82023
|
try {
|
|
81791
|
-
parsed = JSON.parse(fs26.readFileSync(
|
|
82024
|
+
parsed = JSON.parse(fs26.readFileSync(path63.join(dir, name), "utf8"));
|
|
81792
82025
|
} catch {
|
|
81793
82026
|
continue;
|
|
81794
82027
|
}
|
|
@@ -81944,10 +82177,10 @@ var init_check_evidence = __esm(() => {
|
|
|
81944
82177
|
|
|
81945
82178
|
// packages/workit-core/src/forge/reruns.ts
|
|
81946
82179
|
import fs27 from "node:fs";
|
|
81947
|
-
import
|
|
82180
|
+
import path64 from "node:path";
|
|
81948
82181
|
function rerunLogPath(cwd) {
|
|
81949
82182
|
const common = gitCommonDir(cwd);
|
|
81950
|
-
return common ?
|
|
82183
|
+
return common ? path64.join(common, "workit", "ci-reruns.jsonl") : null;
|
|
81951
82184
|
}
|
|
81952
82185
|
function rerunCounts(cwd, key) {
|
|
81953
82186
|
const counts = new Map;
|
|
@@ -81982,7 +82215,7 @@ function recordReruns(cwd, rows) {
|
|
|
81982
82215
|
if (!file)
|
|
81983
82216
|
return false;
|
|
81984
82217
|
try {
|
|
81985
|
-
fs27.mkdirSync(
|
|
82218
|
+
fs27.mkdirSync(path64.dirname(file), { recursive: true });
|
|
81986
82219
|
fs27.appendFileSync(file, rows.map((row) => `${JSON.stringify(row)}
|
|
81987
82220
|
`).join(""));
|
|
81988
82221
|
return true;
|
|
@@ -81995,7 +82228,7 @@ function withRerunLock(cwd, fn) {
|
|
|
81995
82228
|
if (!file)
|
|
81996
82229
|
return fn();
|
|
81997
82230
|
const lock = `${file.slice(0, -".jsonl".length)}.lock`;
|
|
81998
|
-
fs27.mkdirSync(
|
|
82231
|
+
fs27.mkdirSync(path64.dirname(lock), { recursive: true });
|
|
81999
82232
|
const until = Date.now() + LOCK_WAIT_MS2;
|
|
82000
82233
|
for (;; ) {
|
|
82001
82234
|
try {
|
|
@@ -82991,7 +83224,7 @@ var init_pr_ops = __esm(() => {
|
|
|
82991
83224
|
import { spawnSync as spawnSync23 } from "node:child_process";
|
|
82992
83225
|
import { createHash as createHash18, randomBytes as randomBytes4 } from "node:crypto";
|
|
82993
83226
|
import fs28 from "node:fs";
|
|
82994
|
-
import
|
|
83227
|
+
import path65 from "node:path";
|
|
82995
83228
|
function worktreeOf(cwd, branch) {
|
|
82996
83229
|
const list = gitRun3(cwd, ["worktree", "list", "--porcelain"]);
|
|
82997
83230
|
if (!list.ok)
|
|
@@ -83040,7 +83273,7 @@ function gitRestack(cwd, input) {
|
|
|
83040
83273
|
error: "no store root"
|
|
83041
83274
|
};
|
|
83042
83275
|
fs28.mkdirSync(scratch, { recursive: true });
|
|
83043
|
-
dir =
|
|
83276
|
+
dir = path65.join(scratch, `${input.branch.replace(/[^A-Za-z0-9._-]+/gu, "_").slice(0, 40)}-${randomBytes4(4).toString("hex")}`);
|
|
83044
83277
|
const added = gitRun3(cwd, ["worktree", "add", "-q", dir, input.branch], GIT_TIMEOUTS.worktree);
|
|
83045
83278
|
if (!added.ok)
|
|
83046
83279
|
return {
|
|
@@ -83096,7 +83329,7 @@ function pruneScratch(cwd) {
|
|
|
83096
83329
|
if (!scratch || !fs28.existsSync(scratch))
|
|
83097
83330
|
return;
|
|
83098
83331
|
for (const name of fs28.readdirSync(scratch)) {
|
|
83099
|
-
const dir =
|
|
83332
|
+
const dir = path65.join(scratch, name);
|
|
83100
83333
|
if (!rebaseInProgress(dir) && !trackedDirt(dir))
|
|
83101
83334
|
gitRun3(cwd, ["worktree", "remove", "--force", dir]);
|
|
83102
83335
|
}
|
|
@@ -83106,7 +83339,7 @@ function stacksDir(cwd) {
|
|
|
83106
83339
|
const root = storeRoot(cwd);
|
|
83107
83340
|
if (!root.ok)
|
|
83108
83341
|
return stackFail(root.code, root.error, root.unblock);
|
|
83109
|
-
return { ok: true, data:
|
|
83342
|
+
return { ok: true, data: path65.join(root.value.root, "stacks") };
|
|
83110
83343
|
}
|
|
83111
83344
|
function parseStack(raw) {
|
|
83112
83345
|
if (!isRecord12(raw) || !Array.isArray(raw.branches))
|
|
@@ -83158,7 +83391,7 @@ function readStack(cwd, name) {
|
|
|
83158
83391
|
const dir = stacksDir(cwd);
|
|
83159
83392
|
if (!dir.ok)
|
|
83160
83393
|
return dir;
|
|
83161
|
-
const file =
|
|
83394
|
+
const file = path65.join(dir.data, fileFor(name));
|
|
83162
83395
|
let text;
|
|
83163
83396
|
try {
|
|
83164
83397
|
text = fs28.readFileSync(file, "utf8");
|
|
@@ -83179,7 +83412,7 @@ function writeStack(cwd, stack, now = new Date) {
|
|
|
83179
83412
|
const dir = stacksDir(cwd);
|
|
83180
83413
|
if (!dir.ok)
|
|
83181
83414
|
return dir;
|
|
83182
|
-
const file =
|
|
83415
|
+
const file = path65.join(dir.data, fileFor(stack.name));
|
|
83183
83416
|
const temp = `${file}.${process.pid}.tmp`;
|
|
83184
83417
|
try {
|
|
83185
83418
|
fs28.mkdirSync(dir.data, { recursive: true });
|
|
@@ -83207,7 +83440,7 @@ function listStacks(cwd) {
|
|
|
83207
83440
|
for (const name of names) {
|
|
83208
83441
|
let parsed = null;
|
|
83209
83442
|
try {
|
|
83210
|
-
parsed = parseStack(JSON.parse(fs28.readFileSync(
|
|
83443
|
+
parsed = parseStack(JSON.parse(fs28.readFileSync(path65.join(dir.data, name), "utf8")));
|
|
83211
83444
|
} catch {
|
|
83212
83445
|
parsed = null;
|
|
83213
83446
|
}
|
|
@@ -83269,7 +83502,7 @@ function takeLock(lock) {
|
|
|
83269
83502
|
host: localLockHost(),
|
|
83270
83503
|
nonce: randomBytes4(8).toString("hex")
|
|
83271
83504
|
};
|
|
83272
|
-
fs28.writeFileSync(
|
|
83505
|
+
fs28.writeFileSync(path65.join(lock, OWNER), JSON.stringify(owner));
|
|
83273
83506
|
return owner;
|
|
83274
83507
|
}
|
|
83275
83508
|
function reapLock(lock, observed) {
|
|
@@ -83306,7 +83539,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
|
|
|
83306
83539
|
return dir;
|
|
83307
83540
|
if (!validName(name))
|
|
83308
83541
|
return stackFail("invalid_input", "a stack name must be 1-200 printable characters");
|
|
83309
|
-
const lock =
|
|
83542
|
+
const lock = path65.join(dir.data, `${fileFor(name)}.lock`);
|
|
83310
83543
|
try {
|
|
83311
83544
|
fs28.mkdirSync(dir.data, { recursive: true });
|
|
83312
83545
|
} catch (error) {
|
|
@@ -83336,7 +83569,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
|
|
|
83336
83569
|
const touch = () => {
|
|
83337
83570
|
try {
|
|
83338
83571
|
const now = new Date;
|
|
83339
|
-
fs28.utimesSync(
|
|
83572
|
+
fs28.utimesSync(path65.join(lock, OWNER), now, now);
|
|
83340
83573
|
} catch {}
|
|
83341
83574
|
};
|
|
83342
83575
|
const beat = setInterval(touch, HEARTBEAT_MS);
|
|
@@ -84305,7 +84538,7 @@ var STACK_VERSION = 1, stackFail = (code, error, unblock, data) => ({
|
|
|
84305
84538
|
return !status.ok || status.stdout.trim() !== "";
|
|
84306
84539
|
}, scratchDir = (cwd) => {
|
|
84307
84540
|
const dir = stacksDir(cwd);
|
|
84308
|
-
return dir.ok ?
|
|
84541
|
+
return dir.ok ? path65.join(dir.data, "worktrees") : null;
|
|
84309
84542
|
}, firstLine = (run) => (`${run.stderr}
|
|
84310
84543
|
${run.stdout}`.split(`
|
|
84311
84544
|
`).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) => {
|
|
@@ -84320,12 +84553,12 @@ ${run.stdout}`.split(`
|
|
|
84320
84553
|
}, 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) => {
|
|
84321
84554
|
let raw = null;
|
|
84322
84555
|
try {
|
|
84323
|
-
raw = fs28.readFileSync(
|
|
84556
|
+
raw = fs28.readFileSync(path65.join(lock, OWNER), "utf8");
|
|
84324
84557
|
} catch {
|
|
84325
84558
|
raw = null;
|
|
84326
84559
|
}
|
|
84327
84560
|
let age = null;
|
|
84328
|
-
for (const target of [
|
|
84561
|
+
for (const target of [path65.join(lock, OWNER), lock])
|
|
84329
84562
|
try {
|
|
84330
84563
|
age = Date.now() - fs28.statSync(target).mtimeMs;
|
|
84331
84564
|
break;
|
|
@@ -84369,7 +84602,7 @@ var init_stack = __esm(() => {
|
|
|
84369
84602
|
import { spawnSync as spawnSync24 } from "node:child_process";
|
|
84370
84603
|
import { createHash as createHash19 } from "node:crypto";
|
|
84371
84604
|
import fs29 from "node:fs";
|
|
84372
|
-
import
|
|
84605
|
+
import path66 from "node:path";
|
|
84373
84606
|
function expandBraces2(pattern, limit = 64) {
|
|
84374
84607
|
for (let index = 0;index < pattern.length; index += 1) {
|
|
84375
84608
|
if (pattern[index] === "\\") {
|
|
@@ -84615,7 +84848,7 @@ function parsePlan(raw, defaults, name) {
|
|
|
84615
84848
|
id,
|
|
84616
84849
|
branch,
|
|
84617
84850
|
base: optional("base") ?? "",
|
|
84618
|
-
worktree:
|
|
84851
|
+
worktree: path66.resolve(defaults.root, optional("worktree") ?? path66.join(defaults.worktreeRoot, id)),
|
|
84619
84852
|
tier,
|
|
84620
84853
|
reason,
|
|
84621
84854
|
dependsOn: [...new Set(dependsOn ?? [])],
|
|
@@ -84744,12 +84977,12 @@ function regeneratedFiles(root, tracked) {
|
|
|
84744
84977
|
const found = new Map;
|
|
84745
84978
|
let scripts;
|
|
84746
84979
|
try {
|
|
84747
|
-
const manifest = JSON.parse(fs29.readFileSync(
|
|
84980
|
+
const manifest = JSON.parse(fs29.readFileSync(path66.join(root, "package.json"), "utf8"));
|
|
84748
84981
|
scripts = manifest.scripts ?? {};
|
|
84749
84982
|
} catch {
|
|
84750
84983
|
return found;
|
|
84751
84984
|
}
|
|
84752
|
-
const runner = fs29.existsSync(
|
|
84985
|
+
const runner = fs29.existsSync(path66.join(root, "bun.lock")) ? "bun run" : fs29.existsSync(path66.join(root, "pnpm-lock.yaml")) ? "pnpm run" : fs29.existsSync(path66.join(root, "yarn.lock")) ? "yarn run" : "npm run";
|
|
84753
84986
|
const outputs = tracked.filter((file) => !CODE.test(file));
|
|
84754
84987
|
for (const [name, command] of Object.entries(scripts)) {
|
|
84755
84988
|
if (!name.startsWith("write:") || typeof command !== "string")
|
|
@@ -84757,7 +84990,7 @@ function regeneratedFiles(root, tracked) {
|
|
|
84757
84990
|
for (const file of command.match(/[\w./-]+\.[cm]?[jt]s\b/gu) ?? []) {
|
|
84758
84991
|
let source;
|
|
84759
84992
|
try {
|
|
84760
|
-
source = fs29.readFileSync(
|
|
84993
|
+
source = fs29.readFileSync(path66.join(root, file), "utf8");
|
|
84761
84994
|
} catch {
|
|
84762
84995
|
continue;
|
|
84763
84996
|
}
|
|
@@ -84879,11 +85112,11 @@ function defaultTrunk(cwd) {
|
|
|
84879
85112
|
}
|
|
84880
85113
|
function mainCheckout(cwd) {
|
|
84881
85114
|
const common = gitCommonDir(cwd);
|
|
84882
|
-
return common &&
|
|
85115
|
+
return common && path66.basename(common) === ".git" ? path66.dirname(common) : path66.resolve(cwd);
|
|
84883
85116
|
}
|
|
84884
85117
|
function worktreeRoot(cwd) {
|
|
84885
85118
|
const main = mainCheckout(cwd);
|
|
84886
|
-
return
|
|
85119
|
+
return path66.join(path66.dirname(main), `${path66.basename(main)}-wt`);
|
|
84887
85120
|
}
|
|
84888
85121
|
function sliceHash(slice) {
|
|
84889
85122
|
const {
|
|
@@ -84903,7 +85136,7 @@ function fanoutsDir(cwd) {
|
|
|
84903
85136
|
const root = storeRoot(cwd);
|
|
84904
85137
|
if (!root.ok)
|
|
84905
85138
|
return fanoutFail(root.code, root.error, root.unblock);
|
|
84906
|
-
return { ok: true, data:
|
|
85139
|
+
return { ok: true, data: path66.join(root.value.root, "fanouts") };
|
|
84907
85140
|
}
|
|
84908
85141
|
function parseStored(raw) {
|
|
84909
85142
|
if (!isRecord13(raw) || typeof raw.name !== "string" || typeof raw.trunk !== "string")
|
|
@@ -84971,7 +85204,7 @@ function readFanout(cwd, name) {
|
|
|
84971
85204
|
const dir = fanoutsDir(cwd);
|
|
84972
85205
|
if (!dir.ok)
|
|
84973
85206
|
return dir;
|
|
84974
|
-
const file =
|
|
85207
|
+
const file = path66.join(dir.data, stackFileName(name));
|
|
84975
85208
|
let parsed = null;
|
|
84976
85209
|
try {
|
|
84977
85210
|
parsed = parseStored(JSON.parse(fs29.readFileSync(file, "utf8")));
|
|
@@ -84996,7 +85229,7 @@ function listFanouts(cwd) {
|
|
|
84996
85229
|
for (const entry of names) {
|
|
84997
85230
|
let parsed = null;
|
|
84998
85231
|
try {
|
|
84999
|
-
parsed = parseStored(JSON.parse(fs29.readFileSync(
|
|
85232
|
+
parsed = parseStored(JSON.parse(fs29.readFileSync(path66.join(dir.data, entry), "utf8")));
|
|
85000
85233
|
} catch {
|
|
85001
85234
|
parsed = null;
|
|
85002
85235
|
}
|
|
@@ -85035,7 +85268,7 @@ function writeFanout(cwd, plan) {
|
|
|
85035
85268
|
const dir = fanoutsDir(cwd);
|
|
85036
85269
|
if (!dir.ok)
|
|
85037
85270
|
return dir;
|
|
85038
|
-
const file =
|
|
85271
|
+
const file = path66.join(dir.data, stackFileName(plan.name));
|
|
85039
85272
|
const temp = `${file}.${process.pid}.tmp`;
|
|
85040
85273
|
try {
|
|
85041
85274
|
fs29.mkdirSync(dir.data, { recursive: true });
|
|
@@ -85246,13 +85479,13 @@ var init_fanout = __esm(() => {
|
|
|
85246
85479
|
// packages/workit-core/src/forge/exec.ts
|
|
85247
85480
|
import { spawnSync as spawnSync25 } from "node:child_process";
|
|
85248
85481
|
import fs30 from "node:fs";
|
|
85249
|
-
import
|
|
85482
|
+
import path67 from "node:path";
|
|
85250
85483
|
function findExecutable(bin, env) {
|
|
85251
|
-
const dirs = (env.PATH ?? env.Path ?? "").split(
|
|
85484
|
+
const dirs = (env.PATH ?? env.Path ?? "").split(path67.delimiter).filter(Boolean);
|
|
85252
85485
|
const exts = process.platform === "win32" ? [".exe"] : [""];
|
|
85253
85486
|
for (const dir of dirs)
|
|
85254
85487
|
for (const ext of exts) {
|
|
85255
|
-
const candidate =
|
|
85488
|
+
const candidate = path67.join(dir, `${bin}${ext}`);
|
|
85256
85489
|
try {
|
|
85257
85490
|
const stat = fs30.statSync(candidate);
|
|
85258
85491
|
if (stat.isFile())
|
|
@@ -87042,7 +87275,7 @@ var init_live_session = __esm(() => {
|
|
|
87042
87275
|
});
|
|
87043
87276
|
|
|
87044
87277
|
// packages/workit-core/src/hooks/write-gate.ts
|
|
87045
|
-
import
|
|
87278
|
+
import path68 from "node:path";
|
|
87046
87279
|
var CASE_INSENSITIVE, PREFIXES2, SCRIPT_SHELLS, cache3, MUTATING_GIT, DRY_N, MUTATING_WORKIT_GIT, CD2, PUSHD2, POPD2, UNKNOWN_DIR;
|
|
87047
87280
|
var init_write_gate = __esm(() => {
|
|
87048
87281
|
init_task_store();
|
|
@@ -87082,7 +87315,7 @@ var init_write_gate = __esm(() => {
|
|
|
87082
87315
|
CD2 = new Set(["cd", "chdir", "set-location", "sl"]);
|
|
87083
87316
|
PUSHD2 = new Set(["pushd", "push-location"]);
|
|
87084
87317
|
POPD2 = new Set(["popd", "pop-location"]);
|
|
87085
|
-
UNKNOWN_DIR =
|
|
87318
|
+
UNKNOWN_DIR = path68.resolve(path68.parse(process.cwd()).root, ".workit-unknown-dir");
|
|
87086
87319
|
});
|
|
87087
87320
|
|
|
87088
87321
|
// packages/workit-core/src/hooks/worktree-confine.ts
|
|
@@ -87107,20 +87340,20 @@ var init_worktree_confine = __esm(() => {
|
|
|
87107
87340
|
|
|
87108
87341
|
// packages/workit-core/src/worktree-deps.ts
|
|
87109
87342
|
import fs31 from "node:fs";
|
|
87110
|
-
import
|
|
87343
|
+
import path69 from "node:path";
|
|
87111
87344
|
function moduleDirs(main) {
|
|
87112
87345
|
const out = [];
|
|
87113
87346
|
const walk = (relative, depth) => {
|
|
87114
87347
|
let entries;
|
|
87115
87348
|
try {
|
|
87116
|
-
entries = fs31.readdirSync(
|
|
87349
|
+
entries = fs31.readdirSync(path69.join(main, relative), { withFileTypes: true });
|
|
87117
87350
|
} catch {
|
|
87118
87351
|
return;
|
|
87119
87352
|
}
|
|
87120
87353
|
for (const entry of entries) {
|
|
87121
87354
|
if (!entry.isDirectory())
|
|
87122
87355
|
continue;
|
|
87123
|
-
const child =
|
|
87356
|
+
const child = path69.join(relative, entry.name);
|
|
87124
87357
|
if (entry.name === MODULES)
|
|
87125
87358
|
out.push(child);
|
|
87126
87359
|
else if (depth < MAX_DEPTH2 && !entry.name.startsWith("."))
|
|
@@ -87134,8 +87367,8 @@ function linkEntry(main, worktree, source, target) {
|
|
|
87134
87367
|
const stat = fs31.lstatSync(source);
|
|
87135
87368
|
if (stat.isSymbolicLink()) {
|
|
87136
87369
|
const link = fs31.readlinkSync(source);
|
|
87137
|
-
const outside =
|
|
87138
|
-
const to = outside ?
|
|
87370
|
+
const outside = path69.isAbsolute(link) && within(link, main) && !path69.relative(main, link).split(path69.sep).includes(MODULES);
|
|
87371
|
+
const to = outside ? path69.join(worktree, path69.relative(main, link)) : link;
|
|
87139
87372
|
fs31.symlinkSync(to, target, process.platform === "win32" ? "junction" : undefined);
|
|
87140
87373
|
return;
|
|
87141
87374
|
}
|
|
@@ -87145,8 +87378,8 @@ function mirror(main, worktree, source, target, top) {
|
|
|
87145
87378
|
fs31.mkdirSync(target);
|
|
87146
87379
|
let count = 0;
|
|
87147
87380
|
for (const entry of fs31.readdirSync(source, { withFileTypes: true })) {
|
|
87148
|
-
const from =
|
|
87149
|
-
const to =
|
|
87381
|
+
const from = path69.join(source, entry.name);
|
|
87382
|
+
const to = path69.join(target, entry.name);
|
|
87150
87383
|
if (top && entry.isDirectory() && (entry.name.startsWith("@") || entry.name === ".bin"))
|
|
87151
87384
|
count += mirror(main, worktree, from, to, false);
|
|
87152
87385
|
else {
|
|
@@ -87162,16 +87395,16 @@ function linkWorktreeDependencies(main, worktree) {
|
|
|
87162
87395
|
const dirs = [];
|
|
87163
87396
|
let entries = 0;
|
|
87164
87397
|
for (const relative of moduleDirs(main)) {
|
|
87165
|
-
const target =
|
|
87166
|
-
if (!fs31.existsSync(
|
|
87398
|
+
const target = path69.join(worktree, relative);
|
|
87399
|
+
if (!fs31.existsSync(path69.dirname(target)) || fs31.existsSync(target))
|
|
87167
87400
|
continue;
|
|
87168
|
-
if (!gitRun4(worktree, ["check-ignore", "-q", `${relative.split(
|
|
87169
|
-
notes.push(`${relative.split(
|
|
87401
|
+
if (!gitRun4(worktree, ["check-ignore", "-q", `${relative.split(path69.sep).join("/")}/`]).ok) {
|
|
87402
|
+
notes.push(`${relative.split(path69.sep).join("/")} is not ignored by git, so it was not linked from ${main}; install dependencies in the worktree yourself`);
|
|
87170
87403
|
continue;
|
|
87171
87404
|
}
|
|
87172
87405
|
try {
|
|
87173
|
-
entries += mirror(main, worktree,
|
|
87174
|
-
dirs.push(relative.split(
|
|
87406
|
+
entries += mirror(main, worktree, path69.join(main, relative), target, true);
|
|
87407
|
+
dirs.push(relative.split(path69.sep).join("/"));
|
|
87175
87408
|
} catch (error) {
|
|
87176
87409
|
fs31.rmSync(target, { recursive: true, force: true });
|
|
87177
87410
|
notes.push(`could not link ${relative} from ${main} (${error.message}); install dependencies in the worktree yourself`);
|
|
@@ -87184,8 +87417,8 @@ function linkWorktreeDependencies(main, worktree) {
|
|
|
87184
87417
|
return { linked: { from: main, dirs, entries, ms }, notes };
|
|
87185
87418
|
}
|
|
87186
87419
|
var MODULES = "node_modules", MAX_DEPTH2 = 2, within = (child, parent) => {
|
|
87187
|
-
const relative =
|
|
87188
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
87420
|
+
const relative = path69.relative(parent, child);
|
|
87421
|
+
return relative === "" || !relative.startsWith("..") && !path69.isAbsolute(relative);
|
|
87189
87422
|
};
|
|
87190
87423
|
var init_worktree_deps = __esm(() => {
|
|
87191
87424
|
init_fanout();
|
|
@@ -87194,7 +87427,7 @@ var init_worktree_deps = __esm(() => {
|
|
|
87194
87427
|
// packages/workit-core/src/fanout-worktree.ts
|
|
87195
87428
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
87196
87429
|
import fs32 from "node:fs";
|
|
87197
|
-
import
|
|
87430
|
+
import path70 from "node:path";
|
|
87198
87431
|
function rowSample(lines) {
|
|
87199
87432
|
const out = [];
|
|
87200
87433
|
let bytes = 0;
|
|
@@ -87254,7 +87487,7 @@ function adminDir(worktree) {
|
|
|
87254
87487
|
const file = dir.stdout.trim();
|
|
87255
87488
|
let token = null;
|
|
87256
87489
|
try {
|
|
87257
|
-
token = fs32.readFileSync(
|
|
87490
|
+
token = fs32.readFileSync(path70.join(file, FANOUT_TOKEN_FILE), "utf8").trim() || null;
|
|
87258
87491
|
} catch {
|
|
87259
87492
|
token = null;
|
|
87260
87493
|
}
|
|
@@ -87262,7 +87495,7 @@ function adminDir(worktree) {
|
|
|
87262
87495
|
const stat = worktreeDeps.stat(file);
|
|
87263
87496
|
return {
|
|
87264
87497
|
path: file,
|
|
87265
|
-
id:
|
|
87498
|
+
id: path70.basename(file),
|
|
87266
87499
|
ino: stat.ino.toString(),
|
|
87267
87500
|
token,
|
|
87268
87501
|
birthMs: stat.birthtimeNs > 0n ? Number(stat.birthtimeMs) : null,
|
|
@@ -87278,7 +87511,7 @@ function markAdminDir(worktree) {
|
|
|
87278
87511
|
return null;
|
|
87279
87512
|
const token = randomBytes5(16).toString("hex");
|
|
87280
87513
|
try {
|
|
87281
|
-
fs32.writeFileSync(
|
|
87514
|
+
fs32.writeFileSync(path70.join(admin.path, FANOUT_TOKEN_FILE), `${token}
|
|
87282
87515
|
`);
|
|
87283
87516
|
} catch {
|
|
87284
87517
|
return null;
|
|
@@ -87293,7 +87526,7 @@ function excludeScratch(cwd) {
|
|
|
87293
87526
|
const common = gitCommonDir(cwd);
|
|
87294
87527
|
if (!common)
|
|
87295
87528
|
return;
|
|
87296
|
-
const file =
|
|
87529
|
+
const file = path70.join(common, "info", "exclude");
|
|
87297
87530
|
let text = "";
|
|
87298
87531
|
try {
|
|
87299
87532
|
text = fs32.readFileSync(file, "utf8");
|
|
@@ -87302,7 +87535,7 @@ function excludeScratch(cwd) {
|
|
|
87302
87535
|
}
|
|
87303
87536
|
if (text.split(/\r?\n/u).includes(EXCLUDE_LINE))
|
|
87304
87537
|
return;
|
|
87305
|
-
fs32.mkdirSync(
|
|
87538
|
+
fs32.mkdirSync(path70.dirname(file), { recursive: true });
|
|
87306
87539
|
fs32.appendFileSync(file, `${text && !text.endsWith(`
|
|
87307
87540
|
`) ? `
|
|
87308
87541
|
` : ""}# workit fanout: per-worker scratch dirs
|
|
@@ -87311,13 +87544,13 @@ ${EXCLUDE_LINE}
|
|
|
87311
87544
|
}
|
|
87312
87545
|
function worktreeDependencies(main, worktree) {
|
|
87313
87546
|
for (const [name, install] of LOCKFILES2) {
|
|
87314
|
-
const ours = readBytes(
|
|
87315
|
-
const theirs = readBytes(
|
|
87547
|
+
const ours = readBytes(path70.join(main, name));
|
|
87548
|
+
const theirs = readBytes(path70.join(worktree, name));
|
|
87316
87549
|
if (ours === null && theirs === null)
|
|
87317
87550
|
continue;
|
|
87318
87551
|
if (ours !== null && theirs !== null && ours.equals(theirs))
|
|
87319
87552
|
continue;
|
|
87320
|
-
if (fs32.existsSync(
|
|
87553
|
+
if (fs32.existsSync(path70.join(worktree, "node_modules")))
|
|
87321
87554
|
break;
|
|
87322
87555
|
const command = install(worktree);
|
|
87323
87556
|
return {
|
|
@@ -87329,7 +87562,7 @@ function worktreeDependencies(main, worktree) {
|
|
|
87329
87562
|
};
|
|
87330
87563
|
}
|
|
87331
87564
|
const stale = staleBunInstall(main);
|
|
87332
|
-
if (stale && !fs32.existsSync(
|
|
87565
|
+
if (stale && !fs32.existsSync(path70.join(worktree, "node_modules"))) {
|
|
87333
87566
|
const command = `bun install --frozen-lockfile --cwd ${worktree}`;
|
|
87334
87567
|
return {
|
|
87335
87568
|
linked: null,
|
|
@@ -87342,9 +87575,9 @@ function worktreeDependencies(main, worktree) {
|
|
|
87342
87575
|
return { ...linkWorktreeDependencies(main, worktree), install: null };
|
|
87343
87576
|
}
|
|
87344
87577
|
function staleBunInstall(main) {
|
|
87345
|
-
if (!fs32.existsSync(
|
|
87578
|
+
if (!fs32.existsSync(path70.join(main, "node_modules")))
|
|
87346
87579
|
return null;
|
|
87347
|
-
const text = readBytes(
|
|
87580
|
+
const text = readBytes(path70.join(main, "bun.lock"))?.toString("utf8");
|
|
87348
87581
|
if (!text)
|
|
87349
87582
|
return null;
|
|
87350
87583
|
let packages;
|
|
@@ -87371,7 +87604,7 @@ function staleBunInstall(main) {
|
|
|
87371
87604
|
const version = spec.slice(at + 1);
|
|
87372
87605
|
if (name !== key || version.includes(":"))
|
|
87373
87606
|
continue;
|
|
87374
|
-
const manifest = readBytes(
|
|
87607
|
+
const manifest = readBytes(path70.join(main, "node_modules", key, "package.json"));
|
|
87375
87608
|
if (!manifest) {
|
|
87376
87609
|
problems.push(`${key} missing`);
|
|
87377
87610
|
continue;
|
|
@@ -87388,7 +87621,7 @@ function staleBunInstall(main) {
|
|
|
87388
87621
|
return problems.length ? problems.join("; ") : null;
|
|
87389
87622
|
}
|
|
87390
87623
|
function ensureScratch(worktree) {
|
|
87391
|
-
const scratch =
|
|
87624
|
+
const scratch = path70.join(worktree, SCRATCH_DIR);
|
|
87392
87625
|
fs32.mkdirSync(scratch, { recursive: true });
|
|
87393
87626
|
return scratch;
|
|
87394
87627
|
}
|
|
@@ -87662,7 +87895,7 @@ function unpushedCount(cwd, branch) {
|
|
|
87662
87895
|
return count.ok ? Number(count.stdout.trim()) : null;
|
|
87663
87896
|
}
|
|
87664
87897
|
function removeScratch(worktree) {
|
|
87665
|
-
const scratch =
|
|
87898
|
+
const scratch = path70.join(worktree, SCRATCH_DIR);
|
|
87666
87899
|
let stat;
|
|
87667
87900
|
try {
|
|
87668
87901
|
stat = fs32.lstatSync(scratch);
|
|
@@ -87678,16 +87911,16 @@ var SLOW, SCRATCH_DIR = ".workit-scratch", EXCLUDE_LINE, DIRTY_ROW_BYTES = 2000,
|
|
|
87678
87911
|
try {
|
|
87679
87912
|
return fs32.realpathSync.native(target);
|
|
87680
87913
|
} catch {
|
|
87681
|
-
return
|
|
87914
|
+
return path70.resolve(target);
|
|
87682
87915
|
}
|
|
87683
87916
|
}, samePath = (a, b) => {
|
|
87684
87917
|
const left = canonical2(a);
|
|
87685
87918
|
const right = canonical2(b);
|
|
87686
87919
|
return process.platform === "win32" || process.platform === "darwin" ? left.toLowerCase() === right.toLowerCase() : left === right;
|
|
87687
87920
|
}, inside3 = (child, parent) => {
|
|
87688
|
-
const relative =
|
|
87689
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
87690
|
-
}, slicePath = (cwd, slice) =>
|
|
87921
|
+
const relative = path70.relative(canonical2(parent), canonical2(child));
|
|
87922
|
+
return relative === "" || !relative.startsWith("..") && !path70.isAbsolute(relative);
|
|
87923
|
+
}, slicePath = (cwd, slice) => path70.isAbsolute(slice.worktree) ? slice.worktree : path70.resolve(mainCheckout(cwd), slice.worktree), CLOCK_SLACK_MS = 2000, worktreeDeps, LOCKFILES2, readBytes = (file) => {
|
|
87691
87924
|
try {
|
|
87692
87925
|
return fs32.readFileSync(file);
|
|
87693
87926
|
} catch {
|
|
@@ -87719,7 +87952,7 @@ var init_fanout_worktree = __esm(() => {
|
|
|
87719
87952
|
|
|
87720
87953
|
// packages/workit-core/src/forge/merge-cleanup.ts
|
|
87721
87954
|
import fs33 from "node:fs";
|
|
87722
|
-
import
|
|
87955
|
+
import path71 from "node:path";
|
|
87723
87956
|
function cleanupMergedBranch(cwd, branch, mergedHead) {
|
|
87724
87957
|
const out = { branchDeleted: false, worktreeRemoved: null, notes: [] };
|
|
87725
87958
|
if (!branch || branch.startsWith("-"))
|
|
@@ -87779,13 +88012,13 @@ var SLOW2, isFanoutWorktree = (worktree) => {
|
|
|
87779
88012
|
if (!dir.ok)
|
|
87780
88013
|
return false;
|
|
87781
88014
|
try {
|
|
87782
|
-
return fs33.readFileSync(
|
|
88015
|
+
return fs33.readFileSync(path71.join(dir.stdout.trim(), FANOUT_TOKEN_FILE), "utf8").trim() !== "";
|
|
87783
88016
|
} catch {
|
|
87784
88017
|
return false;
|
|
87785
88018
|
}
|
|
87786
88019
|
}, inside4 = (child, parent) => {
|
|
87787
|
-
const relative =
|
|
87788
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
88020
|
+
const relative = path71.relative(fs33.realpathSync.native(parent), fs33.realpathSync.native(child));
|
|
88021
|
+
return relative === "" || !relative.startsWith("..") && !path71.isAbsolute(relative);
|
|
87789
88022
|
};
|
|
87790
88023
|
var init_merge_cleanup = __esm(() => {
|
|
87791
88024
|
init_fanout();
|
|
@@ -88066,7 +88299,7 @@ var init_duration = __esm(() => {
|
|
|
88066
88299
|
});
|
|
88067
88300
|
|
|
88068
88301
|
// packages/workit-cli/src/verbs/forge-common.ts
|
|
88069
|
-
import { readFileSync as
|
|
88302
|
+
import { readFileSync as readFileSync29 } from "node:fs";
|
|
88070
88303
|
function parseFlags(argv, spec) {
|
|
88071
88304
|
const parsed = { values: {}, booleans: new Set, lists: {}, positionals: [] };
|
|
88072
88305
|
for (let index = 0;index < argv.length; index += 1) {
|
|
@@ -88224,7 +88457,7 @@ var init_forge_common = __esm(() => {
|
|
|
88224
88457
|
forgeDeps = {
|
|
88225
88458
|
runner: undefined,
|
|
88226
88459
|
npm: undefined,
|
|
88227
|
-
readStdin: () =>
|
|
88460
|
+
readStdin: () => readFileSync29(0, "utf8"),
|
|
88228
88461
|
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
88229
88462
|
now: () => Date.now()
|
|
88230
88463
|
};
|
|
@@ -88236,8 +88469,8 @@ __export(exports_pr, {
|
|
|
88236
88469
|
checkPrTitle: () => checkPrTitle,
|
|
88237
88470
|
run: () => run15
|
|
88238
88471
|
});
|
|
88239
|
-
import { existsSync as
|
|
88240
|
-
import
|
|
88472
|
+
import { existsSync as existsSync28, readFileSync as readFileSync30 } from "node:fs";
|
|
88473
|
+
import path72 from "node:path";
|
|
88241
88474
|
function titleRules(cwd) {
|
|
88242
88475
|
let root;
|
|
88243
88476
|
try {
|
|
@@ -88248,16 +88481,16 @@ function titleRules(cwd) {
|
|
|
88248
88481
|
let text = null;
|
|
88249
88482
|
let name = "";
|
|
88250
88483
|
for (const candidate of COMMITLINT_FILES) {
|
|
88251
|
-
const full =
|
|
88252
|
-
if (!
|
|
88484
|
+
const full = path72.join(root, candidate);
|
|
88485
|
+
if (!existsSync28(full))
|
|
88253
88486
|
continue;
|
|
88254
|
-
text =
|
|
88487
|
+
text = readFileSync30(full, "utf8");
|
|
88255
88488
|
name = candidate;
|
|
88256
88489
|
break;
|
|
88257
88490
|
}
|
|
88258
88491
|
if (text === null) {
|
|
88259
88492
|
try {
|
|
88260
|
-
const pkg = JSON.parse(
|
|
88493
|
+
const pkg = JSON.parse(readFileSync30(path72.join(root, "package.json"), "utf8"));
|
|
88261
88494
|
if (pkg.commitlint === undefined)
|
|
88262
88495
|
return { rules: null, note: null };
|
|
88263
88496
|
text = JSON.stringify(pkg.commitlint);
|
|
@@ -88354,7 +88587,7 @@ function refuseTitle(io, title, line) {
|
|
|
88354
88587
|
function readBodyFile(io, file) {
|
|
88355
88588
|
try {
|
|
88356
88589
|
return {
|
|
88357
|
-
body: file === "-" ? forgeDeps.readStdin() :
|
|
88590
|
+
body: file === "-" ? forgeDeps.readStdin() : readFileSync30(path72.resolve(io.cwd, file), "utf8")
|
|
88358
88591
|
};
|
|
88359
88592
|
} catch {
|
|
88360
88593
|
return `cannot read --body-file ${file}`;
|
|
@@ -89243,8 +89476,8 @@ var exports_git = {};
|
|
|
89243
89476
|
__export(exports_git, {
|
|
89244
89477
|
run: () => run17
|
|
89245
89478
|
});
|
|
89246
|
-
import { readFileSync as
|
|
89247
|
-
import
|
|
89479
|
+
import { readFileSync as readFileSync31 } from "node:fs";
|
|
89480
|
+
import path73 from "node:path";
|
|
89248
89481
|
function kindHint(cwd, kind) {
|
|
89249
89482
|
let kinds = [...BRANCH_KINDS];
|
|
89250
89483
|
try {
|
|
@@ -89348,7 +89581,7 @@ function commitMessage(parsed, io) {
|
|
|
89348
89581
|
|
|
89349
89582
|
`);
|
|
89350
89583
|
try {
|
|
89351
|
-
return file === "-" ?
|
|
89584
|
+
return file === "-" ? readFileSync31(0, "utf8") : readFileSync31(path73.resolve(io.cwd, file), "utf8");
|
|
89352
89585
|
} catch (error) {
|
|
89353
89586
|
return {
|
|
89354
89587
|
error: `cannot read -F ${file}: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -90812,7 +91045,7 @@ var init_stack2 = __esm(() => {
|
|
|
90812
91045
|
// packages/workit-core/src/fanout-brief.ts
|
|
90813
91046
|
import { createHash as createHash20 } from "node:crypto";
|
|
90814
91047
|
import fs35 from "node:fs";
|
|
90815
|
-
import
|
|
91048
|
+
import path74 from "node:path";
|
|
90816
91049
|
function workerSession(lead, slice, attempt) {
|
|
90817
91050
|
const tail = attempt === null ? "" : `+try${attempt}`;
|
|
90818
91051
|
const full = `${lead}-w-${slice}${tail}`;
|
|
@@ -90895,7 +91128,7 @@ function renderBrief(cwd, plan, input) {
|
|
|
90895
91128
|
"STANDING:",
|
|
90896
91129
|
...standing.length ? standing.map((order) => ` - ${order.what}`) : [" - none recorded beyond this brief"],
|
|
90897
91130
|
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)`,
|
|
90898
|
-
...exists && typeof made?.install === "string" && !fs35.existsSync(
|
|
91131
|
+
...exists && typeof made?.install === "string" && !fs35.existsSync(path74.join(planned, "node_modules")) ? [`INSTALL: \`${made.install}\` first: the main checkout's node_modules was not linked here`] : [],
|
|
90899
91132
|
...identityLines(identity, minted),
|
|
90900
91133
|
...rules(mode, branch, sliceBase, exists ? planned : null)
|
|
90901
91134
|
];
|
|
@@ -91437,7 +91670,7 @@ __export(exports_fanout, {
|
|
|
91437
91670
|
run: () => run21
|
|
91438
91671
|
});
|
|
91439
91672
|
import fs36 from "node:fs";
|
|
91440
|
-
import
|
|
91673
|
+
import path75 from "node:path";
|
|
91441
91674
|
function forgeFor(io, offline) {
|
|
91442
91675
|
if (offline)
|
|
91443
91676
|
return { forge: null, error: "--offline" };
|
|
@@ -91498,7 +91731,7 @@ function plan2(argv, io) {
|
|
|
91498
91731
|
return usage4(io, "pass --trunk or --track, not both (--track picks the trunk)", PLAN_USAGE2);
|
|
91499
91732
|
if (flags.positionals.length !== 1)
|
|
91500
91733
|
return usage4(io, flags.positionals.length ? `unexpected argument ${flags.positionals[1]}` : "missing <plan.json>", PLAN_USAGE2);
|
|
91501
|
-
const file =
|
|
91734
|
+
const file = path75.resolve(io.cwd, flags.positionals[0]);
|
|
91502
91735
|
let raw;
|
|
91503
91736
|
try {
|
|
91504
91737
|
raw = JSON.parse(fs36.readFileSync(file, "utf8"));
|
|
@@ -107074,7 +107307,7 @@ var init_ast = __esm(() => {
|
|
|
107074
107307
|
|
|
107075
107308
|
// packages/workit-cli/src/test-audit/rules.ts
|
|
107076
107309
|
import { builtinModules } from "node:module";
|
|
107077
|
-
import
|
|
107310
|
+
import path76 from "node:path";
|
|
107078
107311
|
function testCallee(call) {
|
|
107079
107312
|
let callee = call.callee;
|
|
107080
107313
|
if (callee.type === "CallExpression")
|
|
@@ -107567,12 +107800,12 @@ function checkConstantsOnly(ctx, emit) {
|
|
|
107567
107800
|
}
|
|
107568
107801
|
function checkOverMocking(ctx, emit) {
|
|
107569
107802
|
const { program } = ctx.parsed;
|
|
107570
|
-
const unit =
|
|
107803
|
+
const unit = path76.basename(ctx.file).replace(/\.(?:[cm]?[jt]sx?)$/, "").replace(/\.(?:test|spec)$/, "");
|
|
107571
107804
|
const mocked = find2(program, (node) => node.type === "CallExpression" && MODULE_MOCK.test(calleeName(node.callee) ?? "") && node.arguments[0]?.type === "StringLiteral");
|
|
107572
107805
|
const internal = mocked.filter((call) => /^(?:\.|@\/|~\/)/.test(call.arguments[0].value));
|
|
107573
107806
|
for (const call of mocked) {
|
|
107574
107807
|
const spec = call.arguments[0].value;
|
|
107575
|
-
const base =
|
|
107808
|
+
const base = path76.basename(spec.replace(/\/index(?:\.[cm]?[jt]sx?)?$/, "")).replace(/\.(?:[cm]?[jt]sx?)$/, "");
|
|
107576
107809
|
if (base === unit)
|
|
107577
107810
|
emit({
|
|
107578
107811
|
rule: "over-mocking",
|
|
@@ -107961,8 +108194,8 @@ var init_rules = __esm(() => {
|
|
|
107961
108194
|
|
|
107962
108195
|
// packages/workit-cli/src/test-audit/audit.ts
|
|
107963
108196
|
import { spawnSync as spawnSync30 } from "node:child_process";
|
|
107964
|
-
import { existsSync as
|
|
107965
|
-
import
|
|
108197
|
+
import { existsSync as existsSync29, readdirSync as readdirSync14, readFileSync as readFileSync32, statSync as statSync10 } from "node:fs";
|
|
108198
|
+
import path77 from "node:path";
|
|
107966
108199
|
function git7(cwd, args) {
|
|
107967
108200
|
const run = spawnSync30("git", ["-c", "core.quotepath=off", ...args], {
|
|
107968
108201
|
cwd,
|
|
@@ -107975,7 +108208,7 @@ function walkTests(dir, out) {
|
|
|
107975
108208
|
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
107976
108209
|
if (entry.name.startsWith(".") && entry.name !== "." && entry.isDirectory())
|
|
107977
108210
|
continue;
|
|
107978
|
-
const full =
|
|
108211
|
+
const full = path77.join(dir, entry.name);
|
|
107979
108212
|
if (entry.isDirectory()) {
|
|
107980
108213
|
if (!SKIP_DIRS.has(entry.name))
|
|
107981
108214
|
walkTests(full, out);
|
|
@@ -107987,8 +108220,8 @@ function expandPaths(cwd, inputs) {
|
|
|
107987
108220
|
const files = [];
|
|
107988
108221
|
const missing = [];
|
|
107989
108222
|
for (const input of inputs.length > 0 ? inputs : ["."]) {
|
|
107990
|
-
const full =
|
|
107991
|
-
if (!
|
|
108223
|
+
const full = path77.resolve(cwd, input);
|
|
108224
|
+
if (!existsSync29(full))
|
|
107992
108225
|
missing.push(input);
|
|
107993
108226
|
else if (statSync10(full).isDirectory())
|
|
107994
108227
|
walkTests(full, files);
|
|
@@ -108024,11 +108257,11 @@ function changedLines(cwd, base) {
|
|
|
108024
108257
|
for (let offset = 0;offset < count; offset += 1)
|
|
108025
108258
|
lines.add(start + offset);
|
|
108026
108259
|
}
|
|
108027
|
-
changed.set(
|
|
108260
|
+
changed.set(path77.join(root, file), lines);
|
|
108028
108261
|
}
|
|
108029
108262
|
const untracked = git7(root, ["ls-files", "--others", "--exclude-standard", "-z"]);
|
|
108030
108263
|
for (const file of untracked.stdout.split("\x00").filter(Boolean))
|
|
108031
|
-
changed.set(
|
|
108264
|
+
changed.set(path77.join(root, file), "all");
|
|
108032
108265
|
return changed;
|
|
108033
108266
|
}
|
|
108034
108267
|
function auditFiles(files, display) {
|
|
@@ -108041,7 +108274,7 @@ function auditFiles(files, display) {
|
|
|
108041
108274
|
const shown = display(file);
|
|
108042
108275
|
let parsed;
|
|
108043
108276
|
try {
|
|
108044
|
-
parsed = parseSource(
|
|
108277
|
+
parsed = parseSource(readFileSync32(file, "utf8"), file);
|
|
108045
108278
|
} catch (error) {
|
|
108046
108279
|
parseErrors.push({
|
|
108047
108280
|
file: shown,
|
|
@@ -108090,7 +108323,7 @@ function auditFiles(files, display) {
|
|
|
108090
108323
|
durationMs: Math.round(performance.now() - started)
|
|
108091
108324
|
};
|
|
108092
108325
|
}
|
|
108093
|
-
var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(
|
|
108326
|
+
var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(path77.sep).join("/"), SEVERITY_ORDER, ruleIds;
|
|
108094
108327
|
var init_audit = __esm(() => {
|
|
108095
108328
|
init_ast();
|
|
108096
108329
|
init_rules();
|
|
@@ -108104,23 +108337,23 @@ var init_audit = __esm(() => {
|
|
|
108104
108337
|
// packages/workit-cli/src/test-audit/mutate.ts
|
|
108105
108338
|
import { spawn as spawn5 } from "node:child_process";
|
|
108106
108339
|
import {
|
|
108107
|
-
existsSync as
|
|
108340
|
+
existsSync as existsSync30,
|
|
108108
108341
|
lstatSync as lstatSync9,
|
|
108109
108342
|
mkdirSync as mkdirSync13,
|
|
108110
|
-
mkdtempSync as
|
|
108343
|
+
mkdtempSync as mkdtempSync6,
|
|
108111
108344
|
readdirSync as readdirSync15,
|
|
108112
|
-
readFileSync as
|
|
108345
|
+
readFileSync as readFileSync33,
|
|
108113
108346
|
readlinkSync as readlinkSync3,
|
|
108114
108347
|
realpathSync as realpathSync11,
|
|
108115
108348
|
renameSync as renameSync8,
|
|
108116
|
-
rmSync as
|
|
108349
|
+
rmSync as rmSync11,
|
|
108117
108350
|
statSync as statSync11,
|
|
108118
108351
|
symlinkSync,
|
|
108119
|
-
writeFileSync as
|
|
108352
|
+
writeFileSync as writeFileSync15,
|
|
108120
108353
|
copyFileSync as copyFileSync8
|
|
108121
108354
|
} from "node:fs";
|
|
108122
|
-
import
|
|
108123
|
-
import
|
|
108355
|
+
import os26 from "node:os";
|
|
108356
|
+
import path78 from "node:path";
|
|
108124
108357
|
function mutantsFor(source, file, lines) {
|
|
108125
108358
|
const parsed = parseSource(source, file);
|
|
108126
108359
|
const out = [];
|
|
@@ -108193,7 +108426,7 @@ function relatedTests(source, testFiles) {
|
|
|
108193
108426
|
for (const match of text.matchAll(SPECIFIER)) {
|
|
108194
108427
|
const spec = match[1];
|
|
108195
108428
|
if (spec.startsWith(".")) {
|
|
108196
|
-
if (stripExt(
|
|
108429
|
+
if (stripExt(path78.posix.join(path78.posix.dirname(file), spec)) === target)
|
|
108197
108430
|
return true;
|
|
108198
108431
|
} else if (spec.includes("/") && stripExt(spec).split("/").slice(-2).join("/") === tail)
|
|
108199
108432
|
return true;
|
|
@@ -108201,7 +108434,7 @@ function relatedTests(source, testFiles) {
|
|
|
108201
108434
|
return false;
|
|
108202
108435
|
}).map((entry) => entry.file);
|
|
108203
108436
|
}
|
|
108204
|
-
function removeStaleCopies(tmp =
|
|
108437
|
+
function removeStaleCopies(tmp = os26.tmpdir()) {
|
|
108205
108438
|
let removed = 0;
|
|
108206
108439
|
let names = [];
|
|
108207
108440
|
try {
|
|
@@ -108213,12 +108446,12 @@ function removeStaleCopies(tmp = os24.tmpdir()) {
|
|
|
108213
108446
|
for (const name of names) {
|
|
108214
108447
|
if (!name.startsWith(TEMP_PREFIX))
|
|
108215
108448
|
continue;
|
|
108216
|
-
const dir =
|
|
108449
|
+
const dir = path78.join(tmp, name);
|
|
108217
108450
|
try {
|
|
108218
108451
|
const stat = lstatSync9(dir);
|
|
108219
108452
|
if (!stat.isDirectory() || uid !== undefined && stat.uid !== uid)
|
|
108220
108453
|
continue;
|
|
108221
|
-
const pid = Number(
|
|
108454
|
+
const pid = Number(readFileSync33(path78.join(dir, PID_FILE), "utf8"));
|
|
108222
108455
|
if (Number.isInteger(pid) && pid > 0 && alive(pid))
|
|
108223
108456
|
continue;
|
|
108224
108457
|
} catch (error) {
|
|
@@ -108226,7 +108459,7 @@ function removeStaleCopies(tmp = os24.tmpdir()) {
|
|
|
108226
108459
|
continue;
|
|
108227
108460
|
}
|
|
108228
108461
|
try {
|
|
108229
|
-
|
|
108462
|
+
rmSync11(dir, { recursive: true, force: true });
|
|
108230
108463
|
removed += 1;
|
|
108231
108464
|
} catch {}
|
|
108232
108465
|
}
|
|
@@ -108235,8 +108468,8 @@ function removeStaleCopies(tmp = os24.tmpdir()) {
|
|
|
108235
108468
|
function linkNodeModules(origin, target, repo, copy) {
|
|
108236
108469
|
mkdirSync13(target, { recursive: true });
|
|
108237
108470
|
for (const entry of readdirSync15(origin, { withFileTypes: true })) {
|
|
108238
|
-
const from =
|
|
108239
|
-
const to =
|
|
108471
|
+
const from = path78.join(origin, entry.name);
|
|
108472
|
+
const to = path78.join(target, entry.name);
|
|
108240
108473
|
if (entry.name.startsWith("@") && entry.isDirectory()) {
|
|
108241
108474
|
linkNodeModules(from, to, repo, copy);
|
|
108242
108475
|
continue;
|
|
@@ -108252,9 +108485,9 @@ function linkNodeModules(origin, target, repo, copy) {
|
|
|
108252
108485
|
} catch {
|
|
108253
108486
|
continue;
|
|
108254
108487
|
}
|
|
108255
|
-
const relative =
|
|
108256
|
-
if (!relative.startsWith("..") && !
|
|
108257
|
-
symlinkSync(
|
|
108488
|
+
const relative = path78.relative(repo, real);
|
|
108489
|
+
if (!relative.startsWith("..") && !path78.isAbsolute(relative) && !relative.split(path78.sep).includes("node_modules")) {
|
|
108490
|
+
symlinkSync(path78.join(copy, relative), to, "junction");
|
|
108258
108491
|
continue;
|
|
108259
108492
|
}
|
|
108260
108493
|
}
|
|
@@ -108270,7 +108503,7 @@ function copySymlink(repo, tree, from, to) {
|
|
|
108270
108503
|
}
|
|
108271
108504
|
const realRepo = realpathSync11(repo);
|
|
108272
108505
|
if (real && inside5(realRepo, real)) {
|
|
108273
|
-
symlinkSync(
|
|
108506
|
+
symlinkSync(path78.relative(path78.dirname(to), path78.join(tree, path78.relative(realRepo, real))), to);
|
|
108274
108507
|
return;
|
|
108275
108508
|
}
|
|
108276
108509
|
if (real && statSync11(real).isFile())
|
|
@@ -108279,23 +108512,23 @@ function copySymlink(repo, tree, from, to) {
|
|
|
108279
108512
|
symlinkSync(readlinkSync3(from), to);
|
|
108280
108513
|
}
|
|
108281
108514
|
function writeInside(copy, file, content) {
|
|
108282
|
-
const target =
|
|
108515
|
+
const target = path78.join(copy, file);
|
|
108283
108516
|
try {
|
|
108284
108517
|
const stat = lstatSync9(target);
|
|
108285
|
-
if (!stat.isFile() || !inside5(realpathSync11(copy), realpathSync11(
|
|
108518
|
+
if (!stat.isFile() || !inside5(realpathSync11(copy), realpathSync11(path78.dirname(target))))
|
|
108286
108519
|
return false;
|
|
108287
108520
|
} catch {
|
|
108288
108521
|
return false;
|
|
108289
108522
|
}
|
|
108290
108523
|
const temp = `${target}.workit-mutant-${process.pid}`;
|
|
108291
|
-
|
|
108524
|
+
writeFileSync15(temp, content);
|
|
108292
108525
|
renameSync8(temp, target);
|
|
108293
108526
|
return true;
|
|
108294
108527
|
}
|
|
108295
108528
|
function copyWorkingTree(repo) {
|
|
108296
|
-
const dir =
|
|
108297
|
-
|
|
108298
|
-
const tree =
|
|
108529
|
+
const dir = mkdtempSync6(path78.join(os26.tmpdir(), TEMP_PREFIX));
|
|
108530
|
+
writeFileSync15(path78.join(dir, PID_FILE), String(process.pid));
|
|
108531
|
+
const tree = path78.join(dir, "tree");
|
|
108299
108532
|
const head = git7(repo, ["rev-parse", "--verify", "--quiet", "HEAD"]).stdout.trim();
|
|
108300
108533
|
if (head && git7(dir, ["clone", "-q", "--shared", "--no-checkout", repo, tree]).ok) {
|
|
108301
108534
|
const branch = git7(repo, ["symbolic-ref", "--quiet", "--short", "HEAD"]).stdout.trim();
|
|
@@ -108312,29 +108545,29 @@ function copyWorkingTree(repo) {
|
|
|
108312
108545
|
for (const relative of listed) {
|
|
108313
108546
|
if (!relative)
|
|
108314
108547
|
continue;
|
|
108315
|
-
const from =
|
|
108548
|
+
const from = path78.join(repo, relative);
|
|
108316
108549
|
let stat;
|
|
108317
108550
|
try {
|
|
108318
108551
|
stat = lstatSync9(from);
|
|
108319
108552
|
} catch {
|
|
108320
108553
|
continue;
|
|
108321
108554
|
}
|
|
108322
|
-
const to =
|
|
108323
|
-
mkdirSync13(
|
|
108555
|
+
const to = path78.join(tree, relative);
|
|
108556
|
+
mkdirSync13(path78.dirname(to), { recursive: true });
|
|
108324
108557
|
if (stat.isSymbolicLink())
|
|
108325
108558
|
copySymlink(repo, tree, from, to);
|
|
108326
108559
|
else if (stat.isFile())
|
|
108327
108560
|
copyFileSync8(from, to);
|
|
108328
|
-
let parent =
|
|
108561
|
+
let parent = path78.dirname(relative);
|
|
108329
108562
|
while (parent !== "." && !dirs.has(parent)) {
|
|
108330
108563
|
dirs.add(parent);
|
|
108331
|
-
parent =
|
|
108564
|
+
parent = path78.dirname(parent);
|
|
108332
108565
|
}
|
|
108333
108566
|
}
|
|
108334
108567
|
for (const parent of dirs) {
|
|
108335
|
-
const modules =
|
|
108336
|
-
if (
|
|
108337
|
-
linkNodeModules(modules,
|
|
108568
|
+
const modules = path78.join(repo, parent, "node_modules");
|
|
108569
|
+
if (existsSync30(modules) && !existsSync30(path78.join(tree, parent, "node_modules")))
|
|
108570
|
+
linkNodeModules(modules, path78.join(tree, parent, "node_modules"), repo, tree);
|
|
108338
108571
|
}
|
|
108339
108572
|
return { dir, tree };
|
|
108340
108573
|
}
|
|
@@ -108373,20 +108606,20 @@ async function runMutation(options) {
|
|
|
108373
108606
|
const tracked = git7(repo, ["ls-files", "-co", "--exclude-standard", "-z"]).stdout.split("\x00").filter(Boolean);
|
|
108374
108607
|
const testFiles = tracked.filter((file) => TEST_FILE.test(file)).map((file) => {
|
|
108375
108608
|
try {
|
|
108376
|
-
return { file, text:
|
|
108609
|
+
return { file, text: readFileSync33(path78.join(repo, file), "utf8") };
|
|
108377
108610
|
} catch {
|
|
108378
108611
|
return { file, text: "" };
|
|
108379
108612
|
}
|
|
108380
108613
|
});
|
|
108381
108614
|
const candidates = [];
|
|
108382
108615
|
for (const [absolute, lines] of [...options.changed].toSorted(([a], [b]) => a.localeCompare(b))) {
|
|
108383
|
-
const relative = toPosix(
|
|
108616
|
+
const relative = toPosix(path78.relative(repo, absolute));
|
|
108384
108617
|
if (!CODE_FILE.test(relative) || TEST_FILE.test(relative) || relative.endsWith(".d.ts"))
|
|
108385
108618
|
continue;
|
|
108386
|
-
if (NOT_SOURCE.test(relative) || !
|
|
108619
|
+
if (NOT_SOURCE.test(relative) || !existsSync30(absolute))
|
|
108387
108620
|
continue;
|
|
108388
108621
|
try {
|
|
108389
|
-
candidates.push(...mutantsFor(
|
|
108622
|
+
candidates.push(...mutantsFor(readFileSync33(absolute, "utf8"), relative, lines));
|
|
108390
108623
|
} catch {}
|
|
108391
108624
|
}
|
|
108392
108625
|
const mutants = candidates.map((mutant, index) => ({ ...mutant, id: index + 1 }));
|
|
@@ -108394,9 +108627,9 @@ async function runMutation(options) {
|
|
|
108394
108627
|
for (const mutant of mutants)
|
|
108395
108628
|
if (!related.has(mutant.file))
|
|
108396
108629
|
related.set(mutant.file, relatedTests(mutant.file, testFiles));
|
|
108397
|
-
const cwdRelative =
|
|
108630
|
+
const cwdRelative = path78.relative(repo, options.cwd);
|
|
108398
108631
|
const asArg = (file) => {
|
|
108399
|
-
const relative = toPosix(
|
|
108632
|
+
const relative = toPosix(path78.relative(cwdRelative, file));
|
|
108400
108633
|
return shellQuote(relative.startsWith(".") ? relative : `./${relative}`);
|
|
108401
108634
|
};
|
|
108402
108635
|
const commandFor = (tests) => options.command.replaceAll("{files}", () => tests.map(asArg).join(" "));
|
|
@@ -108432,7 +108665,7 @@ async function runMutation(options) {
|
|
|
108432
108665
|
return finish3(options, 0, results, counts, started);
|
|
108433
108666
|
removeStaleCopies();
|
|
108434
108667
|
const { dir: copyDir, tree: copy } = copyWorkingTree(repo);
|
|
108435
|
-
const copyCwd =
|
|
108668
|
+
const copyCwd = path78.join(copy, cwdRelative);
|
|
108436
108669
|
let current = null;
|
|
108437
108670
|
const restore = () => {
|
|
108438
108671
|
if (current)
|
|
@@ -108443,7 +108676,7 @@ async function runMutation(options) {
|
|
|
108443
108676
|
for (const child of active)
|
|
108444
108677
|
killTree(child);
|
|
108445
108678
|
restore();
|
|
108446
|
-
|
|
108679
|
+
rmSync11(copyDir, { recursive: true, force: true });
|
|
108447
108680
|
};
|
|
108448
108681
|
const onSignal = (signal) => {
|
|
108449
108682
|
cleanup();
|
|
@@ -108467,7 +108700,7 @@ async function runMutation(options) {
|
|
|
108467
108700
|
record({ ...mutant, status: "skipped", durationMs: 0, tests, reason: "budget" });
|
|
108468
108701
|
continue;
|
|
108469
108702
|
}
|
|
108470
|
-
const original =
|
|
108703
|
+
const original = readFileSync33(path78.join(copy, mutant.file), "utf8");
|
|
108471
108704
|
const mutated = original.slice(0, mutant.start) + mutant.replacement + original.slice(mutant.end);
|
|
108472
108705
|
current = { file: mutant.file, original };
|
|
108473
108706
|
if (!writeInside(copy, mutant.file, mutated)) {
|
|
@@ -108524,8 +108757,8 @@ var NOT_SOURCE, FLIPS, isStringy = (node) => node.type === "StringLiteral" || no
|
|
|
108524
108757
|
return error.code === "EPERM";
|
|
108525
108758
|
}
|
|
108526
108759
|
}, inside5 = (root, file) => {
|
|
108527
|
-
const relative =
|
|
108528
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
108760
|
+
const relative = path78.relative(root, file);
|
|
108761
|
+
return relative === "" || !relative.startsWith("..") && !path78.isAbsolute(relative);
|
|
108529
108762
|
}, active, killTree = (child) => {
|
|
108530
108763
|
try {
|
|
108531
108764
|
if (child.pid && process.platform !== "win32")
|
|
@@ -108573,8 +108806,8 @@ var exports_test_audit = {};
|
|
|
108573
108806
|
__export(exports_test_audit, {
|
|
108574
108807
|
run: () => run23
|
|
108575
108808
|
});
|
|
108576
|
-
import { existsSync as
|
|
108577
|
-
import
|
|
108809
|
+
import { existsSync as existsSync31 } from "node:fs";
|
|
108810
|
+
import path79 from "node:path";
|
|
108578
108811
|
function parse8(argv) {
|
|
108579
108812
|
const options = {
|
|
108580
108813
|
paths: [],
|
|
@@ -108679,8 +108912,8 @@ async function run23(argv, io) {
|
|
|
108679
108912
|
return emit(io, fail2("invalid_input", `${options}
|
|
108680
108913
|
usage: ${USAGE16}`));
|
|
108681
108914
|
const top = git7(io.cwd, ["rev-parse", "--show-toplevel"]);
|
|
108682
|
-
const repo = top.ok ?
|
|
108683
|
-
const display = (file) => toPosix(
|
|
108915
|
+
const repo = top.ok ? path79.resolve(top.stdout.trim()) : null;
|
|
108916
|
+
const display = (file) => toPosix(path79.relative(io.cwd, file) || file);
|
|
108684
108917
|
let base = null;
|
|
108685
108918
|
let changed = null;
|
|
108686
108919
|
if (options.diff || options.mutate) {
|
|
@@ -108697,7 +108930,7 @@ usage: ${USAGE16}`));
|
|
|
108697
108930
|
}
|
|
108698
108931
|
let files;
|
|
108699
108932
|
if (options.diff && changed)
|
|
108700
|
-
files = [...changed.keys()].filter((file) => TEST_FILE.test(toPosix(file)) &&
|
|
108933
|
+
files = [...changed.keys()].filter((file) => TEST_FILE.test(toPosix(file)) && existsSync31(file)).toSorted();
|
|
108701
108934
|
else {
|
|
108702
108935
|
const expanded = expandPaths(io.cwd, options.paths);
|
|
108703
108936
|
if (expanded.missing.length > 0)
|
|
@@ -108818,8 +109051,8 @@ var exports_youtrack = {};
|
|
|
108818
109051
|
__export(exports_youtrack, {
|
|
108819
109052
|
run: () => run25
|
|
108820
109053
|
});
|
|
108821
|
-
import { readFileSync as
|
|
108822
|
-
import
|
|
109054
|
+
import { readFileSync as readFileSync34 } from "node:fs";
|
|
109055
|
+
import path80 from "node:path";
|
|
108823
109056
|
async function run25(argv, io) {
|
|
108824
109057
|
const [sub, ...rest] = argv;
|
|
108825
109058
|
if (sub !== "note" && sub !== "time" && sub !== "meeting")
|
|
@@ -108865,7 +109098,7 @@ async function run25(argv, io) {
|
|
|
108865
109098
|
let markdown = flags.values.markdown ?? "";
|
|
108866
109099
|
if (flags.values.file)
|
|
108867
109100
|
try {
|
|
108868
|
-
markdown =
|
|
109101
|
+
markdown = readFileSync34(path80.resolve(io.cwd, flags.values.file), "utf8");
|
|
108869
109102
|
} catch (error) {
|
|
108870
109103
|
return usage4(io, `cannot read ${flags.values.file}: ${String(error)}`, USAGE18);
|
|
108871
109104
|
}
|
|
@@ -108936,8 +109169,8 @@ var exports_changelog = {};
|
|
|
108936
109169
|
__export(exports_changelog, {
|
|
108937
109170
|
run: () => run26
|
|
108938
109171
|
});
|
|
108939
|
-
import { readFileSync as
|
|
108940
|
-
import
|
|
109172
|
+
import { readFileSync as readFileSync35 } from "node:fs";
|
|
109173
|
+
import path81 from "node:path";
|
|
108941
109174
|
async function run26(argv, io) {
|
|
108942
109175
|
const [sub, ...rest] = argv;
|
|
108943
109176
|
if (sub !== "apply")
|
|
@@ -108983,7 +109216,7 @@ async function run26(argv, io) {
|
|
|
108983
109216
|
]);
|
|
108984
109217
|
}
|
|
108985
109218
|
var USAGE19 = "workit changelog apply (--entries <JSON|@file|-> | --normalize-only) [--path CHANGELOG.md] [--preview]", readEntries = (raw, cwd) => {
|
|
108986
|
-
const text = raw === "-" ?
|
|
109219
|
+
const text = raw === "-" ? readFileSync35(0, "utf8") : raw.startsWith("@") ? readFileSync35(path81.resolve(cwd, raw.slice(1)), "utf8") : raw;
|
|
108987
109220
|
return JSON.parse(text);
|
|
108988
109221
|
};
|
|
108989
109222
|
var init_changelog2 = __esm(() => {
|
|
@@ -108999,7 +109232,7 @@ __export(exports_handoff, {
|
|
|
108999
109232
|
run: () => run27
|
|
109000
109233
|
});
|
|
109001
109234
|
import fs37 from "node:fs";
|
|
109002
|
-
import
|
|
109235
|
+
import path82 from "node:path";
|
|
109003
109236
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
109004
109237
|
function render3(brief) {
|
|
109005
109238
|
const lines = [
|
|
@@ -109039,9 +109272,9 @@ function bounded(brief, cwd) {
|
|
|
109039
109272
|
let file = null;
|
|
109040
109273
|
if (store.ok)
|
|
109041
109274
|
try {
|
|
109042
|
-
const dir =
|
|
109275
|
+
const dir = path82.join(store.value.root, "handoff");
|
|
109043
109276
|
fs37.mkdirSync(dir, { recursive: true });
|
|
109044
|
-
file =
|
|
109277
|
+
file = path82.join(dir, `${(brief.branch ?? "detached").replaceAll(/[^\w.-]+/gu, "-")}.txt`);
|
|
109045
109278
|
fs37.writeFileSync(file, `${[...body, ...tail].join(`
|
|
109046
109279
|
`)}
|
|
109047
109280
|
`, {
|
|
@@ -109116,7 +109349,7 @@ var init_handoff = __esm(() => {
|
|
|
109116
109349
|
});
|
|
109117
109350
|
|
|
109118
109351
|
// packages/workit-cli/src/main.ts
|
|
109119
|
-
import
|
|
109352
|
+
import path83 from "node:path";
|
|
109120
109353
|
|
|
109121
109354
|
// packages/workit-core/src/git/env-redirect.ts
|
|
109122
109355
|
var GIT_REDIRECT_ENV = [
|
|
@@ -110065,7 +110298,7 @@ var defaultIo = (json) => ({
|
|
|
110065
110298
|
});
|
|
110066
110299
|
async function main(argv, overrides = {}, options = {}) {
|
|
110067
110300
|
const parsed = parseGlobals(argv);
|
|
110068
|
-
const cwd =
|
|
110301
|
+
const cwd = path83.resolve(overrides.cwd ?? process.cwd(), parsed.cwd ?? ".");
|
|
110069
110302
|
const io = {
|
|
110070
110303
|
...defaultIo(parsed.json),
|
|
110071
110304
|
terminals: {
|