@brainervirus/workit-cli 8.13.0 → 8.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +610 -207
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -65,7 +65,7 @@ var package_default;
|
|
|
65
65
|
var init_package = __esm(() => {
|
|
66
66
|
package_default = {
|
|
67
67
|
name: "@brainervirus/workit-cli",
|
|
68
|
-
version: "8.13.
|
|
68
|
+
version: "8.13.1",
|
|
69
69
|
private: false,
|
|
70
70
|
description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
71
71
|
keywords: [
|
|
@@ -103,13 +103,14 @@ var init_package = __esm(() => {
|
|
|
103
103
|
},
|
|
104
104
|
dependencies: {
|
|
105
105
|
"@babel/parser": "7.29.9",
|
|
106
|
-
"@brainervirus/workit-
|
|
107
|
-
"@brainervirus/workit-cursor": "^8.13.0",
|
|
108
|
-
"@brainervirus/workit-opencode": "^8.13.0",
|
|
106
|
+
"@brainervirus/workit-cursor": "^8.13.1",
|
|
109
107
|
"@inkjs/ui": "2.0.0",
|
|
110
108
|
ink: "7.1.1",
|
|
111
109
|
react: "19.2.8"
|
|
112
110
|
},
|
|
111
|
+
devDependencies: {
|
|
112
|
+
"@brainervirus/workit-core": "^8.13.1"
|
|
113
|
+
},
|
|
113
114
|
engines: {
|
|
114
115
|
node: ">=24"
|
|
115
116
|
}
|
|
@@ -10429,7 +10430,7 @@ var init_paths = __esm(() => {
|
|
|
10429
10430
|
});
|
|
10430
10431
|
|
|
10431
10432
|
// packages/workit-core/src/host-session.ts
|
|
10432
|
-
import { createHash as createHash3 } from "node:crypto";
|
|
10433
|
+
import { createHash as createHash3, randomBytes as randomBytes2, timingSafeEqual } from "node:crypto";
|
|
10433
10434
|
import fs6 from "node:fs";
|
|
10434
10435
|
import path6 from "node:path";
|
|
10435
10436
|
function hostSessionFromEnv(env) {
|
|
@@ -10482,7 +10483,12 @@ function migrateRepoIssued(cwd) {
|
|
|
10482
10483
|
const to = path6.join(userIssuedRoot(), lead);
|
|
10483
10484
|
fs6.mkdirSync(to, { recursive: true, mode: 448 });
|
|
10484
10485
|
for (const id of fs6.readdirSync(from)) {
|
|
10485
|
-
|
|
10486
|
+
try {
|
|
10487
|
+
fs6.copyFileSync(path6.join(from, id), path6.join(to, id), fs6.constants.COPYFILE_EXCL);
|
|
10488
|
+
} catch (error) {
|
|
10489
|
+
if (error.code !== "EEXIST")
|
|
10490
|
+
throw error;
|
|
10491
|
+
}
|
|
10486
10492
|
fs6.rmSync(path6.join(from, id), { force: true });
|
|
10487
10493
|
}
|
|
10488
10494
|
removeIfEmpty(from);
|
|
@@ -10490,7 +10496,25 @@ function migrateRepoIssued(cwd) {
|
|
|
10490
10496
|
}
|
|
10491
10497
|
removeIfEmpty(old);
|
|
10492
10498
|
}
|
|
10493
|
-
function
|
|
10499
|
+
function issuedBinding(cwd, claimed) {
|
|
10500
|
+
const record = issuedRecord(cwd, claimed);
|
|
10501
|
+
const { stored, leadBound } = issuedToken(claimed);
|
|
10502
|
+
if (stored)
|
|
10503
|
+
return "token";
|
|
10504
|
+
if (record === null)
|
|
10505
|
+
return null;
|
|
10506
|
+
return leadBound ? "token" : "legacy";
|
|
10507
|
+
}
|
|
10508
|
+
function issuedTokenMatches(cwd, claimed, token) {
|
|
10509
|
+
migrateRepoIssued(cwd);
|
|
10510
|
+
const { stored } = issuedToken(claimed);
|
|
10511
|
+
if (!stored || !token)
|
|
10512
|
+
return false;
|
|
10513
|
+
const given = Buffer.from(tokenHash(token.trim()));
|
|
10514
|
+
const want = Buffer.from(stored);
|
|
10515
|
+
return given.length === want.length && timingSafeEqual(given, want);
|
|
10516
|
+
}
|
|
10517
|
+
function sessionClaimRefusal(env, claimed, cwd, options = {}) {
|
|
10494
10518
|
const real = realHostSession(env);
|
|
10495
10519
|
const host = family(real.host);
|
|
10496
10520
|
if (real.kind !== "derived" && host !== null && HOST_SET_VARIABLE[host])
|
|
@@ -10500,18 +10524,22 @@ function sessionClaimRefusal(env, claimed, cwd) {
|
|
|
10500
10524
|
};
|
|
10501
10525
|
if (real.kind === "none" || !real.session)
|
|
10502
10526
|
return null;
|
|
10503
|
-
|
|
10504
|
-
if (
|
|
10505
|
-
|
|
10506
|
-
|
|
10507
|
-
|
|
10508
|
-
|
|
10509
|
-
|
|
10510
|
-
|
|
10511
|
-
|
|
10512
|
-
if (
|
|
10527
|
+
const ownShell = claimed === real.session && !(real.kind === "declared" && claimed.includes(":")) || real.kind === "derived" && claimed.endsWith(`:${real.session}`);
|
|
10528
|
+
if (ownShell)
|
|
10529
|
+
return options.flag ? {
|
|
10530
|
+
error: `session_flag: --session ${claimed} names this shell's own ${real.host} session; on a host only an issued subagent id is passed as --session`,
|
|
10531
|
+
unblock: "drop --session: the shell's own session is already the acting one"
|
|
10532
|
+
} : null;
|
|
10533
|
+
const issuedClaim = claimed === real.session || claimed.startsWith(`${real.session}:`);
|
|
10534
|
+
if (issuedClaim) {
|
|
10535
|
+
const binding = issuedBinding(cwd, claimed);
|
|
10536
|
+
if (binding === "legacy")
|
|
10513
10537
|
return null;
|
|
10514
|
-
|
|
10538
|
+
if (binding === "token")
|
|
10539
|
+
return issuedTokenMatches(cwd, claimed, options.token) ? null : {
|
|
10540
|
+
error: `unbound_session: ${claimed} was issued to a subagent, and this call did not present the token its SubagentStart hook gave it`,
|
|
10541
|
+
unblock: `only that subagent acts as ${claimed}: it passes --token exactly as its SubagentStart context names it (or WORKIT_SESSION_TOKEN); anyone else spawns their own verifier`
|
|
10542
|
+
};
|
|
10515
10543
|
}
|
|
10516
10544
|
const error = `forged_session: ${claimed} is neither this shell's session (${real.session}) nor an id its host issued to a child of it`;
|
|
10517
10545
|
if (issuedClaim && noIssuedRecord(cwd, leadOf(claimed)) && host !== null && PLUGIN_UPDATE[host])
|
|
@@ -10522,10 +10550,10 @@ function sessionClaimRefusal(env, claimed, cwd) {
|
|
|
10522
10550
|
const ownChildShell = host !== null && OWN_CHILD_SHELL.has(host);
|
|
10523
10551
|
return {
|
|
10524
10552
|
error,
|
|
10525
|
-
unblock: ownChildShell ? `record the verdict from the verifier's own ${host === "pi" ? "Pi worker" : "OpenCode child session"} shell, where WORKIT_SESSION_ID is already set; never set WORKIT_SESSION_ID or --session by hand` : "never name a session yourself: spawn a verifier or reviewer subagent and pass exactly the --session its SubagentStart context names, or pass --as verifier"
|
|
10553
|
+
unblock: ownChildShell ? `record the verdict from the verifier's own ${host === "pi" ? "Pi worker" : "OpenCode child session"} shell, where WORKIT_SESSION_ID is already set; never set WORKIT_SESSION_ID or --session by hand` : "never name a session yourself: spawn a verifier or reviewer subagent and pass exactly the --session and --token its SubagentStart context names, or pass --as verifier"
|
|
10526
10554
|
};
|
|
10527
10555
|
}
|
|
10528
|
-
var HOST_SESSION_VARS, family = (host) => host?.replace(/_(?:cli|desktop)$/, "") ?? null, hash = (value) => createHash3("sha256").update(value).digest("hex").slice(0, 32), userIssuedRoot = () => path6.join(resolveStateDir(), "issued"), safeList = (dir) => {
|
|
10556
|
+
var HOST_SESSION_VARS, family = (host) => host?.replace(/_(?:cli|desktop)$/, "") ?? null, hash = (value) => createHash3("sha256").update(value).digest("hex").slice(0, 32), userIssuedRoot = () => path6.join(resolveStateDir(), "issued"), userTokenRoot = () => path6.join(resolveStateDir(), "issued-tokens"), safeList = (dir) => {
|
|
10529
10557
|
try {
|
|
10530
10558
|
return fs6.readdirSync(dir);
|
|
10531
10559
|
} catch {
|
|
@@ -10544,12 +10572,26 @@ var HOST_SESSION_VARS, family = (host) => host?.replace(/_(?:cli|desktop)$/, "")
|
|
|
10544
10572
|
} catch {
|
|
10545
10573
|
return false;
|
|
10546
10574
|
}
|
|
10547
|
-
}, PLUGIN_UPDATE,
|
|
10575
|
+
}, PLUGIN_UPDATE, tokenHash = (token) => createHash3("sha256").update(token).digest("hex"), issuedRecord = (cwd, claimed) => {
|
|
10576
|
+
const cut = claimed.lastIndexOf(":");
|
|
10577
|
+
if (cut <= 0)
|
|
10578
|
+
return null;
|
|
10548
10579
|
migrateRepoIssued(cwd);
|
|
10549
10580
|
try {
|
|
10550
|
-
return fs6.
|
|
10581
|
+
return fs6.readFileSync(path6.join(userIssuedRoot(), hash(claimed.slice(0, cut)), hash(claimed)), "utf8");
|
|
10551
10582
|
} catch {
|
|
10552
|
-
return
|
|
10583
|
+
return null;
|
|
10584
|
+
}
|
|
10585
|
+
}, TOKEN_HASH, issuedToken = (claimed) => {
|
|
10586
|
+
const cut = claimed.lastIndexOf(":");
|
|
10587
|
+
if (cut <= 0)
|
|
10588
|
+
return { stored: null, leadBound: false };
|
|
10589
|
+
const dir = path6.join(userTokenRoot(), hash(claimed.slice(0, cut)));
|
|
10590
|
+
try {
|
|
10591
|
+
const text = fs6.readFileSync(path6.join(dir, hash(claimed)), "utf8");
|
|
10592
|
+
return { stored: TOKEN_HASH.exec(text)?.[1] ?? null, leadBound: true };
|
|
10593
|
+
} catch {
|
|
10594
|
+
return { stored: null, leadBound: safeList(dir).length > 0 };
|
|
10553
10595
|
}
|
|
10554
10596
|
}, leadOf = (session) => session.slice(0, session.lastIndexOf(":")), OWN_CHILD_SHELL, HOST_SET_VARIABLE;
|
|
10555
10597
|
var init_host_session = __esm(() => {
|
|
@@ -10567,6 +10609,7 @@ var init_host_session = __esm(() => {
|
|
|
10567
10609
|
claude_code: "claude plugin marketplace update workit && claude plugin update workit@workit",
|
|
10568
10610
|
codex: "codex plugin remove workit@workit && codex plugin add workit@workit"
|
|
10569
10611
|
};
|
|
10612
|
+
TOKEN_HASH = /^([0-9a-f]{64})$/mu;
|
|
10570
10613
|
OWN_CHILD_SHELL = new Set(["opencode", "pi"]);
|
|
10571
10614
|
HOST_SET_VARIABLE = {
|
|
10572
10615
|
opencode: "OPENCODE_SESSION_ID",
|
|
@@ -10599,7 +10642,7 @@ import { spawnSync as spawnSync3 } from "node:child_process";
|
|
|
10599
10642
|
import fs7 from "node:fs";
|
|
10600
10643
|
import { hostname } from "node:os";
|
|
10601
10644
|
import path8 from "node:path";
|
|
10602
|
-
var metadataLockSchema, FOREIGN_LOCK_TTL_MS, UNREADABLE_LOCK_TTL_MS = 30000, RECLAIM_GUARD_TTL_MS = 30000,
|
|
10645
|
+
var metadataLockSchema, FOREIGN_LOCK_TTL_MS, UNREADABLE_LOCK_TTL_MS = 30000, RECLAIM_GUARD_TTL_MS = 30000, IN_PROCESS_LOCK_TIMEOUT_MS = 250, defaultLockTimeoutMs, defaultLockTimeout = () => defaultLockTimeoutMs, hostAwareLockTimeout = (cliMs) => defaultLockTimeoutMs > IN_PROCESS_LOCK_TIMEOUT_MS ? cliMs : IN_PROCESS_LOCK_TIMEOUT_MS, setDefaultLockTimeout = (ms) => {
|
|
10603
10646
|
defaultLockTimeoutMs = ms;
|
|
10604
10647
|
}, parseMetadataLock = (raw) => {
|
|
10605
10648
|
let value;
|
|
@@ -10789,6 +10832,7 @@ var init_store_lock = __esm(() => {
|
|
|
10789
10832
|
externalAction: literal(true).optional()
|
|
10790
10833
|
}).strict();
|
|
10791
10834
|
FOREIGN_LOCK_TTL_MS = 10 * 60000;
|
|
10835
|
+
defaultLockTimeoutMs = IN_PROCESS_LOCK_TIMEOUT_MS;
|
|
10792
10836
|
TASK_STORE_LOCK = { reclaimUnverifiedAfterTtl: true };
|
|
10793
10837
|
});
|
|
10794
10838
|
|
|
@@ -14789,7 +14833,7 @@ var init_vcs_config = __esm(() => {
|
|
|
14789
14833
|
|
|
14790
14834
|
// packages/workit-core/src/ledger.ts
|
|
14791
14835
|
import { spawnSync as spawnSync9 } from "node:child_process";
|
|
14792
|
-
import { createHash as createHash9, randomBytes as
|
|
14836
|
+
import { createHash as createHash9, randomBytes as randomBytes3 } from "node:crypto";
|
|
14793
14837
|
import fs12 from "node:fs";
|
|
14794
14838
|
import path15 from "node:path";
|
|
14795
14839
|
function resolveCommit(cwd, ref) {
|
|
@@ -14878,7 +14922,7 @@ function actorFromEnv(env) {
|
|
|
14878
14922
|
agentId: value("WORKIT_AGENT_ID")
|
|
14879
14923
|
};
|
|
14880
14924
|
}
|
|
14881
|
-
function withLedgerLock(file, fn, waitMs = LOCK_WAIT_MS) {
|
|
14925
|
+
function withLedgerLock(file, fn, waitMs = hostAwareLockTimeout(LOCK_WAIT_MS)) {
|
|
14882
14926
|
const lock = `${file}.lock`;
|
|
14883
14927
|
const deadline = Date.now() + waitMs;
|
|
14884
14928
|
let token = null;
|
|
@@ -14902,8 +14946,10 @@ function withLedgerLock(file, fn, waitMs = LOCK_WAIT_MS) {
|
|
|
14902
14946
|
}
|
|
14903
14947
|
function appendLine(file, build, options) {
|
|
14904
14948
|
const write = () => {
|
|
14905
|
-
const fd = fs12.openSync(file, "a+");
|
|
14949
|
+
const fd = fs12.openSync(file, "a+", 384);
|
|
14906
14950
|
try {
|
|
14951
|
+
if (process.platform !== "win32")
|
|
14952
|
+
tighten(fd);
|
|
14907
14953
|
const size = fs12.fstatSync(fd).size;
|
|
14908
14954
|
let fence = "";
|
|
14909
14955
|
if (size > 0) {
|
|
@@ -14982,7 +15028,9 @@ function readLedger(cwd, options = {}) {
|
|
|
14982
15028
|
if (!file.ok)
|
|
14983
15029
|
return file;
|
|
14984
15030
|
let text = "";
|
|
15031
|
+
let stat = null;
|
|
14985
15032
|
try {
|
|
15033
|
+
stat = fs12.statSync(file.value);
|
|
14986
15034
|
text = fs12.readFileSync(file.value, "utf8");
|
|
14987
15035
|
} catch (error) {
|
|
14988
15036
|
if (error.code === "ENOENT")
|
|
@@ -15002,6 +15050,7 @@ function readLedger(cwd, options = {}) {
|
|
|
15002
15050
|
const integrity = { chained: 0, legacy: 0, unverified: [] };
|
|
15003
15051
|
const earlier = new Set([null]);
|
|
15004
15052
|
let chainStarted = false;
|
|
15053
|
+
const ids = new Set;
|
|
15005
15054
|
for (const raw of text.split(`
|
|
15006
15055
|
`)) {
|
|
15007
15056
|
const trimmed = raw.trim();
|
|
@@ -15035,6 +15084,10 @@ function readLedger(cwd, options = {}) {
|
|
|
15035
15084
|
reason = "unsigned";
|
|
15036
15085
|
else
|
|
15037
15086
|
rowIntegrity = "legacy";
|
|
15087
|
+
if (options.integrity && !reason && ids.has(parsed.id))
|
|
15088
|
+
reason = "duplicate_id";
|
|
15089
|
+
if (options.integrity)
|
|
15090
|
+
ids.add(parsed.id);
|
|
15038
15091
|
if (reason)
|
|
15039
15092
|
rowIntegrity = "unverified";
|
|
15040
15093
|
const pr = typeof parsed.pr === "number" && Number.isInteger(parsed.pr) ? parsed.pr : undefined;
|
|
@@ -15058,7 +15111,8 @@ function readLedger(cwd, options = {}) {
|
|
|
15058
15111
|
seq: rows.length + 1,
|
|
15059
15112
|
superseded: false,
|
|
15060
15113
|
supersedeIgnored: false,
|
|
15061
|
-
...rowIntegrity ? { integrity: rowIntegrity } : {}
|
|
15114
|
+
...rowIntegrity ? { integrity: rowIntegrity } : {},
|
|
15115
|
+
...reason ? { integrityReason: reason } : {}
|
|
15062
15116
|
};
|
|
15063
15117
|
rows.push(row);
|
|
15064
15118
|
if (!options.integrity)
|
|
@@ -15086,18 +15140,44 @@ function readLedger(cwd, options = {}) {
|
|
|
15086
15140
|
const byId = new Map;
|
|
15087
15141
|
for (const row of rows) {
|
|
15088
15142
|
const target = row.supersedes ? byId.get(row.supersedes) : undefined;
|
|
15089
|
-
if (target && supersedeAllowed(row, target, renameAwareBranch(scopeOf, row.branch)) === null)
|
|
15143
|
+
if (target && row.integrity !== "unverified" && supersedeAllowed(row, target, renameAwareBranch(scopeOf, row.branch)) === null)
|
|
15090
15144
|
target.superseded = true;
|
|
15091
15145
|
else if (row.supersedes)
|
|
15092
15146
|
row.supersedeIgnored = true;
|
|
15093
15147
|
if (!byId.has(row.id))
|
|
15094
15148
|
byId.set(row.id, row);
|
|
15095
15149
|
}
|
|
15150
|
+
if (options.integrity && stat && Buffer.byteLength(text) === stat.size)
|
|
15151
|
+
tamperCache.set(file.value, {
|
|
15152
|
+
size: stat.size,
|
|
15153
|
+
stamp: fileStamp(stat),
|
|
15154
|
+
breaks: integrity.unverified.filter((row) => TAMPER_REASONS.has(row.reason))
|
|
15155
|
+
});
|
|
15096
15156
|
return {
|
|
15097
15157
|
ok: true,
|
|
15098
15158
|
value: { path: file.value, rows, skipped, integrity: options.integrity ? integrity : null }
|
|
15099
15159
|
};
|
|
15100
15160
|
}
|
|
15161
|
+
function ledgerTampering(cwd) {
|
|
15162
|
+
const file = ledgerPath(cwd);
|
|
15163
|
+
if (!file.ok)
|
|
15164
|
+
return [];
|
|
15165
|
+
try {
|
|
15166
|
+
const stat = fs12.statSync(file.value);
|
|
15167
|
+
const cached = tamperCache.get(file.value);
|
|
15168
|
+
if (cached && cached.size === stat.size && cached.stamp === fileStamp(stat))
|
|
15169
|
+
return cached.breaks;
|
|
15170
|
+
} catch {
|
|
15171
|
+
return [];
|
|
15172
|
+
}
|
|
15173
|
+
const read = readLedger(cwd, { integrity: true });
|
|
15174
|
+
return read.ok ? (read.value.integrity?.unverified ?? []).filter((row) => TAMPER_REASONS.has(row.reason)) : [];
|
|
15175
|
+
}
|
|
15176
|
+
function tamperedUnblock(cwd) {
|
|
15177
|
+
const file = ledgerPath(cwd);
|
|
15178
|
+
const where = file.ok ? file.value : "the ledger file";
|
|
15179
|
+
return `workit ledger verify-integrity # lists the edited or missing rows; if the edit is understood, move ${where} aside (mv ${where} ${where}.tampered-<date>) and record the verdicts again`;
|
|
15180
|
+
}
|
|
15101
15181
|
function filterRows(rows, filter) {
|
|
15102
15182
|
const matched = rows.filter((row) => (filter.branch === undefined || row.branch === filter.branch) && (filter.pr === undefined || row.pr === filter.pr) && (filter.type === undefined || row.type === filter.type));
|
|
15103
15183
|
return filter.last === undefined ? matched : matched.slice(Math.max(0, matched.length - filter.last));
|
|
@@ -15213,15 +15293,51 @@ function authorSessions(cwd, rows, branch, range = { base: null, head: null }, s
|
|
|
15213
15293
|
sessions.add(session);
|
|
15214
15294
|
return sessions;
|
|
15215
15295
|
}
|
|
15216
|
-
function
|
|
15296
|
+
function sessionTrust(cwd, row) {
|
|
15297
|
+
const session = row.actor.session;
|
|
15298
|
+
if (!session || row.self === true)
|
|
15299
|
+
return null;
|
|
15300
|
+
const source = typeof row.sessionSource === "string" ? row.sessionSource : "env";
|
|
15301
|
+
const host = row.actor.host;
|
|
15302
|
+
const issuedOnly = source === "flag" ? host !== "cli" : source === "env" && session.includes(":") && !SHELL_VOUCHED_HOSTS.has(host);
|
|
15303
|
+
if (!issuedOnly)
|
|
15304
|
+
return null;
|
|
15305
|
+
const binding = issuedBinding(cwd, session);
|
|
15306
|
+
if (binding === null)
|
|
15307
|
+
return "unissued_session";
|
|
15308
|
+
return binding === "token" && row.sessionBound !== true ? "unbound_session" : null;
|
|
15309
|
+
}
|
|
15310
|
+
function trustReasons(cwd, row) {
|
|
15311
|
+
if (row.integrity === "unverified")
|
|
15312
|
+
return [row.integrityReason ?? "unsigned"];
|
|
15313
|
+
if (row.integrity !== "verified")
|
|
15314
|
+
return ["unsigned"];
|
|
15315
|
+
const session = sessionTrust(cwd, row);
|
|
15316
|
+
return session ? [session] : [];
|
|
15317
|
+
}
|
|
15318
|
+
function withIntegrity(cwd, rows) {
|
|
15319
|
+
if (rows.every((row) => row.integrity !== undefined))
|
|
15320
|
+
return rows;
|
|
15321
|
+
const read = readLedger(cwd, { integrity: true });
|
|
15322
|
+
const bySeq = new Map(read.ok ? read.value.rows.map((row) => [row.seq, row]) : []);
|
|
15323
|
+
return rows.map((row) => {
|
|
15324
|
+
if (row.integrity !== undefined)
|
|
15325
|
+
return row;
|
|
15326
|
+
const fresh = bySeq.get(row.seq);
|
|
15327
|
+
return fresh && fresh.id === row.id && fresh.at === row.at ? fresh : row;
|
|
15328
|
+
});
|
|
15329
|
+
}
|
|
15330
|
+
function effectiveOf(rows, reasonsOf, sameCode, isCurrent) {
|
|
15217
15331
|
let effective = null;
|
|
15218
15332
|
for (const row of rows) {
|
|
15219
15333
|
if (!effective) {
|
|
15220
15334
|
effective = row;
|
|
15221
15335
|
continue;
|
|
15222
15336
|
}
|
|
15223
|
-
|
|
15224
|
-
|
|
15337
|
+
if (untrusted(reasonsOf(row)) && !untrusted(reasonsOf(effective)))
|
|
15338
|
+
continue;
|
|
15339
|
+
const rowIndependent = reasonsOf(row).length === 0;
|
|
15340
|
+
const effIndependent = reasonsOf(effective).length === 0;
|
|
15225
15341
|
if (effIndependent && !rowIndependent && isCurrent(effective))
|
|
15226
15342
|
continue;
|
|
15227
15343
|
if (effIndependent && FAILING.has(String(effective.result)) && row.actor.session === effective.actor.session && sameCode(effective, row))
|
|
@@ -15235,7 +15351,7 @@ function restackCarries(rows, branch, from, to) {
|
|
|
15235
15351
|
return false;
|
|
15236
15352
|
const edges = new Map;
|
|
15237
15353
|
for (const row of rows)
|
|
15238
|
-
if (row.type === "stack.restacked" && row.observer === "workit_cli" && row.branch === branch && row.patchEqual === true && typeof row.fromHead === "string" && row.head)
|
|
15354
|
+
if (row.type === "stack.restacked" && row.observer === "workit_cli" && row.integrity === "verified" && row.branch === branch && row.patchEqual === true && typeof row.fromHead === "string" && row.head)
|
|
15239
15355
|
edges.set(row.fromHead, [...edges.get(row.fromHead) ?? [], row.head]);
|
|
15240
15356
|
const seen = new Set([from]);
|
|
15241
15357
|
const queue = [from];
|
|
@@ -15251,7 +15367,8 @@ function restackCarries(rows, branch, from, to) {
|
|
|
15251
15367
|
}
|
|
15252
15368
|
return false;
|
|
15253
15369
|
}
|
|
15254
|
-
function checkVerdicts(cwd, branch,
|
|
15370
|
+
function checkVerdicts(cwd, branch, ledgerRows) {
|
|
15371
|
+
const rows = withIntegrity(cwd, ledgerRows);
|
|
15255
15372
|
const head = branchHead(cwd, branch);
|
|
15256
15373
|
const fallbackBase = defaultBase(cwd);
|
|
15257
15374
|
const scope = branchScope(cwd, branch);
|
|
@@ -15281,21 +15398,47 @@ function checkVerdicts(cwd, branch, rows) {
|
|
|
15281
15398
|
return verdictBasis(failed, { head: row.head, ...keys }) !== "stale" || restackCarries(rows, branch, failed.head, row.head);
|
|
15282
15399
|
};
|
|
15283
15400
|
const authors = authorSessions(cwd, rows, branch, { base: fallbackBase, head }, scope);
|
|
15401
|
+
const failureAuthorCache = new Map;
|
|
15402
|
+
const failureAuthors = (row) => {
|
|
15403
|
+
let set = failureAuthorCache.get(row.seq);
|
|
15404
|
+
if (!set) {
|
|
15405
|
+
set = authorSessions(cwd, rows.filter((other) => other.integrity === "verified" && other.seq < row.seq), branch, { base: null, head: null }, scope);
|
|
15406
|
+
failureAuthorCache.set(row.seq, set);
|
|
15407
|
+
}
|
|
15408
|
+
return set;
|
|
15409
|
+
};
|
|
15410
|
+
const reasonCache = new Map;
|
|
15411
|
+
const reasonsOf = (row) => {
|
|
15412
|
+
let reasons = reasonCache.get(row);
|
|
15413
|
+
if (!reasons) {
|
|
15414
|
+
const failing = FAILING.has(String(row.result));
|
|
15415
|
+
reasons = [
|
|
15416
|
+
...trustReasons(cwd, row),
|
|
15417
|
+
...independenceReasons(row, failing ? failureAuthors(row) : authors)
|
|
15418
|
+
];
|
|
15419
|
+
reasonCache.set(row, reasons);
|
|
15420
|
+
}
|
|
15421
|
+
return reasons;
|
|
15422
|
+
};
|
|
15423
|
+
const retired = new Set;
|
|
15424
|
+
for (const row of rows)
|
|
15425
|
+
if (row.type === "verdict" && row.supersedes && !row.supersedeIgnored && trustReasons(cwd, row).length === 0)
|
|
15426
|
+
retired.add(row.supersedes);
|
|
15284
15427
|
const byKind = new Map;
|
|
15285
15428
|
for (const row of rows)
|
|
15286
|
-
if (isLiveVerdict(row) && scope(row)) {
|
|
15429
|
+
if (isLiveVerdict(row, retired) && scope(row)) {
|
|
15287
15430
|
const kind = typeof row.kind === "string" ? row.kind : "review";
|
|
15288
15431
|
byKind.set(kind, [...byKind.get(kind) ?? [], row]);
|
|
15289
15432
|
}
|
|
15290
15433
|
const verdicts = [];
|
|
15291
15434
|
const warnings = [];
|
|
15292
15435
|
for (const [kind, list] of byKind) {
|
|
15293
|
-
const row = effectiveOf(list,
|
|
15436
|
+
const row = effectiveOf(list, reasonsOf, sameCode, (candidate) => basisOf(candidate) !== "stale");
|
|
15294
15437
|
if (!row)
|
|
15295
15438
|
continue;
|
|
15296
15439
|
const basis = basisOf(row);
|
|
15297
15440
|
const current = basis !== "stale";
|
|
15298
|
-
const independence =
|
|
15441
|
+
const independence = reasonsOf(row);
|
|
15299
15442
|
const reasons = [
|
|
15300
15443
|
...current ? [] : ["stale"],
|
|
15301
15444
|
...PASSING.has(String(row.result)) ? [] : ["not_passing"],
|
|
@@ -15312,23 +15455,31 @@ function checkVerdicts(cwd, branch, rows) {
|
|
|
15312
15455
|
});
|
|
15313
15456
|
if (reasons.length === 0) {
|
|
15314
15457
|
for (const later of list)
|
|
15315
|
-
if (later.seq > row.seq &&
|
|
15458
|
+
if (later.seq > row.seq && reasonsOf(later).length > 0 && !untrusted(reasonsOf(later)) && FAILING.has(String(later.result)) && basisOf(later) !== "stale")
|
|
15316
15459
|
warnings.push(`the author's own (self) ${String(later.result)} ${kind} verdict ${later.id} by ${later.actor.session ?? "no session"} on the current code is newer than the accepted pass ${row.id}: read it before merging`);
|
|
15317
15460
|
}
|
|
15318
15461
|
}
|
|
15319
15462
|
for (const row of rows)
|
|
15320
15463
|
if (row.integrity === "unverified" && scope(row))
|
|
15321
15464
|
warnings.push(`ledger row ${row.id} (${row.type}) on ${row.branch ?? branch} is unverified: the workit CLI did not write it or it changed afterwards (workit ledger verify-integrity)`);
|
|
15465
|
+
const tampered = ledgerTampering(cwd);
|
|
15466
|
+
if (tampered.length) {
|
|
15467
|
+
warnings.push(tamperedWarning(cwd, tampered));
|
|
15468
|
+
for (const entry of verdicts) {
|
|
15469
|
+
entry.accepted = false;
|
|
15470
|
+
entry.reasons = [...entry.reasons, "ledger_tampered"];
|
|
15471
|
+
}
|
|
15472
|
+
}
|
|
15322
15473
|
verdicts.sort((a, b) => a.verdict.seq - b.verdict.seq);
|
|
15323
15474
|
const newestCurrent = verdicts.findLast((entry) => entry.current) ?? verdicts.at(-1) ?? null;
|
|
15324
15475
|
const failing = verdicts.find((entry) => entry.current && entry.independent && FAILING.has(String(entry.verdict.result)));
|
|
15325
15476
|
const newestAccepted = verdicts.findLast((entry) => entry.accepted && STRONG_RESULTS.has(String(entry.verdict.result))) ?? null;
|
|
15326
|
-
const accepted = newestAccepted && !failing ? { accepted: true, verdict: newestAccepted.verdict, reasons: [] } : {
|
|
15477
|
+
const accepted = tampered.length ? { accepted: false, verdict: null, reasons: ["ledger_tampered"] } : newestAccepted && !failing ? { accepted: true, verdict: newestAccepted.verdict, reasons: [] } : {
|
|
15327
15478
|
accepted: false,
|
|
15328
15479
|
verdict: failing?.verdict ?? null,
|
|
15329
15480
|
reasons: failing ? ["failing_verdict"] : !newestCurrent ? ["no_verdict"] : newestCurrent.reasons.length ? newestCurrent.reasons : ["type_check_only"]
|
|
15330
15481
|
};
|
|
15331
|
-
const selfEntry = failing ? undefined : verdicts.findLast((entry) => entry.current && !entry.independent && STRONG_RESULTS.has(String(entry.verdict.result)));
|
|
15482
|
+
const selfEntry = failing ? undefined : verdicts.findLast((entry) => entry.current && !entry.independent && !untrusted(entry.reasons) && STRONG_RESULTS.has(String(entry.verdict.result)));
|
|
15332
15483
|
return {
|
|
15333
15484
|
branch,
|
|
15334
15485
|
head,
|
|
@@ -15523,6 +15674,7 @@ function recordVerdict(context, input) {
|
|
|
15523
15674
|
self: self2,
|
|
15524
15675
|
selfReason,
|
|
15525
15676
|
sessionSource: context.sessionSource ?? "env",
|
|
15677
|
+
...context.sessionBound === true ? { sessionBound: true } : {},
|
|
15526
15678
|
evidenceRefs: input.evidenceRefs ?? []
|
|
15527
15679
|
}, { now: context.now });
|
|
15528
15680
|
}
|
|
@@ -15751,7 +15903,7 @@ var LEDGER_VERSION = 1, MAX_LINE_BYTES = 4096, VERDICT_RESULTS, PASSING, FAILING
|
|
|
15751
15903
|
} catch {
|
|
15752
15904
|
return null;
|
|
15753
15905
|
}
|
|
15754
|
-
}, newId2 = () => `${Date.now().toString(36)}-${
|
|
15906
|
+
}, newId2 = () => `${Date.now().toString(36)}-${randomBytes3(6).toString("hex")}`, NETWORK_FS_TYPES, isNetworkFsType = (type) => NETWORK_FS_TYPES.has(type >>> 0), onNetworkFs = (dir) => {
|
|
15755
15907
|
if (process.platform !== "linux")
|
|
15756
15908
|
return false;
|
|
15757
15909
|
try {
|
|
@@ -15804,6 +15956,11 @@ ${body}`), TAIL_BYTES, lastLine = (fd, size) => {
|
|
|
15804
15956
|
return text || null;
|
|
15805
15957
|
}
|
|
15806
15958
|
return null;
|
|
15959
|
+
}, tighten = (fd) => {
|
|
15960
|
+
try {
|
|
15961
|
+
if ((fs12.fstatSync(fd).mode & 63) !== 0)
|
|
15962
|
+
fs12.fchmodSync(fd, 384);
|
|
15963
|
+
} catch {}
|
|
15807
15964
|
}, sealed = (row, id, at, previous) => {
|
|
15808
15965
|
const { prevHash: _prev, rowHash: _row, ...fields } = row;
|
|
15809
15966
|
const prevHash = previous === null ? null : sha2562(previous);
|
|
@@ -15818,7 +15975,7 @@ ${body}`), TAIL_BYTES, lastLine = (fd, size) => {
|
|
|
15818
15975
|
session: str2(actor.session),
|
|
15819
15976
|
agentId: str2(actor.agentId)
|
|
15820
15977
|
};
|
|
15821
|
-
}, isLiveVerdict = (row) => row.type === "verdict" && typeof row.result === "string" && !row.
|
|
15978
|
+
}, TAMPER_REASONS, tamperCache, fileStamp = (stat) => `${stat.ino}:${stat.mtimeMs}:${stat.ctimeMs}`, tamperedWarning = (cwd, breaks) => `the ledger was edited, or a row was removed or moved (${breaks.slice(0, 3).map((row) => `${row.reason} at row ${row.seq}`).join(", ")}${breaks.length > 3 ? ", …" : ""}): no verdict is accepted until it is repaired. ${tamperedUnblock(cwd)}`, isLiveVerdict = (row, retired) => row.type === "verdict" && typeof row.result === "string" && !retired.has(row.id), RENAMED, renameAwareBranch = (scopeOf, branch) => {
|
|
15822
15979
|
return (target) => {
|
|
15823
15980
|
const own = typeof branch === "string" ? branch : null;
|
|
15824
15981
|
const theirs = typeof target.branch === "string" ? target.branch : null;
|
|
@@ -15835,7 +15992,7 @@ ${body}`), TAIL_BYTES, lastLine = (fd, size) => {
|
|
|
15835
15992
|
if (derivesFrom(author, session) || derivesFrom(session, author))
|
|
15836
15993
|
return true;
|
|
15837
15994
|
return false;
|
|
15838
|
-
}, independenceReasons = (row, authors) => {
|
|
15995
|
+
}, TRUST_REASONS, SHELL_VOUCHED_HOSTS, untrusted = (reasons) => reasons.some((reason) => TRUST_REASONS.has(reason)), independenceReasons = (row, authors) => {
|
|
15839
15996
|
const reasons = [];
|
|
15840
15997
|
if (!row.actor.session)
|
|
15841
15998
|
reasons.push("no_session");
|
|
@@ -15897,6 +16054,7 @@ ${body}`), TAIL_BYTES, lastLine = (fd, size) => {
|
|
|
15897
16054
|
return brief.pr === null ? "workit pr create" : `workit pr status --pr ${brief.pr}`;
|
|
15898
16055
|
};
|
|
15899
16056
|
var init_ledger = __esm(() => {
|
|
16057
|
+
init_store_lock();
|
|
15900
16058
|
init_vcs_config();
|
|
15901
16059
|
init_rev();
|
|
15902
16060
|
init_host_session();
|
|
@@ -15935,14 +16093,14 @@ var init_ledger = __esm(() => {
|
|
|
15935
16093
|
return null;
|
|
15936
16094
|
throw error;
|
|
15937
16095
|
}
|
|
15938
|
-
const token = `${process.pid}-${
|
|
16096
|
+
const token = `${process.pid}-${randomBytes3(8).toString("hex")}`;
|
|
15939
16097
|
fs12.writeFileSync(path15.join(lock, LOCK_OWNER), token);
|
|
15940
16098
|
return token;
|
|
15941
16099
|
},
|
|
15942
16100
|
release(lock, token) {
|
|
15943
16101
|
if (lockToken(lock) !== token)
|
|
15944
16102
|
return false;
|
|
15945
|
-
const tomb = `${lock}.release-${
|
|
16103
|
+
const tomb = `${lock}.release-${randomBytes3(6).toString("hex")}`;
|
|
15946
16104
|
try {
|
|
15947
16105
|
fs12.renameSync(lock, tomb);
|
|
15948
16106
|
} catch {
|
|
@@ -15959,7 +16117,7 @@ var init_ledger = __esm(() => {
|
|
|
15959
16117
|
},
|
|
15960
16118
|
token: lockToken,
|
|
15961
16119
|
reap(lock, observed) {
|
|
15962
|
-
const tomb = `${lock}.reap-${
|
|
16120
|
+
const tomb = `${lock}.reap-${randomBytes3(6).toString("hex")}`;
|
|
15963
16121
|
try {
|
|
15964
16122
|
fs12.renameSync(lock, tomb);
|
|
15965
16123
|
} catch {
|
|
@@ -15978,7 +16136,24 @@ var init_ledger = __esm(() => {
|
|
|
15978
16136
|
}
|
|
15979
16137
|
};
|
|
15980
16138
|
TAIL_BYTES = 64 * 1024;
|
|
16139
|
+
TAMPER_REASONS = new Set(["hash_mismatch", "broken_link"]);
|
|
16140
|
+
tamperCache = new Map;
|
|
15981
16141
|
RENAMED = /^branch: renamed refs\/heads\/(.+) to refs\/heads\/(.+)$/iu;
|
|
16142
|
+
TRUST_REASONS = new Set([
|
|
16143
|
+
"unsigned",
|
|
16144
|
+
"hash_mismatch",
|
|
16145
|
+
"broken_link",
|
|
16146
|
+
"duplicate_id",
|
|
16147
|
+
"unissued_session",
|
|
16148
|
+
"unbound_session"
|
|
16149
|
+
]);
|
|
16150
|
+
SHELL_VOUCHED_HOSTS = new Set([
|
|
16151
|
+
"cli",
|
|
16152
|
+
"opencode",
|
|
16153
|
+
"pi",
|
|
16154
|
+
"codex_cli",
|
|
16155
|
+
"codex_desktop"
|
|
16156
|
+
]);
|
|
15982
16157
|
OBSERVED_ONLY = new Set([
|
|
15983
16158
|
"check",
|
|
15984
16159
|
"merge.unverified",
|
|
@@ -63713,7 +63888,8 @@ var init_changelog = __esm(() => {
|
|
|
63713
63888
|
});
|
|
63714
63889
|
|
|
63715
63890
|
// packages/workit-core/src/core/hygiene.ts
|
|
63716
|
-
import {
|
|
63891
|
+
import { spawnSync as spawnSync12 } from "node:child_process";
|
|
63892
|
+
import { existsSync as existsSync9, readFileSync as readFileSync9, readdirSync as readdirSync5, writeFileSync as writeFileSync4 } from "node:fs";
|
|
63717
63893
|
import path26 from "node:path";
|
|
63718
63894
|
var repoRoot2, templatesDir = () => path26.join(repoRoot2, "templates", "hygiene"), packageJson = (root) => {
|
|
63719
63895
|
if (!existsSync9(path26.join(root, "package.json")))
|
|
@@ -63743,6 +63919,23 @@ var repoRoot2, templatesDir = () => path26.join(repoRoot2, "templates", "hygiene
|
|
|
63743
63919
|
}
|
|
63744
63920
|
}
|
|
63745
63921
|
return "";
|
|
63922
|
+
}, projectTarget = (dir) => {
|
|
63923
|
+
const start = path26.resolve(dir);
|
|
63924
|
+
const top = spawnSync12("git", ["rev-parse", "--show-toplevel"], { cwd: start, encoding: "utf8" });
|
|
63925
|
+
const root = top.status === 0 ? (top.stdout ?? "").trim() : "";
|
|
63926
|
+
if (root)
|
|
63927
|
+
return { ok: true, root: path26.resolve(root) };
|
|
63928
|
+
let children = [];
|
|
63929
|
+
try {
|
|
63930
|
+
children = readdirSync5(start, { withFileTypes: true }).filter((entry) => entry.isDirectory() && existsSync9(path26.join(start, entry.name, ".git"))).map((entry) => path26.join(start, entry.name)).toSorted();
|
|
63931
|
+
} catch {
|
|
63932
|
+
children = [];
|
|
63933
|
+
}
|
|
63934
|
+
const where = children.length > 0 ? `run it inside one of its repositories: ${children.slice(0, 5).map((child) => `cd ${child}`).join(", ")}${children.length > 5 ? ` (+${children.length - 5} more)` : ""}` : "cd <repo> (or git init here) and run workit init again";
|
|
63935
|
+
return {
|
|
63936
|
+
ok: false,
|
|
63937
|
+
refused: `${start} is not a git repository, so no project files were added there; ${where}`
|
|
63938
|
+
};
|
|
63746
63939
|
}, planHygieneFiles = (root, opts = {}) => {
|
|
63747
63940
|
const openSource = opts.includeOpenSource ?? isOpenSource(root);
|
|
63748
63941
|
const files = ["CHANGELOG.md", "README.md", ".editorconfig", ".gitattributes"];
|
|
@@ -63967,13 +64160,13 @@ var init_support_matrix = __esm(() => {
|
|
|
63967
64160
|
});
|
|
63968
64161
|
|
|
63969
64162
|
// packages/workit-cli/src/admin/host-install.ts
|
|
63970
|
-
import { spawnSync as
|
|
64163
|
+
import { spawnSync as spawnSync13 } from "node:child_process";
|
|
63971
64164
|
import {
|
|
63972
64165
|
accessSync,
|
|
63973
64166
|
constants as constants2,
|
|
63974
64167
|
existsSync as existsSync11,
|
|
63975
64168
|
readFileSync as readFileSync11,
|
|
63976
|
-
readdirSync as
|
|
64169
|
+
readdirSync as readdirSync6,
|
|
63977
64170
|
realpathSync as realpathSync6,
|
|
63978
64171
|
statSync as statSync2
|
|
63979
64172
|
} from "node:fs";
|
|
@@ -64016,7 +64209,7 @@ function findHostExecutable(name, options = {}) {
|
|
|
64016
64209
|
[path29.join(home, ".nvm", "versions", "node"), "bin"]
|
|
64017
64210
|
]) {
|
|
64018
64211
|
try {
|
|
64019
|
-
for (const entry of
|
|
64212
|
+
for (const entry of readdirSync6(base, { withFileTypes: true })) {
|
|
64020
64213
|
if (entry.isDirectory())
|
|
64021
64214
|
dirs.push(path29.join(base, entry.name, tail));
|
|
64022
64215
|
}
|
|
@@ -64238,7 +64431,7 @@ function runHostCommand(step, context = {}) {
|
|
|
64238
64431
|
stderr: `Cannot safely execute batch shim ${step.command}; resolve its Node.js CLI entrypoint and retry`
|
|
64239
64432
|
};
|
|
64240
64433
|
}
|
|
64241
|
-
const result =
|
|
64434
|
+
const result = spawnSync13(step.command, step.args, {
|
|
64242
64435
|
cwd: step.cwd,
|
|
64243
64436
|
env: (() => {
|
|
64244
64437
|
const home = context.home ?? context.env?.HOME ?? os7.homedir();
|
|
@@ -64292,6 +64485,40 @@ var resolveWindowsShimScript = (shim) => {
|
|
|
64292
64485
|
} catch {
|
|
64293
64486
|
return false;
|
|
64294
64487
|
}
|
|
64488
|
+
}, OPENCODE_PLUGIN_SCOPE = "@brainervirus", OPENCODE_PLUGIN_NAME = "workit-opencode", packageVersionAt = (root, name) => {
|
|
64489
|
+
try {
|
|
64490
|
+
const pkg = JSON.parse(readFileSync11(path29.join(root, "package.json"), "utf8"));
|
|
64491
|
+
return pkg.name === name && typeof pkg.version === "string" ? pkg.version : null;
|
|
64492
|
+
} catch {
|
|
64493
|
+
return null;
|
|
64494
|
+
}
|
|
64495
|
+
}, compareVersions = (a, b) => {
|
|
64496
|
+
const pa = a.split(/[.+-]/).map((n) => Number(n) || 0);
|
|
64497
|
+
const pb = b.split(/[.+-]/).map((n) => Number(n) || 0);
|
|
64498
|
+
for (let i = 0;i < Math.max(pa.length, pb.length); i++) {
|
|
64499
|
+
const d = (pa[i] ?? 0) - (pb[i] ?? 0);
|
|
64500
|
+
if (d !== 0)
|
|
64501
|
+
return d;
|
|
64502
|
+
}
|
|
64503
|
+
return 0;
|
|
64504
|
+
}, openCodeCacheDir = (home, env = process.env) => path29.join(env.XDG_CACHE_HOME || path29.join(home, ".cache"), "opencode"), subdirs = (dir) => {
|
|
64505
|
+
try {
|
|
64506
|
+
return readdirSync6(dir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => path29.join(dir, entry.name));
|
|
64507
|
+
} catch {
|
|
64508
|
+
return [];
|
|
64509
|
+
}
|
|
64510
|
+
}, openCodeInstalledPlugin = (home, env = process.env) => {
|
|
64511
|
+
const name = `${OPENCODE_PLUGIN_SCOPE}/${OPENCODE_PLUGIN_NAME}`;
|
|
64512
|
+
const cache = openCodeCacheDir(home, env);
|
|
64513
|
+
const specDirs = (layout) => subdirs(path29.join(cache, layout, OPENCODE_PLUGIN_SCOPE)).filter((dir) => path29.basename(dir) === `${OPENCODE_PLUGIN_NAME}@latest`);
|
|
64514
|
+
const installs = [...specDirs("npm").flatMap(subdirs), ...specDirs("packages")].map((dir) => path29.join(dir, "node_modules", OPENCODE_PLUGIN_SCOPE, OPENCODE_PLUGIN_NAME));
|
|
64515
|
+
let best = null;
|
|
64516
|
+
for (const root of installs) {
|
|
64517
|
+
const version = packageVersionAt(root, name);
|
|
64518
|
+
if (version && (!best || compareVersions(version, best.version) > 0))
|
|
64519
|
+
best = { root, version };
|
|
64520
|
+
}
|
|
64521
|
+
return best;
|
|
64295
64522
|
}, isCanonicalCodexPackage = (root) => {
|
|
64296
64523
|
for (const file of [
|
|
64297
64524
|
path29.join(root, ".codex-plugin", "plugin.json"),
|
|
@@ -64311,7 +64538,7 @@ var resolveWindowsShimScript = (shim) => {
|
|
|
64311
64538
|
if (isCanonicalCodexPackage(root))
|
|
64312
64539
|
return true;
|
|
64313
64540
|
try {
|
|
64314
|
-
return
|
|
64541
|
+
return readdirSync6(root, { withFileTypes: true }).some((entry) => entry.isDirectory() && isCanonicalCodexPackage(path29.join(root, entry.name)));
|
|
64315
64542
|
} catch {
|
|
64316
64543
|
return false;
|
|
64317
64544
|
}
|
|
@@ -64320,7 +64547,7 @@ var resolveWindowsShimScript = (shim) => {
|
|
|
64320
64547
|
return true;
|
|
64321
64548
|
const root = path29.join(codexHome, "plugins", "cache");
|
|
64322
64549
|
try {
|
|
64323
|
-
for (const marketplace of
|
|
64550
|
+
for (const marketplace of readdirSync6(root, { withFileTypes: true })) {
|
|
64324
64551
|
if (!marketplace.isDirectory())
|
|
64325
64552
|
continue;
|
|
64326
64553
|
if (isPackageOrVersionDirectory(path29.join(root, marketplace.name, "workit")))
|
|
@@ -64398,9 +64625,9 @@ var init_host_install = __esm(() => {
|
|
|
64398
64625
|
});
|
|
64399
64626
|
|
|
64400
64627
|
// packages/workit-core/src/core/skill-manifests.ts
|
|
64401
|
-
import { cpSync as cpSync3, existsSync as existsSync12, readFileSync as readFileSync12, readdirSync as
|
|
64628
|
+
import { cpSync as cpSync3, existsSync as existsSync12, readFileSync as readFileSync12, readdirSync as readdirSync7, statSync as statSync3, writeFileSync as writeFileSync5 } from "node:fs";
|
|
64402
64629
|
import path30 from "node:path";
|
|
64403
|
-
var WORKIT_METHOD_SKILLS, skillManifestNames = (root) => existsSync12(root) ?
|
|
64630
|
+
var WORKIT_METHOD_SKILLS, skillManifestNames = (root) => existsSync12(root) ? readdirSync7(root).filter((name) => existsSync12(path30.join(root, name, "SKILL.md"))).toSorted() : [], validateSkillManifests = (root, expected, label) => {
|
|
64404
64631
|
const actual = skillManifestNames(root);
|
|
64405
64632
|
const missing = expected.filter((name) => !actual.includes(name));
|
|
64406
64633
|
const extra = actual.filter((name) => !expected.includes(name));
|
|
@@ -64412,7 +64639,7 @@ var WORKIT_METHOD_SKILLS, skillManifestNames = (root) => existsSync12(root) ? re
|
|
|
64412
64639
|
const pending = [path30.join(pluginDir, "skills")];
|
|
64413
64640
|
while (pending.length > 0) {
|
|
64414
64641
|
const dir = pending.pop();
|
|
64415
|
-
for (const entry of
|
|
64642
|
+
for (const entry of readdirSync7(dir, { withFileTypes: true })) {
|
|
64416
64643
|
const file = path30.join(dir, entry.name);
|
|
64417
64644
|
if (entry.isDirectory())
|
|
64418
64645
|
pending.push(file);
|
|
@@ -64443,7 +64670,7 @@ var init_skill_manifests = __esm(() => {
|
|
|
64443
64670
|
});
|
|
64444
64671
|
|
|
64445
64672
|
// packages/workit-core/src/git/session-hook.ts
|
|
64446
|
-
import { spawnSync as
|
|
64673
|
+
import { spawnSync as spawnSync14 } from "node:child_process";
|
|
64447
64674
|
import {
|
|
64448
64675
|
chmodSync,
|
|
64449
64676
|
existsSync as existsSync13,
|
|
@@ -64638,7 +64865,7 @@ add_trailer "$(git rev-parse --git-path COMMIT_EDITMSG)"
|
|
|
64638
64865
|
[ "$2" != merge ] || add_trailer "$(git rev-parse --git-path MERGE_MSG)"
|
|
64639
64866
|
exit 0
|
|
64640
64867
|
`, manualTrailerLine = () => `h="$(git rev-parse --git-common-dir 2>/dev/null)/${HELPER.join("/")}"; [ ! -f "$h" ] || sh "$h" "$@" || true`, lefthookTrailerRun = () => `set -f; IFS=; h=$(git rev-parse --git-common-dir 2>/dev/null)/${HELPER.join("/")}; [ ! -f $h ] || sh $h '' {2} {3} || true`, HELPER_REF, SESSION_HOOK_SCRIPT, run2 = (cwd, args, env) => {
|
|
64641
|
-
const r =
|
|
64868
|
+
const r = spawnSync14("git", args, {
|
|
64642
64869
|
cwd,
|
|
64643
64870
|
encoding: "utf8",
|
|
64644
64871
|
timeout: GIT_TIMEOUTS.local,
|
|
@@ -64799,14 +65026,14 @@ ${manualTrailerLine()}
|
|
|
64799
65026
|
});
|
|
64800
65027
|
|
|
64801
65028
|
// packages/workit-cli/src/admin/doctor.ts
|
|
64802
|
-
import { spawnSync as
|
|
65029
|
+
import { spawnSync as spawnSync15 } from "node:child_process";
|
|
64803
65030
|
import { createHash as createHash14 } from "node:crypto";
|
|
64804
65031
|
import {
|
|
64805
65032
|
existsSync as existsSync14,
|
|
64806
65033
|
lstatSync as lstatSync5,
|
|
64807
65034
|
mkdirSync as mkdirSync6,
|
|
64808
65035
|
mkdtempSync,
|
|
64809
|
-
readdirSync as
|
|
65036
|
+
readdirSync as readdirSync8,
|
|
64810
65037
|
readFileSync as readFileSync14,
|
|
64811
65038
|
readlinkSync as readlinkSync2,
|
|
64812
65039
|
rmSync as rmSync3,
|
|
@@ -64832,7 +65059,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
64832
65059
|
const configDir = options.configDir ?? env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path32.join(home, ".config", "workit");
|
|
64833
65060
|
const stateDir = options.stateDir ?? env.WORKFLOW_TOOLKIT_STATE ?? path32.join(home, ".local", "state", "workit");
|
|
64834
65061
|
const cwd = options.cwd ?? process.cwd();
|
|
64835
|
-
const dev = options.dev
|
|
65062
|
+
const dev = options.dev?.trim() || env.WORKFLOW_TOOLKIT_DEV?.trim() || findDevFromCwd(cwd);
|
|
64836
65063
|
return {
|
|
64837
65064
|
host: options.host ?? "cli",
|
|
64838
65065
|
home,
|
|
@@ -64842,7 +65069,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
64842
65069
|
workspaceRoot: options.workspaceRoot ?? env.WORKFLOW_WORKSPACE_ROOT ?? cwd,
|
|
64843
65070
|
dev,
|
|
64844
65071
|
opencodeConfig: options.opencodeConfig ?? path32.join(home, ".config", "opencode", "opencode.json"),
|
|
64845
|
-
opencodePackageCacheDir: options.opencodePackageCacheDir ??
|
|
65072
|
+
opencodePackageCacheDir: options.opencodePackageCacheDir ?? null,
|
|
64846
65073
|
cursorSettings: options.cursorSettings ?? path32.join(home, ".cursor", "settings.json"),
|
|
64847
65074
|
cursorMcp: options.cursorMcp ?? path32.join(home, ".cursor", "mcp.json"),
|
|
64848
65075
|
cursorPluginDir: options.cursorPluginDir ?? path32.join(home, ".cursor", "plugins", "local", "workit"),
|
|
@@ -64888,7 +65115,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
64888
65115
|
}
|
|
64889
65116
|
return null;
|
|
64890
65117
|
}, versionOf = (bin, env, timeout) => {
|
|
64891
|
-
const r =
|
|
65118
|
+
const r = spawnSync15(bin, ["--version"], { encoding: "utf8", env, timeout });
|
|
64892
65119
|
if (r.error)
|
|
64893
65120
|
return null;
|
|
64894
65121
|
return (r.stdout ?? "").trim();
|
|
@@ -64906,7 +65133,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
64906
65133
|
if (env.BUN && existsSync14(env.BUN))
|
|
64907
65134
|
return env.BUN;
|
|
64908
65135
|
for (const candidate of [
|
|
64909
|
-
path32.join(os8.homedir(), ".bun/bin/bun"),
|
|
65136
|
+
path32.join(env.HOME || os8.homedir(), ".bun/bin/bun"),
|
|
64910
65137
|
"/usr/local/bin/bun",
|
|
64911
65138
|
"/usr/bin/bun"
|
|
64912
65139
|
]) {
|
|
@@ -64915,47 +65142,50 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
64915
65142
|
}
|
|
64916
65143
|
return commandOnPath("bun", env) ? "bun" : null;
|
|
64917
65144
|
}, checkRuntime = (res) => {
|
|
64918
|
-
const
|
|
64919
|
-
const
|
|
65145
|
+
const running = `v${process.versions.node}`;
|
|
65146
|
+
const runningOk = semverAtLeast(running, SUPPORT_MATRIX.node.minimum);
|
|
65147
|
+
const pathNode = versionOf("node", res.env);
|
|
64920
65148
|
const bun = resolveBun(res.env);
|
|
64921
65149
|
const bunVersion = bun ? versionOf(bun, res.env) : null;
|
|
64922
65150
|
const bunOk = bunVersion !== null;
|
|
64923
65151
|
const needsBun = res.dev !== null;
|
|
64924
|
-
if (!
|
|
65152
|
+
if (!runningOk) {
|
|
64925
65153
|
return {
|
|
64926
65154
|
id: "runtime",
|
|
64927
65155
|
status: "fail",
|
|
64928
|
-
detail: `node ${SUPPORT_MATRIX.node.minimum}+ required (
|
|
65156
|
+
detail: `node ${SUPPORT_MATRIX.node.minimum}+ required (workit runs under ${running} at ${process.execPath})`,
|
|
64929
65157
|
fix: `Install Node ${SUPPORT_MATRIX.node.minimum}+ (declared support: ${SUPPORT_MATRIX.node.minimum}/current)`
|
|
64930
65158
|
};
|
|
64931
65159
|
}
|
|
64932
|
-
|
|
65160
|
+
const pathNote = pathNode !== null && pathNode !== running ? `; node on PATH is ${pathNode}${semverAtLeast(pathNode, SUPPORT_MATRIX.node.minimum) ? "" : ` (below ${SUPPORT_MATRIX.node.minimum}; it does not run this CLI)`}` : "";
|
|
65161
|
+
if (pathNode === null) {
|
|
64933
65162
|
return {
|
|
64934
65163
|
id: "runtime",
|
|
64935
|
-
status: "
|
|
64936
|
-
detail: `
|
|
64937
|
-
fix: `
|
|
65164
|
+
status: "warn",
|
|
65165
|
+
detail: `workit runs under node ${running}, but no node is on PATH for host hooks`,
|
|
65166
|
+
fix: `Put Node ${SUPPORT_MATRIX.node.minimum}+ on PATH (host hooks launch \`node\`)`
|
|
64938
65167
|
};
|
|
64939
65168
|
}
|
|
64940
|
-
if (!bunOk) {
|
|
65169
|
+
if (!bunOk && needsBun) {
|
|
64941
65170
|
return {
|
|
64942
65171
|
id: "runtime",
|
|
64943
|
-
status: "
|
|
64944
|
-
detail:
|
|
64945
|
-
fix:
|
|
65172
|
+
status: "fail",
|
|
65173
|
+
detail: `bun not found on PATH (dev checkout requires the pinned toolchain ${SUPPORT_MATRIX.bun})`,
|
|
65174
|
+
fix: `Install bun ${SUPPORT_MATRIX.bun} (curl -fsSL https://bun.sh/install | bash)`
|
|
64946
65175
|
};
|
|
64947
65176
|
}
|
|
65177
|
+
const pathOld = !semverAtLeast(pathNode, SUPPORT_MATRIX.node.minimum);
|
|
64948
65178
|
return {
|
|
64949
65179
|
id: "runtime",
|
|
64950
|
-
status: "pass",
|
|
64951
|
-
detail: `node ${
|
|
65180
|
+
status: bunOk && !pathOld ? "pass" : "info",
|
|
65181
|
+
detail: `node ${running} (>=${SUPPORT_MATRIX.node.minimum})${pathNote}, ${bunOk ? `bun ${bunVersion}` : "no bun (needed only for a dev checkout)"}`
|
|
64952
65182
|
};
|
|
64953
65183
|
}, checkVersions = (res) => {
|
|
64954
65184
|
if (!res.dev) {
|
|
64955
65185
|
return {
|
|
64956
65186
|
id: "versions",
|
|
64957
|
-
status: "
|
|
64958
|
-
detail: "
|
|
65187
|
+
status: "info",
|
|
65188
|
+
detail: "installed package, not a dev checkout — version parity applies to checkouts only"
|
|
64959
65189
|
};
|
|
64960
65190
|
}
|
|
64961
65191
|
const corePkg = readJson(path32.join(res.dev, "packages/workit-core/package.json"));
|
|
@@ -64969,7 +65199,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
64969
65199
|
const refs = new Set;
|
|
64970
65200
|
for (const name of ["workit-opencode", "workit-cursor", "workit-cli"]) {
|
|
64971
65201
|
const pkg = readJson(path32.join(res.dev, "packages", name, "package.json"));
|
|
64972
|
-
const dep = pkg?.dependencies?.["@brainervirus/workit-core"];
|
|
65202
|
+
const dep = pkg?.dependencies?.["@brainervirus/workit-core"] ?? pkg?.devDependencies?.["@brainervirus/workit-core"];
|
|
64973
65203
|
if (typeof dep === "string")
|
|
64974
65204
|
refs.add(dep);
|
|
64975
65205
|
}
|
|
@@ -65066,10 +65296,16 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
65066
65296
|
status: "pass",
|
|
65067
65297
|
detail: `codex CLI ${installed} matches the qualified pin`
|
|
65068
65298
|
};
|
|
65299
|
+
if (semverAtLeast(installed, qualified))
|
|
65300
|
+
return {
|
|
65301
|
+
id: "codex_pin",
|
|
65302
|
+
status: "info",
|
|
65303
|
+
detail: `codex CLI ${installed} is newer than the qualified ${qualified}`
|
|
65304
|
+
};
|
|
65069
65305
|
return {
|
|
65070
65306
|
id: "codex_pin",
|
|
65071
65307
|
status: "warn",
|
|
65072
|
-
detail: `codex CLI ${installed}
|
|
65308
|
+
detail: `codex CLI ${installed} is older than the qualified ${qualified}`,
|
|
65073
65309
|
fix: `Reinstall the qualified Codex CLI ${qualified} or record fresh qualification evidence`
|
|
65074
65310
|
};
|
|
65075
65311
|
}, readTomlTables = (file) => {
|
|
@@ -65126,7 +65362,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
65126
65362
|
const dir = path32.join(codexHome, "plugins", "cache", marketplace, "workit");
|
|
65127
65363
|
let versions = [];
|
|
65128
65364
|
try {
|
|
65129
|
-
versions =
|
|
65365
|
+
versions = readdirSync8(dir).filter((v) => existsSync14(path32.join(dir, v, ".codex-plugin")));
|
|
65130
65366
|
} catch {
|
|
65131
65367
|
versions = [];
|
|
65132
65368
|
}
|
|
@@ -65235,7 +65471,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
65235
65471
|
const installed = [];
|
|
65236
65472
|
for (const install of installs) {
|
|
65237
65473
|
const source = install.root ? path32.join(install.root, "agents") : null;
|
|
65238
|
-
const files = source && existsSync14(source) ?
|
|
65474
|
+
const files = source && existsSync14(source) ? readdirSync8(source).filter((f) => f.endsWith(".toml")).toSorted() : [];
|
|
65239
65475
|
if (files.length === 0) {
|
|
65240
65476
|
problems.push(`${install.id} ${install.version ?? "?"} bundles no agents`);
|
|
65241
65477
|
fixes.push(`codex plugin remove ${install.id} && codex plugin add ${install.id}`);
|
|
@@ -65463,8 +65699,8 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
65463
65699
|
if (!dev && res.host === "opencode") {
|
|
65464
65700
|
return {
|
|
65465
65701
|
id: "assets",
|
|
65466
|
-
status: "
|
|
65467
|
-
detail: "
|
|
65702
|
+
status: "info",
|
|
65703
|
+
detail: "installed package — OpenCode loads the published assets, no checkout to compare"
|
|
65468
65704
|
};
|
|
65469
65705
|
}
|
|
65470
65706
|
return {
|
|
@@ -65499,7 +65735,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
65499
65735
|
`)) {
|
|
65500
65736
|
return false;
|
|
65501
65737
|
}
|
|
65502
|
-
return
|
|
65738
|
+
return spawnSync15(runtime, ["--check", entry], { encoding: "utf8", env }).status === 0;
|
|
65503
65739
|
} catch {
|
|
65504
65740
|
return false;
|
|
65505
65741
|
}
|
|
@@ -65589,8 +65825,8 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
65589
65825
|
if (!dev && res.host !== "cursor") {
|
|
65590
65826
|
return {
|
|
65591
65827
|
id: "launcher",
|
|
65592
|
-
status: "
|
|
65593
|
-
detail: "
|
|
65828
|
+
status: "info",
|
|
65829
|
+
detail: "installed package — non-Cursor launchers ship inside each host plugin, no checkout to check"
|
|
65594
65830
|
};
|
|
65595
65831
|
}
|
|
65596
65832
|
return {
|
|
@@ -65630,7 +65866,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
65630
65866
|
fix: "Re-run install-cursor-plugin.sh (or `workit init` with Cursor) to rewrite the hook entries"
|
|
65631
65867
|
};
|
|
65632
65868
|
const started = performance.now();
|
|
65633
|
-
const probe =
|
|
65869
|
+
const probe = spawnSync15("node", [launcher, "--probe", "workit-cursor-hook"], {
|
|
65634
65870
|
encoding: "utf8",
|
|
65635
65871
|
env: { ...res.env, WORKIT_CURSOR_HOOK_NPX_OFFLINE: "1" },
|
|
65636
65872
|
timeout: 40000,
|
|
@@ -65699,18 +65935,18 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
65699
65935
|
fix: "Install git and ensure it is on PATH"
|
|
65700
65936
|
};
|
|
65701
65937
|
}
|
|
65702
|
-
if (process.platform !== "win32" && !commandOnPath("flock", res.env)) {
|
|
65938
|
+
if (res.dev && process.platform !== "win32" && !commandOnPath("flock", res.env)) {
|
|
65703
65939
|
return {
|
|
65704
65940
|
id: "utility",
|
|
65705
65941
|
status: "warn",
|
|
65706
|
-
detail: "flock
|
|
65707
|
-
fix: "Install util-linux (flock)"
|
|
65942
|
+
detail: "flock not found — the dev checkout's sync-runtime requires it for locking",
|
|
65943
|
+
fix: process.platform === "darwin" ? "brew install flock (Homebrew's util-linux is keg-only and leaves flock off PATH)" : "Install util-linux (flock)"
|
|
65708
65944
|
};
|
|
65709
65945
|
}
|
|
65710
65946
|
return {
|
|
65711
65947
|
id: "utility",
|
|
65712
65948
|
status: "pass",
|
|
65713
|
-
detail: "git
|
|
65949
|
+
detail: res.dev ? "git and flock on PATH" : "git on PATH"
|
|
65714
65950
|
};
|
|
65715
65951
|
}, isFragileCachePin = (entry) => {
|
|
65716
65952
|
const n = entry.replaceAll("\\", "/").toLowerCase();
|
|
@@ -65804,7 +66040,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
65804
66040
|
if (!cmd)
|
|
65805
66041
|
return null;
|
|
65806
66042
|
try {
|
|
65807
|
-
const r =
|
|
66043
|
+
const r = spawnSync15(cmd, ["view", pkgName, "version"], {
|
|
65808
66044
|
encoding: "utf8",
|
|
65809
66045
|
timeout: 20000,
|
|
65810
66046
|
env: res.env
|
|
@@ -65817,9 +66053,18 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
65817
66053
|
}, installedPluginVersion = (res) => {
|
|
65818
66054
|
const pkg = readJson(path32.join(res.cursorPluginDir, "package.json"));
|
|
65819
66055
|
return typeof pkg?.version === "string" && pkg.version ? pkg.version : null;
|
|
65820
|
-
},
|
|
65821
|
-
|
|
65822
|
-
|
|
66056
|
+
}, installedOpenCodeCache = (res) => {
|
|
66057
|
+
if (res.opencodePackageCacheDir !== null) {
|
|
66058
|
+
const pkg = readJson(path32.join(res.opencodePackageCacheDir, "node_modules", "@brainervirus", "workit-opencode", "package.json"));
|
|
66059
|
+
return typeof pkg?.version === "string" && pkg.version ? { version: pkg.version, dir: res.opencodePackageCacheDir } : null;
|
|
66060
|
+
}
|
|
66061
|
+
const found = openCodeInstalledPlugin(res.home, res.env);
|
|
66062
|
+
if (!found)
|
|
66063
|
+
return null;
|
|
66064
|
+
let dir = path32.dirname(path32.dirname(path32.dirname(found.root)));
|
|
66065
|
+
if (path32.basename(dir) !== "workit-opencode@latest")
|
|
66066
|
+
dir = path32.dirname(dir);
|
|
66067
|
+
return { version: found.version, dir };
|
|
65823
66068
|
}, checkOpenCodePackageCache = (res) => {
|
|
65824
66069
|
if (!existsSync14(res.opencodeConfig)) {
|
|
65825
66070
|
return {
|
|
@@ -65851,8 +66096,9 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
65851
66096
|
detail: `opencode pin ${pin} is an exact version — not compared to registry latest`
|
|
65852
66097
|
};
|
|
65853
66098
|
}
|
|
65854
|
-
const
|
|
65855
|
-
|
|
66099
|
+
const cache = installedOpenCodeCache(res);
|
|
66100
|
+
const installed = cache?.version ?? null;
|
|
66101
|
+
if (cache === null || installed === null) {
|
|
65856
66102
|
return {
|
|
65857
66103
|
id: "stale_install",
|
|
65858
66104
|
status: "pass",
|
|
@@ -65866,7 +66112,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
65866
66112
|
status: "warn",
|
|
65867
66113
|
registryProbed: true,
|
|
65868
66114
|
detail: "registry_unreachable: cannot compare OpenCode @latest cache against published workit-opencode",
|
|
65869
|
-
fix: `Retry when npm is reachable, or remove ${
|
|
66115
|
+
fix: `Retry when npm is reachable, or remove ${cache.dir} and restart OpenCode to re-resolve`
|
|
65870
66116
|
};
|
|
65871
66117
|
}
|
|
65872
66118
|
if (!semverAtLeast(installed, expected)) {
|
|
@@ -65875,7 +66121,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
65875
66121
|
status: "fail",
|
|
65876
66122
|
registryProbed: true,
|
|
65877
66123
|
detail: `stale_install: OpenCode @latest cache has workit-opencode ${installed} behind published ${expected}`,
|
|
65878
|
-
fix: `Remove ${
|
|
66124
|
+
fix: `Remove ${cache.dir} and restart OpenCode — it re-resolves @latest on the next launch`
|
|
65879
66125
|
};
|
|
65880
66126
|
}
|
|
65881
66127
|
return {
|
|
@@ -66344,7 +66590,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
66344
66590
|
}, defaultIdentityProbes = (env) => ({
|
|
66345
66591
|
origin: (cwd) => {
|
|
66346
66592
|
try {
|
|
66347
|
-
const out =
|
|
66593
|
+
const out = spawnSync15("git", ["remote", "get-url", "origin"], {
|
|
66348
66594
|
cwd,
|
|
66349
66595
|
encoding: "utf8",
|
|
66350
66596
|
env
|
|
@@ -66356,7 +66602,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
66356
66602
|
},
|
|
66357
66603
|
ghLogin: (e) => {
|
|
66358
66604
|
try {
|
|
66359
|
-
const out =
|
|
66605
|
+
const out = spawnSync15("gh", ["api", "user", "--jq", ".login"], { encoding: "utf8", env: e });
|
|
66360
66606
|
const login = (out.stdout ?? "").trim();
|
|
66361
66607
|
return out.status === 0 && login ? login : null;
|
|
66362
66608
|
} catch {
|
|
@@ -66365,7 +66611,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
66365
66611
|
},
|
|
66366
66612
|
glabLogin: (e) => {
|
|
66367
66613
|
try {
|
|
66368
|
-
const out =
|
|
66614
|
+
const out = spawnSync15("glab", ["api", "user", "--jq", ".username"], {
|
|
66369
66615
|
encoding: "utf8",
|
|
66370
66616
|
env: e
|
|
66371
66617
|
});
|
|
@@ -66377,7 +66623,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
66377
66623
|
},
|
|
66378
66624
|
sshLogin: (host) => {
|
|
66379
66625
|
try {
|
|
66380
|
-
const out =
|
|
66626
|
+
const out = spawnSync15("ssh", ["-o", "BatchMode=yes", "-o", "ConnectTimeout=5", "-T", `git@${host}`], {
|
|
66381
66627
|
encoding: "utf8",
|
|
66382
66628
|
env
|
|
66383
66629
|
});
|
|
@@ -66534,10 +66780,10 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
66534
66780
|
fix: repair,
|
|
66535
66781
|
registryProbed
|
|
66536
66782
|
};
|
|
66537
|
-
}, HOOK_ISSUED_MARKER = "workit-issued-sessions/
|
|
66783
|
+
}, HOOK_ISSUED_MARKER = "workit-issued-sessions/3", hookRecordsIssued = (root) => {
|
|
66538
66784
|
let files;
|
|
66539
66785
|
try {
|
|
66540
|
-
files =
|
|
66786
|
+
files = readdirSync8(path32.join(root, "dist")).filter((f) => f.endsWith(".js"));
|
|
66541
66787
|
} catch {
|
|
66542
66788
|
return null;
|
|
66543
66789
|
}
|
|
@@ -66596,12 +66842,12 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
66596
66842
|
if (cached)
|
|
66597
66843
|
return cached;
|
|
66598
66844
|
const viaShell = process.platform === "win32" && /\.(?:cmd|bat)$/i.test(bin);
|
|
66599
|
-
const r = viaShell ?
|
|
66845
|
+
const r = viaShell ? spawnSync15(`"${bin}" --version`, {
|
|
66600
66846
|
encoding: "utf8",
|
|
66601
66847
|
env,
|
|
66602
66848
|
timeout: WORKIT_PROBE_TIMEOUT_MS,
|
|
66603
66849
|
shell: true
|
|
66604
|
-
}) :
|
|
66850
|
+
}) : spawnSync15(bin, ["--version"], { encoding: "utf8", env, timeout: WORKIT_PROBE_TIMEOUT_MS });
|
|
66605
66851
|
const timedOut = r.error !== undefined && "code" in r.error && r.error.code === "ETIMEDOUT";
|
|
66606
66852
|
const version = r.status === 0 ? (r.stdout ?? "").match(SEMVER)?.[0] ?? null : null;
|
|
66607
66853
|
const probe = { version: timedOut ? null : version, timedOut };
|
|
@@ -66614,7 +66860,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
66614
66860
|
version: i.version
|
|
66615
66861
|
})),
|
|
66616
66862
|
{ label: "Cursor plugin", version: installedPluginVersion(res) },
|
|
66617
|
-
{ label: "OpenCode plugin", version:
|
|
66863
|
+
{ label: "OpenCode plugin", version: installedOpenCodeCache(res)?.version ?? null }
|
|
66618
66864
|
].filter((p) => p.version !== null);
|
|
66619
66865
|
const newest = plugins.reduce((best, p) => best && semverAtLeast(best.version, p.version) ? best : p, null);
|
|
66620
66866
|
const target = newest?.version ?? "latest";
|
|
@@ -66655,7 +66901,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
66655
66901
|
} : c) : raw;
|
|
66656
66902
|
const failed = checks.filter((c) => c.status === "fail").length;
|
|
66657
66903
|
const warned = checks.filter((c) => c.status === "warn").length;
|
|
66658
|
-
const passed = checks.filter((c) => c.status === "pass").length;
|
|
66904
|
+
const passed = checks.filter((c) => c.status === "pass" || c.status === "info").length;
|
|
66659
66905
|
const exitCode = failed > 0 ? 1 : 0;
|
|
66660
66906
|
const offline = !raw.some((c) => ("registryProbed" in c) && c.registryProbed);
|
|
66661
66907
|
const report = {
|
|
@@ -66746,13 +66992,14 @@ import {
|
|
|
66746
66992
|
mkdirSync as mkdirSync7,
|
|
66747
66993
|
mkdtempSync as mkdtempSync2,
|
|
66748
66994
|
readFileSync as readFileSync15,
|
|
66749
|
-
readdirSync as
|
|
66995
|
+
readdirSync as readdirSync9,
|
|
66750
66996
|
realpathSync as realpathSync7,
|
|
66751
66997
|
renameSync as renameSync4,
|
|
66752
66998
|
rmSync as rmSync4,
|
|
66753
66999
|
statSync as statSync6,
|
|
66754
67000
|
writeFileSync as writeFileSync8
|
|
66755
67001
|
} from "node:fs";
|
|
67002
|
+
import { createRequire as createRequire2 } from "node:module";
|
|
66756
67003
|
import os9 from "node:os";
|
|
66757
67004
|
import path33 from "node:path";
|
|
66758
67005
|
import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
|
|
@@ -66789,6 +67036,7 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
66789
67036
|
const blocked = [];
|
|
66790
67037
|
const mutations = [];
|
|
66791
67038
|
const preserved = [];
|
|
67039
|
+
let projectRefused;
|
|
66792
67040
|
const overrides = activeSetupOverrides(env);
|
|
66793
67041
|
for (const entry of [state.config, state.youtrack, state.vcs, state.workspaces]) {
|
|
66794
67042
|
if (entry.status === "malformed")
|
|
@@ -66911,8 +67159,11 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
66911
67159
|
}
|
|
66912
67160
|
}
|
|
66913
67161
|
}
|
|
66914
|
-
|
|
66915
|
-
|
|
67162
|
+
const target = values.applyProject ? projectTarget(opts.cwd ?? process.cwd()) : null;
|
|
67163
|
+
if (target && !target.ok)
|
|
67164
|
+
projectRefused = target.refused;
|
|
67165
|
+
if (target?.ok) {
|
|
67166
|
+
const root = target.root;
|
|
66916
67167
|
const gitignorePath = path33.join(root, ".gitignore");
|
|
66917
67168
|
const existing = existsSync15(gitignorePath) ? readFileSync15(gitignorePath, "utf8") : "";
|
|
66918
67169
|
const existingLines = new Set(existing.split(`
|
|
@@ -66931,7 +67182,8 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
66931
67182
|
overrides,
|
|
66932
67183
|
preserved,
|
|
66933
67184
|
platforms: values.platforms ?? [],
|
|
66934
|
-
state
|
|
67185
|
+
state,
|
|
67186
|
+
...projectRefused === undefined ? {} : { projectRefused }
|
|
66935
67187
|
};
|
|
66936
67188
|
}
|
|
66937
67189
|
function resolveApply(preview, options) {
|
|
@@ -67114,7 +67366,14 @@ function adapterRoot(platform, res, preferInstalledAdapter = false) {
|
|
|
67114
67366
|
if (res.dev) {
|
|
67115
67367
|
candidates.push(path33.join(res.dev, "packages", `workit-${platform}`));
|
|
67116
67368
|
} else {
|
|
67117
|
-
candidates.push(
|
|
67369
|
+
candidates.push(...nodeResolvedAdapters(platform));
|
|
67370
|
+
if (platform === "cursor")
|
|
67371
|
+
candidates.push(stagedCursor);
|
|
67372
|
+
if (platform === "opencode") {
|
|
67373
|
+
const cached = openCodeInstalledPlugin(res.home, res.env);
|
|
67374
|
+
if (cached)
|
|
67375
|
+
candidates.push(cached.root);
|
|
67376
|
+
}
|
|
67118
67377
|
let dir = path33.resolve(res.cwd);
|
|
67119
67378
|
while (true) {
|
|
67120
67379
|
candidates.push(path33.join(dir, "packages", `workit-${platform}`));
|
|
@@ -67124,17 +67383,14 @@ function adapterRoot(platform, res, preferInstalledAdapter = false) {
|
|
|
67124
67383
|
dir = parent;
|
|
67125
67384
|
}
|
|
67126
67385
|
}
|
|
67127
|
-
candidates.push(path33.join(res.home, ".local", "share", "workit", "packages", `workit-${platform}`));
|
|
67128
|
-
if (platform === "cursor")
|
|
67129
|
-
candidates.push(stagedCursor);
|
|
67130
67386
|
for (const candidate of candidates) {
|
|
67131
67387
|
if (isAdapter(candidate, platform))
|
|
67132
|
-
return candidate;
|
|
67388
|
+
return realRoot(candidate);
|
|
67133
67389
|
}
|
|
67134
67390
|
return null;
|
|
67135
67391
|
}
|
|
67136
67392
|
function applyOpenCode(root, res) {
|
|
67137
|
-
const resolvedPin = opencodePin(root, res);
|
|
67393
|
+
const resolvedPin = root === null ? OPENCODE_NPM_PIN : opencodePin(root, res);
|
|
67138
67394
|
if (!resolvedPin) {
|
|
67139
67395
|
return {
|
|
67140
67396
|
platform: "opencode",
|
|
@@ -67433,6 +67689,10 @@ function applySetupPreview(preview, options = {}) {
|
|
|
67433
67689
|
root = adapterRoot(platform, res, options.preferInstalledAdapter);
|
|
67434
67690
|
rootFor.set(platform, root);
|
|
67435
67691
|
}
|
|
67692
|
+
if (root === null && registersNpmPin(platform, res)) {
|
|
67693
|
+
entries.push(applyOpenCode(null, res));
|
|
67694
|
+
continue;
|
|
67695
|
+
}
|
|
67436
67696
|
if (root === null) {
|
|
67437
67697
|
entries.push({
|
|
67438
67698
|
platform,
|
|
@@ -67474,12 +67734,20 @@ function applySetupPreview(preview, options = {}) {
|
|
|
67474
67734
|
detail: "existing credential preserved"
|
|
67475
67735
|
});
|
|
67476
67736
|
}
|
|
67737
|
+
if (preview.projectRefused) {
|
|
67738
|
+
entries.push({
|
|
67739
|
+
platform: "core",
|
|
67740
|
+
file: path33.resolve(res.cwd),
|
|
67741
|
+
status: "Skipped",
|
|
67742
|
+
detail: preview.projectRefused
|
|
67743
|
+
});
|
|
67744
|
+
}
|
|
67477
67745
|
const doctor = [];
|
|
67478
67746
|
for (const platform of preview.platforms) {
|
|
67479
67747
|
if (platform !== "opencode" && platform !== "cursor")
|
|
67480
67748
|
continue;
|
|
67481
67749
|
const root = rootFor.get(platform);
|
|
67482
|
-
if (root ===
|
|
67750
|
+
if (root === undefined || root === null && !registersNpmPin(platform, res))
|
|
67483
67751
|
continue;
|
|
67484
67752
|
if (!entries.some((e) => e.platform === platform && e.status !== "Failed"))
|
|
67485
67753
|
continue;
|
|
@@ -67608,6 +67876,16 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
67608
67876
|
} catch {
|
|
67609
67877
|
return false;
|
|
67610
67878
|
}
|
|
67879
|
+
}, nodeResolvedAdapters = (platform) => {
|
|
67880
|
+
const name = `@brainervirus/workit-${platform}`;
|
|
67881
|
+
const require2 = createRequire2(path33.join(packageRoot(), "package.json"));
|
|
67882
|
+
return (require2.resolve.paths(name) ?? []).map((dir) => path33.join(dir, name));
|
|
67883
|
+
}, realRoot = (root) => {
|
|
67884
|
+
try {
|
|
67885
|
+
return realpathSync7(root);
|
|
67886
|
+
} catch {
|
|
67887
|
+
return root;
|
|
67888
|
+
}
|
|
67611
67889
|
}, isDevOpenCodeAdapterRoot = (root, dev) => {
|
|
67612
67890
|
if (dev)
|
|
67613
67891
|
return true;
|
|
@@ -67622,7 +67900,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
67622
67900
|
return `file://${entry}`;
|
|
67623
67901
|
}
|
|
67624
67902
|
return null;
|
|
67625
|
-
}, opencodePin = (root, res) => resolveOpenCodePin(root, { dev: res.dev }), CURSOR_HOOKS_FILE, localizedCursorHooks = (shipped, pluginDir) => {
|
|
67903
|
+
}, opencodePin = (root, res) => resolveOpenCodePin(root, { dev: res.dev }), registersNpmPin = (platform, res) => platform === "opencode" && !res.dev, CURSOR_HOOKS_FILE, localizedCursorHooks = (shipped, pluginDir) => {
|
|
67626
67904
|
try {
|
|
67627
67905
|
const merged = mergeCursorHooks(JSON.parse(shipped.toString("utf8")), { command: cursorHooksEntry(pluginDir).command }, pluginDir);
|
|
67628
67906
|
return Buffer.from(`${JSON.stringify(merged.config, null, 2)}
|
|
@@ -67632,7 +67910,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
67632
67910
|
}
|
|
67633
67911
|
}, samePluginContent = (src, dest, pluginDir, relative = "") => {
|
|
67634
67912
|
try {
|
|
67635
|
-
for (const entry of
|
|
67913
|
+
for (const entry of readdirSync9(src, { withFileTypes: true })) {
|
|
67636
67914
|
if (entry.name === "node_modules")
|
|
67637
67915
|
continue;
|
|
67638
67916
|
const source = path33.join(src, entry.name);
|
|
@@ -67647,7 +67925,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
67647
67925
|
return false;
|
|
67648
67926
|
}
|
|
67649
67927
|
}
|
|
67650
|
-
for (const entry of
|
|
67928
|
+
for (const entry of readdirSync9(dest, { withFileTypes: true })) {
|
|
67651
67929
|
if (existsSync15(path33.join(src, entry.name)))
|
|
67652
67930
|
continue;
|
|
67653
67931
|
const rel = path33.join(relative, entry.name);
|
|
@@ -67666,7 +67944,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
67666
67944
|
const sourceRules = path33.join(src, "rules");
|
|
67667
67945
|
const installedRules = path33.join(dest, "rules");
|
|
67668
67946
|
try {
|
|
67669
|
-
for (const entry of
|
|
67947
|
+
for (const entry of readdirSync9(installedRules, { withFileTypes: true })) {
|
|
67670
67948
|
if (!entry.isFile() || !entry.name.endsWith(".mdc"))
|
|
67671
67949
|
continue;
|
|
67672
67950
|
if (existsSync15(path33.join(sourceRules, entry.name)))
|
|
@@ -67683,7 +67961,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
67683
67961
|
if (existsSync15(legacyRules)) {
|
|
67684
67962
|
try {
|
|
67685
67963
|
mkdirSync7(path33.join(res.cursorPluginDir, "rules"), { recursive: true });
|
|
67686
|
-
for (const entry of
|
|
67964
|
+
for (const entry of readdirSync9(legacyRules, { withFileTypes: true })) {
|
|
67687
67965
|
if (!entry.isFile() || !entry.name.endsWith(".mdc"))
|
|
67688
67966
|
continue;
|
|
67689
67967
|
const target = path33.join(res.cursorPluginDir, "rules", entry.name);
|
|
@@ -67693,7 +67971,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
67693
67971
|
} catch {}
|
|
67694
67972
|
}
|
|
67695
67973
|
rmSync4(legacy, { recursive: true, force: true });
|
|
67696
|
-
}, failedDetail = (report) => report.checks.filter((c) => c.status === "fail").map((c) => `${c.id}: ${c.detail}`).join("; "), setupCompletionGuidance = () => [
|
|
67974
|
+
}, failedDetail = (report) => report.checks.filter((c) => c.status === "fail").map((c) => c.detail.startsWith(`${c.id}:`) ? c.detail : `${c.id}: ${c.detail}`).join("; "), setupCompletionGuidance = () => [
|
|
67697
67975
|
"Run `workit doctor` to verify your installation.",
|
|
67698
67976
|
"Run /wk-status in OpenCode to review token setup steps."
|
|
67699
67977
|
];
|
|
@@ -70762,7 +71040,43 @@ function Screen({
|
|
|
70762
71040
|
}, undefined, false, undefined, this)
|
|
70763
71041
|
]
|
|
70764
71042
|
}, undefined, true, undefined, this);
|
|
70765
|
-
case "project":
|
|
71043
|
+
case "project": {
|
|
71044
|
+
const target = projectTargetFor(resolveBasePath(draft.values));
|
|
71045
|
+
if (!target.ok) {
|
|
71046
|
+
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
71047
|
+
flexDirection: "column",
|
|
71048
|
+
gap: 1,
|
|
71049
|
+
children: [
|
|
71050
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
71051
|
+
bold: true,
|
|
71052
|
+
children: "Step 6 — Project setup"
|
|
71053
|
+
}, undefined, false, undefined, this),
|
|
71054
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
71055
|
+
color: "yellow",
|
|
71056
|
+
children: [
|
|
71057
|
+
"Skipped: ",
|
|
71058
|
+
target.refused
|
|
71059
|
+
]
|
|
71060
|
+
}, undefined, true, undefined, this),
|
|
71061
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(ConfirmInput, {
|
|
71062
|
+
defaultChoice: "confirm",
|
|
71063
|
+
submitOnEnter: false,
|
|
71064
|
+
onConfirm: () => {
|
|
71065
|
+
dispatch({ type: "set", field: "applyProject", value: true });
|
|
71066
|
+
dispatch({ type: "next" });
|
|
71067
|
+
},
|
|
71068
|
+
onCancel: () => {
|
|
71069
|
+
dispatch({ type: "set", field: "applyProject", value: false });
|
|
71070
|
+
dispatch({ type: "next" });
|
|
71071
|
+
}
|
|
71072
|
+
}, undefined, false, undefined, this),
|
|
71073
|
+
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
71074
|
+
dimColor: true,
|
|
71075
|
+
children: "y to keep this note in the summary · n to skip it · either adds no project files · b Back · Esc Cancel"
|
|
71076
|
+
}, undefined, false, undefined, this)
|
|
71077
|
+
]
|
|
71078
|
+
}, undefined, true, undefined, this);
|
|
71079
|
+
}
|
|
70766
71080
|
return /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Box_default, {
|
|
70767
71081
|
flexDirection: "column",
|
|
70768
71082
|
gap: 1,
|
|
@@ -70775,7 +71089,7 @@ function Screen({
|
|
|
70775
71089
|
dimColor: true,
|
|
70776
71090
|
children: [
|
|
70777
71091
|
"Apply gitignore + hygiene in ",
|
|
70778
|
-
|
|
71092
|
+
target.root,
|
|
70779
71093
|
"? (Existing files are never overwritten.)"
|
|
70780
71094
|
]
|
|
70781
71095
|
}, undefined, true, undefined, this),
|
|
@@ -70797,6 +71111,7 @@ function Screen({
|
|
|
70797
71111
|
}, undefined, false, undefined, this)
|
|
70798
71112
|
]
|
|
70799
71113
|
}, undefined, true, undefined, this);
|
|
71114
|
+
}
|
|
70800
71115
|
case "summary": {
|
|
70801
71116
|
const policy = effectivePolicy(draft.values);
|
|
70802
71117
|
const preview = buildSetupPreview(draft.values, { cwd: resolveBasePath(draft.values) });
|
|
@@ -70938,8 +71253,15 @@ function Screen({
|
|
|
70938
71253
|
}, undefined, true, undefined, this),
|
|
70939
71254
|
/* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
70940
71255
|
children: [
|
|
70941
|
-
"Project hygiene:
|
|
70942
|
-
|
|
71256
|
+
"Project hygiene:",
|
|
71257
|
+
" ",
|
|
71258
|
+
preview.projectRefused ? /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
71259
|
+
color: "yellow",
|
|
71260
|
+
children: [
|
|
71261
|
+
"skipped — ",
|
|
71262
|
+
preview.projectRefused
|
|
71263
|
+
]
|
|
71264
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime2.jsxDEV(Text, {
|
|
70943
71265
|
color: "green",
|
|
70944
71266
|
children: draft.values.applyProject ? "yes" : "no"
|
|
70945
71267
|
}, undefined, false, undefined, this)
|
|
@@ -71028,7 +71350,11 @@ function Screen({
|
|
|
71028
71350
|
}, undefined, false, undefined, this);
|
|
71029
71351
|
}
|
|
71030
71352
|
}
|
|
71031
|
-
var import_react66, jsx_dev_runtime2,
|
|
71353
|
+
var import_react66, jsx_dev_runtime2, lastProjectTarget = null, projectTargetFor = (base) => {
|
|
71354
|
+
if (lastProjectTarget?.base !== base)
|
|
71355
|
+
lastProjectTarget = { base, target: projectTarget(base) };
|
|
71356
|
+
return lastProjectTarget.target;
|
|
71357
|
+
}, PLATFORM_LABELS, BRANCH_PRESETS, BRANCH_PRESET_DESCRIPTIONS, SCREEN_PLACEHOLDERS, VCS_PROVIDERS, LOCALE_PICKER_OPTIONS, ISSUE_TRACKERS, WORKSPACE_ADVANCED_FIELDS, PROFILE_FIELDS, TRACK_FIELDS, enumFieldOptions = (field) => {
|
|
71032
71358
|
if (field === "commitPolicy.preset")
|
|
71033
71359
|
return [{ label: "Inherit global", value: "inherit" }, ...commitPresetOptions];
|
|
71034
71360
|
if (field === "branchPolicy.preset")
|
|
@@ -71070,6 +71396,7 @@ var init_steps = __esm(async () => {
|
|
|
71070
71396
|
init_logic();
|
|
71071
71397
|
init_workspaces();
|
|
71072
71398
|
init_branch_policy();
|
|
71399
|
+
init_hygiene();
|
|
71073
71400
|
init_wizard_state();
|
|
71074
71401
|
init_detect_hosts();
|
|
71075
71402
|
await __promiseAll([
|
|
@@ -71461,7 +71788,7 @@ var init_init = __esm(() => {
|
|
|
71461
71788
|
});
|
|
71462
71789
|
|
|
71463
71790
|
// packages/workit-cli/src/upgrade.ts
|
|
71464
|
-
import { spawnSync as
|
|
71791
|
+
import { spawnSync as spawnSync16 } from "node:child_process";
|
|
71465
71792
|
import {
|
|
71466
71793
|
existsSync as existsSync18,
|
|
71467
71794
|
mkdtempSync as mkdtempSync3,
|
|
@@ -71817,7 +72144,7 @@ async function runLaunchCommand(argv, deps = {}) {
|
|
|
71817
72144
|
}
|
|
71818
72145
|
if (deps.run)
|
|
71819
72146
|
return deps.run(host, hostArgs).status ?? 1;
|
|
71820
|
-
return
|
|
72147
|
+
return spawnSync16(launch.command, launch.args, {
|
|
71821
72148
|
stdio: "inherit",
|
|
71822
72149
|
env
|
|
71823
72150
|
}).status ?? 1;
|
|
@@ -71999,7 +72326,7 @@ var init_launch = __esm(() => {
|
|
|
71999
72326
|
});
|
|
72000
72327
|
|
|
72001
72328
|
// packages/workit-core/src/knowledge.ts
|
|
72002
|
-
import { spawnSync as
|
|
72329
|
+
import { spawnSync as spawnSync17 } from "node:child_process";
|
|
72003
72330
|
import fs18 from "node:fs";
|
|
72004
72331
|
import path38 from "node:path";
|
|
72005
72332
|
function lintKnowledge(root) {
|
|
@@ -72120,7 +72447,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
72120
72447
|
return "unreadable";
|
|
72121
72448
|
}
|
|
72122
72449
|
}, trackedTopLevel = (root) => {
|
|
72123
|
-
const run =
|
|
72450
|
+
const run = spawnSync17("git", ["ls-files", "-z", "--cached"], {
|
|
72124
72451
|
cwd: root,
|
|
72125
72452
|
encoding: "utf8",
|
|
72126
72453
|
maxBuffer: 256 * 1024 * 1024,
|
|
@@ -72488,7 +72815,8 @@ var R = "[REDACTED]", TOKEN_PATTERNS, WEBHOOK, URL_USERINFO, CURL_USER, KEY, ASS
|
|
|
72488
72815
|
var init_redact = __esm(() => {
|
|
72489
72816
|
TOKEN_PATTERNS = [
|
|
72490
72817
|
/\b(?:gh[pousr]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,})/gu,
|
|
72491
|
-
/\
|
|
72818
|
+
/\b(?:glpat|gloas|gldt|glrtr|glrt|glcbt|glptt|glft|glimt|glagent|glwt|glsoat|glffct)-[A-Za-z0-9_-]{20,}/gu,
|
|
72819
|
+
/\b_gitlab_session=[A-Za-z0-9%_-]{16,}/gu,
|
|
72492
72820
|
/\bnpm_[A-Za-z0-9]{30,}/gu,
|
|
72493
72821
|
/\bxox[abposr]-[A-Za-z0-9-]{10,}/gu,
|
|
72494
72822
|
/\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/gu,
|
|
@@ -72522,7 +72850,7 @@ var init_redact = __esm(() => {
|
|
|
72522
72850
|
});
|
|
72523
72851
|
|
|
72524
72852
|
// packages/workit-core/src/checks.ts
|
|
72525
|
-
import { spawn, spawnSync as
|
|
72853
|
+
import { spawn, spawnSync as spawnSync18 } from "node:child_process";
|
|
72526
72854
|
import { createHash as createHash16 } from "node:crypto";
|
|
72527
72855
|
import fs19 from "node:fs";
|
|
72528
72856
|
import os13 from "node:os";
|
|
@@ -72704,7 +73032,7 @@ function runCheckCommand(argv, options) {
|
|
|
72704
73032
|
if (!child?.pid)
|
|
72705
73033
|
return;
|
|
72706
73034
|
if (windows)
|
|
72707
|
-
|
|
73035
|
+
spawnSync18("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
|
|
72708
73036
|
stdio: "ignore",
|
|
72709
73037
|
windowsHide: true
|
|
72710
73038
|
});
|
|
@@ -74040,7 +74368,7 @@ var init_check = __esm(() => {
|
|
|
74040
74368
|
var success2 = (data) => ({ ok: true, data }), failure3 = (code, error, unblock) => ({ ok: false, code, error, ...unblock ? { unblock } : {} });
|
|
74041
74369
|
|
|
74042
74370
|
// packages/workit-core/src/git/ops.ts
|
|
74043
|
-
import { spawnSync as
|
|
74371
|
+
import { spawnSync as spawnSync19 } from "node:child_process";
|
|
74044
74372
|
import { existsSync as existsSync19, readFileSync as readFileSync19 } from "node:fs";
|
|
74045
74373
|
import path42 from "node:path";
|
|
74046
74374
|
function operationInProgress(cwd) {
|
|
@@ -74355,6 +74683,14 @@ function gitCommit(cwd, input) {
|
|
|
74355
74683
|
const session = input.actor.session;
|
|
74356
74684
|
if (session && !SESSION_SAFE.test(session))
|
|
74357
74685
|
return failure3("invalid_input", "WORKIT_SESSION_ID must be 1-128 characters of [A-Za-z0-9_.:@/+-]");
|
|
74686
|
+
if (session) {
|
|
74687
|
+
const env = input.env ?? process.env;
|
|
74688
|
+
if (issuedBinding(cwd, session) !== null)
|
|
74689
|
+
return failure3("blocked", `judge_session: ${session} was issued to a verifier or reviewer subagent; it records verdicts and never authors commits`, "commit from the implementer's or the lead's own session (unset WORKIT_SESSION_ID back to the shell's)");
|
|
74690
|
+
const refusal = sessionClaimRefusal(env, session, cwd);
|
|
74691
|
+
if (refusal)
|
|
74692
|
+
return failure3("blocked", refusal.error, "commit from the session this shell really is: never set WORKIT_SESSION_ID by hand for a commit (unset it, or use the id the host put in this shell)");
|
|
74693
|
+
}
|
|
74358
74694
|
const changeRequired = !input.amend && !input.allowEmpty;
|
|
74359
74695
|
const emptyAmend = previous !== null && git5(cwd, ["rev-parse", "--verify", "-q", `${previous}^{tree}`]).stdout.trim() === git5(cwd, ["rev-parse", "--verify", "-q", `${previous}~1^{tree}`]).stdout.trim();
|
|
74360
74696
|
const args = ["commit", "--no-edit"];
|
|
@@ -74853,7 +75189,7 @@ ${run.stdout}`;
|
|
|
74853
75189
|
} : { ok: false, lease: false, error: gitError(run) };
|
|
74854
75190
|
}
|
|
74855
75191
|
var COMMIT_TIMEOUT_MS, PUSH_TIMEOUT_MS = 120000, git5 = (cwd, args, options = {}) => {
|
|
74856
|
-
const result =
|
|
75192
|
+
const result = spawnSync19("git", args, {
|
|
74857
75193
|
cwd,
|
|
74858
75194
|
encoding: "utf8",
|
|
74859
75195
|
env: { ...options.env ?? process.env, GIT_TERMINAL_PROMPT: "0" },
|
|
@@ -74898,6 +75234,7 @@ var init_ops = __esm(() => {
|
|
|
74898
75234
|
init_vcs_config();
|
|
74899
75235
|
init_workspaces();
|
|
74900
75236
|
init_redact();
|
|
75237
|
+
init_host_session();
|
|
74901
75238
|
init_ledger();
|
|
74902
75239
|
init_rev();
|
|
74903
75240
|
COMMIT_TIMEOUT_MS = 10 * 60000;
|
|
@@ -75386,7 +75723,7 @@ var init_report = __esm(() => {
|
|
|
75386
75723
|
});
|
|
75387
75724
|
|
|
75388
75725
|
// packages/workit-core/src/forge/pr-ops.ts
|
|
75389
|
-
import { spawnSync as
|
|
75726
|
+
import { spawnSync as spawnSync20 } from "node:child_process";
|
|
75390
75727
|
function fillFromCommits(cwd, resolved, base) {
|
|
75391
75728
|
const tracking = `refs/remotes/${resolved.baseRemote}/${base}`;
|
|
75392
75729
|
if (!base.startsWith("-"))
|
|
@@ -75394,7 +75731,7 @@ function fillFromCommits(cwd, resolved, base) {
|
|
|
75394
75731
|
const from = resolveRef(cwd, tracking) ?? resolveRef(cwd, `refs/heads/${base}`);
|
|
75395
75732
|
if (!from)
|
|
75396
75733
|
return failure3("not_found", `base ${base} is not available locally`, `git fetch ${resolved.baseRemote} ${base}`);
|
|
75397
|
-
const log =
|
|
75734
|
+
const log = spawnSync20("git", ["log", "--reverse", "--no-merges", "--format=%s%x1f%b%x1e", `${from}..HEAD`], {
|
|
75398
75735
|
cwd,
|
|
75399
75736
|
encoding: "utf8",
|
|
75400
75737
|
timeout: GIT_TIMEOUTS.local,
|
|
@@ -75591,7 +75928,7 @@ function squashCommitList(cwd, resolved, base, head) {
|
|
|
75591
75928
|
const from = resolveRef(cwd, `refs/remotes/${resolved.baseRemote}/${base}`) ?? resolveRef(cwd, `refs/heads/${base}`);
|
|
75592
75929
|
if (!from)
|
|
75593
75930
|
return "";
|
|
75594
|
-
const log =
|
|
75931
|
+
const log = spawnSync20("git", ["log", "--reverse", "--no-merges", "--format=%B%x1e", `${from}..${head}`], {
|
|
75595
75932
|
cwd,
|
|
75596
75933
|
encoding: "utf8",
|
|
75597
75934
|
timeout: GIT_TIMEOUTS.local,
|
|
@@ -75664,7 +76001,7 @@ async function mergePullRequest(cwd, resolved, input, sleep) {
|
|
|
75664
76001
|
if (reason)
|
|
75665
76002
|
return refuse(`protected_branch: --delete-branch would delete ${branch}, which ${reason}; workit never deletes it`, `workit pr merge${input.pr ? ` --pr ${doc.number}` : ""} --method ${input.method} # without --delete-branch`, { reason: "protected_branch" });
|
|
75666
76003
|
}
|
|
75667
|
-
const ledger = readLedger(cwd);
|
|
76004
|
+
const ledger = readLedger(cwd, { integrity: true });
|
|
75668
76005
|
if (!ledger.ok)
|
|
75669
76006
|
return ledger;
|
|
75670
76007
|
const check = checkVerdicts(cwd, branch, ledger.value.rows);
|
|
@@ -75696,18 +76033,54 @@ async function mergePullRequest(cwd, resolved, input, sleep) {
|
|
|
75696
76033
|
unverified = { reason, recorded: String(recorded.value.id) };
|
|
75697
76034
|
} else if (check.head !== head)
|
|
75698
76035
|
return refuse(`head_mismatch: the verdict check reads ${branch} at ${check.head?.slice(0, 12) ?? "(missing)"} but ${label} is at ${head.slice(0, 12)}`, `git fetch && git switch ${branch} && git merge --ff-only @{u} # then re-verify that head`, { reason: "head_mismatch", verdict: summary });
|
|
76036
|
+
else if (!covered && check.accepted.reasons.includes("ledger_tampered"))
|
|
76037
|
+
return refuse(`ledger_tampered: a ledger row was edited, removed or moved, so no verdict for ${label} is accepted until it is repaired`, tamperedUnblock(cwd), { reason: "ledger_tampered", verdict: summary });
|
|
75699
76038
|
else if (!covered)
|
|
75700
76039
|
return refuse(`NEEDS_VERDICT: ${label} has no accepted independent verdict for ${head.slice(0, 12)} (${check.accepted.reasons.join(", ")})`, `an independent session verifies the head and runs: workit ledger verdict verified --how "<what was exercised>" --branch ${branch}${grant.allowUnverified ? `; or, only if the user asks to merge unverified: workit pr merge --unverified --reason "<why>"` : ""}`, { reason: "needs_verdict", verdict: summary });
|
|
75701
76040
|
const squashMessage = squashMessageFor(cwd, resolved, input, doc);
|
|
75702
76041
|
if (squashMessage && !squashMessage.ok)
|
|
75703
76042
|
return squashMessage;
|
|
76043
|
+
const intent = appendObserved(cwd, {
|
|
76044
|
+
type: "pr.merge.intent",
|
|
76045
|
+
actor: input.actor,
|
|
76046
|
+
branch,
|
|
76047
|
+
head,
|
|
76048
|
+
pr: doc.number,
|
|
76049
|
+
base: doc.base,
|
|
76050
|
+
method: input.method,
|
|
76051
|
+
verdictId: verdict.verdictId,
|
|
76052
|
+
...unverified ? { unverified: unverified.recorded } : {},
|
|
76053
|
+
grant: grant.source
|
|
76054
|
+
});
|
|
76055
|
+
if (!intent.ok)
|
|
76056
|
+
return refuse(`intent_unrecorded: the merge intent for ${label} could not be recorded (${intent.error}); nothing was merged`, "fix the ledger (workit ledger check), then merge again", { reason: "intent_unrecorded" });
|
|
76057
|
+
const intentId = String(intent.value.id);
|
|
75704
76058
|
const merged = resolved.forge.merge(doc.number, {
|
|
75705
76059
|
sha: head,
|
|
75706
76060
|
method: input.method,
|
|
75707
76061
|
...squashMessage ? { squashMessage: squashMessage.data } : {}
|
|
75708
76062
|
});
|
|
75709
76063
|
if (!merged.ok)
|
|
75710
|
-
return
|
|
76064
|
+
return {
|
|
76065
|
+
...merged,
|
|
76066
|
+
error: `${merged.error} (merge intent ${intentId} is recorded: if the forge merged anyway, workit pr status reads it)`
|
|
76067
|
+
};
|
|
76068
|
+
const row = appendObserved(cwd, {
|
|
76069
|
+
type: "pr.merged",
|
|
76070
|
+
actor: input.actor,
|
|
76071
|
+
branch,
|
|
76072
|
+
head,
|
|
76073
|
+
pr: doc.number,
|
|
76074
|
+
base: doc.base,
|
|
76075
|
+
mergeSha: merged.data.mergeSha,
|
|
76076
|
+
method: input.method,
|
|
76077
|
+
verdictId: verdict.verdictId,
|
|
76078
|
+
...unverified ? { unverified: unverified.recorded } : {},
|
|
76079
|
+
grant: grant.source,
|
|
76080
|
+
intent: intentId,
|
|
76081
|
+
verified: false
|
|
76082
|
+
});
|
|
76083
|
+
const recorded = row.ok ? { id: String(row.value.id) } : { error: row.error };
|
|
75711
76084
|
let state = "open";
|
|
75712
76085
|
for (const delay of [0, ...VERIFY_DELAYS_MS]) {
|
|
75713
76086
|
if (delay)
|
|
@@ -75722,9 +76095,21 @@ async function mergePullRequest(cwd, resolved, input, sleep) {
|
|
|
75722
76095
|
return {
|
|
75723
76096
|
ok: false,
|
|
75724
76097
|
code: "failed",
|
|
75725
|
-
error: `merge_unverified: the forge accepted the merge of ${label} but still reports it ${state}`,
|
|
75726
|
-
unblock: `workit verify-delivery merged --pr ${doc.number}
|
|
76098
|
+
error: `merge_unverified: the forge accepted the merge of ${label} but still reports it ${state}${"id" in recorded ? `; recorded as pr.merged ${recorded.id} (verified: false)` : `; the pr.merged row could not be written (${recorded.error})`}`,
|
|
76099
|
+
unblock: `workit verify-delivery merged --pr ${doc.number}`,
|
|
76100
|
+
recorded
|
|
75727
76101
|
};
|
|
76102
|
+
const confirmation = "id" in recorded ? appendObserved(cwd, {
|
|
76103
|
+
type: "pr.merge.verified",
|
|
76104
|
+
actor: input.actor,
|
|
76105
|
+
branch,
|
|
76106
|
+
head,
|
|
76107
|
+
pr: doc.number,
|
|
76108
|
+
base: doc.base,
|
|
76109
|
+
merged: recorded.id,
|
|
76110
|
+
mergeSha: merged.data.mergeSha
|
|
76111
|
+
}) : null;
|
|
76112
|
+
const confirmed = confirmation === null ? { error: "no pr.merged row to confirm" } : confirmation.ok ? { id: String(confirmation.value.id) } : { error: confirmation.error };
|
|
75728
76113
|
let deletedBranch = false;
|
|
75729
76114
|
if (input.deleteBranch) {
|
|
75730
76115
|
const deleted = deleteRemoteBranch(cwd, resolved.remote, branch, head);
|
|
@@ -75732,19 +76117,6 @@ async function mergePullRequest(cwd, resolved, input, sleep) {
|
|
|
75732
76117
|
deletedBranch = deleted.ok || gone && gone.ok && gone.sha === null ? true : { error: deleted.error };
|
|
75733
76118
|
}
|
|
75734
76119
|
const mergeBack = mergeBackFor(cwd, doc.base, branch);
|
|
75735
|
-
const row = appendObserved(cwd, {
|
|
75736
|
-
type: "pr.merged",
|
|
75737
|
-
actor: input.actor,
|
|
75738
|
-
branch,
|
|
75739
|
-
head,
|
|
75740
|
-
pr: doc.number,
|
|
75741
|
-
base: doc.base,
|
|
75742
|
-
mergeSha: merged.data.mergeSha,
|
|
75743
|
-
method: input.method,
|
|
75744
|
-
verdictId: verdict.verdictId,
|
|
75745
|
-
...unverified ? { unverified: unverified.recorded } : {},
|
|
75746
|
-
grant: grant.source
|
|
75747
|
-
});
|
|
75748
76120
|
return {
|
|
75749
76121
|
ok: true,
|
|
75750
76122
|
data: {
|
|
@@ -75759,7 +76131,8 @@ async function mergePullRequest(cwd, resolved, input, sleep) {
|
|
|
75759
76131
|
unverified,
|
|
75760
76132
|
grant: { source: grant.source },
|
|
75761
76133
|
deletedBranch,
|
|
75762
|
-
recorded
|
|
76134
|
+
recorded,
|
|
76135
|
+
confirmed,
|
|
75763
76136
|
mergeBack: mergeBack.branches,
|
|
75764
76137
|
mergeBackTrack: mergeBack.track
|
|
75765
76138
|
}
|
|
@@ -75817,8 +76190,8 @@ var init_pr_ops = __esm(() => {
|
|
|
75817
76190
|
});
|
|
75818
76191
|
|
|
75819
76192
|
// packages/workit-core/src/stack.ts
|
|
75820
|
-
import { spawnSync as
|
|
75821
|
-
import { createHash as createHash17, randomBytes as
|
|
76193
|
+
import { spawnSync as spawnSync21 } from "node:child_process";
|
|
76194
|
+
import { createHash as createHash17, randomBytes as randomBytes4 } from "node:crypto";
|
|
75822
76195
|
import fs22 from "node:fs";
|
|
75823
76196
|
import path44 from "node:path";
|
|
75824
76197
|
function worktreeOf(cwd, branch) {
|
|
@@ -75864,7 +76237,7 @@ function gitRestack(cwd, input) {
|
|
|
75864
76237
|
if (!scratch)
|
|
75865
76238
|
return { ok: false, conflict: false, worktree: cwd, error: "no store root" };
|
|
75866
76239
|
fs22.mkdirSync(scratch, { recursive: true });
|
|
75867
|
-
dir = path44.join(scratch, `${input.branch.replace(/[^A-Za-z0-9._-]+/gu, "_").slice(0, 40)}-${
|
|
76240
|
+
dir = path44.join(scratch, `${input.branch.replace(/[^A-Za-z0-9._-]+/gu, "_").slice(0, 40)}-${randomBytes4(4).toString("hex")}`);
|
|
75868
76241
|
const added = gitRun3(cwd, ["worktree", "add", "-q", dir, input.branch], GIT_TIMEOUTS.worktree);
|
|
75869
76242
|
if (!added.ok)
|
|
75870
76243
|
return { ok: false, conflict: false, worktree: cwd, error: firstLine(added) };
|
|
@@ -76073,13 +76446,13 @@ function takeLock(lock) {
|
|
|
76073
76446
|
pid: process.pid,
|
|
76074
76447
|
processStart: processStartOf(process.pid),
|
|
76075
76448
|
host: localLockHost(),
|
|
76076
|
-
nonce:
|
|
76449
|
+
nonce: randomBytes4(8).toString("hex")
|
|
76077
76450
|
};
|
|
76078
76451
|
fs22.writeFileSync(path44.join(lock, OWNER), JSON.stringify(owner));
|
|
76079
76452
|
return owner;
|
|
76080
76453
|
}
|
|
76081
76454
|
function reapLock(lock, observed) {
|
|
76082
|
-
const tomb = `${lock}.reap-${
|
|
76455
|
+
const tomb = `${lock}.reap-${randomBytes4(6).toString("hex")}`;
|
|
76083
76456
|
try {
|
|
76084
76457
|
fs22.renameSync(lock, tomb);
|
|
76085
76458
|
} catch {
|
|
@@ -76100,7 +76473,7 @@ function releaseLock(lock, owner) {
|
|
|
76100
76473
|
const { raw } = readOwner(lock);
|
|
76101
76474
|
if (raw !== JSON.stringify(owner))
|
|
76102
76475
|
return;
|
|
76103
|
-
const tomb = `${lock}.release-${
|
|
76476
|
+
const tomb = `${lock}.release-${randomBytes4(6).toString("hex")}`;
|
|
76104
76477
|
try {
|
|
76105
76478
|
fs22.renameSync(lock, tomb);
|
|
76106
76479
|
fs22.rmSync(tomb, { recursive: true, force: true });
|
|
@@ -76330,7 +76703,7 @@ function commitKeys(cwd, range) {
|
|
|
76330
76703
|
const patches = new Map;
|
|
76331
76704
|
const diff = gitRun3(cwd, ["log", "--no-merges", "-p", "--format=commit %H", range]);
|
|
76332
76705
|
if (diff.ok && diff.stdout.trim()) {
|
|
76333
|
-
const ids =
|
|
76706
|
+
const ids = spawnSync21("git", ["patch-id", "--stable"], {
|
|
76334
76707
|
cwd,
|
|
76335
76708
|
input: diff.stdout,
|
|
76336
76709
|
encoding: "utf8",
|
|
@@ -76423,7 +76796,7 @@ function stackStatus(ctx, stack) {
|
|
|
76423
76796
|
const mismatch = repoMismatch(ctx, stack);
|
|
76424
76797
|
if (mismatch)
|
|
76425
76798
|
return mismatch;
|
|
76426
|
-
const ledger = readLedger(ctx.cwd);
|
|
76799
|
+
const ledger = readLedger(ctx.cwd, { integrity: true });
|
|
76427
76800
|
if (!ledger.ok)
|
|
76428
76801
|
return stackFail(ledger.code, ledger.error, ledger.unblock);
|
|
76429
76802
|
const remote = remoteFor(ctx.cwd, ctx.resolved, stack.trunk);
|
|
@@ -76847,7 +77220,7 @@ async function landStack(ctx, stack, options) {
|
|
|
76847
77220
|
absorb(synced.data);
|
|
76848
77221
|
}
|
|
76849
77222
|
const ledgerRows = () => {
|
|
76850
|
-
const ledger = readLedger(ctx.cwd);
|
|
77223
|
+
const ledger = readLedger(ctx.cwd, { integrity: true });
|
|
76851
77224
|
return ledger.ok ? ledger.value.rows : [];
|
|
76852
77225
|
};
|
|
76853
77226
|
const simulated = new Set;
|
|
@@ -76954,7 +77327,7 @@ var STACK_VERSION = 1, stackFail = (code, error, unblock, data) => ({
|
|
|
76954
77327
|
...unblock ? { unblock } : {},
|
|
76955
77328
|
...data ? { data } : {}
|
|
76956
77329
|
}), fromForge = (result) => stackFail(result.code, result.error, result.unblock), stackDeps, gitRun3 = (cwd, args, timeoutMs = GIT_TIMEOUTS.local) => {
|
|
76957
|
-
const run =
|
|
77330
|
+
const run = spawnSync21("git", args, {
|
|
76958
77331
|
cwd,
|
|
76959
77332
|
encoding: "utf8",
|
|
76960
77333
|
timeout: timeoutMs,
|
|
@@ -77035,7 +77408,7 @@ var init_stack = __esm(() => {
|
|
|
77035
77408
|
});
|
|
77036
77409
|
|
|
77037
77410
|
// packages/workit-core/src/forge/pr-edit.ts
|
|
77038
|
-
import { spawnSync as
|
|
77411
|
+
import { spawnSync as spawnSync22 } from "node:child_process";
|
|
77039
77412
|
function openPr(cwd, resolved, pr) {
|
|
77040
77413
|
const grant = requireGrant(cwd, "pr");
|
|
77041
77414
|
if (!grant.allowed)
|
|
@@ -77200,7 +77573,7 @@ function replyToThread(cwd, resolved, input) {
|
|
|
77200
77573
|
});
|
|
77201
77574
|
}
|
|
77202
77575
|
var label = (resolved, number) => `${resolved.forge.kind === "github" ? "PR #" : "MR !"}${number}`, git6 = (cwd, args) => {
|
|
77203
|
-
const run =
|
|
77576
|
+
const run = spawnSync22("git", args, {
|
|
77204
77577
|
cwd,
|
|
77205
77578
|
encoding: "utf8",
|
|
77206
77579
|
timeout: GIT_TIMEOUTS.local,
|
|
@@ -77220,7 +77593,7 @@ var init_pr_edit = __esm(() => {
|
|
|
77220
77593
|
});
|
|
77221
77594
|
|
|
77222
77595
|
// packages/workit-core/src/forge/exec.ts
|
|
77223
|
-
import { spawnSync as
|
|
77596
|
+
import { spawnSync as spawnSync23 } from "node:child_process";
|
|
77224
77597
|
import fs23 from "node:fs";
|
|
77225
77598
|
import path45 from "node:path";
|
|
77226
77599
|
function findExecutable(bin, env) {
|
|
@@ -77255,7 +77628,7 @@ function systemRunner(kind, apiHost, env = process.env) {
|
|
|
77255
77628
|
if (!exe)
|
|
77256
77629
|
return { status: null, stdout: "", stderr: "", timedOut: false, missing: true };
|
|
77257
77630
|
const token = options.token ? kind === "github" ? { GH_TOKEN: options.token, GH_ENTERPRISE_TOKEN: options.token } : { GITLAB_TOKEN: options.token } : {};
|
|
77258
|
-
const result =
|
|
77631
|
+
const result = spawnSync23(exe, [...args], {
|
|
77259
77632
|
encoding: "utf8",
|
|
77260
77633
|
env: { ...childEnv, ...token },
|
|
77261
77634
|
maxBuffer: MAX_BUFFER2,
|
|
@@ -78255,6 +78628,14 @@ function resolveCredential(workspace, derived, run, scope) {
|
|
|
78255
78628
|
const explicit = typeof workspaceHost === "string" && workspaceHost.trim().toLowerCase().replace(/^https?:\/\//u, "").replace(/\/.*$/u, "") === apiHost;
|
|
78256
78629
|
if (derived.via === "host_name" && !explicit)
|
|
78257
78630
|
return failure3("blocked", `token_host_unverified: push host ${derived.host} only looks like ${kind}; workspace ${workspace?.name ?? "?"} vcs.tokenFile is not sent to it`, `if ${apiHost} is your ${kind} server, set ${kind}.host in ~/.config/workit/vcs.json (or vcs.host for the workspace); otherwise fix the push remote`);
|
|
78631
|
+
if (process.platform !== "win32") {
|
|
78632
|
+
let mode = 0;
|
|
78633
|
+
try {
|
|
78634
|
+
mode = fs24.statSync(tokenFile.trim()).mode;
|
|
78635
|
+
} catch {}
|
|
78636
|
+
if ((mode & 63) !== 0)
|
|
78637
|
+
return failure3("blocked", `workspace ${workspace?.name ?? "?"} vcs.tokenFile is readable by group or other (mode ${(mode & 511).toString(8).padStart(4, "0")})`, `chmod 600 ${tokenFile.trim()}`);
|
|
78638
|
+
}
|
|
78258
78639
|
let token = "";
|
|
78259
78640
|
try {
|
|
78260
78641
|
token = fs24.readFileSync(tokenFile.trim(), "utf8").trim();
|
|
@@ -78678,17 +79059,20 @@ async function status(argv, io) {
|
|
|
78678
79059
|
});
|
|
78679
79060
|
}
|
|
78680
79061
|
function verdictBlock(cwd, branch, doc) {
|
|
78681
|
-
const ledger = readLedger(cwd);
|
|
79062
|
+
const ledger = readLedger(cwd, { integrity: true });
|
|
78682
79063
|
if (!ledger.ok)
|
|
78683
79064
|
return null;
|
|
78684
79065
|
const check = checkVerdicts(cwd, branch, ledger.value.rows);
|
|
78685
79066
|
let landed = null;
|
|
78686
79067
|
if (doc.state === "merged") {
|
|
78687
|
-
const
|
|
79068
|
+
const mine = (type) => ledger.value.rows.findLast((candidate) => candidate.type === type && candidate.observer === "workit_cli" && candidate.integrity !== "unverified" && candidate.pr === doc.number && candidate.base === doc.base);
|
|
79069
|
+
const merged = mine("pr.merged");
|
|
79070
|
+
const row = merged ?? mine("pr.merge.intent");
|
|
78688
79071
|
landed = row ? {
|
|
78689
79072
|
head: typeof row.head === "string" ? row.head : null,
|
|
78690
79073
|
verdictId: typeof row.verdictId === "string" ? row.verdictId : null,
|
|
78691
|
-
unverified: row.unverified !== undefined && row.unverified !== null
|
|
79074
|
+
unverified: row.unverified !== undefined && row.unverified !== null,
|
|
79075
|
+
...merged ? {} : { intentOnly: true }
|
|
78692
79076
|
} : "untracked";
|
|
78693
79077
|
}
|
|
78694
79078
|
return {
|
|
@@ -78859,7 +79243,7 @@ async function merge3(argv, io) {
|
|
|
78859
79243
|
if (!result.ok)
|
|
78860
79244
|
return emit(io, fail(result.code, result.error, {
|
|
78861
79245
|
unblock: result.unblock,
|
|
78862
|
-
data: "refusal" in result && result.refusal ? result.refusal : {}
|
|
79246
|
+
data: "refusal" in result && result.refusal ? result.refusal : ("recorded" in result) && result.recorded ? { recorded: result.recorded } : {}
|
|
78863
79247
|
}));
|
|
78864
79248
|
return emit(io, ok(result.data), (data) => [
|
|
78865
79249
|
`merged ${connected.data.forge.kind === "github" ? "PR #" : "MR !"}${data.number} (${data.method}) at head ${data.head.slice(0, 12)}${data.mergeSha ? ` -> ${data.mergeSha.slice(0, 12)}` : ""}`,
|
|
@@ -78868,7 +79252,8 @@ async function merge3(argv, io) {
|
|
|
78868
79252
|
`merge back: ${data.base} is the ${data.mergeBackTrack} production branch; bring it into ${data.mergeBack.join(", ")}`
|
|
78869
79253
|
] : [],
|
|
78870
79254
|
...data.deletedBranch === true ? [`deleted ${data.branch}`] : typeof data.deletedBranch === "object" ? [`branch not deleted: ${data.deletedBranch.error}`] : [],
|
|
78871
|
-
..."error" in data.recorded ? [`ledger: not recorded (${data.recorded.error})`] : []
|
|
79255
|
+
..."error" in data.recorded ? [`ledger: not recorded (${data.recorded.error})`] : [],
|
|
79256
|
+
..."error" in data.confirmed && !("error" in data.recorded) ? [`ledger: merge not confirmed in the ledger (${data.confirmed.error})`] : []
|
|
78872
79257
|
]);
|
|
78873
79258
|
}
|
|
78874
79259
|
async function ready(argv, io) {
|
|
@@ -79018,7 +79403,7 @@ async function run11(argv, io) {
|
|
|
79018
79403
|
return reply(rest, io);
|
|
79019
79404
|
return usage3(io, sub && !sub.startsWith("-") ? `unknown pr subcommand "${sub}"` : "missing pr subcommand", USAGE4);
|
|
79020
79405
|
}
|
|
79021
|
-
var STATUS_USAGE = "workit pr status [--pr <n> | --branch <b>] [--log-lines 60] [--json]", CREATE_USAGE = "workit pr create [--base <b> | --track <t>] (--title <t> [--body <text> | --body-file <f|->] | --fill) [--label <l>]… [--reviewer <login>]… [--draft] [--json]", MERGE_USAGE = "workit pr merge [--pr <n>] [--method squash|merge|rebase] [--subject <s>] [--body <b> | --body-file <f|->] [--delete-branch] [--unverified --reason <why>] [--json]", READY_USAGE = "workit pr ready [--pr <n>] [--undo] [--json]", EDIT_USAGE = "workit pr edit [--pr <n>] [--title <t>] [--body-file <f|->] [--add-label <l>]… [--remove-label <l>]… [--add-reviewer <login>]… [--base <b>] [--json]", THREADS_USAGE = "workit pr threads [--pr <n>] [--json]", REPLY_USAGE = "workit pr reply [--pr <n>] --thread <id> [--body-file <f|->] [--resolve] [--json]", USAGE4 = "workit pr status|create|merge|ready|edit|threads|reply ... (workit help pr)", prLabel = (kind, number) => `${kind === "github" ? "PR #" : "MR !"}${number}`, mergedVerdictLine = (landed) => landed === "untracked" ? "merged outside workit (no merge record)" : landed.unverified ? `merged unverified at ${(landed.head ?? "?").slice(0, 12)} (recorded bypass)` : `merged with accepted verdict ${landed.verdictId ?? "?"} at ${(landed.head ?? "?").slice(0, 12)}`, METHODS2;
|
|
79406
|
+
var STATUS_USAGE = "workit pr status [--pr <n> | --branch <b>] [--log-lines 60] [--json]", CREATE_USAGE = "workit pr create [--base <b> | --track <t>] (--title <t> [--body <text> | --body-file <f|->] | --fill) [--label <l>]… [--reviewer <login>]… [--draft] [--json]", MERGE_USAGE = "workit pr merge [--pr <n>] [--method squash|merge|rebase] [--subject <s>] [--body <b> | --body-file <f|->] [--delete-branch] [--unverified --reason <why>] [--json]", READY_USAGE = "workit pr ready [--pr <n>] [--undo] [--json]", EDIT_USAGE = "workit pr edit [--pr <n>] [--title <t>] [--body-file <f|->] [--add-label <l>]… [--remove-label <l>]… [--add-reviewer <login>]… [--base <b>] [--json]", THREADS_USAGE = "workit pr threads [--pr <n>] [--json]", REPLY_USAGE = "workit pr reply [--pr <n>] --thread <id> [--body-file <f|->] [--resolve] [--json]", USAGE4 = "workit pr status|create|merge|ready|edit|threads|reply ... (workit help pr)", prLabel = (kind, number) => `${kind === "github" ? "PR #" : "MR !"}${number}`, mergedVerdictLine = (landed) => landed === "untracked" ? "merged outside workit (no merge record)" : landed.unverified ? `merged unverified at ${(landed.head ?? "?").slice(0, 12)} (recorded bypass)` : `merged with accepted verdict ${landed.verdictId ?? "?"} at ${(landed.head ?? "?").slice(0, 12)}${landed.intentOnly ? " (merge intent recorded; the merge call itself failed)" : ""}`, METHODS2;
|
|
79022
79407
|
var init_pr = __esm(() => {
|
|
79023
79408
|
init_pr_body();
|
|
79024
79409
|
init_pr_edit();
|
|
@@ -79543,7 +79928,7 @@ var init_git2 = __esm(() => {
|
|
|
79543
79928
|
});
|
|
79544
79929
|
|
|
79545
79930
|
// packages/workit-core/src/forge/verify.ts
|
|
79546
|
-
import { spawnSync as
|
|
79931
|
+
import { spawnSync as spawnSync24 } from "node:child_process";
|
|
79547
79932
|
function finish(cwd, report, actor) {
|
|
79548
79933
|
const delivered = report.observations.length > 0 && report.observations.every((entry) => entry.ok);
|
|
79549
79934
|
const out = { ...report, delivered };
|
|
@@ -79756,7 +80141,7 @@ var NPM_NAME, SEMVER2, SAFE_ARG, systemNpm = (args) => {
|
|
|
79756
80141
|
};
|
|
79757
80142
|
const found = process.platform === "win32" ? findExecutable("npm.cmd", process.env) : null;
|
|
79758
80143
|
const npmCmd = found && !/["%!^]/u.test(found) ? `"${found}"` : "npm.cmd";
|
|
79759
|
-
const result = process.platform === "win32" ?
|
|
80144
|
+
const result = process.platform === "win32" ? spawnSync24(`${npmCmd} ${args.join(" ")}`, { ...options, shell: true }) : spawnSync24("npm", [...args], options);
|
|
79760
80145
|
return { status: result.status, stdout: result.stdout ?? "", stderr: result.stderr ?? "" };
|
|
79761
80146
|
}, short3 = (sha) => sha ? sha.slice(0, 12) : "(absent)", npmView = (stdout) => {
|
|
79762
80147
|
try {
|
|
@@ -80765,7 +81150,7 @@ var init_stack2 = __esm(() => {
|
|
|
80765
81150
|
});
|
|
80766
81151
|
|
|
80767
81152
|
// packages/workit-core/src/fanout.ts
|
|
80768
|
-
import { spawnSync as
|
|
81153
|
+
import { spawnSync as spawnSync25 } from "node:child_process";
|
|
80769
81154
|
import { createHash as createHash18 } from "node:crypto";
|
|
80770
81155
|
import fs25 from "node:fs";
|
|
80771
81156
|
import path48 from "node:path";
|
|
@@ -81538,7 +81923,7 @@ var FANOUT_VERSION = 1, TIERS, FAN_IN_MODES, fanoutFail = (code, error, unblock,
|
|
|
81538
81923
|
text: edges.map((edge) => `add "${edge.dependsOn}" to "dependsOn" of slice ${edge.slice}`).join("; ")
|
|
81539
81924
|
};
|
|
81540
81925
|
}, gitRun4 = (cwd, args, timeoutMs = GIT_TIMEOUTS.local) => {
|
|
81541
|
-
const run =
|
|
81926
|
+
const run = spawnSync25("git", args, {
|
|
81542
81927
|
cwd,
|
|
81543
81928
|
encoding: "utf8",
|
|
81544
81929
|
timeout: timeoutMs,
|
|
@@ -81576,7 +81961,7 @@ var init_fanout = __esm(() => {
|
|
|
81576
81961
|
});
|
|
81577
81962
|
|
|
81578
81963
|
// packages/workit-core/src/fanout-worktree.ts
|
|
81579
|
-
import { randomBytes as
|
|
81964
|
+
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
81580
81965
|
import fs26 from "node:fs";
|
|
81581
81966
|
import path49 from "node:path";
|
|
81582
81967
|
function rowSample(lines) {
|
|
@@ -81660,7 +82045,7 @@ function markAdminDir(worktree) {
|
|
|
81660
82045
|
const admin = adminDir(worktree);
|
|
81661
82046
|
if (!admin)
|
|
81662
82047
|
return null;
|
|
81663
|
-
const token =
|
|
82048
|
+
const token = randomBytes5(16).toString("hex");
|
|
81664
82049
|
try {
|
|
81665
82050
|
fs26.writeFileSync(path49.join(admin.path, TOKEN_FILE), `${token}
|
|
81666
82051
|
`);
|
|
@@ -82085,7 +82470,7 @@ var init_fanout_brief = __esm(() => {
|
|
|
82085
82470
|
});
|
|
82086
82471
|
|
|
82087
82472
|
// packages/workit-core/src/fanout-landed.ts
|
|
82088
|
-
import { spawnSync as
|
|
82473
|
+
import { spawnSync as spawnSync26 } from "node:child_process";
|
|
82089
82474
|
function forgeBreaker(resolved) {
|
|
82090
82475
|
if (!resolved)
|
|
82091
82476
|
return { forge: null, down: () => null };
|
|
@@ -82176,7 +82561,7 @@ function trunkPatchIds(ctx, fork) {
|
|
|
82176
82561
|
"--"
|
|
82177
82562
|
]);
|
|
82178
82563
|
if (log.ok && log.stdout.trim()) {
|
|
82179
|
-
const run =
|
|
82564
|
+
const run = spawnSync26("git", ["patch-id", "--stable"], {
|
|
82180
82565
|
cwd: ctx.cwd,
|
|
82181
82566
|
input: log.stdout,
|
|
82182
82567
|
encoding: "utf8",
|
|
@@ -83025,7 +83410,7 @@ var exports_ledger = {};
|
|
|
83025
83410
|
__export(exports_ledger, {
|
|
83026
83411
|
run: () => run18
|
|
83027
83412
|
});
|
|
83028
|
-
import { randomBytes as
|
|
83413
|
+
import { randomBytes as randomBytes6 } from "node:crypto";
|
|
83029
83414
|
import { parseArgs } from "node:util";
|
|
83030
83415
|
function targetBranch(io, rows, branch, pr) {
|
|
83031
83416
|
if (pr !== undefined) {
|
|
@@ -83163,10 +83548,12 @@ async function run18(argv, io) {
|
|
|
83163
83548
|
if (rest.length !== 1)
|
|
83164
83549
|
return usage4(io, `ledger verdict takes one result: ${VERDICT_RESULTS.join("|")}`);
|
|
83165
83550
|
const claimed = values.self === true ? null : claimedSession(acting);
|
|
83166
|
-
const
|
|
83551
|
+
const token = values.token ?? io.env.WORKIT_SESSION_TOKEN ?? null;
|
|
83552
|
+
const refusal = claimed === null ? null : sessionClaimRefusal(io.env, claimed, io.cwd, { token, flag: acting.source === "flag" });
|
|
83167
83553
|
if (refusal)
|
|
83168
83554
|
return emit(io, fail("blocked", refusal.error, { unblock: refusal.unblock }));
|
|
83169
|
-
const
|
|
83555
|
+
const bound = claimed !== null && issuedTokenMatches(io.cwd, claimed, token);
|
|
83556
|
+
const verdict = await recorded(recordVerdict({ ...context, ...bound ? { sessionBound: true } : {} }, {
|
|
83170
83557
|
result: rest[0],
|
|
83171
83558
|
kind: values.kind,
|
|
83172
83559
|
how: values.how,
|
|
@@ -83182,7 +83569,12 @@ async function run18(argv, io) {
|
|
|
83182
83569
|
if (shadowed)
|
|
83183
83570
|
io.stderr(`warning: ${shadowed}
|
|
83184
83571
|
`);
|
|
83185
|
-
|
|
83572
|
+
const withGate = verdict.ok ? { ok: true, value: { ...verdict.value, gate: gateReading(io.cwd, verdict.value) } } : verdict;
|
|
83573
|
+
return fromResult(io, withGate, (row) => [
|
|
83574
|
+
`recorded verdict ${row.id}: ${row.result} [${row.kind}] for ${row.branch} @ ${(row.head ?? "").slice(0, 12)} as ${actor.session ?? "no session"}${row.self ? ` (self${row.selfReason === "no_session" ? ": WORKIT_SESSION_ID unset" : ""}; never accepted)` : ""}`,
|
|
83575
|
+
row.gate ? `gate: ${row.branch} ${row.gate.accepted ? `accepted (verdict ${row.gate.verdictId ?? "?"})` : `not accepted (${row.gate.reasons.join(", ")})`}` : "gate: unknown (ledger unreadable)"
|
|
83576
|
+
].join(`
|
|
83577
|
+
`));
|
|
83186
83578
|
}
|
|
83187
83579
|
function standingFanout(io, values) {
|
|
83188
83580
|
if (values.fanout !== undefined) {
|
|
@@ -83253,7 +83645,7 @@ var USAGE10 = "workit ledger decision|ruling|verdict|standing|list|check ... (wo
|
|
|
83253
83645
|
return new Error("--as takes a lowercase role, e.g. verifier");
|
|
83254
83646
|
const prefix = (actor.session ?? actor.host).slice(0, 96);
|
|
83255
83647
|
return {
|
|
83256
|
-
actor: { ...actor, session: `${prefix}:${values.as}:${
|
|
83648
|
+
actor: { ...actor, session: `${prefix}:${values.as}:${randomBytes6(4).toString("hex")}` },
|
|
83257
83649
|
source: "as",
|
|
83258
83650
|
derivedFrom: actor.session
|
|
83259
83651
|
};
|
|
@@ -83296,7 +83688,17 @@ var USAGE10 = "workit ledger decision|ruling|verdict|standing|list|check ... (wo
|
|
|
83296
83688
|
] : [
|
|
83297
83689
|
`${data.unverified_rows.length} unverified row(s) (not written by the workit CLI, or changed afterwards):`,
|
|
83298
83690
|
...data.unverified_rows.map((row) => ` #${row.seq} ${row.id} ${row.type}${row.branch ? ` [${row.branch}]` : ""}: ${row.reason}`)
|
|
83299
|
-
]
|
|
83691
|
+
], gateReading = (cwd, row) => {
|
|
83692
|
+
const ledger = readLedger(cwd, { integrity: true });
|
|
83693
|
+
if (!ledger.ok || !row.branch)
|
|
83694
|
+
return null;
|
|
83695
|
+
const { accepted } = checkVerdicts(cwd, row.branch, ledger.value.rows);
|
|
83696
|
+
return {
|
|
83697
|
+
accepted: accepted.accepted,
|
|
83698
|
+
reasons: accepted.reasons,
|
|
83699
|
+
verdictId: typeof accepted.verdict?.id === "string" ? accepted.verdict.id : null
|
|
83700
|
+
};
|
|
83701
|
+
};
|
|
83300
83702
|
var init_ledger2 = __esm(() => {
|
|
83301
83703
|
init_ledger();
|
|
83302
83704
|
init_fanout();
|
|
@@ -83320,6 +83722,7 @@ var init_ledger2 = __esm(() => {
|
|
|
83320
83722
|
last: { type: "string" },
|
|
83321
83723
|
supersedes: { type: "string" },
|
|
83322
83724
|
session: { type: "string" },
|
|
83725
|
+
token: { type: "string" },
|
|
83323
83726
|
as: { type: "string" },
|
|
83324
83727
|
fanout: { type: "string" },
|
|
83325
83728
|
json: { type: "boolean" }
|
|
@@ -99175,11 +99578,11 @@ var init_rules = __esm(() => {
|
|
|
99175
99578
|
});
|
|
99176
99579
|
|
|
99177
99580
|
// packages/workit-cli/src/test-audit/audit.ts
|
|
99178
|
-
import { spawnSync as
|
|
99179
|
-
import { existsSync as existsSync20, readdirSync as
|
|
99581
|
+
import { spawnSync as spawnSync27 } from "node:child_process";
|
|
99582
|
+
import { existsSync as existsSync20, readdirSync as readdirSync10, readFileSync as readFileSync23, statSync as statSync8 } from "node:fs";
|
|
99180
99583
|
import path52 from "node:path";
|
|
99181
99584
|
function git7(cwd, args) {
|
|
99182
|
-
const run =
|
|
99585
|
+
const run = spawnSync27("git", ["-c", "core.quotepath=off", ...args], {
|
|
99183
99586
|
cwd,
|
|
99184
99587
|
encoding: "utf8",
|
|
99185
99588
|
maxBuffer: 64 * 1024 * 1024
|
|
@@ -99187,7 +99590,7 @@ function git7(cwd, args) {
|
|
|
99187
99590
|
return { ok: run.status === 0, stdout: run.stdout ?? "" };
|
|
99188
99591
|
}
|
|
99189
99592
|
function walkTests(dir, out) {
|
|
99190
|
-
for (const entry of
|
|
99593
|
+
for (const entry of readdirSync10(dir, { withFileTypes: true })) {
|
|
99191
99594
|
if (entry.name.startsWith(".") && entry.name !== "." && entry.isDirectory())
|
|
99192
99595
|
continue;
|
|
99193
99596
|
const full = path52.join(dir, entry.name);
|
|
@@ -99323,7 +99726,7 @@ import {
|
|
|
99323
99726
|
lstatSync as lstatSync8,
|
|
99324
99727
|
mkdirSync as mkdirSync10,
|
|
99325
99728
|
mkdtempSync as mkdtempSync4,
|
|
99326
|
-
readdirSync as
|
|
99729
|
+
readdirSync as readdirSync11,
|
|
99327
99730
|
readFileSync as readFileSync24,
|
|
99328
99731
|
readlinkSync as readlinkSync3,
|
|
99329
99732
|
realpathSync as realpathSync9,
|
|
@@ -99420,7 +99823,7 @@ function removeStaleCopies(tmp = os16.tmpdir()) {
|
|
|
99420
99823
|
let removed = 0;
|
|
99421
99824
|
let names = [];
|
|
99422
99825
|
try {
|
|
99423
|
-
names =
|
|
99826
|
+
names = readdirSync11(tmp);
|
|
99424
99827
|
} catch {
|
|
99425
99828
|
return 0;
|
|
99426
99829
|
}
|
|
@@ -99449,7 +99852,7 @@ function removeStaleCopies(tmp = os16.tmpdir()) {
|
|
|
99449
99852
|
}
|
|
99450
99853
|
function linkNodeModules(origin, target, repo, copy) {
|
|
99451
99854
|
mkdirSync10(target, { recursive: true });
|
|
99452
|
-
for (const entry of
|
|
99855
|
+
for (const entry of readdirSync11(origin, { withFileTypes: true })) {
|
|
99453
99856
|
const from = path53.join(origin, entry.name);
|
|
99454
99857
|
const to = path53.join(target, entry.name);
|
|
99455
99858
|
if (entry.name.startsWith("@") && entry.isDirectory()) {
|
|
@@ -100586,7 +100989,7 @@ function withSubcommands(entry, options = {}) {
|
|
|
100586
100989
|
};
|
|
100587
100990
|
}
|
|
100588
100991
|
var VERIFY_OPTIONS = "[--expect pushed|pr|merged|released] [--pr <n> | --branch <b>] [--sha <sha>] [--tag <t>] [--package <name[@version]>]";
|
|
100589
|
-
var LEDGER_ACTOR = "[--branch <b> | --pr <n>] [--supersedes <id>] [--session <id> | --as <role>]";
|
|
100992
|
+
var LEDGER_ACTOR = "[--branch <b> | --pr <n>] [--supersedes <id>] [--session <id> [--token <t>] | --as <role>]";
|
|
100590
100993
|
var VERBS = [
|
|
100591
100994
|
{
|
|
100592
100995
|
name: "init",
|
|
@@ -100915,7 +101318,7 @@ var VERBS = [
|
|
|
100915
101318
|
},
|
|
100916
101319
|
{
|
|
100917
101320
|
name: "standing",
|
|
100918
|
-
usage: `workit ledger standing add "<order>" | standing list | standing clear [<id>] [--fanout <name>] [--supersedes <id>] [--session <id> | --as <role>]`,
|
|
101321
|
+
usage: `workit ledger standing add "<order>" | standing list | standing clear [<id>] [--fanout <name>] [--supersedes <id>] [--session <id> [--token <t>] | --as <role>]`,
|
|
100919
101322
|
summary: "The lead's standing orders for a fanout's workers"
|
|
100920
101323
|
},
|
|
100921
101324
|
{
|