@brainervirus/workit-cli 8.40.7 → 8.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +357 -106
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -6537,6 +6537,15 @@ var nonBlank, branchPreset, commitPreset, workspaceBranchPolicySchema, workspace
|
|
|
6537
6537
|
return cached;
|
|
6538
6538
|
let dir = path2.resolve(cwd);
|
|
6539
6539
|
while (!existsSync2(path2.join(dir, ".git"))) {
|
|
6540
|
+
if (["HEAD", "objects", "refs"].every((name) => existsSync2(path2.join(dir, name)))) {
|
|
6541
|
+
const real = realpathOf(dir);
|
|
6542
|
+
const owner = ownInternals(real) === true ? gitDirOwner(real) : null;
|
|
6543
|
+
if (owner === null)
|
|
6544
|
+
return Error(`${cwd} is in a repository with no work tree at ${real}: no grants apply`);
|
|
6545
|
+
const probe = { main: owner, superproject: null };
|
|
6546
|
+
probes.set(cwd, probe);
|
|
6547
|
+
return probe;
|
|
6548
|
+
}
|
|
6540
6549
|
const up = path2.dirname(dir);
|
|
6541
6550
|
if (up === dir)
|
|
6542
6551
|
return null;
|
|
@@ -6575,6 +6584,14 @@ var nonBlank, branchPreset, commitPreset, workspaceBranchPolicySchema, workspace
|
|
|
6575
6584
|
if (owner !== realpathOf(dir))
|
|
6576
6585
|
main = owner;
|
|
6577
6586
|
}
|
|
6587
|
+
const lender = ownInternals(real);
|
|
6588
|
+
if (lender === false)
|
|
6589
|
+
return Error(`${cwd} borrows git internals from outside ${real} that no checkout owns`);
|
|
6590
|
+
if (lender !== true && lender !== realpathOf(dir)) {
|
|
6591
|
+
if (main !== null && main !== lender)
|
|
6592
|
+
return Error(`${cwd} mixes the repositories of ${main} and ${lender}`);
|
|
6593
|
+
main = lender;
|
|
6594
|
+
}
|
|
6578
6595
|
} else {
|
|
6579
6596
|
const list = git(["worktree", "list", "--porcelain"]);
|
|
6580
6597
|
if (list === null)
|
|
@@ -6590,6 +6607,30 @@ var nonBlank, branchPreset, commitPreset, workspaceBranchPolicySchema, workspace
|
|
|
6590
6607
|
} catch {
|
|
6591
6608
|
return false;
|
|
6592
6609
|
}
|
|
6610
|
+
}, INTERNALS, ownInternals = (real) => {
|
|
6611
|
+
let lender = null;
|
|
6612
|
+
for (const name of INTERNALS) {
|
|
6613
|
+
const at = path2.join(real, name);
|
|
6614
|
+
try {
|
|
6615
|
+
lstatSync(at);
|
|
6616
|
+
} catch {
|
|
6617
|
+
continue;
|
|
6618
|
+
}
|
|
6619
|
+
let resolved;
|
|
6620
|
+
try {
|
|
6621
|
+
resolved = (realpathSync.native ?? realpathSync)(at);
|
|
6622
|
+
} catch {
|
|
6623
|
+
return false;
|
|
6624
|
+
}
|
|
6625
|
+
const rel = path2.relative(real, resolved);
|
|
6626
|
+
if (rel && !rel.startsWith("..") && !path2.isAbsolute(rel))
|
|
6627
|
+
continue;
|
|
6628
|
+
const owner = path2.basename(resolved) === name ? gitDirOwner(path2.dirname(resolved)) : null;
|
|
6629
|
+
if (owner === null || lender !== null && lender !== owner)
|
|
6630
|
+
return false;
|
|
6631
|
+
lender = owner;
|
|
6632
|
+
}
|
|
6633
|
+
return lender ?? true;
|
|
6593
6634
|
}, gitDirOwner = (real) => {
|
|
6594
6635
|
const parts = real.split(/[\\/]/u);
|
|
6595
6636
|
const at = parts.lastIndexOf(".git");
|
|
@@ -7058,6 +7099,7 @@ var init_workspaces = __esm(() => {
|
|
|
7058
7099
|
name = "WorkspaceConfigError";
|
|
7059
7100
|
};
|
|
7060
7101
|
probes = new Map;
|
|
7102
|
+
INTERNALS = ["refs", "objects", "config", "packed-refs", "commondir"];
|
|
7061
7103
|
runtimeWorkspaceIndexSchema = object({
|
|
7062
7104
|
workspaces: array(object({ name: nonBlank, glob: nonBlank }).passthrough()).optional()
|
|
7063
7105
|
}).passthrough();
|
|
@@ -9375,7 +9417,7 @@ var package_default;
|
|
|
9375
9417
|
var init_package = __esm(() => {
|
|
9376
9418
|
package_default = {
|
|
9377
9419
|
name: "@brainervirus/workit-cli",
|
|
9378
|
-
version: "8.
|
|
9420
|
+
version: "8.41.0",
|
|
9379
9421
|
private: false,
|
|
9380
9422
|
description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
9381
9423
|
keywords: [
|
|
@@ -9413,13 +9455,13 @@ var init_package = __esm(() => {
|
|
|
9413
9455
|
},
|
|
9414
9456
|
dependencies: {
|
|
9415
9457
|
"@babel/parser": "7.29.9",
|
|
9416
|
-
"@brainervirus/workit-cursor": "^8.
|
|
9458
|
+
"@brainervirus/workit-cursor": "^8.41.0",
|
|
9417
9459
|
"@inkjs/ui": "2.0.0",
|
|
9418
9460
|
ink: "7.1.1",
|
|
9419
9461
|
react: "19.2.8"
|
|
9420
9462
|
},
|
|
9421
9463
|
devDependencies: {
|
|
9422
|
-
"@brainervirus/workit-core": "^8.
|
|
9464
|
+
"@brainervirus/workit-core": "^8.41.0"
|
|
9423
9465
|
},
|
|
9424
9466
|
engines: {
|
|
9425
9467
|
node: ">=24"
|
|
@@ -75176,7 +75218,124 @@ var init_setup2 = __esm(() => {
|
|
|
75176
75218
|
ALL_HOSTS = ["claude-code", "codex", "cursor", "opencode", "pi"];
|
|
75177
75219
|
});
|
|
75178
75220
|
|
|
75221
|
+
// packages/workit-cli/src/progress.ts
|
|
75222
|
+
function createProgress(options = {}) {
|
|
75223
|
+
const env = options.env ?? process.env;
|
|
75224
|
+
const mode = modeFor(options, env);
|
|
75225
|
+
const stream = options.stream;
|
|
75226
|
+
const now = options.now ?? Date.now;
|
|
75227
|
+
const every = options.setInterval ?? ((tick, ms) => setInterval(tick, ms));
|
|
75228
|
+
const stop = options.clearInterval ?? ((timer) => clearInterval(timer));
|
|
75229
|
+
const proc = options.proc ?? process;
|
|
75230
|
+
const ascii = env.TERM === "dumb";
|
|
75231
|
+
const glyphs = mode === "spinner" ? { done: "\x1B[32m✓\x1B[0m", failed: "\x1B[31m✗\x1B[0m", skipped: "–" } : ascii ? { done: "ok", failed: "x", skipped: "-" } : { done: "✓", failed: "✗", skipped: "–" };
|
|
75232
|
+
const start = (initial) => {
|
|
75233
|
+
if (mode === "off" || !stream)
|
|
75234
|
+
return NOOP_STEP;
|
|
75235
|
+
let text = initial;
|
|
75236
|
+
let finished = false;
|
|
75237
|
+
const began = now();
|
|
75238
|
+
let frame = 0;
|
|
75239
|
+
const draw = () => {
|
|
75240
|
+
const seconds = Math.floor((now() - began) / 1000);
|
|
75241
|
+
let line = `${FRAMES[frame % FRAMES.length]} ${text} (${seconds}s)`;
|
|
75242
|
+
if (stream.columns && line.length >= stream.columns)
|
|
75243
|
+
line = `${line.slice(0, Math.max(1, stream.columns - 2))}…`;
|
|
75244
|
+
stream.write(`${CLEAR}${line}`);
|
|
75245
|
+
};
|
|
75246
|
+
let timer;
|
|
75247
|
+
if (mode === "spinner") {
|
|
75248
|
+
draw();
|
|
75249
|
+
timer = every(() => {
|
|
75250
|
+
frame += 1;
|
|
75251
|
+
draw();
|
|
75252
|
+
}, FRAME_MS);
|
|
75253
|
+
}
|
|
75254
|
+
const handlers = [];
|
|
75255
|
+
const release = () => {
|
|
75256
|
+
for (const [event, handler] of handlers)
|
|
75257
|
+
proc.off(event, handler);
|
|
75258
|
+
handlers.length = 0;
|
|
75259
|
+
};
|
|
75260
|
+
if (mode === "spinner") {
|
|
75261
|
+
const onSignal = (signal) => () => {
|
|
75262
|
+
if (!finished) {
|
|
75263
|
+
finished = true;
|
|
75264
|
+
if (timer !== undefined)
|
|
75265
|
+
stop(timer);
|
|
75266
|
+
stream.write(CLEAR);
|
|
75267
|
+
}
|
|
75268
|
+
release();
|
|
75269
|
+
proc.kill(proc.pid, signal);
|
|
75270
|
+
};
|
|
75271
|
+
const onExit = () => {
|
|
75272
|
+
if (!finished)
|
|
75273
|
+
stream.write(CLEAR);
|
|
75274
|
+
};
|
|
75275
|
+
handlers.push(["SIGINT", onSignal("SIGINT")], ["SIGTERM", onSignal("SIGTERM")]);
|
|
75276
|
+
handlers.push(["exit", onExit]);
|
|
75277
|
+
for (const [event, handler] of handlers)
|
|
75278
|
+
proc.on(event, handler);
|
|
75279
|
+
}
|
|
75280
|
+
return {
|
|
75281
|
+
label: (next) => {
|
|
75282
|
+
text = next;
|
|
75283
|
+
if (mode === "spinner" && !finished)
|
|
75284
|
+
draw();
|
|
75285
|
+
},
|
|
75286
|
+
end: (status, note) => {
|
|
75287
|
+
if (finished)
|
|
75288
|
+
return;
|
|
75289
|
+
finished = true;
|
|
75290
|
+
if (timer !== undefined)
|
|
75291
|
+
stop(timer);
|
|
75292
|
+
release();
|
|
75293
|
+
stream.write(`${mode === "spinner" ? CLEAR : ""}${glyphs[status]} ${text}${note ? `: ${note}` : ""}
|
|
75294
|
+
`);
|
|
75295
|
+
}
|
|
75296
|
+
};
|
|
75297
|
+
};
|
|
75298
|
+
return {
|
|
75299
|
+
mode,
|
|
75300
|
+
start,
|
|
75301
|
+
async run(label, fn, classify) {
|
|
75302
|
+
const step = start(label);
|
|
75303
|
+
try {
|
|
75304
|
+
const value = await fn();
|
|
75305
|
+
step.end(classify ? classify(value) : "done");
|
|
75306
|
+
return value;
|
|
75307
|
+
} catch (error) {
|
|
75308
|
+
step.end("failed");
|
|
75309
|
+
throw error;
|
|
75310
|
+
}
|
|
75311
|
+
},
|
|
75312
|
+
runSync(label, fn, classify) {
|
|
75313
|
+
const step = start(label);
|
|
75314
|
+
try {
|
|
75315
|
+
const value = fn();
|
|
75316
|
+
step.end(classify ? classify(value) : "done");
|
|
75317
|
+
return value;
|
|
75318
|
+
} catch (error) {
|
|
75319
|
+
step.end("failed");
|
|
75320
|
+
throw error;
|
|
75321
|
+
}
|
|
75322
|
+
}
|
|
75323
|
+
};
|
|
75324
|
+
}
|
|
75325
|
+
var FRAMES, FRAME_MS = 120, CLEAR = "\r\x1B[2K", truthy = (value) => value !== undefined && value !== "" && value !== "0" && value.toLowerCase() !== "false", modeFor = (options, env) => {
|
|
75326
|
+
if (options.json || !options.stream?.isTTY || truthy(env.CI))
|
|
75327
|
+
return "off";
|
|
75328
|
+
if (truthy(env.NO_COLOR) || env.TERM === "dumb")
|
|
75329
|
+
return "plain";
|
|
75330
|
+
return "spinner";
|
|
75331
|
+
}, NOOP_STEP;
|
|
75332
|
+
var init_progress = __esm(() => {
|
|
75333
|
+
FRAMES = ["·", "✢", "✳", "∗", "✻", "✽"];
|
|
75334
|
+
NOOP_STEP = { label: () => {}, end: () => {} };
|
|
75335
|
+
});
|
|
75336
|
+
|
|
75179
75337
|
// packages/workit-cli/src/upgrade/shared.ts
|
|
75338
|
+
import { spawn } from "node:child_process";
|
|
75180
75339
|
import { existsSync as existsSync21, readFileSync as readFileSync22 } from "node:fs";
|
|
75181
75340
|
import path44 from "node:path";
|
|
75182
75341
|
import os16 from "node:os";
|
|
@@ -75237,7 +75396,61 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75237
75396
|
}
|
|
75238
75397
|
const result = runHostCommand(step, { home, env });
|
|
75239
75398
|
return { status: result.exitCode, stdout: result.stdout };
|
|
75240
|
-
}),
|
|
75399
|
+
}), COMMAND_TIMEOUT_MS = 60000, asyncRunner = (deps) => {
|
|
75400
|
+
if (deps.runAsync)
|
|
75401
|
+
return deps.runAsync;
|
|
75402
|
+
const injected = deps.run;
|
|
75403
|
+
if (injected)
|
|
75404
|
+
return async (command, args) => injected(command, args);
|
|
75405
|
+
return (command, args) => {
|
|
75406
|
+
const { home, env } = upgradePaths(deps);
|
|
75407
|
+
let step;
|
|
75408
|
+
try {
|
|
75409
|
+
step = hostCommand(command, args, { home, env });
|
|
75410
|
+
} catch {
|
|
75411
|
+
return Promise.resolve({ status: 1, stdout: "" });
|
|
75412
|
+
}
|
|
75413
|
+
if (process.platform === "win32" && /\.(?:cmd|bat)$/i.test(step.command))
|
|
75414
|
+
return Promise.resolve({ status: 1, stdout: "" });
|
|
75415
|
+
const childEnv = { ...process.env, ...env, HOME: home };
|
|
75416
|
+
childEnv.CODEX_HOME = env.CODEX_HOME ?? path44.join(home, ".codex");
|
|
75417
|
+
childEnv.PI_CODING_AGENT_DIR = env.PI_CODING_AGENT_DIR ?? path44.join(home, ".pi", "agent");
|
|
75418
|
+
childEnv.CLAUDE_CONFIG_DIR = env.CLAUDE_CONFIG_DIR ?? path44.join(home, ".claude");
|
|
75419
|
+
childEnv.XDG_CONFIG_HOME = env.XDG_CONFIG_HOME ?? path44.join(home, ".config");
|
|
75420
|
+
return new Promise((resolve) => {
|
|
75421
|
+
let stdout = "";
|
|
75422
|
+
let settled = false;
|
|
75423
|
+
const finish = (status) => {
|
|
75424
|
+
if (settled)
|
|
75425
|
+
return;
|
|
75426
|
+
settled = true;
|
|
75427
|
+
clearTimeout(timer);
|
|
75428
|
+
resolve({ status, stdout });
|
|
75429
|
+
};
|
|
75430
|
+
let child;
|
|
75431
|
+
try {
|
|
75432
|
+
child = spawn(step.command, step.args, {
|
|
75433
|
+
cwd: step.cwd,
|
|
75434
|
+
env: childEnv,
|
|
75435
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
75436
|
+
windowsHide: true,
|
|
75437
|
+
shell: false
|
|
75438
|
+
});
|
|
75439
|
+
} catch {
|
|
75440
|
+
resolve({ status: 1, stdout: "" });
|
|
75441
|
+
return;
|
|
75442
|
+
}
|
|
75443
|
+
const timer = setTimeout(() => {
|
|
75444
|
+
child.kill("SIGKILL");
|
|
75445
|
+
finish(1);
|
|
75446
|
+
}, COMMAND_TIMEOUT_MS);
|
|
75447
|
+
child.stdout?.setEncoding("utf8");
|
|
75448
|
+
child.stdout?.on("data", (chunk) => stdout += chunk);
|
|
75449
|
+
child.on("error", () => finish(1));
|
|
75450
|
+
child.on("close", (code) => finish(code ?? 1));
|
|
75451
|
+
});
|
|
75452
|
+
};
|
|
75453
|
+
}, errorText = (error) => error instanceof Error ? error.message : "installed source could not be read", piInstalledVersion = (listing, selector) => {
|
|
75241
75454
|
const lines = listing.split(/\r?\n/).map((line) => line.trim());
|
|
75242
75455
|
const index = lines.indexOf(selector);
|
|
75243
75456
|
if (index < 0 || !lines[index + 1] || !path44.isAbsolute(lines[index + 1]))
|
|
@@ -75326,7 +75539,7 @@ var init_processes = __esm(() => {
|
|
|
75326
75539
|
import { existsSync as existsSync22, readdirSync as readdirSync12, mkdirSync as mkdirSync11, copyFileSync as copyFileSync6, chmodSync as chmodSync2, cpSync as cpSync5 } from "node:fs";
|
|
75327
75540
|
import path46 from "node:path";
|
|
75328
75541
|
import { createHash as createHash16 } from "node:crypto";
|
|
75329
|
-
function applyUpgrade(plan, deps = {}) {
|
|
75542
|
+
async function applyUpgrade(plan, deps = {}) {
|
|
75330
75543
|
const hosts = [...plan.failed];
|
|
75331
75544
|
const done = (backup) => {
|
|
75332
75545
|
const failures = hosts.filter((entry) => entry.status === "failed");
|
|
@@ -75381,6 +75594,9 @@ function applyUpgrade(plan, deps = {}) {
|
|
|
75381
75594
|
`, 384);
|
|
75382
75595
|
}
|
|
75383
75596
|
const run = runner(deps);
|
|
75597
|
+
const runAsync = asyncRunner(deps);
|
|
75598
|
+
const progress = deps.progress ?? createProgress({ json: true });
|
|
75599
|
+
const statusOf = (outcome) => outcome?.status === "failed" ? "failed" : outcome?.status === "updated" ? "done" : "skipped";
|
|
75384
75600
|
let cursorBackupError = null;
|
|
75385
75601
|
if (plan.entries.some((entry) => entry.host === "cursor") && existsSync22(paths.cursorRoot))
|
|
75386
75602
|
try {
|
|
@@ -75393,96 +75609,104 @@ function applyUpgrade(plan, deps = {}) {
|
|
|
75393
75609
|
const listed = plan.entries.length ? listProcesses(deps) : [];
|
|
75394
75610
|
const running = (listed ?? []).flatMap((entry) => classifyProcess(entry) ?? []);
|
|
75395
75611
|
for (const entry of plan.entries) {
|
|
75396
|
-
|
|
75397
|
-
|
|
75398
|
-
|
|
75399
|
-
|
|
75400
|
-
reason: cursorBackupError,
|
|
75401
|
-
fix: entry.fix
|
|
75402
|
-
});
|
|
75403
|
-
continue;
|
|
75404
|
-
}
|
|
75405
|
-
if (!LIVE_HOSTS.has(entry.host)) {
|
|
75406
|
-
if (listed === null) {
|
|
75612
|
+
const before = hosts.length;
|
|
75613
|
+
const step = progress.start(`Updating ${entry.host}`);
|
|
75614
|
+
try {
|
|
75615
|
+
if (entry.host === "cursor" && cursorBackupError) {
|
|
75407
75616
|
hosts.push({
|
|
75408
|
-
host:
|
|
75409
|
-
status: "
|
|
75410
|
-
reason:
|
|
75411
|
-
fix:
|
|
75617
|
+
host: "cursor",
|
|
75618
|
+
status: "failed",
|
|
75619
|
+
reason: cursorBackupError,
|
|
75620
|
+
fix: entry.fix
|
|
75412
75621
|
});
|
|
75413
75622
|
continue;
|
|
75414
75623
|
}
|
|
75415
|
-
|
|
75416
|
-
|
|
75624
|
+
if (!LIVE_HOSTS.has(entry.host)) {
|
|
75625
|
+
if (listed === null) {
|
|
75626
|
+
hosts.push({
|
|
75627
|
+
host: entry.host,
|
|
75628
|
+
status: "skipped",
|
|
75629
|
+
reason: `running processes could not be listed; close ${entry.host} and rerun`,
|
|
75630
|
+
fix: `workit upgrade --hosts=${entry.host}`
|
|
75631
|
+
});
|
|
75632
|
+
continue;
|
|
75633
|
+
}
|
|
75634
|
+
const sessions = running.filter((proc) => proc.host === entry.host && proc.kind === "session");
|
|
75635
|
+
if (sessions.length) {
|
|
75636
|
+
hosts.push({
|
|
75637
|
+
host: entry.host,
|
|
75638
|
+
status: "skipped",
|
|
75639
|
+
reason: `close ${entry.host} (${sessions.map(describe2).join("; ")}), then rerun`,
|
|
75640
|
+
fix: `workit upgrade --hosts=${entry.host}`
|
|
75641
|
+
});
|
|
75642
|
+
continue;
|
|
75643
|
+
}
|
|
75644
|
+
}
|
|
75645
|
+
const daemons = running.filter((proc) => proc.host === "codex" && proc.kind === "daemon");
|
|
75646
|
+
const stopDaemon = entry.host === "codex" && daemons.length > 0;
|
|
75647
|
+
const stopped = stopDaemon ? await progress.run("Stopping the Codex app-server daemon", () => runAsync("codex", ["app-server", "daemon", "stop"]), (result) => result.status === 0 ? "done" : "failed") : null;
|
|
75648
|
+
if (stopped && stopped.status !== 0) {
|
|
75417
75649
|
hosts.push({
|
|
75418
|
-
host:
|
|
75419
|
-
status: "
|
|
75420
|
-
reason: `
|
|
75421
|
-
fix:
|
|
75650
|
+
host: "codex",
|
|
75651
|
+
status: "failed",
|
|
75652
|
+
reason: `could not stop the Codex app-server daemon (${daemons.map(describe2).join("; ")})`,
|
|
75653
|
+
fix: "codex app-server daemon stop && workit upgrade --hosts=codex"
|
|
75422
75654
|
});
|
|
75423
75655
|
continue;
|
|
75424
75656
|
}
|
|
75425
|
-
|
|
75426
|
-
|
|
75427
|
-
|
|
75428
|
-
|
|
75429
|
-
|
|
75430
|
-
|
|
75431
|
-
|
|
75432
|
-
|
|
75433
|
-
|
|
75434
|
-
|
|
75435
|
-
|
|
75436
|
-
|
|
75437
|
-
|
|
75438
|
-
|
|
75439
|
-
|
|
75440
|
-
|
|
75441
|
-
|
|
75442
|
-
|
|
75657
|
+
let outcome;
|
|
75658
|
+
try {
|
|
75659
|
+
outcome = await applyEntry(entry, { run, runAsync, paths, configDir });
|
|
75660
|
+
if (entry.host === "codex" && outcome.status === "updated") {
|
|
75661
|
+
const agents = await refreshCodexAgents(runAsync, paths.codexHome);
|
|
75662
|
+
if (!agents.ok)
|
|
75663
|
+
outcome = {
|
|
75664
|
+
...outcome,
|
|
75665
|
+
status: "failed",
|
|
75666
|
+
reason: `${outcome.reason}; ${agents.note}`,
|
|
75667
|
+
fix: agents.fix
|
|
75668
|
+
};
|
|
75669
|
+
else if (agents.note)
|
|
75670
|
+
outcome = { ...outcome, reason: `${outcome.reason}; ${agents.note}` };
|
|
75671
|
+
}
|
|
75672
|
+
} catch (error) {
|
|
75673
|
+
outcome = {
|
|
75674
|
+
host: entry.host,
|
|
75675
|
+
status: "failed",
|
|
75676
|
+
reason: errorText(error),
|
|
75677
|
+
fix: entry.fix
|
|
75678
|
+
};
|
|
75679
|
+
}
|
|
75680
|
+
if (stopDaemon) {
|
|
75681
|
+
const started = (await progress.run("Restarting the Codex app-server daemon", () => runAsync("codex", ["app-server", "daemon", "start"]), (result) => result.status === 0 ? "done" : "failed")).status === 0;
|
|
75682
|
+
outcome = started ? {
|
|
75683
|
+
...outcome,
|
|
75684
|
+
reason: `${outcome.reason}; app-server daemon stopped and started again`
|
|
75685
|
+
} : {
|
|
75686
|
+
...outcome,
|
|
75687
|
+
status: "failed",
|
|
75688
|
+
reason: `${outcome.reason}; the app-server daemon did not start again`,
|
|
75689
|
+
fix: "codex app-server daemon start"
|
|
75690
|
+
};
|
|
75691
|
+
}
|
|
75692
|
+
if (entry.host === "opencode") {
|
|
75693
|
+
const servers = running.filter((proc) => proc.host === "opencode" && proc.kind === "daemon");
|
|
75694
|
+
if (servers.length && outcome.status === "updated")
|
|
75443
75695
|
outcome = {
|
|
75444
75696
|
...outcome,
|
|
75445
|
-
|
|
75446
|
-
reason: `${outcome.reason}; ${agents.note}`,
|
|
75447
|
-
fix: agents.fix
|
|
75697
|
+
reason: `${outcome.reason}; restart opencode serve (${servers.map(describe2).join("; ")}) to load it`
|
|
75448
75698
|
};
|
|
75449
|
-
else if (agents.note)
|
|
75450
|
-
outcome = { ...outcome, reason: `${outcome.reason}; ${agents.note}` };
|
|
75451
75699
|
}
|
|
75452
|
-
|
|
75453
|
-
|
|
75454
|
-
|
|
75455
|
-
|
|
75456
|
-
reason: errorText(error),
|
|
75457
|
-
fix: entry.fix
|
|
75458
|
-
};
|
|
75459
|
-
}
|
|
75460
|
-
if (stopDaemon) {
|
|
75461
|
-
const started = run("codex", ["app-server", "daemon", "start"]).status === 0;
|
|
75462
|
-
outcome = started ? {
|
|
75463
|
-
...outcome,
|
|
75464
|
-
reason: `${outcome.reason}; app-server daemon stopped and started again`
|
|
75465
|
-
} : {
|
|
75466
|
-
...outcome,
|
|
75467
|
-
status: "failed",
|
|
75468
|
-
reason: `${outcome.reason}; the app-server daemon did not start again`,
|
|
75469
|
-
fix: "codex app-server daemon start"
|
|
75470
|
-
};
|
|
75471
|
-
}
|
|
75472
|
-
if (entry.host === "opencode") {
|
|
75473
|
-
const servers = running.filter((proc) => proc.host === "opencode" && proc.kind === "daemon");
|
|
75474
|
-
if (servers.length && outcome.status === "updated")
|
|
75475
|
-
outcome = {
|
|
75476
|
-
...outcome,
|
|
75477
|
-
reason: `${outcome.reason}; restart opencode serve (${servers.map(describe2).join("; ")}) to load it`
|
|
75478
|
-
};
|
|
75700
|
+
hosts.push(outcome);
|
|
75701
|
+
} finally {
|
|
75702
|
+
const added = hosts.length > before ? hosts[hosts.length - 1] : undefined;
|
|
75703
|
+
step.end(statusOf(added), added && added.status !== "updated" ? added.reason : undefined);
|
|
75479
75704
|
}
|
|
75480
|
-
hosts.push(outcome);
|
|
75481
75705
|
}
|
|
75482
75706
|
if (hosts.some((entry) => entry.host === "codex" && entry.status === "current")) {
|
|
75483
75707
|
let agents;
|
|
75484
75708
|
try {
|
|
75485
|
-
agents = refreshCodexAgents(
|
|
75709
|
+
agents = await refreshCodexAgents(runAsync, paths.codexHome);
|
|
75486
75710
|
} catch (error) {
|
|
75487
75711
|
agents = {
|
|
75488
75712
|
ok: false,
|
|
@@ -75506,7 +75730,7 @@ function applyUpgrade(plan, deps = {}) {
|
|
|
75506
75730
|
}
|
|
75507
75731
|
if (plan.cli)
|
|
75508
75732
|
try {
|
|
75509
|
-
hosts.push(applyCli(plan.cli,
|
|
75733
|
+
hosts.push(await progress.run("Updating the CLI", () => applyCli(plan.cli, runAsync, backup), statusOf));
|
|
75510
75734
|
} catch (error) {
|
|
75511
75735
|
hosts.push({
|
|
75512
75736
|
host: "cli",
|
|
@@ -75527,8 +75751,8 @@ var codexPluginRoot = (codexHome) => {
|
|
|
75527
75751
|
}
|
|
75528
75752
|
const newest = versions.reduce((best, version) => best && versionAtLeast(best, version) ? best : version, null);
|
|
75529
75753
|
return newest ? path46.join(dir, newest) : null;
|
|
75530
|
-
}, opencodeVersion = (run) => {
|
|
75531
|
-
const listing = run("opencode", ["plugin", "list"]);
|
|
75754
|
+
}, opencodeVersion = async (run) => {
|
|
75755
|
+
const listing = await run("opencode", ["plugin", "list"]);
|
|
75532
75756
|
if (listing.status !== 0)
|
|
75533
75757
|
return;
|
|
75534
75758
|
for (const line of listing.stdout.split(/\r?\n/)) {
|
|
@@ -75541,8 +75765,8 @@ var codexPluginRoot = (codexHome) => {
|
|
|
75541
75765
|
return version;
|
|
75542
75766
|
}
|
|
75543
75767
|
return;
|
|
75544
|
-
}, applyEntry = (entry, context) => {
|
|
75545
|
-
const { run, paths, configDir } = context;
|
|
75768
|
+
}, applyEntry = async (entry, context) => {
|
|
75769
|
+
const { run, runAsync, paths, configDir } = context;
|
|
75546
75770
|
const { home, env } = paths;
|
|
75547
75771
|
const fail = (reason) => ({
|
|
75548
75772
|
host: entry.host,
|
|
@@ -75594,12 +75818,12 @@ var codexPluginRoot = (codexHome) => {
|
|
|
75594
75818
|
reason: entry.repair ? `reinstalled missing plugin files (${entry.latest})` : `${entry.installedVersion ?? "?"} -> ${entry.latest}`
|
|
75595
75819
|
};
|
|
75596
75820
|
}
|
|
75597
|
-
const before = entry.host === "opencode" ? opencodeVersion(
|
|
75821
|
+
const before = entry.host === "opencode" ? await opencodeVersion(runAsync) : undefined;
|
|
75598
75822
|
for (const command of entry.commands)
|
|
75599
|
-
if (
|
|
75823
|
+
if ((await runAsync(command.command, command.args)).status !== 0)
|
|
75600
75824
|
return fail(`\`${command.command} ${command.args.join(" ")}\` failed`);
|
|
75601
75825
|
if (entry.host === "opencode") {
|
|
75602
|
-
const after = opencodeVersion(
|
|
75826
|
+
const after = await opencodeVersion(runAsync);
|
|
75603
75827
|
if (before && after)
|
|
75604
75828
|
return after === before ? {
|
|
75605
75829
|
host: "opencode",
|
|
@@ -75628,7 +75852,7 @@ var codexPluginRoot = (codexHome) => {
|
|
|
75628
75852
|
reason: `${entry.installedVersion ?? "?"} -> ${after ?? "?"}; new sessions load it`
|
|
75629
75853
|
};
|
|
75630
75854
|
}
|
|
75631
|
-
const verify = entry.host === "codex" ?
|
|
75855
|
+
const verify = entry.host === "codex" ? await runAsync("codex", ["plugin", "list", "--json"]) : await runAsync("pi", ["list"]);
|
|
75632
75856
|
if (verify.status !== 0)
|
|
75633
75857
|
return fail("update verification failed");
|
|
75634
75858
|
if (entry.host === "codex") {
|
|
@@ -75646,28 +75870,28 @@ var codexPluginRoot = (codexHome) => {
|
|
|
75646
75870
|
status: "updated",
|
|
75647
75871
|
reason: entry.repair ? `reinstalled missing plugin files (${entry.latest})` : `${entry.installedVersion ?? "?"} -> ${entry.latest}`
|
|
75648
75872
|
};
|
|
75649
|
-
}, refreshCodexAgents = (run, codexHome) => {
|
|
75873
|
+
}, refreshCodexAgents = async (run, codexHome) => {
|
|
75650
75874
|
const root = codexPluginRoot(codexHome);
|
|
75651
75875
|
const launcher = root && path46.join(root, "dist", "launch-mcp.js");
|
|
75652
75876
|
if (!launcher || !existsSync22(launcher))
|
|
75653
75877
|
return { ok: true, note: "" };
|
|
75654
75878
|
const fix = `node ${JSON.stringify(launcher)} --install-agents`;
|
|
75655
|
-
return run("node", [launcher, "--install-agents"]).status === 0 ? { ok: true, note: "agents refreshed" } : { ok: false, note: "agent refresh failed", fix };
|
|
75656
|
-
}, applyCli = (cli, run, backup) => {
|
|
75879
|
+
return (await run("node", [launcher, "--install-agents"])).status === 0 ? { ok: true, note: "agents refreshed" } : { ok: false, note: "agent refresh failed", fix };
|
|
75880
|
+
}, applyCli = async (cli, run, backup) => {
|
|
75657
75881
|
const fail = (reason) => ({
|
|
75658
75882
|
host: "cli",
|
|
75659
75883
|
status: "failed",
|
|
75660
75884
|
reason,
|
|
75661
75885
|
fix: CLI_FIX
|
|
75662
75886
|
});
|
|
75663
|
-
const currentRoot = run("npm", ["root", "--global"]);
|
|
75887
|
+
const currentRoot = await run("npm", ["root", "--global"]);
|
|
75664
75888
|
if (currentRoot.status !== 0 || currentRoot.stdout.trim() !== cli.root)
|
|
75665
75889
|
return fail("Global npm location changed; preview again");
|
|
75666
75890
|
const cliBackup = path46.join(backup, "cli-package");
|
|
75667
75891
|
cpSync5(path46.join(cli.root, "@brainervirus/workit-cli"), cliBackup, {
|
|
75668
75892
|
recursive: true
|
|
75669
75893
|
});
|
|
75670
|
-
if (run("npm", ["install", "--global", `@brainervirus/workit-cli@${cli.latest}`]).status !== 0)
|
|
75894
|
+
if ((await run("npm", ["install", "--global", `@brainervirus/workit-cli@${cli.latest}`])).status !== 0)
|
|
75671
75895
|
return fail(`CLI update failed; preserved package at ${cliBackup}; use npm to repair or run node ${path46.join(cliBackup, "dist/index.js")}`);
|
|
75672
75896
|
const installed = objectOrNull(path46.join(cli.root, "@brainervirus/workit-cli/package.json"));
|
|
75673
75897
|
if (installed?.name !== "@brainervirus/workit-cli" || installed.version !== cli.latest)
|
|
@@ -75683,6 +75907,7 @@ var init_apply = __esm(() => {
|
|
|
75683
75907
|
init_setup_state();
|
|
75684
75908
|
init_setup();
|
|
75685
75909
|
init_safe_write();
|
|
75910
|
+
init_progress();
|
|
75686
75911
|
init_processes();
|
|
75687
75912
|
init_shared();
|
|
75688
75913
|
});
|
|
@@ -76103,9 +76328,13 @@ async function runUpgradeCommand(argv, deps = {}) {
|
|
|
76103
76328
|
const legacy = flags.has("--apply");
|
|
76104
76329
|
const json = flags.has("--json") || legacy;
|
|
76105
76330
|
const run = runner(deps);
|
|
76106
|
-
const
|
|
76107
|
-
|
|
76108
|
-
|
|
76331
|
+
const progress = deps.progress ?? createProgress({ stream: process.stderr, json });
|
|
76332
|
+
const plan = progress.runSync("Planning the upgrade", () => {
|
|
76333
|
+
const planned = previewUpgrade(raw, deps);
|
|
76334
|
+
if (hostFlag === undefined || flags.has("--cli"))
|
|
76335
|
+
planCli(planned, run);
|
|
76336
|
+
return planned;
|
|
76337
|
+
});
|
|
76109
76338
|
plan.ok = plan.blocked.length === 0 && plan.failed.length === 0;
|
|
76110
76339
|
const { home, env } = upgradePaths(deps);
|
|
76111
76340
|
const permissions = planHostPermissions({
|
|
@@ -76156,11 +76385,11 @@ Nothing changed.
|
|
|
76156
76385
|
for (const warning of plan.warnings ?? [])
|
|
76157
76386
|
out.write(`warning: ${warning}
|
|
76158
76387
|
`);
|
|
76159
|
-
const result = applyUpgrade(plan, deps);
|
|
76388
|
+
const result = await applyUpgrade(plan, { ...deps, progress });
|
|
76160
76389
|
let permissionsOk = true;
|
|
76161
76390
|
let written;
|
|
76162
76391
|
if (permissions.changes.length && !permissions.refused && !result.error?.startsWith("configuration changed")) {
|
|
76163
|
-
written = applyHostPermissions(permissions, { home, env });
|
|
76392
|
+
written = progress.runSync("Refreshing the permission block", () => applyHostPermissions(permissions, { home, env }), (entries) => entries.every((entry) => entry.status === "written") ? "done" : "failed");
|
|
76164
76393
|
permissionsOk = written.every((entry) => entry.status === "written");
|
|
76165
76394
|
for (const entry of written)
|
|
76166
76395
|
result.hosts.push({
|
|
@@ -76172,7 +76401,7 @@ Nothing changed.
|
|
|
76172
76401
|
}
|
|
76173
76402
|
const failed = !result.ok || !permissionsOk;
|
|
76174
76403
|
const cliVersion = result.hosts.some((h) => h.host === "cli" && h.status === "updated") ? plan.cli.latest : package_default.version;
|
|
76175
|
-
const report = (deps.doctor ?? ((version) => runDoctor({ home, env, cliVersion: version, only: "upgrade" })))(cliVersion);
|
|
76404
|
+
const report = progress.runSync("Checking the result with workit doctor", () => (deps.doctor ?? ((version) => runDoctor({ home, env, cliVersion: version, only: "upgrade" })))(cliVersion));
|
|
76176
76405
|
const left = report.checks.filter((check) => check.status === "warn" || check.status === "fail");
|
|
76177
76406
|
if (json) {
|
|
76178
76407
|
out.write(JSON.stringify({
|
|
@@ -76230,7 +76459,7 @@ async function runLaunchCommand(argv, deps = {}) {
|
|
|
76230
76459
|
for (const skipped of plan.skipped)
|
|
76231
76460
|
(deps.out ?? process.stderr).write(`${skipped.host}: ${skipped.reason}${skipped.fix ? ` (run: ${skipped.fix})` : ""}
|
|
76232
76461
|
`);
|
|
76233
|
-
const result = applyUpgrade(plan, deps);
|
|
76462
|
+
const result = await applyUpgrade(plan, deps);
|
|
76234
76463
|
if (!result.ok) {
|
|
76235
76464
|
(deps.out ?? process.stdout).write(`${result.error}
|
|
76236
76465
|
`);
|
|
@@ -76259,6 +76488,7 @@ var init_upgrade = __esm(() => {
|
|
|
76259
76488
|
init_host_install();
|
|
76260
76489
|
init_doctor();
|
|
76261
76490
|
init_host_permissions();
|
|
76491
|
+
init_progress();
|
|
76262
76492
|
init_apply();
|
|
76263
76493
|
init_plan();
|
|
76264
76494
|
init_report();
|
|
@@ -76789,7 +77019,7 @@ var init_redact = __esm(() => {
|
|
|
76789
77019
|
});
|
|
76790
77020
|
|
|
76791
77021
|
// packages/workit-core/src/checks.ts
|
|
76792
|
-
import { spawn, spawnSync as spawnSync19 } from "node:child_process";
|
|
77022
|
+
import { spawn as spawn2, spawnSync as spawnSync19 } from "node:child_process";
|
|
76793
77023
|
import { createHash as createHash17 } from "node:crypto";
|
|
76794
77024
|
import fs21 from "node:fs";
|
|
76795
77025
|
import os18 from "node:os";
|
|
@@ -77018,7 +77248,7 @@ function runCheckCommand(argv, options) {
|
|
|
77018
77248
|
shell: plan.shell
|
|
77019
77249
|
};
|
|
77020
77250
|
try {
|
|
77021
|
-
child =
|
|
77251
|
+
child = spawn2(plan.file, plan.args, spawnOptions);
|
|
77022
77252
|
} catch (error) {
|
|
77023
77253
|
finish(null, null, error.code ?? error.message);
|
|
77024
77254
|
return;
|
|
@@ -79036,6 +79266,8 @@ async function prepareHeavy(io, settings, label, runCwd, timeoutMs) {
|
|
|
79036
79266
|
wrapper: null,
|
|
79037
79267
|
env: io.env
|
|
79038
79268
|
};
|
|
79269
|
+
const progress = createProgress({ stream: process.stderr, json: io.json });
|
|
79270
|
+
let waiting = null;
|
|
79039
79271
|
const acquired = await acquireLease({
|
|
79040
79272
|
dir,
|
|
79041
79273
|
slots: settings.slots,
|
|
@@ -79048,11 +79280,20 @@ async function prepareHeavy(io, settings, label, runCwd, timeoutMs) {
|
|
|
79048
79280
|
onStatus: (status) => {
|
|
79049
79281
|
const slots = `${settings.slots} slot${settings.slots === 1 ? "" : "s"}`;
|
|
79050
79282
|
const holders = status.holders.map((holder) => describeHolder(holder)).join("; ");
|
|
79283
|
+
if (progress.mode === "spinner") {
|
|
79284
|
+
const text = `Waiting for the heavy-check lease: held by ${holders || "nobody; waiters ahead"}, queue position ${status.position}`;
|
|
79285
|
+
if (waiting)
|
|
79286
|
+
waiting.label(text);
|
|
79287
|
+
else
|
|
79288
|
+
waiting = progress.start(text);
|
|
79289
|
+
return;
|
|
79290
|
+
}
|
|
79051
79291
|
io.stderr(status.first ? `workit: waiting for the heavy-check lease (${slots}): held by ${holders || "nobody; waiters ahead"}; queued at position ${status.position}, waiting up to ${formatWait(settings.waitMs)} (--wait <dur> sets it)
|
|
79052
79292
|
` : `workit: still queued for the heavy-check lease: position ${status.position}, ${formatWait(status.waitedMs)} of ${formatWait(settings.waitMs)} waited; held by ${holders || "nobody; waiters ahead"}
|
|
79053
79293
|
`);
|
|
79054
79294
|
}
|
|
79055
79295
|
});
|
|
79296
|
+
waiting?.end(acquired.ok ? "done" : "failed");
|
|
79056
79297
|
if (!acquired.ok && acquired.reason === "timeout") {
|
|
79057
79298
|
const holders = acquired.holders.map((holder) => describeHolder(holder)).join("; ");
|
|
79058
79299
|
const waited = formatWait(acquired.waitedMs);
|
|
@@ -79334,6 +79575,7 @@ var init_check = __esm(() => {
|
|
|
79334
79575
|
init_package();
|
|
79335
79576
|
init_ledger();
|
|
79336
79577
|
init_output();
|
|
79578
|
+
init_progress();
|
|
79337
79579
|
init_host_session();
|
|
79338
79580
|
init_resources();
|
|
79339
79581
|
MAX_UNVERIFIED_RUN_MS = 6 * 3600000;
|
|
@@ -87888,6 +88130,11 @@ async function wait2(argv, io) {
|
|
|
87888
88130
|
let verdict = { state: "waiting", reason: "not_polled" };
|
|
87889
88131
|
let baseContexts = null;
|
|
87890
88132
|
let expectedMissing = [];
|
|
88133
|
+
const waiting = createProgress({ stream: process.stderr, json: io.json }).start("Waiting for CI");
|
|
88134
|
+
const abort = (...args) => {
|
|
88135
|
+
waiting.end("failed");
|
|
88136
|
+
return forgeFail(io, ...args);
|
|
88137
|
+
};
|
|
87891
88138
|
for (;; ) {
|
|
87892
88139
|
const read = resolved.forge.prStatus(number.data);
|
|
87893
88140
|
polls += 1;
|
|
@@ -87897,7 +88144,7 @@ async function wait2(argv, io) {
|
|
|
87897
88144
|
status = read.data;
|
|
87898
88145
|
const doc = buildStatusDoc(io.cwd, resolved, status, { logLines: 0, behind: false });
|
|
87899
88146
|
if (!doc.ok)
|
|
87900
|
-
return
|
|
88147
|
+
return abort(doc);
|
|
87901
88148
|
recordPrStatus(io.cwd, doc.data, actor);
|
|
87902
88149
|
if (status.requiredContexts === null && baseContexts === null) {
|
|
87903
88150
|
const base = resolved.forge.branchChecks(status.base);
|
|
@@ -87908,12 +88155,14 @@ async function wait2(argv, io) {
|
|
|
87908
88155
|
verdict = waitVerdict(doc.data, { head, elapsedMs, expectedMissing });
|
|
87909
88156
|
if (verdict.state !== "waiting")
|
|
87910
88157
|
break;
|
|
88158
|
+
const pending = doc.data.checks.pending;
|
|
88159
|
+
waiting.label(`Waiting for CI: ${pending.length} check${pending.length === 1 ? "" : "s"} pending${pending.length ? ` (${pending.slice(0, 3).join(", ")}${pending.length > 3 ? ", …" : ""})` : ""}`);
|
|
87911
88160
|
} else {
|
|
87912
88161
|
errors += 1;
|
|
87913
88162
|
if (read.code !== "unavailable" && read.code !== "failed")
|
|
87914
|
-
return
|
|
88163
|
+
return abort(read);
|
|
87915
88164
|
if (errors >= MAX_POLL_ERRORS)
|
|
87916
|
-
return
|
|
88165
|
+
return abort(read, { polls });
|
|
87917
88166
|
}
|
|
87918
88167
|
const remaining = deadline - forgeDeps.now();
|
|
87919
88168
|
if (remaining <= 0)
|
|
@@ -87921,6 +88170,7 @@ async function wait2(argv, io) {
|
|
|
87921
88170
|
await forgeDeps.sleep(Math.min(pollDelay(intervalMs, polls - 1), remaining));
|
|
87922
88171
|
}
|
|
87923
88172
|
const elapsedMs = forgeDeps.now() - started;
|
|
88173
|
+
waiting.end(verdict.state === "ready" ? "done" : verdict.state === "waiting" ? "skipped" : "failed");
|
|
87924
88174
|
if (!status)
|
|
87925
88175
|
return emit(io, fail2("unavailable", "no successful poll before the timeout", { data: { polls } }));
|
|
87926
88176
|
const left = deadline - forgeDeps.now();
|
|
@@ -88087,6 +88337,7 @@ var init_ci = __esm(() => {
|
|
|
88087
88337
|
init_ledger();
|
|
88088
88338
|
init_autonomy();
|
|
88089
88339
|
init_output();
|
|
88340
|
+
init_progress();
|
|
88090
88341
|
init_forge_common();
|
|
88091
88342
|
});
|
|
88092
88343
|
|
|
@@ -106974,7 +107225,7 @@ var init_audit = __esm(() => {
|
|
|
106974
107225
|
});
|
|
106975
107226
|
|
|
106976
107227
|
// packages/workit-cli/src/test-audit/mutate.ts
|
|
106977
|
-
import { spawn as
|
|
107228
|
+
import { spawn as spawn3 } from "node:child_process";
|
|
106978
107229
|
import {
|
|
106979
107230
|
existsSync as existsSync29,
|
|
106980
107231
|
lstatSync as lstatSync9,
|
|
@@ -107213,7 +107464,7 @@ function copyWorkingTree(repo) {
|
|
|
107213
107464
|
function runCommand(command, cwd, timeoutMs, env) {
|
|
107214
107465
|
const started = performance.now();
|
|
107215
107466
|
return new Promise((resolve) => {
|
|
107216
|
-
const child =
|
|
107467
|
+
const child = spawn3(command, {
|
|
107217
107468
|
cwd,
|
|
107218
107469
|
env,
|
|
107219
107470
|
shell: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-cli",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.41.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
6
6
|
"keywords": [
|
|
@@ -38,13 +38,13 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@babel/parser": "7.29.9",
|
|
41
|
-
"@brainervirus/workit-cursor": "^8.
|
|
41
|
+
"@brainervirus/workit-cursor": "^8.41.0",
|
|
42
42
|
"@inkjs/ui": "2.0.0",
|
|
43
43
|
"ink": "7.1.1",
|
|
44
44
|
"react": "19.2.8"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@brainervirus/workit-core": "^8.
|
|
47
|
+
"@brainervirus/workit-core": "^8.41.0"
|
|
48
48
|
},
|
|
49
49
|
"engines": {
|
|
50
50
|
"node": ">=24"
|