@brainervirus/workit-cli 8.38.3 → 8.38.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +454 -189
- package/package.json +3 -3
package/dist/index.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.5",
|
|
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.5",
|
|
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.5"
|
|
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",
|
|
@@ -74839,7 +74918,7 @@ var init_setup2 = __esm(() => {
|
|
|
74839
74918
|
});
|
|
74840
74919
|
|
|
74841
74920
|
// packages/workit-cli/src/upgrade/shared.ts
|
|
74842
|
-
import { existsSync as existsSync20, readFileSync as
|
|
74921
|
+
import { existsSync as existsSync20, readFileSync as readFileSync22 } from "node:fs";
|
|
74843
74922
|
import path44 from "node:path";
|
|
74844
74923
|
import os16 from "node:os";
|
|
74845
74924
|
import { createHash as createHash15 } from "node:crypto";
|
|
@@ -74876,7 +74955,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
74876
74955
|
return null;
|
|
74877
74956
|
let data;
|
|
74878
74957
|
try {
|
|
74879
|
-
data = JSON.parse(
|
|
74958
|
+
data = JSON.parse(readFileSync22(file, "utf8"));
|
|
74880
74959
|
} catch {
|
|
74881
74960
|
throw new Error(`${file} is not valid JSON; use the native host to inspect JSONC settings`);
|
|
74882
74961
|
}
|
|
@@ -74889,7 +74968,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
74889
74968
|
} catch {
|
|
74890
74969
|
return null;
|
|
74891
74970
|
}
|
|
74892
|
-
}, digest2 = (file) => existsSync20(file) ? createHash15("sha256").update(
|
|
74971
|
+
}, digest2 = (file) => existsSync20(file) ? createHash15("sha256").update(readFileSync22(file)).digest("hex") : "missing", runner = (deps) => deps.run ?? ((command, args) => {
|
|
74893
74972
|
const { home, env } = upgradePaths(deps);
|
|
74894
74973
|
let step;
|
|
74895
74974
|
try {
|
|
@@ -75350,7 +75429,7 @@ var init_apply = __esm(() => {
|
|
|
75350
75429
|
});
|
|
75351
75430
|
|
|
75352
75431
|
// packages/workit-cli/src/upgrade/plan.ts
|
|
75353
|
-
import { existsSync as existsSync22, mkdtempSync as mkdtempSync3, rmSync as rmSync8, lstatSync as lstatSync7, readFileSync as
|
|
75432
|
+
import { existsSync as existsSync22, mkdtempSync as mkdtempSync3, rmSync as rmSync8, lstatSync as lstatSync7, readFileSync as readFileSync23 } from "node:fs";
|
|
75354
75433
|
import path47 from "node:path";
|
|
75355
75434
|
import os17 from "node:os";
|
|
75356
75435
|
function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
@@ -75504,7 +75583,7 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
|
75504
75583
|
var codexRegistered = (configFile) => {
|
|
75505
75584
|
let text;
|
|
75506
75585
|
try {
|
|
75507
|
-
text =
|
|
75586
|
+
text = readFileSync23(configFile, "utf8");
|
|
75508
75587
|
} catch {
|
|
75509
75588
|
return false;
|
|
75510
75589
|
}
|
|
@@ -77790,6 +77869,7 @@ function resolveResourceSettings(sources, host = hostShape()) {
|
|
|
77790
77869
|
const settings = {
|
|
77791
77870
|
slots: DEFAULT_SLOTS,
|
|
77792
77871
|
heavy: [...DEFAULT_HEAVY_CHECKS],
|
|
77872
|
+
light: [...DEFAULT_LIGHT_CHECKS],
|
|
77793
77873
|
memoryMax: "",
|
|
77794
77874
|
cpuQuota: "",
|
|
77795
77875
|
waitMs: DEFAULT_WAIT_S * 1000,
|
|
@@ -77831,8 +77911,21 @@ function resolveResourceSettings(sources, host = hostShape()) {
|
|
|
77831
77911
|
const heavy = isRecord9(value.heavy) ? Object.keys(value.heavy) : value.heavy;
|
|
77832
77912
|
if (!Array.isArray(heavy) || !heavy.every((item) => typeof item === "string"))
|
|
77833
77913
|
warn("heavy", "must be a list of check names");
|
|
77834
|
-
else
|
|
77914
|
+
else {
|
|
77835
77915
|
settings.heavy = repo ? [...new Set([...settings.heavy, ...heavy])] : heavy;
|
|
77916
|
+
settings.light = settings.light.filter((name) => !heavy.includes(name));
|
|
77917
|
+
}
|
|
77918
|
+
}
|
|
77919
|
+
if (value.light !== undefined) {
|
|
77920
|
+
const light = value.light;
|
|
77921
|
+
if (repo)
|
|
77922
|
+
machineOnly("light");
|
|
77923
|
+
else if (!Array.isArray(light) || !light.every((item) => typeof item === "string"))
|
|
77924
|
+
warn("light", "must be a list of check names");
|
|
77925
|
+
else {
|
|
77926
|
+
settings.light = light;
|
|
77927
|
+
settings.heavy = settings.heavy.filter((name) => !light.includes(name));
|
|
77928
|
+
}
|
|
77836
77929
|
}
|
|
77837
77930
|
if (value.memoryMax !== undefined) {
|
|
77838
77931
|
const next = memoryValue(value.memoryMax, host);
|
|
@@ -77853,10 +77946,11 @@ function resolveResourceSettings(sources, host = hostShape()) {
|
|
|
77853
77946
|
cpu = next;
|
|
77854
77947
|
}
|
|
77855
77948
|
if (value.wait !== undefined) {
|
|
77856
|
-
|
|
77857
|
-
|
|
77949
|
+
const wait = typeof value.wait === "number" ? value.wait >= 0 ? value.wait * 1000 : null : typeof value.wait === "string" ? parseWait(value.wait) : null;
|
|
77950
|
+
if (wait !== null)
|
|
77951
|
+
settings.waitMs = wait;
|
|
77858
77952
|
else
|
|
77859
|
-
warn("wait",
|
|
77953
|
+
warn("wait", 'must be a number of seconds or a duration ("30m")');
|
|
77860
77954
|
}
|
|
77861
77955
|
}
|
|
77862
77956
|
settings.memoryMax = String(memory);
|
|
@@ -77974,7 +78068,65 @@ function removeOwn(file, id) {
|
|
|
77974
78068
|
if (parseLease(readText5(file))?.id === id)
|
|
77975
78069
|
fs24.rmSync(file, { force: true });
|
|
77976
78070
|
}
|
|
78071
|
+
function leaseQueue(dir, probe = {}) {
|
|
78072
|
+
let names;
|
|
78073
|
+
try {
|
|
78074
|
+
names = fs24.readdirSync(queueDir(dir));
|
|
78075
|
+
} catch {
|
|
78076
|
+
return [];
|
|
78077
|
+
}
|
|
78078
|
+
const entries = [];
|
|
78079
|
+
for (const name of names.filter((item) => item.endsWith(".json")).toSorted()) {
|
|
78080
|
+
const file = path52.join(queueDir(dir), name);
|
|
78081
|
+
const record = parseLease(readText5(file));
|
|
78082
|
+
if (!record)
|
|
78083
|
+
continue;
|
|
78084
|
+
entries.push({
|
|
78085
|
+
file,
|
|
78086
|
+
holder: holderOf(record),
|
|
78087
|
+
id: record.id,
|
|
78088
|
+
stale: staleReason(record, probe)
|
|
78089
|
+
});
|
|
78090
|
+
}
|
|
78091
|
+
return entries;
|
|
78092
|
+
}
|
|
78093
|
+
function waitersAhead(options, own) {
|
|
78094
|
+
let ahead = 0;
|
|
78095
|
+
for (const entry of leaseQueue(options.dir, options.probe)) {
|
|
78096
|
+
if (path52.basename(entry.file) >= own)
|
|
78097
|
+
break;
|
|
78098
|
+
if (!TICKET.test(path52.basename(entry.file)))
|
|
78099
|
+
continue;
|
|
78100
|
+
if (entry.stale && reclaim(entry.file, (current) => !current || staleReason(current, options.probe) !== null))
|
|
78101
|
+
continue;
|
|
78102
|
+
ahead += 1;
|
|
78103
|
+
}
|
|
78104
|
+
return ahead;
|
|
78105
|
+
}
|
|
78106
|
+
function liveHolders(options) {
|
|
78107
|
+
return leaseSlots(options.dir, options.slots, options.probe).filter((slot) => slot.holder && !slot.stale).map((slot) => slot.holder);
|
|
78108
|
+
}
|
|
78109
|
+
function writeTicket(file, record) {
|
|
78110
|
+
fs24.mkdirSync(path52.dirname(file), { recursive: true, mode: 448 });
|
|
78111
|
+
fs24.writeFileSync(file, `${JSON.stringify(record)}
|
|
78112
|
+
`, { mode: 384 });
|
|
78113
|
+
}
|
|
78114
|
+
function parseWait(text) {
|
|
78115
|
+
const match = /^(\d+(?:\.\d+)?)([smh]?)$/u.exec(text.trim());
|
|
78116
|
+
if (!match)
|
|
78117
|
+
return null;
|
|
78118
|
+
const unit = { "": 1000, s: 1000, m: 60000, h: 3600000 }[match[2]] ?? 1000;
|
|
78119
|
+
return Math.round(Number(match[1]) * unit);
|
|
78120
|
+
}
|
|
78121
|
+
function formatWait(ms) {
|
|
78122
|
+
const seconds = Math.max(0, Math.round(ms / 1000));
|
|
78123
|
+
if (seconds < 60)
|
|
78124
|
+
return `${seconds}s`;
|
|
78125
|
+
const minutes = Math.floor(seconds / 60);
|
|
78126
|
+
return seconds % 60 ? `${minutes}m ${seconds % 60}s` : `${minutes}m`;
|
|
78127
|
+
}
|
|
77977
78128
|
async function acquireLease(options) {
|
|
78129
|
+
const clock = options.clock ?? realClock;
|
|
77978
78130
|
const pid = options.pid ?? process.pid;
|
|
77979
78131
|
const boot = bootId();
|
|
77980
78132
|
const record = {
|
|
@@ -77988,7 +78140,7 @@ async function acquireLease(options) {
|
|
|
77988
78140
|
check: options.check,
|
|
77989
78141
|
cwd: options.cwd,
|
|
77990
78142
|
session: options.session,
|
|
77991
|
-
startedAt: new Date().toISOString(),
|
|
78143
|
+
startedAt: new Date(clock.now()).toISOString(),
|
|
77992
78144
|
scope: null
|
|
77993
78145
|
};
|
|
77994
78146
|
try {
|
|
@@ -77996,48 +78148,104 @@ async function acquireLease(options) {
|
|
|
77996
78148
|
} catch (error) {
|
|
77997
78149
|
return { ok: false, reason: "unavailable", error: error.message };
|
|
77998
78150
|
}
|
|
77999
|
-
const started =
|
|
78151
|
+
const started = clock.now();
|
|
78000
78152
|
const reclaimed = [];
|
|
78001
78153
|
let waitedOn = [];
|
|
78002
|
-
|
|
78003
|
-
|
|
78004
|
-
|
|
78005
|
-
|
|
78006
|
-
|
|
78007
|
-
|
|
78008
|
-
|
|
78009
|
-
|
|
78010
|
-
|
|
78011
|
-
|
|
78012
|
-
|
|
78013
|
-
|
|
78014
|
-
|
|
78015
|
-
|
|
78016
|
-
|
|
78017
|
-
|
|
78018
|
-
|
|
78019
|
-
|
|
78020
|
-
|
|
78021
|
-
|
|
78022
|
-
|
|
78023
|
-
|
|
78024
|
-
|
|
78025
|
-
|
|
78026
|
-
|
|
78027
|
-
|
|
78028
|
-
|
|
78029
|
-
|
|
78154
|
+
const name = ticketName(started, record.id);
|
|
78155
|
+
const ticket = path52.join(queueDir(options.dir), name);
|
|
78156
|
+
const ticketRecord = {
|
|
78157
|
+
...record,
|
|
78158
|
+
maxAgeMs: options.waitMs + 60000
|
|
78159
|
+
};
|
|
78160
|
+
let queued = false;
|
|
78161
|
+
const onSignal = (signal) => {
|
|
78162
|
+
leave();
|
|
78163
|
+
process.exit(signal === "SIGINT" ? 130 : 143);
|
|
78164
|
+
};
|
|
78165
|
+
const leave = () => {
|
|
78166
|
+
process.off("exit", leave);
|
|
78167
|
+
process.off("SIGINT", onSignal);
|
|
78168
|
+
process.off("SIGTERM", onSignal);
|
|
78169
|
+
if (queued)
|
|
78170
|
+
removeOwn(ticket, record.id);
|
|
78171
|
+
queued = false;
|
|
78172
|
+
};
|
|
78173
|
+
let nextStatus = 0;
|
|
78174
|
+
try {
|
|
78175
|
+
for (;; ) {
|
|
78176
|
+
const waited = clock.now() - started;
|
|
78177
|
+
const ahead = queued ? waitersAhead(options, name) : waitersAhead(options, "~");
|
|
78178
|
+
const free = options.slots - liveHolders(options).length;
|
|
78179
|
+
if (ahead < free) {
|
|
78180
|
+
const outcome = tryOnce(options, record, reclaimed);
|
|
78181
|
+
if ("slot" in outcome) {
|
|
78182
|
+
const waitedMs = queued ? waited : 0;
|
|
78183
|
+
leave();
|
|
78184
|
+
const { file, slot } = outcome;
|
|
78185
|
+
let released = false;
|
|
78186
|
+
const release = () => {
|
|
78187
|
+
if (released)
|
|
78188
|
+
return;
|
|
78189
|
+
released = true;
|
|
78190
|
+
process.off("exit", release);
|
|
78191
|
+
removeOwn(file, record.id);
|
|
78192
|
+
};
|
|
78193
|
+
process.on("exit", release);
|
|
78194
|
+
return {
|
|
78195
|
+
ok: true,
|
|
78196
|
+
lease: {
|
|
78197
|
+
record,
|
|
78198
|
+
slot,
|
|
78199
|
+
file,
|
|
78200
|
+
waitedOn,
|
|
78201
|
+
waitedMs,
|
|
78202
|
+
reclaimed,
|
|
78203
|
+
release
|
|
78204
|
+
}
|
|
78205
|
+
};
|
|
78030
78206
|
}
|
|
78031
|
-
}
|
|
78032
|
-
|
|
78033
|
-
|
|
78034
|
-
|
|
78035
|
-
|
|
78036
|
-
|
|
78207
|
+
}
|
|
78208
|
+
const holders = liveHolders(options);
|
|
78209
|
+
if (!waitedOn.length) {
|
|
78210
|
+
waitedOn = holders;
|
|
78211
|
+
options.onWait?.(holders);
|
|
78212
|
+
}
|
|
78213
|
+
if (waited >= options.waitMs)
|
|
78214
|
+
return {
|
|
78215
|
+
ok: false,
|
|
78216
|
+
reason: "timeout",
|
|
78217
|
+
holders,
|
|
78218
|
+
waitedMs: waited,
|
|
78219
|
+
position: ahead + 1
|
|
78220
|
+
};
|
|
78221
|
+
if (!queued) {
|
|
78222
|
+
writeTicket(ticket, ticketRecord);
|
|
78223
|
+
queued = true;
|
|
78224
|
+
process.on("exit", leave);
|
|
78225
|
+
process.on("SIGINT", onSignal);
|
|
78226
|
+
process.on("SIGTERM", onSignal);
|
|
78227
|
+
} else if (!fs24.existsSync(ticket)) {
|
|
78228
|
+
writeTicket(ticket, ticketRecord);
|
|
78229
|
+
}
|
|
78230
|
+
if (waited >= nextStatus) {
|
|
78231
|
+
options.onStatus?.({
|
|
78232
|
+
position: ahead + 1,
|
|
78233
|
+
ahead,
|
|
78234
|
+
holders,
|
|
78235
|
+
waitedMs: waited
|
|
78236
|
+
});
|
|
78237
|
+
nextStatus = waited + (options.statusEveryMs ?? 30000);
|
|
78238
|
+
}
|
|
78239
|
+
await clock.sleep(Math.min(options.pollMs ?? 2000, Math.max(1, options.waitMs - waited)));
|
|
78037
78240
|
}
|
|
78038
|
-
|
|
78039
|
-
|
|
78040
|
-
|
|
78241
|
+
} catch (error) {
|
|
78242
|
+
return {
|
|
78243
|
+
ok: false,
|
|
78244
|
+
reason: "unavailable",
|
|
78245
|
+
error: error.message
|
|
78246
|
+
};
|
|
78247
|
+
} finally {
|
|
78248
|
+
leave();
|
|
78041
78249
|
}
|
|
78042
78250
|
}
|
|
78043
78251
|
function updateLease(lease, patch) {
|
|
@@ -78150,7 +78358,7 @@ function leaseSlots(dir, slots, probe = {}) {
|
|
|
78150
78358
|
}
|
|
78151
78359
|
return states;
|
|
78152
78360
|
}
|
|
78153
|
-
var DEFAULT_HEAVY_CHECKS, DEFAULT_SLOTS = 1, DEFAULT_WAIT_S =
|
|
78361
|
+
var DEFAULT_HEAVY_CHECKS, DEFAULT_LIGHT_CHECKS, DEFAULT_SLOTS = 1, DEFAULT_WAIT_S = 1800, DEFAULT_MEMORY_SHARE = 0.4, DEFAULT_CPU_SHARE = 0.7, MAX_SLOTS = 64, UNREADABLE_TTL_MS = 30000, GUARD_TTL_MS = 30000, hostShape = () => ({
|
|
78154
78362
|
totalMemBytes: os20.totalmem(),
|
|
78155
78363
|
cpus: Math.max(1, os20.availableParallelism?.() ?? os20.cpus().length)
|
|
78156
78364
|
}), isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), SIZE, PERCENT, UNITS, leaseDir = (env) => path52.join(stateDir2(env), "leases"), readText5 = (file) => {
|
|
@@ -78184,16 +78392,22 @@ var DEFAULT_HEAVY_CHECKS, DEFAULT_SLOTS = 1, DEFAULT_WAIT_S = 600, DEFAULT_MEMOR
|
|
|
78184
78392
|
cwd: lease.cwd,
|
|
78185
78393
|
session: lease.session,
|
|
78186
78394
|
startedAt: lease.startedAt
|
|
78187
|
-
}),
|
|
78395
|
+
}), realClock, queueDir = (dir) => path52.join(dir, "queue"), TICKET, ticketName = (now, id) => `${String(now).padStart(15, "0")}-${String(process.hrtime.bigint() % 10n ** 16n).padStart(16, "0")}-${id}.json`, SCOPE_START_FAILURE, NOTICE_TTL_MS;
|
|
78188
78396
|
var init_resources = __esm(() => {
|
|
78189
78397
|
init_checks3();
|
|
78190
78398
|
init_heavy();
|
|
78191
78399
|
init_heavy_scope();
|
|
78192
|
-
DEFAULT_HEAVY_CHECKS = ["test", "build"
|
|
78400
|
+
DEFAULT_HEAVY_CHECKS = ["test", "build"];
|
|
78401
|
+
DEFAULT_LIGHT_CHECKS = ["lint", "typecheck", "format"];
|
|
78193
78402
|
SIZE = /^(\d+(?:\.\d+)?)([KMGT]?)$/iu;
|
|
78194
78403
|
PERCENT = /^(\d+(?:\.\d+)?)%$/u;
|
|
78195
78404
|
UNITS = { "": 1, K: 1024, M: 1024 ** 2, G: 1024 ** 3, T: 1024 ** 4 };
|
|
78196
78405
|
SCOPE_UNIT = /^[\w.@-]+\.scope$/u;
|
|
78406
|
+
realClock = {
|
|
78407
|
+
now: () => Date.now(),
|
|
78408
|
+
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms))
|
|
78409
|
+
};
|
|
78410
|
+
TICKET = /^\d{15}-\d{16}-[\w-]+\.json$/u;
|
|
78197
78411
|
SCOPE_START_FAILURE = /^Failed to (?:connect to bus|create bus connection|start transient scope unit|parse \S+?=)/u;
|
|
78198
78412
|
NOTICE_TTL_MS = 7 * 86400000;
|
|
78199
78413
|
});
|
|
@@ -78204,7 +78418,6 @@ __export(exports_check, {
|
|
|
78204
78418
|
OUTPUT_LINES: () => OUTPUT_LINES,
|
|
78205
78419
|
boundedOutput: () => boundedOutput,
|
|
78206
78420
|
countWarnings: () => countWarnings,
|
|
78207
|
-
hostToolWaitCapMs: () => hostToolWaitCapMs,
|
|
78208
78421
|
run: () => run12,
|
|
78209
78422
|
workspaceResources: () => workspaceResources
|
|
78210
78423
|
});
|
|
@@ -78227,6 +78440,7 @@ function parse6(argv) {
|
|
|
78227
78440
|
positionals: [],
|
|
78228
78441
|
command: split >= 0 ? argv.slice(split + 1) : null
|
|
78229
78442
|
};
|
|
78443
|
+
let noWait = false;
|
|
78230
78444
|
for (let index = 0;index < head.length; index += 1) {
|
|
78231
78445
|
const arg = head[index];
|
|
78232
78446
|
const [flag, inline] = arg.startsWith("--") && arg.includes("=") ? arg.split(/=(.*)/su) : [arg];
|
|
@@ -78250,6 +78464,13 @@ function parse6(argv) {
|
|
|
78250
78464
|
options.noLease = true;
|
|
78251
78465
|
continue;
|
|
78252
78466
|
}
|
|
78467
|
+
if (flag === "--no-wait") {
|
|
78468
|
+
if (options.waitMs !== null && !noWait)
|
|
78469
|
+
return new Error("--no-wait goes without --wait");
|
|
78470
|
+
noWait = true;
|
|
78471
|
+
options.waitMs = 0;
|
|
78472
|
+
continue;
|
|
78473
|
+
}
|
|
78253
78474
|
if (flag === "--name" || flag === "--task" || flag === "--base" || flag === "--timeout" || flag === "--wait" || flag === "--reason") {
|
|
78254
78475
|
const got = value();
|
|
78255
78476
|
if (got instanceof Error)
|
|
@@ -78259,10 +78480,12 @@ function parse6(argv) {
|
|
|
78259
78480
|
else if (flag === "--reason")
|
|
78260
78481
|
options.reason = got.trim() || null;
|
|
78261
78482
|
else if (flag === "--wait") {
|
|
78262
|
-
|
|
78263
|
-
|
|
78264
|
-
|
|
78265
|
-
|
|
78483
|
+
if (noWait)
|
|
78484
|
+
return new Error("--no-wait goes without --wait");
|
|
78485
|
+
const waitMs = parseWait(got);
|
|
78486
|
+
if (waitMs === null)
|
|
78487
|
+
return new Error('--wait must be seconds or a duration ("90", "90s", "30m", "1h")');
|
|
78488
|
+
options.waitMs = waitMs;
|
|
78266
78489
|
} else if (flag === "--task")
|
|
78267
78490
|
options.task = got;
|
|
78268
78491
|
else if (flag === "--base")
|
|
@@ -78392,22 +78615,30 @@ function countWarnings(log) {
|
|
|
78392
78615
|
return redactLog(log).replace(ANSI_COLOR, "").split(`
|
|
78393
78616
|
`).filter((line) => WARNING_LINE.test(line) && !NO_WARNINGS.test(line)).length;
|
|
78394
78617
|
}
|
|
78395
|
-
function boundedOutput(log, lines) {
|
|
78618
|
+
function boundedOutput(log, lines, stderr = "") {
|
|
78396
78619
|
const all = tailLines(log, Number.MAX_SAFE_INTEGER);
|
|
78397
78620
|
if (all.length === 0)
|
|
78398
78621
|
return "";
|
|
78399
|
-
|
|
78622
|
+
let shown = all.slice(-lines);
|
|
78623
|
+
const errors = tailLines(redactLog(stderr), STDERR_TAIL_LINES);
|
|
78624
|
+
let missing = [];
|
|
78625
|
+
if (errors.length) {
|
|
78626
|
+
const tail = new Set(shown);
|
|
78627
|
+
if (errors.some((line) => !tail.has(line))) {
|
|
78628
|
+
shown = all.slice(-Math.max(1, lines - errors.length - 2));
|
|
78629
|
+
const kept = new Set(shown);
|
|
78630
|
+
missing = errors.filter((line) => !kept.has(line));
|
|
78631
|
+
}
|
|
78632
|
+
}
|
|
78400
78633
|
const omitted = all.length - shown.length;
|
|
78634
|
+
const footer = missing.length ? `… the last stderr lines, which the merged log holds earlier:
|
|
78635
|
+
${missing.join(`
|
|
78636
|
+
`)}
|
|
78637
|
+
` : "";
|
|
78401
78638
|
return `${omitted ? `… ${omitted} earlier line${omitted === 1 ? "" : "s"} omitted (the full log is named below; --full streams it)
|
|
78402
78639
|
` : ""}${shown.join(`
|
|
78403
78640
|
`)}
|
|
78404
|
-
`;
|
|
78405
|
-
}
|
|
78406
|
-
function hostToolWaitCapMs(env) {
|
|
78407
|
-
if (!env.CLAUDECODE && !env.OPENCODE && !env.OPENCODE_SESSION_ID)
|
|
78408
|
-
return null;
|
|
78409
|
-
const override = Number(env.WORKIT_HOST_WAIT_CAP_MS);
|
|
78410
|
-
return Number.isFinite(override) && override >= 0 && env.WORKIT_HOST_WAIT_CAP_MS ? override : HOST_TOOL_WAIT_CAP_MS;
|
|
78641
|
+
${footer}`;
|
|
78411
78642
|
}
|
|
78412
78643
|
async function workspaceResources(io) {
|
|
78413
78644
|
const env = io.env;
|
|
@@ -78441,14 +78672,26 @@ async function prepareHeavy(io, settings, label, runCwd, timeoutMs) {
|
|
|
78441
78672
|
waitMs: settings.waitMs,
|
|
78442
78673
|
pollMs: 1000,
|
|
78443
78674
|
maxAgeMs: (timeoutMs || MAX_UNVERIFIED_RUN_MS) + 60000,
|
|
78444
|
-
|
|
78445
|
-
|
|
78675
|
+
onStatus: (status) => {
|
|
78676
|
+
const slots = `${settings.slots} slot${settings.slots === 1 ? "" : "s"}`;
|
|
78677
|
+
const holders = status.holders.map((holder) => describeHolder(holder)).join("; ");
|
|
78678
|
+
io.stderr(status.waitedMs === 0 ? `workit: waiting for the heavy-check lease (${slots}): held by ${holders || "nobody; waiters ahead"}; queued at position ${status.position}, waiting up to ${formatWait(settings.waitMs)} (--wait <dur> sets it)
|
|
78679
|
+
` : `workit: still queued for the heavy-check lease: position ${status.position}, ${formatWait(status.waitedMs)} of ${formatWait(settings.waitMs)} waited; held by ${holders || "nobody; waiters ahead"}
|
|
78680
|
+
`);
|
|
78681
|
+
}
|
|
78446
78682
|
});
|
|
78447
78683
|
if (!acquired.ok && acquired.reason === "timeout") {
|
|
78448
78684
|
const holders = acquired.holders.map((holder) => describeHolder(holder)).join("; ");
|
|
78449
|
-
|
|
78450
|
-
|
|
78451
|
-
|
|
78685
|
+
const waited = formatWait(acquired.waitedMs);
|
|
78686
|
+
emit(io, fail2("busy", settings.waitMs === 0 ? `the heavy-check lease is busy (--no-wait): held by ${holders || "nobody; waiters ahead"}` : `the heavy-check lease stayed busy for ${waited} (position ${acquired.position} in the queue)`, {
|
|
78687
|
+
data: {
|
|
78688
|
+
lease: {
|
|
78689
|
+
waitedMs: acquired.waitedMs,
|
|
78690
|
+
holders: acquired.holders,
|
|
78691
|
+
position: acquired.position
|
|
78692
|
+
}
|
|
78693
|
+
},
|
|
78694
|
+
unblock: `wait for ${holders || "the waiters ahead"} to finish (each holder's age is shown; a full test suite takes minutes), then run it again, or queue longer with --wait 30m`
|
|
78452
78695
|
}));
|
|
78453
78696
|
return 4;
|
|
78454
78697
|
}
|
|
@@ -78548,11 +78791,8 @@ async function run12(argv, io) {
|
|
|
78548
78791
|
{ label: "workspaces.json", trust: "machine", value: workspace.value },
|
|
78549
78792
|
{ label: CHECKS_FILE, trust: "repo", value: config.resources }
|
|
78550
78793
|
]);
|
|
78551
|
-
const cap = hostToolWaitCapMs(io.env);
|
|
78552
78794
|
if (options.waitMs !== null)
|
|
78553
78795
|
settings.waitMs = options.waitMs;
|
|
78554
|
-
else if (cap !== null)
|
|
78555
|
-
settings.waitMs = Math.min(settings.waitMs, cap);
|
|
78556
78796
|
for (const warning of [workspace.warning, ...warnings])
|
|
78557
78797
|
if (warning)
|
|
78558
78798
|
io.stderr(`workit: resources: ${warning}
|
|
@@ -78569,6 +78809,7 @@ async function run12(argv, io) {
|
|
|
78569
78809
|
`);
|
|
78570
78810
|
const lease = heavy?.lease ?? null;
|
|
78571
78811
|
let result;
|
|
78812
|
+
let stderrTail = "";
|
|
78572
78813
|
try {
|
|
78573
78814
|
const scoped = await runScoped((wrapper, sinks) => runCheckCommand(command, {
|
|
78574
78815
|
cwd: runCwd,
|
|
@@ -78578,7 +78819,12 @@ async function run12(argv, io) {
|
|
|
78578
78819
|
...sinks,
|
|
78579
78820
|
...wrapper ? { wrapper } : {},
|
|
78580
78821
|
...lease ? { onSpawn: (pid) => updateLease(lease, { pgid: pid }) } : {}
|
|
78581
|
-
}), heavy?.wrapper ?? null, options.full ? { onStdout: io.json ? io.stderr : io.stdout, onStderr: io.stderr } : {
|
|
78822
|
+
}), heavy?.wrapper ?? null, options.full ? { onStdout: io.json ? io.stderr : io.stdout, onStderr: io.stderr } : {
|
|
78823
|
+
onStdout: () => {},
|
|
78824
|
+
onStderr: (text) => {
|
|
78825
|
+
stderrTail = (stderrTail + text).slice(-STDERR_KEEP_CHARS);
|
|
78826
|
+
}
|
|
78827
|
+
});
|
|
78582
78828
|
result = scoped.result;
|
|
78583
78829
|
if (heavy && scoped.fallback) {
|
|
78584
78830
|
io.stderr(`workit: the memory/CPU scope could not start (${scoped.fallback}); ran without it
|
|
@@ -78690,7 +78936,7 @@ async function run12(argv, io) {
|
|
|
78690
78936
|
`);
|
|
78691
78937
|
else {
|
|
78692
78938
|
if (!options.full)
|
|
78693
|
-
io.stdout(boundedOutput(result.log, OUTPUT_LINES));
|
|
78939
|
+
io.stdout(boundedOutput(result.log, OUTPUT_LINES, stderrTail));
|
|
78694
78940
|
io.stderr(`${summary}
|
|
78695
78941
|
`);
|
|
78696
78942
|
if (recordError && passed)
|
|
@@ -78707,7 +78953,7 @@ async function run12(argv, io) {
|
|
|
78707
78953
|
return recordError.code === "busy" ? 4 : recordError.code === "invalid_input" ? 2 : 5;
|
|
78708
78954
|
return 0;
|
|
78709
78955
|
}
|
|
78710
|
-
var USAGE6 = 'workit check <name> [--full] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--heavy] [--full] [--wait <
|
|
78956
|
+
var USAGE6 = 'workit check <name> [--full] [--wait <dur> | --no-wait] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--heavy] [--full] [--wait <dur> | --no-wait] [--timeout <s>] [--task <id>] [--json] -- <cmd…>', OUTPUT_LINES = 60, MAX_UNVERIFIED_RUN_MS, RECORD_TAIL_LINES = 20, RECORD_TAIL_CHARS = 200, posix = (value) => value.split(path53.sep).join("/") || ".", ENGINE_CODES2, FINGERPRINT_VARS, ANSI_COLOR, WARNING_LINE, NO_WARNINGS, STDERR_TAIL_LINES = 10, STDERR_KEEP_CHARS = 65536;
|
|
78711
78957
|
var init_check = __esm(() => {
|
|
78712
78958
|
init_check_config();
|
|
78713
78959
|
init_checks3();
|
|
@@ -78745,25 +78991,35 @@ async function settingsFor(io) {
|
|
|
78745
78991
|
{ label: CHECKS_FILE, trust: "repo", value: config.resources }
|
|
78746
78992
|
]).settings;
|
|
78747
78993
|
}
|
|
78748
|
-
function slotLines(slots) {
|
|
78994
|
+
function slotLines(slots, queue = []) {
|
|
78749
78995
|
const busy = held(slots).length;
|
|
78996
|
+
const waiting = queue.filter((entry) => !entry.stale);
|
|
78750
78997
|
return [
|
|
78751
78998
|
`heavy-check lease: ${busy} of ${slots.length} slot${slots.length === 1 ? "" : "s"} held`,
|
|
78752
|
-
...slots.map((slot) => slot.holder ? ` slot ${slot.slot}: ${describeHolder(slot.holder)}${slot.stale ? ` (stale: ${slot.stale}; the next heavy check reclaims it)` : ""}` : ` slot ${slot.slot}: free`)
|
|
78999
|
+
...slots.map((slot) => slot.holder ? ` slot ${slot.slot}: ${describeHolder(slot.holder)}${slot.stale ? ` (stale: ${slot.stale}; the next heavy check reclaims it)` : ""}` : ` slot ${slot.slot}: free`),
|
|
79000
|
+
`queue: ${waiting.length ? `${waiting.length} waiting, first come, first served` : "empty"}`,
|
|
79001
|
+
...waiting.map((entry, index) => ` ${index + 1}. ${describeHolder(entry.holder)}`)
|
|
78753
79002
|
];
|
|
78754
79003
|
}
|
|
78755
79004
|
async function status(io) {
|
|
78756
79005
|
const settings = await settingsFor(io);
|
|
78757
79006
|
const slots = leaseSlots(leaseDir(io.env), settings.slots);
|
|
78758
|
-
|
|
79007
|
+
const queue = leaseQueue(leaseDir(io.env));
|
|
79008
|
+
const waiting = queue.filter((entry) => !entry.stale).map((entry) => entry.holder);
|
|
79009
|
+
return emit(io, ok2({
|
|
79010
|
+
dir: leaseDir(io.env),
|
|
79011
|
+
slots,
|
|
79012
|
+
queue: waiting,
|
|
79013
|
+
waitMs: settings.waitMs,
|
|
79014
|
+
light: settings.light
|
|
79015
|
+
}), () => slotLines(slots, queue));
|
|
78759
79016
|
}
|
|
78760
79017
|
function timeoutOf(args) {
|
|
78761
79018
|
const at = args.findIndex((arg) => arg === "--timeout" || arg.startsWith("--timeout="));
|
|
78762
79019
|
if (at < 0)
|
|
78763
79020
|
return null;
|
|
78764
79021
|
const raw = args[at].includes("=") ? args[at].split("=")[1] : args[at + 1];
|
|
78765
|
-
|
|
78766
|
-
return Number.isFinite(seconds) && seconds >= 0 ? Math.round(seconds * 1000) : new Error("--timeout must be a number of seconds");
|
|
79022
|
+
return parseWait(raw ?? "") ?? new Error('--timeout must be seconds or a duration ("90", "90s", "30m", "1h")');
|
|
78767
79023
|
}
|
|
78768
79024
|
async function wait(args, io) {
|
|
78769
79025
|
const timeout = timeoutOf(args);
|
|
@@ -78780,10 +79036,10 @@ async function wait(args, io) {
|
|
|
78780
79036
|
const waitedMs = Date.now() - started;
|
|
78781
79037
|
if (busy.length < slots.length)
|
|
78782
79038
|
return emit(io, ok2({ free: true, waitedMs, slots }), () => [
|
|
78783
|
-
`workit: the heavy-check lease has a free slot${waitedMs ? ` after ${
|
|
79039
|
+
`workit: the heavy-check lease has a free slot${waitedMs ? ` after ${formatWait(waitedMs)}` : ""}`
|
|
78784
79040
|
]);
|
|
78785
79041
|
if (waitedMs >= limit)
|
|
78786
|
-
return emit(io, fail2("busy", `the heavy-check lease stayed busy for ${
|
|
79042
|
+
return emit(io, fail2("busy", `the heavy-check lease stayed busy for ${formatWait(waitedMs)}`, {
|
|
78787
79043
|
data: { free: false, waitedMs, slots },
|
|
78788
79044
|
unblock: "workit lock status"
|
|
78789
79045
|
}));
|
|
@@ -78792,16 +79048,16 @@ async function wait(args, io) {
|
|
|
78792
79048
|
io.stderr(`workit: waiting for the heavy-check lease: held by ${busy.flatMap((slot) => slot.holder ? [describeHolder(slot.holder)] : []).join("; ")}
|
|
78793
79049
|
`);
|
|
78794
79050
|
}
|
|
78795
|
-
await
|
|
79051
|
+
await sleep(Math.min(1000, Math.max(1, limit - waitedMs)));
|
|
78796
79052
|
}
|
|
78797
79053
|
}
|
|
78798
79054
|
async function runHeavy(args, io) {
|
|
78799
79055
|
const split = args.indexOf("--");
|
|
78800
79056
|
const head = split < 0 ? args : args.slice(0, split);
|
|
78801
|
-
const unknown = head.find((arg, index) => arg !== "--shell" && arg !== "--json" && !arg.startsWith("--timeout") && !arg.startsWith("--wait") && !((head[index - 1] === "--timeout" || head[index - 1] === "--wait") && !arg.startsWith("-")));
|
|
79057
|
+
const unknown = head.find((arg, index) => arg !== "--shell" && arg !== "--json" && arg !== "--no-wait" && !arg.startsWith("--timeout") && !arg.startsWith("--wait") && !((head[index - 1] === "--timeout" || head[index - 1] === "--wait") && !arg.startsWith("-")));
|
|
78802
79058
|
if (split < 0 || unknown)
|
|
78803
79059
|
return emit(io, fail2("invalid_input", unknown ? `unexpected ${unknown}` : "no command after --", {
|
|
78804
|
-
unblock: "workit lock run [--shell] [--wait <
|
|
79060
|
+
unblock: "workit lock run [--shell] [--wait <dur> | --no-wait] [--timeout <s>] -- <cmd…>"
|
|
78805
79061
|
}));
|
|
78806
79062
|
const check = await Promise.resolve().then(() => (init_check(), {}));
|
|
78807
79063
|
return run12([`--heavy`, ...head, ...args.slice(split)], io);
|
|
@@ -78887,7 +79143,7 @@ async function run13(argv, io) {
|
|
|
78887
79143
|
return heavy(rest, io);
|
|
78888
79144
|
return emit(io, fail2("invalid_input", `unknown lock subcommand ${sub ?? "(none)"}`, { unblock: USAGE7 }));
|
|
78889
79145
|
}
|
|
78890
|
-
var USAGE7 = "workit lock status | wait [--timeout <
|
|
79146
|
+
var USAGE7 = "workit lock status | wait [--timeout <dur>] | run [--shell] [--wait <dur> | --no-wait] [--timeout <s>] -- <cmd…> | heavy list|add|remove|test", held = (slots) => slots.filter((slot) => slot.holder && !slot.stale), sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)), commandText = (args) => {
|
|
78891
79147
|
const split = args.indexOf("--");
|
|
78892
79148
|
return (split < 0 ? args : args.slice(split + 1)).join(" ").trim();
|
|
78893
79149
|
};
|
|
@@ -78904,7 +79160,7 @@ var exports_models = {};
|
|
|
78904
79160
|
__export(exports_models, {
|
|
78905
79161
|
run: () => run14
|
|
78906
79162
|
});
|
|
78907
|
-
import { existsSync as existsSync24, readdirSync as readdirSync13, readFileSync as
|
|
79163
|
+
import { existsSync as existsSync24, readdirSync as readdirSync13, readFileSync as readFileSync24, statSync as statSync9 } from "node:fs";
|
|
78908
79164
|
import os22 from "node:os";
|
|
78909
79165
|
import path55 from "node:path";
|
|
78910
79166
|
async function run14(argv, io) {
|
|
@@ -78967,7 +79223,7 @@ var USAGE8 = "workit models show [--role <role>] [--tier <tier>] [--host <host>]
|
|
|
78967
79223
|
const found = new Set;
|
|
78968
79224
|
let text = "";
|
|
78969
79225
|
try {
|
|
78970
|
-
text =
|
|
79226
|
+
text = readFileSync24(file, "utf8");
|
|
78971
79227
|
} catch {
|
|
78972
79228
|
return found;
|
|
78973
79229
|
}
|
|
@@ -78998,7 +79254,7 @@ var USAGE8 = "workit models show [--role <role>] [--tier <tier>] [--host <host>]
|
|
|
78998
79254
|
try {
|
|
78999
79255
|
if (statSync9(meta).mtimeMs < since)
|
|
79000
79256
|
continue;
|
|
79001
|
-
const agentType = JSON.parse(
|
|
79257
|
+
const agentType = JSON.parse(readFileSync24(meta, "utf8")).agentType;
|
|
79002
79258
|
const transcript = meta.replace(/\.meta\.json$/, ".jsonl");
|
|
79003
79259
|
if (typeof agentType !== "string" || !existsSync24(transcript))
|
|
79004
79260
|
continue;
|
|
@@ -79139,7 +79395,7 @@ var success2 = (data) => ({ ok: true, data }), failure3 = (code, error, unblock)
|
|
|
79139
79395
|
|
|
79140
79396
|
// packages/workit-core/src/git/ops.ts
|
|
79141
79397
|
import { spawnSync as spawnSync20 } from "node:child_process";
|
|
79142
|
-
import { existsSync as existsSync25, readFileSync as
|
|
79398
|
+
import { existsSync as existsSync25, readFileSync as readFileSync25 } from "node:fs";
|
|
79143
79399
|
import path56 from "node:path";
|
|
79144
79400
|
function operationInProgress(cwd) {
|
|
79145
79401
|
const markers = [
|
|
@@ -79164,7 +79420,7 @@ function operationInProgress(cwd) {
|
|
|
79164
79420
|
if (index === 0 && existsSync25(path56.join(marker, "amend")) && !conflicted()) {
|
|
79165
79421
|
let headName = "";
|
|
79166
79422
|
try {
|
|
79167
|
-
headName =
|
|
79423
|
+
headName = readFileSync25(path56.join(marker, "head-name"), "utf8").trim();
|
|
79168
79424
|
} catch {}
|
|
79169
79425
|
const branch = headName.startsWith("refs/heads/") ? headName.slice("refs/heads/".length) : null;
|
|
79170
79426
|
return { operation, commitAllowed: branch !== null, branch };
|
|
@@ -85860,7 +86116,7 @@ var init_duration = __esm(() => {
|
|
|
85860
86116
|
});
|
|
85861
86117
|
|
|
85862
86118
|
// packages/workit-cli/src/verbs/forge-common.ts
|
|
85863
|
-
import { readFileSync as
|
|
86119
|
+
import { readFileSync as readFileSync26 } from "node:fs";
|
|
85864
86120
|
function parseFlags(argv, spec) {
|
|
85865
86121
|
const parsed = { values: {}, booleans: new Set, lists: {}, positionals: [] };
|
|
85866
86122
|
for (let index = 0;index < argv.length; index += 1) {
|
|
@@ -86015,7 +86271,7 @@ var init_forge_common = __esm(() => {
|
|
|
86015
86271
|
forgeDeps = {
|
|
86016
86272
|
runner: undefined,
|
|
86017
86273
|
npm: undefined,
|
|
86018
|
-
readStdin: () =>
|
|
86274
|
+
readStdin: () => readFileSync26(0, "utf8"),
|
|
86019
86275
|
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
86020
86276
|
now: () => Date.now()
|
|
86021
86277
|
};
|
|
@@ -86026,12 +86282,12 @@ var exports_pr = {};
|
|
|
86026
86282
|
__export(exports_pr, {
|
|
86027
86283
|
run: () => run15
|
|
86028
86284
|
});
|
|
86029
|
-
import { readFileSync as
|
|
86285
|
+
import { readFileSync as readFileSync27 } from "node:fs";
|
|
86030
86286
|
import path66 from "node:path";
|
|
86031
86287
|
function readBodyFile(io, file) {
|
|
86032
86288
|
try {
|
|
86033
86289
|
return {
|
|
86034
|
-
body: file === "-" ? forgeDeps.readStdin() :
|
|
86290
|
+
body: file === "-" ? forgeDeps.readStdin() : readFileSync27(path66.resolve(io.cwd, file), "utf8")
|
|
86035
86291
|
};
|
|
86036
86292
|
} catch {
|
|
86037
86293
|
return `cannot read --body-file ${file}`;
|
|
@@ -86835,7 +87091,7 @@ var exports_git = {};
|
|
|
86835
87091
|
__export(exports_git, {
|
|
86836
87092
|
run: () => run17
|
|
86837
87093
|
});
|
|
86838
|
-
import { readFileSync as
|
|
87094
|
+
import { readFileSync as readFileSync28 } from "node:fs";
|
|
86839
87095
|
import path67 from "node:path";
|
|
86840
87096
|
function kindHint(cwd, kind) {
|
|
86841
87097
|
let kinds = [...BRANCH_KINDS];
|
|
@@ -86940,7 +87196,7 @@ function commitMessage(parsed, io) {
|
|
|
86940
87196
|
|
|
86941
87197
|
`);
|
|
86942
87198
|
try {
|
|
86943
|
-
return file === "-" ?
|
|
87199
|
+
return file === "-" ? readFileSync28(0, "utf8") : readFileSync28(path67.resolve(io.cwd, file), "utf8");
|
|
86944
87200
|
} catch (error) {
|
|
86945
87201
|
return {
|
|
86946
87202
|
error: `cannot read -F ${file}: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -88101,6 +88357,11 @@ async function run19(argv, io) {
|
|
|
88101
88357
|
if (!result.ok)
|
|
88102
88358
|
return forgeFail(io, result);
|
|
88103
88359
|
const report = result.data;
|
|
88360
|
+
if (report.delivered && expect === "merged") {
|
|
88361
|
+
try {
|
|
88362
|
+
closeDeliveredTasks(new TaskStore(io.cwd), new Date().toISOString().replace(/\.\d{3}Z$/, "Z"));
|
|
88363
|
+
} catch {}
|
|
88364
|
+
}
|
|
88104
88365
|
if (report.delivered)
|
|
88105
88366
|
return emit(io, ok2(report), render2);
|
|
88106
88367
|
const failed = report.observations.filter((entry) => !entry.ok);
|
|
@@ -88119,6 +88380,8 @@ var USAGE12 = "workit verify-delivery [push|pr|merge|release] [--expect pushed|p
|
|
|
88119
88380
|
];
|
|
88120
88381
|
var init_verify_delivery = __esm(() => {
|
|
88121
88382
|
init_verify();
|
|
88383
|
+
init_task_store();
|
|
88384
|
+
init_task_delivery();
|
|
88122
88385
|
init_ledger();
|
|
88123
88386
|
init_output();
|
|
88124
88387
|
init_forge_common();
|
|
@@ -105693,7 +105956,7 @@ var init_rules = __esm(() => {
|
|
|
105693
105956
|
|
|
105694
105957
|
// packages/workit-cli/src/test-audit/audit.ts
|
|
105695
105958
|
import { spawnSync as spawnSync29 } from "node:child_process";
|
|
105696
|
-
import { existsSync as existsSync26, readdirSync as readdirSync14, readFileSync as
|
|
105959
|
+
import { existsSync as existsSync26, readdirSync as readdirSync14, readFileSync as readFileSync29, statSync as statSync10 } from "node:fs";
|
|
105697
105960
|
import path71 from "node:path";
|
|
105698
105961
|
function git7(cwd, args) {
|
|
105699
105962
|
const run = spawnSync29("git", ["-c", "core.quotepath=off", ...args], {
|
|
@@ -105773,7 +106036,7 @@ function auditFiles(files, display) {
|
|
|
105773
106036
|
const shown = display(file);
|
|
105774
106037
|
let parsed;
|
|
105775
106038
|
try {
|
|
105776
|
-
parsed = parseSource(
|
|
106039
|
+
parsed = parseSource(readFileSync29(file, "utf8"), file);
|
|
105777
106040
|
} catch (error) {
|
|
105778
106041
|
parseErrors.push({
|
|
105779
106042
|
file: shown,
|
|
@@ -105841,14 +106104,14 @@ import {
|
|
|
105841
106104
|
mkdirSync as mkdirSync12,
|
|
105842
106105
|
mkdtempSync as mkdtempSync4,
|
|
105843
106106
|
readdirSync as readdirSync15,
|
|
105844
|
-
readFileSync as
|
|
106107
|
+
readFileSync as readFileSync30,
|
|
105845
106108
|
readlinkSync as readlinkSync3,
|
|
105846
106109
|
realpathSync as realpathSync10,
|
|
105847
106110
|
renameSync as renameSync7,
|
|
105848
106111
|
rmSync as rmSync9,
|
|
105849
106112
|
statSync as statSync11,
|
|
105850
106113
|
symlinkSync,
|
|
105851
|
-
writeFileSync as
|
|
106114
|
+
writeFileSync as writeFileSync13,
|
|
105852
106115
|
copyFileSync as copyFileSync8
|
|
105853
106116
|
} from "node:fs";
|
|
105854
106117
|
import os23 from "node:os";
|
|
@@ -105950,7 +106213,7 @@ function removeStaleCopies(tmp = os23.tmpdir()) {
|
|
|
105950
106213
|
const stat = lstatSync8(dir);
|
|
105951
106214
|
if (!stat.isDirectory() || uid !== undefined && stat.uid !== uid)
|
|
105952
106215
|
continue;
|
|
105953
|
-
const pid = Number(
|
|
106216
|
+
const pid = Number(readFileSync30(path72.join(dir, PID_FILE), "utf8"));
|
|
105954
106217
|
if (Number.isInteger(pid) && pid > 0 && alive(pid))
|
|
105955
106218
|
continue;
|
|
105956
106219
|
} catch (error) {
|
|
@@ -106020,13 +106283,13 @@ function writeInside(copy, file, content) {
|
|
|
106020
106283
|
return false;
|
|
106021
106284
|
}
|
|
106022
106285
|
const temp = `${target}.workit-mutant-${process.pid}`;
|
|
106023
|
-
|
|
106286
|
+
writeFileSync13(temp, content);
|
|
106024
106287
|
renameSync7(temp, target);
|
|
106025
106288
|
return true;
|
|
106026
106289
|
}
|
|
106027
106290
|
function copyWorkingTree(repo) {
|
|
106028
106291
|
const dir = mkdtempSync4(path72.join(os23.tmpdir(), TEMP_PREFIX));
|
|
106029
|
-
|
|
106292
|
+
writeFileSync13(path72.join(dir, PID_FILE), String(process.pid));
|
|
106030
106293
|
const tree = path72.join(dir, "tree");
|
|
106031
106294
|
const head = git7(repo, ["rev-parse", "--verify", "--quiet", "HEAD"]).stdout.trim();
|
|
106032
106295
|
if (head && git7(dir, ["clone", "-q", "--shared", "--no-checkout", repo, tree]).ok) {
|
|
@@ -106105,7 +106368,7 @@ async function runMutation(options) {
|
|
|
106105
106368
|
const tracked = git7(repo, ["ls-files", "-co", "--exclude-standard", "-z"]).stdout.split("\x00").filter(Boolean);
|
|
106106
106369
|
const testFiles = tracked.filter((file) => TEST_FILE.test(file)).map((file) => {
|
|
106107
106370
|
try {
|
|
106108
|
-
return { file, text:
|
|
106371
|
+
return { file, text: readFileSync30(path72.join(repo, file), "utf8") };
|
|
106109
106372
|
} catch {
|
|
106110
106373
|
return { file, text: "" };
|
|
106111
106374
|
}
|
|
@@ -106118,7 +106381,7 @@ async function runMutation(options) {
|
|
|
106118
106381
|
if (NOT_SOURCE.test(relative) || !existsSync27(absolute))
|
|
106119
106382
|
continue;
|
|
106120
106383
|
try {
|
|
106121
|
-
candidates.push(...mutantsFor(
|
|
106384
|
+
candidates.push(...mutantsFor(readFileSync30(absolute, "utf8"), relative, lines));
|
|
106122
106385
|
} catch {}
|
|
106123
106386
|
}
|
|
106124
106387
|
const mutants = candidates.map((mutant, index) => ({ ...mutant, id: index + 1 }));
|
|
@@ -106199,7 +106462,7 @@ async function runMutation(options) {
|
|
|
106199
106462
|
record({ ...mutant, status: "skipped", durationMs: 0, tests, reason: "budget" });
|
|
106200
106463
|
continue;
|
|
106201
106464
|
}
|
|
106202
|
-
const original =
|
|
106465
|
+
const original = readFileSync30(path72.join(copy, mutant.file), "utf8");
|
|
106203
106466
|
const mutated = original.slice(0, mutant.start) + mutant.replacement + original.slice(mutant.end);
|
|
106204
106467
|
current = { file: mutant.file, original };
|
|
106205
106468
|
if (!writeInside(copy, mutant.file, mutated)) {
|
|
@@ -106550,7 +106813,7 @@ var exports_youtrack = {};
|
|
|
106550
106813
|
__export(exports_youtrack, {
|
|
106551
106814
|
run: () => run25
|
|
106552
106815
|
});
|
|
106553
|
-
import { readFileSync as
|
|
106816
|
+
import { readFileSync as readFileSync31 } from "node:fs";
|
|
106554
106817
|
import path74 from "node:path";
|
|
106555
106818
|
async function run25(argv, io) {
|
|
106556
106819
|
const [sub, ...rest] = argv;
|
|
@@ -106597,7 +106860,7 @@ async function run25(argv, io) {
|
|
|
106597
106860
|
let markdown = flags.values.markdown ?? "";
|
|
106598
106861
|
if (flags.values.file)
|
|
106599
106862
|
try {
|
|
106600
|
-
markdown =
|
|
106863
|
+
markdown = readFileSync31(path74.resolve(io.cwd, flags.values.file), "utf8");
|
|
106601
106864
|
} catch (error) {
|
|
106602
106865
|
return usage4(io, `cannot read ${flags.values.file}: ${String(error)}`, USAGE18);
|
|
106603
106866
|
}
|
|
@@ -106665,7 +106928,7 @@ var exports_changelog = {};
|
|
|
106665
106928
|
__export(exports_changelog, {
|
|
106666
106929
|
run: () => run26
|
|
106667
106930
|
});
|
|
106668
|
-
import { readFileSync as
|
|
106931
|
+
import { readFileSync as readFileSync32 } from "node:fs";
|
|
106669
106932
|
import path75 from "node:path";
|
|
106670
106933
|
async function run26(argv, io) {
|
|
106671
106934
|
const [sub, ...rest] = argv;
|
|
@@ -106712,7 +106975,7 @@ async function run26(argv, io) {
|
|
|
106712
106975
|
]);
|
|
106713
106976
|
}
|
|
106714
106977
|
var USAGE19 = "workit changelog apply (--entries <JSON|@file|-> | --normalize-only) [--path CHANGELOG.md] [--preview]", readEntries = (raw, cwd) => {
|
|
106715
|
-
const text = raw === "-" ?
|
|
106978
|
+
const text = raw === "-" ? readFileSync32(0, "utf8") : raw.startsWith("@") ? readFileSync32(path75.resolve(cwd, raw.slice(1)), "utf8") : raw;
|
|
106716
106979
|
return JSON.parse(text);
|
|
106717
106980
|
};
|
|
106718
106981
|
var init_changelog2 = __esm(() => {
|
|
@@ -106955,9 +107218,10 @@ function withSubcommands(entry, options = {}) {
|
|
|
106955
107218
|
};
|
|
106956
107219
|
}
|
|
106957
107220
|
var LEASE_NOTES = [
|
|
106958
|
-
"The heavy-check lease: heavy work (tests, builds,
|
|
106959
|
-
"
|
|
106960
|
-
"
|
|
107221
|
+
"The heavy-check lease: heavy work (tests, builds, installs, image builds) shares one machine-wide lease, so parallel agents and worktrees never exhaust this machine's memory and CPU. `slots` (default 1) heavy checks run at once; on Linux each also runs in a systemd scope with MemoryMax and CPUQuota.",
|
|
107222
|
+
"Queueing: a heavy check that finds every slot held joins a first-come, first-served queue and prints `waiting for the heavy-check lease` naming the holder (check, pid, session, age, directory) and its position, then a status line every 30 s. It waits `--wait <dur>` (90, 90s, 30m, 1h), else `resources.wait` (default 30 min), and exits 4 (busy) only past that wait or at once with --no-wait. A waiter that is killed gives up its place. A wait longer than your shell tool's timeout belongs in a background call. `workit lock status` shows the holders and the queue.",
|
|
107223
|
+
"Light checks: the named checks lint, typecheck and format (`resources.light`, set in workspaces.json) never take the lease, so they run at once beside a long suite.",
|
|
107224
|
+
"--heavy: an ad-hoc `workit check -- <cmd>` takes the lease only with --heavy; the named checks test and build always do. The shell hook runs a raw heavy command (`npx jest`, `npm run test:ci`, `cargo test`, `docker build`) as `workit check --heavy -- <cmd>` on Claude Code, OpenCode and Pi, and denies it with that exact command on Codex and Cursor.",
|
|
106961
107225
|
'--no-lease skips the lease and needs --reason "<why>". Never hand-roll a flock: the lease already queues every agent on the machine.',
|
|
106962
107226
|
"Output: a check prints the last 60 lines of its output and one summary line with `log: <path>` to the full log; --full streams all of it."
|
|
106963
107227
|
];
|
|
@@ -107074,7 +107338,7 @@ var VERBS = [
|
|
|
107074
107338
|
{
|
|
107075
107339
|
name: "check",
|
|
107076
107340
|
group: "delivery",
|
|
107077
|
-
usage: 'workit check <name> [--full] [--task <id>] [--base <ref>] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--full] [--timeout <s>] [--task <id>] [--base <ref>] [--heavy [--wait <
|
|
107341
|
+
usage: 'workit check <name> [--full] [--task <id>] [--base <ref>] [--wait <dur> | --no-wait] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--full] [--timeout <s>] [--task <id>] [--base <ref>] [--heavy [--wait <dur> | --no-wait]] [--no-lease --reason "<why>"] -- <cmd…>',
|
|
107078
107342
|
flagHints: {
|
|
107079
107343
|
list: "workit check <name> runs a configured check; a name that is not configured prints the valid ones (workit check test|lint|typecheck|check)"
|
|
107080
107344
|
},
|
|
@@ -107082,6 +107346,7 @@ var VERBS = [
|
|
|
107082
107346
|
examples: [
|
|
107083
107347
|
"workit check test",
|
|
107084
107348
|
"workit check --heavy -- npx jest",
|
|
107349
|
+
"workit check test --wait 45m",
|
|
107085
107350
|
"workit check --name unit -- bun test test/unit",
|
|
107086
107351
|
'workit check test --no-lease --reason "machine is idle, debugging a hang"'
|
|
107087
107352
|
],
|
|
@@ -107096,16 +107361,16 @@ var VERBS = [
|
|
|
107096
107361
|
{
|
|
107097
107362
|
name: "status",
|
|
107098
107363
|
usage: "workit lock status",
|
|
107099
|
-
summary: "Show each lease slot
|
|
107364
|
+
summary: "Show each lease slot (free, held by check, pid, session, age, directory, or stale) and the queue of waiting checks in arrival order"
|
|
107100
107365
|
},
|
|
107101
107366
|
{
|
|
107102
107367
|
name: "wait",
|
|
107103
|
-
usage: "workit lock wait [--timeout <
|
|
107368
|
+
usage: "workit lock wait [--timeout <dur>]",
|
|
107104
107369
|
summary: "Wait until a lease slot is free, without taking it (exit 0 free, 4 still busy at the timeout)"
|
|
107105
107370
|
},
|
|
107106
107371
|
{
|
|
107107
107372
|
name: "run",
|
|
107108
|
-
usage: "workit lock run [--shell] [--wait <
|
|
107373
|
+
usage: "workit lock run [--shell] [--wait <dur> | --no-wait] [--timeout <s>] -- <cmd…>",
|
|
107109
107374
|
summary: "Run a command under the lease: the same as workit check --heavy -- <cmd…>"
|
|
107110
107375
|
},
|
|
107111
107376
|
{
|