@brainervirus/workit-claude-code 8.38.2 → 8.38.4
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 +1083 -895
- package/package.json +3 -3
package/dist/workit.js
CHANGED
|
@@ -9317,7 +9317,7 @@ var package_default;
|
|
|
9317
9317
|
var init_package = __esm(() => {
|
|
9318
9318
|
package_default = {
|
|
9319
9319
|
name: "@brainervirus/workit-cli",
|
|
9320
|
-
version: "8.38.
|
|
9320
|
+
version: "8.38.4",
|
|
9321
9321
|
private: false,
|
|
9322
9322
|
description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
9323
9323
|
keywords: [
|
|
@@ -9355,13 +9355,13 @@ var init_package = __esm(() => {
|
|
|
9355
9355
|
},
|
|
9356
9356
|
dependencies: {
|
|
9357
9357
|
"@babel/parser": "7.29.9",
|
|
9358
|
-
"@brainervirus/workit-cursor": "^8.38.
|
|
9358
|
+
"@brainervirus/workit-cursor": "^8.38.4",
|
|
9359
9359
|
"@inkjs/ui": "2.0.0",
|
|
9360
9360
|
ink: "7.1.1",
|
|
9361
9361
|
react: "19.2.8"
|
|
9362
9362
|
},
|
|
9363
9363
|
devDependencies: {
|
|
9364
|
-
"@brainervirus/workit-core": "^8.38.
|
|
9364
|
+
"@brainervirus/workit-core": "^8.38.4"
|
|
9365
9365
|
},
|
|
9366
9366
|
engines: {
|
|
9367
9367
|
node: ">=24"
|
|
@@ -16832,6 +16832,79 @@ var init_workers = __esm(() => {
|
|
|
16832
16832
|
UNCERTAIN_WORKER_STATES = ["dispatching", "running", "cancelling", "unknown"];
|
|
16833
16833
|
});
|
|
16834
16834
|
|
|
16835
|
+
// packages/workit-core/src/core/task-delivery.ts
|
|
16836
|
+
import { readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "node:fs";
|
|
16837
|
+
function closeDeliveredTasks(store, now, options = {}) {
|
|
16838
|
+
let closedCount = 0;
|
|
16839
|
+
const index = store.listStoreIndex();
|
|
16840
|
+
if (!index.ok)
|
|
16841
|
+
return 0;
|
|
16842
|
+
const open = index.data.filter((entry) => entry.status !== "closed" && entry.branch !== null);
|
|
16843
|
+
if (open.length === 0)
|
|
16844
|
+
return 0;
|
|
16845
|
+
const file = options.cached ? ledgerPath(store.root) : null;
|
|
16846
|
+
const signature = file?.ok ? `${fileSignature(file.value) ?? "-"}|${open.map((entry) => entry.id).join(",")}` : null;
|
|
16847
|
+
const marker = file?.ok ? `${file.value}.delivery-sweep` : null;
|
|
16848
|
+
if (signature && marker) {
|
|
16849
|
+
try {
|
|
16850
|
+
if (readFileSync6(marker, "utf8") === signature)
|
|
16851
|
+
return 0;
|
|
16852
|
+
} catch {}
|
|
16853
|
+
}
|
|
16854
|
+
const ledger = readLedger(store.root);
|
|
16855
|
+
if (!ledger.ok)
|
|
16856
|
+
return 0;
|
|
16857
|
+
const rows = ledger.value.rows;
|
|
16858
|
+
const after = (row, since) => Date.parse(row.at) >= Date.parse(since);
|
|
16859
|
+
for (const entry of open) {
|
|
16860
|
+
const merged = rows.findLast((row) => row.type === "pr.merged" && row.branch === entry.branch && typeof row.pr === "number" && after(row, entry.createdAt));
|
|
16861
|
+
if (!merged)
|
|
16862
|
+
continue;
|
|
16863
|
+
const pr = merged.pr;
|
|
16864
|
+
const verified = rows.findLast((row) => row.type === "delivery.verified" && row.expect === "merged" && row.branch === entry.branch && (row.pr === undefined || row.pr === pr));
|
|
16865
|
+
if (!verified) {
|
|
16866
|
+
const next = `PR #${pr} is merged but delivery is not verified: run \`workit verify-delivery merged\``;
|
|
16867
|
+
if (entry.progress.nextAction !== next) {
|
|
16868
|
+
store.mutateTask(entry.id, entry.revision, (task, context) => success(context.revision, null, {
|
|
16869
|
+
...task,
|
|
16870
|
+
progress: { ...task.progress, nextAction: next }
|
|
16871
|
+
}));
|
|
16872
|
+
}
|
|
16873
|
+
continue;
|
|
16874
|
+
}
|
|
16875
|
+
const task = store.readTask(entry.id);
|
|
16876
|
+
if (!task.ok || task.data.status === "closed")
|
|
16877
|
+
continue;
|
|
16878
|
+
if (task.data.workers.some((worker) => workerBlocksTransition("close", worker.data.state)))
|
|
16879
|
+
continue;
|
|
16880
|
+
const closed = store.mutateTask(entry.id, task.data.revision, (value, context) => success(context.revision, null, {
|
|
16881
|
+
...value,
|
|
16882
|
+
status: "closed",
|
|
16883
|
+
closure: {
|
|
16884
|
+
outcome: "verified",
|
|
16885
|
+
at: context.now,
|
|
16886
|
+
summary: `delivered: PR #${pr} merged (pr.merged ${String(merged.id)}) and delivery verified (delivery.verified ${String(verified.id)})`,
|
|
16887
|
+
decisionIds: [],
|
|
16888
|
+
evidenceIds: []
|
|
16889
|
+
}
|
|
16890
|
+
}), now);
|
|
16891
|
+
if (closed.ok)
|
|
16892
|
+
closedCount++;
|
|
16893
|
+
}
|
|
16894
|
+
if (signature && marker && closedCount === 0 && !racySignature(signature.split("|")[0] ?? "")) {
|
|
16895
|
+
try {
|
|
16896
|
+
writeFileSync4(marker, signature);
|
|
16897
|
+
} catch {}
|
|
16898
|
+
}
|
|
16899
|
+
return closedCount;
|
|
16900
|
+
}
|
|
16901
|
+
var init_task_delivery = __esm(() => {
|
|
16902
|
+
init_ledger();
|
|
16903
|
+
init_task_store();
|
|
16904
|
+
init_task_contract();
|
|
16905
|
+
init_workers();
|
|
16906
|
+
});
|
|
16907
|
+
|
|
16835
16908
|
// packages/workit-core/src/core/task-evaluation.ts
|
|
16836
16909
|
import { createHash as createHash11 } from "node:crypto";
|
|
16837
16910
|
import * as fs14 from "node:fs";
|
|
@@ -18804,10 +18877,10 @@ var init_route_intent = __esm(() => {
|
|
|
18804
18877
|
|
|
18805
18878
|
// packages/workit-core/src/core/runtime-identity.ts
|
|
18806
18879
|
import { createHash as createHash12 } from "node:crypto";
|
|
18807
|
-
import { readFileSync as
|
|
18880
|
+
import { readFileSync as readFileSync8 } from "node:fs";
|
|
18808
18881
|
var sha256Hex = (bytes) => createHash12("sha256").update(bytes).digest("hex"), bundleHashOfFile = (file) => {
|
|
18809
18882
|
try {
|
|
18810
|
-
return sha256Hex(
|
|
18883
|
+
return sha256Hex(readFileSync8(file));
|
|
18811
18884
|
} catch {
|
|
18812
18885
|
return null;
|
|
18813
18886
|
}
|
|
@@ -21199,7 +21272,7 @@ var init_core3 = __esm(() => {
|
|
|
21199
21272
|
});
|
|
21200
21273
|
|
|
21201
21274
|
// packages/workit-cli/src/task.ts
|
|
21202
|
-
import { readFileSync as
|
|
21275
|
+
import { readFileSync as readFileSync9 } from "node:fs";
|
|
21203
21276
|
import path27 from "node:path";
|
|
21204
21277
|
async function readInput(input) {
|
|
21205
21278
|
if (typeof input === "string")
|
|
@@ -21216,7 +21289,7 @@ async function payloadValue(raw, deps) {
|
|
|
21216
21289
|
return { ok: true, value: {} };
|
|
21217
21290
|
let source;
|
|
21218
21291
|
try {
|
|
21219
|
-
source = raw === "-" ? await readInput(deps.stdin ?? process.stdin) : raw.startsWith("@") ? decodeUtf8(
|
|
21292
|
+
source = raw === "-" ? await readInput(deps.stdin ?? process.stdin) : raw.startsWith("@") ? decodeUtf8(readFileSync9(raw.slice(1))) : raw;
|
|
21220
21293
|
} catch (error) {
|
|
21221
21294
|
return {
|
|
21222
21295
|
ok: false,
|
|
@@ -21504,7 +21577,12 @@ async function runTaskCommand(argv, deps = {}) {
|
|
|
21504
21577
|
return parsed.usage ? 2 : 1;
|
|
21505
21578
|
}
|
|
21506
21579
|
const root = workspaceRootFor(deps);
|
|
21507
|
-
const
|
|
21580
|
+
const store = new TaskStore(root);
|
|
21581
|
+
try {
|
|
21582
|
+
const now = new Date().toISOString().replace(/\.\d{3}Z$/, "Z");
|
|
21583
|
+
closeDeliveredTasks(store, now, { cached: parsed.parsed.action !== "list" });
|
|
21584
|
+
} catch {}
|
|
21585
|
+
const core = new WorkitCore(store, contextFor(root, parsed.parsed.actor !== undefined ? { ...deps, actor: parsed.parsed.actor } : deps));
|
|
21508
21586
|
let result;
|
|
21509
21587
|
if (parsed.parsed.handoff) {
|
|
21510
21588
|
const exported = dispatch(core, "state", parsed.parsed.request);
|
|
@@ -21600,6 +21678,7 @@ var init_task = __esm(() => {
|
|
|
21600
21678
|
init_current_judgment();
|
|
21601
21679
|
init_judgment();
|
|
21602
21680
|
init_lane();
|
|
21681
|
+
init_task_delivery();
|
|
21603
21682
|
init_task_store();
|
|
21604
21683
|
init_core3();
|
|
21605
21684
|
init_task_contract();
|
|
@@ -65285,13 +65364,13 @@ var init_changelog = __esm(() => {
|
|
|
65285
65364
|
|
|
65286
65365
|
// packages/workit-core/src/core/hygiene.ts
|
|
65287
65366
|
import { spawnSync as spawnSync12 } from "node:child_process";
|
|
65288
|
-
import { existsSync as existsSync10, readFileSync as
|
|
65367
|
+
import { existsSync as existsSync10, readFileSync as readFileSync11, readdirSync as readdirSync5, writeFileSync as writeFileSync5 } from "node:fs";
|
|
65289
65368
|
import path29 from "node:path";
|
|
65290
65369
|
var repoRoot2, templatesDir = () => path29.join(repoRoot2, "templates", "hygiene"), packageJson = (root) => {
|
|
65291
65370
|
if (!existsSync10(path29.join(root, "package.json")))
|
|
65292
65371
|
return null;
|
|
65293
65372
|
try {
|
|
65294
|
-
return JSON.parse(
|
|
65373
|
+
return JSON.parse(readFileSync11(path29.join(root, "package.json"), "utf8"));
|
|
65295
65374
|
} catch {
|
|
65296
65375
|
return null;
|
|
65297
65376
|
}
|
|
@@ -65344,7 +65423,7 @@ var repoRoot2, templatesDir = () => path29.join(repoRoot2, "templates", "hygiene
|
|
|
65344
65423
|
const tpl = path29.join(templatesDir(), file);
|
|
65345
65424
|
if (!existsSync10(tpl))
|
|
65346
65425
|
continue;
|
|
65347
|
-
const content =
|
|
65426
|
+
const content = readFileSync11(tpl, "utf8").replace(/<PROJECT>/g, path29.basename(root)).replace(/<YEAR>/g, String(new Date().getFullYear())).replace(/<HOLDER>\s*/g, licenseHolder(root));
|
|
65348
65427
|
planned.push({ path: path29.join(root, file), content });
|
|
65349
65428
|
}
|
|
65350
65429
|
return planned;
|
|
@@ -65356,13 +65435,13 @@ var init_hygiene = __esm(() => {
|
|
|
65356
65435
|
});
|
|
65357
65436
|
|
|
65358
65437
|
// packages/workit-cli/src/admin/setup-state.ts
|
|
65359
|
-
import { existsSync as existsSync11, readFileSync as
|
|
65438
|
+
import { existsSync as existsSync11, readFileSync as readFileSync12 } from "node:fs";
|
|
65360
65439
|
import path30 from "node:path";
|
|
65361
65440
|
var classifySetupFile = (dir, name) => {
|
|
65362
65441
|
const file = path30.join(dir, name);
|
|
65363
65442
|
let raw;
|
|
65364
65443
|
try {
|
|
65365
|
-
raw =
|
|
65444
|
+
raw = readFileSync12(file, "utf8");
|
|
65366
65445
|
} catch {
|
|
65367
65446
|
if (existsSync11(file)) {
|
|
65368
65447
|
return { file, status: "malformed", error: `${file} is not readable` };
|
|
@@ -65803,7 +65882,7 @@ import {
|
|
|
65803
65882
|
accessSync,
|
|
65804
65883
|
constants as constants2,
|
|
65805
65884
|
existsSync as existsSync12,
|
|
65806
|
-
readFileSync as
|
|
65885
|
+
readFileSync as readFileSync13,
|
|
65807
65886
|
readdirSync as readdirSync6,
|
|
65808
65887
|
realpathSync as realpathSync6,
|
|
65809
65888
|
statSync as statSync2
|
|
@@ -66093,7 +66172,7 @@ function runHostCommand(step, context = {}) {
|
|
|
66093
66172
|
}
|
|
66094
66173
|
var resolveWindowsShimScript = (shim) => {
|
|
66095
66174
|
try {
|
|
66096
|
-
const contents =
|
|
66175
|
+
const contents = readFileSync13(shim, "utf8");
|
|
66097
66176
|
return resolveWindowsShimEntry(contents, shim);
|
|
66098
66177
|
} catch {
|
|
66099
66178
|
return null;
|
|
@@ -66114,7 +66193,7 @@ var resolveWindowsShimScript = (shim) => {
|
|
|
66114
66193
|
}, isPiWorkitInstalled = (home, env = process.env) => {
|
|
66115
66194
|
const settings = path33.join(env.PI_CODING_AGENT_DIR ?? path33.join(home, ".pi", "agent"), "settings.json");
|
|
66116
66195
|
try {
|
|
66117
|
-
const document2 = JSON.parse(
|
|
66196
|
+
const document2 = JSON.parse(readFileSync13(settings, "utf8"));
|
|
66118
66197
|
return (document2.packages ?? []).some((entry) => {
|
|
66119
66198
|
const source = entry && typeof entry === "object" && !Array.isArray(entry) ? entry.source : entry;
|
|
66120
66199
|
const value = String(source).replaceAll("\\", "/").replace(/\/+$/, "");
|
|
@@ -66125,7 +66204,7 @@ var resolveWindowsShimScript = (shim) => {
|
|
|
66125
66204
|
}
|
|
66126
66205
|
}, OPENCODE_PLUGIN_SCOPE = "@brainervirus", OPENCODE_PLUGIN_NAME = "workit-opencode", packageVersionAt = (root, name) => {
|
|
66127
66206
|
try {
|
|
66128
|
-
const pkg = JSON.parse(
|
|
66207
|
+
const pkg = JSON.parse(readFileSync13(path33.join(root, "package.json"), "utf8"));
|
|
66129
66208
|
return pkg.name === name && typeof pkg.version === "string" ? pkg.version : null;
|
|
66130
66209
|
} catch {
|
|
66131
66210
|
return null;
|
|
@@ -66163,7 +66242,7 @@ var resolveWindowsShimScript = (shim) => {
|
|
|
66163
66242
|
path33.join(root, "package.json")
|
|
66164
66243
|
]) {
|
|
66165
66244
|
try {
|
|
66166
|
-
const manifest = JSON.parse(
|
|
66245
|
+
const manifest = JSON.parse(readFileSync13(file, "utf8"));
|
|
66167
66246
|
const repository = typeof manifest.repository === "string" ? manifest.repository : manifest.repository?.url;
|
|
66168
66247
|
if ((manifest.name === "workit" || manifest.name === "@brainervirus/workit-codex") && repository?.replace(/\.git$/, "").toLowerCase() === "https://github.com/brainervirus/workit")
|
|
66169
66248
|
return true;
|
|
@@ -66204,7 +66283,7 @@ var resolveWindowsShimScript = (shim) => {
|
|
|
66204
66283
|
return relative === "" || !relative.startsWith("..") && !path33.isAbsolute(relative);
|
|
66205
66284
|
}, isCanonicalClaudePlugin = (root) => {
|
|
66206
66285
|
try {
|
|
66207
|
-
const manifest = JSON.parse(
|
|
66286
|
+
const manifest = JSON.parse(readFileSync13(path33.join(root, ".claude-plugin", "plugin.json"), "utf8"));
|
|
66208
66287
|
const repository = typeof manifest.repository === "string" ? manifest.repository : manifest.repository?.url;
|
|
66209
66288
|
return manifest.name === "workit" && repository?.replace(/\.git$/, "").toLowerCase() === "https://github.com/brainervirus/workit";
|
|
66210
66289
|
} catch {
|
|
@@ -66214,7 +66293,7 @@ var resolveWindowsShimScript = (shim) => {
|
|
|
66214
66293
|
const file = path33.join(claudeConfigDir(home, env), "plugins", "installed_plugins.json");
|
|
66215
66294
|
let registry;
|
|
66216
66295
|
try {
|
|
66217
|
-
registry = JSON.parse(
|
|
66296
|
+
registry = JSON.parse(readFileSync13(file, "utf8"));
|
|
66218
66297
|
} catch {
|
|
66219
66298
|
return [];
|
|
66220
66299
|
}
|
|
@@ -66263,7 +66342,7 @@ var init_host_install = __esm(() => {
|
|
|
66263
66342
|
});
|
|
66264
66343
|
|
|
66265
66344
|
// packages/workit-core/src/core/skill-manifests.ts
|
|
66266
|
-
import { cpSync as cpSync3, existsSync as existsSync13, readFileSync as
|
|
66345
|
+
import { cpSync as cpSync3, existsSync as existsSync13, readFileSync as readFileSync14, readdirSync as readdirSync7, statSync as statSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
66267
66346
|
import path34 from "node:path";
|
|
66268
66347
|
var WORKIT_METHOD_SKILLS, skillManifestNames = (root) => existsSync13(root) ? readdirSync7(root).filter((name) => existsSync13(path34.join(root, name, "SKILL.md"))).toSorted() : [], validateSkillManifests = (root, expected, label) => {
|
|
66269
66348
|
const actual = skillManifestNames(root);
|
|
@@ -66281,7 +66360,7 @@ var WORKIT_METHOD_SKILLS, skillManifestNames = (root) => existsSync13(root) ? re
|
|
|
66281
66360
|
const file = path34.join(dir, entry.name);
|
|
66282
66361
|
if (entry.isDirectory())
|
|
66283
66362
|
pending.push(file);
|
|
66284
|
-
else if ((statSync3(file).mode & 73) !== 0 ||
|
|
66363
|
+
else if ((statSync3(file).mode & 73) !== 0 || readFileSync14(file).subarray(0, 2).toString("latin1") === "#!") {
|
|
66285
66364
|
return `Cursor vendor contains active file: ${file}`;
|
|
66286
66365
|
}
|
|
66287
66366
|
}
|
|
@@ -66314,11 +66393,11 @@ import {
|
|
|
66314
66393
|
existsSync as existsSync14,
|
|
66315
66394
|
lstatSync as lstatSync4,
|
|
66316
66395
|
mkdirSync as mkdirSync5,
|
|
66317
|
-
readFileSync as
|
|
66396
|
+
readFileSync as readFileSync15,
|
|
66318
66397
|
renameSync as renameSync3,
|
|
66319
66398
|
rmSync as rmSync2,
|
|
66320
66399
|
statSync as statSync4,
|
|
66321
|
-
writeFileSync as
|
|
66400
|
+
writeFileSync as writeFileSync7
|
|
66322
66401
|
} from "node:fs";
|
|
66323
66402
|
import path35 from "node:path";
|
|
66324
66403
|
function inspectSessionHook(cwd, env = process.env) {
|
|
@@ -66517,7 +66596,7 @@ exit 0
|
|
|
66517
66596
|
return rel === "" || !rel.startsWith("..") && !path35.isAbsolute(rel);
|
|
66518
66597
|
}, readText3 = (file) => {
|
|
66519
66598
|
try {
|
|
66520
|
-
return
|
|
66599
|
+
return readFileSync15(file, "utf8");
|
|
66521
66600
|
} catch {
|
|
66522
66601
|
return null;
|
|
66523
66602
|
}
|
|
@@ -66621,7 +66700,7 @@ exit 0
|
|
|
66621
66700
|
mkdirSync5(path35.dirname(file), { recursive: true });
|
|
66622
66701
|
const staged = `${file}.workit-new`;
|
|
66623
66702
|
try {
|
|
66624
|
-
|
|
66703
|
+
writeFileSync7(staged, content, { mode: 493 });
|
|
66625
66704
|
chmodSync(staged, 493);
|
|
66626
66705
|
renameSync3(staged, file);
|
|
66627
66706
|
} finally {
|
|
@@ -66684,7 +66763,7 @@ var init_heavy_words = __esm(() => {
|
|
|
66684
66763
|
});
|
|
66685
66764
|
|
|
66686
66765
|
// packages/workit-core/src/hooks/hook-runs.ts
|
|
66687
|
-
import { mkdirSync as mkdirSync6, readdirSync as readdirSync8, readFileSync as
|
|
66766
|
+
import { mkdirSync as mkdirSync6, readdirSync as readdirSync8, readFileSync as readFileSync16, writeFileSync as writeFileSync8 } from "node:fs";
|
|
66688
66767
|
import path37 from "node:path";
|
|
66689
66768
|
var HOOK_RUNS_DIR = "hook-runs", readHookRuns = (dir) => {
|
|
66690
66769
|
const runs = [];
|
|
@@ -66696,7 +66775,7 @@ var HOOK_RUNS_DIR = "hook-runs", readHookRuns = (dir) => {
|
|
|
66696
66775
|
}
|
|
66697
66776
|
for (const name of names) {
|
|
66698
66777
|
try {
|
|
66699
|
-
const row = JSON.parse(
|
|
66778
|
+
const row = JSON.parse(readFileSync16(path37.join(dir, HOOK_RUNS_DIR, name), "utf8"));
|
|
66700
66779
|
if (typeof row.host === "string" && typeof row.event === "string" && typeof row.at === "string" && typeof row.count === "number")
|
|
66701
66780
|
runs.push({
|
|
66702
66781
|
host: row.host,
|
|
@@ -66742,7 +66821,7 @@ import {
|
|
|
66742
66821
|
existsSync as existsSync15,
|
|
66743
66822
|
readdirSync as readdirSync9,
|
|
66744
66823
|
mkdirSync as mkdirSync7,
|
|
66745
|
-
readFileSync as
|
|
66824
|
+
readFileSync as readFileSync17,
|
|
66746
66825
|
realpathSync as realpathSync7,
|
|
66747
66826
|
rmSync as rmSync3,
|
|
66748
66827
|
statSync as statSync5
|
|
@@ -67170,7 +67249,7 @@ ${[...rules, ...lease, grant].join(`
|
|
|
67170
67249
|
}, AGENT_SESSION_VARS, agentSessionVar = (env) => AGENT_SESSION_VARS.find((name) => (env[name] ?? "") !== "") ?? null, RECORD_FILE = "host-permissions.json", readOwnership = (options = {}) => {
|
|
67171
67250
|
const { stateDir } = resolvePaths(options);
|
|
67172
67251
|
try {
|
|
67173
|
-
const value = JSON.parse(
|
|
67252
|
+
const value = JSON.parse(readFileSync17(path38.join(stateDir, RECORD_FILE), "utf8"));
|
|
67174
67253
|
if (isRecord5(value) && isRecord5(value.hosts))
|
|
67175
67254
|
return { version: 1, hosts: value.hosts };
|
|
67176
67255
|
} catch {}
|
|
@@ -67199,7 +67278,7 @@ ${[...rules, ...lease, grant].join(`
|
|
|
67199
67278
|
writeOwnership(record, paths.stateDir);
|
|
67200
67279
|
}, readText4 = (file) => {
|
|
67201
67280
|
try {
|
|
67202
|
-
return
|
|
67281
|
+
return readFileSync17(file, "utf8");
|
|
67203
67282
|
} catch {
|
|
67204
67283
|
return null;
|
|
67205
67284
|
}
|
|
@@ -67361,13 +67440,13 @@ import {
|
|
|
67361
67440
|
mkdirSync as mkdirSync8,
|
|
67362
67441
|
mkdtempSync,
|
|
67363
67442
|
readdirSync as readdirSync10,
|
|
67364
|
-
readFileSync as
|
|
67443
|
+
readFileSync as readFileSync18,
|
|
67365
67444
|
readlinkSync as readlinkSync2,
|
|
67366
67445
|
renameSync as renameSync4,
|
|
67367
67446
|
rmSync as rmSync4,
|
|
67368
67447
|
statSync as statSync6,
|
|
67369
67448
|
unlinkSync as unlinkSync3,
|
|
67370
|
-
writeFileSync as
|
|
67449
|
+
writeFileSync as writeFileSync9
|
|
67371
67450
|
} from "node:fs";
|
|
67372
67451
|
import os12 from "node:os";
|
|
67373
67452
|
import path39 from "node:path";
|
|
@@ -67431,14 +67510,14 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
67431
67510
|
};
|
|
67432
67511
|
}, readJson = (p) => {
|
|
67433
67512
|
try {
|
|
67434
|
-
const parsed = JSON.parse(
|
|
67513
|
+
const parsed = JSON.parse(readFileSync18(p, "utf8"));
|
|
67435
67514
|
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
67436
67515
|
} catch {
|
|
67437
67516
|
return null;
|
|
67438
67517
|
}
|
|
67439
67518
|
}, parsesAsConfigObject = (p) => {
|
|
67440
67519
|
try {
|
|
67441
|
-
return isConfigObject(JSON.parse(
|
|
67520
|
+
return isConfigObject(JSON.parse(readFileSync18(p, "utf8")));
|
|
67442
67521
|
} catch {
|
|
67443
67522
|
return false;
|
|
67444
67523
|
}
|
|
@@ -67661,7 +67740,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
67661
67740
|
const tables = new Map;
|
|
67662
67741
|
let text;
|
|
67663
67742
|
try {
|
|
67664
|
-
text =
|
|
67743
|
+
text = readFileSync18(file, "utf8");
|
|
67665
67744
|
} catch {
|
|
67666
67745
|
return tables;
|
|
67667
67746
|
}
|
|
@@ -67832,7 +67911,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
67832
67911
|
let stale = false;
|
|
67833
67912
|
for (const file of files) {
|
|
67834
67913
|
const dest = path39.join(agentsDir, file);
|
|
67835
|
-
const want = stampCodexAgent(
|
|
67914
|
+
const want = stampCodexAgent(readFileSync18(path39.join(source, file), "utf8"), version);
|
|
67836
67915
|
let link = false;
|
|
67837
67916
|
try {
|
|
67838
67917
|
link = lstatSync5(dest).isSymbolicLink();
|
|
@@ -67846,7 +67925,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
67846
67925
|
}
|
|
67847
67926
|
let have = null;
|
|
67848
67927
|
try {
|
|
67849
|
-
have =
|
|
67928
|
+
have = readFileSync18(dest, "utf8");
|
|
67850
67929
|
} catch {
|
|
67851
67930
|
have = null;
|
|
67852
67931
|
}
|
|
@@ -68095,7 +68174,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68095
68174
|
}, validNodeEntry = (entry, runtime, env) => {
|
|
68096
68175
|
try {
|
|
68097
68176
|
const stat = statSync6(entry);
|
|
68098
|
-
if (!stat.isFile() || stat.size === 0 || !
|
|
68177
|
+
if (!stat.isFile() || stat.size === 0 || !readFileSync18(entry, "utf8").startsWith(`#!/usr/bin/env node
|
|
68099
68178
|
`)) {
|
|
68100
68179
|
return false;
|
|
68101
68180
|
}
|
|
@@ -68951,7 +69030,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68951
69030
|
return { ...installSessionHook(res.cwd, res.env), workspace: workspace.name };
|
|
68952
69031
|
}, isPlaceholder = (p) => {
|
|
68953
69032
|
try {
|
|
68954
|
-
return
|
|
69033
|
+
return readFileSync18(p, "utf8").trim() === TOKEN_PLACEHOLDER2;
|
|
68955
69034
|
} catch {
|
|
68956
69035
|
return false;
|
|
68957
69036
|
}
|
|
@@ -69165,7 +69244,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69165
69244
|
const probe = path39.join(logsDir, "doctor-probe.tmp");
|
|
69166
69245
|
try {
|
|
69167
69246
|
mkdirSync8(logsDir, { recursive: true, mode: 448 });
|
|
69168
|
-
|
|
69247
|
+
writeFileSync9(probe, `{"probe":true}
|
|
69169
69248
|
`, { mode: 384 });
|
|
69170
69249
|
return {
|
|
69171
69250
|
id: "log_writable",
|
|
@@ -69244,7 +69323,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69244
69323
|
const counts = { skip: 0, late: 0 };
|
|
69245
69324
|
let text = "";
|
|
69246
69325
|
try {
|
|
69247
|
-
text =
|
|
69326
|
+
text = readFileSync18(path39.join(stateDir, HOOK_SKIPS_FILE), "utf8");
|
|
69248
69327
|
} catch {
|
|
69249
69328
|
return counts;
|
|
69250
69329
|
}
|
|
@@ -69435,7 +69514,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69435
69514
|
return null;
|
|
69436
69515
|
return files.some((file) => {
|
|
69437
69516
|
try {
|
|
69438
|
-
return
|
|
69517
|
+
return readFileSync18(path39.join(root, "dist", file), "utf8").includes(HOOK_ISSUED_MARKER);
|
|
69439
69518
|
} catch {
|
|
69440
69519
|
return false;
|
|
69441
69520
|
}
|
|
@@ -69779,13 +69858,13 @@ import {
|
|
|
69779
69858
|
lstatSync as lstatSync6,
|
|
69780
69859
|
mkdirSync as mkdirSync9,
|
|
69781
69860
|
mkdtempSync as mkdtempSync2,
|
|
69782
|
-
readFileSync as
|
|
69861
|
+
readFileSync as readFileSync19,
|
|
69783
69862
|
readdirSync as readdirSync11,
|
|
69784
69863
|
realpathSync as realpathSync8,
|
|
69785
69864
|
renameSync as renameSync5,
|
|
69786
69865
|
rmSync as rmSync5,
|
|
69787
69866
|
statSync as statSync7,
|
|
69788
|
-
writeFileSync as
|
|
69867
|
+
writeFileSync as writeFileSync10
|
|
69789
69868
|
} from "node:fs";
|
|
69790
69869
|
import { createRequire as createRequire2 } from "node:module";
|
|
69791
69870
|
import os13 from "node:os";
|
|
@@ -69953,7 +70032,7 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
69953
70032
|
if (target?.ok) {
|
|
69954
70033
|
const root = target.root;
|
|
69955
70034
|
const gitignorePath = path40.join(root, ".gitignore");
|
|
69956
|
-
const existing = existsSync17(gitignorePath) ?
|
|
70035
|
+
const existing = existsSync17(gitignorePath) ? readFileSync19(gitignorePath, "utf8") : "";
|
|
69957
70036
|
const existingLines = new Set(existing.split(`
|
|
69958
70037
|
`).map((l) => l.trim()).filter(Boolean));
|
|
69959
70038
|
const entries = GITIGNORE_ENTRIES.filter((e) => e.trim() !== "" && !existingLines.has(e.trim()));
|
|
@@ -70017,7 +70096,7 @@ function applyMutation(m) {
|
|
|
70017
70096
|
return { platform: "core", file: m.path, status: "Skipped", detail: "already configured" };
|
|
70018
70097
|
}
|
|
70019
70098
|
mkdirSync9(dir, { recursive: true });
|
|
70020
|
-
|
|
70099
|
+
writeFileSync10(m.path, JSON.stringify(merged, null, 2) + `
|
|
70021
70100
|
`, "utf8");
|
|
70022
70101
|
return existing.kind === "record" ? { platform: "core", file: m.path, status: "Configured" } : { platform: "core", file: m.path, status: "Installed" };
|
|
70023
70102
|
}
|
|
@@ -70061,7 +70140,7 @@ function applyMutation(m) {
|
|
|
70061
70140
|
mkdirSync9(dir, { recursive: true });
|
|
70062
70141
|
const tmp = `${m.path}.${process.pid}.tmp`;
|
|
70063
70142
|
try {
|
|
70064
|
-
|
|
70143
|
+
writeFileSync10(tmp, next, "utf8");
|
|
70065
70144
|
if (workspacesRevision(readFileSafe(m.path)) !== m.expectedRevision) {
|
|
70066
70145
|
rmSync5(tmp, { force: true });
|
|
70067
70146
|
return {
|
|
@@ -70100,7 +70179,7 @@ function applyMutation(m) {
|
|
|
70100
70179
|
const separator = existing && !existing.endsWith(`
|
|
70101
70180
|
`) ? `
|
|
70102
70181
|
` : "";
|
|
70103
|
-
|
|
70182
|
+
writeFileSync10(m.path, existing + separator + (existing ? `
|
|
70104
70183
|
` : "") + add.join(`
|
|
70105
70184
|
`) + `
|
|
70106
70185
|
`, "utf8");
|
|
@@ -70140,7 +70219,7 @@ function applyMutation(m) {
|
|
|
70140
70219
|
};
|
|
70141
70220
|
}
|
|
70142
70221
|
mkdirSync9(path40.dirname(m.path), { recursive: true });
|
|
70143
|
-
|
|
70222
|
+
writeFileSync10(m.path, JSON.stringify(merged, null, 2) + `
|
|
70144
70223
|
`, "utf8");
|
|
70145
70224
|
return existing.kind === "record" ? { platform: "core", file: m.path, status: "Configured" } : { platform: "core", file: m.path, status: "Installed" };
|
|
70146
70225
|
}
|
|
@@ -70212,7 +70291,7 @@ function applyOpenCode(root, res) {
|
|
|
70212
70291
|
detail: "already registered"
|
|
70213
70292
|
};
|
|
70214
70293
|
}
|
|
70215
|
-
|
|
70294
|
+
writeFileSync10(res.opencodeConfig, JSON.stringify(merged.config, null, 2) + `
|
|
70216
70295
|
`, "utf8");
|
|
70217
70296
|
return existing.kind === "record" ? {
|
|
70218
70297
|
platform: "opencode",
|
|
@@ -70247,12 +70326,12 @@ function copyPluginDir(src, dest) {
|
|
|
70247
70326
|
});
|
|
70248
70327
|
const stagedHooks = path40.join(stage, CURSOR_HOOKS_FILE);
|
|
70249
70328
|
if (existsSync17(stagedHooks))
|
|
70250
|
-
|
|
70329
|
+
writeFileSync10(stagedHooks, localizedCursorHooks(readFileSync19(stagedHooks), dest));
|
|
70251
70330
|
for (const [name, content] of rules) {
|
|
70252
70331
|
mkdirSync9(path40.join(stage, "rules"), { recursive: true });
|
|
70253
|
-
|
|
70332
|
+
writeFileSync10(path40.join(stage, "rules", name), content);
|
|
70254
70333
|
}
|
|
70255
|
-
|
|
70334
|
+
writeFileSync10(path40.join(stage, ".workit-root"), realSrc + `
|
|
70256
70335
|
`, "utf8");
|
|
70257
70336
|
if (!samePluginContent(realSrc, stage, dest))
|
|
70258
70337
|
throw new Error("staged adapter content is incomplete");
|
|
@@ -70294,7 +70373,7 @@ function applyCursorSettings(root, res) {
|
|
|
70294
70373
|
detail: "already registered"
|
|
70295
70374
|
};
|
|
70296
70375
|
}
|
|
70297
|
-
|
|
70376
|
+
writeFileSync10(res.cursorSettings, JSON.stringify(settings.config, null, 2) + `
|
|
70298
70377
|
`, "utf8");
|
|
70299
70378
|
return {
|
|
70300
70379
|
platform: "cursor",
|
|
@@ -70333,7 +70412,7 @@ function applyCursorMcp(root, res) {
|
|
|
70333
70412
|
detail: "already registered"
|
|
70334
70413
|
};
|
|
70335
70414
|
}
|
|
70336
|
-
|
|
70415
|
+
writeFileSync10(res.cursorMcp, JSON.stringify(mcp.config, null, 2) + `
|
|
70337
70416
|
`, "utf8");
|
|
70338
70417
|
return {
|
|
70339
70418
|
platform: "cursor",
|
|
@@ -70602,7 +70681,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
70602
70681
|
return configured ?? fallback;
|
|
70603
70682
|
}, readConfigRecord = (file) => {
|
|
70604
70683
|
try {
|
|
70605
|
-
const value = JSON.parse(
|
|
70684
|
+
const value = JSON.parse(readFileSync19(file, "utf8"));
|
|
70606
70685
|
return isRecord6(value) ? value : null;
|
|
70607
70686
|
} catch {
|
|
70608
70687
|
return null;
|
|
@@ -70623,7 +70702,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
70623
70702
|
}, isRecord6 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), readExisting = (p) => {
|
|
70624
70703
|
let raw;
|
|
70625
70704
|
try {
|
|
70626
|
-
raw =
|
|
70705
|
+
raw = readFileSync19(p, "utf8");
|
|
70627
70706
|
} catch {
|
|
70628
70707
|
if (existsSync17(p))
|
|
70629
70708
|
return { kind: "malformed", error: `${p} is not readable` };
|
|
@@ -70640,7 +70719,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
70640
70719
|
return { kind: "malformed", error: `${p} is not a JSON object` };
|
|
70641
70720
|
}, readFileSafe = (p) => {
|
|
70642
70721
|
try {
|
|
70643
|
-
return
|
|
70722
|
+
return readFileSync19(p, "utf8");
|
|
70644
70723
|
} catch {
|
|
70645
70724
|
return null;
|
|
70646
70725
|
}
|
|
@@ -70655,7 +70734,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
70655
70734
|
}
|
|
70656
70735
|
}, isAdapter = (root, platform) => {
|
|
70657
70736
|
try {
|
|
70658
|
-
const pkg = JSON.parse(
|
|
70737
|
+
const pkg = JSON.parse(readFileSync19(path40.join(root, "package.json"), "utf8"));
|
|
70659
70738
|
return pkg.name === `@brainervirus/workit-${platform}`;
|
|
70660
70739
|
} catch {
|
|
70661
70740
|
return false;
|
|
@@ -70704,8 +70783,8 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
70704
70783
|
if (!statSync7(installed).isDirectory() || !samePluginContent(source, installed, pluginDir, rel))
|
|
70705
70784
|
return false;
|
|
70706
70785
|
} else {
|
|
70707
|
-
const expected = rel === CURSOR_HOOKS_FILE ? localizedCursorHooks(
|
|
70708
|
-
if (!expected.equals(
|
|
70786
|
+
const expected = rel === CURSOR_HOOKS_FILE ? localizedCursorHooks(readFileSync19(source), pluginDir) : readFileSync19(source);
|
|
70787
|
+
if (!expected.equals(readFileSync19(installed)))
|
|
70709
70788
|
return false;
|
|
70710
70789
|
}
|
|
70711
70790
|
}
|
|
@@ -70733,7 +70812,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
70733
70812
|
continue;
|
|
70734
70813
|
if (existsSync17(path40.join(sourceRules, entry.name)))
|
|
70735
70814
|
continue;
|
|
70736
|
-
preserved.set(entry.name,
|
|
70815
|
+
preserved.set(entry.name, readFileSync19(path40.join(installedRules, entry.name)));
|
|
70737
70816
|
}
|
|
70738
70817
|
} catch {}
|
|
70739
70818
|
return preserved;
|
|
@@ -70788,7 +70867,7 @@ var init_setup = __esm(() => {
|
|
|
70788
70867
|
});
|
|
70789
70868
|
|
|
70790
70869
|
// packages/workit-core/src/core/workspace-branch-policy.ts
|
|
70791
|
-
import { mkdirSync as mkdirSync10, readFileSync as
|
|
70870
|
+
import { mkdirSync as mkdirSync10, readFileSync as readFileSync20, renameSync as renameSync6, rmSync as rmSync6, writeFileSync as writeFileSync11 } from "node:fs";
|
|
70792
70871
|
import path41 from "node:path";
|
|
70793
70872
|
import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
|
|
70794
70873
|
function applyWorkspaceBranchPolicy(opts) {
|
|
@@ -70857,7 +70936,7 @@ function applyWorkspaceBranchPolicy(opts) {
|
|
|
70857
70936
|
mkdirSync10(path41.dirname(wsPath), { recursive: true });
|
|
70858
70937
|
const tmp = `${wsPath}.${process.pid}.tmp`;
|
|
70859
70938
|
try {
|
|
70860
|
-
|
|
70939
|
+
writeFileSync11(tmp, JSON.stringify({ ...document2, workspaces: next }, null, 2) + `
|
|
70861
70940
|
`, "utf8");
|
|
70862
70941
|
if (workspacesRevision(readFileSafe2(wsPath)) !== revision) {
|
|
70863
70942
|
rmSync6(tmp, { force: true });
|
|
@@ -70886,7 +70965,7 @@ function applyWorkspaceBranchPolicy(opts) {
|
|
|
70886
70965
|
}
|
|
70887
70966
|
var readFileSafe2 = (p) => {
|
|
70888
70967
|
try {
|
|
70889
|
-
return
|
|
70968
|
+
return readFileSync20(p, "utf8");
|
|
70890
70969
|
} catch {
|
|
70891
70970
|
return null;
|
|
70892
70971
|
}
|
|
@@ -71726,7 +71805,7 @@ var init_wizard_state = __esm(() => {
|
|
|
71726
71805
|
});
|
|
71727
71806
|
|
|
71728
71807
|
// packages/workit-cli/src/admin/uninstall.ts
|
|
71729
|
-
import { existsSync as existsSync19, readFileSync as
|
|
71808
|
+
import { existsSync as existsSync19, readFileSync as readFileSync21, realpathSync as realpathSync9, rmSync as rmSync7, writeFileSync as writeFileSync12 } from "node:fs";
|
|
71730
71809
|
import os14 from "node:os";
|
|
71731
71810
|
import path43 from "node:path";
|
|
71732
71811
|
function cleanCursorSettings(settings, pluginDir) {
|
|
@@ -71988,7 +72067,7 @@ var resolveUninstallPaths = (options = {}) => {
|
|
|
71988
72067
|
}, isRecord7 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), readJsonRecord = (file) => {
|
|
71989
72068
|
let raw;
|
|
71990
72069
|
try {
|
|
71991
|
-
raw =
|
|
72070
|
+
raw = readFileSync21(file, "utf8");
|
|
71992
72071
|
} catch {
|
|
71993
72072
|
if (existsSync19(file))
|
|
71994
72073
|
return { kind: "malformed", error: `${file} is not readable` };
|
|
@@ -72053,7 +72132,7 @@ var resolveUninstallPaths = (options = {}) => {
|
|
|
72053
72132
|
`;
|
|
72054
72133
|
let current;
|
|
72055
72134
|
try {
|
|
72056
|
-
current =
|
|
72135
|
+
current = readFileSync21(target, "utf8");
|
|
72057
72136
|
} catch (error) {
|
|
72058
72137
|
return {
|
|
72059
72138
|
status: "failed",
|
|
@@ -72064,7 +72143,7 @@ var resolveUninstallPaths = (options = {}) => {
|
|
|
72064
72143
|
return { status: "skipped", detail: "already clean" };
|
|
72065
72144
|
}
|
|
72066
72145
|
try {
|
|
72067
|
-
|
|
72146
|
+
writeFileSync12(target, serialized, "utf8");
|
|
72068
72147
|
} catch (error) {
|
|
72069
72148
|
return {
|
|
72070
72149
|
status: "failed",
|
|
@@ -74838,171 +74917,156 @@ var init_setup2 = __esm(() => {
|
|
|
74838
74917
|
ALL_HOSTS = ["claude-code", "codex", "cursor", "opencode", "pi"];
|
|
74839
74918
|
});
|
|
74840
74919
|
|
|
74841
|
-
// packages/workit-cli/src/upgrade.ts
|
|
74842
|
-
import {
|
|
74843
|
-
import {
|
|
74844
|
-
existsSync as existsSync20,
|
|
74845
|
-
mkdtempSync as mkdtempSync3,
|
|
74846
|
-
rmSync as rmSync8,
|
|
74847
|
-
readFileSync as readFileSync21,
|
|
74848
|
-
readdirSync as readdirSync12,
|
|
74849
|
-
mkdirSync as mkdirSync11,
|
|
74850
|
-
copyFileSync as copyFileSync6,
|
|
74851
|
-
chmodSync as chmodSync2,
|
|
74852
|
-
cpSync as cpSync5,
|
|
74853
|
-
lstatSync as lstatSync7
|
|
74854
|
-
} from "node:fs";
|
|
74920
|
+
// packages/workit-cli/src/upgrade/shared.ts
|
|
74921
|
+
import { existsSync as existsSync20, readFileSync as readFileSync22 } from "node:fs";
|
|
74855
74922
|
import path44 from "node:path";
|
|
74856
74923
|
import os16 from "node:os";
|
|
74857
74924
|
import { createHash as createHash15 } from "node:crypto";
|
|
74858
|
-
|
|
74859
|
-
const
|
|
74860
|
-
const
|
|
74861
|
-
|
|
74862
|
-
|
|
74863
|
-
|
|
74864
|
-
|
|
74865
|
-
|
|
74866
|
-
|
|
74867
|
-
|
|
74868
|
-
|
|
74869
|
-
|
|
74870
|
-
|
|
74925
|
+
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", 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) => {
|
|
74926
|
+
const home = deps.home ?? deps.env?.HOME ?? os16.homedir();
|
|
74927
|
+
const env = {
|
|
74928
|
+
...process.env,
|
|
74929
|
+
...deps.home || deps.env?.HOME ? {
|
|
74930
|
+
HOME: home,
|
|
74931
|
+
CODEX_HOME: path44.join(home, ".codex"),
|
|
74932
|
+
CLAUDE_CONFIG_DIR: path44.join(home, ".claude"),
|
|
74933
|
+
PI_CODING_AGENT_DIR: path44.join(home, ".pi/agent"),
|
|
74934
|
+
XDG_CONFIG_HOME: path44.join(home, ".config"),
|
|
74935
|
+
WORKFLOW_TOOLKIT_CONFIG: undefined,
|
|
74936
|
+
WORKFLOW_TOOLKIT_CONFIG_DIR: undefined
|
|
74937
|
+
} : {},
|
|
74938
|
+
...deps.env,
|
|
74939
|
+
HOME: home
|
|
74871
74940
|
};
|
|
74872
|
-
|
|
74873
|
-
|
|
74874
|
-
|
|
74875
|
-
|
|
74941
|
+
const xdg = env.XDG_CONFIG_HOME || path44.join(home, ".config");
|
|
74942
|
+
const codexHome = env.CODEX_HOME ?? path44.join(home, ".codex");
|
|
74943
|
+
return {
|
|
74944
|
+
home,
|
|
74945
|
+
env,
|
|
74946
|
+
configDir: env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path44.join(xdg, "workit"),
|
|
74947
|
+
opencodeConfig: path44.join(xdg, "opencode/opencode.json"),
|
|
74948
|
+
piSettings: path44.join(env.PI_CODING_AGENT_DIR ?? path44.join(home, ".pi/agent"), "settings.json"),
|
|
74949
|
+
codexHome,
|
|
74950
|
+
codexConfig: path44.join(codexHome, "config.toml"),
|
|
74951
|
+
cursorRoot: path44.join(home, ".cursor/plugins/local/workit")
|
|
74952
|
+
};
|
|
74953
|
+
}, object2 = (file) => {
|
|
74954
|
+
if (!existsSync20(file))
|
|
74955
|
+
return null;
|
|
74956
|
+
let data;
|
|
74957
|
+
try {
|
|
74958
|
+
data = JSON.parse(readFileSync22(file, "utf8"));
|
|
74959
|
+
} catch {
|
|
74960
|
+
throw new Error(`${file} is not valid JSON; use the native host to inspect JSONC settings`);
|
|
74876
74961
|
}
|
|
74877
|
-
|
|
74878
|
-
|
|
74879
|
-
|
|
74880
|
-
|
|
74881
|
-
path44.join(home, ".cursor/mcp.json"),
|
|
74882
|
-
path44.join(paths.cursorRoot, "package.json"),
|
|
74883
|
-
paths.codexConfig,
|
|
74884
|
-
paths.piSettings
|
|
74885
|
-
])
|
|
74886
|
-
plan.configDigests[file] = digest2(file);
|
|
74962
|
+
if (!data || typeof data !== "object" || Array.isArray(data))
|
|
74963
|
+
throw new Error(`${file} is not a configuration object`);
|
|
74964
|
+
return data;
|
|
74965
|
+
}, objectOrNull = (file) => {
|
|
74887
74966
|
try {
|
|
74888
|
-
|
|
74889
|
-
|
|
74890
|
-
|
|
74891
|
-
id: "2.0-remove-ignored-trusted-paths",
|
|
74892
|
-
file: state.config.file,
|
|
74893
|
-
description: "Remove ignored Workit trustedPaths; native host permissions remain unchanged"
|
|
74894
|
-
});
|
|
74895
|
-
} catch (error) {
|
|
74896
|
-
plan.blocked.push(errorText(error));
|
|
74967
|
+
return object2(file);
|
|
74968
|
+
} catch {
|
|
74969
|
+
return null;
|
|
74897
74970
|
}
|
|
74898
|
-
|
|
74899
|
-
|
|
74900
|
-
|
|
74901
|
-
|
|
74902
|
-
|
|
74903
|
-
|
|
74904
|
-
|
|
74971
|
+
}, digest2 = (file) => existsSync20(file) ? createHash15("sha256").update(readFileSync22(file)).digest("hex") : "missing", runner = (deps) => deps.run ?? ((command, args) => {
|
|
74972
|
+
const { home, env } = upgradePaths(deps);
|
|
74973
|
+
let step;
|
|
74974
|
+
try {
|
|
74975
|
+
step = hostCommand(command, args, { home, env });
|
|
74976
|
+
} catch {
|
|
74977
|
+
return { status: 1, stdout: "" };
|
|
74905
74978
|
}
|
|
74906
|
-
|
|
74907
|
-
|
|
74908
|
-
|
|
74909
|
-
|
|
74910
|
-
|
|
74911
|
-
|
|
74912
|
-
|
|
74979
|
+
const result = runHostCommand(step, { home, env });
|
|
74980
|
+
return { status: result.exitCode, stdout: result.stdout };
|
|
74981
|
+
}), errorText = (error) => error instanceof Error ? error.message : "installed source could not be read", piInstalledVersion = (listing, selector) => {
|
|
74982
|
+
const lines = listing.split(/\r?\n/).map((line) => line.trim());
|
|
74983
|
+
const index = lines.indexOf(selector);
|
|
74984
|
+
if (index < 0 || !lines[index + 1] || !path44.isAbsolute(lines[index + 1]))
|
|
74985
|
+
return;
|
|
74986
|
+
const found = objectOrNull(path44.join(lines[index + 1], "package.json"));
|
|
74987
|
+
return found?.name === "@brainervirus/workit-pi" ? found.version : undefined;
|
|
74988
|
+
}, versionAtLeast = (installed, latest) => {
|
|
74989
|
+
if (!/^\d+\.\d+\.\d+$/.test(installed))
|
|
74990
|
+
return false;
|
|
74991
|
+
const current = installed.split(".").map(Number);
|
|
74992
|
+
const target = latest.split(".").map(Number);
|
|
74993
|
+
for (let index = 0;index < 3; index++) {
|
|
74994
|
+
if (current[index] !== target[index])
|
|
74995
|
+
return current[index] > target[index];
|
|
74913
74996
|
}
|
|
74914
|
-
|
|
74915
|
-
|
|
74916
|
-
|
|
74917
|
-
|
|
74918
|
-
|
|
74919
|
-
|
|
74920
|
-
|
|
74921
|
-
|
|
74922
|
-
|
|
74923
|
-
|
|
74924
|
-
|
|
74925
|
-
|
|
74926
|
-
|
|
74927
|
-
|
|
74928
|
-
|
|
74929
|
-
|
|
74930
|
-
|
|
74931
|
-
|
|
74932
|
-
|
|
74933
|
-
|
|
74934
|
-
|
|
74935
|
-
|
|
74936
|
-
|
|
74937
|
-
|
|
74938
|
-
|
|
74939
|
-
|
|
74940
|
-
|
|
74941
|
-
|
|
74942
|
-
|
|
74943
|
-
|
|
74944
|
-
|
|
74945
|
-
|
|
74946
|
-
|
|
74947
|
-
|
|
74948
|
-
|
|
74949
|
-
|
|
74950
|
-
|
|
74951
|
-
|
|
74952
|
-
|
|
74953
|
-
|
|
74954
|
-
|
|
74955
|
-
|
|
74956
|
-
|
|
74957
|
-
|
|
74958
|
-
|
|
74959
|
-
|
|
74960
|
-
|
|
74961
|
-
if (!latest) {
|
|
74962
|
-
plan.failed.push({
|
|
74963
|
-
host: source.host,
|
|
74964
|
-
status: "failed",
|
|
74965
|
-
reason: "registry version unavailable; existing installation preserved",
|
|
74966
|
-
fix: fixFor(source.host, source.selector)
|
|
74967
|
-
});
|
|
74968
|
-
continue;
|
|
74969
|
-
}
|
|
74970
|
-
if (source.installedVersion && versionAtLeast(source.installedVersion, latest)) {
|
|
74971
|
-
plan.skipped.push({
|
|
74972
|
-
host: source.host,
|
|
74973
|
-
reason: `already current (${source.installedVersion})`
|
|
74974
|
-
});
|
|
74975
|
-
continue;
|
|
74976
|
-
}
|
|
74977
|
-
const commands = source.host === "pi" ? [{ command: "pi", args: ["update", "--extension", source.selector] }] : source.host === "codex" ? [
|
|
74978
|
-
{
|
|
74979
|
-
command: "codex",
|
|
74980
|
-
args: ["plugin", "marketplace", "upgrade", CODEX_MARKETPLACE]
|
|
74981
|
-
},
|
|
74982
|
-
{
|
|
74983
|
-
command: "codex",
|
|
74984
|
-
args: ["plugin", "add", `workit@${CODEX_MARKETPLACE}`, "--json"]
|
|
74985
|
-
}
|
|
74986
|
-
] : planHostInstall("cursor", {
|
|
74987
|
-
home,
|
|
74988
|
-
env: deps.env,
|
|
74989
|
-
cwd: home,
|
|
74990
|
-
packageVersion: latest,
|
|
74991
|
-
targetDir: paths.cursorRoot
|
|
74992
|
-
});
|
|
74993
|
-
plan.entries.push({
|
|
74994
|
-
host: source.host,
|
|
74995
|
-
selector: source.selector,
|
|
74996
|
-
latest,
|
|
74997
|
-
commands,
|
|
74998
|
-
installedVersion: source.installedVersion,
|
|
74999
|
-
...source.kind === "repair" ? { repair: true } : {},
|
|
75000
|
-
fix: fixFor(source.host, source.selector)
|
|
74997
|
+
return true;
|
|
74998
|
+
}, registryVersion = (run, name) => {
|
|
74999
|
+
const latest = run("npm", ["view", name, "version"]);
|
|
75000
|
+
const version = latest.stdout.trim();
|
|
75001
|
+
return latest.status === 0 && /^\d+\.\d+\.\d+$/.test(version) ? version : undefined;
|
|
75002
|
+
};
|
|
75003
|
+
var init_shared = __esm(() => {
|
|
75004
|
+
init_host_install();
|
|
75005
|
+
LAUNCH_HOSTS = ["opencode", "cursor", "codex", "pi"];
|
|
75006
|
+
HOSTS2 = [...LAUNCH_HOSTS, "claude-code"];
|
|
75007
|
+
LIVE_HOSTS = new Set(["opencode", "claude-code"]);
|
|
75008
|
+
OPENCODE_UPDATE = `opencode plugin update ${OPENCODE_PACKAGE}`;
|
|
75009
|
+
});
|
|
75010
|
+
|
|
75011
|
+
// packages/workit-cli/src/upgrade/processes.ts
|
|
75012
|
+
import path45 from "node:path";
|
|
75013
|
+
var PROCESS_HOSTS, SCRIPT_RUNTIMES, classifyProcess = (proc) => {
|
|
75014
|
+
if (proc.state.startsWith("Z") || proc.args.includes("<defunct>"))
|
|
75015
|
+
return null;
|
|
75016
|
+
const argv0 = proc.args.trim().split(/\s+/)[0] ?? "";
|
|
75017
|
+
const baseName = (value) => path45.basename(value.replaceAll("\\", "/")).replace(/^\[|\]$/g, "").replace(/\.exe$/i, "").toLowerCase();
|
|
75018
|
+
let host = PROCESS_HOSTS[baseName(argv0)];
|
|
75019
|
+
if (!host && SCRIPT_RUNTIMES.has(baseName(argv0))) {
|
|
75020
|
+
const script = proc.args.trim().split(/\s+/).slice(1).find((arg) => !arg.startsWith("-"));
|
|
75021
|
+
if (script)
|
|
75022
|
+
host = PROCESS_HOSTS[baseName(script).replace(/\.(?:[cm]?js|ts)$/, "")];
|
|
75023
|
+
}
|
|
75024
|
+
if (!host)
|
|
75025
|
+
return null;
|
|
75026
|
+
if (host === "codex" && /\bapp-server\b/.test(proc.args))
|
|
75027
|
+
return /\bdaemon\s+pid-update-loop\b/.test(proc.args) ? null : { ...proc, host, kind: "daemon" };
|
|
75028
|
+
if (host === "opencode" && /\bserve\b/.test(proc.args))
|
|
75029
|
+
return { ...proc, host, kind: "daemon" };
|
|
75030
|
+
return { ...proc, host, kind: "session" };
|
|
75031
|
+
}, listProcesses = (deps) => {
|
|
75032
|
+
if (deps.processes)
|
|
75033
|
+
return deps.processes();
|
|
75034
|
+
if (deps.activeHosts)
|
|
75035
|
+
return deps.activeHosts().map((host) => ({ pid: 0, state: "S", args: host }));
|
|
75036
|
+
const run = runner(deps);
|
|
75037
|
+
if (process.platform === "win32") {
|
|
75038
|
+
const list = run("tasklist", ["/fo", "csv", "/nh"]);
|
|
75039
|
+
if (list.status !== 0)
|
|
75040
|
+
return null;
|
|
75041
|
+
return list.stdout.split(/\r?\n/).flatMap((line) => {
|
|
75042
|
+
const [image, pid] = line.split('","').map((cell) => cell.replaceAll('"', ""));
|
|
75043
|
+
return image && /^\d+$/.test(pid ?? "") ? [{ pid: Number(pid), state: "R", args: image }] : [];
|
|
75001
75044
|
});
|
|
75002
75045
|
}
|
|
75003
|
-
|
|
75004
|
-
|
|
75005
|
-
|
|
75046
|
+
const list = run("ps", ["-eo", "pid=,stat=,args="]);
|
|
75047
|
+
if (list.status !== 0)
|
|
75048
|
+
return null;
|
|
75049
|
+
return list.stdout.split(/\r?\n/).flatMap((line) => {
|
|
75050
|
+
const match = /^\s*(\d+)\s+(\S+)\s+(.+)$/.exec(line);
|
|
75051
|
+
return match ? [{ pid: Number(match[1]), state: match[2], args: match[3] }] : [];
|
|
75052
|
+
});
|
|
75053
|
+
}, describe2 = (proc) => `pid ${proc.pid}: ${proc.args.length > 120 ? `${proc.args.slice(0, 117)}...` : proc.args}`;
|
|
75054
|
+
var init_processes = __esm(() => {
|
|
75055
|
+
init_shared();
|
|
75056
|
+
PROCESS_HOSTS = {
|
|
75057
|
+
claude: "claude-code",
|
|
75058
|
+
codex: "codex",
|
|
75059
|
+
cursor: "cursor",
|
|
75060
|
+
opencode: "opencode",
|
|
75061
|
+
pi: "pi"
|
|
75062
|
+
};
|
|
75063
|
+
SCRIPT_RUNTIMES = new Set(["node", "nodejs", "bun"]);
|
|
75064
|
+
});
|
|
75065
|
+
|
|
75066
|
+
// packages/workit-cli/src/upgrade/apply.ts
|
|
75067
|
+
import { existsSync as existsSync21, readdirSync as readdirSync12, mkdirSync as mkdirSync11, copyFileSync as copyFileSync6, chmodSync as chmodSync2, cpSync as cpSync5 } from "node:fs";
|
|
75068
|
+
import path46 from "node:path";
|
|
75069
|
+
import { createHash as createHash16 } from "node:crypto";
|
|
75006
75070
|
function applyUpgrade(plan, deps = {}) {
|
|
75007
75071
|
const hosts = [...plan.failed];
|
|
75008
75072
|
const done = (backup) => {
|
|
@@ -75036,11 +75100,11 @@ function applyUpgrade(plan, deps = {}) {
|
|
|
75036
75100
|
};
|
|
75037
75101
|
const paths = upgradePaths(deps);
|
|
75038
75102
|
const { home, configDir } = paths;
|
|
75039
|
-
const backup =
|
|
75103
|
+
const backup = path46.join(home, ".local/state/workit/upgrades", new Date().toISOString().replaceAll(":", "-"));
|
|
75040
75104
|
mkdirSync11(backup, { recursive: true, mode: 448 });
|
|
75041
75105
|
for (const file of Object.keys(plan.configDigests))
|
|
75042
|
-
if (
|
|
75043
|
-
const target =
|
|
75106
|
+
if (existsSync21(file)) {
|
|
75107
|
+
const target = path46.join(backup, createHash16("sha256").update(file).digest("hex").slice(0, 12) + "-" + path46.basename(file));
|
|
75044
75108
|
copyFileSync6(file, target);
|
|
75045
75109
|
chmodSync2(target, 384);
|
|
75046
75110
|
}
|
|
@@ -75059,9 +75123,11 @@ function applyUpgrade(plan, deps = {}) {
|
|
|
75059
75123
|
}
|
|
75060
75124
|
const run = runner(deps);
|
|
75061
75125
|
let cursorBackupError = null;
|
|
75062
|
-
if (plan.entries.some((entry) => entry.host === "cursor") &&
|
|
75126
|
+
if (plan.entries.some((entry) => entry.host === "cursor") && existsSync21(paths.cursorRoot))
|
|
75063
75127
|
try {
|
|
75064
|
-
cpSync5(paths.cursorRoot,
|
|
75128
|
+
cpSync5(paths.cursorRoot, path46.join(backup, "cursor-package"), {
|
|
75129
|
+
recursive: true
|
|
75130
|
+
});
|
|
75065
75131
|
} catch (error) {
|
|
75066
75132
|
cursorBackupError = `could not back up the Cursor plugin: ${errorText(error)}`;
|
|
75067
75133
|
}
|
|
@@ -75069,7 +75135,12 @@ function applyUpgrade(plan, deps = {}) {
|
|
|
75069
75135
|
const running = (listed ?? []).flatMap((entry) => classifyProcess(entry) ?? []);
|
|
75070
75136
|
for (const entry of plan.entries) {
|
|
75071
75137
|
if (entry.host === "cursor" && cursorBackupError) {
|
|
75072
|
-
hosts.push({
|
|
75138
|
+
hosts.push({
|
|
75139
|
+
host: "cursor",
|
|
75140
|
+
status: "failed",
|
|
75141
|
+
reason: cursorBackupError,
|
|
75142
|
+
fix: entry.fix
|
|
75143
|
+
});
|
|
75073
75144
|
continue;
|
|
75074
75145
|
}
|
|
75075
75146
|
if (!LIVE_HOSTS.has(entry.host)) {
|
|
@@ -75178,238 +75249,356 @@ function applyUpgrade(plan, deps = {}) {
|
|
|
75178
75249
|
try {
|
|
75179
75250
|
hosts.push(applyCli(plan.cli, run, backup));
|
|
75180
75251
|
} catch (error) {
|
|
75181
|
-
hosts.push({
|
|
75252
|
+
hosts.push({
|
|
75253
|
+
host: "cli",
|
|
75254
|
+
status: "failed",
|
|
75255
|
+
reason: errorText(error),
|
|
75256
|
+
fix: CLI_FIX
|
|
75257
|
+
});
|
|
75182
75258
|
}
|
|
75183
75259
|
return done(backup);
|
|
75184
75260
|
}
|
|
75185
|
-
|
|
75186
|
-
const
|
|
75187
|
-
|
|
75188
|
-
|
|
75189
|
-
|
|
75190
|
-
|
|
75191
|
-
|
|
75192
|
-
out.write(USAGE3);
|
|
75193
|
-
return 2;
|
|
75261
|
+
var codexPluginRoot = (codexHome) => {
|
|
75262
|
+
const dir = path46.join(codexHome, "plugins", "cache", CODEX_MARKETPLACE, "workit");
|
|
75263
|
+
let versions = [];
|
|
75264
|
+
try {
|
|
75265
|
+
versions = readdirSync12(dir).filter((version) => /^\d+\.\d+\.\d+$/.test(version));
|
|
75266
|
+
} catch {
|
|
75267
|
+
return null;
|
|
75194
75268
|
}
|
|
75195
|
-
|
|
75196
|
-
|
|
75197
|
-
|
|
75198
|
-
|
|
75269
|
+
const newest = versions.reduce((best, version) => best && versionAtLeast(best, version) ? best : version, null);
|
|
75270
|
+
return newest ? path46.join(dir, newest) : null;
|
|
75271
|
+
}, opencodeVersion = (run) => {
|
|
75272
|
+
const listing = run("opencode", ["plugin", "list"]);
|
|
75273
|
+
if (listing.status !== 0)
|
|
75274
|
+
return;
|
|
75275
|
+
for (const line of listing.stdout.split(/\r?\n/)) {
|
|
75276
|
+
const fields = line.trim().split(/\s+/);
|
|
75277
|
+
if (fields.length < 3)
|
|
75278
|
+
continue;
|
|
75279
|
+
const source = fields[fields.length - 1].replace(/^file:\/\//, "");
|
|
75280
|
+
const version = fields[fields.length - 2];
|
|
75281
|
+
if (/^(?:npm:)?@brainervirus\/workit-opencode(?:@[^/\s]+)?$/.test(source) && /^\d+\.\d+\.\d+$/.test(version))
|
|
75282
|
+
return version;
|
|
75199
75283
|
}
|
|
75200
|
-
|
|
75201
|
-
|
|
75202
|
-
const run =
|
|
75203
|
-
const
|
|
75204
|
-
|
|
75205
|
-
|
|
75206
|
-
|
|
75207
|
-
|
|
75208
|
-
|
|
75209
|
-
hosts: raw,
|
|
75210
|
-
refreshOnly: true,
|
|
75211
|
-
shell: false,
|
|
75212
|
-
home,
|
|
75213
|
-
env
|
|
75284
|
+
return;
|
|
75285
|
+
}, applyEntry = (entry, context) => {
|
|
75286
|
+
const { run, paths, configDir } = context;
|
|
75287
|
+
const { home, env } = paths;
|
|
75288
|
+
const fail = (reason) => ({
|
|
75289
|
+
host: entry.host,
|
|
75290
|
+
status: "failed",
|
|
75291
|
+
reason,
|
|
75292
|
+
fix: entry.fix
|
|
75214
75293
|
});
|
|
75215
|
-
|
|
75216
|
-
|
|
75217
|
-
|
|
75218
|
-
|
|
75219
|
-
|
|
75220
|
-
|
|
75221
|
-
|
|
75222
|
-
|
|
75223
|
-
|
|
75224
|
-
|
|
75225
|
-
|
|
75226
|
-
|
|
75227
|
-
|
|
75228
|
-
|
|
75229
|
-
|
|
75230
|
-
|
|
75294
|
+
if (entry.host === "cursor") {
|
|
75295
|
+
const preview = {
|
|
75296
|
+
ok: true,
|
|
75297
|
+
blocked: [],
|
|
75298
|
+
preserved: [],
|
|
75299
|
+
overrides: [],
|
|
75300
|
+
platforms: ["cursor"],
|
|
75301
|
+
state: readSetupState(configDir),
|
|
75302
|
+
mutations: [
|
|
75303
|
+
{
|
|
75304
|
+
type: "install-host",
|
|
75305
|
+
platform: "cursor",
|
|
75306
|
+
path: path46.join(home, ".cursor/plugins/local/.workit-package-bootstrap"),
|
|
75307
|
+
commands: entry.commands.map((command) => ({
|
|
75308
|
+
...command,
|
|
75309
|
+
purpose: command.purpose ?? "Upgrade Cursor"
|
|
75310
|
+
}))
|
|
75311
|
+
},
|
|
75312
|
+
{ type: "install-adapter", platform: "cursor", path: paths.cursorRoot }
|
|
75313
|
+
]
|
|
75314
|
+
};
|
|
75315
|
+
const result = applySetupPreview(preview, {
|
|
75316
|
+
home,
|
|
75317
|
+
env,
|
|
75318
|
+
cwd: home,
|
|
75319
|
+
preferInstalledAdapter: true,
|
|
75320
|
+
runHostCommand: (command) => {
|
|
75321
|
+
const outcome = run(command.command, command.args);
|
|
75322
|
+
return {
|
|
75323
|
+
exitCode: outcome.status ?? 1,
|
|
75324
|
+
stdout: outcome.stdout,
|
|
75325
|
+
stderr: ""
|
|
75326
|
+
};
|
|
75327
|
+
}
|
|
75328
|
+
});
|
|
75329
|
+
const installed = objectOrNull(path46.join(paths.cursorRoot, "package.json"));
|
|
75330
|
+
if (!result.ok || installed?.version !== entry.latest)
|
|
75331
|
+
return fail("Cursor install did not verify the requested package version; inspect the installer before retrying");
|
|
75332
|
+
return {
|
|
75333
|
+
host: "cursor",
|
|
75334
|
+
status: "updated",
|
|
75335
|
+
reason: entry.repair ? `reinstalled missing plugin files (${entry.latest})` : `${entry.installedVersion ?? "?"} -> ${entry.latest}`
|
|
75336
|
+
};
|
|
75231
75337
|
}
|
|
75232
|
-
|
|
75233
|
-
|
|
75234
|
-
|
|
75235
|
-
|
|
75236
|
-
|
|
75338
|
+
const before = entry.host === "opencode" ? opencodeVersion(run) : undefined;
|
|
75339
|
+
for (const command of entry.commands)
|
|
75340
|
+
if (run(command.command, command.args).status !== 0)
|
|
75341
|
+
return fail(`\`${command.command} ${command.args.join(" ")}\` failed`);
|
|
75342
|
+
if (entry.host === "opencode") {
|
|
75343
|
+
const after = opencodeVersion(run);
|
|
75344
|
+
if (before && after)
|
|
75345
|
+
return after === before ? {
|
|
75346
|
+
host: "opencode",
|
|
75347
|
+
status: "current",
|
|
75348
|
+
reason: `already current (${after})`
|
|
75349
|
+
} : {
|
|
75350
|
+
host: "opencode",
|
|
75351
|
+
status: "updated",
|
|
75352
|
+
reason: `${before} -> ${after}; OpenCode V2 loads it live`
|
|
75353
|
+
};
|
|
75354
|
+
return {
|
|
75355
|
+
host: "opencode",
|
|
75356
|
+
status: "updated",
|
|
75357
|
+
reason: "scoped update ran; OpenCode V2 loads it live"
|
|
75358
|
+
};
|
|
75237
75359
|
}
|
|
75238
|
-
if (
|
|
75239
|
-
|
|
75240
|
-
|
|
75241
|
-
|
|
75242
|
-
|
|
75360
|
+
if (entry.host === "claude-code") {
|
|
75361
|
+
const after = claudeWorkitInstalls(home, env, null).find((install) => install.id === entry.selector)?.version;
|
|
75362
|
+
return after && after === entry.installedVersion ? {
|
|
75363
|
+
host: "claude-code",
|
|
75364
|
+
status: "current",
|
|
75365
|
+
reason: `already current (${after})`
|
|
75366
|
+
} : {
|
|
75367
|
+
host: "claude-code",
|
|
75368
|
+
status: "updated",
|
|
75369
|
+
reason: `${entry.installedVersion ?? "?"} -> ${after ?? "?"}; new sessions load it`
|
|
75370
|
+
};
|
|
75243
75371
|
}
|
|
75244
|
-
const
|
|
75245
|
-
if (
|
|
75246
|
-
|
|
75247
|
-
|
|
75248
|
-
|
|
75249
|
-
|
|
75250
|
-
|
|
75372
|
+
const verify = entry.host === "codex" ? run("codex", ["plugin", "list", "--json"]) : run("pi", ["list"]);
|
|
75373
|
+
if (verify.status !== 0)
|
|
75374
|
+
return fail("update verification failed");
|
|
75375
|
+
if (entry.host === "codex") {
|
|
75376
|
+
let installed = [];
|
|
75377
|
+
try {
|
|
75378
|
+
installed = JSON.parse(verify.stdout).installed ?? [];
|
|
75379
|
+
} catch {}
|
|
75380
|
+
if (!installed.some((plugin) => plugin.name === "workit" && plugin.marketplaceName === CODEX_MARKETPLACE && plugin.version === entry.latest))
|
|
75381
|
+
return fail("Codex did not report the requested Workit version");
|
|
75251
75382
|
}
|
|
75252
|
-
if (
|
|
75253
|
-
|
|
75254
|
-
|
|
75255
|
-
|
|
75256
|
-
|
|
75257
|
-
|
|
75258
|
-
|
|
75259
|
-
|
|
75260
|
-
|
|
75261
|
-
|
|
75262
|
-
|
|
75263
|
-
|
|
75264
|
-
|
|
75265
|
-
|
|
75266
|
-
|
|
75267
|
-
|
|
75383
|
+
if (entry.host === "pi" && piInstalledVersion(verify.stdout, entry.selector) !== entry.latest)
|
|
75384
|
+
return fail("Pi did not report the requested Workit package version");
|
|
75385
|
+
return {
|
|
75386
|
+
host: entry.host,
|
|
75387
|
+
status: "updated",
|
|
75388
|
+
reason: entry.repair ? `reinstalled missing plugin files (${entry.latest})` : `${entry.installedVersion ?? "?"} -> ${entry.latest}`
|
|
75389
|
+
};
|
|
75390
|
+
}, refreshCodexAgents = (run, codexHome) => {
|
|
75391
|
+
const root = codexPluginRoot(codexHome);
|
|
75392
|
+
const launcher = root && path46.join(root, "dist", "launch-mcp.js");
|
|
75393
|
+
if (!launcher || !existsSync21(launcher))
|
|
75394
|
+
return { ok: true, note: "" };
|
|
75395
|
+
const fix = `node ${JSON.stringify(launcher)} --install-agents`;
|
|
75396
|
+
return run("node", [launcher, "--install-agents"]).status === 0 ? { ok: true, note: "agents refreshed" } : { ok: false, note: "agent refresh failed", fix };
|
|
75397
|
+
}, applyCli = (cli, run, backup) => {
|
|
75398
|
+
const fail = (reason) => ({
|
|
75399
|
+
host: "cli",
|
|
75400
|
+
status: "failed",
|
|
75401
|
+
reason,
|
|
75402
|
+
fix: CLI_FIX
|
|
75403
|
+
});
|
|
75404
|
+
const currentRoot = run("npm", ["root", "--global"]);
|
|
75405
|
+
if (currentRoot.status !== 0 || currentRoot.stdout.trim() !== cli.root)
|
|
75406
|
+
return fail("Global npm location changed; preview again");
|
|
75407
|
+
const cliBackup = path46.join(backup, "cli-package");
|
|
75408
|
+
cpSync5(path46.join(cli.root, "@brainervirus/workit-cli"), cliBackup, {
|
|
75409
|
+
recursive: true
|
|
75410
|
+
});
|
|
75411
|
+
if (run("npm", ["install", "--global", `@brainervirus/workit-cli@${cli.latest}`]).status !== 0)
|
|
75412
|
+
return fail(`CLI update failed; preserved package at ${cliBackup}; use npm to repair or run node ${path46.join(cliBackup, "dist/index.js")}`);
|
|
75413
|
+
const installed = objectOrNull(path46.join(cli.root, "@brainervirus/workit-cli/package.json"));
|
|
75414
|
+
if (installed?.name !== "@brainervirus/workit-cli" || installed.version !== cli.latest)
|
|
75415
|
+
return fail(`CLI update did not verify the requested version; preserved package at ${cliBackup}`);
|
|
75416
|
+
return {
|
|
75417
|
+
host: "cli",
|
|
75418
|
+
status: "updated",
|
|
75419
|
+
reason: `${cli.installed} -> ${cli.latest}`
|
|
75420
|
+
};
|
|
75421
|
+
};
|
|
75422
|
+
var init_apply = __esm(() => {
|
|
75423
|
+
init_host_install();
|
|
75424
|
+
init_setup_state();
|
|
75425
|
+
init_setup();
|
|
75426
|
+
init_safe_write();
|
|
75427
|
+
init_processes();
|
|
75428
|
+
init_shared();
|
|
75429
|
+
});
|
|
75430
|
+
|
|
75431
|
+
// packages/workit-cli/src/upgrade/plan.ts
|
|
75432
|
+
import { existsSync as existsSync22, mkdtempSync as mkdtempSync3, rmSync as rmSync8, lstatSync as lstatSync7, readFileSync as readFileSync23 } from "node:fs";
|
|
75433
|
+
import path47 from "node:path";
|
|
75434
|
+
import os17 from "node:os";
|
|
75435
|
+
function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
75436
|
+
const paths = upgradePaths(deps);
|
|
75437
|
+
const { home, configDir } = paths;
|
|
75438
|
+
const run = runner(deps);
|
|
75439
|
+
const state = readSetupState(configDir);
|
|
75440
|
+
const plan = {
|
|
75441
|
+
ok: true,
|
|
75442
|
+
blocked: [],
|
|
75443
|
+
failed: [],
|
|
75444
|
+
skipped: [],
|
|
75445
|
+
entries: [],
|
|
75446
|
+
configDigests: {},
|
|
75447
|
+
migrations: []
|
|
75448
|
+
};
|
|
75449
|
+
for (const file of [state.config, state.workspaces, state.youtrack, state.vcs]) {
|
|
75450
|
+
if (file.status === "malformed")
|
|
75451
|
+
plan.blocked.push(file.error ?? file.file);
|
|
75452
|
+
plan.configDigests[file.file] = digest2(file.file);
|
|
75453
|
+
}
|
|
75454
|
+
for (const file of [
|
|
75455
|
+
paths.opencodeConfig,
|
|
75456
|
+
paths.opencodeConfig + "c",
|
|
75457
|
+
path47.join(home, ".cursor/settings.json"),
|
|
75458
|
+
path47.join(home, ".cursor/mcp.json"),
|
|
75459
|
+
path47.join(paths.cursorRoot, "package.json"),
|
|
75460
|
+
paths.codexConfig,
|
|
75461
|
+
paths.piSettings
|
|
75462
|
+
])
|
|
75463
|
+
plan.configDigests[file] = digest2(file);
|
|
75464
|
+
try {
|
|
75465
|
+
const config = object2(state.config.file);
|
|
75466
|
+
if (config && Object.hasOwn(config, "trustedPaths"))
|
|
75467
|
+
plan.migrations.push({
|
|
75468
|
+
id: "2.0-remove-ignored-trusted-paths",
|
|
75469
|
+
file: state.config.file,
|
|
75470
|
+
description: "Remove ignored Workit trustedPaths; native host permissions remain unchanged"
|
|
75268
75471
|
});
|
|
75472
|
+
} catch (error) {
|
|
75473
|
+
plan.blocked.push(errorText(error));
|
|
75269
75474
|
}
|
|
75270
|
-
const
|
|
75271
|
-
|
|
75272
|
-
|
|
75273
|
-
|
|
75274
|
-
|
|
75275
|
-
|
|
75276
|
-
|
|
75277
|
-
ok: !failed,
|
|
75278
|
-
...written ? { permissions: { changes: permissionPreview.changes, written } } : permissions.refused ? { permissions: permissionPreview } : {},
|
|
75279
|
-
doctor: { clean: left.length === 0, left }
|
|
75280
|
-
}, null, 2) + `
|
|
75281
|
-
`);
|
|
75282
|
-
return failed ? 1 : 0;
|
|
75475
|
+
const installedSources = sources(paths, run, hosts, plan.failed);
|
|
75476
|
+
let opencodeHelp;
|
|
75477
|
+
if (installedSources.some((source) => source.host === "opencode")) {
|
|
75478
|
+
const probe = opencodeProbe(deps, ["--version"]);
|
|
75479
|
+
const installed = probe.status === 0 ? probe.stdout.match(/\d+\.\d+\.\d+/)?.[0] : undefined;
|
|
75480
|
+
if (installed && !versionAtLeast(installed, SUPPORT_MATRIX.opencode.minimum))
|
|
75481
|
+
(plan.warnings ??= []).push(`opencode ${installed}: ${OPENCODE_V1_FIX}`);
|
|
75283
75482
|
}
|
|
75284
|
-
|
|
75285
|
-
|
|
75286
|
-
|
|
75287
|
-
|
|
75288
|
-
|
|
75289
|
-
|
|
75290
|
-
|
|
75291
|
-
if (result.backup)
|
|
75292
|
-
out.write(`Backup: ${result.backup}
|
|
75293
|
-
`);
|
|
75294
|
-
out.write(left.length === 0 ? `Verified: workit doctor is clean for versions, assets, agents and permissions.
|
|
75295
|
-
` : `Left after upgrade (workit doctor):
|
|
75296
|
-
${left.map((check) => ` ${check.id}: ${check.detail}${check.fix ? `
|
|
75297
|
-
fix: ${check.fix}` : ""}`).join(`
|
|
75298
|
-
`)}
|
|
75299
|
-
`);
|
|
75300
|
-
return failed ? 1 : 0;
|
|
75301
|
-
}
|
|
75302
|
-
async function runLaunchCommand(argv, deps = {}) {
|
|
75303
|
-
const [host, ...args] = argv;
|
|
75304
|
-
if (!LAUNCH_HOSTS.includes(host)) {
|
|
75305
|
-
(deps.out ?? process.stdout).write(`Usage: workit launch <opencode|cursor|codex|pi> [--auto-upgrade] [-- host arguments]
|
|
75306
|
-
`);
|
|
75307
|
-
return 2;
|
|
75483
|
+
for (const host of ["opencode", "pi"]) {
|
|
75484
|
+
if (new Set(installedSources.filter((source) => source.host === host).map((source) => source.selector)).size > 1)
|
|
75485
|
+
plan.failed.push({
|
|
75486
|
+
host,
|
|
75487
|
+
status: "failed",
|
|
75488
|
+
reason: "conflicting Workit registrations; reconcile them in the native host before upgrading"
|
|
75489
|
+
});
|
|
75308
75490
|
}
|
|
75309
|
-
const
|
|
75310
|
-
const
|
|
75311
|
-
|
|
75312
|
-
|
|
75313
|
-
|
|
75314
|
-
|
|
75315
|
-
|
|
75316
|
-
|
|
75317
|
-
} catch (error) {
|
|
75318
|
-
(deps.out ?? process.stderr).write(`${error instanceof Error ? error.message : "Host executable unavailable"}
|
|
75319
|
-
`);
|
|
75320
|
-
return 1;
|
|
75491
|
+
const conflicted = new Set(plan.failed.map((entry) => entry.host));
|
|
75492
|
+
for (const source of installedSources.filter((candidate, index, list) => !conflicted.has(candidate.host) && list.findIndex((entry) => entry.host === candidate.host && entry.selector === candidate.selector) === index)) {
|
|
75493
|
+
if (source.kind === "pinned" || source.kind === "local") {
|
|
75494
|
+
plan.skipped.push({
|
|
75495
|
+
host: source.host,
|
|
75496
|
+
reason: `${source.kind} source preserved; change its source explicitly to upgrade`
|
|
75497
|
+
});
|
|
75498
|
+
continue;
|
|
75321
75499
|
}
|
|
75322
|
-
|
|
75323
|
-
|
|
75324
|
-
|
|
75325
|
-
|
|
75326
|
-
|
|
75327
|
-
|
|
75328
|
-
|
|
75329
|
-
|
|
75330
|
-
|
|
75331
|
-
|
|
75332
|
-
|
|
75333
|
-
|
|
75334
|
-
|
|
75500
|
+
if (source.host === "claude-code") {
|
|
75501
|
+
const [market] = source.selector.split("@").slice(1);
|
|
75502
|
+
plan.entries.push({
|
|
75503
|
+
host: "claude-code",
|
|
75504
|
+
selector: source.selector,
|
|
75505
|
+
latest: "",
|
|
75506
|
+
installedVersion: source.installedVersion,
|
|
75507
|
+
commands: [
|
|
75508
|
+
{
|
|
75509
|
+
command: "claude",
|
|
75510
|
+
args: ["plugin", "marketplace", "update", market ?? "workit"]
|
|
75511
|
+
},
|
|
75512
|
+
{ command: "claude", args: ["plugin", "update", source.selector] }
|
|
75513
|
+
],
|
|
75514
|
+
fix: `claude plugin marketplace update ${market ?? "workit"} && claude plugin update ${source.selector}`
|
|
75515
|
+
});
|
|
75516
|
+
continue;
|
|
75517
|
+
}
|
|
75518
|
+
if (source.host === "opencode") {
|
|
75519
|
+
opencodeHelp ??= opencodeProbe(deps, ["plugin", "--help"]).stdout;
|
|
75520
|
+
if (!/^\s*(?:opencode\s+plugin\s+)?update\b/m.test(opencodeHelp)) {
|
|
75521
|
+
plan.skipped.push({
|
|
75522
|
+
host: "opencode",
|
|
75523
|
+
reason: "this OpenCode has no `opencode plugin update`; upgrade OpenCode, then run the fix. Workit never updates unrelated plugins",
|
|
75524
|
+
fix: OPENCODE_UPDATE
|
|
75525
|
+
});
|
|
75526
|
+
continue;
|
|
75335
75527
|
}
|
|
75336
|
-
|
|
75337
|
-
|
|
75338
|
-
|
|
75339
|
-
|
|
75340
|
-
|
|
75341
|
-
|
|
75342
|
-
|
|
75528
|
+
plan.entries.push({
|
|
75529
|
+
host: "opencode",
|
|
75530
|
+
selector: source.selector,
|
|
75531
|
+
latest: "",
|
|
75532
|
+
commands: [{ command: "opencode", args: ["plugin", "update", OPENCODE_PACKAGE] }],
|
|
75533
|
+
fix: OPENCODE_UPDATE
|
|
75534
|
+
});
|
|
75535
|
+
continue;
|
|
75343
75536
|
}
|
|
75537
|
+
const latest = registryVersion(run, `@brainervirus/workit-${source.host}`);
|
|
75538
|
+
if (!latest) {
|
|
75539
|
+
plan.failed.push({
|
|
75540
|
+
host: source.host,
|
|
75541
|
+
status: "failed",
|
|
75542
|
+
reason: "registry version unavailable; existing installation preserved",
|
|
75543
|
+
fix: fixFor(source.host, source.selector)
|
|
75544
|
+
});
|
|
75545
|
+
continue;
|
|
75546
|
+
}
|
|
75547
|
+
if (source.installedVersion && versionAtLeast(source.installedVersion, latest)) {
|
|
75548
|
+
plan.skipped.push({
|
|
75549
|
+
host: source.host,
|
|
75550
|
+
reason: `already current (${source.installedVersion})`
|
|
75551
|
+
});
|
|
75552
|
+
continue;
|
|
75553
|
+
}
|
|
75554
|
+
const commands = source.host === "pi" ? [{ command: "pi", args: ["update", "--extension", source.selector] }] : source.host === "codex" ? [
|
|
75555
|
+
{
|
|
75556
|
+
command: "codex",
|
|
75557
|
+
args: ["plugin", "marketplace", "upgrade", CODEX_MARKETPLACE]
|
|
75558
|
+
},
|
|
75559
|
+
{
|
|
75560
|
+
command: "codex",
|
|
75561
|
+
args: ["plugin", "add", `workit@${CODEX_MARKETPLACE}`, "--json"]
|
|
75562
|
+
}
|
|
75563
|
+
] : planHostInstall("cursor", {
|
|
75564
|
+
home,
|
|
75565
|
+
env: deps.env,
|
|
75566
|
+
cwd: home,
|
|
75567
|
+
packageVersion: latest,
|
|
75568
|
+
targetDir: paths.cursorRoot
|
|
75569
|
+
});
|
|
75570
|
+
plan.entries.push({
|
|
75571
|
+
host: source.host,
|
|
75572
|
+
selector: source.selector,
|
|
75573
|
+
latest,
|
|
75574
|
+
commands,
|
|
75575
|
+
installedVersion: source.installedVersion,
|
|
75576
|
+
...source.kind === "repair" ? { repair: true } : {},
|
|
75577
|
+
fix: fixFor(source.host, source.selector)
|
|
75578
|
+
});
|
|
75344
75579
|
}
|
|
75345
|
-
|
|
75346
|
-
|
|
75347
|
-
return spawnSync17(launch.command, launch.args, {
|
|
75348
|
-
stdio: "inherit",
|
|
75349
|
-
env
|
|
75350
|
-
}).status ?? 1;
|
|
75580
|
+
plan.ok = plan.blocked.length === 0 && plan.failed.length === 0;
|
|
75581
|
+
return plan;
|
|
75351
75582
|
}
|
|
75352
|
-
var
|
|
75353
|
-
|
|
75354
|
-
const env = {
|
|
75355
|
-
...process.env,
|
|
75356
|
-
...deps.home || deps.env?.HOME ? {
|
|
75357
|
-
HOME: home,
|
|
75358
|
-
CODEX_HOME: path44.join(home, ".codex"),
|
|
75359
|
-
CLAUDE_CONFIG_DIR: path44.join(home, ".claude"),
|
|
75360
|
-
PI_CODING_AGENT_DIR: path44.join(home, ".pi/agent"),
|
|
75361
|
-
XDG_CONFIG_HOME: path44.join(home, ".config"),
|
|
75362
|
-
WORKFLOW_TOOLKIT_CONFIG: undefined,
|
|
75363
|
-
WORKFLOW_TOOLKIT_CONFIG_DIR: undefined
|
|
75364
|
-
} : {},
|
|
75365
|
-
...deps.env,
|
|
75366
|
-
HOME: home
|
|
75367
|
-
};
|
|
75368
|
-
const xdg = env.XDG_CONFIG_HOME || path44.join(home, ".config");
|
|
75369
|
-
const codexHome = env.CODEX_HOME ?? path44.join(home, ".codex");
|
|
75370
|
-
return {
|
|
75371
|
-
home,
|
|
75372
|
-
env,
|
|
75373
|
-
configDir: env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path44.join(xdg, "workit"),
|
|
75374
|
-
opencodeConfig: path44.join(xdg, "opencode/opencode.json"),
|
|
75375
|
-
piSettings: path44.join(env.PI_CODING_AGENT_DIR ?? path44.join(home, ".pi/agent"), "settings.json"),
|
|
75376
|
-
codexHome,
|
|
75377
|
-
codexConfig: path44.join(codexHome, "config.toml"),
|
|
75378
|
-
cursorRoot: path44.join(home, ".cursor/plugins/local/workit")
|
|
75379
|
-
};
|
|
75380
|
-
}, object2 = (file) => {
|
|
75381
|
-
if (!existsSync20(file))
|
|
75382
|
-
return null;
|
|
75383
|
-
let data;
|
|
75384
|
-
try {
|
|
75385
|
-
data = JSON.parse(readFileSync21(file, "utf8"));
|
|
75386
|
-
} catch {
|
|
75387
|
-
throw new Error(`${file} is not valid JSON; use the native host to inspect JSONC settings`);
|
|
75388
|
-
}
|
|
75389
|
-
if (!data || typeof data !== "object" || Array.isArray(data))
|
|
75390
|
-
throw new Error(`${file} is not a configuration object`);
|
|
75391
|
-
return data;
|
|
75392
|
-
}, objectOrNull = (file) => {
|
|
75393
|
-
try {
|
|
75394
|
-
return object2(file);
|
|
75395
|
-
} catch {
|
|
75396
|
-
return null;
|
|
75397
|
-
}
|
|
75398
|
-
}, digest2 = (file) => existsSync20(file) ? createHash15("sha256").update(readFileSync21(file)).digest("hex") : "missing", runner = (deps) => deps.run ?? ((command, args) => {
|
|
75399
|
-
const { home, env } = upgradePaths(deps);
|
|
75400
|
-
let step;
|
|
75583
|
+
var codexRegistered = (configFile) => {
|
|
75584
|
+
let text;
|
|
75401
75585
|
try {
|
|
75402
|
-
|
|
75586
|
+
text = readFileSync23(configFile, "utf8");
|
|
75403
75587
|
} catch {
|
|
75404
|
-
return
|
|
75588
|
+
return false;
|
|
75405
75589
|
}
|
|
75406
|
-
const
|
|
75407
|
-
|
|
75408
|
-
|
|
75590
|
+
const header = `[plugins."workit@${CODEX_MARKETPLACE}"]`;
|
|
75591
|
+
const start = text.split(/\r?\n/).findIndex((line) => line.trim() === header);
|
|
75592
|
+
if (start < 0)
|
|
75593
|
+
return false;
|
|
75594
|
+
const body = text.split(/\r?\n/).slice(start + 1).join(`
|
|
75595
|
+
`).split(/^\s*\[/m)[0];
|
|
75596
|
+
return !/^\s*enabled\s*=\s*false\b/m.test(body);
|
|
75597
|
+
}, classify = (host, selector) => ({
|
|
75409
75598
|
host,
|
|
75410
75599
|
selector,
|
|
75411
75600
|
kind: selector === `@brainervirus/workit-${host}` || selector === `@brainervirus/workit-${host}@latest` || selector === `npm:@brainervirus/workit-${host}` || selector === `npm:@brainervirus/workit-${host}@latest` ? "floating" : new RegExp(`^(?:npm:)?@brainervirus/workit-${host}@[^/]+$`).test(selector) ? "pinned" : "local"
|
|
75412
|
-
}),
|
|
75601
|
+
}), sources = (paths, run, hosts, failed) => {
|
|
75413
75602
|
const { home } = paths;
|
|
75414
75603
|
const result = [];
|
|
75415
75604
|
const guard = (host, read) => {
|
|
@@ -75427,7 +75616,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75427
75616
|
}
|
|
75428
75617
|
};
|
|
75429
75618
|
guard("opencode", () => {
|
|
75430
|
-
if (
|
|
75619
|
+
if (existsSync22(paths.opencodeConfig + "c"))
|
|
75431
75620
|
throw new Error("OpenCode JSONC config is present; inspect effective native configuration before updating");
|
|
75432
75621
|
const oc = object2(paths.opencodeConfig);
|
|
75433
75622
|
if (oc && [oc.plugins, oc.plugin].some((value) => value !== undefined && !Array.isArray(value)))
|
|
@@ -75437,8 +75626,8 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75437
75626
|
result.push(classify("opencode", pin));
|
|
75438
75627
|
});
|
|
75439
75628
|
guard("cursor", () => {
|
|
75440
|
-
const cursor = objectOrNull(
|
|
75441
|
-
const mcp = objectOrNull(
|
|
75629
|
+
const cursor = objectOrNull(path47.join(paths.cursorRoot, "package.json"));
|
|
75630
|
+
const mcp = objectOrNull(path47.join(home, ".cursor/mcp.json"));
|
|
75442
75631
|
const args = mcp?.mcpServers?.workit?.args ?? [];
|
|
75443
75632
|
const arg = args.find((value) => typeof value === "string" && value.startsWith("--package="));
|
|
75444
75633
|
const selector = typeof arg === "string" ? arg.slice(10) : "local";
|
|
@@ -75449,7 +75638,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75449
75638
|
});
|
|
75450
75639
|
return;
|
|
75451
75640
|
}
|
|
75452
|
-
const settings = objectOrNull(
|
|
75641
|
+
const settings = objectOrNull(path47.join(home, ".cursor/settings.json"));
|
|
75453
75642
|
const dirs = Array.isArray(settings?.plugin_dirs) ? settings.plugin_dirs : [];
|
|
75454
75643
|
const registered = mcp?.mcpServers?.workit !== undefined || dirs.some((dir) => String(dir).replaceAll("\\", "/").replace(/\/+$/, "").endsWith("local/workit"));
|
|
75455
75644
|
if (registered)
|
|
@@ -75464,7 +75653,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75464
75653
|
if (typeof source !== "string")
|
|
75465
75654
|
continue;
|
|
75466
75655
|
const npm = /^(?:npm:)?@brainervirus\/workit-pi(?:@[^/]+)?$/.test(source);
|
|
75467
|
-
const local =
|
|
75656
|
+
const local = path47.isAbsolute(source) && source.replaceAll("\\", "/").endsWith("/packages/workit-pi") && object2(path47.join(source, "package.json"))?.name === "@brainervirus/workit-pi";
|
|
75468
75657
|
if (!npm && !local)
|
|
75469
75658
|
continue;
|
|
75470
75659
|
const found = classify("pi", source);
|
|
@@ -75484,7 +75673,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75484
75673
|
hostCommand("codex", [], { home, env: paths.env });
|
|
75485
75674
|
available = true;
|
|
75486
75675
|
} catch {}
|
|
75487
|
-
if (available ||
|
|
75676
|
+
if (available || existsSync22(paths.codexConfig))
|
|
75488
75677
|
throw new Error("Codex plugin inventory failed; inspect the native host before upgrading");
|
|
75489
75678
|
return;
|
|
75490
75679
|
}
|
|
@@ -75506,6 +75695,12 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75506
75695
|
installedVersion: plugin.version
|
|
75507
75696
|
});
|
|
75508
75697
|
}
|
|
75698
|
+
if (!result.some((found) => found.host === "codex") && codexRegistered(paths.codexConfig))
|
|
75699
|
+
result.push({
|
|
75700
|
+
host: "codex",
|
|
75701
|
+
selector: "@brainervirus/workit-codex",
|
|
75702
|
+
kind: "repair"
|
|
75703
|
+
});
|
|
75509
75704
|
});
|
|
75510
75705
|
guard("claude-code", () => {
|
|
75511
75706
|
for (const install of claudeWorkitInstalls(home, paths.env, null))
|
|
@@ -75517,213 +75712,24 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75517
75712
|
});
|
|
75518
75713
|
});
|
|
75519
75714
|
return result;
|
|
75520
|
-
}, piInstalledVersion = (listing, selector) => {
|
|
75521
|
-
const lines = listing.split(/\r?\n/).map((line) => line.trim());
|
|
75522
|
-
const index = lines.indexOf(selector);
|
|
75523
|
-
if (index < 0 || !lines[index + 1] || !path44.isAbsolute(lines[index + 1]))
|
|
75524
|
-
return;
|
|
75525
|
-
const found = objectOrNull(path44.join(lines[index + 1], "package.json"));
|
|
75526
|
-
return found?.name === "@brainervirus/workit-pi" ? found.version : undefined;
|
|
75527
|
-
}, versionAtLeast = (installed, latest) => {
|
|
75528
|
-
if (!/^\d+\.\d+\.\d+$/.test(installed))
|
|
75529
|
-
return false;
|
|
75530
|
-
const current = installed.split(".").map(Number);
|
|
75531
|
-
const target = latest.split(".").map(Number);
|
|
75532
|
-
for (let index = 0;index < 3; index++) {
|
|
75533
|
-
if (current[index] !== target[index])
|
|
75534
|
-
return current[index] > target[index];
|
|
75535
|
-
}
|
|
75536
|
-
return true;
|
|
75537
75715
|
}, opencodeProbe = (deps, args) => {
|
|
75538
|
-
const scratch = mkdtempSync3(
|
|
75716
|
+
const scratch = mkdtempSync3(path47.join(os17.tmpdir(), "workit-upgrade-opencode-"));
|
|
75539
75717
|
try {
|
|
75540
75718
|
return runner({
|
|
75541
75719
|
...deps,
|
|
75542
75720
|
env: {
|
|
75543
75721
|
...deps.env,
|
|
75544
|
-
XDG_DATA_HOME:
|
|
75545
|
-
XDG_STATE_HOME:
|
|
75546
|
-
XDG_CACHE_HOME:
|
|
75722
|
+
XDG_DATA_HOME: path47.join(scratch, "data"),
|
|
75723
|
+
XDG_STATE_HOME: path47.join(scratch, "state"),
|
|
75724
|
+
XDG_CACHE_HOME: path47.join(scratch, "cache")
|
|
75547
75725
|
}
|
|
75548
75726
|
})("opencode", args);
|
|
75549
75727
|
} finally {
|
|
75550
75728
|
rmSync8(scratch, { recursive: true, force: true });
|
|
75551
75729
|
}
|
|
75552
|
-
}, registryVersion = (run, name) => {
|
|
75553
|
-
const latest = run("npm", ["view", name, "version"]);
|
|
75554
|
-
const version = latest.stdout.trim();
|
|
75555
|
-
return latest.status === 0 && /^\d+\.\d+\.\d+$/.test(version) ? version : undefined;
|
|
75556
|
-
}, PROCESS_HOSTS, classifyProcess = (proc) => {
|
|
75557
|
-
if (proc.state.startsWith("Z") || proc.args.includes("<defunct>"))
|
|
75558
|
-
return null;
|
|
75559
|
-
const argv0 = proc.args.trim().split(/\s+/)[0] ?? "";
|
|
75560
|
-
const name = path44.basename(argv0.replaceAll("\\", "/")).replace(/^\[|\]$/g, "").replace(/\.exe$/i, "").toLowerCase();
|
|
75561
|
-
const host = PROCESS_HOSTS[name];
|
|
75562
|
-
if (!host)
|
|
75563
|
-
return null;
|
|
75564
|
-
if (host === "codex" && /\bapp-server\b/.test(proc.args))
|
|
75565
|
-
return /\bdaemon\s+pid-update-loop\b/.test(proc.args) ? null : { ...proc, host, kind: "daemon" };
|
|
75566
|
-
if (host === "opencode" && /\bserve\b/.test(proc.args))
|
|
75567
|
-
return { ...proc, host, kind: "daemon" };
|
|
75568
|
-
return { ...proc, host, kind: "session" };
|
|
75569
|
-
}, listProcesses = (deps) => {
|
|
75570
|
-
if (deps.processes)
|
|
75571
|
-
return deps.processes();
|
|
75572
|
-
if (deps.activeHosts)
|
|
75573
|
-
return deps.activeHosts().map((host) => ({ pid: 0, state: "S", args: host }));
|
|
75574
|
-
const run = runner(deps);
|
|
75575
|
-
if (process.platform === "win32") {
|
|
75576
|
-
const list = run("tasklist", ["/fo", "csv", "/nh"]);
|
|
75577
|
-
if (list.status !== 0)
|
|
75578
|
-
return null;
|
|
75579
|
-
return list.stdout.split(/\r?\n/).flatMap((line) => {
|
|
75580
|
-
const [image, pid] = line.split('","').map((cell) => cell.replaceAll('"', ""));
|
|
75581
|
-
return image && /^\d+$/.test(pid ?? "") ? [{ pid: Number(pid), state: "R", args: image }] : [];
|
|
75582
|
-
});
|
|
75583
|
-
}
|
|
75584
|
-
const list = run("ps", ["-eo", "pid=,stat=,args="]);
|
|
75585
|
-
if (list.status !== 0)
|
|
75586
|
-
return null;
|
|
75587
|
-
return list.stdout.split(/\r?\n/).flatMap((line) => {
|
|
75588
|
-
const match = /^\s*(\d+)\s+(\S+)\s+(.+)$/.exec(line);
|
|
75589
|
-
return match ? [{ pid: Number(match[1]), state: match[2], args: match[3] }] : [];
|
|
75590
|
-
});
|
|
75591
|
-
}, describe2 = (proc) => `pid ${proc.pid}: ${proc.args.length > 120 ? `${proc.args.slice(0, 117)}...` : proc.args}`, codexPluginRoot = (codexHome) => {
|
|
75592
|
-
const dir = path44.join(codexHome, "plugins", "cache", CODEX_MARKETPLACE, "workit");
|
|
75593
|
-
let versions = [];
|
|
75594
|
-
try {
|
|
75595
|
-
versions = readdirSync12(dir).filter((version) => /^\d+\.\d+\.\d+$/.test(version));
|
|
75596
|
-
} catch {
|
|
75597
|
-
return null;
|
|
75598
|
-
}
|
|
75599
|
-
const newest = versions.reduce((best, version) => best && versionAtLeast(best, version) ? best : version, null);
|
|
75600
|
-
return newest ? path44.join(dir, newest) : null;
|
|
75601
|
-
}, applyEntry = (entry, context) => {
|
|
75602
|
-
const { run, paths, configDir } = context;
|
|
75603
|
-
const { home, env } = paths;
|
|
75604
|
-
const fail = (reason) => ({
|
|
75605
|
-
host: entry.host,
|
|
75606
|
-
status: "failed",
|
|
75607
|
-
reason,
|
|
75608
|
-
fix: entry.fix
|
|
75609
|
-
});
|
|
75610
|
-
if (entry.host === "cursor") {
|
|
75611
|
-
const preview = {
|
|
75612
|
-
ok: true,
|
|
75613
|
-
blocked: [],
|
|
75614
|
-
preserved: [],
|
|
75615
|
-
overrides: [],
|
|
75616
|
-
platforms: ["cursor"],
|
|
75617
|
-
state: readSetupState(configDir),
|
|
75618
|
-
mutations: [
|
|
75619
|
-
{
|
|
75620
|
-
type: "install-host",
|
|
75621
|
-
platform: "cursor",
|
|
75622
|
-
path: path44.join(home, ".cursor/plugins/local/.workit-package-bootstrap"),
|
|
75623
|
-
commands: entry.commands.map((command) => ({
|
|
75624
|
-
...command,
|
|
75625
|
-
purpose: command.purpose ?? "Upgrade Cursor"
|
|
75626
|
-
}))
|
|
75627
|
-
},
|
|
75628
|
-
{ type: "install-adapter", platform: "cursor", path: paths.cursorRoot }
|
|
75629
|
-
]
|
|
75630
|
-
};
|
|
75631
|
-
const result = applySetupPreview(preview, {
|
|
75632
|
-
home,
|
|
75633
|
-
env,
|
|
75634
|
-
cwd: home,
|
|
75635
|
-
preferInstalledAdapter: true,
|
|
75636
|
-
runHostCommand: (command) => {
|
|
75637
|
-
const outcome = run(command.command, command.args);
|
|
75638
|
-
return {
|
|
75639
|
-
exitCode: outcome.status ?? 1,
|
|
75640
|
-
stdout: outcome.stdout,
|
|
75641
|
-
stderr: ""
|
|
75642
|
-
};
|
|
75643
|
-
}
|
|
75644
|
-
});
|
|
75645
|
-
const installed = objectOrNull(path44.join(paths.cursorRoot, "package.json"));
|
|
75646
|
-
if (!result.ok || installed?.version !== entry.latest)
|
|
75647
|
-
return fail("Cursor install did not verify the requested package version; inspect the installer before retrying");
|
|
75648
|
-
return {
|
|
75649
|
-
host: "cursor",
|
|
75650
|
-
status: "updated",
|
|
75651
|
-
reason: entry.repair ? `reinstalled missing plugin files (${entry.latest})` : `${entry.installedVersion ?? "?"} -> ${entry.latest}`
|
|
75652
|
-
};
|
|
75653
|
-
}
|
|
75654
|
-
for (const command of entry.commands)
|
|
75655
|
-
if (run(command.command, command.args).status !== 0)
|
|
75656
|
-
return fail(`\`${command.command} ${command.args.join(" ")}\` failed`);
|
|
75657
|
-
if (entry.host === "opencode")
|
|
75658
|
-
return {
|
|
75659
|
-
host: "opencode",
|
|
75660
|
-
status: "updated",
|
|
75661
|
-
reason: "scoped update ran; OpenCode V2 loads it live"
|
|
75662
|
-
};
|
|
75663
|
-
if (entry.host === "claude-code") {
|
|
75664
|
-
const after = claudeWorkitInstalls(home, env, null).find((install) => install.id === entry.selector)?.version;
|
|
75665
|
-
return after && after === entry.installedVersion ? {
|
|
75666
|
-
host: "claude-code",
|
|
75667
|
-
status: "current",
|
|
75668
|
-
reason: `already current (${after})`
|
|
75669
|
-
} : {
|
|
75670
|
-
host: "claude-code",
|
|
75671
|
-
status: "updated",
|
|
75672
|
-
reason: `${entry.installedVersion ?? "?"} -> ${after ?? "?"}; new sessions load it`
|
|
75673
|
-
};
|
|
75674
|
-
}
|
|
75675
|
-
const verify = entry.host === "codex" ? run("codex", ["plugin", "list", "--json"]) : run("pi", ["list"]);
|
|
75676
|
-
if (verify.status !== 0)
|
|
75677
|
-
return fail("update verification failed");
|
|
75678
|
-
if (entry.host === "codex") {
|
|
75679
|
-
let installed = [];
|
|
75680
|
-
try {
|
|
75681
|
-
installed = JSON.parse(verify.stdout).installed ?? [];
|
|
75682
|
-
} catch {}
|
|
75683
|
-
if (!installed.some((plugin) => plugin.name === "workit" && plugin.marketplaceName === CODEX_MARKETPLACE && plugin.version === entry.latest))
|
|
75684
|
-
return fail("Codex did not report the requested Workit version");
|
|
75685
|
-
}
|
|
75686
|
-
if (entry.host === "pi" && piInstalledVersion(verify.stdout, entry.selector) !== entry.latest)
|
|
75687
|
-
return fail("Pi did not report the requested Workit package version");
|
|
75688
|
-
return {
|
|
75689
|
-
host: entry.host,
|
|
75690
|
-
status: "updated",
|
|
75691
|
-
reason: `${entry.installedVersion ?? "?"} -> ${entry.latest}`
|
|
75692
|
-
};
|
|
75693
|
-
}, refreshCodexAgents = (run, codexHome) => {
|
|
75694
|
-
const root = codexPluginRoot(codexHome);
|
|
75695
|
-
const launcher = root && path44.join(root, "dist", "launch-mcp.js");
|
|
75696
|
-
if (!launcher || !existsSync20(launcher))
|
|
75697
|
-
return { ok: true, note: "" };
|
|
75698
|
-
const fix = `node ${JSON.stringify(launcher)} --install-agents`;
|
|
75699
|
-
return run("node", [launcher, "--install-agents"]).status === 0 ? { ok: true, note: "agents refreshed" } : { ok: false, note: "agent refresh failed", fix };
|
|
75700
|
-
}, applyCli = (cli, run, backup) => {
|
|
75701
|
-
const fail = (reason) => ({
|
|
75702
|
-
host: "cli",
|
|
75703
|
-
status: "failed",
|
|
75704
|
-
reason,
|
|
75705
|
-
fix: CLI_FIX
|
|
75706
|
-
});
|
|
75707
|
-
const currentRoot = run("npm", ["root", "--global"]);
|
|
75708
|
-
if (currentRoot.status !== 0 || currentRoot.stdout.trim() !== cli.root)
|
|
75709
|
-
return fail("Global npm location changed; preview again");
|
|
75710
|
-
const cliBackup = path44.join(backup, "cli-package");
|
|
75711
|
-
cpSync5(path44.join(cli.root, "@brainervirus/workit-cli"), cliBackup, {
|
|
75712
|
-
recursive: true
|
|
75713
|
-
});
|
|
75714
|
-
if (run("npm", ["install", "--global", `@brainervirus/workit-cli@${cli.latest}`]).status !== 0)
|
|
75715
|
-
return fail(`CLI update failed; preserved package at ${cliBackup}; use npm to repair or run node ${path44.join(cliBackup, "dist/index.js")}`);
|
|
75716
|
-
const installed = objectOrNull(path44.join(cli.root, "@brainervirus/workit-cli/package.json"));
|
|
75717
|
-
if (installed?.name !== "@brainervirus/workit-cli" || installed.version !== cli.latest)
|
|
75718
|
-
return fail(`CLI update did not verify the requested version; preserved package at ${cliBackup}`);
|
|
75719
|
-
return {
|
|
75720
|
-
host: "cli",
|
|
75721
|
-
status: "updated",
|
|
75722
|
-
reason: `${cli.installed} -> ${cli.latest}`
|
|
75723
|
-
};
|
|
75724
75730
|
}, planCli = (plan, run) => {
|
|
75725
75731
|
const root = run("npm", ["root", "--global"]);
|
|
75726
|
-
if (root.status !== 0 || !
|
|
75732
|
+
if (root.status !== 0 || !path47.isAbsolute(root.stdout.trim())) {
|
|
75727
75733
|
plan.skipped.push({
|
|
75728
75734
|
host: "cli",
|
|
75729
75735
|
reason: "global npm location could not be verified",
|
|
@@ -75731,9 +75737,9 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75731
75737
|
});
|
|
75732
75738
|
return;
|
|
75733
75739
|
}
|
|
75734
|
-
const packageFile =
|
|
75740
|
+
const packageFile = path47.join(root.stdout.trim(), "@brainervirus/workit-cli/package.json");
|
|
75735
75741
|
const installed = objectOrNull(packageFile);
|
|
75736
|
-
if (installed?.name !== "@brainervirus/workit-cli" || lstatSync7(
|
|
75742
|
+
if (installed?.name !== "@brainervirus/workit-cli" || lstatSync7(path47.dirname(packageFile)).isSymbolicLink()) {
|
|
75737
75743
|
plan.skipped.push({
|
|
75738
75744
|
host: "cli",
|
|
75739
75745
|
reason: "no managed global CLI install (local links preserved); use npx @brainervirus/workit-cli@latest"
|
|
@@ -75760,7 +75766,18 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75760
75766
|
host: "cli",
|
|
75761
75767
|
reason: `already current (${installed.version})`
|
|
75762
75768
|
});
|
|
75763
|
-
}
|
|
75769
|
+
};
|
|
75770
|
+
var init_plan = __esm(() => {
|
|
75771
|
+
init_registration();
|
|
75772
|
+
init_setup_state();
|
|
75773
|
+
init_host_install();
|
|
75774
|
+
init_doctor();
|
|
75775
|
+
init_support_matrix();
|
|
75776
|
+
init_shared();
|
|
75777
|
+
});
|
|
75778
|
+
|
|
75779
|
+
// packages/workit-cli/src/upgrade/report.ts
|
|
75780
|
+
var pad2 = (text) => text.padEnd(12), summary = (plan, permissions) => {
|
|
75764
75781
|
const lines = ["Workit upgrade plan:"];
|
|
75765
75782
|
if (plan.cli)
|
|
75766
75783
|
lines.push(` ${pad2("cli")}update ${plan.cli.installed} -> ${plan.cli.latest}`);
|
|
@@ -75797,29 +75814,8 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75797
75814
|
}
|
|
75798
75815
|
await Promise.resolve().then(() => init_prompt());
|
|
75799
75816
|
return /^y(?:es)?$/i.test((await askLine(question)).trim());
|
|
75800
|
-
}
|
|
75801
|
-
|
|
75802
|
-
var init_upgrade = __esm(() => {
|
|
75803
|
-
init_package();
|
|
75804
|
-
init_registration();
|
|
75805
|
-
init_setup_state();
|
|
75806
|
-
init_host_install();
|
|
75807
|
-
init_setup();
|
|
75808
|
-
init_doctor();
|
|
75809
|
-
init_support_matrix();
|
|
75810
|
-
init_safe_write();
|
|
75811
|
-
init_host_permissions();
|
|
75812
|
-
LAUNCH_HOSTS = ["opencode", "cursor", "codex", "pi"];
|
|
75813
|
-
HOSTS2 = [...LAUNCH_HOSTS, "claude-code"];
|
|
75814
|
-
LIVE_HOSTS = new Set(["opencode", "claude-code"]);
|
|
75815
|
-
OPENCODE_UPDATE = `opencode plugin update ${OPENCODE_PACKAGE}`;
|
|
75816
|
-
PROCESS_HOSTS = {
|
|
75817
|
-
claude: "claude-code",
|
|
75818
|
-
codex: "codex",
|
|
75819
|
-
cursor: "cursor",
|
|
75820
|
-
opencode: "opencode",
|
|
75821
|
-
pi: "pi"
|
|
75822
|
-
};
|
|
75817
|
+
};
|
|
75818
|
+
var init_report = __esm(() => {
|
|
75823
75819
|
LABEL = {
|
|
75824
75820
|
updated: "updated",
|
|
75825
75821
|
current: "already current",
|
|
@@ -75828,6 +75824,191 @@ var init_upgrade = __esm(() => {
|
|
|
75828
75824
|
};
|
|
75829
75825
|
});
|
|
75830
75826
|
|
|
75827
|
+
// packages/workit-cli/src/upgrade.ts
|
|
75828
|
+
import { spawnSync as spawnSync17 } from "node:child_process";
|
|
75829
|
+
async function runUpgradeCommand(argv, deps = {}) {
|
|
75830
|
+
const out = deps.out ?? process.stdout;
|
|
75831
|
+
const flags = new Set(argv);
|
|
75832
|
+
const unknown = argv.filter((arg) => !["--apply", "--confirm", "--json", "--cli", "--preview", "--yes"].includes(arg) && !arg.startsWith("--hosts="));
|
|
75833
|
+
const hostFlag = argv.find((arg) => arg.startsWith("--hosts="))?.slice(8);
|
|
75834
|
+
const raw = hostFlag === "none" ? [] : hostFlag?.split(",") ?? HOSTS2;
|
|
75835
|
+
if (unknown.length || raw.some((host) => !HOSTS2.includes(host)) || flags.has("--preview") && (flags.has("--apply") || flags.has("--yes"))) {
|
|
75836
|
+
out.write(USAGE3);
|
|
75837
|
+
return 2;
|
|
75838
|
+
}
|
|
75839
|
+
if (flags.has("--apply") && !flags.has("--confirm")) {
|
|
75840
|
+
out.write(`Apply requires --confirm after reviewing the upgrade preview.
|
|
75841
|
+
`);
|
|
75842
|
+
return 2;
|
|
75843
|
+
}
|
|
75844
|
+
const legacy = flags.has("--apply");
|
|
75845
|
+
const json = flags.has("--json") || legacy;
|
|
75846
|
+
const run = runner(deps);
|
|
75847
|
+
const plan = previewUpgrade(raw, deps);
|
|
75848
|
+
if (hostFlag === undefined || flags.has("--cli"))
|
|
75849
|
+
planCli(plan, run);
|
|
75850
|
+
plan.ok = plan.blocked.length === 0 && plan.failed.length === 0;
|
|
75851
|
+
const { home, env } = upgradePaths(deps);
|
|
75852
|
+
const permissions = planHostPermissions({
|
|
75853
|
+
hosts: raw,
|
|
75854
|
+
refreshOnly: true,
|
|
75855
|
+
shell: false,
|
|
75856
|
+
home,
|
|
75857
|
+
env
|
|
75858
|
+
});
|
|
75859
|
+
const permissionPreview = {
|
|
75860
|
+
changes: permissions.changes.map((c) => ({
|
|
75861
|
+
host: c.host,
|
|
75862
|
+
file: c.file,
|
|
75863
|
+
diff: permissionDiff(c)
|
|
75864
|
+
})),
|
|
75865
|
+
...permissions.refused ? { refused: permissions.refused } : {}
|
|
75866
|
+
};
|
|
75867
|
+
const withPermissions = (value) => permissions.changes.length ? { ...value, permissions: permissionPreview } : value;
|
|
75868
|
+
const applyCommand = `workit upgrade ${[...hostFlag === undefined ? [] : [`--hosts=${hostFlag}`], ...flags.has("--cli") ? ["--cli"] : [], "--yes"].join(" ")}`;
|
|
75869
|
+
const nothingChanged = `preview only; nothing changed. Apply with: ${applyCommand}
|
|
75870
|
+
`;
|
|
75871
|
+
if (json && !legacy && !flags.has("--yes")) {
|
|
75872
|
+
out.write(JSON.stringify(withPermissions(plan), null, 2) + `
|
|
75873
|
+
`);
|
|
75874
|
+
return plan.blocked.length ? 1 : 0;
|
|
75875
|
+
}
|
|
75876
|
+
if (!json)
|
|
75877
|
+
out.write(summary(plan, permissions.changes));
|
|
75878
|
+
if (flags.has("--preview")) {
|
|
75879
|
+
out.write(nothingChanged);
|
|
75880
|
+
return plan.blocked.length ? 1 : 0;
|
|
75881
|
+
}
|
|
75882
|
+
if (plan.blocked.length) {
|
|
75883
|
+
out.write(`Upgrade blocked: ${plan.blocked.join("; ")}
|
|
75884
|
+
Nothing changed.
|
|
75885
|
+
`);
|
|
75886
|
+
return 1;
|
|
75887
|
+
}
|
|
75888
|
+
const work = plan.entries.length + plan.migrations.length + (plan.cli ? 1 : 0) + permissions.changes.length;
|
|
75889
|
+
if (work > 0 && !flags.has("--yes") && !legacy) {
|
|
75890
|
+
const confirmed = await (deps.confirm ?? ((q) => askConfirm(q, out)))("Apply this upgrade? [y/N] ");
|
|
75891
|
+
if (!confirmed) {
|
|
75892
|
+
out.write(nothingChanged);
|
|
75893
|
+
return 0;
|
|
75894
|
+
}
|
|
75895
|
+
}
|
|
75896
|
+
if (json)
|
|
75897
|
+
for (const warning of plan.warnings ?? [])
|
|
75898
|
+
out.write(`warning: ${warning}
|
|
75899
|
+
`);
|
|
75900
|
+
const result = applyUpgrade(plan, deps);
|
|
75901
|
+
let permissionsOk = true;
|
|
75902
|
+
let written;
|
|
75903
|
+
if (permissions.changes.length && !permissions.refused && !result.error?.startsWith("configuration changed")) {
|
|
75904
|
+
written = applyHostPermissions(permissions, { home, env });
|
|
75905
|
+
permissionsOk = written.every((entry) => entry.status === "written");
|
|
75906
|
+
for (const entry of written)
|
|
75907
|
+
result.hosts.push({
|
|
75908
|
+
host: entry.host,
|
|
75909
|
+
status: entry.status === "written" ? "updated" : "failed",
|
|
75910
|
+
reason: `permission block ${entry.status === "written" ? "refreshed" : entry.status} in ${entry.file}`,
|
|
75911
|
+
...entry.status === "written" ? {} : { fix: `workit setup --hosts=${entry.host}` }
|
|
75912
|
+
});
|
|
75913
|
+
}
|
|
75914
|
+
const failed = !result.ok || !permissionsOk;
|
|
75915
|
+
const cliVersion = result.hosts.some((h) => h.host === "cli" && h.status === "updated") ? plan.cli.latest : package_default.version;
|
|
75916
|
+
const report = (deps.doctor ?? ((version) => runDoctor({ home, env, cliVersion: version, only: "upgrade" })))(cliVersion);
|
|
75917
|
+
const left = report.checks.filter((check) => check.status === "warn" || check.status === "fail");
|
|
75918
|
+
if (json) {
|
|
75919
|
+
out.write(JSON.stringify({
|
|
75920
|
+
...result,
|
|
75921
|
+
ok: !failed,
|
|
75922
|
+
...written ? { permissions: { changes: permissionPreview.changes, written } } : permissions.refused ? { permissions: permissionPreview } : {},
|
|
75923
|
+
doctor: { clean: left.length === 0, left }
|
|
75924
|
+
}, null, 2) + `
|
|
75925
|
+
`);
|
|
75926
|
+
return failed ? 1 : 0;
|
|
75927
|
+
}
|
|
75928
|
+
if (result.error && result.hosts.every((h) => h.status !== "failed"))
|
|
75929
|
+
out.write(`Upgrade stopped: ${result.error}
|
|
75930
|
+
`);
|
|
75931
|
+
out.write(table(result.hosts));
|
|
75932
|
+
if (permissions.refused)
|
|
75933
|
+
out.write(`permissions: not refreshed: ${permissions.refused}
|
|
75934
|
+
`);
|
|
75935
|
+
if (result.backup)
|
|
75936
|
+
out.write(`Backup: ${result.backup}
|
|
75937
|
+
`);
|
|
75938
|
+
out.write(left.length === 0 ? `Verified: workit doctor is clean for versions, assets, agents and permissions.
|
|
75939
|
+
` : `Left after upgrade (workit doctor):
|
|
75940
|
+
${left.map((check) => ` ${check.id}: ${check.detail}${check.fix ? `
|
|
75941
|
+
fix: ${check.fix}` : ""}`).join(`
|
|
75942
|
+
`)}
|
|
75943
|
+
`);
|
|
75944
|
+
return failed ? 1 : 0;
|
|
75945
|
+
}
|
|
75946
|
+
async function runLaunchCommand(argv, deps = {}) {
|
|
75947
|
+
const [host, ...args] = argv;
|
|
75948
|
+
if (!LAUNCH_HOSTS.includes(host)) {
|
|
75949
|
+
(deps.out ?? process.stdout).write(`Usage: workit launch <opencode|cursor|codex|pi> [--auto-upgrade] [-- host arguments]
|
|
75950
|
+
`);
|
|
75951
|
+
return 2;
|
|
75952
|
+
}
|
|
75953
|
+
const auto = args[0] === "--auto-upgrade";
|
|
75954
|
+
const rest = auto ? args.slice(1) : args;
|
|
75955
|
+
const hostArgs = rest[0] === "--" ? rest.slice(1) : rest;
|
|
75956
|
+
const { home, env } = upgradePaths(deps);
|
|
75957
|
+
let launch;
|
|
75958
|
+
if (!deps.run) {
|
|
75959
|
+
try {
|
|
75960
|
+
launch = hostCommand(host, hostArgs, { home, env });
|
|
75961
|
+
} catch (error) {
|
|
75962
|
+
(deps.out ?? process.stderr).write(`${error instanceof Error ? error.message : "Host executable unavailable"}
|
|
75963
|
+
`);
|
|
75964
|
+
return 1;
|
|
75965
|
+
}
|
|
75966
|
+
}
|
|
75967
|
+
if (auto) {
|
|
75968
|
+
const plan = previewUpgrade([host], deps);
|
|
75969
|
+
const reasons = [...plan.blocked, ...plan.failed.map((entry) => entry.reason)];
|
|
75970
|
+
if (plan.ok) {
|
|
75971
|
+
for (const skipped of plan.skipped)
|
|
75972
|
+
(deps.out ?? process.stderr).write(`${skipped.host}: ${skipped.reason}${skipped.fix ? ` (run: ${skipped.fix})` : ""}
|
|
75973
|
+
`);
|
|
75974
|
+
const result = applyUpgrade(plan, deps);
|
|
75975
|
+
if (!result.ok) {
|
|
75976
|
+
(deps.out ?? process.stdout).write(`${result.error}
|
|
75977
|
+
`);
|
|
75978
|
+
return 1;
|
|
75979
|
+
}
|
|
75980
|
+
} else if (plan.blocked.length === 0 && reasons.every((reason) => reason.includes("registry version unavailable"))) {
|
|
75981
|
+
(deps.out ?? process.stderr).write(`Upgrade unavailable: ${reasons.join("; ")}. Starting the unchanged host.
|
|
75982
|
+
`);
|
|
75983
|
+
} else {
|
|
75984
|
+
(deps.out ?? process.stderr).write(`Upgrade blocked: ${reasons.join("; ")}
|
|
75985
|
+
`);
|
|
75986
|
+
return 1;
|
|
75987
|
+
}
|
|
75988
|
+
}
|
|
75989
|
+
if (deps.run)
|
|
75990
|
+
return deps.run(host, hostArgs).status ?? 1;
|
|
75991
|
+
return spawnSync17(launch.command, launch.args, {
|
|
75992
|
+
stdio: "inherit",
|
|
75993
|
+
env
|
|
75994
|
+
}).status ?? 1;
|
|
75995
|
+
}
|
|
75996
|
+
var USAGE3 = `Usage: workit upgrade [--hosts=opencode,cursor,codex,pi,claude-code|none] [--cli] [--preview | --yes | --apply --confirm] [--json]
|
|
75997
|
+
`;
|
|
75998
|
+
var init_upgrade = __esm(() => {
|
|
75999
|
+
init_package();
|
|
76000
|
+
init_host_install();
|
|
76001
|
+
init_doctor();
|
|
76002
|
+
init_host_permissions();
|
|
76003
|
+
init_apply();
|
|
76004
|
+
init_plan();
|
|
76005
|
+
init_report();
|
|
76006
|
+
init_shared();
|
|
76007
|
+
init_apply();
|
|
76008
|
+
init_plan();
|
|
76009
|
+
init_processes();
|
|
76010
|
+
});
|
|
76011
|
+
|
|
75831
76012
|
// packages/workit-cli/src/verbs/upgrade.ts
|
|
75832
76013
|
var exports_upgrade = {};
|
|
75833
76014
|
__export(exports_upgrade, {
|
|
@@ -75851,7 +76032,7 @@ var init_launch = __esm(() => {
|
|
|
75851
76032
|
// packages/workit-core/src/knowledge.ts
|
|
75852
76033
|
import { spawnSync as spawnSync18 } from "node:child_process";
|
|
75853
76034
|
import fs20 from "node:fs";
|
|
75854
|
-
import
|
|
76035
|
+
import path48 from "node:path";
|
|
75855
76036
|
function lintKnowledge(root) {
|
|
75856
76037
|
const seen = new Set;
|
|
75857
76038
|
const unreadable = [];
|
|
@@ -75955,7 +76136,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
75955
76136
|
const end = lines.indexOf("---", 1);
|
|
75956
76137
|
return end === -1 ? lines : [...lines.slice(0, end + 1).map(() => ""), ...lines.slice(end + 1)];
|
|
75957
76138
|
}, read = (root, file) => {
|
|
75958
|
-
const full =
|
|
76139
|
+
const full = path48.join(root, file);
|
|
75959
76140
|
try {
|
|
75960
76141
|
fs20.lstatSync(full);
|
|
75961
76142
|
} catch {
|
|
@@ -75996,7 +76177,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
75996
76177
|
}
|
|
75997
76178
|
}, brokenLinks = (root, doc, tracked) => {
|
|
75998
76179
|
const findings = [];
|
|
75999
|
-
const base =
|
|
76180
|
+
const base = path48.dirname(path48.join(root, doc.file));
|
|
76000
76181
|
const missing = (target, line, how) => findings.push({
|
|
76001
76182
|
rule: "broken-link",
|
|
76002
76183
|
file: doc.file,
|
|
@@ -76015,7 +76196,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
76015
76196
|
const local = localTarget(target);
|
|
76016
76197
|
if (!local)
|
|
76017
76198
|
continue;
|
|
76018
|
-
const resolved = local.startsWith("/") ?
|
|
76199
|
+
const resolved = local.startsWith("/") ? path48.join(root, local) : path48.resolve(base, local);
|
|
76019
76200
|
if (!exists2(resolved))
|
|
76020
76201
|
missing(target, index + 1, "link");
|
|
76021
76202
|
}
|
|
@@ -76025,9 +76206,9 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
76025
76206
|
continue;
|
|
76026
76207
|
const relative = /^\.\.?\//.test(candidate);
|
|
76027
76208
|
const first = candidate.split("/")[0];
|
|
76028
|
-
if (!relative && !(tracked ? tracked.has(first) : exists2(
|
|
76209
|
+
if (!relative && !(tracked ? tracked.has(first) : exists2(path48.join(root, first))))
|
|
76029
76210
|
continue;
|
|
76030
|
-
const resolved = relative ?
|
|
76211
|
+
const resolved = relative ? path48.resolve(base, candidate) : path48.join(root, candidate);
|
|
76031
76212
|
if (!exists2(resolved))
|
|
76032
76213
|
missing(span, index + 1, "pointer");
|
|
76033
76214
|
}
|
|
@@ -76350,10 +76531,10 @@ var init_redact = __esm(() => {
|
|
|
76350
76531
|
|
|
76351
76532
|
// packages/workit-core/src/checks.ts
|
|
76352
76533
|
import { spawn, spawnSync as spawnSync19 } from "node:child_process";
|
|
76353
|
-
import { createHash as
|
|
76534
|
+
import { createHash as createHash17 } from "node:crypto";
|
|
76354
76535
|
import fs21 from "node:fs";
|
|
76355
|
-
import
|
|
76356
|
-
import
|
|
76536
|
+
import os18 from "node:os";
|
|
76537
|
+
import path49 from "node:path";
|
|
76357
76538
|
import { StringDecoder } from "node:string_decoder";
|
|
76358
76539
|
function tailLines(text, lines = TAIL_LINES) {
|
|
76359
76540
|
const all = text.replace(/\r\n?/gu, `
|
|
@@ -76473,7 +76654,7 @@ function planSpawn(argv, options) {
|
|
|
76473
76654
|
return { file: argv[0], args: [], verbatim: false, shell: true };
|
|
76474
76655
|
if (options.platform !== "win32")
|
|
76475
76656
|
return { file: argv[0], args: argv.slice(1), verbatim: false, shell: false };
|
|
76476
|
-
const win =
|
|
76657
|
+
const win = path49.win32;
|
|
76477
76658
|
const isFile = options.isFile ?? ((file) => {
|
|
76478
76659
|
try {
|
|
76479
76660
|
return fs21.statSync(file).isFile();
|
|
@@ -76558,7 +76739,7 @@ function runCheckCommand(argv, options) {
|
|
|
76558
76739
|
`);
|
|
76559
76740
|
redactor.end();
|
|
76560
76741
|
resolve({
|
|
76561
|
-
exitCode: spawnError ? 127 : code !== null ? code : 128 + (signal ?
|
|
76742
|
+
exitCode: spawnError ? 127 : code !== null ? code : 128 + (signal ? os18.constants.signals[signal] ?? 1 : 1),
|
|
76562
76743
|
signal: signal ?? null,
|
|
76563
76744
|
timedOut,
|
|
76564
76745
|
durationMs: Date.now() - started,
|
|
@@ -76635,10 +76816,10 @@ function runCheckCommand(argv, options) {
|
|
|
76635
76816
|
function storeLog(storeRoot, log) {
|
|
76636
76817
|
const digest = logDigest(log);
|
|
76637
76818
|
const ref = `blobs/logs/${digest.slice("sha256:".length)}.log`;
|
|
76638
|
-
const file =
|
|
76819
|
+
const file = path49.join(storeRoot, ref);
|
|
76639
76820
|
try {
|
|
76640
76821
|
if (!fs21.existsSync(file)) {
|
|
76641
|
-
fs21.mkdirSync(
|
|
76822
|
+
fs21.mkdirSync(path49.dirname(file), { recursive: true });
|
|
76642
76823
|
const temp = `${file}.${process.pid}.${Date.now()}.tmp`;
|
|
76643
76824
|
fs21.writeFileSync(temp, log, { mode: 384 });
|
|
76644
76825
|
fs21.renameSync(temp, file);
|
|
@@ -76651,7 +76832,7 @@ function storeLog(storeRoot, log) {
|
|
|
76651
76832
|
function pruneCheckLogs(storeRoot, options = {}) {
|
|
76652
76833
|
const limits = { ...LOG_RETENTION, ...options.retention };
|
|
76653
76834
|
const now = options.now ?? Date.now();
|
|
76654
|
-
const dir =
|
|
76835
|
+
const dir = path49.join(storeRoot, "blobs", "logs");
|
|
76655
76836
|
const report = { removed: 0, removedBytes: 0, kept: 0 };
|
|
76656
76837
|
let names;
|
|
76657
76838
|
try {
|
|
@@ -76661,7 +76842,7 @@ function pruneCheckLogs(storeRoot, options = {}) {
|
|
|
76661
76842
|
}
|
|
76662
76843
|
const files = names.flatMap((name) => {
|
|
76663
76844
|
try {
|
|
76664
|
-
const stat = fs21.statSync(
|
|
76845
|
+
const stat = fs21.statSync(path49.join(dir, name));
|
|
76665
76846
|
return stat.isFile() ? [{ name, size: stat.size, mtimeMs: stat.mtimeMs }] : [];
|
|
76666
76847
|
} catch {
|
|
76667
76848
|
return [];
|
|
@@ -76680,7 +76861,7 @@ function pruneCheckLogs(storeRoot, options = {}) {
|
|
|
76680
76861
|
continue;
|
|
76681
76862
|
if (!options.dryRun)
|
|
76682
76863
|
try {
|
|
76683
|
-
fs21.rmSync(
|
|
76864
|
+
fs21.rmSync(path49.join(dir, file.name), { force: true });
|
|
76684
76865
|
} catch {
|
|
76685
76866
|
continue;
|
|
76686
76867
|
}
|
|
@@ -76689,7 +76870,7 @@ function pruneCheckLogs(storeRoot, options = {}) {
|
|
|
76689
76870
|
}
|
|
76690
76871
|
return report;
|
|
76691
76872
|
}
|
|
76692
|
-
var MAX_LOG_BYTES, TAIL_LINES = 80, MAX_LINE_CHARS = 400, redactLog = (text) => redactText(text), PEM_BEGIN, PEM_END, BATCH_BYTES, MAX_PENDING, PEM_BODY, MAX_KEY_LINES = 4096, MAX_KEY_BYTES, CMD_META, DRAIN_MS = 250, FORWARDED_SIGNALS, logDigest = (log) => `sha256:${
|
|
76873
|
+
var MAX_LOG_BYTES, TAIL_LINES = 80, MAX_LINE_CHARS = 400, redactLog = (text) => redactText(text), PEM_BEGIN, PEM_END, BATCH_BYTES, MAX_PENDING, PEM_BODY, MAX_KEY_LINES = 4096, MAX_KEY_BYTES, CMD_META, DRAIN_MS = 250, FORWARDED_SIGNALS, logDigest = (log) => `sha256:${createHash17("sha256").update(log).digest("hex")}`, LOG_RETENTION;
|
|
76693
76874
|
var init_checks3 = __esm(() => {
|
|
76694
76875
|
init_redact();
|
|
76695
76876
|
MAX_LOG_BYTES = 2 * 1024 * 1024;
|
|
@@ -76953,7 +77134,7 @@ __export(exports_workspace, {
|
|
|
76953
77134
|
run: () => run11,
|
|
76954
77135
|
runWorkspace: () => runWorkspace
|
|
76955
77136
|
});
|
|
76956
|
-
import { copyFileSync as copyFileSync7, existsSync as
|
|
77137
|
+
import { copyFileSync as copyFileSync7, existsSync as existsSync23 } from "node:fs";
|
|
76957
77138
|
function list2(argv, io) {
|
|
76958
77139
|
if (argv.length)
|
|
76959
77140
|
return usage3(io, `unexpected argument ${argv[0]}`);
|
|
@@ -77163,7 +77344,7 @@ usage: ${USAGE5}`)), load = (io) => {
|
|
|
77163
77344
|
return { ok: false, error: `${current.path} changed; retry` };
|
|
77164
77345
|
let backup = null;
|
|
77165
77346
|
try {
|
|
77166
|
-
if (
|
|
77347
|
+
if (existsSync23(current.path)) {
|
|
77167
77348
|
backup = `${current.path}.bak`;
|
|
77168
77349
|
copyFileSync7(current.path, backup);
|
|
77169
77350
|
}
|
|
@@ -77231,12 +77412,12 @@ var init_workspace = __esm(() => {
|
|
|
77231
77412
|
|
|
77232
77413
|
// packages/workit-core/src/core/heavy-rules.ts
|
|
77233
77414
|
import fs22 from "node:fs";
|
|
77234
|
-
import
|
|
77415
|
+
import path50 from "node:path";
|
|
77235
77416
|
function gitTop(cwd) {
|
|
77236
|
-
for (let dir =
|
|
77237
|
-
if (fs22.existsSync(
|
|
77417
|
+
for (let dir = path50.resolve(cwd);; dir = path50.dirname(dir)) {
|
|
77418
|
+
if (fs22.existsSync(path50.join(dir, ".git")))
|
|
77238
77419
|
return dir;
|
|
77239
|
-
if (
|
|
77420
|
+
if (path50.dirname(dir) === dir)
|
|
77240
77421
|
return null;
|
|
77241
77422
|
}
|
|
77242
77423
|
}
|
|
@@ -77277,19 +77458,19 @@ var init_heavy_rules = () => {};
|
|
|
77277
77458
|
|
|
77278
77459
|
// packages/workit-core/src/core/heavy.ts
|
|
77279
77460
|
import fs23 from "node:fs";
|
|
77280
|
-
import
|
|
77281
|
-
import
|
|
77461
|
+
import os19 from "node:os";
|
|
77462
|
+
import path51 from "node:path";
|
|
77282
77463
|
function stateDir2(env, platform = process.platform) {
|
|
77283
77464
|
if (env.WORKFLOW_TOOLKIT_STATE)
|
|
77284
77465
|
return env.WORKFLOW_TOOLKIT_STATE;
|
|
77285
77466
|
if (env.XDG_STATE_HOME)
|
|
77286
|
-
return
|
|
77287
|
-
const home = env.HOME ||
|
|
77467
|
+
return path51.join(env.XDG_STATE_HOME, "workit");
|
|
77468
|
+
const home = env.HOME || os19.homedir();
|
|
77288
77469
|
if (platform === "darwin")
|
|
77289
|
-
return
|
|
77470
|
+
return path51.join(home, "Library", "Application Support", "workit");
|
|
77290
77471
|
if (platform === "win32")
|
|
77291
|
-
return
|
|
77292
|
-
return
|
|
77472
|
+
return path51.join(env.LOCALAPPDATA ?? path51.join(home, "AppData", "Local"), "workit");
|
|
77473
|
+
return path51.join(home, ".local", "state", "workit");
|
|
77293
77474
|
}
|
|
77294
77475
|
function positional(words, from, values = PM_VALUES) {
|
|
77295
77476
|
let index = from;
|
|
@@ -77429,7 +77610,7 @@ function machinePatterns(env) {
|
|
|
77429
77610
|
return isRecord8(value) ? stringList2(value.patterns) : [];
|
|
77430
77611
|
}
|
|
77431
77612
|
function repoPatterns(cwd) {
|
|
77432
|
-
return repoHeavyCommands(gitTop(cwd) ??
|
|
77613
|
+
return repoHeavyCommands(gitTop(cwd) ?? path51.resolve(cwd));
|
|
77433
77614
|
}
|
|
77434
77615
|
function heavyLines(lines, options) {
|
|
77435
77616
|
const found = [];
|
|
@@ -77508,7 +77689,7 @@ function leaseRewrite(command) {
|
|
|
77508
77689
|
return null;
|
|
77509
77690
|
return `${prefix}workit check --heavy -- ${rest}`;
|
|
77510
77691
|
}
|
|
77511
|
-
var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) =>
|
|
77692
|
+
var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) => path51.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) => {
|
|
77512
77693
|
try {
|
|
77513
77694
|
return JSON.parse(fs23.readFileSync(file, "utf8"));
|
|
77514
77695
|
} catch {
|
|
@@ -77654,8 +77835,8 @@ var init_heavy = __esm(() => {
|
|
|
77654
77835
|
// packages/workit-core/src/core/resources.ts
|
|
77655
77836
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
77656
77837
|
import fs24 from "node:fs";
|
|
77657
|
-
import
|
|
77658
|
-
import
|
|
77838
|
+
import os20 from "node:os";
|
|
77839
|
+
import path52 from "node:path";
|
|
77659
77840
|
function memoryValue(value, host) {
|
|
77660
77841
|
const text = typeof value === "number" ? String(value) : typeof value === "string" ? value : "";
|
|
77661
77842
|
const percent = PERCENT.exec(text.trim());
|
|
@@ -77836,7 +78017,7 @@ function tryOnce(options, record, reclaimed) {
|
|
|
77836
78017
|
const text = `${JSON.stringify(record)}
|
|
77837
78018
|
`;
|
|
77838
78019
|
for (let slot = 0;slot < options.slots; slot += 1) {
|
|
77839
|
-
const file =
|
|
78020
|
+
const file = path52.join(options.dir, `slot-${slot}.json`);
|
|
77840
78021
|
for (let attempt = 0;attempt < 2; attempt += 1) {
|
|
77841
78022
|
try {
|
|
77842
78023
|
const fd = fs24.openSync(file, "wx", 384);
|
|
@@ -77961,7 +78142,7 @@ function heldLease(dir, id, options = {}) {
|
|
|
77961
78142
|
for (const name of names) {
|
|
77962
78143
|
if (!/^slot-\d+\.json$/u.test(name))
|
|
77963
78144
|
continue;
|
|
77964
|
-
const lease = parseLease(readText5(
|
|
78145
|
+
const lease = parseLease(readText5(path52.join(dir, name)));
|
|
77965
78146
|
if (lease?.id === id && !staleReason(lease, options.probe) && (options.ancestor ?? isAncestor)(lease.pid))
|
|
77966
78147
|
return lease;
|
|
77967
78148
|
}
|
|
@@ -78016,10 +78197,10 @@ async function runScoped(run, wrapper, sinks) {
|
|
|
78016
78197
|
}
|
|
78017
78198
|
function firstNotice(env, session, key, now = Date.now()) {
|
|
78018
78199
|
const id = (session ?? `ppid-${process.ppid}`).replace(/[^A-Za-z0-9_.-]/gu, "_").slice(0, 120);
|
|
78019
|
-
const dir =
|
|
78200
|
+
const dir = path52.join(stateDir2(env), "notices");
|
|
78020
78201
|
try {
|
|
78021
78202
|
fs24.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
78022
|
-
fs24.writeFileSync(
|
|
78203
|
+
fs24.writeFileSync(path52.join(dir, `${key}-${id}`), `${new Date(now).toISOString()}
|
|
78023
78204
|
`, {
|
|
78024
78205
|
flag: "wx",
|
|
78025
78206
|
mode: 384
|
|
@@ -78029,7 +78210,7 @@ function firstNotice(env, session, key, now = Date.now()) {
|
|
|
78029
78210
|
}
|
|
78030
78211
|
try {
|
|
78031
78212
|
for (const name of fs24.readdirSync(dir)) {
|
|
78032
|
-
const file =
|
|
78213
|
+
const file = path52.join(dir, name);
|
|
78033
78214
|
if (now - fs24.statSync(file).mtimeMs > NOTICE_TTL_MS)
|
|
78034
78215
|
fs24.rmSync(file, { force: true });
|
|
78035
78216
|
}
|
|
@@ -78039,7 +78220,7 @@ function firstNotice(env, session, key, now = Date.now()) {
|
|
|
78039
78220
|
function leaseSlots(dir, slots, probe = {}) {
|
|
78040
78221
|
const states = [];
|
|
78041
78222
|
for (let slot = 0;slot < slots; slot += 1) {
|
|
78042
|
-
const lease = parseLease(readText5(
|
|
78223
|
+
const lease = parseLease(readText5(path52.join(dir, `slot-${slot}.json`)));
|
|
78043
78224
|
states.push({
|
|
78044
78225
|
slot,
|
|
78045
78226
|
holder: lease ? holderOf(lease) : null,
|
|
@@ -78049,15 +78230,15 @@ function leaseSlots(dir, slots, probe = {}) {
|
|
|
78049
78230
|
return states;
|
|
78050
78231
|
}
|
|
78051
78232
|
var DEFAULT_HEAVY_CHECKS, DEFAULT_SLOTS = 1, DEFAULT_WAIT_S = 600, DEFAULT_MEMORY_SHARE = 0.4, DEFAULT_CPU_SHARE = 0.7, MAX_SLOTS = 64, UNREADABLE_TTL_MS = 30000, GUARD_TTL_MS = 30000, hostShape = () => ({
|
|
78052
|
-
totalMemBytes:
|
|
78053
|
-
cpus: Math.max(1,
|
|
78054
|
-
}), isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), SIZE, PERCENT, UNITS, leaseDir = (env) =>
|
|
78233
|
+
totalMemBytes: os20.totalmem(),
|
|
78234
|
+
cpus: Math.max(1, os20.availableParallelism?.() ?? os20.cpus().length)
|
|
78235
|
+
}), isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), SIZE, PERCENT, UNITS, leaseDir = (env) => path52.join(stateDir2(env), "leases"), readText5 = (file) => {
|
|
78055
78236
|
try {
|
|
78056
78237
|
return fs24.readFileSync(file, "utf8");
|
|
78057
78238
|
} catch {
|
|
78058
78239
|
return null;
|
|
78059
78240
|
}
|
|
78060
|
-
}, bootId = () => readText5("/proc/sys/kernel/random/boot_id")?.trim() || null, bootTime = () => Math.round((Date.now() -
|
|
78241
|
+
}, bootId = () => readText5("/proc/sys/kernel/random/boot_id")?.trim() || null, bootTime = () => Math.round((Date.now() - os20.uptime() * 1000) / 1000) * 1000, BOOT_SLACK_MS = 120000, statFields = (pid) => {
|
|
78061
78242
|
const stat = readText5(`/proc/${pid}/stat`);
|
|
78062
78243
|
return stat ? stat.slice(stat.lastIndexOf(")") + 2).split(" ") : null;
|
|
78063
78244
|
}, processStart = (pid) => statFields(pid)?.[19] ?? null, pidAlive2 = (pid) => {
|
|
@@ -78106,8 +78287,8 @@ __export(exports_check, {
|
|
|
78106
78287
|
run: () => run12,
|
|
78107
78288
|
workspaceResources: () => workspaceResources
|
|
78108
78289
|
});
|
|
78109
|
-
import
|
|
78110
|
-
import
|
|
78290
|
+
import os21 from "node:os";
|
|
78291
|
+
import path53 from "node:path";
|
|
78111
78292
|
function parse6(argv) {
|
|
78112
78293
|
const split = argv.indexOf("--");
|
|
78113
78294
|
const head = split >= 0 ? argv.slice(0, split) : [...argv];
|
|
@@ -78309,7 +78490,7 @@ function hostToolWaitCapMs(env) {
|
|
|
78309
78490
|
}
|
|
78310
78491
|
async function workspaceResources(io) {
|
|
78311
78492
|
const env = io.env;
|
|
78312
|
-
const dir = env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ??
|
|
78493
|
+
const dir = env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path53.join(env.XDG_CONFIG_HOME || path53.join(env.HOME || os21.homedir(), ".config"), "workit");
|
|
78313
78494
|
try {
|
|
78314
78495
|
await Promise.resolve().then(() => init_workspaces());
|
|
78315
78496
|
const workspace = resolveWorkspaceFrom(io.cwd, dir, env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined);
|
|
@@ -78428,7 +78609,7 @@ async function run12(argv, io) {
|
|
|
78428
78609
|
if (options.shell && command.length !== 1)
|
|
78429
78610
|
return emit(io, fail2("invalid_input", '--shell takes the command as one string: workit check --shell -- "<cmd>"'));
|
|
78430
78611
|
}
|
|
78431
|
-
const relCwd = posix(
|
|
78612
|
+
const relCwd = posix(path53.relative(top, runCwd));
|
|
78432
78613
|
const configured = !options.shell && matchesNamedCheck(config, name, command, relCwd);
|
|
78433
78614
|
const shadowed = !configured && name !== null ? config.checks.find((item) => item.name === name) : undefined;
|
|
78434
78615
|
if (shadowed)
|
|
@@ -78490,7 +78671,7 @@ async function run12(argv, io) {
|
|
|
78490
78671
|
const modifiedWorktree = key.tree !== null && treeAfter !== key.tree;
|
|
78491
78672
|
const store = storeRoot(io.cwd);
|
|
78492
78673
|
const blob = store.ok ? storeLog(store.value.root, result.log) : null;
|
|
78493
|
-
const logPath = store.ok && blob ?
|
|
78674
|
+
const logPath = store.ok && blob ? path53.join(store.value.root, blob.ref) : null;
|
|
78494
78675
|
const tail = tailLines(result.log, TAIL_LINES);
|
|
78495
78676
|
const passed = result.exitCode === 0 && !result.timedOut;
|
|
78496
78677
|
const bounded = boundedArgv(command);
|
|
@@ -78605,7 +78786,7 @@ async function run12(argv, io) {
|
|
|
78605
78786
|
return recordError.code === "busy" ? 4 : recordError.code === "invalid_input" ? 2 : 5;
|
|
78606
78787
|
return 0;
|
|
78607
78788
|
}
|
|
78608
|
-
var USAGE6 = 'workit check <name> [--full] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--heavy] [--full] [--wait <s>] [--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(
|
|
78789
|
+
var USAGE6 = 'workit check <name> [--full] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--heavy] [--full] [--wait <s>] [--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(path53.sep).join("/") || ".", ENGINE_CODES2, FINGERPRINT_VARS, ANSI_COLOR, WARNING_LINE, NO_WARNINGS, HOST_TOOL_WAIT_CAP_MS = 1e5;
|
|
78609
78790
|
var init_check = __esm(() => {
|
|
78610
78791
|
init_check_config();
|
|
78611
78792
|
init_checks3();
|
|
@@ -78634,7 +78815,7 @@ __export(exports_lock, {
|
|
|
78634
78815
|
run: () => run13
|
|
78635
78816
|
});
|
|
78636
78817
|
import fs25 from "node:fs";
|
|
78637
|
-
import
|
|
78818
|
+
import path54 from "node:path";
|
|
78638
78819
|
async function settingsFor(io) {
|
|
78639
78820
|
const workspace = await workspaceResources(io);
|
|
78640
78821
|
const config = loadCheckConfig(io.cwd);
|
|
@@ -78716,7 +78897,7 @@ function readPatterns(file) {
|
|
|
78716
78897
|
return { patterns: [] };
|
|
78717
78898
|
}
|
|
78718
78899
|
function writePatterns(file, value) {
|
|
78719
|
-
fs25.mkdirSync(
|
|
78900
|
+
fs25.mkdirSync(path54.dirname(file), { recursive: true, mode: 448 });
|
|
78720
78901
|
const temp = `${file}.${process.pid}.tmp`;
|
|
78721
78902
|
fs25.writeFileSync(temp, `${JSON.stringify(value, null, 2)}
|
|
78722
78903
|
`, { mode: 384 });
|
|
@@ -78802,9 +78983,9 @@ var exports_models = {};
|
|
|
78802
78983
|
__export(exports_models, {
|
|
78803
78984
|
run: () => run14
|
|
78804
78985
|
});
|
|
78805
|
-
import { existsSync as
|
|
78806
|
-
import
|
|
78807
|
-
import
|
|
78986
|
+
import { existsSync as existsSync24, readdirSync as readdirSync13, readFileSync as readFileSync24, statSync as statSync9 } from "node:fs";
|
|
78987
|
+
import os22 from "node:os";
|
|
78988
|
+
import path55 from "node:path";
|
|
78808
78989
|
async function run14(argv, io) {
|
|
78809
78990
|
const [sub, ...args] = argv.filter((arg) => arg !== "--json");
|
|
78810
78991
|
if (sub !== "show")
|
|
@@ -78865,7 +79046,7 @@ var USAGE8 = "workit models show [--role <role>] [--tier <tier>] [--host <host>]
|
|
|
78865
79046
|
const found = new Set;
|
|
78866
79047
|
let text = "";
|
|
78867
79048
|
try {
|
|
78868
|
-
text =
|
|
79049
|
+
text = readFileSync24(file, "utf8");
|
|
78869
79050
|
} catch {
|
|
78870
79051
|
return found;
|
|
78871
79052
|
}
|
|
@@ -78879,26 +79060,26 @@ var USAGE8 = "workit models show [--role <role>] [--tier <tier>] [--host <host>]
|
|
|
78879
79060
|
} catch {}
|
|
78880
79061
|
return found;
|
|
78881
79062
|
}, matches3 = (ran, configured) => ran.toLowerCase().includes(configured.toLowerCase()), usageReport = (cwd, env, days) => {
|
|
78882
|
-
const projects =
|
|
79063
|
+
const projects = path55.join(env.CLAUDE_CONFIG_DIR || path55.join(env.HOME || os22.homedir(), ".claude"), "projects");
|
|
78883
79064
|
const since = Date.now() - days * 86400000;
|
|
78884
79065
|
const types = {};
|
|
78885
79066
|
let agents = 0;
|
|
78886
79067
|
const dirs = (dir) => {
|
|
78887
79068
|
try {
|
|
78888
|
-
return readdirSync13(dir).map((name) =>
|
|
79069
|
+
return readdirSync13(dir).map((name) => path55.join(dir, name));
|
|
78889
79070
|
} catch {
|
|
78890
79071
|
return [];
|
|
78891
79072
|
}
|
|
78892
79073
|
};
|
|
78893
79074
|
for (const project of dirs(projects))
|
|
78894
79075
|
for (const session of dirs(project))
|
|
78895
|
-
for (const meta of dirs(
|
|
79076
|
+
for (const meta of dirs(path55.join(session, "subagents")).filter((f) => f.endsWith(".meta.json"))) {
|
|
78896
79077
|
try {
|
|
78897
79078
|
if (statSync9(meta).mtimeMs < since)
|
|
78898
79079
|
continue;
|
|
78899
|
-
const agentType = JSON.parse(
|
|
79080
|
+
const agentType = JSON.parse(readFileSync24(meta, "utf8")).agentType;
|
|
78900
79081
|
const transcript = meta.replace(/\.meta\.json$/, ".jsonl");
|
|
78901
|
-
if (typeof agentType !== "string" || !
|
|
79082
|
+
if (typeof agentType !== "string" || !existsSync24(transcript))
|
|
78902
79083
|
continue;
|
|
78903
79084
|
const ran = modelsOf(transcript);
|
|
78904
79085
|
if (!ran.size)
|
|
@@ -79037,8 +79218,8 @@ var success2 = (data) => ({ ok: true, data }), failure3 = (code, error, unblock)
|
|
|
79037
79218
|
|
|
79038
79219
|
// packages/workit-core/src/git/ops.ts
|
|
79039
79220
|
import { spawnSync as spawnSync20 } from "node:child_process";
|
|
79040
|
-
import { existsSync as
|
|
79041
|
-
import
|
|
79221
|
+
import { existsSync as existsSync25, readFileSync as readFileSync25 } from "node:fs";
|
|
79222
|
+
import path56 from "node:path";
|
|
79042
79223
|
function operationInProgress(cwd) {
|
|
79043
79224
|
const markers = [
|
|
79044
79225
|
["rebase-merge", "rebase"],
|
|
@@ -79051,18 +79232,18 @@ function operationInProgress(cwd) {
|
|
|
79051
79232
|
if (!run.ok)
|
|
79052
79233
|
return null;
|
|
79053
79234
|
const found = run.stdout.split(`
|
|
79054
|
-
`).map((line) =>
|
|
79235
|
+
`).map((line) => path56.resolve(cwd, line.trim()));
|
|
79055
79236
|
const conflicted = () => git5(cwd, ["ls-files", "-u"]).stdout.trim() !== "";
|
|
79056
79237
|
for (const [index, [, operation]] of markers.entries()) {
|
|
79057
79238
|
const marker = found[index];
|
|
79058
|
-
if (!marker || !
|
|
79239
|
+
if (!marker || !existsSync25(marker))
|
|
79059
79240
|
continue;
|
|
79060
|
-
if (index === 1 &&
|
|
79241
|
+
if (index === 1 && existsSync25(path56.join(marker, "applying")))
|
|
79061
79242
|
return { operation: "am", commitAllowed: false, branch: null };
|
|
79062
|
-
if (index === 0 &&
|
|
79243
|
+
if (index === 0 && existsSync25(path56.join(marker, "amend")) && !conflicted()) {
|
|
79063
79244
|
let headName = "";
|
|
79064
79245
|
try {
|
|
79065
|
-
headName =
|
|
79246
|
+
headName = readFileSync25(path56.join(marker, "head-name"), "utf8").trim();
|
|
79066
79247
|
} catch {}
|
|
79067
79248
|
const branch = headName.startsWith("refs/heads/") ? headName.slice("refs/heads/".length) : null;
|
|
79068
79249
|
return { operation, commitAllowed: branch !== null, branch };
|
|
@@ -79390,7 +79571,7 @@ function gitCommit(cwd, input) {
|
|
|
79390
79571
|
if (paths.some((value) => value.startsWith("-") || !value.trim()))
|
|
79391
79572
|
return failure3("invalid_input", "paths must not be empty or start with -");
|
|
79392
79573
|
const tracked = new Set(nulList(git5(cwd, ["ls-files", "-z", "--", ...paths]).stdout));
|
|
79393
|
-
const addable = paths.filter((value) =>
|
|
79574
|
+
const addable = paths.filter((value) => existsSync25(path56.resolve(cwd, value)) || [...tracked].some((file) => file === value || file.startsWith(`${value}/`)));
|
|
79394
79575
|
if (addable.length) {
|
|
79395
79576
|
const added = git5(cwd, ["add", "-A", "--", ...addable]);
|
|
79396
79577
|
if (!added.ok)
|
|
@@ -79929,12 +80110,12 @@ var init_ops = __esm(() => {
|
|
|
79929
80110
|
|
|
79930
80111
|
// packages/workit-core/src/verdict-cover.ts
|
|
79931
80112
|
import fs26 from "node:fs";
|
|
79932
|
-
import
|
|
80113
|
+
import path57 from "node:path";
|
|
79933
80114
|
function chainsAbove(cwd, branch) {
|
|
79934
80115
|
const root = storeRoot(cwd);
|
|
79935
80116
|
if (!root.ok)
|
|
79936
80117
|
return [];
|
|
79937
|
-
const dir =
|
|
80118
|
+
const dir = path57.join(root.value.root, "stacks");
|
|
79938
80119
|
let names = [];
|
|
79939
80120
|
try {
|
|
79940
80121
|
names = fs26.readdirSync(dir).filter((name) => name.endsWith(".json"));
|
|
@@ -79945,7 +80126,7 @@ function chainsAbove(cwd, branch) {
|
|
|
79945
80126
|
for (const name of names.toSorted()) {
|
|
79946
80127
|
let parsed;
|
|
79947
80128
|
try {
|
|
79948
|
-
parsed = JSON.parse(fs26.readFileSync(
|
|
80129
|
+
parsed = JSON.parse(fs26.readFileSync(path57.join(dir, name), "utf8"));
|
|
79949
80130
|
} catch {
|
|
79950
80131
|
continue;
|
|
79951
80132
|
}
|
|
@@ -80040,10 +80221,10 @@ var init_pr_lane = __esm(() => {
|
|
|
80040
80221
|
|
|
80041
80222
|
// packages/workit-core/src/forge/reruns.ts
|
|
80042
80223
|
import fs27 from "node:fs";
|
|
80043
|
-
import
|
|
80224
|
+
import path58 from "node:path";
|
|
80044
80225
|
function rerunLogPath(cwd) {
|
|
80045
80226
|
const common = gitCommonDir(cwd);
|
|
80046
|
-
return common ?
|
|
80227
|
+
return common ? path58.join(common, "workit", "ci-reruns.jsonl") : null;
|
|
80047
80228
|
}
|
|
80048
80229
|
function rerunCounts(cwd, key) {
|
|
80049
80230
|
const counts = new Map;
|
|
@@ -80078,7 +80259,7 @@ function recordReruns(cwd, rows) {
|
|
|
80078
80259
|
if (!file)
|
|
80079
80260
|
return false;
|
|
80080
80261
|
try {
|
|
80081
|
-
fs27.mkdirSync(
|
|
80262
|
+
fs27.mkdirSync(path58.dirname(file), { recursive: true });
|
|
80082
80263
|
fs27.appendFileSync(file, rows.map((row) => `${JSON.stringify(row)}
|
|
80083
80264
|
`).join(""));
|
|
80084
80265
|
return true;
|
|
@@ -80091,7 +80272,7 @@ function withRerunLock(cwd, fn) {
|
|
|
80091
80272
|
if (!file)
|
|
80092
80273
|
return fn();
|
|
80093
80274
|
const lock = `${file.slice(0, -".jsonl".length)}.lock`;
|
|
80094
|
-
fs27.mkdirSync(
|
|
80275
|
+
fs27.mkdirSync(path58.dirname(lock), { recursive: true });
|
|
80095
80276
|
const until = Date.now() + LOCK_WAIT_MS2;
|
|
80096
80277
|
for (;; ) {
|
|
80097
80278
|
try {
|
|
@@ -80508,7 +80689,7 @@ function recordAccepted(cwd, resolved, status, accepted, options) {
|
|
|
80508
80689
|
return recordReruns(cwd, rows);
|
|
80509
80690
|
}
|
|
80510
80691
|
var MAX_LOG_TAILS = 5, GITLAB_MERGEABLE, GITHUB_MERGEABLE, NO_CHECKS_GRACE_MS = 90000;
|
|
80511
|
-
var
|
|
80692
|
+
var init_report2 = __esm(() => {
|
|
80512
80693
|
init_rev();
|
|
80513
80694
|
init_ledger();
|
|
80514
80695
|
init_reruns();
|
|
@@ -81057,7 +81238,7 @@ var init_pr_ops = __esm(() => {
|
|
|
81057
81238
|
init_ledger();
|
|
81058
81239
|
init_verdict_cover();
|
|
81059
81240
|
init_pr_lane();
|
|
81060
|
-
|
|
81241
|
+
init_report2();
|
|
81061
81242
|
VERIFY_DELAYS_MS = [1000, 2000, 4000];
|
|
81062
81243
|
AFTER_REVIEW = {
|
|
81063
81244
|
commit: "stop here; review comes when the user asks",
|
|
@@ -81070,9 +81251,9 @@ var init_pr_ops = __esm(() => {
|
|
|
81070
81251
|
|
|
81071
81252
|
// packages/workit-core/src/stack.ts
|
|
81072
81253
|
import { spawnSync as spawnSync22 } from "node:child_process";
|
|
81073
|
-
import { createHash as
|
|
81254
|
+
import { createHash as createHash18, randomBytes as randomBytes4 } from "node:crypto";
|
|
81074
81255
|
import fs28 from "node:fs";
|
|
81075
|
-
import
|
|
81256
|
+
import path59 from "node:path";
|
|
81076
81257
|
function worktreeOf(cwd, branch) {
|
|
81077
81258
|
const list = gitRun3(cwd, ["worktree", "list", "--porcelain"]);
|
|
81078
81259
|
if (!list.ok)
|
|
@@ -81121,7 +81302,7 @@ function gitRestack(cwd, input) {
|
|
|
81121
81302
|
error: "no store root"
|
|
81122
81303
|
};
|
|
81123
81304
|
fs28.mkdirSync(scratch, { recursive: true });
|
|
81124
|
-
dir =
|
|
81305
|
+
dir = path59.join(scratch, `${input.branch.replace(/[^A-Za-z0-9._-]+/gu, "_").slice(0, 40)}-${randomBytes4(4).toString("hex")}`);
|
|
81125
81306
|
const added = gitRun3(cwd, ["worktree", "add", "-q", dir, input.branch], GIT_TIMEOUTS.worktree);
|
|
81126
81307
|
if (!added.ok)
|
|
81127
81308
|
return {
|
|
@@ -81177,7 +81358,7 @@ function pruneScratch(cwd) {
|
|
|
81177
81358
|
if (!scratch || !fs28.existsSync(scratch))
|
|
81178
81359
|
return;
|
|
81179
81360
|
for (const name of fs28.readdirSync(scratch)) {
|
|
81180
|
-
const dir =
|
|
81361
|
+
const dir = path59.join(scratch, name);
|
|
81181
81362
|
if (!rebaseInProgress(dir) && !trackedDirt(dir))
|
|
81182
81363
|
gitRun3(cwd, ["worktree", "remove", "--force", dir]);
|
|
81183
81364
|
}
|
|
@@ -81187,7 +81368,7 @@ function stacksDir(cwd) {
|
|
|
81187
81368
|
const root = storeRoot(cwd);
|
|
81188
81369
|
if (!root.ok)
|
|
81189
81370
|
return stackFail(root.code, root.error, root.unblock);
|
|
81190
|
-
return { ok: true, data:
|
|
81371
|
+
return { ok: true, data: path59.join(root.value.root, "stacks") };
|
|
81191
81372
|
}
|
|
81192
81373
|
function parseStack(raw) {
|
|
81193
81374
|
if (!isRecord12(raw) || !Array.isArray(raw.branches))
|
|
@@ -81239,7 +81420,7 @@ function readStack(cwd, name) {
|
|
|
81239
81420
|
const dir = stacksDir(cwd);
|
|
81240
81421
|
if (!dir.ok)
|
|
81241
81422
|
return dir;
|
|
81242
|
-
const file =
|
|
81423
|
+
const file = path59.join(dir.data, fileFor(name));
|
|
81243
81424
|
let text;
|
|
81244
81425
|
try {
|
|
81245
81426
|
text = fs28.readFileSync(file, "utf8");
|
|
@@ -81260,7 +81441,7 @@ function writeStack(cwd, stack, now = new Date) {
|
|
|
81260
81441
|
const dir = stacksDir(cwd);
|
|
81261
81442
|
if (!dir.ok)
|
|
81262
81443
|
return dir;
|
|
81263
|
-
const file =
|
|
81444
|
+
const file = path59.join(dir.data, fileFor(stack.name));
|
|
81264
81445
|
const temp = `${file}.${process.pid}.tmp`;
|
|
81265
81446
|
try {
|
|
81266
81447
|
fs28.mkdirSync(dir.data, { recursive: true });
|
|
@@ -81288,7 +81469,7 @@ function listStacks(cwd) {
|
|
|
81288
81469
|
for (const name of names) {
|
|
81289
81470
|
let parsed = null;
|
|
81290
81471
|
try {
|
|
81291
|
-
parsed = parseStack(JSON.parse(fs28.readFileSync(
|
|
81472
|
+
parsed = parseStack(JSON.parse(fs28.readFileSync(path59.join(dir.data, name), "utf8")));
|
|
81292
81473
|
} catch {
|
|
81293
81474
|
parsed = null;
|
|
81294
81475
|
}
|
|
@@ -81350,7 +81531,7 @@ function takeLock(lock) {
|
|
|
81350
81531
|
host: localLockHost(),
|
|
81351
81532
|
nonce: randomBytes4(8).toString("hex")
|
|
81352
81533
|
};
|
|
81353
|
-
fs28.writeFileSync(
|
|
81534
|
+
fs28.writeFileSync(path59.join(lock, OWNER), JSON.stringify(owner));
|
|
81354
81535
|
return owner;
|
|
81355
81536
|
}
|
|
81356
81537
|
function reapLock(lock, observed) {
|
|
@@ -81387,7 +81568,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
|
|
|
81387
81568
|
return dir;
|
|
81388
81569
|
if (!validName(name))
|
|
81389
81570
|
return stackFail("invalid_input", "a stack name must be 1-200 printable characters");
|
|
81390
|
-
const lock =
|
|
81571
|
+
const lock = path59.join(dir.data, `${fileFor(name)}.lock`);
|
|
81391
81572
|
try {
|
|
81392
81573
|
fs28.mkdirSync(dir.data, { recursive: true });
|
|
81393
81574
|
} catch (error) {
|
|
@@ -81417,7 +81598,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
|
|
|
81417
81598
|
const touch = () => {
|
|
81418
81599
|
try {
|
|
81419
81600
|
const now = new Date;
|
|
81420
|
-
fs28.utimesSync(
|
|
81601
|
+
fs28.utimesSync(path59.join(lock, OWNER), now, now);
|
|
81421
81602
|
} catch {}
|
|
81422
81603
|
};
|
|
81423
81604
|
const beat = setInterval(touch, HEARTBEAT_MS);
|
|
@@ -82318,10 +82499,10 @@ var STACK_VERSION = 1, stackFail = (code, error, unblock, data) => ({
|
|
|
82318
82499
|
return !status.ok || status.stdout.trim() !== "";
|
|
82319
82500
|
}, scratchDir = (cwd) => {
|
|
82320
82501
|
const dir = stacksDir(cwd);
|
|
82321
|
-
return dir.ok ?
|
|
82502
|
+
return dir.ok ? path59.join(dir.data, "worktrees") : null;
|
|
82322
82503
|
}, firstLine = (run) => (`${run.stderr}
|
|
82323
82504
|
${run.stdout}`.split(`
|
|
82324
|
-
`).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()}-${
|
|
82505
|
+
`).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) => {
|
|
82325
82506
|
if (name.length === 0 || name.length > 200)
|
|
82326
82507
|
return false;
|
|
82327
82508
|
for (let index = 0;index < name.length; index += 1) {
|
|
@@ -82333,12 +82514,12 @@ ${run.stdout}`.split(`
|
|
|
82333
82514
|
}, 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) => {
|
|
82334
82515
|
let raw = null;
|
|
82335
82516
|
try {
|
|
82336
|
-
raw = fs28.readFileSync(
|
|
82517
|
+
raw = fs28.readFileSync(path59.join(lock, OWNER), "utf8");
|
|
82337
82518
|
} catch {
|
|
82338
82519
|
raw = null;
|
|
82339
82520
|
}
|
|
82340
82521
|
let age = null;
|
|
82341
|
-
for (const target of [
|
|
82522
|
+
for (const target of [path59.join(lock, OWNER), lock])
|
|
82342
82523
|
try {
|
|
82343
82524
|
age = Date.now() - fs28.statSync(target).mtimeMs;
|
|
82344
82525
|
break;
|
|
@@ -82362,7 +82543,7 @@ var init_stack = __esm(() => {
|
|
|
82362
82543
|
init_autonomy();
|
|
82363
82544
|
init_store_lock();
|
|
82364
82545
|
init_pr_ops();
|
|
82365
|
-
|
|
82546
|
+
init_report2();
|
|
82366
82547
|
init_ops();
|
|
82367
82548
|
init_rev();
|
|
82368
82549
|
init_ledger();
|
|
@@ -82379,9 +82560,9 @@ var init_stack = __esm(() => {
|
|
|
82379
82560
|
|
|
82380
82561
|
// packages/workit-core/src/fanout.ts
|
|
82381
82562
|
import { spawnSync as spawnSync23 } from "node:child_process";
|
|
82382
|
-
import { createHash as
|
|
82563
|
+
import { createHash as createHash19 } from "node:crypto";
|
|
82383
82564
|
import fs29 from "node:fs";
|
|
82384
|
-
import
|
|
82565
|
+
import path60 from "node:path";
|
|
82385
82566
|
function expandBraces2(pattern, limit = 64) {
|
|
82386
82567
|
for (let index = 0;index < pattern.length; index += 1) {
|
|
82387
82568
|
if (pattern[index] === "\\") {
|
|
@@ -82627,7 +82808,7 @@ function parsePlan(raw, defaults, name) {
|
|
|
82627
82808
|
id,
|
|
82628
82809
|
branch,
|
|
82629
82810
|
base: optional("base") ?? "",
|
|
82630
|
-
worktree:
|
|
82811
|
+
worktree: path60.resolve(defaults.root, optional("worktree") ?? path60.join(defaults.worktreeRoot, id)),
|
|
82631
82812
|
tier,
|
|
82632
82813
|
reason,
|
|
82633
82814
|
dependsOn: [...new Set(dependsOn ?? [])],
|
|
@@ -82756,12 +82937,12 @@ function regeneratedFiles(root, tracked) {
|
|
|
82756
82937
|
const found = new Map;
|
|
82757
82938
|
let scripts;
|
|
82758
82939
|
try {
|
|
82759
|
-
const manifest = JSON.parse(fs29.readFileSync(
|
|
82940
|
+
const manifest = JSON.parse(fs29.readFileSync(path60.join(root, "package.json"), "utf8"));
|
|
82760
82941
|
scripts = manifest.scripts ?? {};
|
|
82761
82942
|
} catch {
|
|
82762
82943
|
return found;
|
|
82763
82944
|
}
|
|
82764
|
-
const runner = fs29.existsSync(
|
|
82945
|
+
const runner = fs29.existsSync(path60.join(root, "bun.lock")) ? "bun run" : fs29.existsSync(path60.join(root, "pnpm-lock.yaml")) ? "pnpm run" : fs29.existsSync(path60.join(root, "yarn.lock")) ? "yarn run" : "npm run";
|
|
82765
82946
|
const outputs = tracked.filter((file) => !CODE.test(file));
|
|
82766
82947
|
for (const [name, command] of Object.entries(scripts)) {
|
|
82767
82948
|
if (!name.startsWith("write:") || typeof command !== "string")
|
|
@@ -82769,7 +82950,7 @@ function regeneratedFiles(root, tracked) {
|
|
|
82769
82950
|
for (const file of command.match(/[\w./-]+\.[cm]?[jt]s\b/gu) ?? []) {
|
|
82770
82951
|
let source;
|
|
82771
82952
|
try {
|
|
82772
|
-
source = fs29.readFileSync(
|
|
82953
|
+
source = fs29.readFileSync(path60.join(root, file), "utf8");
|
|
82773
82954
|
} catch {
|
|
82774
82955
|
continue;
|
|
82775
82956
|
}
|
|
@@ -82891,11 +83072,11 @@ function defaultTrunk(cwd) {
|
|
|
82891
83072
|
}
|
|
82892
83073
|
function mainCheckout(cwd) {
|
|
82893
83074
|
const common = gitCommonDir(cwd);
|
|
82894
|
-
return common &&
|
|
83075
|
+
return common && path60.basename(common) === ".git" ? path60.dirname(common) : path60.resolve(cwd);
|
|
82895
83076
|
}
|
|
82896
83077
|
function worktreeRoot(cwd) {
|
|
82897
83078
|
const main = mainCheckout(cwd);
|
|
82898
|
-
return
|
|
83079
|
+
return path60.join(path60.dirname(main), `${path60.basename(main)}-wt`);
|
|
82899
83080
|
}
|
|
82900
83081
|
function sliceHash(slice) {
|
|
82901
83082
|
const {
|
|
@@ -82909,13 +83090,13 @@ function sliceHash(slice) {
|
|
|
82909
83090
|
issues: _issues,
|
|
82910
83091
|
...definition
|
|
82911
83092
|
} = slice;
|
|
82912
|
-
return
|
|
83093
|
+
return createHash19("sha256").update(JSON.stringify(definition)).digest("hex").slice(0, 16);
|
|
82913
83094
|
}
|
|
82914
83095
|
function fanoutsDir(cwd) {
|
|
82915
83096
|
const root = storeRoot(cwd);
|
|
82916
83097
|
if (!root.ok)
|
|
82917
83098
|
return fanoutFail(root.code, root.error, root.unblock);
|
|
82918
|
-
return { ok: true, data:
|
|
83099
|
+
return { ok: true, data: path60.join(root.value.root, "fanouts") };
|
|
82919
83100
|
}
|
|
82920
83101
|
function parseStored(raw) {
|
|
82921
83102
|
if (!isRecord13(raw) || typeof raw.name !== "string" || typeof raw.trunk !== "string")
|
|
@@ -82983,7 +83164,7 @@ function readFanout(cwd, name) {
|
|
|
82983
83164
|
const dir = fanoutsDir(cwd);
|
|
82984
83165
|
if (!dir.ok)
|
|
82985
83166
|
return dir;
|
|
82986
|
-
const file =
|
|
83167
|
+
const file = path60.join(dir.data, stackFileName(name));
|
|
82987
83168
|
let parsed = null;
|
|
82988
83169
|
try {
|
|
82989
83170
|
parsed = parseStored(JSON.parse(fs29.readFileSync(file, "utf8")));
|
|
@@ -83008,7 +83189,7 @@ function listFanouts(cwd) {
|
|
|
83008
83189
|
for (const entry of names) {
|
|
83009
83190
|
let parsed = null;
|
|
83010
83191
|
try {
|
|
83011
|
-
parsed = parseStored(JSON.parse(fs29.readFileSync(
|
|
83192
|
+
parsed = parseStored(JSON.parse(fs29.readFileSync(path60.join(dir.data, entry), "utf8")));
|
|
83012
83193
|
} catch {
|
|
83013
83194
|
parsed = null;
|
|
83014
83195
|
}
|
|
@@ -83047,7 +83228,7 @@ function writeFanout(cwd, plan) {
|
|
|
83047
83228
|
const dir = fanoutsDir(cwd);
|
|
83048
83229
|
if (!dir.ok)
|
|
83049
83230
|
return dir;
|
|
83050
|
-
const file =
|
|
83231
|
+
const file = path60.join(dir.data, stackFileName(plan.name));
|
|
83051
83232
|
const temp = `${file}.${process.pid}.tmp`;
|
|
83052
83233
|
try {
|
|
83053
83234
|
fs29.mkdirSync(dir.data, { recursive: true });
|
|
@@ -83258,13 +83439,13 @@ var init_fanout = __esm(() => {
|
|
|
83258
83439
|
// packages/workit-core/src/forge/exec.ts
|
|
83259
83440
|
import { spawnSync as spawnSync24 } from "node:child_process";
|
|
83260
83441
|
import fs30 from "node:fs";
|
|
83261
|
-
import
|
|
83442
|
+
import path61 from "node:path";
|
|
83262
83443
|
function findExecutable(bin, env) {
|
|
83263
|
-
const dirs = (env.PATH ?? env.Path ?? "").split(
|
|
83444
|
+
const dirs = (env.PATH ?? env.Path ?? "").split(path61.delimiter).filter(Boolean);
|
|
83264
83445
|
const exts = process.platform === "win32" ? [".exe"] : [""];
|
|
83265
83446
|
for (const dir of dirs)
|
|
83266
83447
|
for (const ext of exts) {
|
|
83267
|
-
const candidate =
|
|
83448
|
+
const candidate = path61.join(dir, `${bin}${ext}`);
|
|
83268
83449
|
try {
|
|
83269
83450
|
const stat = fs30.statSync(candidate);
|
|
83270
83451
|
if (stat.isFile())
|
|
@@ -84807,7 +84988,7 @@ var init_pr_edit = __esm(() => {
|
|
|
84807
84988
|
init_rev();
|
|
84808
84989
|
init_stack();
|
|
84809
84990
|
init_pr_ops();
|
|
84810
|
-
|
|
84991
|
+
init_report2();
|
|
84811
84992
|
});
|
|
84812
84993
|
|
|
84813
84994
|
// packages/workit-core/src/core/live-session.ts
|
|
@@ -84827,7 +85008,7 @@ var init_live_session = __esm(() => {
|
|
|
84827
85008
|
});
|
|
84828
85009
|
|
|
84829
85010
|
// packages/workit-core/src/hooks/write-gate.ts
|
|
84830
|
-
import
|
|
85011
|
+
import path62 from "node:path";
|
|
84831
85012
|
var CASE_INSENSITIVE, PREFIXES2, SCRIPT_SHELLS, cache3, MUTATING_GIT, DRY_N, MUTATING_WORKIT_GIT, CD2, PUSHD2, POPD2, UNKNOWN_DIR;
|
|
84832
85013
|
var init_write_gate = __esm(() => {
|
|
84833
85014
|
init_task_store();
|
|
@@ -84867,7 +85048,7 @@ var init_write_gate = __esm(() => {
|
|
|
84867
85048
|
CD2 = new Set(["cd", "chdir", "set-location", "sl"]);
|
|
84868
85049
|
PUSHD2 = new Set(["pushd", "push-location"]);
|
|
84869
85050
|
POPD2 = new Set(["popd", "pop-location"]);
|
|
84870
|
-
UNKNOWN_DIR =
|
|
85051
|
+
UNKNOWN_DIR = path62.resolve(path62.parse(process.cwd()).root, ".workit-unknown-dir");
|
|
84871
85052
|
});
|
|
84872
85053
|
|
|
84873
85054
|
// packages/workit-core/src/hooks/worktree-confine.ts
|
|
@@ -84892,20 +85073,20 @@ var init_worktree_confine = __esm(() => {
|
|
|
84892
85073
|
|
|
84893
85074
|
// packages/workit-core/src/worktree-deps.ts
|
|
84894
85075
|
import fs31 from "node:fs";
|
|
84895
|
-
import
|
|
85076
|
+
import path63 from "node:path";
|
|
84896
85077
|
function moduleDirs(main) {
|
|
84897
85078
|
const out = [];
|
|
84898
85079
|
const walk = (relative, depth) => {
|
|
84899
85080
|
let entries;
|
|
84900
85081
|
try {
|
|
84901
|
-
entries = fs31.readdirSync(
|
|
85082
|
+
entries = fs31.readdirSync(path63.join(main, relative), { withFileTypes: true });
|
|
84902
85083
|
} catch {
|
|
84903
85084
|
return;
|
|
84904
85085
|
}
|
|
84905
85086
|
for (const entry of entries) {
|
|
84906
85087
|
if (!entry.isDirectory())
|
|
84907
85088
|
continue;
|
|
84908
|
-
const child =
|
|
85089
|
+
const child = path63.join(relative, entry.name);
|
|
84909
85090
|
if (entry.name === MODULES)
|
|
84910
85091
|
out.push(child);
|
|
84911
85092
|
else if (depth < MAX_DEPTH2 && !entry.name.startsWith("."))
|
|
@@ -84919,8 +85100,8 @@ function linkEntry(main, worktree, source, target) {
|
|
|
84919
85100
|
const stat = fs31.lstatSync(source);
|
|
84920
85101
|
if (stat.isSymbolicLink()) {
|
|
84921
85102
|
const link = fs31.readlinkSync(source);
|
|
84922
|
-
const outside =
|
|
84923
|
-
const to = outside ?
|
|
85103
|
+
const outside = path63.isAbsolute(link) && within(link, main) && !path63.relative(main, link).split(path63.sep).includes(MODULES);
|
|
85104
|
+
const to = outside ? path63.join(worktree, path63.relative(main, link)) : link;
|
|
84924
85105
|
fs31.symlinkSync(to, target, process.platform === "win32" ? "junction" : undefined);
|
|
84925
85106
|
return;
|
|
84926
85107
|
}
|
|
@@ -84930,8 +85111,8 @@ function mirror(main, worktree, source, target, top) {
|
|
|
84930
85111
|
fs31.mkdirSync(target);
|
|
84931
85112
|
let count = 0;
|
|
84932
85113
|
for (const entry of fs31.readdirSync(source, { withFileTypes: true })) {
|
|
84933
|
-
const from =
|
|
84934
|
-
const to =
|
|
85114
|
+
const from = path63.join(source, entry.name);
|
|
85115
|
+
const to = path63.join(target, entry.name);
|
|
84935
85116
|
if (top && entry.isDirectory() && (entry.name.startsWith("@") || entry.name === ".bin"))
|
|
84936
85117
|
count += mirror(main, worktree, from, to, false);
|
|
84937
85118
|
else {
|
|
@@ -84947,16 +85128,16 @@ function linkWorktreeDependencies(main, worktree) {
|
|
|
84947
85128
|
const dirs = [];
|
|
84948
85129
|
let entries = 0;
|
|
84949
85130
|
for (const relative of moduleDirs(main)) {
|
|
84950
|
-
const target =
|
|
84951
|
-
if (!fs31.existsSync(
|
|
85131
|
+
const target = path63.join(worktree, relative);
|
|
85132
|
+
if (!fs31.existsSync(path63.dirname(target)) || fs31.existsSync(target))
|
|
84952
85133
|
continue;
|
|
84953
|
-
if (!gitRun4(worktree, ["check-ignore", "-q", `${relative.split(
|
|
84954
|
-
notes.push(`${relative.split(
|
|
85134
|
+
if (!gitRun4(worktree, ["check-ignore", "-q", `${relative.split(path63.sep).join("/")}/`]).ok) {
|
|
85135
|
+
notes.push(`${relative.split(path63.sep).join("/")} is not ignored by git, so it was not linked from ${main}; install dependencies in the worktree yourself`);
|
|
84955
85136
|
continue;
|
|
84956
85137
|
}
|
|
84957
85138
|
try {
|
|
84958
|
-
entries += mirror(main, worktree,
|
|
84959
|
-
dirs.push(relative.split(
|
|
85139
|
+
entries += mirror(main, worktree, path63.join(main, relative), target, true);
|
|
85140
|
+
dirs.push(relative.split(path63.sep).join("/"));
|
|
84960
85141
|
} catch (error) {
|
|
84961
85142
|
fs31.rmSync(target, { recursive: true, force: true });
|
|
84962
85143
|
notes.push(`could not link ${relative} from ${main} (${error.message}); install dependencies in the worktree yourself`);
|
|
@@ -84969,8 +85150,8 @@ function linkWorktreeDependencies(main, worktree) {
|
|
|
84969
85150
|
return { linked: { from: main, dirs, entries, ms }, notes };
|
|
84970
85151
|
}
|
|
84971
85152
|
var MODULES = "node_modules", MAX_DEPTH2 = 2, within = (child, parent) => {
|
|
84972
|
-
const relative =
|
|
84973
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
85153
|
+
const relative = path63.relative(parent, child);
|
|
85154
|
+
return relative === "" || !relative.startsWith("..") && !path63.isAbsolute(relative);
|
|
84974
85155
|
};
|
|
84975
85156
|
var init_worktree_deps = __esm(() => {
|
|
84976
85157
|
init_fanout();
|
|
@@ -84979,7 +85160,7 @@ var init_worktree_deps = __esm(() => {
|
|
|
84979
85160
|
// packages/workit-core/src/fanout-worktree.ts
|
|
84980
85161
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
84981
85162
|
import fs32 from "node:fs";
|
|
84982
|
-
import
|
|
85163
|
+
import path64 from "node:path";
|
|
84983
85164
|
function rowSample(lines) {
|
|
84984
85165
|
const out = [];
|
|
84985
85166
|
let bytes = 0;
|
|
@@ -85039,7 +85220,7 @@ function adminDir(worktree) {
|
|
|
85039
85220
|
const file = dir.stdout.trim();
|
|
85040
85221
|
let token = null;
|
|
85041
85222
|
try {
|
|
85042
|
-
token = fs32.readFileSync(
|
|
85223
|
+
token = fs32.readFileSync(path64.join(file, FANOUT_TOKEN_FILE), "utf8").trim() || null;
|
|
85043
85224
|
} catch {
|
|
85044
85225
|
token = null;
|
|
85045
85226
|
}
|
|
@@ -85047,7 +85228,7 @@ function adminDir(worktree) {
|
|
|
85047
85228
|
const stat = worktreeDeps.stat(file);
|
|
85048
85229
|
return {
|
|
85049
85230
|
path: file,
|
|
85050
|
-
id:
|
|
85231
|
+
id: path64.basename(file),
|
|
85051
85232
|
ino: stat.ino.toString(),
|
|
85052
85233
|
token,
|
|
85053
85234
|
birthMs: stat.birthtimeNs > 0n ? Number(stat.birthtimeMs) : null,
|
|
@@ -85063,7 +85244,7 @@ function markAdminDir(worktree) {
|
|
|
85063
85244
|
return null;
|
|
85064
85245
|
const token = randomBytes5(16).toString("hex");
|
|
85065
85246
|
try {
|
|
85066
|
-
fs32.writeFileSync(
|
|
85247
|
+
fs32.writeFileSync(path64.join(admin.path, FANOUT_TOKEN_FILE), `${token}
|
|
85067
85248
|
`);
|
|
85068
85249
|
} catch {
|
|
85069
85250
|
return null;
|
|
@@ -85078,7 +85259,7 @@ function excludeScratch(cwd) {
|
|
|
85078
85259
|
const common = gitCommonDir(cwd);
|
|
85079
85260
|
if (!common)
|
|
85080
85261
|
return;
|
|
85081
|
-
const file =
|
|
85262
|
+
const file = path64.join(common, "info", "exclude");
|
|
85082
85263
|
let text = "";
|
|
85083
85264
|
try {
|
|
85084
85265
|
text = fs32.readFileSync(file, "utf8");
|
|
@@ -85087,7 +85268,7 @@ function excludeScratch(cwd) {
|
|
|
85087
85268
|
}
|
|
85088
85269
|
if (text.split(/\r?\n/u).includes(EXCLUDE_LINE))
|
|
85089
85270
|
return;
|
|
85090
|
-
fs32.mkdirSync(
|
|
85271
|
+
fs32.mkdirSync(path64.dirname(file), { recursive: true });
|
|
85091
85272
|
fs32.appendFileSync(file, `${text && !text.endsWith(`
|
|
85092
85273
|
`) ? `
|
|
85093
85274
|
` : ""}# workit fanout: per-worker scratch dirs
|
|
@@ -85096,13 +85277,13 @@ ${EXCLUDE_LINE}
|
|
|
85096
85277
|
}
|
|
85097
85278
|
function worktreeDependencies(main, worktree) {
|
|
85098
85279
|
for (const [name, install] of LOCKFILES2) {
|
|
85099
|
-
const ours = readBytes(
|
|
85100
|
-
const theirs = readBytes(
|
|
85280
|
+
const ours = readBytes(path64.join(main, name));
|
|
85281
|
+
const theirs = readBytes(path64.join(worktree, name));
|
|
85101
85282
|
if (ours === null && theirs === null)
|
|
85102
85283
|
continue;
|
|
85103
85284
|
if (ours !== null && theirs !== null && ours.equals(theirs))
|
|
85104
85285
|
continue;
|
|
85105
|
-
if (fs32.existsSync(
|
|
85286
|
+
if (fs32.existsSync(path64.join(worktree, "node_modules")))
|
|
85106
85287
|
break;
|
|
85107
85288
|
const command = install(worktree);
|
|
85108
85289
|
return {
|
|
@@ -85116,7 +85297,7 @@ function worktreeDependencies(main, worktree) {
|
|
|
85116
85297
|
return { ...linkWorktreeDependencies(main, worktree), install: null };
|
|
85117
85298
|
}
|
|
85118
85299
|
function ensureScratch(worktree) {
|
|
85119
|
-
const scratch =
|
|
85300
|
+
const scratch = path64.join(worktree, SCRATCH_DIR);
|
|
85120
85301
|
fs32.mkdirSync(scratch, { recursive: true });
|
|
85121
85302
|
return scratch;
|
|
85122
85303
|
}
|
|
@@ -85355,7 +85536,7 @@ function unpushedCount(cwd, branch) {
|
|
|
85355
85536
|
return count.ok ? Number(count.stdout.trim()) : null;
|
|
85356
85537
|
}
|
|
85357
85538
|
function removeScratch(worktree) {
|
|
85358
|
-
const scratch =
|
|
85539
|
+
const scratch = path64.join(worktree, SCRATCH_DIR);
|
|
85359
85540
|
let stat;
|
|
85360
85541
|
try {
|
|
85361
85542
|
stat = fs32.lstatSync(scratch);
|
|
@@ -85371,16 +85552,16 @@ var SLOW, SCRATCH_DIR = ".workit-scratch", EXCLUDE_LINE, DIRTY_ROW_BYTES = 2000,
|
|
|
85371
85552
|
try {
|
|
85372
85553
|
return fs32.realpathSync.native(target);
|
|
85373
85554
|
} catch {
|
|
85374
|
-
return
|
|
85555
|
+
return path64.resolve(target);
|
|
85375
85556
|
}
|
|
85376
85557
|
}, samePath = (a, b) => {
|
|
85377
85558
|
const left = canonical2(a);
|
|
85378
85559
|
const right = canonical2(b);
|
|
85379
85560
|
return process.platform === "win32" || process.platform === "darwin" ? left.toLowerCase() === right.toLowerCase() : left === right;
|
|
85380
85561
|
}, inside3 = (child, parent) => {
|
|
85381
|
-
const relative =
|
|
85382
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
85383
|
-
}, slicePath = (cwd, slice) =>
|
|
85562
|
+
const relative = path64.relative(canonical2(parent), canonical2(child));
|
|
85563
|
+
return relative === "" || !relative.startsWith("..") && !path64.isAbsolute(relative);
|
|
85564
|
+
}, slicePath = (cwd, slice) => path64.isAbsolute(slice.worktree) ? slice.worktree : path64.resolve(mainCheckout(cwd), slice.worktree), CLOCK_SLACK_MS = 2000, worktreeDeps, LOCKFILES2, readBytes = (file) => {
|
|
85384
85565
|
try {
|
|
85385
85566
|
return fs32.readFileSync(file);
|
|
85386
85567
|
} catch {
|
|
@@ -85411,7 +85592,7 @@ var init_fanout_worktree = __esm(() => {
|
|
|
85411
85592
|
|
|
85412
85593
|
// packages/workit-core/src/forge/merge-cleanup.ts
|
|
85413
85594
|
import fs33 from "node:fs";
|
|
85414
|
-
import
|
|
85595
|
+
import path65 from "node:path";
|
|
85415
85596
|
function cleanupMergedBranch(cwd, branch, mergedHead) {
|
|
85416
85597
|
const out = { branchDeleted: false, worktreeRemoved: null, notes: [] };
|
|
85417
85598
|
if (!branch || branch.startsWith("-"))
|
|
@@ -85471,13 +85652,13 @@ var SLOW2, isFanoutWorktree = (worktree) => {
|
|
|
85471
85652
|
if (!dir.ok)
|
|
85472
85653
|
return false;
|
|
85473
85654
|
try {
|
|
85474
|
-
return fs33.readFileSync(
|
|
85655
|
+
return fs33.readFileSync(path65.join(dir.stdout.trim(), FANOUT_TOKEN_FILE), "utf8").trim() !== "";
|
|
85475
85656
|
} catch {
|
|
85476
85657
|
return false;
|
|
85477
85658
|
}
|
|
85478
85659
|
}, inside4 = (child, parent) => {
|
|
85479
|
-
const relative =
|
|
85480
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
85660
|
+
const relative = path65.relative(fs33.realpathSync.native(parent), fs33.realpathSync.native(child));
|
|
85661
|
+
return relative === "" || !relative.startsWith("..") && !path65.isAbsolute(relative);
|
|
85481
85662
|
};
|
|
85482
85663
|
var init_merge_cleanup = __esm(() => {
|
|
85483
85664
|
init_fanout();
|
|
@@ -85758,7 +85939,7 @@ var init_duration = __esm(() => {
|
|
|
85758
85939
|
});
|
|
85759
85940
|
|
|
85760
85941
|
// packages/workit-cli/src/verbs/forge-common.ts
|
|
85761
|
-
import { readFileSync as
|
|
85942
|
+
import { readFileSync as readFileSync26 } from "node:fs";
|
|
85762
85943
|
function parseFlags(argv, spec) {
|
|
85763
85944
|
const parsed = { values: {}, booleans: new Set, lists: {}, positionals: [] };
|
|
85764
85945
|
for (let index = 0;index < argv.length; index += 1) {
|
|
@@ -85913,7 +86094,7 @@ var init_forge_common = __esm(() => {
|
|
|
85913
86094
|
forgeDeps = {
|
|
85914
86095
|
runner: undefined,
|
|
85915
86096
|
npm: undefined,
|
|
85916
|
-
readStdin: () =>
|
|
86097
|
+
readStdin: () => readFileSync26(0, "utf8"),
|
|
85917
86098
|
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
85918
86099
|
now: () => Date.now()
|
|
85919
86100
|
};
|
|
@@ -85924,12 +86105,12 @@ var exports_pr = {};
|
|
|
85924
86105
|
__export(exports_pr, {
|
|
85925
86106
|
run: () => run15
|
|
85926
86107
|
});
|
|
85927
|
-
import { readFileSync as
|
|
85928
|
-
import
|
|
86108
|
+
import { readFileSync as readFileSync27 } from "node:fs";
|
|
86109
|
+
import path66 from "node:path";
|
|
85929
86110
|
function readBodyFile(io, file) {
|
|
85930
86111
|
try {
|
|
85931
86112
|
return {
|
|
85932
|
-
body: file === "-" ? forgeDeps.readStdin() :
|
|
86113
|
+
body: file === "-" ? forgeDeps.readStdin() : readFileSync27(path66.resolve(io.cwd, file), "utf8")
|
|
85933
86114
|
};
|
|
85934
86115
|
} catch {
|
|
85935
86116
|
return `cannot read --body-file ${file}`;
|
|
@@ -86440,7 +86621,7 @@ var init_pr = __esm(() => {
|
|
|
86440
86621
|
init_issue_link();
|
|
86441
86622
|
init_pr_edit();
|
|
86442
86623
|
init_pr_ops();
|
|
86443
|
-
|
|
86624
|
+
init_report2();
|
|
86444
86625
|
init_rev();
|
|
86445
86626
|
init_workspaces();
|
|
86446
86627
|
init_merge_cleanup();
|
|
@@ -86694,7 +86875,7 @@ async function run16(argv, io) {
|
|
|
86694
86875
|
}
|
|
86695
86876
|
var WAIT_USAGE = "workit ci wait [--pr <n> | --branch <b>] [--head <sha>] [--timeout 20m] [--interval 30s] [--json]", RERUN_USAGE = "workit ci rerun [--pr <n> | --branch <b>] [--check <name>… | --failed] --reason flake|infra [--force] [--json]", LOGS_USAGE = "workit ci logs --failed [--pr <n> | --branch <b>] [--json]", LOG_LINES = 60, ONE_POLL_MS = 20000, MAX_POLL_ERRORS = 3, seconds = (ms) => `${Math.round(ms / 1000)}s`;
|
|
86696
86877
|
var init_ci = __esm(() => {
|
|
86697
|
-
|
|
86878
|
+
init_report2();
|
|
86698
86879
|
init_ledger();
|
|
86699
86880
|
init_autonomy();
|
|
86700
86881
|
init_output();
|
|
@@ -86733,8 +86914,8 @@ var exports_git = {};
|
|
|
86733
86914
|
__export(exports_git, {
|
|
86734
86915
|
run: () => run17
|
|
86735
86916
|
});
|
|
86736
|
-
import { readFileSync as
|
|
86737
|
-
import
|
|
86917
|
+
import { readFileSync as readFileSync28 } from "node:fs";
|
|
86918
|
+
import path67 from "node:path";
|
|
86738
86919
|
function kindHint(cwd, kind) {
|
|
86739
86920
|
let kinds = [...BRANCH_KINDS];
|
|
86740
86921
|
try {
|
|
@@ -86838,7 +87019,7 @@ function commitMessage(parsed, io) {
|
|
|
86838
87019
|
|
|
86839
87020
|
`);
|
|
86840
87021
|
try {
|
|
86841
|
-
return file === "-" ?
|
|
87022
|
+
return file === "-" ? readFileSync28(0, "utf8") : readFileSync28(path67.resolve(io.cwd, file), "utf8");
|
|
86842
87023
|
} catch (error) {
|
|
86843
87024
|
return {
|
|
86844
87025
|
error: `cannot read -F ${file}: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -87252,7 +87433,7 @@ var init_verify = __esm(() => {
|
|
|
87252
87433
|
init_exec();
|
|
87253
87434
|
init_rev();
|
|
87254
87435
|
init_ledger();
|
|
87255
|
-
|
|
87436
|
+
init_report2();
|
|
87256
87437
|
init_redact();
|
|
87257
87438
|
NPM_NAME = /^(?:@[A-Za-z0-9~][A-Za-z0-9-._~]*\/)?[A-Za-z0-9~][A-Za-z0-9-._~]*$/u;
|
|
87258
87439
|
SEMVER2 = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/u;
|
|
@@ -87999,6 +88180,11 @@ async function run19(argv, io) {
|
|
|
87999
88180
|
if (!result.ok)
|
|
88000
88181
|
return forgeFail(io, result);
|
|
88001
88182
|
const report = result.data;
|
|
88183
|
+
if (report.delivered && expect === "merged") {
|
|
88184
|
+
try {
|
|
88185
|
+
closeDeliveredTasks(new TaskStore(io.cwd), new Date().toISOString().replace(/\.\d{3}Z$/, "Z"));
|
|
88186
|
+
} catch {}
|
|
88187
|
+
}
|
|
88002
88188
|
if (report.delivered)
|
|
88003
88189
|
return emit(io, ok2(report), render2);
|
|
88004
88190
|
const failed = report.observations.filter((entry) => !entry.ok);
|
|
@@ -88017,6 +88203,8 @@ var USAGE12 = "workit verify-delivery [push|pr|merge|release] [--expect pushed|p
|
|
|
88017
88203
|
];
|
|
88018
88204
|
var init_verify_delivery = __esm(() => {
|
|
88019
88205
|
init_verify();
|
|
88206
|
+
init_task_store();
|
|
88207
|
+
init_task_delivery();
|
|
88020
88208
|
init_ledger();
|
|
88021
88209
|
init_output();
|
|
88022
88210
|
init_forge_common();
|
|
@@ -88271,15 +88459,15 @@ var init_stack2 = __esm(() => {
|
|
|
88271
88459
|
});
|
|
88272
88460
|
|
|
88273
88461
|
// packages/workit-core/src/fanout-brief.ts
|
|
88274
|
-
import { createHash as
|
|
88462
|
+
import { createHash as createHash20 } from "node:crypto";
|
|
88275
88463
|
import fs35 from "node:fs";
|
|
88276
|
-
import
|
|
88464
|
+
import path68 from "node:path";
|
|
88277
88465
|
function workerSession(lead, slice, attempt) {
|
|
88278
88466
|
const tail = attempt === null ? "" : `+try${attempt}`;
|
|
88279
88467
|
const full = `${lead}-w-${slice}${tail}`;
|
|
88280
88468
|
if (full.length <= SESSION_MAX)
|
|
88281
88469
|
return full;
|
|
88282
|
-
const digest =
|
|
88470
|
+
const digest = createHash20("sha256").update(slice).digest("hex").slice(0, 12);
|
|
88283
88471
|
return `${lead.slice(0, SESSION_MAX - 3 - digest.length - tail.length)}-w-${digest}${tail}`;
|
|
88284
88472
|
}
|
|
88285
88473
|
function renderBrief(cwd, plan, input) {
|
|
@@ -88355,7 +88543,7 @@ function renderBrief(cwd, plan, input) {
|
|
|
88355
88543
|
"STANDING:",
|
|
88356
88544
|
...standing.length ? standing.map((order) => ` - ${order.what}`) : [" - none recorded beyond this brief"],
|
|
88357
88545
|
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)`,
|
|
88358
|
-
...exists && typeof made?.install === "string" && !fs35.existsSync(
|
|
88546
|
+
...exists && typeof made?.install === "string" && !fs35.existsSync(path68.join(planned, "node_modules")) ? [`INSTALL: \`${made.install}\` first: the main checkout's node_modules was not linked here`] : [],
|
|
88359
88547
|
...identityLines(identity, minted),
|
|
88360
88548
|
...rules(mode, branch, slice.base, exists ? planned : null)
|
|
88361
88549
|
];
|
|
@@ -89085,7 +89273,7 @@ var DEFAULT_STUCK_MS, isoOf = (seconds) => {
|
|
|
89085
89273
|
}, newest = (...values) => values.filter((value) => Boolean(value) && !Number.isNaN(Date.parse(value ?? ""))).reduce((best, value) => best === null || Date.parse(value) > Date.parse(best) ? value : best, null);
|
|
89086
89274
|
var init_fanout_status = __esm(() => {
|
|
89087
89275
|
init_duration();
|
|
89088
|
-
|
|
89276
|
+
init_report2();
|
|
89089
89277
|
init_role_models();
|
|
89090
89278
|
init_ledger();
|
|
89091
89279
|
init_fanout_check();
|
|
@@ -89100,7 +89288,7 @@ __export(exports_fanout, {
|
|
|
89100
89288
|
run: () => run21
|
|
89101
89289
|
});
|
|
89102
89290
|
import fs36 from "node:fs";
|
|
89103
|
-
import
|
|
89291
|
+
import path69 from "node:path";
|
|
89104
89292
|
function forgeFor(io, offline) {
|
|
89105
89293
|
if (offline)
|
|
89106
89294
|
return { forge: null, error: "--offline" };
|
|
@@ -89161,7 +89349,7 @@ function plan2(argv, io) {
|
|
|
89161
89349
|
return usage4(io, "pass --trunk or --track, not both (--track picks the trunk)", PLAN_USAGE2);
|
|
89162
89350
|
if (flags.positionals.length !== 1)
|
|
89163
89351
|
return usage4(io, flags.positionals.length ? `unexpected argument ${flags.positionals[1]}` : "missing <plan.json>", PLAN_USAGE2);
|
|
89164
|
-
const file =
|
|
89352
|
+
const file = path69.resolve(io.cwd, flags.positionals[0]);
|
|
89165
89353
|
let raw;
|
|
89166
89354
|
try {
|
|
89167
89355
|
raw = JSON.parse(fs36.readFileSync(file, "utf8"));
|
|
@@ -104704,7 +104892,7 @@ var init_ast = __esm(() => {
|
|
|
104704
104892
|
|
|
104705
104893
|
// packages/workit-cli/src/test-audit/rules.ts
|
|
104706
104894
|
import { builtinModules } from "node:module";
|
|
104707
|
-
import
|
|
104895
|
+
import path70 from "node:path";
|
|
104708
104896
|
function testCallee(call) {
|
|
104709
104897
|
let callee = call.callee;
|
|
104710
104898
|
if (callee.type === "CallExpression")
|
|
@@ -105197,12 +105385,12 @@ function checkConstantsOnly(ctx, emit) {
|
|
|
105197
105385
|
}
|
|
105198
105386
|
function checkOverMocking(ctx, emit) {
|
|
105199
105387
|
const { program } = ctx.parsed;
|
|
105200
|
-
const unit =
|
|
105388
|
+
const unit = path70.basename(ctx.file).replace(/\.(?:[cm]?[jt]sx?)$/, "").replace(/\.(?:test|spec)$/, "");
|
|
105201
105389
|
const mocked = find2(program, (node) => node.type === "CallExpression" && MODULE_MOCK.test(calleeName(node.callee) ?? "") && node.arguments[0]?.type === "StringLiteral");
|
|
105202
105390
|
const internal = mocked.filter((call) => /^(?:\.|@\/|~\/)/.test(call.arguments[0].value));
|
|
105203
105391
|
for (const call of mocked) {
|
|
105204
105392
|
const spec = call.arguments[0].value;
|
|
105205
|
-
const base =
|
|
105393
|
+
const base = path70.basename(spec.replace(/\/index(?:\.[cm]?[jt]sx?)?$/, "")).replace(/\.(?:[cm]?[jt]sx?)$/, "");
|
|
105206
105394
|
if (base === unit)
|
|
105207
105395
|
emit({
|
|
105208
105396
|
rule: "over-mocking",
|
|
@@ -105591,8 +105779,8 @@ var init_rules = __esm(() => {
|
|
|
105591
105779
|
|
|
105592
105780
|
// packages/workit-cli/src/test-audit/audit.ts
|
|
105593
105781
|
import { spawnSync as spawnSync29 } from "node:child_process";
|
|
105594
|
-
import { existsSync as
|
|
105595
|
-
import
|
|
105782
|
+
import { existsSync as existsSync26, readdirSync as readdirSync14, readFileSync as readFileSync29, statSync as statSync10 } from "node:fs";
|
|
105783
|
+
import path71 from "node:path";
|
|
105596
105784
|
function git7(cwd, args) {
|
|
105597
105785
|
const run = spawnSync29("git", ["-c", "core.quotepath=off", ...args], {
|
|
105598
105786
|
cwd,
|
|
@@ -105605,7 +105793,7 @@ function walkTests(dir, out) {
|
|
|
105605
105793
|
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
105606
105794
|
if (entry.name.startsWith(".") && entry.name !== "." && entry.isDirectory())
|
|
105607
105795
|
continue;
|
|
105608
|
-
const full =
|
|
105796
|
+
const full = path71.join(dir, entry.name);
|
|
105609
105797
|
if (entry.isDirectory()) {
|
|
105610
105798
|
if (!SKIP_DIRS.has(entry.name))
|
|
105611
105799
|
walkTests(full, out);
|
|
@@ -105617,8 +105805,8 @@ function expandPaths(cwd, inputs) {
|
|
|
105617
105805
|
const files = [];
|
|
105618
105806
|
const missing = [];
|
|
105619
105807
|
for (const input of inputs.length > 0 ? inputs : ["."]) {
|
|
105620
|
-
const full =
|
|
105621
|
-
if (!
|
|
105808
|
+
const full = path71.resolve(cwd, input);
|
|
105809
|
+
if (!existsSync26(full))
|
|
105622
105810
|
missing.push(input);
|
|
105623
105811
|
else if (statSync10(full).isDirectory())
|
|
105624
105812
|
walkTests(full, files);
|
|
@@ -105654,11 +105842,11 @@ function changedLines(cwd, base) {
|
|
|
105654
105842
|
for (let offset = 0;offset < count; offset += 1)
|
|
105655
105843
|
lines.add(start + offset);
|
|
105656
105844
|
}
|
|
105657
|
-
changed.set(
|
|
105845
|
+
changed.set(path71.join(root, file), lines);
|
|
105658
105846
|
}
|
|
105659
105847
|
const untracked = git7(root, ["ls-files", "--others", "--exclude-standard", "-z"]);
|
|
105660
105848
|
for (const file of untracked.stdout.split("\x00").filter(Boolean))
|
|
105661
|
-
changed.set(
|
|
105849
|
+
changed.set(path71.join(root, file), "all");
|
|
105662
105850
|
return changed;
|
|
105663
105851
|
}
|
|
105664
105852
|
function auditFiles(files, display) {
|
|
@@ -105671,7 +105859,7 @@ function auditFiles(files, display) {
|
|
|
105671
105859
|
const shown = display(file);
|
|
105672
105860
|
let parsed;
|
|
105673
105861
|
try {
|
|
105674
|
-
parsed = parseSource(
|
|
105862
|
+
parsed = parseSource(readFileSync29(file, "utf8"), file);
|
|
105675
105863
|
} catch (error) {
|
|
105676
105864
|
parseErrors.push({
|
|
105677
105865
|
file: shown,
|
|
@@ -105720,7 +105908,7 @@ function auditFiles(files, display) {
|
|
|
105720
105908
|
durationMs: Math.round(performance.now() - started)
|
|
105721
105909
|
};
|
|
105722
105910
|
}
|
|
105723
|
-
var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(
|
|
105911
|
+
var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(path71.sep).join("/"), SEVERITY_ORDER, ruleIds;
|
|
105724
105912
|
var init_audit = __esm(() => {
|
|
105725
105913
|
init_ast();
|
|
105726
105914
|
init_rules();
|
|
@@ -105734,23 +105922,23 @@ var init_audit = __esm(() => {
|
|
|
105734
105922
|
// packages/workit-cli/src/test-audit/mutate.ts
|
|
105735
105923
|
import { spawn as spawn2 } from "node:child_process";
|
|
105736
105924
|
import {
|
|
105737
|
-
existsSync as
|
|
105925
|
+
existsSync as existsSync27,
|
|
105738
105926
|
lstatSync as lstatSync8,
|
|
105739
105927
|
mkdirSync as mkdirSync12,
|
|
105740
105928
|
mkdtempSync as mkdtempSync4,
|
|
105741
105929
|
readdirSync as readdirSync15,
|
|
105742
|
-
readFileSync as
|
|
105930
|
+
readFileSync as readFileSync30,
|
|
105743
105931
|
readlinkSync as readlinkSync3,
|
|
105744
105932
|
realpathSync as realpathSync10,
|
|
105745
105933
|
renameSync as renameSync7,
|
|
105746
105934
|
rmSync as rmSync9,
|
|
105747
105935
|
statSync as statSync11,
|
|
105748
105936
|
symlinkSync,
|
|
105749
|
-
writeFileSync as
|
|
105937
|
+
writeFileSync as writeFileSync13,
|
|
105750
105938
|
copyFileSync as copyFileSync8
|
|
105751
105939
|
} from "node:fs";
|
|
105752
|
-
import
|
|
105753
|
-
import
|
|
105940
|
+
import os23 from "node:os";
|
|
105941
|
+
import path72 from "node:path";
|
|
105754
105942
|
function mutantsFor(source, file, lines) {
|
|
105755
105943
|
const parsed = parseSource(source, file);
|
|
105756
105944
|
const out = [];
|
|
@@ -105823,7 +106011,7 @@ function relatedTests(source, testFiles) {
|
|
|
105823
106011
|
for (const match of text.matchAll(SPECIFIER)) {
|
|
105824
106012
|
const spec = match[1];
|
|
105825
106013
|
if (spec.startsWith(".")) {
|
|
105826
|
-
if (stripExt(
|
|
106014
|
+
if (stripExt(path72.posix.join(path72.posix.dirname(file), spec)) === target)
|
|
105827
106015
|
return true;
|
|
105828
106016
|
} else if (spec.includes("/") && stripExt(spec).split("/").slice(-2).join("/") === tail)
|
|
105829
106017
|
return true;
|
|
@@ -105831,7 +106019,7 @@ function relatedTests(source, testFiles) {
|
|
|
105831
106019
|
return false;
|
|
105832
106020
|
}).map((entry) => entry.file);
|
|
105833
106021
|
}
|
|
105834
|
-
function removeStaleCopies(tmp =
|
|
106022
|
+
function removeStaleCopies(tmp = os23.tmpdir()) {
|
|
105835
106023
|
let removed = 0;
|
|
105836
106024
|
let names = [];
|
|
105837
106025
|
try {
|
|
@@ -105843,12 +106031,12 @@ function removeStaleCopies(tmp = os22.tmpdir()) {
|
|
|
105843
106031
|
for (const name of names) {
|
|
105844
106032
|
if (!name.startsWith(TEMP_PREFIX))
|
|
105845
106033
|
continue;
|
|
105846
|
-
const dir =
|
|
106034
|
+
const dir = path72.join(tmp, name);
|
|
105847
106035
|
try {
|
|
105848
106036
|
const stat = lstatSync8(dir);
|
|
105849
106037
|
if (!stat.isDirectory() || uid !== undefined && stat.uid !== uid)
|
|
105850
106038
|
continue;
|
|
105851
|
-
const pid = Number(
|
|
106039
|
+
const pid = Number(readFileSync30(path72.join(dir, PID_FILE), "utf8"));
|
|
105852
106040
|
if (Number.isInteger(pid) && pid > 0 && alive(pid))
|
|
105853
106041
|
continue;
|
|
105854
106042
|
} catch (error) {
|
|
@@ -105865,8 +106053,8 @@ function removeStaleCopies(tmp = os22.tmpdir()) {
|
|
|
105865
106053
|
function linkNodeModules(origin, target, repo, copy) {
|
|
105866
106054
|
mkdirSync12(target, { recursive: true });
|
|
105867
106055
|
for (const entry of readdirSync15(origin, { withFileTypes: true })) {
|
|
105868
|
-
const from =
|
|
105869
|
-
const to =
|
|
106056
|
+
const from = path72.join(origin, entry.name);
|
|
106057
|
+
const to = path72.join(target, entry.name);
|
|
105870
106058
|
if (entry.name.startsWith("@") && entry.isDirectory()) {
|
|
105871
106059
|
linkNodeModules(from, to, repo, copy);
|
|
105872
106060
|
continue;
|
|
@@ -105882,9 +106070,9 @@ function linkNodeModules(origin, target, repo, copy) {
|
|
|
105882
106070
|
} catch {
|
|
105883
106071
|
continue;
|
|
105884
106072
|
}
|
|
105885
|
-
const relative =
|
|
105886
|
-
if (!relative.startsWith("..") && !
|
|
105887
|
-
symlinkSync(
|
|
106073
|
+
const relative = path72.relative(repo, real);
|
|
106074
|
+
if (!relative.startsWith("..") && !path72.isAbsolute(relative) && !relative.split(path72.sep).includes("node_modules")) {
|
|
106075
|
+
symlinkSync(path72.join(copy, relative), to, "junction");
|
|
105888
106076
|
continue;
|
|
105889
106077
|
}
|
|
105890
106078
|
}
|
|
@@ -105900,7 +106088,7 @@ function copySymlink(repo, tree, from, to) {
|
|
|
105900
106088
|
}
|
|
105901
106089
|
const realRepo = realpathSync10(repo);
|
|
105902
106090
|
if (real && inside5(realRepo, real)) {
|
|
105903
|
-
symlinkSync(
|
|
106091
|
+
symlinkSync(path72.relative(path72.dirname(to), path72.join(tree, path72.relative(realRepo, real))), to);
|
|
105904
106092
|
return;
|
|
105905
106093
|
}
|
|
105906
106094
|
if (real && statSync11(real).isFile())
|
|
@@ -105909,23 +106097,23 @@ function copySymlink(repo, tree, from, to) {
|
|
|
105909
106097
|
symlinkSync(readlinkSync3(from), to);
|
|
105910
106098
|
}
|
|
105911
106099
|
function writeInside(copy, file, content) {
|
|
105912
|
-
const target =
|
|
106100
|
+
const target = path72.join(copy, file);
|
|
105913
106101
|
try {
|
|
105914
106102
|
const stat = lstatSync8(target);
|
|
105915
|
-
if (!stat.isFile() || !inside5(realpathSync10(copy), realpathSync10(
|
|
106103
|
+
if (!stat.isFile() || !inside5(realpathSync10(copy), realpathSync10(path72.dirname(target))))
|
|
105916
106104
|
return false;
|
|
105917
106105
|
} catch {
|
|
105918
106106
|
return false;
|
|
105919
106107
|
}
|
|
105920
106108
|
const temp = `${target}.workit-mutant-${process.pid}`;
|
|
105921
|
-
|
|
106109
|
+
writeFileSync13(temp, content);
|
|
105922
106110
|
renameSync7(temp, target);
|
|
105923
106111
|
return true;
|
|
105924
106112
|
}
|
|
105925
106113
|
function copyWorkingTree(repo) {
|
|
105926
|
-
const dir = mkdtempSync4(
|
|
105927
|
-
|
|
105928
|
-
const tree =
|
|
106114
|
+
const dir = mkdtempSync4(path72.join(os23.tmpdir(), TEMP_PREFIX));
|
|
106115
|
+
writeFileSync13(path72.join(dir, PID_FILE), String(process.pid));
|
|
106116
|
+
const tree = path72.join(dir, "tree");
|
|
105929
106117
|
const head = git7(repo, ["rev-parse", "--verify", "--quiet", "HEAD"]).stdout.trim();
|
|
105930
106118
|
if (head && git7(dir, ["clone", "-q", "--shared", "--no-checkout", repo, tree]).ok) {
|
|
105931
106119
|
const branch = git7(repo, ["symbolic-ref", "--quiet", "--short", "HEAD"]).stdout.trim();
|
|
@@ -105942,29 +106130,29 @@ function copyWorkingTree(repo) {
|
|
|
105942
106130
|
for (const relative of listed) {
|
|
105943
106131
|
if (!relative)
|
|
105944
106132
|
continue;
|
|
105945
|
-
const from =
|
|
106133
|
+
const from = path72.join(repo, relative);
|
|
105946
106134
|
let stat;
|
|
105947
106135
|
try {
|
|
105948
106136
|
stat = lstatSync8(from);
|
|
105949
106137
|
} catch {
|
|
105950
106138
|
continue;
|
|
105951
106139
|
}
|
|
105952
|
-
const to =
|
|
105953
|
-
mkdirSync12(
|
|
106140
|
+
const to = path72.join(tree, relative);
|
|
106141
|
+
mkdirSync12(path72.dirname(to), { recursive: true });
|
|
105954
106142
|
if (stat.isSymbolicLink())
|
|
105955
106143
|
copySymlink(repo, tree, from, to);
|
|
105956
106144
|
else if (stat.isFile())
|
|
105957
106145
|
copyFileSync8(from, to);
|
|
105958
|
-
let parent =
|
|
106146
|
+
let parent = path72.dirname(relative);
|
|
105959
106147
|
while (parent !== "." && !dirs.has(parent)) {
|
|
105960
106148
|
dirs.add(parent);
|
|
105961
|
-
parent =
|
|
106149
|
+
parent = path72.dirname(parent);
|
|
105962
106150
|
}
|
|
105963
106151
|
}
|
|
105964
106152
|
for (const parent of dirs) {
|
|
105965
|
-
const modules =
|
|
105966
|
-
if (
|
|
105967
|
-
linkNodeModules(modules,
|
|
106153
|
+
const modules = path72.join(repo, parent, "node_modules");
|
|
106154
|
+
if (existsSync27(modules) && !existsSync27(path72.join(tree, parent, "node_modules")))
|
|
106155
|
+
linkNodeModules(modules, path72.join(tree, parent, "node_modules"), repo, tree);
|
|
105968
106156
|
}
|
|
105969
106157
|
return { dir, tree };
|
|
105970
106158
|
}
|
|
@@ -106003,20 +106191,20 @@ async function runMutation(options) {
|
|
|
106003
106191
|
const tracked = git7(repo, ["ls-files", "-co", "--exclude-standard", "-z"]).stdout.split("\x00").filter(Boolean);
|
|
106004
106192
|
const testFiles = tracked.filter((file) => TEST_FILE.test(file)).map((file) => {
|
|
106005
106193
|
try {
|
|
106006
|
-
return { file, text:
|
|
106194
|
+
return { file, text: readFileSync30(path72.join(repo, file), "utf8") };
|
|
106007
106195
|
} catch {
|
|
106008
106196
|
return { file, text: "" };
|
|
106009
106197
|
}
|
|
106010
106198
|
});
|
|
106011
106199
|
const candidates = [];
|
|
106012
106200
|
for (const [absolute, lines] of [...options.changed].toSorted(([a], [b]) => a.localeCompare(b))) {
|
|
106013
|
-
const relative = toPosix(
|
|
106201
|
+
const relative = toPosix(path72.relative(repo, absolute));
|
|
106014
106202
|
if (!CODE_FILE.test(relative) || TEST_FILE.test(relative) || relative.endsWith(".d.ts"))
|
|
106015
106203
|
continue;
|
|
106016
|
-
if (NOT_SOURCE.test(relative) || !
|
|
106204
|
+
if (NOT_SOURCE.test(relative) || !existsSync27(absolute))
|
|
106017
106205
|
continue;
|
|
106018
106206
|
try {
|
|
106019
|
-
candidates.push(...mutantsFor(
|
|
106207
|
+
candidates.push(...mutantsFor(readFileSync30(absolute, "utf8"), relative, lines));
|
|
106020
106208
|
} catch {}
|
|
106021
106209
|
}
|
|
106022
106210
|
const mutants = candidates.map((mutant, index) => ({ ...mutant, id: index + 1 }));
|
|
@@ -106024,9 +106212,9 @@ async function runMutation(options) {
|
|
|
106024
106212
|
for (const mutant of mutants)
|
|
106025
106213
|
if (!related.has(mutant.file))
|
|
106026
106214
|
related.set(mutant.file, relatedTests(mutant.file, testFiles));
|
|
106027
|
-
const cwdRelative =
|
|
106215
|
+
const cwdRelative = path72.relative(repo, options.cwd);
|
|
106028
106216
|
const asArg = (file) => {
|
|
106029
|
-
const relative = toPosix(
|
|
106217
|
+
const relative = toPosix(path72.relative(cwdRelative, file));
|
|
106030
106218
|
return shellQuote(relative.startsWith(".") ? relative : `./${relative}`);
|
|
106031
106219
|
};
|
|
106032
106220
|
const commandFor = (tests) => options.command.replaceAll("{files}", () => tests.map(asArg).join(" "));
|
|
@@ -106062,7 +106250,7 @@ async function runMutation(options) {
|
|
|
106062
106250
|
return finish3(options, 0, results, counts, started);
|
|
106063
106251
|
removeStaleCopies();
|
|
106064
106252
|
const { dir: copyDir, tree: copy } = copyWorkingTree(repo);
|
|
106065
|
-
const copyCwd =
|
|
106253
|
+
const copyCwd = path72.join(copy, cwdRelative);
|
|
106066
106254
|
let current = null;
|
|
106067
106255
|
const restore = () => {
|
|
106068
106256
|
if (current)
|
|
@@ -106097,7 +106285,7 @@ async function runMutation(options) {
|
|
|
106097
106285
|
record({ ...mutant, status: "skipped", durationMs: 0, tests, reason: "budget" });
|
|
106098
106286
|
continue;
|
|
106099
106287
|
}
|
|
106100
|
-
const original =
|
|
106288
|
+
const original = readFileSync30(path72.join(copy, mutant.file), "utf8");
|
|
106101
106289
|
const mutated = original.slice(0, mutant.start) + mutant.replacement + original.slice(mutant.end);
|
|
106102
106290
|
current = { file: mutant.file, original };
|
|
106103
106291
|
if (!writeInside(copy, mutant.file, mutated)) {
|
|
@@ -106154,8 +106342,8 @@ var NOT_SOURCE, FLIPS, isStringy = (node) => node.type === "StringLiteral" || no
|
|
|
106154
106342
|
return error.code === "EPERM";
|
|
106155
106343
|
}
|
|
106156
106344
|
}, inside5 = (root, file) => {
|
|
106157
|
-
const relative =
|
|
106158
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
106345
|
+
const relative = path72.relative(root, file);
|
|
106346
|
+
return relative === "" || !relative.startsWith("..") && !path72.isAbsolute(relative);
|
|
106159
106347
|
}, active, killTree = (child) => {
|
|
106160
106348
|
try {
|
|
106161
106349
|
if (child.pid && process.platform !== "win32")
|
|
@@ -106203,8 +106391,8 @@ var exports_test_audit = {};
|
|
|
106203
106391
|
__export(exports_test_audit, {
|
|
106204
106392
|
run: () => run23
|
|
106205
106393
|
});
|
|
106206
|
-
import { existsSync as
|
|
106207
|
-
import
|
|
106394
|
+
import { existsSync as existsSync28 } from "node:fs";
|
|
106395
|
+
import path73 from "node:path";
|
|
106208
106396
|
function parse8(argv) {
|
|
106209
106397
|
const options = {
|
|
106210
106398
|
paths: [],
|
|
@@ -106309,8 +106497,8 @@ async function run23(argv, io) {
|
|
|
106309
106497
|
return emit(io, fail2("invalid_input", `${options}
|
|
106310
106498
|
usage: ${USAGE16}`));
|
|
106311
106499
|
const top = git7(io.cwd, ["rev-parse", "--show-toplevel"]);
|
|
106312
|
-
const repo = top.ok ?
|
|
106313
|
-
const display = (file) => toPosix(
|
|
106500
|
+
const repo = top.ok ? path73.resolve(top.stdout.trim()) : null;
|
|
106501
|
+
const display = (file) => toPosix(path73.relative(io.cwd, file) || file);
|
|
106314
106502
|
let base = null;
|
|
106315
106503
|
let changed = null;
|
|
106316
106504
|
if (options.diff || options.mutate) {
|
|
@@ -106327,7 +106515,7 @@ usage: ${USAGE16}`));
|
|
|
106327
106515
|
}
|
|
106328
106516
|
let files;
|
|
106329
106517
|
if (options.diff && changed)
|
|
106330
|
-
files = [...changed.keys()].filter((file) => TEST_FILE.test(toPosix(file)) &&
|
|
106518
|
+
files = [...changed.keys()].filter((file) => TEST_FILE.test(toPosix(file)) && existsSync28(file)).toSorted();
|
|
106331
106519
|
else {
|
|
106332
106520
|
const expanded = expandPaths(io.cwd, options.paths);
|
|
106333
106521
|
if (expanded.missing.length > 0)
|
|
@@ -106448,8 +106636,8 @@ var exports_youtrack = {};
|
|
|
106448
106636
|
__export(exports_youtrack, {
|
|
106449
106637
|
run: () => run25
|
|
106450
106638
|
});
|
|
106451
|
-
import { readFileSync as
|
|
106452
|
-
import
|
|
106639
|
+
import { readFileSync as readFileSync31 } from "node:fs";
|
|
106640
|
+
import path74 from "node:path";
|
|
106453
106641
|
async function run25(argv, io) {
|
|
106454
106642
|
const [sub, ...rest] = argv;
|
|
106455
106643
|
if (sub !== "note" && sub !== "time" && sub !== "meeting")
|
|
@@ -106495,7 +106683,7 @@ async function run25(argv, io) {
|
|
|
106495
106683
|
let markdown = flags.values.markdown ?? "";
|
|
106496
106684
|
if (flags.values.file)
|
|
106497
106685
|
try {
|
|
106498
|
-
markdown =
|
|
106686
|
+
markdown = readFileSync31(path74.resolve(io.cwd, flags.values.file), "utf8");
|
|
106499
106687
|
} catch (error) {
|
|
106500
106688
|
return usage4(io, `cannot read ${flags.values.file}: ${String(error)}`, USAGE18);
|
|
106501
106689
|
}
|
|
@@ -106563,8 +106751,8 @@ var exports_changelog = {};
|
|
|
106563
106751
|
__export(exports_changelog, {
|
|
106564
106752
|
run: () => run26
|
|
106565
106753
|
});
|
|
106566
|
-
import { readFileSync as
|
|
106567
|
-
import
|
|
106754
|
+
import { readFileSync as readFileSync32 } from "node:fs";
|
|
106755
|
+
import path75 from "node:path";
|
|
106568
106756
|
async function run26(argv, io) {
|
|
106569
106757
|
const [sub, ...rest] = argv;
|
|
106570
106758
|
if (sub !== "apply")
|
|
@@ -106610,7 +106798,7 @@ async function run26(argv, io) {
|
|
|
106610
106798
|
]);
|
|
106611
106799
|
}
|
|
106612
106800
|
var USAGE19 = "workit changelog apply (--entries <JSON|@file|-> | --normalize-only) [--path CHANGELOG.md] [--preview]", readEntries = (raw, cwd) => {
|
|
106613
|
-
const text = raw === "-" ?
|
|
106801
|
+
const text = raw === "-" ? readFileSync32(0, "utf8") : raw.startsWith("@") ? readFileSync32(path75.resolve(cwd, raw.slice(1)), "utf8") : raw;
|
|
106614
106802
|
return JSON.parse(text);
|
|
106615
106803
|
};
|
|
106616
106804
|
var init_changelog2 = __esm(() => {
|
|
@@ -106626,7 +106814,7 @@ __export(exports_handoff, {
|
|
|
106626
106814
|
run: () => run27
|
|
106627
106815
|
});
|
|
106628
106816
|
import fs37 from "node:fs";
|
|
106629
|
-
import
|
|
106817
|
+
import path76 from "node:path";
|
|
106630
106818
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
106631
106819
|
function render3(brief) {
|
|
106632
106820
|
const lines = [
|
|
@@ -106666,9 +106854,9 @@ function bounded(brief, cwd) {
|
|
|
106666
106854
|
let file = null;
|
|
106667
106855
|
if (store.ok)
|
|
106668
106856
|
try {
|
|
106669
|
-
const dir =
|
|
106857
|
+
const dir = path76.join(store.value.root, "handoff");
|
|
106670
106858
|
fs37.mkdirSync(dir, { recursive: true });
|
|
106671
|
-
file =
|
|
106859
|
+
file = path76.join(dir, `${(brief.branch ?? "detached").replaceAll(/[^\w.-]+/gu, "-")}.txt`);
|
|
106672
106860
|
fs37.writeFileSync(file, `${[...body, ...tail].join(`
|
|
106673
106861
|
`)}
|
|
106674
106862
|
`, {
|
|
@@ -106745,7 +106933,7 @@ var init_handoff = __esm(() => {
|
|
|
106745
106933
|
// packages/workit-cli/src/main.ts
|
|
106746
106934
|
init_host_session();
|
|
106747
106935
|
init_package();
|
|
106748
|
-
import
|
|
106936
|
+
import path77 from "node:path";
|
|
106749
106937
|
|
|
106750
106938
|
// packages/workit-cli/src/verbs/registry.ts
|
|
106751
106939
|
var TASK_FAMILY_NAMES = [
|
|
@@ -107657,7 +107845,7 @@ var defaultIo = (json) => ({
|
|
|
107657
107845
|
});
|
|
107658
107846
|
async function main(argv, overrides = {}, options = {}) {
|
|
107659
107847
|
const parsed = parseGlobals(argv);
|
|
107660
|
-
const cwd =
|
|
107848
|
+
const cwd = path77.resolve(overrides.cwd ?? process.cwd(), parsed.cwd ?? ".");
|
|
107661
107849
|
const io = { ...defaultIo(parsed.json), ...overrides, json: parsed.json, cwd };
|
|
107662
107850
|
if (parsed.error)
|
|
107663
107851
|
return emit(io, fail2("invalid_input", parsed.error));
|