@brainervirus/workit-cli 8.40.1 → 8.40.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +352 -249
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -6389,7 +6389,7 @@ var init_zod = __esm(() => {
|
|
|
6389
6389
|
// packages/workit-core/src/core/workspaces.ts
|
|
6390
6390
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
6391
6391
|
import { createHash } from "node:crypto";
|
|
6392
|
-
import { readFileSync as readFileSync2, realpathSync } from "node:fs";
|
|
6392
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, realpathSync } from "node:fs";
|
|
6393
6393
|
import path2 from "node:path";
|
|
6394
6394
|
function workspaceDefaultTarget(cwd, globalDefault) {
|
|
6395
6395
|
const ws = resolveRuntimeWorkspaceVcs(cwd);
|
|
@@ -6531,10 +6531,17 @@ var nonBlank, branchPreset, commitPreset, workspaceBranchPolicySchema, workspace
|
|
|
6531
6531
|
};
|
|
6532
6532
|
}
|
|
6533
6533
|
return { ok: true };
|
|
6534
|
-
}, WorkspaceConfigError,
|
|
6535
|
-
const cached =
|
|
6534
|
+
}, WorkspaceConfigError, probes, probeCheckout = (cwd) => {
|
|
6535
|
+
const cached = probes.get(cwd);
|
|
6536
6536
|
if (cached !== undefined)
|
|
6537
6537
|
return cached;
|
|
6538
|
+
let dir = path2.resolve(cwd);
|
|
6539
|
+
while (!existsSync2(path2.join(dir, ".git"))) {
|
|
6540
|
+
const up = path2.dirname(dir);
|
|
6541
|
+
if (up === dir)
|
|
6542
|
+
return null;
|
|
6543
|
+
dir = up;
|
|
6544
|
+
}
|
|
6538
6545
|
const env = { ...process.env };
|
|
6539
6546
|
for (const name of ["GIT_DIR", "GIT_WORK_TREE", "GIT_COMMON_DIR", "GIT_INDEX_FILE"])
|
|
6540
6547
|
delete env[name];
|
|
@@ -6548,15 +6555,43 @@ var nonBlank, branchPreset, commitPreset, workspaceBranchPolicySchema, workspace
|
|
|
6548
6555
|
});
|
|
6549
6556
|
return run.status === 0 ? run.stdout : null;
|
|
6550
6557
|
};
|
|
6558
|
+
const failed = Error(`git could not tell what checkout ${cwd} is`);
|
|
6559
|
+
const [gitDir, common, superproject] = (git([
|
|
6560
|
+
"rev-parse",
|
|
6561
|
+
"--path-format=absolute",
|
|
6562
|
+
"--git-dir",
|
|
6563
|
+
"--git-common-dir",
|
|
6564
|
+
"--show-superproject-working-tree"
|
|
6565
|
+
]) ?? "").trim().split(/\r?\n/u);
|
|
6566
|
+
if (!gitDir || !common)
|
|
6567
|
+
return failed;
|
|
6551
6568
|
let main = null;
|
|
6552
|
-
|
|
6553
|
-
|
|
6554
|
-
|
|
6555
|
-
|
|
6556
|
-
main =
|
|
6557
|
-
}
|
|
6558
|
-
|
|
6559
|
-
|
|
6569
|
+
if (path2.resolve(gitDir) !== path2.resolve(common)) {
|
|
6570
|
+
const list = git(["worktree", "list", "--porcelain"]);
|
|
6571
|
+
if (list === null)
|
|
6572
|
+
return failed;
|
|
6573
|
+
main = /^worktree (.+)$/mu.exec(list)?.[1]?.trim() || (path2.basename(common) === ".git" ? path2.dirname(common) : common);
|
|
6574
|
+
}
|
|
6575
|
+
const probe = { main, superproject: superproject || null };
|
|
6576
|
+
probes.set(cwd, probe);
|
|
6577
|
+
return probe;
|
|
6578
|
+
}, mainCheckoutOf = (cwd) => {
|
|
6579
|
+
const probe = probeCheckout(cwd);
|
|
6580
|
+
return probe instanceof Error ? null : probe?.main ?? null;
|
|
6581
|
+
}, checkoutsAbove = (cwd, seen = new Set) => {
|
|
6582
|
+
const probe = probeCheckout(cwd);
|
|
6583
|
+
if (probe instanceof Error)
|
|
6584
|
+
return probe;
|
|
6585
|
+
const out = [];
|
|
6586
|
+
for (const above of [probe?.main, probe?.superproject])
|
|
6587
|
+
if (above && !seen.has(above)) {
|
|
6588
|
+
seen.add(above);
|
|
6589
|
+
const rest = checkoutsAbove(above, seen);
|
|
6590
|
+
if (rest instanceof Error)
|
|
6591
|
+
return rest;
|
|
6592
|
+
out.push(above, ...rest);
|
|
6593
|
+
}
|
|
6594
|
+
return out;
|
|
6560
6595
|
}, matchingEntries = (cwd, entries) => {
|
|
6561
6596
|
const match = (where) => {
|
|
6562
6597
|
const targets = [where, realpathOf(where)].map((value) => value.replaceAll("\\", "/"));
|
|
@@ -6999,7 +7034,7 @@ var init_workspaces = __esm(() => {
|
|
|
6999
7034
|
WorkspaceConfigError = class WorkspaceConfigError extends Error {
|
|
7000
7035
|
name = "WorkspaceConfigError";
|
|
7001
7036
|
};
|
|
7002
|
-
|
|
7037
|
+
probes = new Map;
|
|
7003
7038
|
runtimeWorkspaceIndexSchema = object({
|
|
7004
7039
|
workspaces: array(object({ name: nonBlank, glob: nonBlank }).passthrough()).optional()
|
|
7005
7040
|
}).passthrough();
|
|
@@ -9317,7 +9352,7 @@ var package_default;
|
|
|
9317
9352
|
var init_package = __esm(() => {
|
|
9318
9353
|
package_default = {
|
|
9319
9354
|
name: "@brainervirus/workit-cli",
|
|
9320
|
-
version: "8.40.
|
|
9355
|
+
version: "8.40.4",
|
|
9321
9356
|
private: false,
|
|
9322
9357
|
description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
9323
9358
|
keywords: [
|
|
@@ -9355,13 +9390,13 @@ var init_package = __esm(() => {
|
|
|
9355
9390
|
},
|
|
9356
9391
|
dependencies: {
|
|
9357
9392
|
"@babel/parser": "7.29.9",
|
|
9358
|
-
"@brainervirus/workit-cursor": "^8.40.
|
|
9393
|
+
"@brainervirus/workit-cursor": "^8.40.4",
|
|
9359
9394
|
"@inkjs/ui": "2.0.0",
|
|
9360
9395
|
ink: "7.1.1",
|
|
9361
9396
|
react: "19.2.8"
|
|
9362
9397
|
},
|
|
9363
9398
|
devDependencies: {
|
|
9364
|
-
"@brainervirus/workit-core": "^8.40.
|
|
9399
|
+
"@brainervirus/workit-core": "^8.40.4"
|
|
9365
9400
|
},
|
|
9366
9401
|
engines: {
|
|
9367
9402
|
node: ">=24"
|
|
@@ -9700,7 +9735,7 @@ function writeFileAtomic(file, content, mode) {
|
|
|
9700
9735
|
var init_safe_write = () => {};
|
|
9701
9736
|
|
|
9702
9737
|
// packages/workit-core/src/autonomy.ts
|
|
9703
|
-
import { copyFileSync as copyFileSync2, existsSync as
|
|
9738
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync3 } from "node:fs";
|
|
9704
9739
|
import os4 from "node:os";
|
|
9705
9740
|
import path11 from "node:path";
|
|
9706
9741
|
function endpointOf(entry) {
|
|
@@ -9726,7 +9761,7 @@ function effectiveEndpoint(endpoint, context) {
|
|
|
9726
9761
|
if (context.configured.length > 0 && !context.accountConfigured)
|
|
9727
9762
|
return {
|
|
9728
9763
|
endpoint: "commit",
|
|
9729
|
-
reason: `vcs.account missing;
|
|
9764
|
+
reason: `vcs.account missing; ${accountHint(context.workspace)}`
|
|
9730
9765
|
};
|
|
9731
9766
|
if (endpoint === "merged" && context.grants.merge === false)
|
|
9732
9767
|
return { endpoint: "green", reason: missing("merge") };
|
|
@@ -9779,34 +9814,20 @@ function configuredGrants(entry) {
|
|
|
9779
9814
|
const legacy = fromAutoApprove(record.autoApprove);
|
|
9780
9815
|
return legacy ? { grants: legacy, source: "autoApprove" } : { grants: {}, source: "default" };
|
|
9781
9816
|
}
|
|
9782
|
-
function
|
|
9783
|
-
const override = grantsOverride();
|
|
9784
|
-
if (override)
|
|
9785
|
-
return {
|
|
9786
|
-
workspace: null,
|
|
9787
|
-
grants: { ...DEFAULT_GRANTS },
|
|
9788
|
-
configured: [],
|
|
9789
|
-
source: "default",
|
|
9790
|
-
accountConfigured: false,
|
|
9791
|
-
defaultEndpoint: DEFAULT_ENDPOINT,
|
|
9792
|
-
configuredEndpoint: null,
|
|
9793
|
-
effectiveEndpoint: DEFAULT_ENDPOINT,
|
|
9794
|
-
verification: DEFAULT_VERIFICATION,
|
|
9795
|
-
note: override
|
|
9796
|
-
};
|
|
9797
|
-
const workspace = resolveWorkspaceFrom(cwd, grantsDir(), process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined);
|
|
9817
|
+
function autonomyOf(workspace) {
|
|
9798
9818
|
const { grants, source } = configuredGrants(workspace);
|
|
9799
9819
|
const full = { ...DEFAULT_GRANTS, ...grants };
|
|
9800
9820
|
const configured = GRANT_KINDS.filter((kind) => grants[kind] !== undefined);
|
|
9801
9821
|
const accountConfigured = Boolean(workspace?.vcs?.account);
|
|
9822
|
+
const name = workspace?.name ?? null;
|
|
9802
9823
|
return {
|
|
9803
|
-
workspace:
|
|
9824
|
+
workspace: name,
|
|
9804
9825
|
grants: full,
|
|
9805
9826
|
configured,
|
|
9806
9827
|
source,
|
|
9807
9828
|
accountConfigured,
|
|
9808
9829
|
...endpointView(workspace, {
|
|
9809
|
-
workspace:
|
|
9830
|
+
workspace: name,
|
|
9810
9831
|
grants: full,
|
|
9811
9832
|
configured,
|
|
9812
9833
|
accountConfigured
|
|
@@ -9814,6 +9835,63 @@ function resolveAutonomy(cwd) {
|
|
|
9814
9835
|
verification: verificationOf(workspace)
|
|
9815
9836
|
};
|
|
9816
9837
|
}
|
|
9838
|
+
function capAt(named, where, by, why, main = false) {
|
|
9839
|
+
let folder = null;
|
|
9840
|
+
let none = "";
|
|
9841
|
+
try {
|
|
9842
|
+
if (where instanceof Error)
|
|
9843
|
+
throw where;
|
|
9844
|
+
folder = autonomyOf(resolveWorkspaceFrom(where, grantsDir()));
|
|
9845
|
+
} catch (error) {
|
|
9846
|
+
none = error.message;
|
|
9847
|
+
}
|
|
9848
|
+
if (!main && folder?.workspace === named.workspace)
|
|
9849
|
+
return named;
|
|
9850
|
+
const nothing = !folder || folder.configured.length > 0 && !folder.accountConfigured;
|
|
9851
|
+
const grants = { ...named.grants };
|
|
9852
|
+
const unblocks = { ...named.unblocks };
|
|
9853
|
+
const lowered = [];
|
|
9854
|
+
for (const kind of GRANT_KINDS) {
|
|
9855
|
+
const floor = !nothing && folder.grants[kind];
|
|
9856
|
+
if (!raises(kind, floor, grants[kind]))
|
|
9857
|
+
continue;
|
|
9858
|
+
grants[kind] = floor;
|
|
9859
|
+
unblocks[kind] = folder ? nothing ? accountHint(folder.workspace) : grantHint(folder.workspace, kind) : `ask the user to fix: ${none}`;
|
|
9860
|
+
lowered.push(kind);
|
|
9861
|
+
}
|
|
9862
|
+
const ceiling = !nothing && folder.effectiveEndpoint || DEFAULT_ENDPOINT;
|
|
9863
|
+
const endpoint = raisesEndpoint(ceiling, named.effectiveEndpoint);
|
|
9864
|
+
if (endpoint)
|
|
9865
|
+
lowered.push("defaultEndpoint");
|
|
9866
|
+
const strict = folder?.verification ?? "independent";
|
|
9867
|
+
const looser = VERIFICATION_MODES.indexOf(named.verification) < VERIFICATION_MODES.indexOf(strict);
|
|
9868
|
+
if (looser)
|
|
9869
|
+
lowered.push("verification");
|
|
9870
|
+
if (lowered.length === 0)
|
|
9871
|
+
return named;
|
|
9872
|
+
const note = `${by}: ${lowered.join(", ")} capped at ${folder ? `workspace ${folder.workspace}` : `nothing (${none})`}; ${why}`;
|
|
9873
|
+
return {
|
|
9874
|
+
...named,
|
|
9875
|
+
grants,
|
|
9876
|
+
unblocks,
|
|
9877
|
+
...endpoint ? { effectiveEndpoint: ceiling, endpointReason: undefined } : {},
|
|
9878
|
+
verification: looser ? strict : named.verification,
|
|
9879
|
+
note: named.note ? `${named.note}; ${note}` : note
|
|
9880
|
+
};
|
|
9881
|
+
}
|
|
9882
|
+
function resolveAutonomy(cwd) {
|
|
9883
|
+
const override = grantsOverride();
|
|
9884
|
+
if (override)
|
|
9885
|
+
return { ...autonomyOf(null), note: override };
|
|
9886
|
+
const name = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
|
|
9887
|
+
let autonomy = autonomyOf(resolveWorkspaceFrom(cwd, grantsDir(), name));
|
|
9888
|
+
if (name)
|
|
9889
|
+
autonomy = capAt(autonomy, cwd, `WORKFLOW_WORKSPACE_NAME=${name}`, "a name never raises grants");
|
|
9890
|
+
const above = checkoutsAbove(cwd);
|
|
9891
|
+
for (const where of above instanceof Error ? [above] : above)
|
|
9892
|
+
autonomy = capAt(autonomy, where, where instanceof Error ? "git" : `checkout ${where}`, "a worktree or submodule never exceeds it", true);
|
|
9893
|
+
return autonomy;
|
|
9894
|
+
}
|
|
9817
9895
|
function requireGrant(cwd, kind, options = {}) {
|
|
9818
9896
|
let autonomy;
|
|
9819
9897
|
try {
|
|
@@ -9837,7 +9915,7 @@ function requireGrant(cwd, kind, options = {}) {
|
|
|
9837
9915
|
kind,
|
|
9838
9916
|
reason: "grant_required",
|
|
9839
9917
|
error: `grant_required: ${kind} is not granted for ${workspace ? `workspace "${workspace}"` : "this checkout (no workspace matches it)"}${configured ? "" : " (the default ceiling stops at verified, ready)"}${autonomy.note ? `; ${autonomy.note}` : ""}`,
|
|
9840
|
-
unblock: workspace ? grantHint(workspace, kind) : "ask the user to add a workspace for this checkout (workit init → Workspaces), then: workit grant set <workspace> " + `${kind}=${suggested(kind)}
|
|
9918
|
+
unblock: autonomy.unblocks?.[kind] ?? (workspace ? grantHint(workspace, kind) : "ask the user to add a workspace for this checkout (workit init → Workspaces), then: workit grant set <workspace> " + `${kind}=${suggested(kind)}`),
|
|
9841
9919
|
workspace
|
|
9842
9920
|
};
|
|
9843
9921
|
if (autonomy.configured.length > 0 && !autonomy.accountConfigured && options.forge !== false && kind !== "release")
|
|
@@ -9846,7 +9924,7 @@ function requireGrant(cwd, kind, options = {}) {
|
|
|
9846
9924
|
kind,
|
|
9847
9925
|
reason: "account_required",
|
|
9848
9926
|
error: `account_required: workspace "${workspace ?? "?"}" has autonomy grants but no vcs.account, so the credential cannot be checked`,
|
|
9849
|
-
unblock:
|
|
9927
|
+
unblock: accountHint(workspace),
|
|
9850
9928
|
workspace
|
|
9851
9929
|
};
|
|
9852
9930
|
return {
|
|
@@ -9903,7 +9981,7 @@ function writeGrants(workspaceName, changes, dir = grantsDir(), endpoint, verifi
|
|
|
9903
9981
|
return { ok: false, code: "failed", error: `${current.path} changed; retry` };
|
|
9904
9982
|
let backup = null;
|
|
9905
9983
|
try {
|
|
9906
|
-
if (
|
|
9984
|
+
if (existsSync3(current.path)) {
|
|
9907
9985
|
backup = `${current.path}.bak`;
|
|
9908
9986
|
copyFileSync2(current.path, backup);
|
|
9909
9987
|
}
|
|
@@ -9984,7 +10062,7 @@ var accountHome = () => {
|
|
|
9984
10062
|
else if (item === "merge")
|
|
9985
10063
|
grants.merge = "verified";
|
|
9986
10064
|
return Object.keys(grants).length > 0 ? grants : null;
|
|
9987
|
-
}, accountOf = (entry) => entry?.vcs?.account, suggested = (kind) => kind === "merge" ? "verified" : "true", grantHint = (workspace, kind) => `ask the user to run, in their own terminal: workit grant set ${workspace ?? "<workspace>"} ${kind}=${suggested(kind)}`, raises = (kind, current, next) => {
|
|
10065
|
+
}, accountOf = (entry) => entry?.vcs?.account, suggested = (kind) => kind === "merge" ? "verified" : "true", accountHint = (workspace) => `set vcs.account for workspace "${workspace ?? "?"}" in ~/.config/workit/workspaces.json`, grantHint = (workspace, kind) => `ask the user to run, in their own terminal: workit grant set ${workspace ?? "<workspace>"} ${kind}=${suggested(kind)}`, raises = (kind, current, next) => {
|
|
9988
10066
|
const rank = (value) => value === true ? 2 : value === "verified" ? 1 : 0;
|
|
9989
10067
|
return rank(normalized(kind, next)) > rank(normalized(kind, current));
|
|
9990
10068
|
};
|
|
@@ -10642,21 +10720,21 @@ var init_file_lock = __esm(() => {
|
|
|
10642
10720
|
});
|
|
10643
10721
|
|
|
10644
10722
|
// packages/workit-core/src/core/package-root.ts
|
|
10645
|
-
import { existsSync as
|
|
10723
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
10646
10724
|
import path14 from "node:path";
|
|
10647
10725
|
import { fileURLToPath } from "node:url";
|
|
10648
10726
|
var packageRoot = () => {
|
|
10649
10727
|
let dir = path14.dirname(fileURLToPath(import.meta.url));
|
|
10650
10728
|
while (true) {
|
|
10651
10729
|
const parent = path14.dirname(dir);
|
|
10652
|
-
if (
|
|
10730
|
+
if (existsSync4(path14.join(dir, "package.json")) || parent === dir)
|
|
10653
10731
|
return dir;
|
|
10654
10732
|
dir = parent;
|
|
10655
10733
|
}
|
|
10656
10734
|
}, assetRoot = () => {
|
|
10657
10735
|
const root = packageRoot();
|
|
10658
10736
|
const assets = path14.join(root, "assets");
|
|
10659
|
-
return
|
|
10737
|
+
return existsSync4(assets) ? assets : root;
|
|
10660
10738
|
};
|
|
10661
10739
|
var init_package_root = () => {};
|
|
10662
10740
|
|
|
@@ -14263,7 +14341,7 @@ var init_substance = __esm(() => {
|
|
|
14263
14341
|
});
|
|
14264
14342
|
|
|
14265
14343
|
// packages/workit-core/src/core/policy/lane.ts
|
|
14266
|
-
import { existsSync as
|
|
14344
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "node:fs";
|
|
14267
14345
|
import path18 from "node:path";
|
|
14268
14346
|
function kindOf(file) {
|
|
14269
14347
|
if (file.binary)
|
|
@@ -14477,7 +14555,7 @@ function branchLane(cwd, options) {
|
|
|
14477
14555
|
}
|
|
14478
14556
|
function untrackedRiskPathsWarning(cwd) {
|
|
14479
14557
|
const root = worktreeTop(cwd);
|
|
14480
|
-
if (!root || !
|
|
14558
|
+
if (!root || !existsSync6(path18.join(root, RISK_PATHS_FILE)))
|
|
14481
14559
|
return null;
|
|
14482
14560
|
return isTracked(root, RISK_PATHS_FILE) ? null : `${RISK_PATHS_FILE} is not committed: it does not apply until it is committed on the base branch`;
|
|
14483
14561
|
}
|
|
@@ -16095,7 +16173,7 @@ var init_ledger = __esm(() => {
|
|
|
16095
16173
|
});
|
|
16096
16174
|
|
|
16097
16175
|
// packages/workit-core/src/core/policy/derive.ts
|
|
16098
|
-
import { existsSync as
|
|
16176
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
16099
16177
|
import path21 from "node:path";
|
|
16100
16178
|
function deriveRequirements(judgment, scope, constraints, verification = "self") {
|
|
16101
16179
|
const out = [];
|
|
@@ -16250,7 +16328,7 @@ var RULES, derived2 = (spec) => ({
|
|
|
16250
16328
|
decisionIds: []
|
|
16251
16329
|
};
|
|
16252
16330
|
}, planRecorded = (task, root) => {
|
|
16253
|
-
const cited = (latestJudgment(task)?.refs ?? []).find((ref) => ref.kind === "external" || ref.kind === "file" &&
|
|
16331
|
+
const cited = (latestJudgment(task)?.refs ?? []).find((ref) => ref.kind === "external" || ref.kind === "file" && existsSync7(path21.resolve(root, ref.path)));
|
|
16254
16332
|
if (cited)
|
|
16255
16333
|
return {
|
|
16256
16334
|
met: true,
|
|
@@ -18967,8 +19045,97 @@ var init_policy_resolver = __esm(() => {
|
|
|
18967
19045
|
init_derive();
|
|
18968
19046
|
});
|
|
18969
19047
|
|
|
18970
|
-
// packages/workit-core/src/core/task-
|
|
19048
|
+
// packages/workit-core/src/core/task-view.ts
|
|
18971
19049
|
import { realpathSync as realpathSync4 } from "node:fs";
|
|
19050
|
+
function contextRootError(store, context) {
|
|
19051
|
+
try {
|
|
19052
|
+
realpathSync4(context.root);
|
|
19053
|
+
const root = checkoutRootOf(context.root);
|
|
19054
|
+
if (root !== store.root && !sameDirectoryIdentity(root, store.root))
|
|
19055
|
+
return failure2("invalid_input", "operation context root does not match the task store root");
|
|
19056
|
+
} catch {
|
|
19057
|
+
return failure2("invalid_input", "operation context root cannot be resolved");
|
|
19058
|
+
}
|
|
19059
|
+
return success(null, null, null);
|
|
19060
|
+
}
|
|
19061
|
+
function helperEntry(task, context, requireSession = false, requireActive = false) {
|
|
19062
|
+
const workerId = context.workerId ?? null;
|
|
19063
|
+
if (workerId === null)
|
|
19064
|
+
return failure2("permission_denied", "operation is lead-only");
|
|
19065
|
+
const worker = task.workers.find((entry) => entry.id === workerId);
|
|
19066
|
+
if (!worker)
|
|
19067
|
+
return failure2("permission_denied", "worker is not assigned to this task");
|
|
19068
|
+
if (worker.data.session && !sameSession2(worker.data.session, context))
|
|
19069
|
+
return failure2("permission_denied", "worker session does not match the caller");
|
|
19070
|
+
if (requireSession && (!worker.data.session || !sameSession2(worker.data.session, context)))
|
|
19071
|
+
return failure2("permission_denied", "worker session has not been observed");
|
|
19072
|
+
if (requireActive && worker.data.state !== "running")
|
|
19073
|
+
return failure2("permission_denied", "worker is not active");
|
|
19074
|
+
return success(null, null, worker);
|
|
19075
|
+
}
|
|
19076
|
+
function helperTaskGuard(task, context, allowRead = false) {
|
|
19077
|
+
if ((context.workerId ?? null) === null)
|
|
19078
|
+
return success(null, null, null);
|
|
19079
|
+
const worker = helperEntry(task, context);
|
|
19080
|
+
if (!worker.ok)
|
|
19081
|
+
return worker;
|
|
19082
|
+
return allowRead ? success(null, null, null) : failure2("permission_denied", "helpers cannot control task lifecycle or scope");
|
|
19083
|
+
}
|
|
19084
|
+
function taskView(store, context, task, capture = true, freshness = treeFreshness(store.root)) {
|
|
19085
|
+
const workspace = store.readWorkspace();
|
|
19086
|
+
if (!workspace.ok)
|
|
19087
|
+
return workspace;
|
|
19088
|
+
if (!workspace.data)
|
|
19089
|
+
return failure2("not_found", "workspace not found");
|
|
19090
|
+
const historical = task.status === "closed" ? task.candidates.at(-1) : undefined;
|
|
19091
|
+
const current = historical ? success(null, null, historical) : capture ? captureCandidate(store.root, task.intent.data.scope, environment()) : success(null, null, task.candidates.at(-1) ?? null);
|
|
19092
|
+
if (!current.ok)
|
|
19093
|
+
return current;
|
|
19094
|
+
const evaluationWorkspace = workspace.data;
|
|
19095
|
+
const tree = freshness;
|
|
19096
|
+
const requirements = evaluateRequirements(task, evaluationWorkspace, context.capabilities, current.data, store.root, context.caller, tree);
|
|
19097
|
+
return success(task.revision, workspace.data.revision, {
|
|
19098
|
+
task,
|
|
19099
|
+
workspace: evaluationWorkspace,
|
|
19100
|
+
capabilities: context.capabilities,
|
|
19101
|
+
requirements,
|
|
19102
|
+
evidence: evaluateEvidence(task, current.data, tree)
|
|
19103
|
+
});
|
|
19104
|
+
}
|
|
19105
|
+
function compactContext(store, context, taskId, freshness, origin = null) {
|
|
19106
|
+
const root = contextRootError(store, context);
|
|
19107
|
+
if (!root.ok)
|
|
19108
|
+
return root;
|
|
19109
|
+
const base = origin && store.readStoreTask(origin.taskId);
|
|
19110
|
+
const inherited = base?.ok && base.data ? {
|
|
19111
|
+
origin: origin.origin,
|
|
19112
|
+
taskId: base.data.id,
|
|
19113
|
+
decisions: base.data.decisions.filter((entry) => entry.data.revoked === null)
|
|
19114
|
+
} : null;
|
|
19115
|
+
if (taskId === null)
|
|
19116
|
+
return success(null, null, inherited?.decisions.length ? compactTaskContext(null, inherited) : "");
|
|
19117
|
+
const task = store.readTask(taskId);
|
|
19118
|
+
if (!task.ok)
|
|
19119
|
+
return task;
|
|
19120
|
+
const helper = helperTaskGuard(task.data, context, true);
|
|
19121
|
+
if (!helper.ok)
|
|
19122
|
+
return helper;
|
|
19123
|
+
const view = taskView(store, context, task.data, false, freshness ?? signalFreshness(store.root));
|
|
19124
|
+
if (!view.ok)
|
|
19125
|
+
return view;
|
|
19126
|
+
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data, inherited));
|
|
19127
|
+
}
|
|
19128
|
+
var environment = () => [], sameSession2 = (value, context) => typeof value === "object" && value !== null && value.kind === "host" && value.host === context.caller.host && value.handle === context.caller.actor;
|
|
19129
|
+
var init_task_view = __esm(() => {
|
|
19130
|
+
init_task_contract();
|
|
19131
|
+
init_paths();
|
|
19132
|
+
init_task_store();
|
|
19133
|
+
init_task_context();
|
|
19134
|
+
init_task_evaluation();
|
|
19135
|
+
});
|
|
19136
|
+
|
|
19137
|
+
// packages/workit-core/src/core/task-engine.ts
|
|
19138
|
+
import { realpathSync as realpathSync5 } from "node:fs";
|
|
18972
19139
|
|
|
18973
19140
|
class WorkitCore {
|
|
18974
19141
|
store;
|
|
@@ -18982,15 +19149,7 @@ class WorkitCore {
|
|
|
18982
19149
|
return this.context.workerId !== null && this.context.workerId !== undefined;
|
|
18983
19150
|
}
|
|
18984
19151
|
contextRootError() {
|
|
18985
|
-
|
|
18986
|
-
realpathSync4(this.context.root);
|
|
18987
|
-
const root = checkoutRootOf(this.context.root);
|
|
18988
|
-
if (root !== this.store.root && !sameDirectoryIdentity(root, this.store.root))
|
|
18989
|
-
return failure2("invalid_input", "operation context root does not match the task store root");
|
|
18990
|
-
} catch {
|
|
18991
|
-
return failure2("invalid_input", "operation context root cannot be resolved");
|
|
18992
|
-
}
|
|
18993
|
-
return success(null, null, null);
|
|
19152
|
+
return contextRootError(this.store, this.context);
|
|
18994
19153
|
}
|
|
18995
19154
|
fillRevisions(input, task, workspace) {
|
|
18996
19155
|
if (input.expectedRevision === undefined && task)
|
|
@@ -19038,27 +19197,10 @@ class WorkitCore {
|
|
|
19038
19197
|
return success(null, null, { ...request, taskId: found.data.task.id });
|
|
19039
19198
|
}
|
|
19040
19199
|
helperEntry(task, requireSession = false, requireActive = false) {
|
|
19041
|
-
|
|
19042
|
-
if (workerId === null)
|
|
19043
|
-
return failure2("permission_denied", "operation is lead-only");
|
|
19044
|
-
const worker = task.workers.find((entry) => entry.id === workerId);
|
|
19045
|
-
if (!worker)
|
|
19046
|
-
return failure2("permission_denied", "worker is not assigned to this task");
|
|
19047
|
-
if (worker.data.session && !sameSession2(worker.data.session, this.context))
|
|
19048
|
-
return failure2("permission_denied", "worker session does not match the caller");
|
|
19049
|
-
if (requireSession && (!worker.data.session || !sameSession2(worker.data.session, this.context)))
|
|
19050
|
-
return failure2("permission_denied", "worker session has not been observed");
|
|
19051
|
-
if (requireActive && worker.data.state !== "running")
|
|
19052
|
-
return failure2("permission_denied", "worker is not active");
|
|
19053
|
-
return success(null, null, worker);
|
|
19200
|
+
return helperEntry(task, this.context, requireSession, requireActive);
|
|
19054
19201
|
}
|
|
19055
19202
|
helperTaskGuard(task, allowRead = false) {
|
|
19056
|
-
|
|
19057
|
-
return success(null, null, null);
|
|
19058
|
-
const worker = this.helperEntry(task);
|
|
19059
|
-
if (!worker.ok)
|
|
19060
|
-
return worker;
|
|
19061
|
-
return allowRead ? success(null, null, null) : failure2("permission_denied", "helpers cannot control task lifecycle or scope");
|
|
19203
|
+
return helperTaskGuard(task, this.context, allowRead);
|
|
19062
19204
|
}
|
|
19063
19205
|
activeWorkerBlocker(task) {
|
|
19064
19206
|
if (task.workers.some((entry) => workerBlocksTransition("close", entry.data.state)))
|
|
@@ -19968,48 +20110,10 @@ class WorkitCore {
|
|
|
19968
20110
|
});
|
|
19969
20111
|
}
|
|
19970
20112
|
compactContext(taskId, freshness, origin = null) {
|
|
19971
|
-
|
|
19972
|
-
if (!root.ok)
|
|
19973
|
-
return root;
|
|
19974
|
-
const base = origin && this.store.readStoreTask(origin.taskId);
|
|
19975
|
-
const inherited = base?.ok && base.data ? {
|
|
19976
|
-
origin: origin.origin,
|
|
19977
|
-
taskId: base.data.id,
|
|
19978
|
-
decisions: base.data.decisions.filter((entry) => entry.data.revoked === null)
|
|
19979
|
-
} : null;
|
|
19980
|
-
if (taskId === null)
|
|
19981
|
-
return success(null, null, inherited?.decisions.length ? compactTaskContext(null, inherited) : "");
|
|
19982
|
-
const task = this.store.readTask(taskId);
|
|
19983
|
-
if (!task.ok)
|
|
19984
|
-
return task;
|
|
19985
|
-
const helper = this.helperTaskGuard(task.data, true);
|
|
19986
|
-
if (!helper.ok)
|
|
19987
|
-
return helper;
|
|
19988
|
-
const view = this.view(task.data, false, freshness ?? signalFreshness(this.store.root));
|
|
19989
|
-
if (!view.ok)
|
|
19990
|
-
return view;
|
|
19991
|
-
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data, inherited));
|
|
20113
|
+
return compactContext(this.store, this.context, taskId, freshness, origin);
|
|
19992
20114
|
}
|
|
19993
|
-
view(task, capture = true, freshness
|
|
19994
|
-
|
|
19995
|
-
if (!workspace.ok)
|
|
19996
|
-
return workspace;
|
|
19997
|
-
if (!workspace.data)
|
|
19998
|
-
return failure2("not_found", "workspace not found");
|
|
19999
|
-
const historical = task.status === "closed" ? task.candidates.at(-1) : undefined;
|
|
20000
|
-
const current = historical ? success(null, null, historical) : capture ? captureCandidate(this.store.root, task.intent.data.scope, environment()) : success(null, null, task.candidates.at(-1) ?? null);
|
|
20001
|
-
if (!current.ok)
|
|
20002
|
-
return current;
|
|
20003
|
-
const evaluationWorkspace = workspace.data;
|
|
20004
|
-
const tree = freshness;
|
|
20005
|
-
const requirements = evaluateRequirements(task, evaluationWorkspace, this.context.capabilities, current.data, this.store.root, this.context.caller, tree);
|
|
20006
|
-
return success(task.revision, workspace.data.revision, {
|
|
20007
|
-
task,
|
|
20008
|
-
workspace: evaluationWorkspace,
|
|
20009
|
-
capabilities: this.context.capabilities,
|
|
20010
|
-
requirements,
|
|
20011
|
-
evidence: evaluateEvidence(task, current.data, tree)
|
|
20012
|
-
});
|
|
20115
|
+
view(task, capture = true, freshness) {
|
|
20116
|
+
return taskView(this.store, this.context, task, capture, freshness);
|
|
20013
20117
|
}
|
|
20014
20118
|
reconcileResume(view, observations = []) {
|
|
20015
20119
|
const root = this.contextRootError();
|
|
@@ -20020,7 +20124,7 @@ class WorkitCore {
|
|
|
20020
20124
|
if (view.task.workspaceId !== view.workspace.id)
|
|
20021
20125
|
return failure2("invalid_input", "task and workspace bindings are invalid");
|
|
20022
20126
|
try {
|
|
20023
|
-
if (
|
|
20127
|
+
if (realpathSync5(view.workspace.root) !== this.store.root)
|
|
20024
20128
|
return failure2("invalid_input", "task view root does not match the task store");
|
|
20025
20129
|
} catch {
|
|
20026
20130
|
return failure2("invalid_input", "task view root cannot be resolved");
|
|
@@ -20280,7 +20384,7 @@ var MAX_JUDGED_REFS = 5, workspaceVerification = (root) => {
|
|
|
20280
20384
|
host: context.caller.host,
|
|
20281
20385
|
session: { kind: "host", host: context.caller.host, handle: context.caller.actor },
|
|
20282
20386
|
workerId: context.workerId ?? null
|
|
20283
|
-
}),
|
|
20387
|
+
}), verifiedWorkers, sameValue = (left, right) => {
|
|
20284
20388
|
try {
|
|
20285
20389
|
return canonicalJson(left) === canonicalJson(right);
|
|
20286
20390
|
} catch {
|
|
@@ -20599,8 +20703,7 @@ var init_task_engine = __esm(() => {
|
|
|
20599
20703
|
init_ledger();
|
|
20600
20704
|
init_rev();
|
|
20601
20705
|
init_autonomy();
|
|
20602
|
-
|
|
20603
|
-
init_paths();
|
|
20706
|
+
init_task_view();
|
|
20604
20707
|
init_store_lock();
|
|
20605
20708
|
init_task_context();
|
|
20606
20709
|
init_workers();
|
|
@@ -21242,18 +21345,18 @@ var init_context_read = __esm(() => {
|
|
|
21242
21345
|
});
|
|
21243
21346
|
|
|
21244
21347
|
// packages/workit-core/src/core.ts
|
|
21245
|
-
import { existsSync as
|
|
21348
|
+
import { existsSync as existsSync9, realpathSync as realpathSync6 } from "node:fs";
|
|
21246
21349
|
import path26 from "node:path";
|
|
21247
21350
|
function resolveInside(root, candidate) {
|
|
21248
|
-
const base =
|
|
21351
|
+
const base = realpathSync6(root);
|
|
21249
21352
|
const target = path26.resolve(base, candidate);
|
|
21250
21353
|
if (target !== base && !target.startsWith(base + path26.sep)) {
|
|
21251
21354
|
throw new Error("path must stay inside repository root");
|
|
21252
21355
|
}
|
|
21253
21356
|
let ancestor = target;
|
|
21254
|
-
while (!
|
|
21357
|
+
while (!existsSync9(ancestor))
|
|
21255
21358
|
ancestor = path26.dirname(ancestor);
|
|
21256
|
-
const canonicalAncestor =
|
|
21359
|
+
const canonicalAncestor = realpathSync6(ancestor);
|
|
21257
21360
|
if (canonicalAncestor !== base && !canonicalAncestor.startsWith(base + path26.sep)) {
|
|
21258
21361
|
throw new Error("path must stay inside repository root");
|
|
21259
21362
|
}
|
|
@@ -65487,10 +65590,10 @@ var init_changelog = __esm(() => {
|
|
|
65487
65590
|
|
|
65488
65591
|
// packages/workit-core/src/core/hygiene.ts
|
|
65489
65592
|
import { spawnSync as spawnSync12 } from "node:child_process";
|
|
65490
|
-
import { existsSync as
|
|
65593
|
+
import { existsSync as existsSync11, readFileSync as readFileSync11, readdirSync as readdirSync5, writeFileSync as writeFileSync5 } from "node:fs";
|
|
65491
65594
|
import path29 from "node:path";
|
|
65492
65595
|
var repoRoot2, templatesDir = () => path29.join(repoRoot2, "templates", "hygiene"), packageJson = (root) => {
|
|
65493
|
-
if (!
|
|
65596
|
+
if (!existsSync11(path29.join(root, "package.json")))
|
|
65494
65597
|
return null;
|
|
65495
65598
|
try {
|
|
65496
65599
|
return JSON.parse(readFileSync11(path29.join(root, "package.json"), "utf8"));
|
|
@@ -65498,7 +65601,7 @@ var repoRoot2, templatesDir = () => path29.join(repoRoot2, "templates", "hygiene
|
|
|
65498
65601
|
return null;
|
|
65499
65602
|
}
|
|
65500
65603
|
}, isOpenSource = (root) => {
|
|
65501
|
-
if (
|
|
65604
|
+
if (existsSync11(path29.join(root, "LICENSE")))
|
|
65502
65605
|
return true;
|
|
65503
65606
|
const pkg = packageJson(root);
|
|
65504
65607
|
if (pkg && !pkg.private)
|
|
@@ -65525,7 +65628,7 @@ var repoRoot2, templatesDir = () => path29.join(repoRoot2, "templates", "hygiene
|
|
|
65525
65628
|
return { ok: true, root: path29.resolve(root) };
|
|
65526
65629
|
let children = [];
|
|
65527
65630
|
try {
|
|
65528
|
-
children = readdirSync5(start, { withFileTypes: true }).filter((entry) => entry.isDirectory() &&
|
|
65631
|
+
children = readdirSync5(start, { withFileTypes: true }).filter((entry) => entry.isDirectory() && existsSync11(path29.join(start, entry.name, ".git"))).map((entry) => path29.join(start, entry.name)).toSorted();
|
|
65529
65632
|
} catch {
|
|
65530
65633
|
children = [];
|
|
65531
65634
|
}
|
|
@@ -65541,10 +65644,10 @@ var repoRoot2, templatesDir = () => path29.join(repoRoot2, "templates", "hygiene
|
|
|
65541
65644
|
files.push("LICENSE", "CONTRIBUTING.md");
|
|
65542
65645
|
const planned = [];
|
|
65543
65646
|
for (const file of files) {
|
|
65544
|
-
if (
|
|
65647
|
+
if (existsSync11(path29.join(root, file)))
|
|
65545
65648
|
continue;
|
|
65546
65649
|
const tpl = path29.join(templatesDir(), file);
|
|
65547
|
-
if (!
|
|
65650
|
+
if (!existsSync11(tpl))
|
|
65548
65651
|
continue;
|
|
65549
65652
|
const content = readFileSync11(tpl, "utf8").replace(/<PROJECT>/g, path29.basename(root)).replace(/<YEAR>/g, String(new Date().getFullYear())).replace(/<HOLDER>\s*/g, licenseHolder(root));
|
|
65550
65653
|
planned.push({ path: path29.join(root, file), content });
|
|
@@ -65558,7 +65661,7 @@ var init_hygiene = __esm(() => {
|
|
|
65558
65661
|
});
|
|
65559
65662
|
|
|
65560
65663
|
// packages/workit-cli/src/admin/setup-state.ts
|
|
65561
|
-
import { existsSync as
|
|
65664
|
+
import { existsSync as existsSync12, readFileSync as readFileSync12 } from "node:fs";
|
|
65562
65665
|
import path30 from "node:path";
|
|
65563
65666
|
var classifySetupFile = (dir, name) => {
|
|
65564
65667
|
const file = path30.join(dir, name);
|
|
@@ -65566,7 +65669,7 @@ var classifySetupFile = (dir, name) => {
|
|
|
65566
65669
|
try {
|
|
65567
65670
|
raw = readFileSync12(file, "utf8");
|
|
65568
65671
|
} catch {
|
|
65569
|
-
if (
|
|
65672
|
+
if (existsSync12(file)) {
|
|
65570
65673
|
return { file, status: "malformed", error: `${file} is not readable` };
|
|
65571
65674
|
}
|
|
65572
65675
|
return { file, status: "missing" };
|
|
@@ -66004,10 +66107,10 @@ import { spawnSync as spawnSync14 } from "node:child_process";
|
|
|
66004
66107
|
import {
|
|
66005
66108
|
accessSync,
|
|
66006
66109
|
constants as constants2,
|
|
66007
|
-
existsSync as
|
|
66110
|
+
existsSync as existsSync13,
|
|
66008
66111
|
readFileSync as readFileSync13,
|
|
66009
66112
|
readdirSync as readdirSync6,
|
|
66010
|
-
realpathSync as
|
|
66113
|
+
realpathSync as realpathSync7,
|
|
66011
66114
|
statSync as statSync2
|
|
66012
66115
|
} from "node:fs";
|
|
66013
66116
|
import os9 from "node:os";
|
|
@@ -66027,7 +66130,7 @@ function hostCommand(name, args, options = {}) {
|
|
|
66027
66130
|
}
|
|
66028
66131
|
return { command: executable, args, cwd: options.cwd, purpose: `${name} CLI` };
|
|
66029
66132
|
}
|
|
66030
|
-
function resolveWindowsShimEntry(contents, shim, exists =
|
|
66133
|
+
function resolveWindowsShimEntry(contents, shim, exists = existsSync13) {
|
|
66031
66134
|
const root = path33.win32.dirname(shim);
|
|
66032
66135
|
const matches = contents.matchAll(/(["']?)([^\r\n"']*node_modules[\\/][^\r\n"']+?\.js)\1/gi);
|
|
66033
66136
|
for (const match of matches) {
|
|
@@ -66070,7 +66173,7 @@ function findHostExecutable(name, options = {}) {
|
|
|
66070
66173
|
}
|
|
66071
66174
|
return null;
|
|
66072
66175
|
}
|
|
66073
|
-
function installedHostApp(host, home, env = process.env, platform = process.platform, exists =
|
|
66176
|
+
function installedHostApp(host, home, env = process.env, platform = process.platform, exists = existsSync13) {
|
|
66074
66177
|
const candidates = [];
|
|
66075
66178
|
const pathApi = platform === "win32" ? path33.win32 : path33;
|
|
66076
66179
|
if (platform === "darwin") {
|
|
@@ -66227,7 +66330,7 @@ ${result.stdout}
|
|
|
66227
66330
|
${result.stderr}`;
|
|
66228
66331
|
if (command.packageRoot && command.packageTarget) {
|
|
66229
66332
|
try {
|
|
66230
|
-
if (!
|
|
66333
|
+
if (!existsSync13(command.packageRoot)) {
|
|
66231
66334
|
return {
|
|
66232
66335
|
ok: false,
|
|
66233
66336
|
results: [
|
|
@@ -66447,7 +66550,7 @@ var resolveWindowsShimScript = (shim) => {
|
|
|
66447
66550
|
return found;
|
|
66448
66551
|
}, isClaudeWorkitInstalled = (home, env = process.env, cwd = process.cwd()) => claudeWorkitInstalls(home, env, cwd).length > 0, findNpmCli = (npm) => {
|
|
66449
66552
|
try {
|
|
66450
|
-
const resolved =
|
|
66553
|
+
const resolved = realpathSync7(npm);
|
|
66451
66554
|
if (path33.basename(resolved) === "npm-cli.js")
|
|
66452
66555
|
return resolved;
|
|
66453
66556
|
} catch {}
|
|
@@ -66457,7 +66560,7 @@ var resolveWindowsShimScript = (shim) => {
|
|
|
66457
66560
|
path33.join(dir, "..", "node_modules", "npm", "bin", "npm-cli.js"),
|
|
66458
66561
|
path33.join(dir, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
|
|
66459
66562
|
];
|
|
66460
|
-
return candidates.find((candidate) =>
|
|
66563
|
+
return candidates.find((candidate) => existsSync13(candidate)) ?? null;
|
|
66461
66564
|
};
|
|
66462
66565
|
var init_host_install = __esm(() => {
|
|
66463
66566
|
CLAUDE_PLUGIN_ID = `workit@${CLAUDE_MARKETPLACE_NAME}`;
|
|
@@ -66465,9 +66568,9 @@ var init_host_install = __esm(() => {
|
|
|
66465
66568
|
});
|
|
66466
66569
|
|
|
66467
66570
|
// packages/workit-core/src/core/skill-manifests.ts
|
|
66468
|
-
import { cpSync as cpSync3, existsSync as
|
|
66571
|
+
import { cpSync as cpSync3, existsSync as existsSync14, readFileSync as readFileSync14, readdirSync as readdirSync7, statSync as statSync3, writeFileSync as writeFileSync6 } from "node:fs";
|
|
66469
66572
|
import path34 from "node:path";
|
|
66470
|
-
var WORKIT_METHOD_SKILLS, skillManifestNames = (root) =>
|
|
66573
|
+
var WORKIT_METHOD_SKILLS, skillManifestNames = (root) => existsSync14(root) ? readdirSync7(root).filter((name) => existsSync14(path34.join(root, name, "SKILL.md"))).toSorted() : [], validateSkillManifests = (root, expected, label) => {
|
|
66471
66574
|
const actual = skillManifestNames(root);
|
|
66472
66575
|
const missing = expected.filter((name) => !actual.includes(name));
|
|
66473
66576
|
const extra = actual.filter((name) => !expected.includes(name));
|
|
@@ -66513,7 +66616,7 @@ var init_skill_manifests = __esm(() => {
|
|
|
66513
66616
|
import { spawnSync as spawnSync15 } from "node:child_process";
|
|
66514
66617
|
import {
|
|
66515
66618
|
chmodSync,
|
|
66516
|
-
existsSync as
|
|
66619
|
+
existsSync as existsSync15,
|
|
66517
66620
|
lstatSync as lstatSync4,
|
|
66518
66621
|
mkdirSync as mkdirSync5,
|
|
66519
66622
|
readFileSync as readFileSync15,
|
|
@@ -66525,7 +66628,7 @@ import {
|
|
|
66525
66628
|
import path35 from "node:path";
|
|
66526
66629
|
function inspectSessionHook(cwd, env = process.env) {
|
|
66527
66630
|
const none = { hooksDir: null, hookPath: null, helperPath: null, helperCurrent: false };
|
|
66528
|
-
if (!
|
|
66631
|
+
if (!existsSync15(cwd))
|
|
66529
66632
|
return { state: "not_git", ...none };
|
|
66530
66633
|
const top = run2(cwd, ["rev-parse", "--show-toplevel"], env);
|
|
66531
66634
|
if (!top.ok || !top.out)
|
|
@@ -66730,7 +66833,7 @@ exit 0
|
|
|
66730
66833
|
} catch {
|
|
66731
66834
|
return false;
|
|
66732
66835
|
}
|
|
66733
|
-
}, LEFTHOOK_CONFIGS, lefthookConfig = (top) => LEFTHOOK_CONFIGS.map((name) => path35.join(top, name)).find((file) =>
|
|
66836
|
+
}, LEFTHOOK_CONFIGS, lefthookConfig = (top) => LEFTHOOK_CONFIGS.map((name) => path35.join(top, name)).find((file) => existsSync15(file)) ?? null, isComment = (line) => /^\s*#/.test(line), COMMAND_SH, DIRECT_CALL, VAR_CALL, runsHelperText = (text) => {
|
|
66734
66837
|
const lines = text.split(/\r?\n/).filter((line) => !isComment(line));
|
|
66735
66838
|
const assigned = lines.some((line) => /(?:^|[\s;])h=/.test(line) && line.includes(HELPER_REF));
|
|
66736
66839
|
return lines.some((line) => DIRECT_CALL.test(line) || assigned && VAR_CALL.test(line));
|
|
@@ -66782,7 +66885,7 @@ exit 0
|
|
|
66782
66885
|
if (text === null || !runsHelperText(text))
|
|
66783
66886
|
return false;
|
|
66784
66887
|
return input.owner === "husky" && target !== input.hookPath || isExecutable(target);
|
|
66785
|
-
}, isHuskyV9 = (text, hooksDir) => /\$\(dirname (?:-- )?"\$0"\)\/h"/.test(text) &&
|
|
66888
|
+
}, isHuskyV9 = (text, hooksDir) => /\$\(dirname (?:-- )?"\$0"\)\/h"/.test(text) && existsSync15(path35.join(hooksDir, "h")), ownerOf = (text, hooksDir, top) => {
|
|
66786
66889
|
if (text.includes("husky.sh") || isHuskyV9(text, hooksDir))
|
|
66787
66890
|
return "husky";
|
|
66788
66891
|
if (/lefthook/i.test(text) || lefthookConfig(top))
|
|
@@ -66941,11 +67044,11 @@ var init_delivery_verbs = __esm(() => {
|
|
|
66941
67044
|
// packages/workit-cli/src/admin/host-permissions.ts
|
|
66942
67045
|
import {
|
|
66943
67046
|
copyFileSync as copyFileSync4,
|
|
66944
|
-
existsSync as
|
|
67047
|
+
existsSync as existsSync16,
|
|
66945
67048
|
readdirSync as readdirSync9,
|
|
66946
67049
|
mkdirSync as mkdirSync7,
|
|
66947
67050
|
readFileSync as readFileSync17,
|
|
66948
|
-
realpathSync as
|
|
67051
|
+
realpathSync as realpathSync8,
|
|
66949
67052
|
rmSync as rmSync3,
|
|
66950
67053
|
statSync as statSync5
|
|
66951
67054
|
} from "node:fs";
|
|
@@ -67045,7 +67148,7 @@ function planHostPermissions(options) {
|
|
|
67045
67148
|
if (!PERMISSION_HOSTS.has(host))
|
|
67046
67149
|
continue;
|
|
67047
67150
|
const target = permissionTarget(host, paths);
|
|
67048
|
-
if (!
|
|
67151
|
+
if (!existsSync16(target.hostDir)) {
|
|
67049
67152
|
plan.notes.push(`${host}: not installed (${target.hostDir} is missing); nothing written`);
|
|
67050
67153
|
continue;
|
|
67051
67154
|
}
|
|
@@ -67168,7 +67271,7 @@ function applyHostPermissions(plan, options = {}) {
|
|
|
67168
67271
|
continue;
|
|
67169
67272
|
}
|
|
67170
67273
|
try {
|
|
67171
|
-
const target = change.before === null ? change.file :
|
|
67274
|
+
const target = change.before === null ? change.file : realpathSync8(change.file);
|
|
67172
67275
|
if (change.before !== null) {
|
|
67173
67276
|
const backups = path38.join(paths.stateDir, "host-permissions-backup");
|
|
67174
67277
|
mkdirSync7(backups, { recursive: true, mode: 448 });
|
|
@@ -67198,7 +67301,7 @@ function applyHostPermissions(plan, options = {}) {
|
|
|
67198
67301
|
}
|
|
67199
67302
|
function permissionHealth(host, options = {}) {
|
|
67200
67303
|
const target = permissionTarget(host, options);
|
|
67201
|
-
if (!
|
|
67304
|
+
if (!existsSync16(target.hostDir))
|
|
67202
67305
|
return { state: "no-host" };
|
|
67203
67306
|
const text = readText4(target.file);
|
|
67204
67307
|
if (host === "codex") {
|
|
@@ -67232,7 +67335,7 @@ function permissionHealth(host, options = {}) {
|
|
|
67232
67335
|
}
|
|
67233
67336
|
function permissionCoverage(host, commands, options = {}) {
|
|
67234
67337
|
const target = permissionTarget(host, options);
|
|
67235
|
-
if (!
|
|
67338
|
+
if (!existsSync16(target.hostDir))
|
|
67236
67339
|
return { state: "no-host" };
|
|
67237
67340
|
const cwd = options.cwd ?? process.cwd();
|
|
67238
67341
|
let missing;
|
|
@@ -67417,7 +67520,7 @@ ${[...rules, ...lease, grant].join(`
|
|
|
67417
67520
|
return null;
|
|
67418
67521
|
}, setupCommand = (hosts) => `workit setup --hosts=${hosts.join(",")}`, removeCodexRules = (file, options = {}) => {
|
|
67419
67522
|
const expected = permissionTarget("codex", options).file;
|
|
67420
|
-
if (path38.resolve(file) !== path38.resolve(expected) || !
|
|
67523
|
+
if (path38.resolve(file) !== path38.resolve(expected) || !existsSync16(expected))
|
|
67421
67524
|
return false;
|
|
67422
67525
|
rmSync3(expected);
|
|
67423
67526
|
return true;
|
|
@@ -67558,7 +67661,7 @@ var init_host_permissions = __esm(() => {
|
|
|
67558
67661
|
import { spawnSync as spawnSync16 } from "node:child_process";
|
|
67559
67662
|
import { createHash as createHash14 } from "node:crypto";
|
|
67560
67663
|
import {
|
|
67561
|
-
existsSync as
|
|
67664
|
+
existsSync as existsSync17,
|
|
67562
67665
|
lstatSync as lstatSync5,
|
|
67563
67666
|
mkdirSync as mkdirSync8,
|
|
67564
67667
|
mkdtempSync,
|
|
@@ -67576,7 +67679,7 @@ import path39 from "node:path";
|
|
|
67576
67679
|
var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
67577
67680
|
let dir = path39.resolve(cwd);
|
|
67578
67681
|
while (true) {
|
|
67579
|
-
if (
|
|
67682
|
+
if (existsSync17(path39.join(dir, "packages", "workit-core", "package.json")))
|
|
67580
67683
|
return dir;
|
|
67581
67684
|
const parent = path39.dirname(dir);
|
|
67582
67685
|
if (parent === dir)
|
|
@@ -67681,14 +67784,14 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
67681
67784
|
}
|
|
67682
67785
|
return true;
|
|
67683
67786
|
}, resolveBun = (env) => {
|
|
67684
|
-
if (env.BUN &&
|
|
67787
|
+
if (env.BUN && existsSync17(env.BUN))
|
|
67685
67788
|
return env.BUN;
|
|
67686
67789
|
for (const candidate of [
|
|
67687
67790
|
path39.join(env.HOME || os12.homedir(), ".bun/bin/bun"),
|
|
67688
67791
|
"/usr/local/bin/bun",
|
|
67689
67792
|
"/usr/bin/bun"
|
|
67690
67793
|
]) {
|
|
67691
|
-
if (
|
|
67794
|
+
if (existsSync17(candidate))
|
|
67692
67795
|
return candidate;
|
|
67693
67796
|
}
|
|
67694
67797
|
return commandOnPath("bun", env) ? "bun" : null;
|
|
@@ -67913,7 +68016,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
67913
68016
|
const dir = path39.join(codexHome, "plugins", "cache", marketplace, "workit");
|
|
67914
68017
|
let versions = [];
|
|
67915
68018
|
try {
|
|
67916
|
-
versions = readdirSync10(dir).filter((v) =>
|
|
68019
|
+
versions = readdirSync10(dir).filter((v) => existsSync17(path39.join(dir, v, ".codex-plugin")));
|
|
67917
68020
|
} catch {
|
|
67918
68021
|
versions = [];
|
|
67919
68022
|
}
|
|
@@ -68022,7 +68125,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68022
68125
|
const installed = [];
|
|
68023
68126
|
for (const install of installs) {
|
|
68024
68127
|
const source = install.root ? path39.join(install.root, "agents") : null;
|
|
68025
|
-
const files = source &&
|
|
68128
|
+
const files = source && existsSync17(source) ? readdirSync10(source).filter((f) => f.endsWith(".toml")).toSorted() : [];
|
|
68026
68129
|
if (files.length === 0) {
|
|
68027
68130
|
problems.push(`${install.id} ${install.version ?? "?"} bundles no agents`);
|
|
68028
68131
|
fixes.push(`codex plugin remove ${install.id} && codex plugin add ${install.id}`);
|
|
@@ -68158,7 +68261,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68158
68261
|
return kept;
|
|
68159
68262
|
}, checkPiExtension = (res) => {
|
|
68160
68263
|
const agentDir = piAgentDirOf(res);
|
|
68161
|
-
if (!
|
|
68264
|
+
if (!existsSync17(agentDir) && !commandOnPath("pi", res.env))
|
|
68162
68265
|
return {
|
|
68163
68266
|
id: "pi_extension",
|
|
68164
68267
|
status: "pass",
|
|
@@ -68184,7 +68287,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68184
68287
|
fix: entry.npm ? installCmd(entry.scope, entry.source) : `restore ${entry.root}, then ${rebuild}`
|
|
68185
68288
|
};
|
|
68186
68289
|
const declared = Array.isArray(pkg.pi?.extensions) ? pkg.pi.extensions.some((e) => typeof e === "string" && e.replace(/^\.\//, "") === PI_EXTENSION) : false;
|
|
68187
|
-
if (!declared || !
|
|
68290
|
+
if (!declared || !existsSync17(path39.join(entry.root, PI_EXTENSION)))
|
|
68188
68291
|
return {
|
|
68189
68292
|
id: "pi_extension",
|
|
68190
68293
|
status: "warn",
|
|
@@ -68241,7 +68344,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68241
68344
|
switch (host) {
|
|
68242
68345
|
case "opencode": {
|
|
68243
68346
|
const packaged = path39.join(pkg, "assets", "skills");
|
|
68244
|
-
const root =
|
|
68347
|
+
const root = existsSync17(packaged) ? packaged : path39.join(dev, "packages", "workit-core", "skills");
|
|
68245
68348
|
return WORKIT_METHOD_SKILLS.map((skill) => path39.join(root, skill, "SKILL.md"));
|
|
68246
68349
|
}
|
|
68247
68350
|
case "cursor":
|
|
@@ -68255,7 +68358,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68255
68358
|
}
|
|
68256
68359
|
}, hostsFor = (host) => host === "cli" ? ["opencode", "cursor", "cli"] : [host], checkAssets = (res) => {
|
|
68257
68360
|
const dev = res.dev;
|
|
68258
|
-
const missing = dev ? hostsFor(res.host).flatMap((h) => assetPathsFor(h, dev).filter((p) => !
|
|
68361
|
+
const missing = dev ? hostsFor(res.host).flatMap((h) => assetPathsFor(h, dev).filter((p) => !existsSync17(p)).map((p) => `${h}: ${p}`)) : [];
|
|
68259
68362
|
if (res.host === "cursor" || res.host === "cli") {
|
|
68260
68363
|
const cursorError = validateCursorSkills(res.cursorPluginDir, WORKIT_METHOD_SKILLS);
|
|
68261
68364
|
if (cursorError)
|
|
@@ -68306,7 +68409,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68306
68409
|
return false;
|
|
68307
68410
|
}
|
|
68308
68411
|
}, registeredCursorLauncher = (res) => {
|
|
68309
|
-
if (!
|
|
68412
|
+
if (!existsSync17(res.cursorMcp))
|
|
68310
68413
|
return "invalid";
|
|
68311
68414
|
const config = readJson(res.cursorMcp);
|
|
68312
68415
|
if (!config)
|
|
@@ -68335,7 +68438,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68335
68438
|
};
|
|
68336
68439
|
}, canonicalCursorHook, isCanonicalCursorHook = (command, res) => command === canonicalCursorHook || command === cursorHooksEntry(res.cursorPluginDir).command, registeredCursorHook = (res) => {
|
|
68337
68440
|
const hooksFile = path39.join(res.cursorPluginDir, "hooks", "hooks-cursor.json");
|
|
68338
|
-
if (!
|
|
68441
|
+
if (!existsSync17(hooksFile))
|
|
68339
68442
|
return "invalid";
|
|
68340
68443
|
const config = readJson(hooksFile);
|
|
68341
68444
|
if (!config)
|
|
@@ -68378,7 +68481,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68378
68481
|
}
|
|
68379
68482
|
}
|
|
68380
68483
|
if (dev) {
|
|
68381
|
-
missing.push(...hosts.filter((h) => h !== "cursor").flatMap((h) => launcherSlotsFor(h, dev).filter((slot) => !slot.some((p) =>
|
|
68484
|
+
missing.push(...hosts.filter((h) => h !== "cursor").flatMap((h) => launcherSlotsFor(h, dev).filter((slot) => !slot.some((p) => existsSync17(p))).map((slot) => `${h}: ${slot.join(" or ")}`)));
|
|
68382
68485
|
}
|
|
68383
68486
|
if (missing.length > 0) {
|
|
68384
68487
|
return {
|
|
@@ -68404,7 +68507,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68404
68507
|
const problems = [];
|
|
68405
68508
|
const fixes = [];
|
|
68406
68509
|
if (hostsFor(res.host).includes("cursor")) {
|
|
68407
|
-
const settings =
|
|
68510
|
+
const settings = existsSync17(res.cursorSettings) ? readJson(res.cursorSettings) : null;
|
|
68408
68511
|
const dirs = Array.isArray(settings?.plugin_dirs) ? settings.plugin_dirs : [];
|
|
68409
68512
|
for (const entry of dirs.map(String)) {
|
|
68410
68513
|
const normal = entry.replaceAll("\\", "/").replace(/\/+$/, "");
|
|
@@ -68448,14 +68551,14 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68448
68551
|
status: "pass",
|
|
68449
68552
|
detail: "cursor hook not inspected on this host"
|
|
68450
68553
|
};
|
|
68451
|
-
if (!
|
|
68554
|
+
if (!existsSync17(res.cursorPluginDir))
|
|
68452
68555
|
return {
|
|
68453
68556
|
id: "cursor_hook",
|
|
68454
68557
|
status: "pass",
|
|
68455
68558
|
detail: "no Cursor plugin install — hook launcher not inspected"
|
|
68456
68559
|
};
|
|
68457
68560
|
const launcher = path39.join(res.cursorPluginDir, "hooks", "launch.mjs");
|
|
68458
|
-
if (!
|
|
68561
|
+
if (!existsSync17(launcher))
|
|
68459
68562
|
return {
|
|
68460
68563
|
id: "cursor_hook",
|
|
68461
68564
|
status: "warn",
|
|
@@ -68577,7 +68680,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68577
68680
|
return "fragile-cache";
|
|
68578
68681
|
if (entry.startsWith("file:")) {
|
|
68579
68682
|
const target = entry.replace(/^file:\/\//, "").replace(/^file:/, "");
|
|
68580
|
-
return
|
|
68683
|
+
return existsSync17(target) ? "ok" : "missing-file";
|
|
68581
68684
|
}
|
|
68582
68685
|
return "ok";
|
|
68583
68686
|
}, checkStalePin = (res) => {
|
|
@@ -68588,7 +68691,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68588
68691
|
detail: "opencode pin not inspected on the cursor host"
|
|
68589
68692
|
};
|
|
68590
68693
|
}
|
|
68591
|
-
if (!
|
|
68694
|
+
if (!existsSync17(res.opencodeConfig)) {
|
|
68592
68695
|
return {
|
|
68593
68696
|
id: "stale_pin",
|
|
68594
68697
|
status: "pass",
|
|
@@ -68641,7 +68744,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68641
68744
|
return { id: "stale_pin", status: "pass", detail: "opencode pin resolves" };
|
|
68642
68745
|
}, pluginMcpSelectors = (res) => {
|
|
68643
68746
|
const p = path39.join(res.cursorPluginDir, "mcp.json");
|
|
68644
|
-
if (!
|
|
68747
|
+
if (!existsSync17(p))
|
|
68645
68748
|
return null;
|
|
68646
68749
|
const cfg = readJson(p);
|
|
68647
68750
|
const server = cfg?.mcpServers?.workit;
|
|
@@ -68689,7 +68792,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68689
68792
|
dir = path39.dirname(dir);
|
|
68690
68793
|
return { version: found.version, dir };
|
|
68691
68794
|
}, checkOpenCodePackageCache = (res) => {
|
|
68692
|
-
if (!
|
|
68795
|
+
if (!existsSync17(res.opencodeConfig)) {
|
|
68693
68796
|
return {
|
|
68694
68797
|
id: "stale_install",
|
|
68695
68798
|
status: "pass",
|
|
@@ -68764,7 +68867,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68764
68867
|
detail: "cursor plugin not inspected on this host"
|
|
68765
68868
|
};
|
|
68766
68869
|
}
|
|
68767
|
-
if (
|
|
68870
|
+
if (existsSync17(res.cursorPluginDir) && lstatSync5(res.cursorPluginDir).isSymbolicLink()) {
|
|
68768
68871
|
let target = "";
|
|
68769
68872
|
try {
|
|
68770
68873
|
target = readlinkSync2(res.cursorPluginDir);
|
|
@@ -68802,7 +68905,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68802
68905
|
fix: "Re-run install-cursor-plugin.sh — it rewrites the sessionStart hook to the canonical pinned launcher"
|
|
68803
68906
|
};
|
|
68804
68907
|
}
|
|
68805
|
-
const hookDrift =
|
|
68908
|
+
const hookDrift = existsSync17(hooksFile) ? cursorHookDrift(readJson(hooksFile), res.cursorPluginDir) : [];
|
|
68806
68909
|
if (hookDrift.length > 0) {
|
|
68807
68910
|
return {
|
|
68808
68911
|
id: "stale_install",
|
|
@@ -68886,13 +68989,13 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68886
68989
|
const problems = [];
|
|
68887
68990
|
const opencodeHost = res.host !== "cursor";
|
|
68888
68991
|
const cursorHost = res.host !== "opencode";
|
|
68889
|
-
if (opencodeHost &&
|
|
68992
|
+
if (opencodeHost && existsSync17(res.opencodeConfig)) {
|
|
68890
68993
|
const cfg = readJson(res.opencodeConfig);
|
|
68891
68994
|
const entries = pluginEntries(cfg);
|
|
68892
68995
|
if (entries.length > 1)
|
|
68893
68996
|
problems.push(`opencode registers ${entries.length} workit plugin entries`);
|
|
68894
68997
|
}
|
|
68895
|
-
if (cursorHost &&
|
|
68998
|
+
if (cursorHost && existsSync17(res.cursorSettings)) {
|
|
68896
68999
|
const settings = readJson(res.cursorSettings);
|
|
68897
69000
|
const enabled = settings?.enabled_plugins;
|
|
68898
69001
|
if (enabled && typeof enabled === "object") {
|
|
@@ -68907,7 +69010,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68907
69010
|
if (dirs.length > 1)
|
|
68908
69011
|
problems.push(`cursor plugin_dirs has ${dirs.length} workit entries`);
|
|
68909
69012
|
}
|
|
68910
|
-
if (cursorHost &&
|
|
69013
|
+
if (cursorHost && existsSync17(res.cursorMcp)) {
|
|
68911
69014
|
const mcp = readJson(res.cursorMcp);
|
|
68912
69015
|
const servers = mcp?.mcpServers ?? {};
|
|
68913
69016
|
if (servers && typeof servers === "object") {
|
|
@@ -68933,16 +69036,16 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68933
69036
|
const files = [];
|
|
68934
69037
|
for (const name of ["config.json", "youtrack.json", "vcs.json", "workspaces.json"]) {
|
|
68935
69038
|
const p = path39.join(res.configDir, name);
|
|
68936
|
-
if (
|
|
69039
|
+
if (existsSync17(p))
|
|
68937
69040
|
files.push(p);
|
|
68938
69041
|
}
|
|
68939
69042
|
const opencodeHost = res.host !== "cursor";
|
|
68940
69043
|
const cursorHost = res.host !== "opencode";
|
|
68941
|
-
if (opencodeHost &&
|
|
69044
|
+
if (opencodeHost && existsSync17(res.opencodeConfig))
|
|
68942
69045
|
files.push(res.opencodeConfig);
|
|
68943
|
-
if (cursorHost &&
|
|
69046
|
+
if (cursorHost && existsSync17(res.cursorSettings))
|
|
68944
69047
|
files.push(res.cursorSettings);
|
|
68945
|
-
if (cursorHost &&
|
|
69048
|
+
if (cursorHost && existsSync17(res.cursorMcp))
|
|
68946
69049
|
files.push(res.cursorMcp);
|
|
68947
69050
|
const bad = files.filter((p) => !parsesAsConfigObject(p));
|
|
68948
69051
|
if (bad.length === 0)
|
|
@@ -69162,7 +69265,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69162
69265
|
const youtrackJson = readJson(path39.join(res.configDir, "youtrack.json"));
|
|
69163
69266
|
if (youtrackJson) {
|
|
69164
69267
|
tokenPaths.push(typeof youtrackJson.tokenFile === "string" ? youtrackJson.tokenFile : path39.join(res.configDir, "youtrack.token"));
|
|
69165
|
-
} else if (
|
|
69268
|
+
} else if (existsSync17(path39.join(res.configDir, "youtrack.token"))) {
|
|
69166
69269
|
tokenPaths.push(path39.join(res.configDir, "youtrack.token"));
|
|
69167
69270
|
}
|
|
69168
69271
|
if (tokenPaths.length === 0) {
|
|
@@ -69175,7 +69278,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69175
69278
|
const problems = [];
|
|
69176
69279
|
for (const raw of tokenPaths) {
|
|
69177
69280
|
const p = path39.isAbsolute(raw) ? raw : path39.resolve(res.configDir, raw);
|
|
69178
|
-
if (!
|
|
69281
|
+
if (!existsSync17(p)) {
|
|
69179
69282
|
problems.push(`${p} is missing`);
|
|
69180
69283
|
continue;
|
|
69181
69284
|
}
|
|
@@ -69502,8 +69605,8 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69502
69605
|
};
|
|
69503
69606
|
}, checkChecksConfig = (res) => {
|
|
69504
69607
|
const root = checkRoot(res.cwd);
|
|
69505
|
-
const current =
|
|
69506
|
-
const legacy =
|
|
69608
|
+
const current = existsSync17(path39.join(root, CHECKS_FILE));
|
|
69609
|
+
const legacy = existsSync17(path39.join(root, LEGACY_CHECKS_FILE));
|
|
69507
69610
|
if (!legacy)
|
|
69508
69611
|
return {
|
|
69509
69612
|
id: "checks_config",
|
|
@@ -69520,9 +69623,9 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69520
69623
|
const root = checkRoot(resolve(options).cwd);
|
|
69521
69624
|
const from = path39.join(root, LEGACY_CHECKS_FILE);
|
|
69522
69625
|
const to = path39.join(root, CHECKS_FILE);
|
|
69523
|
-
if (!
|
|
69626
|
+
if (!existsSync17(from))
|
|
69524
69627
|
return { action: "none", detail: `no ${LEGACY_CHECKS_FILE} at ${root}` };
|
|
69525
|
-
if (
|
|
69628
|
+
if (existsSync17(to))
|
|
69526
69629
|
return {
|
|
69527
69630
|
action: "skipped",
|
|
69528
69631
|
detail: `${CHECKS_FILE} already exists; ${LEGACY_CHECKS_FILE} left in place`
|
|
@@ -69816,7 +69919,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69816
69919
|
return {
|
|
69817
69920
|
id,
|
|
69818
69921
|
status: "warn",
|
|
69819
|
-
detail: `${host} rules in ${coverage.file} do not cover ${shown}${coverage.missing.length > 4 ? ", …" : ""}${
|
|
69922
|
+
detail: `${host} rules in ${coverage.file} do not cover ${shown}${coverage.missing.length > 4 ? ", …" : ""}${existsSync17(coverage.file) ? "" : ` (${coverage.file} does not exist yet; \`workit setup\` writes it)`}: agents get a prompt (or an auto-mode denial) on verbs the workspace grants`,
|
|
69820
69923
|
fix: `workit setup --hosts=${host}`
|
|
69821
69924
|
};
|
|
69822
69925
|
}, ago = (ms) => {
|
|
@@ -69977,13 +70080,13 @@ var init_doctor = __esm(() => {
|
|
|
69977
70080
|
import {
|
|
69978
70081
|
copyFileSync as copyFileSync5,
|
|
69979
70082
|
cpSync as cpSync4,
|
|
69980
|
-
existsSync as
|
|
70083
|
+
existsSync as existsSync18,
|
|
69981
70084
|
lstatSync as lstatSync6,
|
|
69982
70085
|
mkdirSync as mkdirSync9,
|
|
69983
70086
|
mkdtempSync as mkdtempSync2,
|
|
69984
70087
|
readFileSync as readFileSync19,
|
|
69985
70088
|
readdirSync as readdirSync11,
|
|
69986
|
-
realpathSync as
|
|
70089
|
+
realpathSync as realpathSync9,
|
|
69987
70090
|
renameSync as renameSync5,
|
|
69988
70091
|
rmSync as rmSync5,
|
|
69989
70092
|
statSync as statSync7,
|
|
@@ -70088,7 +70191,7 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
70088
70191
|
path: ytPath,
|
|
70089
70192
|
value: draft
|
|
70090
70193
|
});
|
|
70091
|
-
if (
|
|
70194
|
+
if (existsSync18(tokenPath))
|
|
70092
70195
|
preserved.push(tokenPath);
|
|
70093
70196
|
else
|
|
70094
70197
|
mutations.push({
|
|
@@ -70155,7 +70258,7 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
70155
70258
|
if (target?.ok) {
|
|
70156
70259
|
const root = target.root;
|
|
70157
70260
|
const gitignorePath = path40.join(root, ".gitignore");
|
|
70158
|
-
const existing =
|
|
70261
|
+
const existing = existsSync18(gitignorePath) ? readFileSync19(gitignorePath, "utf8") : "";
|
|
70159
70262
|
const existingLines = new Set(existing.split(`
|
|
70160
70263
|
`).map((l) => l.trim()).filter(Boolean));
|
|
70161
70264
|
const entries = GITIGNORE_ENTRIES.filter((e) => e.trim() !== "" && !existingLines.has(e.trim()));
|
|
@@ -70429,13 +70532,13 @@ function applyOpenCode(root, res) {
|
|
|
70429
70532
|
};
|
|
70430
70533
|
}
|
|
70431
70534
|
function copyPluginDir(src, dest) {
|
|
70432
|
-
const realSrc =
|
|
70535
|
+
const realSrc = realpathSync9(src);
|
|
70433
70536
|
const marker = path40.join(dest, ".workit-root");
|
|
70434
|
-
const destIsLink =
|
|
70537
|
+
const destIsLink = existsSync18(dest) && lstatSync6(dest).isSymbolicLink();
|
|
70435
70538
|
const synced = !destIsLink && readFileSafe(marker)?.trim() === realSrc && samePluginContent(realSrc, dest, dest);
|
|
70436
70539
|
if (synced)
|
|
70437
70540
|
return "Skipped";
|
|
70438
|
-
const hadDir =
|
|
70541
|
+
const hadDir = existsSync18(dest);
|
|
70439
70542
|
const rules = preservedCursorRules(realSrc, dest);
|
|
70440
70543
|
const parent = path40.dirname(dest);
|
|
70441
70544
|
mkdirSync9(parent, { recursive: true });
|
|
@@ -70448,7 +70551,7 @@ function copyPluginDir(src, dest) {
|
|
|
70448
70551
|
filter: (entry) => !path40.relative(realSrc, entry).split(path40.sep).includes("node_modules")
|
|
70449
70552
|
});
|
|
70450
70553
|
const stagedHooks = path40.join(stage, CURSOR_HOOKS_FILE);
|
|
70451
|
-
if (
|
|
70554
|
+
if (existsSync18(stagedHooks))
|
|
70452
70555
|
writeFileSync10(stagedHooks, localizedCursorHooks(readFileSync19(stagedHooks), dest));
|
|
70453
70556
|
for (const [name, content] of rules) {
|
|
70454
70557
|
mkdirSync9(path40.join(stage, "rules"), { recursive: true });
|
|
@@ -70466,7 +70569,7 @@ function copyPluginDir(src, dest) {
|
|
|
70466
70569
|
try {
|
|
70467
70570
|
renameSync5(stage, dest);
|
|
70468
70571
|
} catch (error) {
|
|
70469
|
-
if (hadDir && !
|
|
70572
|
+
if (hadDir && !existsSync18(dest))
|
|
70470
70573
|
renameSync5(backup, dest);
|
|
70471
70574
|
throw error;
|
|
70472
70575
|
}
|
|
@@ -70544,9 +70647,9 @@ function applyCursorMcp(root, res) {
|
|
|
70544
70647
|
};
|
|
70545
70648
|
}
|
|
70546
70649
|
function verifyPlatform(platform, res) {
|
|
70547
|
-
if (platform === "opencode" && !
|
|
70650
|
+
if (platform === "opencode" && !existsSync18(res.opencodeConfig))
|
|
70548
70651
|
return null;
|
|
70549
|
-
if (platform === "cursor" && !
|
|
70652
|
+
if (platform === "cursor" && !existsSync18(res.cursorSettings) && !existsSync18(res.cursorMcp)) {
|
|
70550
70653
|
return null;
|
|
70551
70654
|
}
|
|
70552
70655
|
return runDoctor({
|
|
@@ -70827,7 +70930,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
70827
70930
|
try {
|
|
70828
70931
|
raw = readFileSync19(p, "utf8");
|
|
70829
70932
|
} catch {
|
|
70830
|
-
if (
|
|
70933
|
+
if (existsSync18(p))
|
|
70831
70934
|
return { kind: "malformed", error: `${p} is not readable` };
|
|
70832
70935
|
return { kind: "missing" };
|
|
70833
70936
|
}
|
|
@@ -70868,7 +70971,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
70868
70971
|
return (require2.resolve.paths(name) ?? []).map((dir) => path40.join(dir, name));
|
|
70869
70972
|
}, realRoot = (root) => {
|
|
70870
70973
|
try {
|
|
70871
|
-
return
|
|
70974
|
+
return realpathSync9(root);
|
|
70872
70975
|
} catch {
|
|
70873
70976
|
return root;
|
|
70874
70977
|
}
|
|
@@ -70882,7 +70985,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
70882
70985
|
return OPENCODE_NPM_PIN;
|
|
70883
70986
|
for (const rel of ["src/plugin.ts", "dist/plugin.js"]) {
|
|
70884
70987
|
const entry = path40.join(root, rel);
|
|
70885
|
-
if (
|
|
70988
|
+
if (existsSync18(entry))
|
|
70886
70989
|
return `file://${entry}`;
|
|
70887
70990
|
}
|
|
70888
70991
|
return null;
|
|
@@ -70912,7 +71015,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
70912
71015
|
}
|
|
70913
71016
|
}
|
|
70914
71017
|
for (const entry of readdirSync11(dest, { withFileTypes: true })) {
|
|
70915
|
-
if (
|
|
71018
|
+
if (existsSync18(path40.join(src, entry.name)))
|
|
70916
71019
|
continue;
|
|
70917
71020
|
const rel = path40.join(relative, entry.name);
|
|
70918
71021
|
if (rel === ".workit-root")
|
|
@@ -70933,7 +71036,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
70933
71036
|
for (const entry of readdirSync11(installedRules, { withFileTypes: true })) {
|
|
70934
71037
|
if (!entry.isFile() || !entry.name.endsWith(".mdc"))
|
|
70935
71038
|
continue;
|
|
70936
|
-
if (
|
|
71039
|
+
if (existsSync18(path40.join(sourceRules, entry.name)))
|
|
70937
71040
|
continue;
|
|
70938
71041
|
preserved.set(entry.name, readFileSync19(path40.join(installedRules, entry.name)));
|
|
70939
71042
|
}
|
|
@@ -70941,17 +71044,17 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
70941
71044
|
return preserved;
|
|
70942
71045
|
}, removeLegacyCursorDir = (res) => {
|
|
70943
71046
|
const legacy = path40.join(res.home, ".cursor", "plugins", "local", "workflow-toolkit");
|
|
70944
|
-
if (legacy === res.cursorPluginDir || !
|
|
71047
|
+
if (legacy === res.cursorPluginDir || !existsSync18(legacy))
|
|
70945
71048
|
return;
|
|
70946
71049
|
const legacyRules = path40.join(legacy, "rules");
|
|
70947
|
-
if (
|
|
71050
|
+
if (existsSync18(legacyRules)) {
|
|
70948
71051
|
try {
|
|
70949
71052
|
mkdirSync9(path40.join(res.cursorPluginDir, "rules"), { recursive: true });
|
|
70950
71053
|
for (const entry of readdirSync11(legacyRules, { withFileTypes: true })) {
|
|
70951
71054
|
if (!entry.isFile() || !entry.name.endsWith(".mdc"))
|
|
70952
71055
|
continue;
|
|
70953
71056
|
const target = path40.join(res.cursorPluginDir, "rules", entry.name);
|
|
70954
|
-
if (!
|
|
71057
|
+
if (!existsSync18(target))
|
|
70955
71058
|
copyFileSync5(path40.join(legacyRules, entry.name), target);
|
|
70956
71059
|
}
|
|
70957
71060
|
} catch {}
|
|
@@ -71340,7 +71443,7 @@ var init_logic = __esm(() => {
|
|
|
71340
71443
|
});
|
|
71341
71444
|
|
|
71342
71445
|
// packages/workit-cli/src/wizard-state.ts
|
|
71343
|
-
import { existsSync as
|
|
71446
|
+
import { existsSync as existsSync19, statSync as statSync8 } from "node:fs";
|
|
71344
71447
|
import path42 from "node:path";
|
|
71345
71448
|
import { isDeepStrictEqual as isDeepStrictEqual4 } from "node:util";
|
|
71346
71449
|
function resolveBasePath(values, env = process.env) {
|
|
@@ -71869,7 +71972,7 @@ var NEXT, PREV, skipsCustomBranch = (screen, preset) => (screen === "branchAllow
|
|
|
71869
71972
|
if (!p)
|
|
71870
71973
|
return "workspace root path is required";
|
|
71871
71974
|
return !path42.isAbsolute(p) || !isDirectory(p) ? `invalid workspace root "${p}" — enter an existing absolute directory` : null;
|
|
71872
|
-
}, skipsBranchPolicy = (screen, basePath) => (screen === "branchPolicy" || screen === "branchPolicyDevelop") && !
|
|
71975
|
+
}, skipsBranchPolicy = (screen, basePath) => (screen === "branchPolicy" || screen === "branchPolicyDevelop") && !existsSync19(path42.join(basePath, ".git")), decodeBranchPreset = (value, fallback) => value === "gitflow" || value === "github-flow" || value === "trunk-based" || value === "custom" ? value : fallback, decodeVcsProvider = (value, fallback) => value === "gitlab" || value === "github" || value === "skip" ? value : fallback, decodeIssueTracker = (value, fallback) => value === "youtrack" || value === "github" || value === "gitlab" || value === "none" ? value : fallback, GITHUB_ISSUES, withGithubIssues = (draft, tracker) => tracker === "github" ? { ...draft, issues: { ...GITHUB_ISSUES } } : draft;
|
|
71873
71976
|
var init_wizard_state = __esm(() => {
|
|
71874
71977
|
init_config();
|
|
71875
71978
|
init_workspaces();
|
|
@@ -71928,7 +72031,7 @@ var init_wizard_state = __esm(() => {
|
|
|
71928
72031
|
});
|
|
71929
72032
|
|
|
71930
72033
|
// packages/workit-cli/src/admin/uninstall.ts
|
|
71931
|
-
import { existsSync as
|
|
72034
|
+
import { existsSync as existsSync20, readFileSync as readFileSync21, realpathSync as realpathSync10, rmSync as rmSync7, writeFileSync as writeFileSync12 } from "node:fs";
|
|
71932
72035
|
import os14 from "node:os";
|
|
71933
72036
|
import path43 from "node:path";
|
|
71934
72037
|
function cleanCursorSettings(settings, pluginDir) {
|
|
@@ -72030,7 +72133,7 @@ function planUninstall(paths = {}) {
|
|
|
72030
72133
|
const mcpExisting = readJsonRecord(res.cursorMcp);
|
|
72031
72134
|
const settingsDirty = settingsExisting.kind === "malformed" || settingsExisting.kind === "record" && cleanCursorSettings(settingsExisting.value, res.cursorPluginDir).changed;
|
|
72032
72135
|
const mcpDirty = mcpExisting.kind === "malformed" || mcpExisting.kind === "record" && cleanCursorMcp(mcpExisting.value).changed;
|
|
72033
|
-
const dirExists =
|
|
72136
|
+
const dirExists = existsSync20(res.cursorPluginDir);
|
|
72034
72137
|
const actions = [];
|
|
72035
72138
|
if (settingsDirty) {
|
|
72036
72139
|
actions.push({
|
|
@@ -72058,7 +72161,7 @@ function planUninstall(paths = {}) {
|
|
|
72058
72161
|
installed: settingsDirty || mcpDirty || dirExists,
|
|
72059
72162
|
actions
|
|
72060
72163
|
};
|
|
72061
|
-
const codexInstalled =
|
|
72164
|
+
const codexInstalled = existsSync20(res.codexPluginDir);
|
|
72062
72165
|
const codex = {
|
|
72063
72166
|
host: "codex",
|
|
72064
72167
|
installed: codexInstalled,
|
|
@@ -72106,7 +72209,7 @@ function planUninstall(paths = {}) {
|
|
|
72106
72209
|
detail: `remove Workit's permission block from ${path43.basename(file)}`
|
|
72107
72210
|
});
|
|
72108
72211
|
}
|
|
72109
|
-
if (
|
|
72212
|
+
if (existsSync20(res.codexRules))
|
|
72110
72213
|
codex.actions.push({
|
|
72111
72214
|
kind: "remove-file",
|
|
72112
72215
|
path: res.codexRules,
|
|
@@ -72142,7 +72245,7 @@ function applyUninstall(plan, paths = {}) {
|
|
|
72142
72245
|
if (!allowed) {
|
|
72143
72246
|
status = "failed";
|
|
72144
72247
|
detail = `refusing to remove non-canonical plugin directory: ${resolved}`;
|
|
72145
|
-
} else if (!
|
|
72248
|
+
} else if (!existsSync20(resolved)) {
|
|
72146
72249
|
status = "skipped";
|
|
72147
72250
|
detail = "directory already absent";
|
|
72148
72251
|
} else {
|
|
@@ -72192,7 +72295,7 @@ var resolveUninstallPaths = (options = {}) => {
|
|
|
72192
72295
|
try {
|
|
72193
72296
|
raw = readFileSync21(file, "utf8");
|
|
72194
72297
|
} catch {
|
|
72195
|
-
if (
|
|
72298
|
+
if (existsSync20(file))
|
|
72196
72299
|
return { kind: "malformed", error: `${file} is not readable` };
|
|
72197
72300
|
return { kind: "missing" };
|
|
72198
72301
|
}
|
|
@@ -72236,7 +72339,7 @@ var resolveUninstallPaths = (options = {}) => {
|
|
|
72236
72339
|
return false;
|
|
72237
72340
|
}
|
|
72238
72341
|
try {
|
|
72239
|
-
return
|
|
72342
|
+
return realpathSync10(actionPath) === realpathSync10(expected);
|
|
72240
72343
|
} catch {
|
|
72241
72344
|
return true;
|
|
72242
72345
|
}
|
|
@@ -75041,7 +75144,7 @@ var init_setup2 = __esm(() => {
|
|
|
75041
75144
|
});
|
|
75042
75145
|
|
|
75043
75146
|
// packages/workit-cli/src/upgrade/shared.ts
|
|
75044
|
-
import { existsSync as
|
|
75147
|
+
import { existsSync as existsSync21, readFileSync as readFileSync22 } from "node:fs";
|
|
75045
75148
|
import path44 from "node:path";
|
|
75046
75149
|
import os16 from "node:os";
|
|
75047
75150
|
import { createHash as createHash15 } from "node:crypto";
|
|
@@ -75074,7 +75177,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75074
75177
|
cursorRoot: path44.join(home, ".cursor/plugins/local/workit")
|
|
75075
75178
|
};
|
|
75076
75179
|
}, object2 = (file) => {
|
|
75077
|
-
if (!
|
|
75180
|
+
if (!existsSync21(file))
|
|
75078
75181
|
return null;
|
|
75079
75182
|
let data;
|
|
75080
75183
|
try {
|
|
@@ -75091,7 +75194,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75091
75194
|
} catch {
|
|
75092
75195
|
return null;
|
|
75093
75196
|
}
|
|
75094
|
-
}, digest2 = (file) =>
|
|
75197
|
+
}, digest2 = (file) => existsSync21(file) ? createHash15("sha256").update(readFileSync22(file)).digest("hex") : "missing", runner = (deps) => deps.run ?? ((command, args) => {
|
|
75095
75198
|
const { home, env } = upgradePaths(deps);
|
|
75096
75199
|
let step;
|
|
75097
75200
|
try {
|
|
@@ -75187,7 +75290,7 @@ var init_processes = __esm(() => {
|
|
|
75187
75290
|
});
|
|
75188
75291
|
|
|
75189
75292
|
// packages/workit-cli/src/upgrade/apply.ts
|
|
75190
|
-
import { existsSync as
|
|
75293
|
+
import { existsSync as existsSync22, readdirSync as readdirSync12, mkdirSync as mkdirSync11, copyFileSync as copyFileSync6, chmodSync as chmodSync2, cpSync as cpSync5 } from "node:fs";
|
|
75191
75294
|
import path46 from "node:path";
|
|
75192
75295
|
import { createHash as createHash16 } from "node:crypto";
|
|
75193
75296
|
function applyUpgrade(plan, deps = {}) {
|
|
@@ -75226,7 +75329,7 @@ function applyUpgrade(plan, deps = {}) {
|
|
|
75226
75329
|
const backup = path46.join(home, ".local/state/workit/upgrades", new Date().toISOString().replaceAll(":", "-"));
|
|
75227
75330
|
mkdirSync11(backup, { recursive: true, mode: 448 });
|
|
75228
75331
|
for (const file of Object.keys(plan.configDigests))
|
|
75229
|
-
if (
|
|
75332
|
+
if (existsSync22(file)) {
|
|
75230
75333
|
const target = path46.join(backup, createHash16("sha256").update(file).digest("hex").slice(0, 12) + "-" + path46.basename(file));
|
|
75231
75334
|
copyFileSync6(file, target);
|
|
75232
75335
|
chmodSync2(target, 384);
|
|
@@ -75246,7 +75349,7 @@ function applyUpgrade(plan, deps = {}) {
|
|
|
75246
75349
|
}
|
|
75247
75350
|
const run = runner(deps);
|
|
75248
75351
|
let cursorBackupError = null;
|
|
75249
|
-
if (plan.entries.some((entry) => entry.host === "cursor") &&
|
|
75352
|
+
if (plan.entries.some((entry) => entry.host === "cursor") && existsSync22(paths.cursorRoot))
|
|
75250
75353
|
try {
|
|
75251
75354
|
cpSync5(paths.cursorRoot, path46.join(backup, "cursor-package"), {
|
|
75252
75355
|
recursive: true
|
|
@@ -75513,7 +75616,7 @@ var codexPluginRoot = (codexHome) => {
|
|
|
75513
75616
|
}, refreshCodexAgents = (run, codexHome) => {
|
|
75514
75617
|
const root = codexPluginRoot(codexHome);
|
|
75515
75618
|
const launcher = root && path46.join(root, "dist", "launch-mcp.js");
|
|
75516
|
-
if (!launcher || !
|
|
75619
|
+
if (!launcher || !existsSync22(launcher))
|
|
75517
75620
|
return { ok: true, note: "" };
|
|
75518
75621
|
const fix = `node ${JSON.stringify(launcher)} --install-agents`;
|
|
75519
75622
|
return run("node", [launcher, "--install-agents"]).status === 0 ? { ok: true, note: "agents refreshed" } : { ok: false, note: "agent refresh failed", fix };
|
|
@@ -75552,7 +75655,7 @@ var init_apply = __esm(() => {
|
|
|
75552
75655
|
});
|
|
75553
75656
|
|
|
75554
75657
|
// packages/workit-cli/src/upgrade/plan.ts
|
|
75555
|
-
import { existsSync as
|
|
75658
|
+
import { existsSync as existsSync23, mkdtempSync as mkdtempSync3, rmSync as rmSync8, lstatSync as lstatSync7, readFileSync as readFileSync23 } from "node:fs";
|
|
75556
75659
|
import path47 from "node:path";
|
|
75557
75660
|
import os17 from "node:os";
|
|
75558
75661
|
function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
@@ -75739,7 +75842,7 @@ var codexRegistered = (configFile) => {
|
|
|
75739
75842
|
}
|
|
75740
75843
|
};
|
|
75741
75844
|
guard("opencode", () => {
|
|
75742
|
-
if (
|
|
75845
|
+
if (existsSync23(paths.opencodeConfig + "c"))
|
|
75743
75846
|
throw new Error("OpenCode JSONC config is present; inspect effective native configuration before updating");
|
|
75744
75847
|
const oc = object2(paths.opencodeConfig);
|
|
75745
75848
|
if (oc && [oc.plugins, oc.plugin].some((value) => value !== undefined && !Array.isArray(value)))
|
|
@@ -75796,7 +75899,7 @@ var codexRegistered = (configFile) => {
|
|
|
75796
75899
|
hostCommand("codex", [], { home, env: paths.env });
|
|
75797
75900
|
available = true;
|
|
75798
75901
|
} catch {}
|
|
75799
|
-
if (available ||
|
|
75902
|
+
if (available || existsSync23(paths.codexConfig))
|
|
75800
75903
|
throw new Error("Codex plugin inventory failed; inspect the native host before upgrading");
|
|
75801
75904
|
return;
|
|
75802
75905
|
}
|
|
@@ -77258,7 +77361,7 @@ __export(exports_workspace, {
|
|
|
77258
77361
|
run: () => run11,
|
|
77259
77362
|
runWorkspace: () => runWorkspace
|
|
77260
77363
|
});
|
|
77261
|
-
import { copyFileSync as copyFileSync7, existsSync as
|
|
77364
|
+
import { copyFileSync as copyFileSync7, existsSync as existsSync24 } from "node:fs";
|
|
77262
77365
|
function list2(argv, io) {
|
|
77263
77366
|
if (argv.length)
|
|
77264
77367
|
return usage3(io, `unexpected argument ${argv[0]}`);
|
|
@@ -77567,7 +77670,7 @@ usage: ${USAGE5}`)), load = (io) => {
|
|
|
77567
77670
|
return { ok: false, error: `${current.path} changed; retry` };
|
|
77568
77671
|
let backup = null;
|
|
77569
77672
|
try {
|
|
77570
|
-
if (
|
|
77673
|
+
if (existsSync24(current.path)) {
|
|
77571
77674
|
backup = `${current.path}.bak`;
|
|
77572
77675
|
copyFileSync7(current.path, backup);
|
|
77573
77676
|
}
|
|
@@ -79403,7 +79506,7 @@ var exports_models = {};
|
|
|
79403
79506
|
__export(exports_models, {
|
|
79404
79507
|
run: () => run14
|
|
79405
79508
|
});
|
|
79406
|
-
import { existsSync as
|
|
79509
|
+
import { existsSync as existsSync25, readdirSync as readdirSync13, readFileSync as readFileSync24, statSync as statSync9 } from "node:fs";
|
|
79407
79510
|
import os22 from "node:os";
|
|
79408
79511
|
import path55 from "node:path";
|
|
79409
79512
|
async function run14(argv, io) {
|
|
@@ -79499,7 +79602,7 @@ var USAGE8 = "workit models show [--role <role>] [--tier <tier>] [--host <host>]
|
|
|
79499
79602
|
continue;
|
|
79500
79603
|
const agentType = JSON.parse(readFileSync24(meta, "utf8")).agentType;
|
|
79501
79604
|
const transcript = meta.replace(/\.meta\.json$/, ".jsonl");
|
|
79502
|
-
if (typeof agentType !== "string" || !
|
|
79605
|
+
if (typeof agentType !== "string" || !existsSync25(transcript))
|
|
79503
79606
|
continue;
|
|
79504
79607
|
const ran = modelsOf(transcript);
|
|
79505
79608
|
if (!ran.size)
|
|
@@ -79638,7 +79741,7 @@ var success2 = (data) => ({ ok: true, data }), failure3 = (code, error, unblock)
|
|
|
79638
79741
|
|
|
79639
79742
|
// packages/workit-core/src/git/ops.ts
|
|
79640
79743
|
import { spawnSync as spawnSync20 } from "node:child_process";
|
|
79641
|
-
import { existsSync as
|
|
79744
|
+
import { existsSync as existsSync26, readFileSync as readFileSync25 } from "node:fs";
|
|
79642
79745
|
import path56 from "node:path";
|
|
79643
79746
|
function operationInProgress(cwd) {
|
|
79644
79747
|
const markers = [
|
|
@@ -79656,11 +79759,11 @@ function operationInProgress(cwd) {
|
|
|
79656
79759
|
const conflicted = () => git5(cwd, ["ls-files", "-u"]).stdout.trim() !== "";
|
|
79657
79760
|
for (const [index, [, operation]] of markers.entries()) {
|
|
79658
79761
|
const marker = found[index];
|
|
79659
|
-
if (!marker || !
|
|
79762
|
+
if (!marker || !existsSync26(marker))
|
|
79660
79763
|
continue;
|
|
79661
|
-
if (index === 1 &&
|
|
79764
|
+
if (index === 1 && existsSync26(path56.join(marker, "applying")))
|
|
79662
79765
|
return { operation: "am", commitAllowed: false, branch: null };
|
|
79663
|
-
if (index === 0 &&
|
|
79766
|
+
if (index === 0 && existsSync26(path56.join(marker, "amend")) && !conflicted()) {
|
|
79664
79767
|
let headName = "";
|
|
79665
79768
|
try {
|
|
79666
79769
|
headName = readFileSync25(path56.join(marker, "head-name"), "utf8").trim();
|
|
@@ -79991,7 +80094,7 @@ function gitCommit(cwd, input) {
|
|
|
79991
80094
|
if (paths.some((value) => value.startsWith("-") || !value.trim()))
|
|
79992
80095
|
return failure3("invalid_input", "paths must not be empty or start with -");
|
|
79993
80096
|
const tracked = new Set(nulList(git5(cwd, ["ls-files", "-z", "--", ...paths]).stdout));
|
|
79994
|
-
const addable = paths.filter((value) =>
|
|
80097
|
+
const addable = paths.filter((value) => existsSync26(path56.resolve(cwd, value)) || [...tracked].some((file) => file === value || file.startsWith(`${value}/`)));
|
|
79995
80098
|
if (addable.length) {
|
|
79996
80099
|
const added = git5(cwd, ["add", "-A", "--", ...addable]);
|
|
79997
80100
|
if (!added.ok)
|
|
@@ -86972,7 +87075,7 @@ __export(exports_pr, {
|
|
|
86972
87075
|
checkPrTitle: () => checkPrTitle,
|
|
86973
87076
|
run: () => run15
|
|
86974
87077
|
});
|
|
86975
|
-
import { existsSync as
|
|
87078
|
+
import { existsSync as existsSync27, readFileSync as readFileSync27 } from "node:fs";
|
|
86976
87079
|
import path66 from "node:path";
|
|
86977
87080
|
function titleRules(cwd) {
|
|
86978
87081
|
let root;
|
|
@@ -86985,7 +87088,7 @@ function titleRules(cwd) {
|
|
|
86985
87088
|
let name = "";
|
|
86986
87089
|
for (const candidate of COMMITLINT_FILES) {
|
|
86987
87090
|
const full = path66.join(root, candidate);
|
|
86988
|
-
if (!
|
|
87091
|
+
if (!existsSync27(full))
|
|
86989
87092
|
continue;
|
|
86990
87093
|
text = readFileSync27(full, "utf8");
|
|
86991
87094
|
name = candidate;
|
|
@@ -106680,7 +106783,7 @@ var init_rules = __esm(() => {
|
|
|
106680
106783
|
|
|
106681
106784
|
// packages/workit-cli/src/test-audit/audit.ts
|
|
106682
106785
|
import { spawnSync as spawnSync29 } from "node:child_process";
|
|
106683
|
-
import { existsSync as
|
|
106786
|
+
import { existsSync as existsSync28, readdirSync as readdirSync14, readFileSync as readFileSync29, statSync as statSync10 } from "node:fs";
|
|
106684
106787
|
import path71 from "node:path";
|
|
106685
106788
|
function git7(cwd, args) {
|
|
106686
106789
|
const run = spawnSync29("git", ["-c", "core.quotepath=off", ...args], {
|
|
@@ -106707,7 +106810,7 @@ function expandPaths(cwd, inputs) {
|
|
|
106707
106810
|
const missing = [];
|
|
106708
106811
|
for (const input of inputs.length > 0 ? inputs : ["."]) {
|
|
106709
106812
|
const full = path71.resolve(cwd, input);
|
|
106710
|
-
if (!
|
|
106813
|
+
if (!existsSync28(full))
|
|
106711
106814
|
missing.push(input);
|
|
106712
106815
|
else if (statSync10(full).isDirectory())
|
|
106713
106816
|
walkTests(full, files);
|
|
@@ -106823,14 +106926,14 @@ var init_audit = __esm(() => {
|
|
|
106823
106926
|
// packages/workit-cli/src/test-audit/mutate.ts
|
|
106824
106927
|
import { spawn as spawn2 } from "node:child_process";
|
|
106825
106928
|
import {
|
|
106826
|
-
existsSync as
|
|
106929
|
+
existsSync as existsSync29,
|
|
106827
106930
|
lstatSync as lstatSync8,
|
|
106828
106931
|
mkdirSync as mkdirSync12,
|
|
106829
106932
|
mkdtempSync as mkdtempSync4,
|
|
106830
106933
|
readdirSync as readdirSync15,
|
|
106831
106934
|
readFileSync as readFileSync30,
|
|
106832
106935
|
readlinkSync as readlinkSync3,
|
|
106833
|
-
realpathSync as
|
|
106936
|
+
realpathSync as realpathSync11,
|
|
106834
106937
|
renameSync as renameSync7,
|
|
106835
106938
|
rmSync as rmSync9,
|
|
106836
106939
|
statSync as statSync11,
|
|
@@ -106967,7 +107070,7 @@ function linkNodeModules(origin, target, repo, copy) {
|
|
|
106967
107070
|
if (entry.isSymbolicLink()) {
|
|
106968
107071
|
let real;
|
|
106969
107072
|
try {
|
|
106970
|
-
real =
|
|
107073
|
+
real = realpathSync11(from);
|
|
106971
107074
|
} catch {
|
|
106972
107075
|
continue;
|
|
106973
107076
|
}
|
|
@@ -106983,11 +107086,11 @@ function linkNodeModules(origin, target, repo, copy) {
|
|
|
106983
107086
|
function copySymlink(repo, tree, from, to) {
|
|
106984
107087
|
let real = null;
|
|
106985
107088
|
try {
|
|
106986
|
-
real =
|
|
107089
|
+
real = realpathSync11(from);
|
|
106987
107090
|
} catch {
|
|
106988
107091
|
real = null;
|
|
106989
107092
|
}
|
|
106990
|
-
const realRepo =
|
|
107093
|
+
const realRepo = realpathSync11(repo);
|
|
106991
107094
|
if (real && inside5(realRepo, real)) {
|
|
106992
107095
|
symlinkSync(path72.relative(path72.dirname(to), path72.join(tree, path72.relative(realRepo, real))), to);
|
|
106993
107096
|
return;
|
|
@@ -107001,7 +107104,7 @@ function writeInside(copy, file, content) {
|
|
|
107001
107104
|
const target = path72.join(copy, file);
|
|
107002
107105
|
try {
|
|
107003
107106
|
const stat = lstatSync8(target);
|
|
107004
|
-
if (!stat.isFile() || !inside5(
|
|
107107
|
+
if (!stat.isFile() || !inside5(realpathSync11(copy), realpathSync11(path72.dirname(target))))
|
|
107005
107108
|
return false;
|
|
107006
107109
|
} catch {
|
|
107007
107110
|
return false;
|
|
@@ -107052,7 +107155,7 @@ function copyWorkingTree(repo) {
|
|
|
107052
107155
|
}
|
|
107053
107156
|
for (const parent of dirs) {
|
|
107054
107157
|
const modules = path72.join(repo, parent, "node_modules");
|
|
107055
|
-
if (
|
|
107158
|
+
if (existsSync29(modules) && !existsSync29(path72.join(tree, parent, "node_modules")))
|
|
107056
107159
|
linkNodeModules(modules, path72.join(tree, parent, "node_modules"), repo, tree);
|
|
107057
107160
|
}
|
|
107058
107161
|
return { dir, tree };
|
|
@@ -107102,7 +107205,7 @@ async function runMutation(options) {
|
|
|
107102
107205
|
const relative = toPosix(path72.relative(repo, absolute));
|
|
107103
107206
|
if (!CODE_FILE.test(relative) || TEST_FILE.test(relative) || relative.endsWith(".d.ts"))
|
|
107104
107207
|
continue;
|
|
107105
|
-
if (NOT_SOURCE.test(relative) || !
|
|
107208
|
+
if (NOT_SOURCE.test(relative) || !existsSync29(absolute))
|
|
107106
107209
|
continue;
|
|
107107
107210
|
try {
|
|
107108
107211
|
candidates.push(...mutantsFor(readFileSync30(absolute, "utf8"), relative, lines));
|
|
@@ -107292,7 +107395,7 @@ var exports_test_audit = {};
|
|
|
107292
107395
|
__export(exports_test_audit, {
|
|
107293
107396
|
run: () => run23
|
|
107294
107397
|
});
|
|
107295
|
-
import { existsSync as
|
|
107398
|
+
import { existsSync as existsSync30 } from "node:fs";
|
|
107296
107399
|
import path73 from "node:path";
|
|
107297
107400
|
function parse8(argv) {
|
|
107298
107401
|
const options = {
|
|
@@ -107416,7 +107519,7 @@ usage: ${USAGE16}`));
|
|
|
107416
107519
|
}
|
|
107417
107520
|
let files;
|
|
107418
107521
|
if (options.diff && changed)
|
|
107419
|
-
files = [...changed.keys()].filter((file) => TEST_FILE.test(toPosix(file)) &&
|
|
107522
|
+
files = [...changed.keys()].filter((file) => TEST_FILE.test(toPosix(file)) && existsSync30(file)).toSorted();
|
|
107420
107523
|
else {
|
|
107421
107524
|
const expanded = expandPaths(io.cwd, options.paths);
|
|
107422
107525
|
if (expanded.missing.length > 0)
|