@brainervirus/workit-claude-code 8.44.0 → 8.44.2
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 +744 -367
- 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.2",
|
|
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.2",
|
|
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.2"
|
|
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,
|
|
@@ -75769,9 +75775,13 @@ import { createHash as createHash15 } from "node:crypto";
|
|
|
75769
75775
|
function errorText(error) {
|
|
75770
75776
|
return error instanceof Error ? error.message : "installed source could not be read";
|
|
75771
75777
|
}
|
|
75772
|
-
var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-opencode", OPENCODE_UPDATE, CODEX_MARKETPLACE = "workflow-toolkit", CLI_FIX = "npm install --global @brainervirus/workit-cli@latest", stderrTail = (text, lines = 5) => (text ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).slice(-lines).join(" | "),
|
|
75778
|
+
var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-opencode", OPENCODE_UPDATE, CODEX_MARKETPLACE = "workflow-toolkit", CLI_FIX = "npm install --global @brainervirus/workit-cli@latest", stderrTail = (text, lines = 5) => (text ?? "").split(/\r?\n/).map((line) => line.trim()).filter(Boolean).slice(-lines).join(" | "), errorLine = (result) => `${result.stdout}
|
|
75779
|
+
${result.stderr ?? ""}`.split(/\r?\n/).map((line) => line.trim()).find((line) => /\bError:/.test(line)), failureReason = (command, result) => {
|
|
75773
75780
|
const tail = stderrTail(result.stderr);
|
|
75774
|
-
|
|
75781
|
+
const message = errorLine(result);
|
|
75782
|
+
const detail = message && !tail.includes(message) ? [message, tail].filter(Boolean) : [tail];
|
|
75783
|
+
const text = detail.filter(Boolean).join(" | ");
|
|
75784
|
+
return `\`${command.command} ${command.args.join(" ")}\` failed${text ? `: ${text}` : ""}`;
|
|
75775
75785
|
}, fixFor = (host, selector = "") => host === "pi" ? `pi update --extension ${selector || "npm:@brainervirus/workit-pi"}` : host === "codex" ? `codex plugin marketplace upgrade ${CODEX_MARKETPLACE} && codex plugin add workit@${CODEX_MARKETPLACE}` : host === "claude-code" ? "claude plugin marketplace update workit && claude plugin update workit@workit" : host === "opencode" ? OPENCODE_UPDATE : host === "cursor" ? "workit upgrade --hosts=cursor" : CLI_FIX, upgradePaths = (deps) => {
|
|
75776
75786
|
const home = deps.home ?? deps.env?.HOME ?? os17.homedir();
|
|
75777
75787
|
const env = {
|
|
@@ -75818,27 +75828,27 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75818
75828
|
} catch {
|
|
75819
75829
|
return null;
|
|
75820
75830
|
}
|
|
75821
|
-
}, digest2 = (file) => existsSync21(file) ? createHash15("sha256").update(readFileSync23(file)).digest("hex") : "missing", runner = (deps) => deps.run ?? ((command, args) => {
|
|
75831
|
+
}, digest2 = (file) => existsSync21(file) ? createHash15("sha256").update(readFileSync23(file)).digest("hex") : "missing", runner = (deps) => deps.run ?? ((command, args, options) => {
|
|
75822
75832
|
const { home, env } = upgradePaths(deps);
|
|
75823
75833
|
let step;
|
|
75824
75834
|
try {
|
|
75825
|
-
step = hostCommand(command, args, { home, env });
|
|
75835
|
+
step = hostCommand(command, args, { home, env, cwd: options?.cwd });
|
|
75826
75836
|
} catch (error) {
|
|
75827
75837
|
return { status: 1, stdout: "", stderr: errorText(error) };
|
|
75828
75838
|
}
|
|
75829
75839
|
const result = runHostCommand(step, { home, env });
|
|
75830
75840
|
return { status: result.exitCode, stdout: result.stdout, stderr: result.stderr };
|
|
75831
|
-
}), COMMAND_TIMEOUT_MS = 60000, asyncRunner = (deps) => {
|
|
75841
|
+
}), COMMAND_TIMEOUT_MS = 60000, asyncRunner = (deps, timeoutMs = COMMAND_TIMEOUT_MS) => {
|
|
75832
75842
|
if (deps.runAsync)
|
|
75833
75843
|
return deps.runAsync;
|
|
75834
75844
|
const injected = deps.run;
|
|
75835
75845
|
if (injected)
|
|
75836
|
-
return async (command, args) => injected(command, args);
|
|
75837
|
-
return (command, args) => {
|
|
75846
|
+
return async (command, args, options) => injected(command, args, options);
|
|
75847
|
+
return (command, args, options) => {
|
|
75838
75848
|
const { home, env } = upgradePaths(deps);
|
|
75839
75849
|
let step;
|
|
75840
75850
|
try {
|
|
75841
|
-
step = hostCommand(command, args, { home, env });
|
|
75851
|
+
step = hostCommand(command, args, { home, env, cwd: options?.cwd });
|
|
75842
75852
|
} catch (error) {
|
|
75843
75853
|
return Promise.resolve({ status: 1, stdout: "", stderr: errorText(error) });
|
|
75844
75854
|
}
|
|
@@ -75880,7 +75890,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75880
75890
|
const timer = setTimeout(() => {
|
|
75881
75891
|
child.kill("SIGKILL");
|
|
75882
75892
|
finish(1);
|
|
75883
|
-
},
|
|
75893
|
+
}, timeoutMs);
|
|
75884
75894
|
child.stdout?.setEncoding("utf8");
|
|
75885
75895
|
child.stdout?.on("data", (chunk) => stdout += chunk);
|
|
75886
75896
|
child.stderr?.setEncoding("utf8");
|
|
@@ -75978,11 +75988,95 @@ var init_processes = __esm(() => {
|
|
|
75978
75988
|
SCRIPT_RUNTIMES = new Set(["node", "nodejs", "bun"]);
|
|
75979
75989
|
});
|
|
75980
75990
|
|
|
75991
|
+
// packages/workit-cli/src/upgrade/opencode.ts
|
|
75992
|
+
var pluginApiArgs = (home) => [
|
|
75993
|
+
"api",
|
|
75994
|
+
"plugin.list",
|
|
75995
|
+
"-H",
|
|
75996
|
+
`x-opencode-directory:${home}`
|
|
75997
|
+
], PLUGIN_LIST, OPENCODE_READY_TIMEOUT_MS = 20000, READY_INTERVAL_MS = 500, OPENCODE_NOT_READY, isWorkitTarget = (target) => typeof target === "string" && /^(?:npm:)?@brainervirus\/workit-opencode(?:@[^/\s]+)?$/.test(target), lacksApi = (result) => result.status !== 0 && !result.timedOut && /\b(?:unknown|unrecognized|unsupported) (?:command|operation|argument)|\bno such (?:command|operation)/i.test(`${result.stdout}
|
|
75998
|
+
${result.stderr ?? ""}`), parsePluginApi = (result) => {
|
|
75999
|
+
if (result.status !== 0)
|
|
76000
|
+
return null;
|
|
76001
|
+
let parsed;
|
|
76002
|
+
try {
|
|
76003
|
+
parsed = JSON.parse(result.stdout);
|
|
76004
|
+
} catch {
|
|
76005
|
+
return null;
|
|
76006
|
+
}
|
|
76007
|
+
const data = parsed?.data;
|
|
76008
|
+
if (!Array.isArray(data))
|
|
76009
|
+
return null;
|
|
76010
|
+
const entry = data.find((item) => isWorkitTarget(item?.source?.target));
|
|
76011
|
+
if (!entry)
|
|
76012
|
+
return { via: "api", listed: false };
|
|
76013
|
+
const version = entry.source?.version;
|
|
76014
|
+
return {
|
|
76015
|
+
via: "api",
|
|
76016
|
+
listed: true,
|
|
76017
|
+
...typeof version === "string" && /^\d+\.\d+\.\d+$/.test(version) ? { version } : {},
|
|
76018
|
+
...typeof entry.source?.outdated === "boolean" ? { outdated: entry.source.outdated } : {},
|
|
76019
|
+
...typeof entry.state?.status === "string" ? { status: entry.state.status } : {}
|
|
76020
|
+
};
|
|
76021
|
+
}, parsePluginList = (result) => {
|
|
76022
|
+
if (result.status === 0)
|
|
76023
|
+
for (const line of result.stdout.split(/\r?\n/)) {
|
|
76024
|
+
const fields = line.trim().split(/\s+/);
|
|
76025
|
+
if (fields.length < 3)
|
|
76026
|
+
continue;
|
|
76027
|
+
const source = fields[fields.length - 1].replace(/^file:\/\//, "");
|
|
76028
|
+
const version = fields[fields.length - 2];
|
|
76029
|
+
if (isWorkitTarget(source) && /^\d+\.\d+\.\d+$/.test(version))
|
|
76030
|
+
return { via: "list", listed: true, version };
|
|
76031
|
+
}
|
|
76032
|
+
return { via: "list", listed: false };
|
|
76033
|
+
}, readOpencodePlugin = async (run, home) => parsePluginApi(await run("opencode", pluginApiArgs(home), { cwd: home })) ?? parsePluginList(await run("opencode", PLUGIN_LIST, { cwd: home })), waitForOpencodePlugin = async (run, home, options = {}) => {
|
|
76034
|
+
const timeoutMs = options.timeoutMs ?? OPENCODE_READY_TIMEOUT_MS;
|
|
76035
|
+
const intervalMs = options.intervalMs ?? READY_INTERVAL_MS;
|
|
76036
|
+
const now = options.now ?? Date.now;
|
|
76037
|
+
const sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
|
|
76038
|
+
const deadline = now() + timeoutMs;
|
|
76039
|
+
const [versionResult, firstApi] = await Promise.all([
|
|
76040
|
+
run("opencode", ["--version"], { cwd: home }),
|
|
76041
|
+
run("opencode", pluginApiArgs(home), { cwd: home })
|
|
76042
|
+
]);
|
|
76043
|
+
const installed = versionResult.stdout.match(/\d+\.\d+\.\d+/)?.[0];
|
|
76044
|
+
if (installed && !versionAtLeast(installed, SUPPORT_MATRIX.opencode.minimum)) {
|
|
76045
|
+
const text = parsePluginList(await run("opencode", PLUGIN_LIST, { cwd: home }));
|
|
76046
|
+
return text.listed ? text : { via: "list", listed: true };
|
|
76047
|
+
}
|
|
76048
|
+
let pending = firstApi;
|
|
76049
|
+
let textOnly = false;
|
|
76050
|
+
for (;; ) {
|
|
76051
|
+
let api = null;
|
|
76052
|
+
if (!textOnly) {
|
|
76053
|
+
const result = pending ?? await run("opencode", pluginApiArgs(home), { cwd: home });
|
|
76054
|
+
pending = undefined;
|
|
76055
|
+
api = parsePluginApi(result);
|
|
76056
|
+
textOnly = !api && lacksApi(result);
|
|
76057
|
+
}
|
|
76058
|
+
if (textOnly || api?.listed) {
|
|
76059
|
+
const text = parsePluginList(await run("opencode", PLUGIN_LIST, { cwd: home }));
|
|
76060
|
+
if (text.listed)
|
|
76061
|
+
return api?.listed ? { ...api, version: api.version ?? text.version } : text;
|
|
76062
|
+
}
|
|
76063
|
+
if (now() >= deadline)
|
|
76064
|
+
return null;
|
|
76065
|
+
await sleep(Math.min(intervalMs, Math.max(0, deadline - now())));
|
|
76066
|
+
}
|
|
76067
|
+
};
|
|
76068
|
+
var init_opencode = __esm(() => {
|
|
76069
|
+
init_support_matrix();
|
|
76070
|
+
init_shared();
|
|
76071
|
+
PLUGIN_LIST = ["plugin", "list"];
|
|
76072
|
+
OPENCODE_NOT_READY = `OpenCode did not finish loading its plugins (opencode api plugin.list never listed ${OPENCODE_PACKAGE})`;
|
|
76073
|
+
});
|
|
76074
|
+
|
|
75981
76075
|
// packages/workit-cli/src/upgrade/apply.ts
|
|
75982
76076
|
import { existsSync as existsSync22, readdirSync as readdirSync12, mkdirSync as mkdirSync12, copyFileSync as copyFileSync6, chmodSync as chmodSync2, cpSync as cpSync5 } from "node:fs";
|
|
75983
76077
|
import path48 from "node:path";
|
|
75984
76078
|
import { createHash as createHash16 } from "node:crypto";
|
|
75985
|
-
async function applyUpgrade(plan, deps = {}) {
|
|
76079
|
+
async function applyUpgrade(plan, deps = {}, options = {}) {
|
|
75986
76080
|
const hosts = [...plan.failed];
|
|
75987
76081
|
const done = (backup) => {
|
|
75988
76082
|
const failures = hosts.filter((entry) => entry.status === "failed");
|
|
@@ -76039,6 +76133,26 @@ async function applyUpgrade(plan, deps = {}) {
|
|
|
76039
76133
|
const runAsync = asyncRunner(deps);
|
|
76040
76134
|
const progress = deps.progress ?? createProgress({ json: true });
|
|
76041
76135
|
const statusOf = (outcome) => outcome?.status === "failed" ? "failed" : outcome?.status === "updated" ? "done" : "skipped";
|
|
76136
|
+
if (plan.cli) {
|
|
76137
|
+
let cli;
|
|
76138
|
+
try {
|
|
76139
|
+
cli = await progress.run("Updating the CLI", () => applyCli(plan.cli, runAsync, backup), statusOf, { signals: true });
|
|
76140
|
+
} catch (error) {
|
|
76141
|
+
cli = { host: "cli", status: "failed", reason: errorText(error), fix: CLI_FIX };
|
|
76142
|
+
}
|
|
76143
|
+
if (cli.status === "updated" && options.handoff) {
|
|
76144
|
+
const code = await options.handoff(cli);
|
|
76145
|
+
if (code !== undefined)
|
|
76146
|
+
return { ...done(backup), hosts: [...hosts, cli], handedOff: code };
|
|
76147
|
+
if (plan.entries.length)
|
|
76148
|
+
cli = {
|
|
76149
|
+
...cli,
|
|
76150
|
+
reason: `${cli.reason}; the new CLI could not be started, hosts upgraded with workit ${package_default.version}`
|
|
76151
|
+
};
|
|
76152
|
+
} else if (cli.status === "failed" && plan.entries.length)
|
|
76153
|
+
cli = { ...cli, reason: `${cli.reason}; hosts upgraded with workit ${package_default.version}` };
|
|
76154
|
+
hosts.push(cli);
|
|
76155
|
+
}
|
|
76042
76156
|
let cursorBackupError = null;
|
|
76043
76157
|
if (plan.entries.some((entry) => entry.host === "cursor") && existsSync22(paths.cursorRoot))
|
|
76044
76158
|
try {
|
|
@@ -76098,7 +76212,12 @@ async function applyUpgrade(plan, deps = {}) {
|
|
|
76098
76212
|
}
|
|
76099
76213
|
let outcome;
|
|
76100
76214
|
try {
|
|
76101
|
-
outcome = await applyEntry(entry, {
|
|
76215
|
+
outcome = await applyEntry(entry, {
|
|
76216
|
+
runAsync,
|
|
76217
|
+
paths,
|
|
76218
|
+
configDir,
|
|
76219
|
+
opencodeReady: deps.opencodeReady
|
|
76220
|
+
});
|
|
76102
76221
|
if (entry.host === "codex" && outcome.status === "updated") {
|
|
76103
76222
|
const agents = await refreshCodexAgents(runAsync, paths.codexHome);
|
|
76104
76223
|
if (!agents.ok)
|
|
@@ -76173,17 +76292,6 @@ async function applyUpgrade(plan, deps = {}) {
|
|
|
76173
76292
|
reason: `${hosts[index].reason}; ${agents.note}`
|
|
76174
76293
|
};
|
|
76175
76294
|
}
|
|
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
76295
|
return done(backup);
|
|
76188
76296
|
}
|
|
76189
76297
|
var briefDetail = (detail) => {
|
|
@@ -76199,20 +76307,31 @@ var briefDetail = (detail) => {
|
|
|
76199
76307
|
}
|
|
76200
76308
|
const newest = versions.reduce((best, version) => best && versionAtLeast(best, version) ? best : version, null);
|
|
76201
76309
|
return newest ? path48.join(dir, newest) : null;
|
|
76202
|
-
}, opencodeVersion = async (run) => {
|
|
76203
|
-
const
|
|
76204
|
-
|
|
76205
|
-
|
|
76206
|
-
|
|
76207
|
-
|
|
76208
|
-
|
|
76209
|
-
|
|
76210
|
-
|
|
76211
|
-
|
|
76212
|
-
|
|
76213
|
-
|
|
76214
|
-
|
|
76215
|
-
|
|
76310
|
+
}, opencodeVersion = async (run, home) => (await readOpencodePlugin(run, home)).version, opencodeOutcome = async (before, target, runAsync, home) => {
|
|
76311
|
+
const below = (version) => target !== undefined && (version === undefined || !versionAtLeast(version, target));
|
|
76312
|
+
let after = await opencodeVersion(runAsync, home);
|
|
76313
|
+
if (below(after))
|
|
76314
|
+
after = await opencodeVersion(runAsync, home) ?? after;
|
|
76315
|
+
const live = "OpenCode V2 loads it live";
|
|
76316
|
+
if (before && target && versionAtLeast(before, target))
|
|
76317
|
+
return { host: "opencode", status: "current", reason: `already current (${before})` };
|
|
76318
|
+
if (after && below(after))
|
|
76319
|
+
return {
|
|
76320
|
+
host: "opencode",
|
|
76321
|
+
status: "updated",
|
|
76322
|
+
reason: `update ran, but OpenCode still lists ${after} (published ${target}); the doctor below checks its package cache`
|
|
76323
|
+
};
|
|
76324
|
+
if (before && after && after !== before)
|
|
76325
|
+
return { host: "opencode", status: "updated", reason: `${before} -> ${after}; ${live}` };
|
|
76326
|
+
if (before && after)
|
|
76327
|
+
return {
|
|
76328
|
+
host: "opencode",
|
|
76329
|
+
status: "current",
|
|
76330
|
+
reason: `unchanged (${after}); the published version could not be read`
|
|
76331
|
+
};
|
|
76332
|
+
if (after)
|
|
76333
|
+
return { host: "opencode", status: "updated", reason: `now ${after}; ${live}` };
|
|
76334
|
+
return { host: "opencode", status: "updated", reason: `scoped update ran; ${live}` };
|
|
76216
76335
|
}, applyEntry = async (entry, context) => {
|
|
76217
76336
|
const { runAsync, paths, configDir } = context;
|
|
76218
76337
|
const { home, env } = paths;
|
|
@@ -76289,32 +76408,23 @@ ${result.stderr}`;
|
|
|
76289
76408
|
reason: entry.repair ? `reinstalled missing plugin files (${entry.latest})` : `${entry.installedVersion ?? "?"} -> ${entry.latest}`
|
|
76290
76409
|
};
|
|
76291
76410
|
}
|
|
76292
|
-
|
|
76411
|
+
let before;
|
|
76412
|
+
if (entry.host === "opencode") {
|
|
76413
|
+
const ready = await waitForOpencodePlugin(runAsync, home, context.opencodeReady);
|
|
76414
|
+
if (!ready)
|
|
76415
|
+
return fail(OPENCODE_NOT_READY);
|
|
76416
|
+
before = ready.version;
|
|
76417
|
+
}
|
|
76293
76418
|
for (const command of entry.commands) {
|
|
76294
|
-
|
|
76419
|
+
const where = command.cwd ? { cwd: command.cwd } : undefined;
|
|
76420
|
+
let result = await runAsync(command.command, command.args, where);
|
|
76295
76421
|
if (result.status !== 0 && entry.host === "opencode")
|
|
76296
|
-
result = await runAsync(command.command, command.args);
|
|
76422
|
+
result = await runAsync(command.command, command.args, where);
|
|
76297
76423
|
if (result.status !== 0)
|
|
76298
76424
|
return fail(failureReason(command, result));
|
|
76299
76425
|
}
|
|
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
|
-
}
|
|
76426
|
+
if (entry.host === "opencode")
|
|
76427
|
+
return opencodeOutcome(before, entry.published, runAsync, home);
|
|
76318
76428
|
if (entry.host === "claude-code") {
|
|
76319
76429
|
const after = claudeWorkitInstalls(home, env, null).find((install) => install.id === entry.selector)?.version;
|
|
76320
76430
|
return after && after === entry.installedVersion ? {
|
|
@@ -76388,12 +76498,14 @@ ${result.stderr}`;
|
|
|
76388
76498
|
};
|
|
76389
76499
|
};
|
|
76390
76500
|
var init_apply = __esm(() => {
|
|
76501
|
+
init_package();
|
|
76391
76502
|
init_host_install();
|
|
76392
76503
|
init_setup_state();
|
|
76393
76504
|
init_setup();
|
|
76394
76505
|
init_safe_write();
|
|
76395
76506
|
init_progress();
|
|
76396
76507
|
init_processes();
|
|
76508
|
+
init_opencode();
|
|
76397
76509
|
init_shared();
|
|
76398
76510
|
});
|
|
76399
76511
|
|
|
@@ -76558,14 +76670,107 @@ var init_update_check = __esm(() => {
|
|
|
76558
76670
|
]);
|
|
76559
76671
|
});
|
|
76560
76672
|
|
|
76561
|
-
// packages/workit-cli/src/upgrade/
|
|
76562
|
-
import { existsSync as existsSync23, mkdtempSync as mkdtempSync3, rmSync as rmSync8
|
|
76563
|
-
import path50 from "node:path";
|
|
76673
|
+
// packages/workit-cli/src/upgrade/probes.ts
|
|
76674
|
+
import { existsSync as existsSync23, mkdtempSync as mkdtempSync3, rmSync as rmSync8 } from "node:fs";
|
|
76564
76675
|
import os18 from "node:os";
|
|
76565
|
-
|
|
76676
|
+
import path50 from "node:path";
|
|
76677
|
+
var PROBE_TIMEOUT_MS = 20000, probeKey = (command, args) => [command, ...args].join(" "), opencodeScratchEnv = (deps, scratch) => ({
|
|
76678
|
+
...deps.env,
|
|
76679
|
+
XDG_DATA_HOME: path50.join(scratch, "data"),
|
|
76680
|
+
XDG_STATE_HOME: path50.join(scratch, "state"),
|
|
76681
|
+
XDG_CACHE_HOME: path50.join(scratch, "cache")
|
|
76682
|
+
}), registry2 = (name) => ["npm", ["view", name, "version"]], OPENCODE_READY_KEY = "opencode-ready", opencodeReading = (probes) => {
|
|
76683
|
+
const result = probes?.get(OPENCODE_READY_KEY);
|
|
76684
|
+
if (!result)
|
|
76685
|
+
return;
|
|
76686
|
+
return result.status === 0 ? JSON.parse(result.stdout) : null;
|
|
76687
|
+
}, opencodeRegistersWorkit = (file) => {
|
|
76688
|
+
const config = objectOrNull(file);
|
|
76689
|
+
return [config?.plugins, config?.plugin].flatMap((value) => Array.isArray(value) ? value : []).some((pin) => typeof pin === "string" && /^(?:npm:)?@brainervirus\/workit-opencode(?:@[^/\s]+)?$/.test(pin));
|
|
76690
|
+
}, runProbes = async (hosts, cli, deps, options = {}) => {
|
|
76691
|
+
const paths = upgradePaths(deps);
|
|
76692
|
+
const timeoutMs = deps.probeTimeoutMs ?? PROBE_TIMEOUT_MS;
|
|
76693
|
+
const run = asyncRunner(deps, timeoutMs);
|
|
76694
|
+
const probes = [];
|
|
76695
|
+
const add = (command, args, runner = run) => probes.push([command, args, runner]);
|
|
76696
|
+
const scratch = mkdtempSync3(path50.join(os18.tmpdir(), "workit-upgrade-opencode-"));
|
|
76697
|
+
try {
|
|
76698
|
+
if (hosts.includes("opencode") && existsSync23(paths.opencodeConfig)) {
|
|
76699
|
+
if (!options.check) {
|
|
76700
|
+
const opencode = asyncRunner({ ...deps, env: opencodeScratchEnv(deps, scratch) }, timeoutMs);
|
|
76701
|
+
add("opencode", ["--version"], opencode);
|
|
76702
|
+
add("opencode", ["plugin", "--help"], opencode);
|
|
76703
|
+
}
|
|
76704
|
+
add(...registry2(OPENCODE_PACKAGE));
|
|
76705
|
+
}
|
|
76706
|
+
for (const name of options.registries ?? [])
|
|
76707
|
+
add(...registry2(name));
|
|
76708
|
+
if (hosts.includes("cursor"))
|
|
76709
|
+
add(...registry2("@brainervirus/workit-cursor"));
|
|
76710
|
+
if (hosts.includes("codex")) {
|
|
76711
|
+
add("codex", ["plugin", "list", "--json"]);
|
|
76712
|
+
add(...registry2("@brainervirus/workit-codex"));
|
|
76713
|
+
}
|
|
76714
|
+
if (hosts.includes("pi")) {
|
|
76715
|
+
if (existsSync23(paths.piSettings))
|
|
76716
|
+
add("pi", ["list"]);
|
|
76717
|
+
add(...registry2("@brainervirus/workit-pi"));
|
|
76718
|
+
}
|
|
76719
|
+
if (cli) {
|
|
76720
|
+
add("npm", ["root", "--global"]);
|
|
76721
|
+
add(...registry2(CLI_PACKAGE2));
|
|
76722
|
+
}
|
|
76723
|
+
const ready = hosts.includes("opencode") && opencodeRegistersWorkit(paths.opencodeConfig) ? waitForOpencodePlugin((command, args, where) => run(command, args, where).catch((error) => ({
|
|
76724
|
+
status: 1,
|
|
76725
|
+
stdout: "",
|
|
76726
|
+
stderr: error instanceof Error ? error.message : String(error)
|
|
76727
|
+
})), paths.home, deps.opencodeReady).then((reading) => [
|
|
76728
|
+
OPENCODE_READY_KEY,
|
|
76729
|
+
reading ? { status: 0, stdout: JSON.stringify(reading) } : { status: 1, stdout: "", stderr: OPENCODE_NOT_READY }
|
|
76730
|
+
]) : undefined;
|
|
76731
|
+
const results = await Promise.all(probes.map(async ([command, args, runner]) => {
|
|
76732
|
+
let timer;
|
|
76733
|
+
const timedOut = new Promise((resolve) => {
|
|
76734
|
+
timer = setTimeout(() => resolve({
|
|
76735
|
+
status: null,
|
|
76736
|
+
stdout: "",
|
|
76737
|
+
stderr: `\`${probeKey(command, args)}\` timed out after ${Math.round(timeoutMs / 1000)} s`,
|
|
76738
|
+
timedOut: true
|
|
76739
|
+
}), timeoutMs);
|
|
76740
|
+
});
|
|
76741
|
+
try {
|
|
76742
|
+
const result = await Promise.race([
|
|
76743
|
+
runner(command, args).catch((error) => ({
|
|
76744
|
+
status: 1,
|
|
76745
|
+
stdout: "",
|
|
76746
|
+
stderr: error instanceof Error ? error.message : String(error)
|
|
76747
|
+
})),
|
|
76748
|
+
timedOut
|
|
76749
|
+
]);
|
|
76750
|
+
return [probeKey(command, args), result];
|
|
76751
|
+
} finally {
|
|
76752
|
+
clearTimeout(timer);
|
|
76753
|
+
}
|
|
76754
|
+
}));
|
|
76755
|
+
return new Map([...results, ...ready ? [await ready] : []]);
|
|
76756
|
+
} finally {
|
|
76757
|
+
rmSync8(scratch, { recursive: true, force: true });
|
|
76758
|
+
}
|
|
76759
|
+
};
|
|
76760
|
+
var init_probes = __esm(() => {
|
|
76761
|
+
init_update_check();
|
|
76762
|
+
init_opencode();
|
|
76763
|
+
init_shared();
|
|
76764
|
+
});
|
|
76765
|
+
|
|
76766
|
+
// packages/workit-cli/src/upgrade/plan.ts
|
|
76767
|
+
import { existsSync as existsSync24, mkdtempSync as mkdtempSync4, rmSync as rmSync9, lstatSync as lstatSync8, readFileSync as readFileSync25 } from "node:fs";
|
|
76768
|
+
import path51 from "node:path";
|
|
76769
|
+
import os19 from "node:os";
|
|
76770
|
+
function previewUpgrade(hosts = HOSTS2, deps = {}, probes) {
|
|
76566
76771
|
const paths = upgradePaths(deps);
|
|
76567
76772
|
const { home, configDir } = paths;
|
|
76568
|
-
const run =
|
|
76773
|
+
const run = probedRunner(deps, probes);
|
|
76569
76774
|
const state = readSetupState(configDir);
|
|
76570
76775
|
const plan = {
|
|
76571
76776
|
ok: true,
|
|
@@ -76584,9 +76789,9 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
|
76584
76789
|
for (const file of [
|
|
76585
76790
|
paths.opencodeConfig,
|
|
76586
76791
|
paths.opencodeConfig + "c",
|
|
76587
|
-
|
|
76588
|
-
|
|
76589
|
-
|
|
76792
|
+
path51.join(home, ".cursor/settings.json"),
|
|
76793
|
+
path51.join(home, ".cursor/mcp.json"),
|
|
76794
|
+
path51.join(paths.cursorRoot, "package.json"),
|
|
76590
76795
|
paths.codexConfig,
|
|
76591
76796
|
paths.piSettings
|
|
76592
76797
|
])
|
|
@@ -76605,7 +76810,7 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
|
76605
76810
|
const installedSources = sources(paths, run, hosts, plan.failed);
|
|
76606
76811
|
let opencodeHelp;
|
|
76607
76812
|
if (installedSources.some((source) => source.host === "opencode")) {
|
|
76608
|
-
const probe = opencodeProbe(deps, ["--version"]);
|
|
76813
|
+
const probe = opencodeProbe(deps, ["--version"], probes);
|
|
76609
76814
|
const installed = probe.status === 0 ? probe.stdout.match(/\d+\.\d+\.\d+/)?.[0] : undefined;
|
|
76610
76815
|
if (installed && !versionAtLeast(installed, SUPPORT_MATRIX.opencode.minimum))
|
|
76611
76816
|
(plan.warnings ??= []).push(`opencode ${installed}: ${OPENCODE_V1_FIX}`);
|
|
@@ -76646,7 +76851,17 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
|
76646
76851
|
continue;
|
|
76647
76852
|
}
|
|
76648
76853
|
if (source.host === "opencode") {
|
|
76649
|
-
|
|
76854
|
+
const help = opencodeProbe(deps, ["plugin", "--help"], probes);
|
|
76855
|
+
if (help.timedOut) {
|
|
76856
|
+
plan.failed.push({
|
|
76857
|
+
host: "opencode",
|
|
76858
|
+
status: "failed",
|
|
76859
|
+
reason: `could not check: ${help.stderr}`,
|
|
76860
|
+
fix: OPENCODE_UPDATE
|
|
76861
|
+
});
|
|
76862
|
+
continue;
|
|
76863
|
+
}
|
|
76864
|
+
opencodeHelp ??= help.stdout;
|
|
76650
76865
|
if (!/^\s*(?:opencode\s+plugin\s+)?update\b/m.test(opencodeHelp)) {
|
|
76651
76866
|
plan.skipped.push({
|
|
76652
76867
|
host: "opencode",
|
|
@@ -76655,11 +76870,26 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
|
76655
76870
|
});
|
|
76656
76871
|
continue;
|
|
76657
76872
|
}
|
|
76873
|
+
const reading = opencodeReading(probes);
|
|
76874
|
+
if (reading === null) {
|
|
76875
|
+
plan.failed.push({
|
|
76876
|
+
host: "opencode",
|
|
76877
|
+
status: "failed",
|
|
76878
|
+
reason: OPENCODE_NOT_READY,
|
|
76879
|
+
fix: OPENCODE_UPDATE
|
|
76880
|
+
});
|
|
76881
|
+
continue;
|
|
76882
|
+
}
|
|
76883
|
+
const published = registryVersion(run, OPENCODE_PACKAGE);
|
|
76658
76884
|
plan.entries.push({
|
|
76659
76885
|
host: "opencode",
|
|
76660
76886
|
selector: source.selector,
|
|
76661
76887
|
latest: "",
|
|
76662
|
-
|
|
76888
|
+
...published ? { published } : {},
|
|
76889
|
+
...reading?.version ? { installedVersion: reading.version } : {},
|
|
76890
|
+
commands: [
|
|
76891
|
+
{ command: "opencode", args: ["plugin", "update", OPENCODE_PACKAGE], cwd: home }
|
|
76892
|
+
],
|
|
76663
76893
|
fix: OPENCODE_UPDATE
|
|
76664
76894
|
});
|
|
76665
76895
|
continue;
|
|
@@ -76746,7 +76976,7 @@ var codexRegistered = (configFile) => {
|
|
|
76746
76976
|
}
|
|
76747
76977
|
};
|
|
76748
76978
|
guard("opencode", () => {
|
|
76749
|
-
if (
|
|
76979
|
+
if (existsSync24(paths.opencodeConfig + "c"))
|
|
76750
76980
|
throw new Error("OpenCode JSONC config is present; inspect effective native configuration before updating");
|
|
76751
76981
|
const oc = object2(paths.opencodeConfig);
|
|
76752
76982
|
if (oc && [oc.plugins, oc.plugin].some((value) => value !== undefined && !Array.isArray(value)))
|
|
@@ -76756,8 +76986,8 @@ var codexRegistered = (configFile) => {
|
|
|
76756
76986
|
result.push(classify("opencode", pin));
|
|
76757
76987
|
});
|
|
76758
76988
|
guard("cursor", () => {
|
|
76759
|
-
const cursor = objectOrNull(
|
|
76760
|
-
const mcp = objectOrNull(
|
|
76989
|
+
const cursor = objectOrNull(path51.join(paths.cursorRoot, "package.json"));
|
|
76990
|
+
const mcp = objectOrNull(path51.join(home, ".cursor/mcp.json"));
|
|
76761
76991
|
const args = mcp?.mcpServers?.workit?.args ?? [];
|
|
76762
76992
|
const arg = args.find((value) => typeof value === "string" && value.startsWith("--package="));
|
|
76763
76993
|
const selector = typeof arg === "string" ? arg.slice(10) : "local";
|
|
@@ -76768,7 +76998,7 @@ var codexRegistered = (configFile) => {
|
|
|
76768
76998
|
});
|
|
76769
76999
|
return;
|
|
76770
77000
|
}
|
|
76771
|
-
const settings = objectOrNull(
|
|
77001
|
+
const settings = objectOrNull(path51.join(home, ".cursor/settings.json"));
|
|
76772
77002
|
const dirs = Array.isArray(settings?.plugin_dirs) ? settings.plugin_dirs : [];
|
|
76773
77003
|
const registered = mcp?.mcpServers?.workit !== undefined || dirs.some((dir) => String(dir).replaceAll("\\", "/").replace(/\/+$/, "").endsWith("local/workit"));
|
|
76774
77004
|
if (registered)
|
|
@@ -76783,12 +77013,14 @@ var codexRegistered = (configFile) => {
|
|
|
76783
77013
|
if (typeof source !== "string")
|
|
76784
77014
|
continue;
|
|
76785
77015
|
const npm = /^(?:npm:)?@brainervirus\/workit-pi(?:@[^/]+)?$/.test(source);
|
|
76786
|
-
const local =
|
|
77016
|
+
const local = path51.isAbsolute(source) && source.replaceAll("\\", "/").endsWith("/packages/workit-pi") && object2(path51.join(source, "package.json"))?.name === "@brainervirus/workit-pi";
|
|
76787
77017
|
if (!npm && !local)
|
|
76788
77018
|
continue;
|
|
76789
77019
|
const found = classify("pi", source);
|
|
76790
77020
|
if (found.kind === "floating") {
|
|
76791
77021
|
const inventory = run("pi", ["list"]);
|
|
77022
|
+
if (inventory.timedOut)
|
|
77023
|
+
throw new Error(`could not check: ${inventory.stderr}`);
|
|
76792
77024
|
if (inventory.status === 0)
|
|
76793
77025
|
found.installedVersion = piInstalledVersion(inventory.stdout, source);
|
|
76794
77026
|
}
|
|
@@ -76797,13 +77029,15 @@ var codexRegistered = (configFile) => {
|
|
|
76797
77029
|
});
|
|
76798
77030
|
guard("codex", () => {
|
|
76799
77031
|
const listing = run("codex", ["plugin", "list", "--json"]);
|
|
77032
|
+
if (listing.timedOut)
|
|
77033
|
+
throw new Error(`could not check: ${listing.stderr}`);
|
|
76800
77034
|
if (listing.status !== 0) {
|
|
76801
77035
|
let available = false;
|
|
76802
77036
|
try {
|
|
76803
77037
|
hostCommand("codex", [], { home, env: paths.env });
|
|
76804
77038
|
available = true;
|
|
76805
77039
|
} catch {}
|
|
76806
|
-
if (available ||
|
|
77040
|
+
if (available || existsSync24(paths.codexConfig))
|
|
76807
77041
|
throw new Error("Codex plugin inventory failed; inspect the native host before upgrading");
|
|
76808
77042
|
return;
|
|
76809
77043
|
}
|
|
@@ -76842,24 +77076,22 @@ var codexRegistered = (configFile) => {
|
|
|
76842
77076
|
});
|
|
76843
77077
|
});
|
|
76844
77078
|
return result;
|
|
76845
|
-
}, opencodeProbe = (deps, args) => {
|
|
76846
|
-
const
|
|
77079
|
+
}, opencodeProbe = (deps, args, probes) => {
|
|
77080
|
+
const cached = probes?.get(probeKey("opencode", args));
|
|
77081
|
+
if (cached)
|
|
77082
|
+
return cached;
|
|
77083
|
+
const scratch = mkdtempSync4(path51.join(os19.tmpdir(), "workit-upgrade-opencode-"));
|
|
76847
77084
|
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);
|
|
77085
|
+
return runner({ ...deps, env: opencodeScratchEnv(deps, scratch) })("opencode", args);
|
|
76857
77086
|
} finally {
|
|
76858
|
-
|
|
77087
|
+
rmSync9(scratch, { recursive: true, force: true });
|
|
76859
77088
|
}
|
|
77089
|
+
}, probedRunner = (deps, probes) => {
|
|
77090
|
+
const run = runner(deps);
|
|
77091
|
+
return probes ? (command, args) => probes.get(probeKey(command, args)) ?? run(command, args) : run;
|
|
76860
77092
|
}, planCli = (plan, run) => {
|
|
76861
77093
|
const root = run("npm", ["root", "--global"]);
|
|
76862
|
-
if (root.status !== 0 || !
|
|
77094
|
+
if (root.status !== 0 || !path51.isAbsolute(root.stdout.trim())) {
|
|
76863
77095
|
plan.skipped.push({
|
|
76864
77096
|
host: "cli",
|
|
76865
77097
|
reason: "global npm location could not be verified",
|
|
@@ -76867,9 +77099,9 @@ var codexRegistered = (configFile) => {
|
|
|
76867
77099
|
});
|
|
76868
77100
|
return;
|
|
76869
77101
|
}
|
|
76870
|
-
const packageFile =
|
|
77102
|
+
const packageFile = path51.join(root.stdout.trim(), "@brainervirus/workit-cli/package.json");
|
|
76871
77103
|
const installed = objectOrNull(packageFile);
|
|
76872
|
-
if (installed?.name !== "@brainervirus/workit-cli" || lstatSync8(
|
|
77104
|
+
if (installed?.name !== "@brainervirus/workit-cli" || lstatSync8(path51.dirname(packageFile)).isSymbolicLink()) {
|
|
76873
77105
|
plan.skipped.push({
|
|
76874
77106
|
host: "cli",
|
|
76875
77107
|
reason: "no managed global CLI install (local links preserved); use npx @brainervirus/workit-cli@latest"
|
|
@@ -76898,6 +77130,8 @@ var codexRegistered = (configFile) => {
|
|
|
76898
77130
|
});
|
|
76899
77131
|
};
|
|
76900
77132
|
var init_plan = __esm(() => {
|
|
77133
|
+
init_probes();
|
|
77134
|
+
init_opencode();
|
|
76901
77135
|
init_registration();
|
|
76902
77136
|
init_setup_state();
|
|
76903
77137
|
init_host_install();
|
|
@@ -76907,11 +77141,17 @@ var init_plan = __esm(() => {
|
|
|
76907
77141
|
});
|
|
76908
77142
|
|
|
76909
77143
|
// packages/workit-cli/src/upgrade/check.ts
|
|
76910
|
-
import
|
|
76911
|
-
function runUpdateCheck(json, deps) {
|
|
77144
|
+
import path52 from "node:path";
|
|
77145
|
+
async function runUpdateCheck(json, deps) {
|
|
76912
77146
|
const out = deps.out ?? process.stdout;
|
|
76913
77147
|
const paths = upgradePaths(deps);
|
|
76914
|
-
const
|
|
77148
|
+
const progress = deps.progress ?? createProgress({ stream: process.stderr, json });
|
|
77149
|
+
const checking = HOSTS2.length + 1;
|
|
77150
|
+
const probes = await progress.run(`Checking ${checking} hosts`, () => runProbes(HOSTS2, true, deps, {
|
|
77151
|
+
check: true,
|
|
77152
|
+
registries: ["@brainervirus/workit-claude-code"]
|
|
77153
|
+
}));
|
|
77154
|
+
const run = probedRunner(deps, probes);
|
|
76915
77155
|
const latest = (name) => registryVersion(run, name);
|
|
76916
77156
|
const cliLatest = latest(CLI_PACKAGE2);
|
|
76917
77157
|
if (cliLatest)
|
|
@@ -76952,14 +77192,27 @@ function runUpdateCheck(json, deps) {
|
|
|
76952
77192
|
}
|
|
76953
77193
|
if (!versionBy.has(host))
|
|
76954
77194
|
continue;
|
|
76955
|
-
const
|
|
77195
|
+
const reading = host === "opencode" ? opencodeReading(probes) : undefined;
|
|
77196
|
+
if (reading === null) {
|
|
77197
|
+
components.push({
|
|
77198
|
+
component: host,
|
|
77199
|
+
package: name,
|
|
77200
|
+
installed: null,
|
|
77201
|
+
latest: null,
|
|
77202
|
+
status: "unreadable",
|
|
77203
|
+
reason: OPENCODE_NOT_READY
|
|
77204
|
+
});
|
|
77205
|
+
continue;
|
|
77206
|
+
}
|
|
77207
|
+
const version = versionBy.get(host) ?? reading?.version;
|
|
76956
77208
|
const newest = latest(name);
|
|
77209
|
+
const status = statusOf(version, newest);
|
|
76957
77210
|
components.push({
|
|
76958
77211
|
component: host,
|
|
76959
77212
|
package: name,
|
|
76960
77213
|
installed: version ?? null,
|
|
76961
77214
|
latest: newest ?? null,
|
|
76962
|
-
status:
|
|
77215
|
+
status: reading?.outdated && status === "current" ? "update" : status
|
|
76963
77216
|
});
|
|
76964
77217
|
}
|
|
76965
77218
|
const pending = components.some((entry) => entry.status === "update" || entry.status === "unknown");
|
|
@@ -77009,7 +77262,7 @@ function runSetUpdates(value, deps) {
|
|
|
77009
77262
|
`);
|
|
77010
77263
|
return 1;
|
|
77011
77264
|
}
|
|
77012
|
-
out.write(`updates: ${value} (saved in ${
|
|
77265
|
+
out.write(`updates: ${value} (saved in ${path52.join(configDir, "config.json")})
|
|
77013
77266
|
`);
|
|
77014
77267
|
return 0;
|
|
77015
77268
|
}
|
|
@@ -77019,7 +77272,10 @@ var init_check = __esm(() => {
|
|
|
77019
77272
|
init_package();
|
|
77020
77273
|
init_style();
|
|
77021
77274
|
init_update_check();
|
|
77275
|
+
init_progress();
|
|
77276
|
+
init_opencode();
|
|
77022
77277
|
init_plan();
|
|
77278
|
+
init_probes();
|
|
77023
77279
|
init_shared();
|
|
77024
77280
|
SET_USAGE = `Usage: workit upgrade --set-updates=${UPDATES_MODES.join("|")}
|
|
77025
77281
|
`;
|
|
@@ -77106,7 +77362,24 @@ __export(exports_upgrade, {
|
|
|
77106
77362
|
runUpgradeCommand: () => runUpgradeCommand
|
|
77107
77363
|
});
|
|
77108
77364
|
import { spawnSync as spawnSync18 } from "node:child_process";
|
|
77365
|
+
import { mkdtempSync as mkdtempSync5, readFileSync as readFileSync26, rmSync as rmSync10, writeFileSync as writeFileSync14 } from "node:fs";
|
|
77366
|
+
import os20 from "node:os";
|
|
77367
|
+
import path53 from "node:path";
|
|
77109
77368
|
async function runUpgradeCommand(argv, deps = {}) {
|
|
77369
|
+
const { env } = upgradePaths(deps);
|
|
77370
|
+
const handBack = env[CONTINUE_ENV] !== undefined ? env[ROWS_ENV] : undefined;
|
|
77371
|
+
const handed = {};
|
|
77372
|
+
const code = await upgradeOnce(argv, deps, handed);
|
|
77373
|
+
if (!handBack)
|
|
77374
|
+
return code;
|
|
77375
|
+
try {
|
|
77376
|
+
writeFileSync14(handBack, JSON.stringify({ code, rows: handed.rows ?? [] }));
|
|
77377
|
+
return 0;
|
|
77378
|
+
} catch {
|
|
77379
|
+
return code;
|
|
77380
|
+
}
|
|
77381
|
+
}
|
|
77382
|
+
async function upgradeOnce(argv, deps, handed) {
|
|
77110
77383
|
const out = deps.out ?? process.stdout;
|
|
77111
77384
|
const setting = argv.find((arg) => arg.startsWith("--set-updates="));
|
|
77112
77385
|
if (argv.includes("--check") || setting) {
|
|
@@ -77115,7 +77388,7 @@ async function runUpgradeCommand(argv, deps = {}) {
|
|
|
77115
77388
|
out.write(USAGE3);
|
|
77116
77389
|
return 2;
|
|
77117
77390
|
}
|
|
77118
|
-
return setting ? runSetUpdates(setting.slice("--set-updates=".length), deps) : runUpdateCheck(argv.includes("--json"), deps);
|
|
77391
|
+
return setting ? runSetUpdates(setting.slice("--set-updates=".length), deps) : await runUpdateCheck(argv.includes("--json"), deps);
|
|
77119
77392
|
}
|
|
77120
77393
|
const flags = new Set(argv);
|
|
77121
77394
|
const unknown = argv.filter((arg) => !["--apply", "--confirm", "--json", "--cli", "--preview", "--yes"].includes(arg) && !arg.startsWith("--hosts="));
|
|
@@ -77132,16 +77405,19 @@ async function runUpgradeCommand(argv, deps = {}) {
|
|
|
77132
77405
|
}
|
|
77133
77406
|
const legacy = flags.has("--apply");
|
|
77134
77407
|
const json = flags.has("--json") || legacy;
|
|
77135
|
-
const
|
|
77408
|
+
const { home, env } = upgradePaths(deps);
|
|
77409
|
+
const continued = env[CONTINUE_ENV] !== undefined ? priorRows(env[CONTINUE_ENV]) : undefined;
|
|
77136
77410
|
const progress = deps.progress ?? createProgress({ stream: process.stderr, json });
|
|
77137
|
-
const
|
|
77138
|
-
|
|
77139
|
-
|
|
77140
|
-
|
|
77411
|
+
const withCli = !continued && (hostFlag === undefined || flags.has("--cli"));
|
|
77412
|
+
const checking = raw.length + (withCli ? 1 : 0);
|
|
77413
|
+
const plan = await progress.run(`Checking ${checking} ${checking === 1 ? "host" : "hosts"}`, async () => {
|
|
77414
|
+
const probes = await runProbes(raw, withCli, deps);
|
|
77415
|
+
const planned = previewUpgrade(raw, deps, probes);
|
|
77416
|
+
if (withCli)
|
|
77417
|
+
planCli(planned, probedRunner(deps, probes));
|
|
77141
77418
|
return planned;
|
|
77142
77419
|
});
|
|
77143
77420
|
plan.ok = plan.blocked.length === 0 && plan.failed.length === 0;
|
|
77144
|
-
const { home, env } = upgradePaths(deps);
|
|
77145
77421
|
const style = createStyle({
|
|
77146
77422
|
stream: out === process.stdout ? process.stdout : out === process.stderr ? process.stderr : undefined,
|
|
77147
77423
|
env,
|
|
@@ -77172,7 +77448,8 @@ async function runUpgradeCommand(argv, deps = {}) {
|
|
|
77172
77448
|
return plan.blocked.length ? 1 : 0;
|
|
77173
77449
|
}
|
|
77174
77450
|
if (!json)
|
|
77175
|
-
out.write(
|
|
77451
|
+
out.write(continued ? `Continuing the upgrade with the new CLI (workit ${package_default.version}).
|
|
77452
|
+
` : summary(plan, permissions.changes, style));
|
|
77176
77453
|
if (flags.has("--preview")) {
|
|
77177
77454
|
out.write(nothingChanged);
|
|
77178
77455
|
return plan.blocked.length ? 1 : 0;
|
|
@@ -77195,7 +77472,44 @@ Nothing changed.
|
|
|
77195
77472
|
for (const warning of plan.warnings ?? [])
|
|
77196
77473
|
out.write(`warning: ${warning}
|
|
77197
77474
|
`);
|
|
77198
|
-
const
|
|
77475
|
+
const reexec = deps.reexec ?? (deps.run && !deps.cliEntry ? undefined : spawnUpgrade({
|
|
77476
|
+
entry: deps.cliEntry ?? process.argv[1],
|
|
77477
|
+
out,
|
|
77478
|
+
toStderr: out === process.stderr,
|
|
77479
|
+
json
|
|
77480
|
+
}));
|
|
77481
|
+
const handoff = async (cli) => {
|
|
77482
|
+
if (!reexec || (deps.cliOnDisk ?? runningCliVersion)() !== plan.cli?.latest)
|
|
77483
|
+
return;
|
|
77484
|
+
const scratch = mkdtempSync5(path53.join(os20.tmpdir(), "workit-upgrade-"));
|
|
77485
|
+
const rowsFile = path53.join(scratch, "rows.json");
|
|
77486
|
+
try {
|
|
77487
|
+
const code = await reexec([
|
|
77488
|
+
...legacy ? ["--apply", "--confirm"] : ["--yes"],
|
|
77489
|
+
...flags.has("--json") ? ["--json"] : [],
|
|
77490
|
+
`--hosts=${raw.length ? raw.join(",") : "none"}`
|
|
77491
|
+
], {
|
|
77492
|
+
[CONTINUE_ENV]: JSON.stringify([cli]),
|
|
77493
|
+
[ROWS_ENV]: rowsFile,
|
|
77494
|
+
WORKIT_UPDATE_CHECK: "0"
|
|
77495
|
+
});
|
|
77496
|
+
if (code === undefined)
|
|
77497
|
+
return;
|
|
77498
|
+
const back = handedBack(readText5(rowsFile));
|
|
77499
|
+
deps.onResult?.(back?.rows.length ? back.rows : [cli]);
|
|
77500
|
+
return back?.code ?? code;
|
|
77501
|
+
} finally {
|
|
77502
|
+
rmSync10(scratch, { recursive: true, force: true });
|
|
77503
|
+
}
|
|
77504
|
+
};
|
|
77505
|
+
const result = await applyUpgrade(plan, { ...deps, progress }, continued || !reexec ? {} : { handoff });
|
|
77506
|
+
if (result.handedOff !== undefined)
|
|
77507
|
+
return result.handedOff;
|
|
77508
|
+
if (continued?.length) {
|
|
77509
|
+
result.hosts.unshift(...continued);
|
|
77510
|
+
if (continued.some((row) => row.status === "failed"))
|
|
77511
|
+
result.ok = false;
|
|
77512
|
+
}
|
|
77199
77513
|
let permissionsOk = true;
|
|
77200
77514
|
let written;
|
|
77201
77515
|
if (permissions.changes.length && !permissions.refused && !result.error?.startsWith("configuration changed")) {
|
|
@@ -77210,8 +77524,9 @@ Nothing changed.
|
|
|
77210
77524
|
});
|
|
77211
77525
|
}
|
|
77212
77526
|
deps.onResult?.(result.hosts);
|
|
77527
|
+
handed.rows = result.hosts;
|
|
77213
77528
|
const failed = !result.ok || !permissionsOk;
|
|
77214
|
-
const cliVersion = result.hosts.some((h) => h.host === "cli" && h.status === "updated") ? plan.cli.latest : package_default.version;
|
|
77529
|
+
const cliVersion = plan.cli && result.hosts.some((h) => h.host === "cli" && h.status === "updated") ? plan.cli.latest : package_default.version;
|
|
77215
77530
|
const report = progress.runSync("Checking the result with workit doctor", () => (deps.doctor ?? ((version) => runDoctor({ home, env, cliVersion: version, only: "upgrade" })))(cliVersion));
|
|
77216
77531
|
const left = report.checks.filter((check) => check.status === "warn" || check.status === "fail");
|
|
77217
77532
|
if (json) {
|
|
@@ -77234,7 +77549,7 @@ Nothing changed.
|
|
|
77234
77549
|
if (result.backup)
|
|
77235
77550
|
out.write(`Backup: ${style.path(result.backup)}
|
|
77236
77551
|
`);
|
|
77237
|
-
out.write(left.length === 0 ? `${style.ok("Verified:")} workit doctor is clean for versions, assets, agents and permissions.
|
|
77552
|
+
out.write(left.length === 0 ? `${style.ok("Verified:")} workit doctor is clean for versions, assets, agents, stale installs and permissions.
|
|
77238
77553
|
` : `${style.warn("Left after upgrade (workit doctor):")}
|
|
77239
77554
|
${left.map((check) => ` ${style.bold(check.id)}: ${check.detail}${check.fix ? `
|
|
77240
77555
|
fix: ${style.command(check.fix)}` : ""}`).join(`
|
|
@@ -77295,7 +77610,68 @@ async function runLaunchCommand(argv, deps = {}) {
|
|
|
77295
77610
|
var USAGE3 = `Usage: workit upgrade [--hosts=opencode,cursor,codex,pi,claude-code|none] [--cli] [--preview | --yes | --apply --confirm] [--json]
|
|
77296
77611
|
workit upgrade --check [--json]
|
|
77297
77612
|
workit upgrade --set-updates=prompt|auto|off
|
|
77298
|
-
|
|
77613
|
+
`, CONTINUE_ENV = "WORKIT_UPGRADE_CONTINUE", ROWS_ENV = "WORKIT_UPGRADE_ROWS", readText5 = (file) => {
|
|
77614
|
+
try {
|
|
77615
|
+
return readFileSync26(file, "utf8");
|
|
77616
|
+
} catch {
|
|
77617
|
+
return;
|
|
77618
|
+
}
|
|
77619
|
+
}, priorRows = (text) => {
|
|
77620
|
+
if (text === undefined)
|
|
77621
|
+
return;
|
|
77622
|
+
try {
|
|
77623
|
+
const rows = JSON.parse(text);
|
|
77624
|
+
return Array.isArray(rows) ? rows.filter((row) => typeof row?.host === "string" && typeof row?.status === "string" && typeof row?.reason === "string") : [];
|
|
77625
|
+
} catch {
|
|
77626
|
+
return [];
|
|
77627
|
+
}
|
|
77628
|
+
}, handedBack = (text) => {
|
|
77629
|
+
if (text === undefined)
|
|
77630
|
+
return;
|
|
77631
|
+
try {
|
|
77632
|
+
const value = JSON.parse(text);
|
|
77633
|
+
return {
|
|
77634
|
+
code: typeof value.code === "number" ? value.code : undefined,
|
|
77635
|
+
rows: priorRows(JSON.stringify(value.rows ?? [])) ?? []
|
|
77636
|
+
};
|
|
77637
|
+
} catch {
|
|
77638
|
+
return;
|
|
77639
|
+
}
|
|
77640
|
+
}, runningCliVersion = () => {
|
|
77641
|
+
const script = process.argv[1];
|
|
77642
|
+
if (!script)
|
|
77643
|
+
return;
|
|
77644
|
+
let dir = path53.dirname(script);
|
|
77645
|
+
for (let depth = 0;depth < 4; depth += 1, dir = path53.dirname(dir)) {
|
|
77646
|
+
const found = cliPackageVersion(readText5(path53.join(dir, "package.json")));
|
|
77647
|
+
if (found)
|
|
77648
|
+
return found;
|
|
77649
|
+
}
|
|
77650
|
+
return;
|
|
77651
|
+
}, cliPackageVersion = (text) => {
|
|
77652
|
+
if (text === undefined)
|
|
77653
|
+
return;
|
|
77654
|
+
try {
|
|
77655
|
+
const found = JSON.parse(text);
|
|
77656
|
+
return found.name === package_default.name && typeof found.version === "string" ? found.version : undefined;
|
|
77657
|
+
} catch {
|
|
77658
|
+
return;
|
|
77659
|
+
}
|
|
77660
|
+
}, spawnUpgrade = (options) => (argv, extra) => {
|
|
77661
|
+
if (!options.entry)
|
|
77662
|
+
return;
|
|
77663
|
+
const result = spawnSync18(process.execPath, [options.entry, "upgrade", ...argv], {
|
|
77664
|
+
stdio: ["inherit", options.json ? "pipe" : options.toStderr ? 2 : "inherit", "inherit"],
|
|
77665
|
+
encoding: "utf8",
|
|
77666
|
+
maxBuffer: 64 * 1024 * 1024,
|
|
77667
|
+
env: { ...process.env, ...extra }
|
|
77668
|
+
});
|
|
77669
|
+
if (result.error)
|
|
77670
|
+
return;
|
|
77671
|
+
if (options.json && result.stdout)
|
|
77672
|
+
options.out.write(result.stdout);
|
|
77673
|
+
return result.status ?? 1;
|
|
77674
|
+
};
|
|
77299
77675
|
var init_upgrade = __esm(() => {
|
|
77300
77676
|
init_package();
|
|
77301
77677
|
init_host_install();
|
|
@@ -77306,6 +77682,7 @@ var init_upgrade = __esm(() => {
|
|
|
77306
77682
|
init_apply();
|
|
77307
77683
|
init_check();
|
|
77308
77684
|
init_plan();
|
|
77685
|
+
init_probes();
|
|
77309
77686
|
init_report();
|
|
77310
77687
|
init_shared();
|
|
77311
77688
|
init_apply();
|
|
@@ -77336,7 +77713,7 @@ var init_launch = __esm(() => {
|
|
|
77336
77713
|
// packages/workit-core/src/knowledge.ts
|
|
77337
77714
|
import { spawnSync as spawnSync19 } from "node:child_process";
|
|
77338
77715
|
import fs20 from "node:fs";
|
|
77339
|
-
import
|
|
77716
|
+
import path54 from "node:path";
|
|
77340
77717
|
function lintKnowledge(root) {
|
|
77341
77718
|
const seen = new Set;
|
|
77342
77719
|
const unreadable = [];
|
|
@@ -77440,7 +77817,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
77440
77817
|
const end = lines.indexOf("---", 1);
|
|
77441
77818
|
return end === -1 ? lines : [...lines.slice(0, end + 1).map(() => ""), ...lines.slice(end + 1)];
|
|
77442
77819
|
}, read = (root, file) => {
|
|
77443
|
-
const full =
|
|
77820
|
+
const full = path54.join(root, file);
|
|
77444
77821
|
try {
|
|
77445
77822
|
fs20.lstatSync(full);
|
|
77446
77823
|
} catch {
|
|
@@ -77481,7 +77858,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
77481
77858
|
}
|
|
77482
77859
|
}, brokenLinks = (root, doc, tracked) => {
|
|
77483
77860
|
const findings = [];
|
|
77484
|
-
const base =
|
|
77861
|
+
const base = path54.dirname(path54.join(root, doc.file));
|
|
77485
77862
|
const missing = (target, line, how) => findings.push({
|
|
77486
77863
|
rule: "broken-link",
|
|
77487
77864
|
file: doc.file,
|
|
@@ -77500,7 +77877,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
77500
77877
|
const local = localTarget(target);
|
|
77501
77878
|
if (!local)
|
|
77502
77879
|
continue;
|
|
77503
|
-
const resolved = local.startsWith("/") ?
|
|
77880
|
+
const resolved = local.startsWith("/") ? path54.join(root, local) : path54.resolve(base, local);
|
|
77504
77881
|
if (!exists2(resolved))
|
|
77505
77882
|
missing(target, index + 1, "link");
|
|
77506
77883
|
}
|
|
@@ -77510,9 +77887,9 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
77510
77887
|
continue;
|
|
77511
77888
|
const relative = /^\.\.?\//.test(candidate);
|
|
77512
77889
|
const first = candidate.split("/")[0];
|
|
77513
|
-
if (!relative && !(tracked ? tracked.has(first) : exists2(
|
|
77890
|
+
if (!relative && !(tracked ? tracked.has(first) : exists2(path54.join(root, first))))
|
|
77514
77891
|
continue;
|
|
77515
|
-
const resolved = relative ?
|
|
77892
|
+
const resolved = relative ? path54.resolve(base, candidate) : path54.join(root, candidate);
|
|
77516
77893
|
if (!exists2(resolved))
|
|
77517
77894
|
missing(span, index + 1, "pointer");
|
|
77518
77895
|
}
|
|
@@ -77881,8 +78258,8 @@ var init_redact = __esm(() => {
|
|
|
77881
78258
|
import { spawn as spawn4, spawnSync as spawnSync20 } from "node:child_process";
|
|
77882
78259
|
import { createHash as createHash17 } from "node:crypto";
|
|
77883
78260
|
import fs21 from "node:fs";
|
|
77884
|
-
import
|
|
77885
|
-
import
|
|
78261
|
+
import os21 from "node:os";
|
|
78262
|
+
import path55 from "node:path";
|
|
77886
78263
|
import { StringDecoder } from "node:string_decoder";
|
|
77887
78264
|
function tailLines(text, lines = TAIL_LINES) {
|
|
77888
78265
|
const all = text.replace(/\r\n?/gu, `
|
|
@@ -78002,7 +78379,7 @@ function planSpawn(argv, options) {
|
|
|
78002
78379
|
return { file: argv[0], args: [], verbatim: false, shell: true };
|
|
78003
78380
|
if (options.platform !== "win32")
|
|
78004
78381
|
return { file: argv[0], args: argv.slice(1), verbatim: false, shell: false };
|
|
78005
|
-
const win =
|
|
78382
|
+
const win = path55.win32;
|
|
78006
78383
|
const isFile = options.isFile ?? ((file) => {
|
|
78007
78384
|
try {
|
|
78008
78385
|
return fs21.statSync(file).isFile();
|
|
@@ -78087,7 +78464,7 @@ function runCheckCommand(argv, options) {
|
|
|
78087
78464
|
`);
|
|
78088
78465
|
redactor.end();
|
|
78089
78466
|
resolve({
|
|
78090
|
-
exitCode: spawnError ? 127 : code !== null ? code : 128 + (signal ?
|
|
78467
|
+
exitCode: spawnError ? 127 : code !== null ? code : 128 + (signal ? os21.constants.signals[signal] ?? 1 : 1),
|
|
78091
78468
|
signal: signal ?? null,
|
|
78092
78469
|
timedOut,
|
|
78093
78470
|
durationMs: Date.now() - started,
|
|
@@ -78164,10 +78541,10 @@ function runCheckCommand(argv, options) {
|
|
|
78164
78541
|
function storeLog(storeRoot, log) {
|
|
78165
78542
|
const digest = logDigest(log);
|
|
78166
78543
|
const ref = `blobs/logs/${digest.slice("sha256:".length)}.log`;
|
|
78167
|
-
const file =
|
|
78544
|
+
const file = path55.join(storeRoot, ref);
|
|
78168
78545
|
try {
|
|
78169
78546
|
if (!fs21.existsSync(file)) {
|
|
78170
|
-
fs21.mkdirSync(
|
|
78547
|
+
fs21.mkdirSync(path55.dirname(file), { recursive: true });
|
|
78171
78548
|
const temp = `${file}.${process.pid}.${Date.now()}.tmp`;
|
|
78172
78549
|
fs21.writeFileSync(temp, log, { mode: 384 });
|
|
78173
78550
|
fs21.renameSync(temp, file);
|
|
@@ -78180,7 +78557,7 @@ function storeLog(storeRoot, log) {
|
|
|
78180
78557
|
function pruneCheckLogs(storeRoot, options = {}) {
|
|
78181
78558
|
const limits = { ...LOG_RETENTION, ...options.retention };
|
|
78182
78559
|
const now = options.now ?? Date.now();
|
|
78183
|
-
const dir =
|
|
78560
|
+
const dir = path55.join(storeRoot, "blobs", "logs");
|
|
78184
78561
|
const report = { removed: 0, removedBytes: 0, kept: 0 };
|
|
78185
78562
|
let names;
|
|
78186
78563
|
try {
|
|
@@ -78190,7 +78567,7 @@ function pruneCheckLogs(storeRoot, options = {}) {
|
|
|
78190
78567
|
}
|
|
78191
78568
|
const files = names.flatMap((name) => {
|
|
78192
78569
|
try {
|
|
78193
|
-
const stat = fs21.statSync(
|
|
78570
|
+
const stat = fs21.statSync(path55.join(dir, name));
|
|
78194
78571
|
return stat.isFile() ? [{ name, size: stat.size, mtimeMs: stat.mtimeMs }] : [];
|
|
78195
78572
|
} catch {
|
|
78196
78573
|
return [];
|
|
@@ -78209,7 +78586,7 @@ function pruneCheckLogs(storeRoot, options = {}) {
|
|
|
78209
78586
|
continue;
|
|
78210
78587
|
if (!options.dryRun)
|
|
78211
78588
|
try {
|
|
78212
|
-
fs21.rmSync(
|
|
78589
|
+
fs21.rmSync(path55.join(dir, file.name), { force: true });
|
|
78213
78590
|
} catch {
|
|
78214
78591
|
continue;
|
|
78215
78592
|
}
|
|
@@ -78479,7 +78856,7 @@ __export(exports_workspace, {
|
|
|
78479
78856
|
run: () => run11,
|
|
78480
78857
|
runWorkspace: () => runWorkspace
|
|
78481
78858
|
});
|
|
78482
|
-
import { copyFileSync as copyFileSync7, existsSync as
|
|
78859
|
+
import { copyFileSync as copyFileSync7, existsSync as existsSync25 } from "node:fs";
|
|
78483
78860
|
function list2(argv, io) {
|
|
78484
78861
|
if (argv.length)
|
|
78485
78862
|
return usage3(io, `unexpected argument ${argv[0]}`);
|
|
@@ -78788,7 +79165,7 @@ usage: ${USAGE5}`)), load = (io) => {
|
|
|
78788
79165
|
return { ok: false, error: `${current.path} changed; retry` };
|
|
78789
79166
|
let backup = null;
|
|
78790
79167
|
try {
|
|
78791
|
-
if (
|
|
79168
|
+
if (existsSync25(current.path)) {
|
|
78792
79169
|
backup = `${current.path}.bak`;
|
|
78793
79170
|
copyFileSync7(current.path, backup);
|
|
78794
79171
|
}
|
|
@@ -78862,12 +79239,12 @@ var init_workspace = __esm(() => {
|
|
|
78862
79239
|
|
|
78863
79240
|
// packages/workit-core/src/core/heavy-rules.ts
|
|
78864
79241
|
import fs22 from "node:fs";
|
|
78865
|
-
import
|
|
79242
|
+
import path56 from "node:path";
|
|
78866
79243
|
function gitTop(cwd) {
|
|
78867
|
-
for (let dir =
|
|
78868
|
-
if (fs22.existsSync(
|
|
79244
|
+
for (let dir = path56.resolve(cwd);; dir = path56.dirname(dir)) {
|
|
79245
|
+
if (fs22.existsSync(path56.join(dir, ".git")))
|
|
78869
79246
|
return dir;
|
|
78870
|
-
if (
|
|
79247
|
+
if (path56.dirname(dir) === dir)
|
|
78871
79248
|
return null;
|
|
78872
79249
|
}
|
|
78873
79250
|
}
|
|
@@ -78908,19 +79285,19 @@ var init_heavy_rules = () => {};
|
|
|
78908
79285
|
|
|
78909
79286
|
// packages/workit-core/src/core/heavy.ts
|
|
78910
79287
|
import fs23 from "node:fs";
|
|
78911
|
-
import
|
|
78912
|
-
import
|
|
79288
|
+
import os22 from "node:os";
|
|
79289
|
+
import path57 from "node:path";
|
|
78913
79290
|
function stateDir2(env, platform = process.platform) {
|
|
78914
79291
|
if (env.WORKFLOW_TOOLKIT_STATE)
|
|
78915
79292
|
return env.WORKFLOW_TOOLKIT_STATE;
|
|
78916
79293
|
if (env.XDG_STATE_HOME)
|
|
78917
|
-
return
|
|
78918
|
-
const home = env.HOME ||
|
|
79294
|
+
return path57.join(env.XDG_STATE_HOME, "workit");
|
|
79295
|
+
const home = env.HOME || os22.homedir();
|
|
78919
79296
|
if (platform === "darwin")
|
|
78920
|
-
return
|
|
79297
|
+
return path57.join(home, "Library", "Application Support", "workit");
|
|
78921
79298
|
if (platform === "win32")
|
|
78922
|
-
return
|
|
78923
|
-
return
|
|
79299
|
+
return path57.join(env.LOCALAPPDATA ?? path57.join(home, "AppData", "Local"), "workit");
|
|
79300
|
+
return path57.join(home, ".local", "state", "workit");
|
|
78924
79301
|
}
|
|
78925
79302
|
function positional(words, from, values = PM_VALUES) {
|
|
78926
79303
|
let index = from;
|
|
@@ -79060,7 +79437,7 @@ function machinePatterns(env) {
|
|
|
79060
79437
|
return isRecord8(value) ? stringList2(value.patterns) : [];
|
|
79061
79438
|
}
|
|
79062
79439
|
function repoPatterns(cwd) {
|
|
79063
|
-
return repoHeavyCommands(gitTop(cwd) ??
|
|
79440
|
+
return repoHeavyCommands(gitTop(cwd) ?? path57.resolve(cwd));
|
|
79064
79441
|
}
|
|
79065
79442
|
function heavyLines(lines, options) {
|
|
79066
79443
|
const found = [];
|
|
@@ -79139,7 +79516,7 @@ function leaseRewrite(command) {
|
|
|
79139
79516
|
return null;
|
|
79140
79517
|
return `${prefix}workit check --heavy -- ${rest}`;
|
|
79141
79518
|
}
|
|
79142
|
-
var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) =>
|
|
79519
|
+
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
79520
|
try {
|
|
79144
79521
|
return JSON.parse(fs23.readFileSync(file, "utf8"));
|
|
79145
79522
|
} catch {
|
|
@@ -79285,8 +79662,8 @@ var init_heavy = __esm(() => {
|
|
|
79285
79662
|
// packages/workit-core/src/core/resources.ts
|
|
79286
79663
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
79287
79664
|
import fs24 from "node:fs";
|
|
79288
|
-
import
|
|
79289
|
-
import
|
|
79665
|
+
import os23 from "node:os";
|
|
79666
|
+
import path58 from "node:path";
|
|
79290
79667
|
function memoryValue(value, host) {
|
|
79291
79668
|
const text = typeof value === "number" ? String(value) : typeof value === "string" ? value : "";
|
|
79292
79669
|
const percent = PERCENT.exec(text.trim());
|
|
@@ -79412,7 +79789,7 @@ function scopeBusy(unit) {
|
|
|
79412
79789
|
return false;
|
|
79413
79790
|
const uid = process.getuid?.() ?? 0;
|
|
79414
79791
|
const manager = `/sys/fs/cgroup/user.slice/user-${uid}.slice/user@${uid}.service`;
|
|
79415
|
-
return [`${manager}/app.slice/${unit}`, `${manager}/${unit}`].some((dir) => (
|
|
79792
|
+
return [`${manager}/app.slice/${unit}`, `${manager}/${unit}`].some((dir) => (readText6(`${dir}/cgroup.procs`) ?? "").trim() !== "");
|
|
79416
79793
|
}
|
|
79417
79794
|
function isAncestor(pid) {
|
|
79418
79795
|
if (process.platform !== "linux")
|
|
@@ -79469,7 +79846,7 @@ function reclaim(file, stale) {
|
|
|
79469
79846
|
} catch {
|
|
79470
79847
|
return true;
|
|
79471
79848
|
}
|
|
79472
|
-
if (!stale(parseLease(
|
|
79849
|
+
if (!stale(parseLease(readText6(file)), ageMs))
|
|
79473
79850
|
return false;
|
|
79474
79851
|
fs24.rmSync(file, { force: true });
|
|
79475
79852
|
return true;
|
|
@@ -79482,7 +79859,7 @@ function tryOnce(options, record, reclaimed) {
|
|
|
79482
79859
|
const text = `${JSON.stringify(record)}
|
|
79483
79860
|
`;
|
|
79484
79861
|
for (let slot = 0;slot < options.slots; slot += 1) {
|
|
79485
|
-
const file =
|
|
79862
|
+
const file = path58.join(options.dir, `slot-${slot}.json`);
|
|
79486
79863
|
for (let attempt = 0;attempt < 2; attempt += 1) {
|
|
79487
79864
|
try {
|
|
79488
79865
|
const fd = fs24.openSync(file, "wx", 384);
|
|
@@ -79496,7 +79873,7 @@ function tryOnce(options, record, reclaimed) {
|
|
|
79496
79873
|
if (error.code !== "EEXIST")
|
|
79497
79874
|
throw error;
|
|
79498
79875
|
}
|
|
79499
|
-
const lease = parseLease(
|
|
79876
|
+
const lease = parseLease(readText6(file));
|
|
79500
79877
|
let reason = null;
|
|
79501
79878
|
const removed = reclaim(file, (current, ageMs) => {
|
|
79502
79879
|
reason = current ? staleReason(current, options.probe) : ageMs > UNREADABLE_TTL_MS ? "unreadable" : null;
|
|
@@ -79515,7 +79892,7 @@ function tryOnce(options, record, reclaimed) {
|
|
|
79515
79892
|
return { holders };
|
|
79516
79893
|
}
|
|
79517
79894
|
function removeOwn(file, id) {
|
|
79518
|
-
if (parseLease(
|
|
79895
|
+
if (parseLease(readText6(file))?.id === id)
|
|
79519
79896
|
fs24.rmSync(file, { force: true });
|
|
79520
79897
|
}
|
|
79521
79898
|
function leaseQueue(dir, probe = {}) {
|
|
@@ -79527,8 +79904,8 @@ function leaseQueue(dir, probe = {}) {
|
|
|
79527
79904
|
}
|
|
79528
79905
|
const entries = [];
|
|
79529
79906
|
for (const name of names.filter((item) => item.endsWith(".json")).toSorted()) {
|
|
79530
|
-
const file =
|
|
79531
|
-
const record = parseLease(
|
|
79907
|
+
const file = path58.join(queueDir(dir), name);
|
|
79908
|
+
const record = parseLease(readText6(file));
|
|
79532
79909
|
if (!record)
|
|
79533
79910
|
continue;
|
|
79534
79911
|
entries.push({
|
|
@@ -79543,9 +79920,9 @@ function leaseQueue(dir, probe = {}) {
|
|
|
79543
79920
|
function waitersAhead(options, own) {
|
|
79544
79921
|
let ahead = 0;
|
|
79545
79922
|
for (const entry of leaseQueue(options.dir, options.probe)) {
|
|
79546
|
-
if (
|
|
79923
|
+
if (path58.basename(entry.file) >= own)
|
|
79547
79924
|
break;
|
|
79548
|
-
if (!TICKET.test(
|
|
79925
|
+
if (!TICKET.test(path58.basename(entry.file)))
|
|
79549
79926
|
continue;
|
|
79550
79927
|
if (entry.stale && reclaim(entry.file, (current) => !current || staleReason(current, options.probe) !== null))
|
|
79551
79928
|
continue;
|
|
@@ -79557,7 +79934,7 @@ function liveHolders(options) {
|
|
|
79557
79934
|
return leaseSlots(options.dir, options.slots, options.probe).filter((slot) => slot.holder && !slot.stale).map((slot) => slot.holder);
|
|
79558
79935
|
}
|
|
79559
79936
|
function writeTicket(file, record) {
|
|
79560
|
-
fs24.mkdirSync(
|
|
79937
|
+
fs24.mkdirSync(path58.dirname(file), { recursive: true, mode: 448 });
|
|
79561
79938
|
fs24.writeFileSync(file, `${JSON.stringify(record)}
|
|
79562
79939
|
`, { mode: 384 });
|
|
79563
79940
|
}
|
|
@@ -79602,7 +79979,7 @@ async function acquireLease(options) {
|
|
|
79602
79979
|
const reclaimed = [];
|
|
79603
79980
|
let waitedOn = [];
|
|
79604
79981
|
const name = ticketName(started, record.id);
|
|
79605
|
-
const ticket =
|
|
79982
|
+
const ticket = path58.join(queueDir(options.dir), name);
|
|
79606
79983
|
const ticketRecord = {
|
|
79607
79984
|
...record,
|
|
79608
79985
|
maxAgeMs: options.waitMs + 60000
|
|
@@ -79703,7 +80080,7 @@ async function acquireLease(options) {
|
|
|
79703
80080
|
function updateLease(lease, patch) {
|
|
79704
80081
|
Object.assign(lease.record, patch);
|
|
79705
80082
|
try {
|
|
79706
|
-
if (parseLease(
|
|
80083
|
+
if (parseLease(readText6(lease.file))?.id !== lease.record.id)
|
|
79707
80084
|
return;
|
|
79708
80085
|
const temp = `${lease.file}.${process.pid}.tmp`;
|
|
79709
80086
|
fs24.writeFileSync(temp, `${JSON.stringify(lease.record)}
|
|
@@ -79723,7 +80100,7 @@ function heldLease(dir, id, options = {}) {
|
|
|
79723
80100
|
for (const name of names) {
|
|
79724
80101
|
if (!/^slot-\d+\.json$/u.test(name))
|
|
79725
80102
|
continue;
|
|
79726
|
-
const lease = parseLease(
|
|
80103
|
+
const lease = parseLease(readText6(path58.join(dir, name)));
|
|
79727
80104
|
if (lease?.id === id && !staleReason(lease, options.probe) && (options.ancestor ?? isAncestor)(lease.pid))
|
|
79728
80105
|
return lease;
|
|
79729
80106
|
}
|
|
@@ -79778,10 +80155,10 @@ async function runScoped(run, wrapper, sinks) {
|
|
|
79778
80155
|
}
|
|
79779
80156
|
function firstNotice(env, session, key, now = Date.now()) {
|
|
79780
80157
|
const id = (session ?? `ppid-${process.ppid}`).replace(/[^A-Za-z0-9_.-]/gu, "_").slice(0, 120);
|
|
79781
|
-
const dir =
|
|
80158
|
+
const dir = path58.join(stateDir2(env), "notices");
|
|
79782
80159
|
try {
|
|
79783
80160
|
fs24.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
79784
|
-
fs24.writeFileSync(
|
|
80161
|
+
fs24.writeFileSync(path58.join(dir, `${key}-${id}`), `${new Date(now).toISOString()}
|
|
79785
80162
|
`, {
|
|
79786
80163
|
flag: "wx",
|
|
79787
80164
|
mode: 384
|
|
@@ -79791,7 +80168,7 @@ function firstNotice(env, session, key, now = Date.now()) {
|
|
|
79791
80168
|
}
|
|
79792
80169
|
try {
|
|
79793
80170
|
for (const name of fs24.readdirSync(dir)) {
|
|
79794
|
-
const file =
|
|
80171
|
+
const file = path58.join(dir, name);
|
|
79795
80172
|
if (now - fs24.statSync(file).mtimeMs > NOTICE_TTL_MS)
|
|
79796
80173
|
fs24.rmSync(file, { force: true });
|
|
79797
80174
|
}
|
|
@@ -79801,7 +80178,7 @@ function firstNotice(env, session, key, now = Date.now()) {
|
|
|
79801
80178
|
function leaseSlots(dir, slots, probe = {}) {
|
|
79802
80179
|
const states = [];
|
|
79803
80180
|
for (let slot = 0;slot < slots; slot += 1) {
|
|
79804
|
-
const lease = parseLease(
|
|
80181
|
+
const lease = parseLease(readText6(path58.join(dir, `slot-${slot}.json`)));
|
|
79805
80182
|
states.push({
|
|
79806
80183
|
slot,
|
|
79807
80184
|
holder: lease ? holderOf(lease) : null,
|
|
@@ -79811,16 +80188,16 @@ function leaseSlots(dir, slots, probe = {}) {
|
|
|
79811
80188
|
return states;
|
|
79812
80189
|
}
|
|
79813
80190
|
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) =>
|
|
80191
|
+
totalMemBytes: os23.totalmem(),
|
|
80192
|
+
cpus: Math.max(1, os23.availableParallelism?.() ?? os23.cpus().length)
|
|
80193
|
+
}), isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), SIZE, PERCENT, UNITS, leaseDir = (env) => path58.join(stateDir2(env), "leases"), readText6 = (file) => {
|
|
79817
80194
|
try {
|
|
79818
80195
|
return fs24.readFileSync(file, "utf8");
|
|
79819
80196
|
} catch {
|
|
79820
80197
|
return null;
|
|
79821
80198
|
}
|
|
79822
|
-
}, bootId = () =>
|
|
79823
|
-
const stat =
|
|
80199
|
+
}, 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) => {
|
|
80200
|
+
const stat = readText6(`/proc/${pid}/stat`);
|
|
79824
80201
|
return stat ? stat.slice(stat.lastIndexOf(")") + 2).split(" ") : null;
|
|
79825
80202
|
}, processStart = (pid) => statFields(pid)?.[19] ?? null, pidAlive2 = (pid) => {
|
|
79826
80203
|
try {
|
|
@@ -79844,7 +80221,7 @@ var DEFAULT_HEAVY_CHECKS, DEFAULT_LIGHT_CHECKS, DEFAULT_SLOTS = 1, DEFAULT_WAIT_
|
|
|
79844
80221
|
cwd: lease.cwd,
|
|
79845
80222
|
session: lease.session,
|
|
79846
80223
|
startedAt: lease.startedAt
|
|
79847
|
-
}), realClock, queueDir = (dir) =>
|
|
80224
|
+
}), 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
80225
|
var init_resources = __esm(() => {
|
|
79849
80226
|
init_checks3();
|
|
79850
80227
|
init_heavy();
|
|
@@ -79873,8 +80250,8 @@ __export(exports_check, {
|
|
|
79873
80250
|
run: () => run12,
|
|
79874
80251
|
workspaceResources: () => workspaceResources
|
|
79875
80252
|
});
|
|
79876
|
-
import
|
|
79877
|
-
import
|
|
80253
|
+
import os24 from "node:os";
|
|
80254
|
+
import path59 from "node:path";
|
|
79878
80255
|
function parse6(argv) {
|
|
79879
80256
|
const split = argv.indexOf("--");
|
|
79880
80257
|
const head = split >= 0 ? argv.slice(0, split) : [...argv];
|
|
@@ -80105,7 +80482,7 @@ ${footer}`;
|
|
|
80105
80482
|
}
|
|
80106
80483
|
async function workspaceResources(io) {
|
|
80107
80484
|
const env = io.env;
|
|
80108
|
-
const dir = env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ??
|
|
80485
|
+
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
80486
|
try {
|
|
80110
80487
|
await Promise.resolve().then(() => init_workspaces());
|
|
80111
80488
|
const workspace = resolveWorkspaceFrom(io.cwd, dir, env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined);
|
|
@@ -80247,7 +80624,7 @@ async function run12(argv, io) {
|
|
|
80247
80624
|
if (options.shell && command.length !== 1)
|
|
80248
80625
|
return emit(io, fail2("invalid_input", '--shell takes the command as one string: workit check --shell -- "<cmd>"'));
|
|
80249
80626
|
}
|
|
80250
|
-
const relCwd = posix(
|
|
80627
|
+
const relCwd = posix(path59.relative(top, runCwd));
|
|
80251
80628
|
const configured = !options.shell && matchesNamedCheck(config, name, command, relCwd);
|
|
80252
80629
|
const shadowed = !configured && name !== null ? config.checks.find((item) => item.name === name) : undefined;
|
|
80253
80630
|
if (shadowed)
|
|
@@ -80312,7 +80689,7 @@ async function run12(argv, io) {
|
|
|
80312
80689
|
const modifiedWorktree = key.tree !== null && treeAfter !== key.tree;
|
|
80313
80690
|
const store = storeRoot(io.cwd);
|
|
80314
80691
|
const blob = store.ok ? storeLog(store.value.root, result.log) : null;
|
|
80315
|
-
const logPath = store.ok && blob ?
|
|
80692
|
+
const logPath = store.ok && blob ? path59.join(store.value.root, blob.ref) : null;
|
|
80316
80693
|
const tail = tailLines(result.log, TAIL_LINES);
|
|
80317
80694
|
const passed = result.exitCode === 0 && !result.timedOut;
|
|
80318
80695
|
const bounded = boundedArgv(command);
|
|
@@ -80427,7 +80804,7 @@ async function run12(argv, io) {
|
|
|
80427
80804
|
return recordError.code === "busy" ? 4 : recordError.code === "invalid_input" ? 2 : 5;
|
|
80428
80805
|
return 0;
|
|
80429
80806
|
}
|
|
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(
|
|
80807
|
+
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
80808
|
var init_check2 = __esm(() => {
|
|
80432
80809
|
init_check_config();
|
|
80433
80810
|
init_checks3();
|
|
@@ -80458,7 +80835,7 @@ __export(exports_lock, {
|
|
|
80458
80835
|
run: () => run13
|
|
80459
80836
|
});
|
|
80460
80837
|
import fs25 from "node:fs";
|
|
80461
|
-
import
|
|
80838
|
+
import path60 from "node:path";
|
|
80462
80839
|
async function settingsFor(io) {
|
|
80463
80840
|
const workspace = await workspaceResources(io);
|
|
80464
80841
|
const config = loadCheckConfig(io.cwd);
|
|
@@ -80550,7 +80927,7 @@ function readPatterns(file) {
|
|
|
80550
80927
|
return { patterns: [] };
|
|
80551
80928
|
}
|
|
80552
80929
|
function writePatterns(file, value) {
|
|
80553
|
-
fs25.mkdirSync(
|
|
80930
|
+
fs25.mkdirSync(path60.dirname(file), { recursive: true, mode: 448 });
|
|
80554
80931
|
const temp = `${file}.${process.pid}.tmp`;
|
|
80555
80932
|
fs25.writeFileSync(temp, `${JSON.stringify(value, null, 2)}
|
|
80556
80933
|
`, { mode: 384 });
|
|
@@ -80636,9 +81013,9 @@ var exports_models = {};
|
|
|
80636
81013
|
__export(exports_models, {
|
|
80637
81014
|
run: () => run14
|
|
80638
81015
|
});
|
|
80639
|
-
import { existsSync as
|
|
80640
|
-
import
|
|
80641
|
-
import
|
|
81016
|
+
import { existsSync as existsSync26, readdirSync as readdirSync13, readFileSync as readFileSync27, statSync as statSync9 } from "node:fs";
|
|
81017
|
+
import os25 from "node:os";
|
|
81018
|
+
import path61 from "node:path";
|
|
80642
81019
|
async function run14(argv, io) {
|
|
80643
81020
|
const [sub, ...args] = argv.filter((arg) => arg !== "--json");
|
|
80644
81021
|
if (sub !== "show")
|
|
@@ -80699,7 +81076,7 @@ var USAGE8 = "workit models show [--role <role>] [--tier <tier>] [--host <host>]
|
|
|
80699
81076
|
const found = new Set;
|
|
80700
81077
|
let text = "";
|
|
80701
81078
|
try {
|
|
80702
|
-
text =
|
|
81079
|
+
text = readFileSync27(file, "utf8");
|
|
80703
81080
|
} catch {
|
|
80704
81081
|
return found;
|
|
80705
81082
|
}
|
|
@@ -80713,26 +81090,26 @@ var USAGE8 = "workit models show [--role <role>] [--tier <tier>] [--host <host>]
|
|
|
80713
81090
|
} catch {}
|
|
80714
81091
|
return found;
|
|
80715
81092
|
}, matches3 = (ran, configured) => ran.toLowerCase().includes(configured.toLowerCase()), usageReport = (cwd, env, days) => {
|
|
80716
|
-
const projects =
|
|
81093
|
+
const projects = path61.join(env.CLAUDE_CONFIG_DIR || path61.join(env.HOME || os25.homedir(), ".claude"), "projects");
|
|
80717
81094
|
const since = Date.now() - days * 86400000;
|
|
80718
81095
|
const types = {};
|
|
80719
81096
|
let agents = 0;
|
|
80720
81097
|
const dirs = (dir) => {
|
|
80721
81098
|
try {
|
|
80722
|
-
return readdirSync13(dir).map((name) =>
|
|
81099
|
+
return readdirSync13(dir).map((name) => path61.join(dir, name));
|
|
80723
81100
|
} catch {
|
|
80724
81101
|
return [];
|
|
80725
81102
|
}
|
|
80726
81103
|
};
|
|
80727
81104
|
for (const project of dirs(projects))
|
|
80728
81105
|
for (const session of dirs(project))
|
|
80729
|
-
for (const meta of dirs(
|
|
81106
|
+
for (const meta of dirs(path61.join(session, "subagents")).filter((f) => f.endsWith(".meta.json"))) {
|
|
80730
81107
|
try {
|
|
80731
81108
|
if (statSync9(meta).mtimeMs < since)
|
|
80732
81109
|
continue;
|
|
80733
|
-
const agentType = JSON.parse(
|
|
81110
|
+
const agentType = JSON.parse(readFileSync27(meta, "utf8")).agentType;
|
|
80734
81111
|
const transcript = meta.replace(/\.meta\.json$/, ".jsonl");
|
|
80735
|
-
if (typeof agentType !== "string" || !
|
|
81112
|
+
if (typeof agentType !== "string" || !existsSync26(transcript))
|
|
80736
81113
|
continue;
|
|
80737
81114
|
const ran = modelsOf(transcript);
|
|
80738
81115
|
if (!ran.size)
|
|
@@ -80871,8 +81248,8 @@ var success2 = (data) => ({ ok: true, data }), failure3 = (code, error, unblock)
|
|
|
80871
81248
|
|
|
80872
81249
|
// packages/workit-core/src/git/ops.ts
|
|
80873
81250
|
import { spawnSync as spawnSync21 } from "node:child_process";
|
|
80874
|
-
import { existsSync as
|
|
80875
|
-
import
|
|
81251
|
+
import { existsSync as existsSync27, readFileSync as readFileSync28 } from "node:fs";
|
|
81252
|
+
import path62 from "node:path";
|
|
80876
81253
|
function operationInProgress(cwd) {
|
|
80877
81254
|
const markers = [
|
|
80878
81255
|
["rebase-merge", "rebase"],
|
|
@@ -80885,18 +81262,18 @@ function operationInProgress(cwd) {
|
|
|
80885
81262
|
if (!run.ok)
|
|
80886
81263
|
return null;
|
|
80887
81264
|
const found = run.stdout.split(`
|
|
80888
|
-
`).map((line) =>
|
|
81265
|
+
`).map((line) => path62.resolve(cwd, line.trim()));
|
|
80889
81266
|
const conflicted = () => git5(cwd, ["ls-files", "-u"]).stdout.trim() !== "";
|
|
80890
81267
|
for (const [index, [, operation]] of markers.entries()) {
|
|
80891
81268
|
const marker = found[index];
|
|
80892
|
-
if (!marker || !
|
|
81269
|
+
if (!marker || !existsSync27(marker))
|
|
80893
81270
|
continue;
|
|
80894
|
-
if (index === 1 &&
|
|
81271
|
+
if (index === 1 && existsSync27(path62.join(marker, "applying")))
|
|
80895
81272
|
return { operation: "am", commitAllowed: false, branch: null };
|
|
80896
|
-
if (index === 0 &&
|
|
81273
|
+
if (index === 0 && existsSync27(path62.join(marker, "amend")) && !conflicted()) {
|
|
80897
81274
|
let headName = "";
|
|
80898
81275
|
try {
|
|
80899
|
-
headName =
|
|
81276
|
+
headName = readFileSync28(path62.join(marker, "head-name"), "utf8").trim();
|
|
80900
81277
|
} catch {}
|
|
80901
81278
|
const branch = headName.startsWith("refs/heads/") ? headName.slice("refs/heads/".length) : null;
|
|
80902
81279
|
return { operation, commitAllowed: branch !== null, branch };
|
|
@@ -81231,7 +81608,7 @@ function gitCommit(cwd, input) {
|
|
|
81231
81608
|
if (paths.some((value) => value.startsWith("-") || !value.trim()))
|
|
81232
81609
|
return failure3("invalid_input", "paths must not be empty or start with -");
|
|
81233
81610
|
const tracked = new Set(nulList(git5(cwd, ["ls-files", "-z", "--", ...paths]).stdout));
|
|
81234
|
-
const addable = paths.filter((value) =>
|
|
81611
|
+
const addable = paths.filter((value) => existsSync27(path62.resolve(cwd, value)) || [...tracked].some((file) => file === value || file.startsWith(`${value}/`)));
|
|
81235
81612
|
if (addable.length) {
|
|
81236
81613
|
const added = git5(cwd, ["add", "-A", "--", ...addable]);
|
|
81237
81614
|
if (!added.ok)
|
|
@@ -81772,12 +82149,12 @@ var init_ops = __esm(() => {
|
|
|
81772
82149
|
|
|
81773
82150
|
// packages/workit-core/src/verdict-cover.ts
|
|
81774
82151
|
import fs26 from "node:fs";
|
|
81775
|
-
import
|
|
82152
|
+
import path63 from "node:path";
|
|
81776
82153
|
function chainsAbove(cwd, branch) {
|
|
81777
82154
|
const root = storeRoot(cwd);
|
|
81778
82155
|
if (!root.ok)
|
|
81779
82156
|
return [];
|
|
81780
|
-
const dir =
|
|
82157
|
+
const dir = path63.join(root.value.root, "stacks");
|
|
81781
82158
|
let names = [];
|
|
81782
82159
|
try {
|
|
81783
82160
|
names = fs26.readdirSync(dir).filter((name) => name.endsWith(".json"));
|
|
@@ -81788,7 +82165,7 @@ function chainsAbove(cwd, branch) {
|
|
|
81788
82165
|
for (const name of names.toSorted()) {
|
|
81789
82166
|
let parsed;
|
|
81790
82167
|
try {
|
|
81791
|
-
parsed = JSON.parse(fs26.readFileSync(
|
|
82168
|
+
parsed = JSON.parse(fs26.readFileSync(path63.join(dir, name), "utf8"));
|
|
81792
82169
|
} catch {
|
|
81793
82170
|
continue;
|
|
81794
82171
|
}
|
|
@@ -81944,10 +82321,10 @@ var init_check_evidence = __esm(() => {
|
|
|
81944
82321
|
|
|
81945
82322
|
// packages/workit-core/src/forge/reruns.ts
|
|
81946
82323
|
import fs27 from "node:fs";
|
|
81947
|
-
import
|
|
82324
|
+
import path64 from "node:path";
|
|
81948
82325
|
function rerunLogPath(cwd) {
|
|
81949
82326
|
const common = gitCommonDir(cwd);
|
|
81950
|
-
return common ?
|
|
82327
|
+
return common ? path64.join(common, "workit", "ci-reruns.jsonl") : null;
|
|
81951
82328
|
}
|
|
81952
82329
|
function rerunCounts(cwd, key) {
|
|
81953
82330
|
const counts = new Map;
|
|
@@ -81982,7 +82359,7 @@ function recordReruns(cwd, rows) {
|
|
|
81982
82359
|
if (!file)
|
|
81983
82360
|
return false;
|
|
81984
82361
|
try {
|
|
81985
|
-
fs27.mkdirSync(
|
|
82362
|
+
fs27.mkdirSync(path64.dirname(file), { recursive: true });
|
|
81986
82363
|
fs27.appendFileSync(file, rows.map((row) => `${JSON.stringify(row)}
|
|
81987
82364
|
`).join(""));
|
|
81988
82365
|
return true;
|
|
@@ -81995,7 +82372,7 @@ function withRerunLock(cwd, fn) {
|
|
|
81995
82372
|
if (!file)
|
|
81996
82373
|
return fn();
|
|
81997
82374
|
const lock = `${file.slice(0, -".jsonl".length)}.lock`;
|
|
81998
|
-
fs27.mkdirSync(
|
|
82375
|
+
fs27.mkdirSync(path64.dirname(lock), { recursive: true });
|
|
81999
82376
|
const until = Date.now() + LOCK_WAIT_MS2;
|
|
82000
82377
|
for (;; ) {
|
|
82001
82378
|
try {
|
|
@@ -82991,7 +83368,7 @@ var init_pr_ops = __esm(() => {
|
|
|
82991
83368
|
import { spawnSync as spawnSync23 } from "node:child_process";
|
|
82992
83369
|
import { createHash as createHash18, randomBytes as randomBytes4 } from "node:crypto";
|
|
82993
83370
|
import fs28 from "node:fs";
|
|
82994
|
-
import
|
|
83371
|
+
import path65 from "node:path";
|
|
82995
83372
|
function worktreeOf(cwd, branch) {
|
|
82996
83373
|
const list = gitRun3(cwd, ["worktree", "list", "--porcelain"]);
|
|
82997
83374
|
if (!list.ok)
|
|
@@ -83040,7 +83417,7 @@ function gitRestack(cwd, input) {
|
|
|
83040
83417
|
error: "no store root"
|
|
83041
83418
|
};
|
|
83042
83419
|
fs28.mkdirSync(scratch, { recursive: true });
|
|
83043
|
-
dir =
|
|
83420
|
+
dir = path65.join(scratch, `${input.branch.replace(/[^A-Za-z0-9._-]+/gu, "_").slice(0, 40)}-${randomBytes4(4).toString("hex")}`);
|
|
83044
83421
|
const added = gitRun3(cwd, ["worktree", "add", "-q", dir, input.branch], GIT_TIMEOUTS.worktree);
|
|
83045
83422
|
if (!added.ok)
|
|
83046
83423
|
return {
|
|
@@ -83096,7 +83473,7 @@ function pruneScratch(cwd) {
|
|
|
83096
83473
|
if (!scratch || !fs28.existsSync(scratch))
|
|
83097
83474
|
return;
|
|
83098
83475
|
for (const name of fs28.readdirSync(scratch)) {
|
|
83099
|
-
const dir =
|
|
83476
|
+
const dir = path65.join(scratch, name);
|
|
83100
83477
|
if (!rebaseInProgress(dir) && !trackedDirt(dir))
|
|
83101
83478
|
gitRun3(cwd, ["worktree", "remove", "--force", dir]);
|
|
83102
83479
|
}
|
|
@@ -83106,7 +83483,7 @@ function stacksDir(cwd) {
|
|
|
83106
83483
|
const root = storeRoot(cwd);
|
|
83107
83484
|
if (!root.ok)
|
|
83108
83485
|
return stackFail(root.code, root.error, root.unblock);
|
|
83109
|
-
return { ok: true, data:
|
|
83486
|
+
return { ok: true, data: path65.join(root.value.root, "stacks") };
|
|
83110
83487
|
}
|
|
83111
83488
|
function parseStack(raw) {
|
|
83112
83489
|
if (!isRecord12(raw) || !Array.isArray(raw.branches))
|
|
@@ -83158,7 +83535,7 @@ function readStack(cwd, name) {
|
|
|
83158
83535
|
const dir = stacksDir(cwd);
|
|
83159
83536
|
if (!dir.ok)
|
|
83160
83537
|
return dir;
|
|
83161
|
-
const file =
|
|
83538
|
+
const file = path65.join(dir.data, fileFor(name));
|
|
83162
83539
|
let text;
|
|
83163
83540
|
try {
|
|
83164
83541
|
text = fs28.readFileSync(file, "utf8");
|
|
@@ -83179,7 +83556,7 @@ function writeStack(cwd, stack, now = new Date) {
|
|
|
83179
83556
|
const dir = stacksDir(cwd);
|
|
83180
83557
|
if (!dir.ok)
|
|
83181
83558
|
return dir;
|
|
83182
|
-
const file =
|
|
83559
|
+
const file = path65.join(dir.data, fileFor(stack.name));
|
|
83183
83560
|
const temp = `${file}.${process.pid}.tmp`;
|
|
83184
83561
|
try {
|
|
83185
83562
|
fs28.mkdirSync(dir.data, { recursive: true });
|
|
@@ -83207,7 +83584,7 @@ function listStacks(cwd) {
|
|
|
83207
83584
|
for (const name of names) {
|
|
83208
83585
|
let parsed = null;
|
|
83209
83586
|
try {
|
|
83210
|
-
parsed = parseStack(JSON.parse(fs28.readFileSync(
|
|
83587
|
+
parsed = parseStack(JSON.parse(fs28.readFileSync(path65.join(dir.data, name), "utf8")));
|
|
83211
83588
|
} catch {
|
|
83212
83589
|
parsed = null;
|
|
83213
83590
|
}
|
|
@@ -83269,7 +83646,7 @@ function takeLock(lock) {
|
|
|
83269
83646
|
host: localLockHost(),
|
|
83270
83647
|
nonce: randomBytes4(8).toString("hex")
|
|
83271
83648
|
};
|
|
83272
|
-
fs28.writeFileSync(
|
|
83649
|
+
fs28.writeFileSync(path65.join(lock, OWNER), JSON.stringify(owner));
|
|
83273
83650
|
return owner;
|
|
83274
83651
|
}
|
|
83275
83652
|
function reapLock(lock, observed) {
|
|
@@ -83306,7 +83683,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
|
|
|
83306
83683
|
return dir;
|
|
83307
83684
|
if (!validName(name))
|
|
83308
83685
|
return stackFail("invalid_input", "a stack name must be 1-200 printable characters");
|
|
83309
|
-
const lock =
|
|
83686
|
+
const lock = path65.join(dir.data, `${fileFor(name)}.lock`);
|
|
83310
83687
|
try {
|
|
83311
83688
|
fs28.mkdirSync(dir.data, { recursive: true });
|
|
83312
83689
|
} catch (error) {
|
|
@@ -83336,7 +83713,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
|
|
|
83336
83713
|
const touch = () => {
|
|
83337
83714
|
try {
|
|
83338
83715
|
const now = new Date;
|
|
83339
|
-
fs28.utimesSync(
|
|
83716
|
+
fs28.utimesSync(path65.join(lock, OWNER), now, now);
|
|
83340
83717
|
} catch {}
|
|
83341
83718
|
};
|
|
83342
83719
|
const beat = setInterval(touch, HEARTBEAT_MS);
|
|
@@ -84305,7 +84682,7 @@ var STACK_VERSION = 1, stackFail = (code, error, unblock, data) => ({
|
|
|
84305
84682
|
return !status.ok || status.stdout.trim() !== "";
|
|
84306
84683
|
}, scratchDir = (cwd) => {
|
|
84307
84684
|
const dir = stacksDir(cwd);
|
|
84308
|
-
return dir.ok ?
|
|
84685
|
+
return dir.ok ? path65.join(dir.data, "worktrees") : null;
|
|
84309
84686
|
}, firstLine = (run) => (`${run.stderr}
|
|
84310
84687
|
${run.stdout}`.split(`
|
|
84311
84688
|
`).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 +84697,12 @@ ${run.stdout}`.split(`
|
|
|
84320
84697
|
}, 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
84698
|
let raw = null;
|
|
84322
84699
|
try {
|
|
84323
|
-
raw = fs28.readFileSync(
|
|
84700
|
+
raw = fs28.readFileSync(path65.join(lock, OWNER), "utf8");
|
|
84324
84701
|
} catch {
|
|
84325
84702
|
raw = null;
|
|
84326
84703
|
}
|
|
84327
84704
|
let age = null;
|
|
84328
|
-
for (const target of [
|
|
84705
|
+
for (const target of [path65.join(lock, OWNER), lock])
|
|
84329
84706
|
try {
|
|
84330
84707
|
age = Date.now() - fs28.statSync(target).mtimeMs;
|
|
84331
84708
|
break;
|
|
@@ -84369,7 +84746,7 @@ var init_stack = __esm(() => {
|
|
|
84369
84746
|
import { spawnSync as spawnSync24 } from "node:child_process";
|
|
84370
84747
|
import { createHash as createHash19 } from "node:crypto";
|
|
84371
84748
|
import fs29 from "node:fs";
|
|
84372
|
-
import
|
|
84749
|
+
import path66 from "node:path";
|
|
84373
84750
|
function expandBraces2(pattern, limit = 64) {
|
|
84374
84751
|
for (let index = 0;index < pattern.length; index += 1) {
|
|
84375
84752
|
if (pattern[index] === "\\") {
|
|
@@ -84615,7 +84992,7 @@ function parsePlan(raw, defaults, name) {
|
|
|
84615
84992
|
id,
|
|
84616
84993
|
branch,
|
|
84617
84994
|
base: optional("base") ?? "",
|
|
84618
|
-
worktree:
|
|
84995
|
+
worktree: path66.resolve(defaults.root, optional("worktree") ?? path66.join(defaults.worktreeRoot, id)),
|
|
84619
84996
|
tier,
|
|
84620
84997
|
reason,
|
|
84621
84998
|
dependsOn: [...new Set(dependsOn ?? [])],
|
|
@@ -84744,12 +85121,12 @@ function regeneratedFiles(root, tracked) {
|
|
|
84744
85121
|
const found = new Map;
|
|
84745
85122
|
let scripts;
|
|
84746
85123
|
try {
|
|
84747
|
-
const manifest = JSON.parse(fs29.readFileSync(
|
|
85124
|
+
const manifest = JSON.parse(fs29.readFileSync(path66.join(root, "package.json"), "utf8"));
|
|
84748
85125
|
scripts = manifest.scripts ?? {};
|
|
84749
85126
|
} catch {
|
|
84750
85127
|
return found;
|
|
84751
85128
|
}
|
|
84752
|
-
const runner = fs29.existsSync(
|
|
85129
|
+
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
85130
|
const outputs = tracked.filter((file) => !CODE.test(file));
|
|
84754
85131
|
for (const [name, command] of Object.entries(scripts)) {
|
|
84755
85132
|
if (!name.startsWith("write:") || typeof command !== "string")
|
|
@@ -84757,7 +85134,7 @@ function regeneratedFiles(root, tracked) {
|
|
|
84757
85134
|
for (const file of command.match(/[\w./-]+\.[cm]?[jt]s\b/gu) ?? []) {
|
|
84758
85135
|
let source;
|
|
84759
85136
|
try {
|
|
84760
|
-
source = fs29.readFileSync(
|
|
85137
|
+
source = fs29.readFileSync(path66.join(root, file), "utf8");
|
|
84761
85138
|
} catch {
|
|
84762
85139
|
continue;
|
|
84763
85140
|
}
|
|
@@ -84879,11 +85256,11 @@ function defaultTrunk(cwd) {
|
|
|
84879
85256
|
}
|
|
84880
85257
|
function mainCheckout(cwd) {
|
|
84881
85258
|
const common = gitCommonDir(cwd);
|
|
84882
|
-
return common &&
|
|
85259
|
+
return common && path66.basename(common) === ".git" ? path66.dirname(common) : path66.resolve(cwd);
|
|
84883
85260
|
}
|
|
84884
85261
|
function worktreeRoot(cwd) {
|
|
84885
85262
|
const main = mainCheckout(cwd);
|
|
84886
|
-
return
|
|
85263
|
+
return path66.join(path66.dirname(main), `${path66.basename(main)}-wt`);
|
|
84887
85264
|
}
|
|
84888
85265
|
function sliceHash(slice) {
|
|
84889
85266
|
const {
|
|
@@ -84903,7 +85280,7 @@ function fanoutsDir(cwd) {
|
|
|
84903
85280
|
const root = storeRoot(cwd);
|
|
84904
85281
|
if (!root.ok)
|
|
84905
85282
|
return fanoutFail(root.code, root.error, root.unblock);
|
|
84906
|
-
return { ok: true, data:
|
|
85283
|
+
return { ok: true, data: path66.join(root.value.root, "fanouts") };
|
|
84907
85284
|
}
|
|
84908
85285
|
function parseStored(raw) {
|
|
84909
85286
|
if (!isRecord13(raw) || typeof raw.name !== "string" || typeof raw.trunk !== "string")
|
|
@@ -84971,7 +85348,7 @@ function readFanout(cwd, name) {
|
|
|
84971
85348
|
const dir = fanoutsDir(cwd);
|
|
84972
85349
|
if (!dir.ok)
|
|
84973
85350
|
return dir;
|
|
84974
|
-
const file =
|
|
85351
|
+
const file = path66.join(dir.data, stackFileName(name));
|
|
84975
85352
|
let parsed = null;
|
|
84976
85353
|
try {
|
|
84977
85354
|
parsed = parseStored(JSON.parse(fs29.readFileSync(file, "utf8")));
|
|
@@ -84996,7 +85373,7 @@ function listFanouts(cwd) {
|
|
|
84996
85373
|
for (const entry of names) {
|
|
84997
85374
|
let parsed = null;
|
|
84998
85375
|
try {
|
|
84999
|
-
parsed = parseStored(JSON.parse(fs29.readFileSync(
|
|
85376
|
+
parsed = parseStored(JSON.parse(fs29.readFileSync(path66.join(dir.data, entry), "utf8")));
|
|
85000
85377
|
} catch {
|
|
85001
85378
|
parsed = null;
|
|
85002
85379
|
}
|
|
@@ -85035,7 +85412,7 @@ function writeFanout(cwd, plan) {
|
|
|
85035
85412
|
const dir = fanoutsDir(cwd);
|
|
85036
85413
|
if (!dir.ok)
|
|
85037
85414
|
return dir;
|
|
85038
|
-
const file =
|
|
85415
|
+
const file = path66.join(dir.data, stackFileName(plan.name));
|
|
85039
85416
|
const temp = `${file}.${process.pid}.tmp`;
|
|
85040
85417
|
try {
|
|
85041
85418
|
fs29.mkdirSync(dir.data, { recursive: true });
|
|
@@ -85246,13 +85623,13 @@ var init_fanout = __esm(() => {
|
|
|
85246
85623
|
// packages/workit-core/src/forge/exec.ts
|
|
85247
85624
|
import { spawnSync as spawnSync25 } from "node:child_process";
|
|
85248
85625
|
import fs30 from "node:fs";
|
|
85249
|
-
import
|
|
85626
|
+
import path67 from "node:path";
|
|
85250
85627
|
function findExecutable(bin, env) {
|
|
85251
|
-
const dirs = (env.PATH ?? env.Path ?? "").split(
|
|
85628
|
+
const dirs = (env.PATH ?? env.Path ?? "").split(path67.delimiter).filter(Boolean);
|
|
85252
85629
|
const exts = process.platform === "win32" ? [".exe"] : [""];
|
|
85253
85630
|
for (const dir of dirs)
|
|
85254
85631
|
for (const ext of exts) {
|
|
85255
|
-
const candidate =
|
|
85632
|
+
const candidate = path67.join(dir, `${bin}${ext}`);
|
|
85256
85633
|
try {
|
|
85257
85634
|
const stat = fs30.statSync(candidate);
|
|
85258
85635
|
if (stat.isFile())
|
|
@@ -87042,7 +87419,7 @@ var init_live_session = __esm(() => {
|
|
|
87042
87419
|
});
|
|
87043
87420
|
|
|
87044
87421
|
// packages/workit-core/src/hooks/write-gate.ts
|
|
87045
|
-
import
|
|
87422
|
+
import path68 from "node:path";
|
|
87046
87423
|
var CASE_INSENSITIVE, PREFIXES2, SCRIPT_SHELLS, cache3, MUTATING_GIT, DRY_N, MUTATING_WORKIT_GIT, CD2, PUSHD2, POPD2, UNKNOWN_DIR;
|
|
87047
87424
|
var init_write_gate = __esm(() => {
|
|
87048
87425
|
init_task_store();
|
|
@@ -87082,7 +87459,7 @@ var init_write_gate = __esm(() => {
|
|
|
87082
87459
|
CD2 = new Set(["cd", "chdir", "set-location", "sl"]);
|
|
87083
87460
|
PUSHD2 = new Set(["pushd", "push-location"]);
|
|
87084
87461
|
POPD2 = new Set(["popd", "pop-location"]);
|
|
87085
|
-
UNKNOWN_DIR =
|
|
87462
|
+
UNKNOWN_DIR = path68.resolve(path68.parse(process.cwd()).root, ".workit-unknown-dir");
|
|
87086
87463
|
});
|
|
87087
87464
|
|
|
87088
87465
|
// packages/workit-core/src/hooks/worktree-confine.ts
|
|
@@ -87107,20 +87484,20 @@ var init_worktree_confine = __esm(() => {
|
|
|
87107
87484
|
|
|
87108
87485
|
// packages/workit-core/src/worktree-deps.ts
|
|
87109
87486
|
import fs31 from "node:fs";
|
|
87110
|
-
import
|
|
87487
|
+
import path69 from "node:path";
|
|
87111
87488
|
function moduleDirs(main) {
|
|
87112
87489
|
const out = [];
|
|
87113
87490
|
const walk = (relative, depth) => {
|
|
87114
87491
|
let entries;
|
|
87115
87492
|
try {
|
|
87116
|
-
entries = fs31.readdirSync(
|
|
87493
|
+
entries = fs31.readdirSync(path69.join(main, relative), { withFileTypes: true });
|
|
87117
87494
|
} catch {
|
|
87118
87495
|
return;
|
|
87119
87496
|
}
|
|
87120
87497
|
for (const entry of entries) {
|
|
87121
87498
|
if (!entry.isDirectory())
|
|
87122
87499
|
continue;
|
|
87123
|
-
const child =
|
|
87500
|
+
const child = path69.join(relative, entry.name);
|
|
87124
87501
|
if (entry.name === MODULES)
|
|
87125
87502
|
out.push(child);
|
|
87126
87503
|
else if (depth < MAX_DEPTH2 && !entry.name.startsWith("."))
|
|
@@ -87134,8 +87511,8 @@ function linkEntry(main, worktree, source, target) {
|
|
|
87134
87511
|
const stat = fs31.lstatSync(source);
|
|
87135
87512
|
if (stat.isSymbolicLink()) {
|
|
87136
87513
|
const link = fs31.readlinkSync(source);
|
|
87137
|
-
const outside =
|
|
87138
|
-
const to = outside ?
|
|
87514
|
+
const outside = path69.isAbsolute(link) && within(link, main) && !path69.relative(main, link).split(path69.sep).includes(MODULES);
|
|
87515
|
+
const to = outside ? path69.join(worktree, path69.relative(main, link)) : link;
|
|
87139
87516
|
fs31.symlinkSync(to, target, process.platform === "win32" ? "junction" : undefined);
|
|
87140
87517
|
return;
|
|
87141
87518
|
}
|
|
@@ -87145,8 +87522,8 @@ function mirror(main, worktree, source, target, top) {
|
|
|
87145
87522
|
fs31.mkdirSync(target);
|
|
87146
87523
|
let count = 0;
|
|
87147
87524
|
for (const entry of fs31.readdirSync(source, { withFileTypes: true })) {
|
|
87148
|
-
const from =
|
|
87149
|
-
const to =
|
|
87525
|
+
const from = path69.join(source, entry.name);
|
|
87526
|
+
const to = path69.join(target, entry.name);
|
|
87150
87527
|
if (top && entry.isDirectory() && (entry.name.startsWith("@") || entry.name === ".bin"))
|
|
87151
87528
|
count += mirror(main, worktree, from, to, false);
|
|
87152
87529
|
else {
|
|
@@ -87162,16 +87539,16 @@ function linkWorktreeDependencies(main, worktree) {
|
|
|
87162
87539
|
const dirs = [];
|
|
87163
87540
|
let entries = 0;
|
|
87164
87541
|
for (const relative of moduleDirs(main)) {
|
|
87165
|
-
const target =
|
|
87166
|
-
if (!fs31.existsSync(
|
|
87542
|
+
const target = path69.join(worktree, relative);
|
|
87543
|
+
if (!fs31.existsSync(path69.dirname(target)) || fs31.existsSync(target))
|
|
87167
87544
|
continue;
|
|
87168
|
-
if (!gitRun4(worktree, ["check-ignore", "-q", `${relative.split(
|
|
87169
|
-
notes.push(`${relative.split(
|
|
87545
|
+
if (!gitRun4(worktree, ["check-ignore", "-q", `${relative.split(path69.sep).join("/")}/`]).ok) {
|
|
87546
|
+
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
87547
|
continue;
|
|
87171
87548
|
}
|
|
87172
87549
|
try {
|
|
87173
|
-
entries += mirror(main, worktree,
|
|
87174
|
-
dirs.push(relative.split(
|
|
87550
|
+
entries += mirror(main, worktree, path69.join(main, relative), target, true);
|
|
87551
|
+
dirs.push(relative.split(path69.sep).join("/"));
|
|
87175
87552
|
} catch (error) {
|
|
87176
87553
|
fs31.rmSync(target, { recursive: true, force: true });
|
|
87177
87554
|
notes.push(`could not link ${relative} from ${main} (${error.message}); install dependencies in the worktree yourself`);
|
|
@@ -87184,8 +87561,8 @@ function linkWorktreeDependencies(main, worktree) {
|
|
|
87184
87561
|
return { linked: { from: main, dirs, entries, ms }, notes };
|
|
87185
87562
|
}
|
|
87186
87563
|
var MODULES = "node_modules", MAX_DEPTH2 = 2, within = (child, parent) => {
|
|
87187
|
-
const relative =
|
|
87188
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
87564
|
+
const relative = path69.relative(parent, child);
|
|
87565
|
+
return relative === "" || !relative.startsWith("..") && !path69.isAbsolute(relative);
|
|
87189
87566
|
};
|
|
87190
87567
|
var init_worktree_deps = __esm(() => {
|
|
87191
87568
|
init_fanout();
|
|
@@ -87194,7 +87571,7 @@ var init_worktree_deps = __esm(() => {
|
|
|
87194
87571
|
// packages/workit-core/src/fanout-worktree.ts
|
|
87195
87572
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
87196
87573
|
import fs32 from "node:fs";
|
|
87197
|
-
import
|
|
87574
|
+
import path70 from "node:path";
|
|
87198
87575
|
function rowSample(lines) {
|
|
87199
87576
|
const out = [];
|
|
87200
87577
|
let bytes = 0;
|
|
@@ -87254,7 +87631,7 @@ function adminDir(worktree) {
|
|
|
87254
87631
|
const file = dir.stdout.trim();
|
|
87255
87632
|
let token = null;
|
|
87256
87633
|
try {
|
|
87257
|
-
token = fs32.readFileSync(
|
|
87634
|
+
token = fs32.readFileSync(path70.join(file, FANOUT_TOKEN_FILE), "utf8").trim() || null;
|
|
87258
87635
|
} catch {
|
|
87259
87636
|
token = null;
|
|
87260
87637
|
}
|
|
@@ -87262,7 +87639,7 @@ function adminDir(worktree) {
|
|
|
87262
87639
|
const stat = worktreeDeps.stat(file);
|
|
87263
87640
|
return {
|
|
87264
87641
|
path: file,
|
|
87265
|
-
id:
|
|
87642
|
+
id: path70.basename(file),
|
|
87266
87643
|
ino: stat.ino.toString(),
|
|
87267
87644
|
token,
|
|
87268
87645
|
birthMs: stat.birthtimeNs > 0n ? Number(stat.birthtimeMs) : null,
|
|
@@ -87278,7 +87655,7 @@ function markAdminDir(worktree) {
|
|
|
87278
87655
|
return null;
|
|
87279
87656
|
const token = randomBytes5(16).toString("hex");
|
|
87280
87657
|
try {
|
|
87281
|
-
fs32.writeFileSync(
|
|
87658
|
+
fs32.writeFileSync(path70.join(admin.path, FANOUT_TOKEN_FILE), `${token}
|
|
87282
87659
|
`);
|
|
87283
87660
|
} catch {
|
|
87284
87661
|
return null;
|
|
@@ -87293,7 +87670,7 @@ function excludeScratch(cwd) {
|
|
|
87293
87670
|
const common = gitCommonDir(cwd);
|
|
87294
87671
|
if (!common)
|
|
87295
87672
|
return;
|
|
87296
|
-
const file =
|
|
87673
|
+
const file = path70.join(common, "info", "exclude");
|
|
87297
87674
|
let text = "";
|
|
87298
87675
|
try {
|
|
87299
87676
|
text = fs32.readFileSync(file, "utf8");
|
|
@@ -87302,7 +87679,7 @@ function excludeScratch(cwd) {
|
|
|
87302
87679
|
}
|
|
87303
87680
|
if (text.split(/\r?\n/u).includes(EXCLUDE_LINE))
|
|
87304
87681
|
return;
|
|
87305
|
-
fs32.mkdirSync(
|
|
87682
|
+
fs32.mkdirSync(path70.dirname(file), { recursive: true });
|
|
87306
87683
|
fs32.appendFileSync(file, `${text && !text.endsWith(`
|
|
87307
87684
|
`) ? `
|
|
87308
87685
|
` : ""}# workit fanout: per-worker scratch dirs
|
|
@@ -87311,13 +87688,13 @@ ${EXCLUDE_LINE}
|
|
|
87311
87688
|
}
|
|
87312
87689
|
function worktreeDependencies(main, worktree) {
|
|
87313
87690
|
for (const [name, install] of LOCKFILES2) {
|
|
87314
|
-
const ours = readBytes(
|
|
87315
|
-
const theirs = readBytes(
|
|
87691
|
+
const ours = readBytes(path70.join(main, name));
|
|
87692
|
+
const theirs = readBytes(path70.join(worktree, name));
|
|
87316
87693
|
if (ours === null && theirs === null)
|
|
87317
87694
|
continue;
|
|
87318
87695
|
if (ours !== null && theirs !== null && ours.equals(theirs))
|
|
87319
87696
|
continue;
|
|
87320
|
-
if (fs32.existsSync(
|
|
87697
|
+
if (fs32.existsSync(path70.join(worktree, "node_modules")))
|
|
87321
87698
|
break;
|
|
87322
87699
|
const command = install(worktree);
|
|
87323
87700
|
return {
|
|
@@ -87329,7 +87706,7 @@ function worktreeDependencies(main, worktree) {
|
|
|
87329
87706
|
};
|
|
87330
87707
|
}
|
|
87331
87708
|
const stale = staleBunInstall(main);
|
|
87332
|
-
if (stale && !fs32.existsSync(
|
|
87709
|
+
if (stale && !fs32.existsSync(path70.join(worktree, "node_modules"))) {
|
|
87333
87710
|
const command = `bun install --frozen-lockfile --cwd ${worktree}`;
|
|
87334
87711
|
return {
|
|
87335
87712
|
linked: null,
|
|
@@ -87342,9 +87719,9 @@ function worktreeDependencies(main, worktree) {
|
|
|
87342
87719
|
return { ...linkWorktreeDependencies(main, worktree), install: null };
|
|
87343
87720
|
}
|
|
87344
87721
|
function staleBunInstall(main) {
|
|
87345
|
-
if (!fs32.existsSync(
|
|
87722
|
+
if (!fs32.existsSync(path70.join(main, "node_modules")))
|
|
87346
87723
|
return null;
|
|
87347
|
-
const text = readBytes(
|
|
87724
|
+
const text = readBytes(path70.join(main, "bun.lock"))?.toString("utf8");
|
|
87348
87725
|
if (!text)
|
|
87349
87726
|
return null;
|
|
87350
87727
|
let packages;
|
|
@@ -87371,7 +87748,7 @@ function staleBunInstall(main) {
|
|
|
87371
87748
|
const version = spec.slice(at + 1);
|
|
87372
87749
|
if (name !== key || version.includes(":"))
|
|
87373
87750
|
continue;
|
|
87374
|
-
const manifest = readBytes(
|
|
87751
|
+
const manifest = readBytes(path70.join(main, "node_modules", key, "package.json"));
|
|
87375
87752
|
if (!manifest) {
|
|
87376
87753
|
problems.push(`${key} missing`);
|
|
87377
87754
|
continue;
|
|
@@ -87388,7 +87765,7 @@ function staleBunInstall(main) {
|
|
|
87388
87765
|
return problems.length ? problems.join("; ") : null;
|
|
87389
87766
|
}
|
|
87390
87767
|
function ensureScratch(worktree) {
|
|
87391
|
-
const scratch =
|
|
87768
|
+
const scratch = path70.join(worktree, SCRATCH_DIR);
|
|
87392
87769
|
fs32.mkdirSync(scratch, { recursive: true });
|
|
87393
87770
|
return scratch;
|
|
87394
87771
|
}
|
|
@@ -87662,7 +88039,7 @@ function unpushedCount(cwd, branch) {
|
|
|
87662
88039
|
return count.ok ? Number(count.stdout.trim()) : null;
|
|
87663
88040
|
}
|
|
87664
88041
|
function removeScratch(worktree) {
|
|
87665
|
-
const scratch =
|
|
88042
|
+
const scratch = path70.join(worktree, SCRATCH_DIR);
|
|
87666
88043
|
let stat;
|
|
87667
88044
|
try {
|
|
87668
88045
|
stat = fs32.lstatSync(scratch);
|
|
@@ -87678,16 +88055,16 @@ var SLOW, SCRATCH_DIR = ".workit-scratch", EXCLUDE_LINE, DIRTY_ROW_BYTES = 2000,
|
|
|
87678
88055
|
try {
|
|
87679
88056
|
return fs32.realpathSync.native(target);
|
|
87680
88057
|
} catch {
|
|
87681
|
-
return
|
|
88058
|
+
return path70.resolve(target);
|
|
87682
88059
|
}
|
|
87683
88060
|
}, samePath = (a, b) => {
|
|
87684
88061
|
const left = canonical2(a);
|
|
87685
88062
|
const right = canonical2(b);
|
|
87686
88063
|
return process.platform === "win32" || process.platform === "darwin" ? left.toLowerCase() === right.toLowerCase() : left === right;
|
|
87687
88064
|
}, inside3 = (child, parent) => {
|
|
87688
|
-
const relative =
|
|
87689
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
87690
|
-
}, slicePath = (cwd, slice) =>
|
|
88065
|
+
const relative = path70.relative(canonical2(parent), canonical2(child));
|
|
88066
|
+
return relative === "" || !relative.startsWith("..") && !path70.isAbsolute(relative);
|
|
88067
|
+
}, slicePath = (cwd, slice) => path70.isAbsolute(slice.worktree) ? slice.worktree : path70.resolve(mainCheckout(cwd), slice.worktree), CLOCK_SLACK_MS = 2000, worktreeDeps, LOCKFILES2, readBytes = (file) => {
|
|
87691
88068
|
try {
|
|
87692
88069
|
return fs32.readFileSync(file);
|
|
87693
88070
|
} catch {
|
|
@@ -87719,7 +88096,7 @@ var init_fanout_worktree = __esm(() => {
|
|
|
87719
88096
|
|
|
87720
88097
|
// packages/workit-core/src/forge/merge-cleanup.ts
|
|
87721
88098
|
import fs33 from "node:fs";
|
|
87722
|
-
import
|
|
88099
|
+
import path71 from "node:path";
|
|
87723
88100
|
function cleanupMergedBranch(cwd, branch, mergedHead) {
|
|
87724
88101
|
const out = { branchDeleted: false, worktreeRemoved: null, notes: [] };
|
|
87725
88102
|
if (!branch || branch.startsWith("-"))
|
|
@@ -87779,13 +88156,13 @@ var SLOW2, isFanoutWorktree = (worktree) => {
|
|
|
87779
88156
|
if (!dir.ok)
|
|
87780
88157
|
return false;
|
|
87781
88158
|
try {
|
|
87782
|
-
return fs33.readFileSync(
|
|
88159
|
+
return fs33.readFileSync(path71.join(dir.stdout.trim(), FANOUT_TOKEN_FILE), "utf8").trim() !== "";
|
|
87783
88160
|
} catch {
|
|
87784
88161
|
return false;
|
|
87785
88162
|
}
|
|
87786
88163
|
}, inside4 = (child, parent) => {
|
|
87787
|
-
const relative =
|
|
87788
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
88164
|
+
const relative = path71.relative(fs33.realpathSync.native(parent), fs33.realpathSync.native(child));
|
|
88165
|
+
return relative === "" || !relative.startsWith("..") && !path71.isAbsolute(relative);
|
|
87789
88166
|
};
|
|
87790
88167
|
var init_merge_cleanup = __esm(() => {
|
|
87791
88168
|
init_fanout();
|
|
@@ -88066,7 +88443,7 @@ var init_duration = __esm(() => {
|
|
|
88066
88443
|
});
|
|
88067
88444
|
|
|
88068
88445
|
// packages/workit-cli/src/verbs/forge-common.ts
|
|
88069
|
-
import { readFileSync as
|
|
88446
|
+
import { readFileSync as readFileSync29 } from "node:fs";
|
|
88070
88447
|
function parseFlags(argv, spec) {
|
|
88071
88448
|
const parsed = { values: {}, booleans: new Set, lists: {}, positionals: [] };
|
|
88072
88449
|
for (let index = 0;index < argv.length; index += 1) {
|
|
@@ -88224,7 +88601,7 @@ var init_forge_common = __esm(() => {
|
|
|
88224
88601
|
forgeDeps = {
|
|
88225
88602
|
runner: undefined,
|
|
88226
88603
|
npm: undefined,
|
|
88227
|
-
readStdin: () =>
|
|
88604
|
+
readStdin: () => readFileSync29(0, "utf8"),
|
|
88228
88605
|
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
88229
88606
|
now: () => Date.now()
|
|
88230
88607
|
};
|
|
@@ -88236,8 +88613,8 @@ __export(exports_pr, {
|
|
|
88236
88613
|
checkPrTitle: () => checkPrTitle,
|
|
88237
88614
|
run: () => run15
|
|
88238
88615
|
});
|
|
88239
|
-
import { existsSync as
|
|
88240
|
-
import
|
|
88616
|
+
import { existsSync as existsSync28, readFileSync as readFileSync30 } from "node:fs";
|
|
88617
|
+
import path72 from "node:path";
|
|
88241
88618
|
function titleRules(cwd) {
|
|
88242
88619
|
let root;
|
|
88243
88620
|
try {
|
|
@@ -88248,16 +88625,16 @@ function titleRules(cwd) {
|
|
|
88248
88625
|
let text = null;
|
|
88249
88626
|
let name = "";
|
|
88250
88627
|
for (const candidate of COMMITLINT_FILES) {
|
|
88251
|
-
const full =
|
|
88252
|
-
if (!
|
|
88628
|
+
const full = path72.join(root, candidate);
|
|
88629
|
+
if (!existsSync28(full))
|
|
88253
88630
|
continue;
|
|
88254
|
-
text =
|
|
88631
|
+
text = readFileSync30(full, "utf8");
|
|
88255
88632
|
name = candidate;
|
|
88256
88633
|
break;
|
|
88257
88634
|
}
|
|
88258
88635
|
if (text === null) {
|
|
88259
88636
|
try {
|
|
88260
|
-
const pkg = JSON.parse(
|
|
88637
|
+
const pkg = JSON.parse(readFileSync30(path72.join(root, "package.json"), "utf8"));
|
|
88261
88638
|
if (pkg.commitlint === undefined)
|
|
88262
88639
|
return { rules: null, note: null };
|
|
88263
88640
|
text = JSON.stringify(pkg.commitlint);
|
|
@@ -88354,7 +88731,7 @@ function refuseTitle(io, title, line) {
|
|
|
88354
88731
|
function readBodyFile(io, file) {
|
|
88355
88732
|
try {
|
|
88356
88733
|
return {
|
|
88357
|
-
body: file === "-" ? forgeDeps.readStdin() :
|
|
88734
|
+
body: file === "-" ? forgeDeps.readStdin() : readFileSync30(path72.resolve(io.cwd, file), "utf8")
|
|
88358
88735
|
};
|
|
88359
88736
|
} catch {
|
|
88360
88737
|
return `cannot read --body-file ${file}`;
|
|
@@ -89243,8 +89620,8 @@ var exports_git = {};
|
|
|
89243
89620
|
__export(exports_git, {
|
|
89244
89621
|
run: () => run17
|
|
89245
89622
|
});
|
|
89246
|
-
import { readFileSync as
|
|
89247
|
-
import
|
|
89623
|
+
import { readFileSync as readFileSync31 } from "node:fs";
|
|
89624
|
+
import path73 from "node:path";
|
|
89248
89625
|
function kindHint(cwd, kind) {
|
|
89249
89626
|
let kinds = [...BRANCH_KINDS];
|
|
89250
89627
|
try {
|
|
@@ -89348,7 +89725,7 @@ function commitMessage(parsed, io) {
|
|
|
89348
89725
|
|
|
89349
89726
|
`);
|
|
89350
89727
|
try {
|
|
89351
|
-
return file === "-" ?
|
|
89728
|
+
return file === "-" ? readFileSync31(0, "utf8") : readFileSync31(path73.resolve(io.cwd, file), "utf8");
|
|
89352
89729
|
} catch (error) {
|
|
89353
89730
|
return {
|
|
89354
89731
|
error: `cannot read -F ${file}: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -90812,7 +91189,7 @@ var init_stack2 = __esm(() => {
|
|
|
90812
91189
|
// packages/workit-core/src/fanout-brief.ts
|
|
90813
91190
|
import { createHash as createHash20 } from "node:crypto";
|
|
90814
91191
|
import fs35 from "node:fs";
|
|
90815
|
-
import
|
|
91192
|
+
import path74 from "node:path";
|
|
90816
91193
|
function workerSession(lead, slice, attempt) {
|
|
90817
91194
|
const tail = attempt === null ? "" : `+try${attempt}`;
|
|
90818
91195
|
const full = `${lead}-w-${slice}${tail}`;
|
|
@@ -90895,7 +91272,7 @@ function renderBrief(cwd, plan, input) {
|
|
|
90895
91272
|
"STANDING:",
|
|
90896
91273
|
...standing.length ? standing.map((order) => ` - ${order.what}`) : [" - none recorded beyond this brief"],
|
|
90897
91274
|
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(
|
|
91275
|
+
...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
91276
|
...identityLines(identity, minted),
|
|
90900
91277
|
...rules(mode, branch, sliceBase, exists ? planned : null)
|
|
90901
91278
|
];
|
|
@@ -91437,7 +91814,7 @@ __export(exports_fanout, {
|
|
|
91437
91814
|
run: () => run21
|
|
91438
91815
|
});
|
|
91439
91816
|
import fs36 from "node:fs";
|
|
91440
|
-
import
|
|
91817
|
+
import path75 from "node:path";
|
|
91441
91818
|
function forgeFor(io, offline) {
|
|
91442
91819
|
if (offline)
|
|
91443
91820
|
return { forge: null, error: "--offline" };
|
|
@@ -91498,7 +91875,7 @@ function plan2(argv, io) {
|
|
|
91498
91875
|
return usage4(io, "pass --trunk or --track, not both (--track picks the trunk)", PLAN_USAGE2);
|
|
91499
91876
|
if (flags.positionals.length !== 1)
|
|
91500
91877
|
return usage4(io, flags.positionals.length ? `unexpected argument ${flags.positionals[1]}` : "missing <plan.json>", PLAN_USAGE2);
|
|
91501
|
-
const file =
|
|
91878
|
+
const file = path75.resolve(io.cwd, flags.positionals[0]);
|
|
91502
91879
|
let raw;
|
|
91503
91880
|
try {
|
|
91504
91881
|
raw = JSON.parse(fs36.readFileSync(file, "utf8"));
|
|
@@ -107074,7 +107451,7 @@ var init_ast = __esm(() => {
|
|
|
107074
107451
|
|
|
107075
107452
|
// packages/workit-cli/src/test-audit/rules.ts
|
|
107076
107453
|
import { builtinModules } from "node:module";
|
|
107077
|
-
import
|
|
107454
|
+
import path76 from "node:path";
|
|
107078
107455
|
function testCallee(call) {
|
|
107079
107456
|
let callee = call.callee;
|
|
107080
107457
|
if (callee.type === "CallExpression")
|
|
@@ -107567,12 +107944,12 @@ function checkConstantsOnly(ctx, emit) {
|
|
|
107567
107944
|
}
|
|
107568
107945
|
function checkOverMocking(ctx, emit) {
|
|
107569
107946
|
const { program } = ctx.parsed;
|
|
107570
|
-
const unit =
|
|
107947
|
+
const unit = path76.basename(ctx.file).replace(/\.(?:[cm]?[jt]sx?)$/, "").replace(/\.(?:test|spec)$/, "");
|
|
107571
107948
|
const mocked = find2(program, (node) => node.type === "CallExpression" && MODULE_MOCK.test(calleeName(node.callee) ?? "") && node.arguments[0]?.type === "StringLiteral");
|
|
107572
107949
|
const internal = mocked.filter((call) => /^(?:\.|@\/|~\/)/.test(call.arguments[0].value));
|
|
107573
107950
|
for (const call of mocked) {
|
|
107574
107951
|
const spec = call.arguments[0].value;
|
|
107575
|
-
const base =
|
|
107952
|
+
const base = path76.basename(spec.replace(/\/index(?:\.[cm]?[jt]sx?)?$/, "")).replace(/\.(?:[cm]?[jt]sx?)$/, "");
|
|
107576
107953
|
if (base === unit)
|
|
107577
107954
|
emit({
|
|
107578
107955
|
rule: "over-mocking",
|
|
@@ -107961,8 +108338,8 @@ var init_rules = __esm(() => {
|
|
|
107961
108338
|
|
|
107962
108339
|
// packages/workit-cli/src/test-audit/audit.ts
|
|
107963
108340
|
import { spawnSync as spawnSync30 } from "node:child_process";
|
|
107964
|
-
import { existsSync as
|
|
107965
|
-
import
|
|
108341
|
+
import { existsSync as existsSync29, readdirSync as readdirSync14, readFileSync as readFileSync32, statSync as statSync10 } from "node:fs";
|
|
108342
|
+
import path77 from "node:path";
|
|
107966
108343
|
function git7(cwd, args) {
|
|
107967
108344
|
const run = spawnSync30("git", ["-c", "core.quotepath=off", ...args], {
|
|
107968
108345
|
cwd,
|
|
@@ -107975,7 +108352,7 @@ function walkTests(dir, out) {
|
|
|
107975
108352
|
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
107976
108353
|
if (entry.name.startsWith(".") && entry.name !== "." && entry.isDirectory())
|
|
107977
108354
|
continue;
|
|
107978
|
-
const full =
|
|
108355
|
+
const full = path77.join(dir, entry.name);
|
|
107979
108356
|
if (entry.isDirectory()) {
|
|
107980
108357
|
if (!SKIP_DIRS.has(entry.name))
|
|
107981
108358
|
walkTests(full, out);
|
|
@@ -107987,8 +108364,8 @@ function expandPaths(cwd, inputs) {
|
|
|
107987
108364
|
const files = [];
|
|
107988
108365
|
const missing = [];
|
|
107989
108366
|
for (const input of inputs.length > 0 ? inputs : ["."]) {
|
|
107990
|
-
const full =
|
|
107991
|
-
if (!
|
|
108367
|
+
const full = path77.resolve(cwd, input);
|
|
108368
|
+
if (!existsSync29(full))
|
|
107992
108369
|
missing.push(input);
|
|
107993
108370
|
else if (statSync10(full).isDirectory())
|
|
107994
108371
|
walkTests(full, files);
|
|
@@ -108024,11 +108401,11 @@ function changedLines(cwd, base) {
|
|
|
108024
108401
|
for (let offset = 0;offset < count; offset += 1)
|
|
108025
108402
|
lines.add(start + offset);
|
|
108026
108403
|
}
|
|
108027
|
-
changed.set(
|
|
108404
|
+
changed.set(path77.join(root, file), lines);
|
|
108028
108405
|
}
|
|
108029
108406
|
const untracked = git7(root, ["ls-files", "--others", "--exclude-standard", "-z"]);
|
|
108030
108407
|
for (const file of untracked.stdout.split("\x00").filter(Boolean))
|
|
108031
|
-
changed.set(
|
|
108408
|
+
changed.set(path77.join(root, file), "all");
|
|
108032
108409
|
return changed;
|
|
108033
108410
|
}
|
|
108034
108411
|
function auditFiles(files, display) {
|
|
@@ -108041,7 +108418,7 @@ function auditFiles(files, display) {
|
|
|
108041
108418
|
const shown = display(file);
|
|
108042
108419
|
let parsed;
|
|
108043
108420
|
try {
|
|
108044
|
-
parsed = parseSource(
|
|
108421
|
+
parsed = parseSource(readFileSync32(file, "utf8"), file);
|
|
108045
108422
|
} catch (error) {
|
|
108046
108423
|
parseErrors.push({
|
|
108047
108424
|
file: shown,
|
|
@@ -108090,7 +108467,7 @@ function auditFiles(files, display) {
|
|
|
108090
108467
|
durationMs: Math.round(performance.now() - started)
|
|
108091
108468
|
};
|
|
108092
108469
|
}
|
|
108093
|
-
var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(
|
|
108470
|
+
var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(path77.sep).join("/"), SEVERITY_ORDER, ruleIds;
|
|
108094
108471
|
var init_audit = __esm(() => {
|
|
108095
108472
|
init_ast();
|
|
108096
108473
|
init_rules();
|
|
@@ -108104,23 +108481,23 @@ var init_audit = __esm(() => {
|
|
|
108104
108481
|
// packages/workit-cli/src/test-audit/mutate.ts
|
|
108105
108482
|
import { spawn as spawn5 } from "node:child_process";
|
|
108106
108483
|
import {
|
|
108107
|
-
existsSync as
|
|
108484
|
+
existsSync as existsSync30,
|
|
108108
108485
|
lstatSync as lstatSync9,
|
|
108109
108486
|
mkdirSync as mkdirSync13,
|
|
108110
|
-
mkdtempSync as
|
|
108487
|
+
mkdtempSync as mkdtempSync6,
|
|
108111
108488
|
readdirSync as readdirSync15,
|
|
108112
|
-
readFileSync as
|
|
108489
|
+
readFileSync as readFileSync33,
|
|
108113
108490
|
readlinkSync as readlinkSync3,
|
|
108114
108491
|
realpathSync as realpathSync11,
|
|
108115
108492
|
renameSync as renameSync8,
|
|
108116
|
-
rmSync as
|
|
108493
|
+
rmSync as rmSync11,
|
|
108117
108494
|
statSync as statSync11,
|
|
108118
108495
|
symlinkSync,
|
|
108119
|
-
writeFileSync as
|
|
108496
|
+
writeFileSync as writeFileSync15,
|
|
108120
108497
|
copyFileSync as copyFileSync8
|
|
108121
108498
|
} from "node:fs";
|
|
108122
|
-
import
|
|
108123
|
-
import
|
|
108499
|
+
import os26 from "node:os";
|
|
108500
|
+
import path78 from "node:path";
|
|
108124
108501
|
function mutantsFor(source, file, lines) {
|
|
108125
108502
|
const parsed = parseSource(source, file);
|
|
108126
108503
|
const out = [];
|
|
@@ -108193,7 +108570,7 @@ function relatedTests(source, testFiles) {
|
|
|
108193
108570
|
for (const match of text.matchAll(SPECIFIER)) {
|
|
108194
108571
|
const spec = match[1];
|
|
108195
108572
|
if (spec.startsWith(".")) {
|
|
108196
|
-
if (stripExt(
|
|
108573
|
+
if (stripExt(path78.posix.join(path78.posix.dirname(file), spec)) === target)
|
|
108197
108574
|
return true;
|
|
108198
108575
|
} else if (spec.includes("/") && stripExt(spec).split("/").slice(-2).join("/") === tail)
|
|
108199
108576
|
return true;
|
|
@@ -108201,7 +108578,7 @@ function relatedTests(source, testFiles) {
|
|
|
108201
108578
|
return false;
|
|
108202
108579
|
}).map((entry) => entry.file);
|
|
108203
108580
|
}
|
|
108204
|
-
function removeStaleCopies(tmp =
|
|
108581
|
+
function removeStaleCopies(tmp = os26.tmpdir()) {
|
|
108205
108582
|
let removed = 0;
|
|
108206
108583
|
let names = [];
|
|
108207
108584
|
try {
|
|
@@ -108213,12 +108590,12 @@ function removeStaleCopies(tmp = os24.tmpdir()) {
|
|
|
108213
108590
|
for (const name of names) {
|
|
108214
108591
|
if (!name.startsWith(TEMP_PREFIX))
|
|
108215
108592
|
continue;
|
|
108216
|
-
const dir =
|
|
108593
|
+
const dir = path78.join(tmp, name);
|
|
108217
108594
|
try {
|
|
108218
108595
|
const stat = lstatSync9(dir);
|
|
108219
108596
|
if (!stat.isDirectory() || uid !== undefined && stat.uid !== uid)
|
|
108220
108597
|
continue;
|
|
108221
|
-
const pid = Number(
|
|
108598
|
+
const pid = Number(readFileSync33(path78.join(dir, PID_FILE), "utf8"));
|
|
108222
108599
|
if (Number.isInteger(pid) && pid > 0 && alive(pid))
|
|
108223
108600
|
continue;
|
|
108224
108601
|
} catch (error) {
|
|
@@ -108226,7 +108603,7 @@ function removeStaleCopies(tmp = os24.tmpdir()) {
|
|
|
108226
108603
|
continue;
|
|
108227
108604
|
}
|
|
108228
108605
|
try {
|
|
108229
|
-
|
|
108606
|
+
rmSync11(dir, { recursive: true, force: true });
|
|
108230
108607
|
removed += 1;
|
|
108231
108608
|
} catch {}
|
|
108232
108609
|
}
|
|
@@ -108235,8 +108612,8 @@ function removeStaleCopies(tmp = os24.tmpdir()) {
|
|
|
108235
108612
|
function linkNodeModules(origin, target, repo, copy) {
|
|
108236
108613
|
mkdirSync13(target, { recursive: true });
|
|
108237
108614
|
for (const entry of readdirSync15(origin, { withFileTypes: true })) {
|
|
108238
|
-
const from =
|
|
108239
|
-
const to =
|
|
108615
|
+
const from = path78.join(origin, entry.name);
|
|
108616
|
+
const to = path78.join(target, entry.name);
|
|
108240
108617
|
if (entry.name.startsWith("@") && entry.isDirectory()) {
|
|
108241
108618
|
linkNodeModules(from, to, repo, copy);
|
|
108242
108619
|
continue;
|
|
@@ -108252,9 +108629,9 @@ function linkNodeModules(origin, target, repo, copy) {
|
|
|
108252
108629
|
} catch {
|
|
108253
108630
|
continue;
|
|
108254
108631
|
}
|
|
108255
|
-
const relative =
|
|
108256
|
-
if (!relative.startsWith("..") && !
|
|
108257
|
-
symlinkSync(
|
|
108632
|
+
const relative = path78.relative(repo, real);
|
|
108633
|
+
if (!relative.startsWith("..") && !path78.isAbsolute(relative) && !relative.split(path78.sep).includes("node_modules")) {
|
|
108634
|
+
symlinkSync(path78.join(copy, relative), to, "junction");
|
|
108258
108635
|
continue;
|
|
108259
108636
|
}
|
|
108260
108637
|
}
|
|
@@ -108270,7 +108647,7 @@ function copySymlink(repo, tree, from, to) {
|
|
|
108270
108647
|
}
|
|
108271
108648
|
const realRepo = realpathSync11(repo);
|
|
108272
108649
|
if (real && inside5(realRepo, real)) {
|
|
108273
|
-
symlinkSync(
|
|
108650
|
+
symlinkSync(path78.relative(path78.dirname(to), path78.join(tree, path78.relative(realRepo, real))), to);
|
|
108274
108651
|
return;
|
|
108275
108652
|
}
|
|
108276
108653
|
if (real && statSync11(real).isFile())
|
|
@@ -108279,23 +108656,23 @@ function copySymlink(repo, tree, from, to) {
|
|
|
108279
108656
|
symlinkSync(readlinkSync3(from), to);
|
|
108280
108657
|
}
|
|
108281
108658
|
function writeInside(copy, file, content) {
|
|
108282
|
-
const target =
|
|
108659
|
+
const target = path78.join(copy, file);
|
|
108283
108660
|
try {
|
|
108284
108661
|
const stat = lstatSync9(target);
|
|
108285
|
-
if (!stat.isFile() || !inside5(realpathSync11(copy), realpathSync11(
|
|
108662
|
+
if (!stat.isFile() || !inside5(realpathSync11(copy), realpathSync11(path78.dirname(target))))
|
|
108286
108663
|
return false;
|
|
108287
108664
|
} catch {
|
|
108288
108665
|
return false;
|
|
108289
108666
|
}
|
|
108290
108667
|
const temp = `${target}.workit-mutant-${process.pid}`;
|
|
108291
|
-
|
|
108668
|
+
writeFileSync15(temp, content);
|
|
108292
108669
|
renameSync8(temp, target);
|
|
108293
108670
|
return true;
|
|
108294
108671
|
}
|
|
108295
108672
|
function copyWorkingTree(repo) {
|
|
108296
|
-
const dir =
|
|
108297
|
-
|
|
108298
|
-
const tree =
|
|
108673
|
+
const dir = mkdtempSync6(path78.join(os26.tmpdir(), TEMP_PREFIX));
|
|
108674
|
+
writeFileSync15(path78.join(dir, PID_FILE), String(process.pid));
|
|
108675
|
+
const tree = path78.join(dir, "tree");
|
|
108299
108676
|
const head = git7(repo, ["rev-parse", "--verify", "--quiet", "HEAD"]).stdout.trim();
|
|
108300
108677
|
if (head && git7(dir, ["clone", "-q", "--shared", "--no-checkout", repo, tree]).ok) {
|
|
108301
108678
|
const branch = git7(repo, ["symbolic-ref", "--quiet", "--short", "HEAD"]).stdout.trim();
|
|
@@ -108312,29 +108689,29 @@ function copyWorkingTree(repo) {
|
|
|
108312
108689
|
for (const relative of listed) {
|
|
108313
108690
|
if (!relative)
|
|
108314
108691
|
continue;
|
|
108315
|
-
const from =
|
|
108692
|
+
const from = path78.join(repo, relative);
|
|
108316
108693
|
let stat;
|
|
108317
108694
|
try {
|
|
108318
108695
|
stat = lstatSync9(from);
|
|
108319
108696
|
} catch {
|
|
108320
108697
|
continue;
|
|
108321
108698
|
}
|
|
108322
|
-
const to =
|
|
108323
|
-
mkdirSync13(
|
|
108699
|
+
const to = path78.join(tree, relative);
|
|
108700
|
+
mkdirSync13(path78.dirname(to), { recursive: true });
|
|
108324
108701
|
if (stat.isSymbolicLink())
|
|
108325
108702
|
copySymlink(repo, tree, from, to);
|
|
108326
108703
|
else if (stat.isFile())
|
|
108327
108704
|
copyFileSync8(from, to);
|
|
108328
|
-
let parent =
|
|
108705
|
+
let parent = path78.dirname(relative);
|
|
108329
108706
|
while (parent !== "." && !dirs.has(parent)) {
|
|
108330
108707
|
dirs.add(parent);
|
|
108331
|
-
parent =
|
|
108708
|
+
parent = path78.dirname(parent);
|
|
108332
108709
|
}
|
|
108333
108710
|
}
|
|
108334
108711
|
for (const parent of dirs) {
|
|
108335
|
-
const modules =
|
|
108336
|
-
if (
|
|
108337
|
-
linkNodeModules(modules,
|
|
108712
|
+
const modules = path78.join(repo, parent, "node_modules");
|
|
108713
|
+
if (existsSync30(modules) && !existsSync30(path78.join(tree, parent, "node_modules")))
|
|
108714
|
+
linkNodeModules(modules, path78.join(tree, parent, "node_modules"), repo, tree);
|
|
108338
108715
|
}
|
|
108339
108716
|
return { dir, tree };
|
|
108340
108717
|
}
|
|
@@ -108373,20 +108750,20 @@ async function runMutation(options) {
|
|
|
108373
108750
|
const tracked = git7(repo, ["ls-files", "-co", "--exclude-standard", "-z"]).stdout.split("\x00").filter(Boolean);
|
|
108374
108751
|
const testFiles = tracked.filter((file) => TEST_FILE.test(file)).map((file) => {
|
|
108375
108752
|
try {
|
|
108376
|
-
return { file, text:
|
|
108753
|
+
return { file, text: readFileSync33(path78.join(repo, file), "utf8") };
|
|
108377
108754
|
} catch {
|
|
108378
108755
|
return { file, text: "" };
|
|
108379
108756
|
}
|
|
108380
108757
|
});
|
|
108381
108758
|
const candidates = [];
|
|
108382
108759
|
for (const [absolute, lines] of [...options.changed].toSorted(([a], [b]) => a.localeCompare(b))) {
|
|
108383
|
-
const relative = toPosix(
|
|
108760
|
+
const relative = toPosix(path78.relative(repo, absolute));
|
|
108384
108761
|
if (!CODE_FILE.test(relative) || TEST_FILE.test(relative) || relative.endsWith(".d.ts"))
|
|
108385
108762
|
continue;
|
|
108386
|
-
if (NOT_SOURCE.test(relative) || !
|
|
108763
|
+
if (NOT_SOURCE.test(relative) || !existsSync30(absolute))
|
|
108387
108764
|
continue;
|
|
108388
108765
|
try {
|
|
108389
|
-
candidates.push(...mutantsFor(
|
|
108766
|
+
candidates.push(...mutantsFor(readFileSync33(absolute, "utf8"), relative, lines));
|
|
108390
108767
|
} catch {}
|
|
108391
108768
|
}
|
|
108392
108769
|
const mutants = candidates.map((mutant, index) => ({ ...mutant, id: index + 1 }));
|
|
@@ -108394,9 +108771,9 @@ async function runMutation(options) {
|
|
|
108394
108771
|
for (const mutant of mutants)
|
|
108395
108772
|
if (!related.has(mutant.file))
|
|
108396
108773
|
related.set(mutant.file, relatedTests(mutant.file, testFiles));
|
|
108397
|
-
const cwdRelative =
|
|
108774
|
+
const cwdRelative = path78.relative(repo, options.cwd);
|
|
108398
108775
|
const asArg = (file) => {
|
|
108399
|
-
const relative = toPosix(
|
|
108776
|
+
const relative = toPosix(path78.relative(cwdRelative, file));
|
|
108400
108777
|
return shellQuote(relative.startsWith(".") ? relative : `./${relative}`);
|
|
108401
108778
|
};
|
|
108402
108779
|
const commandFor = (tests) => options.command.replaceAll("{files}", () => tests.map(asArg).join(" "));
|
|
@@ -108432,7 +108809,7 @@ async function runMutation(options) {
|
|
|
108432
108809
|
return finish3(options, 0, results, counts, started);
|
|
108433
108810
|
removeStaleCopies();
|
|
108434
108811
|
const { dir: copyDir, tree: copy } = copyWorkingTree(repo);
|
|
108435
|
-
const copyCwd =
|
|
108812
|
+
const copyCwd = path78.join(copy, cwdRelative);
|
|
108436
108813
|
let current = null;
|
|
108437
108814
|
const restore = () => {
|
|
108438
108815
|
if (current)
|
|
@@ -108443,7 +108820,7 @@ async function runMutation(options) {
|
|
|
108443
108820
|
for (const child of active)
|
|
108444
108821
|
killTree(child);
|
|
108445
108822
|
restore();
|
|
108446
|
-
|
|
108823
|
+
rmSync11(copyDir, { recursive: true, force: true });
|
|
108447
108824
|
};
|
|
108448
108825
|
const onSignal = (signal) => {
|
|
108449
108826
|
cleanup();
|
|
@@ -108467,7 +108844,7 @@ async function runMutation(options) {
|
|
|
108467
108844
|
record({ ...mutant, status: "skipped", durationMs: 0, tests, reason: "budget" });
|
|
108468
108845
|
continue;
|
|
108469
108846
|
}
|
|
108470
|
-
const original =
|
|
108847
|
+
const original = readFileSync33(path78.join(copy, mutant.file), "utf8");
|
|
108471
108848
|
const mutated = original.slice(0, mutant.start) + mutant.replacement + original.slice(mutant.end);
|
|
108472
108849
|
current = { file: mutant.file, original };
|
|
108473
108850
|
if (!writeInside(copy, mutant.file, mutated)) {
|
|
@@ -108524,8 +108901,8 @@ var NOT_SOURCE, FLIPS, isStringy = (node) => node.type === "StringLiteral" || no
|
|
|
108524
108901
|
return error.code === "EPERM";
|
|
108525
108902
|
}
|
|
108526
108903
|
}, inside5 = (root, file) => {
|
|
108527
|
-
const relative =
|
|
108528
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
108904
|
+
const relative = path78.relative(root, file);
|
|
108905
|
+
return relative === "" || !relative.startsWith("..") && !path78.isAbsolute(relative);
|
|
108529
108906
|
}, active, killTree = (child) => {
|
|
108530
108907
|
try {
|
|
108531
108908
|
if (child.pid && process.platform !== "win32")
|
|
@@ -108573,8 +108950,8 @@ var exports_test_audit = {};
|
|
|
108573
108950
|
__export(exports_test_audit, {
|
|
108574
108951
|
run: () => run23
|
|
108575
108952
|
});
|
|
108576
|
-
import { existsSync as
|
|
108577
|
-
import
|
|
108953
|
+
import { existsSync as existsSync31 } from "node:fs";
|
|
108954
|
+
import path79 from "node:path";
|
|
108578
108955
|
function parse8(argv) {
|
|
108579
108956
|
const options = {
|
|
108580
108957
|
paths: [],
|
|
@@ -108679,8 +109056,8 @@ async function run23(argv, io) {
|
|
|
108679
109056
|
return emit(io, fail2("invalid_input", `${options}
|
|
108680
109057
|
usage: ${USAGE16}`));
|
|
108681
109058
|
const top = git7(io.cwd, ["rev-parse", "--show-toplevel"]);
|
|
108682
|
-
const repo = top.ok ?
|
|
108683
|
-
const display = (file) => toPosix(
|
|
109059
|
+
const repo = top.ok ? path79.resolve(top.stdout.trim()) : null;
|
|
109060
|
+
const display = (file) => toPosix(path79.relative(io.cwd, file) || file);
|
|
108684
109061
|
let base = null;
|
|
108685
109062
|
let changed = null;
|
|
108686
109063
|
if (options.diff || options.mutate) {
|
|
@@ -108697,7 +109074,7 @@ usage: ${USAGE16}`));
|
|
|
108697
109074
|
}
|
|
108698
109075
|
let files;
|
|
108699
109076
|
if (options.diff && changed)
|
|
108700
|
-
files = [...changed.keys()].filter((file) => TEST_FILE.test(toPosix(file)) &&
|
|
109077
|
+
files = [...changed.keys()].filter((file) => TEST_FILE.test(toPosix(file)) && existsSync31(file)).toSorted();
|
|
108701
109078
|
else {
|
|
108702
109079
|
const expanded = expandPaths(io.cwd, options.paths);
|
|
108703
109080
|
if (expanded.missing.length > 0)
|
|
@@ -108818,8 +109195,8 @@ var exports_youtrack = {};
|
|
|
108818
109195
|
__export(exports_youtrack, {
|
|
108819
109196
|
run: () => run25
|
|
108820
109197
|
});
|
|
108821
|
-
import { readFileSync as
|
|
108822
|
-
import
|
|
109198
|
+
import { readFileSync as readFileSync34 } from "node:fs";
|
|
109199
|
+
import path80 from "node:path";
|
|
108823
109200
|
async function run25(argv, io) {
|
|
108824
109201
|
const [sub, ...rest] = argv;
|
|
108825
109202
|
if (sub !== "note" && sub !== "time" && sub !== "meeting")
|
|
@@ -108865,7 +109242,7 @@ async function run25(argv, io) {
|
|
|
108865
109242
|
let markdown = flags.values.markdown ?? "";
|
|
108866
109243
|
if (flags.values.file)
|
|
108867
109244
|
try {
|
|
108868
|
-
markdown =
|
|
109245
|
+
markdown = readFileSync34(path80.resolve(io.cwd, flags.values.file), "utf8");
|
|
108869
109246
|
} catch (error) {
|
|
108870
109247
|
return usage4(io, `cannot read ${flags.values.file}: ${String(error)}`, USAGE18);
|
|
108871
109248
|
}
|
|
@@ -108936,8 +109313,8 @@ var exports_changelog = {};
|
|
|
108936
109313
|
__export(exports_changelog, {
|
|
108937
109314
|
run: () => run26
|
|
108938
109315
|
});
|
|
108939
|
-
import { readFileSync as
|
|
108940
|
-
import
|
|
109316
|
+
import { readFileSync as readFileSync35 } from "node:fs";
|
|
109317
|
+
import path81 from "node:path";
|
|
108941
109318
|
async function run26(argv, io) {
|
|
108942
109319
|
const [sub, ...rest] = argv;
|
|
108943
109320
|
if (sub !== "apply")
|
|
@@ -108983,7 +109360,7 @@ async function run26(argv, io) {
|
|
|
108983
109360
|
]);
|
|
108984
109361
|
}
|
|
108985
109362
|
var USAGE19 = "workit changelog apply (--entries <JSON|@file|-> | --normalize-only) [--path CHANGELOG.md] [--preview]", readEntries = (raw, cwd) => {
|
|
108986
|
-
const text = raw === "-" ?
|
|
109363
|
+
const text = raw === "-" ? readFileSync35(0, "utf8") : raw.startsWith("@") ? readFileSync35(path81.resolve(cwd, raw.slice(1)), "utf8") : raw;
|
|
108987
109364
|
return JSON.parse(text);
|
|
108988
109365
|
};
|
|
108989
109366
|
var init_changelog2 = __esm(() => {
|
|
@@ -108999,7 +109376,7 @@ __export(exports_handoff, {
|
|
|
108999
109376
|
run: () => run27
|
|
109000
109377
|
});
|
|
109001
109378
|
import fs37 from "node:fs";
|
|
109002
|
-
import
|
|
109379
|
+
import path82 from "node:path";
|
|
109003
109380
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
109004
109381
|
function render3(brief) {
|
|
109005
109382
|
const lines = [
|
|
@@ -109039,9 +109416,9 @@ function bounded(brief, cwd) {
|
|
|
109039
109416
|
let file = null;
|
|
109040
109417
|
if (store.ok)
|
|
109041
109418
|
try {
|
|
109042
|
-
const dir =
|
|
109419
|
+
const dir = path82.join(store.value.root, "handoff");
|
|
109043
109420
|
fs37.mkdirSync(dir, { recursive: true });
|
|
109044
|
-
file =
|
|
109421
|
+
file = path82.join(dir, `${(brief.branch ?? "detached").replaceAll(/[^\w.-]+/gu, "-")}.txt`);
|
|
109045
109422
|
fs37.writeFileSync(file, `${[...body, ...tail].join(`
|
|
109046
109423
|
`)}
|
|
109047
109424
|
`, {
|
|
@@ -109116,7 +109493,7 @@ var init_handoff = __esm(() => {
|
|
|
109116
109493
|
});
|
|
109117
109494
|
|
|
109118
109495
|
// packages/workit-cli/src/main.ts
|
|
109119
|
-
import
|
|
109496
|
+
import path83 from "node:path";
|
|
109120
109497
|
|
|
109121
109498
|
// packages/workit-core/src/git/env-redirect.ts
|
|
109122
109499
|
var GIT_REDIRECT_ENV = [
|
|
@@ -110065,7 +110442,7 @@ var defaultIo = (json) => ({
|
|
|
110065
110442
|
});
|
|
110066
110443
|
async function main(argv, overrides = {}, options = {}) {
|
|
110067
110444
|
const parsed = parseGlobals(argv);
|
|
110068
|
-
const cwd =
|
|
110445
|
+
const cwd = path83.resolve(overrides.cwd ?? process.cwd(), parsed.cwd ?? ".");
|
|
110069
110446
|
const io = {
|
|
110070
110447
|
...defaultIo(parsed.json),
|
|
110071
110448
|
terminals: {
|