@brainervirus/workit-claude-code 8.43.2 → 8.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/dist/workit-hook.js +74 -74
- package/dist/workit.js +1015 -603
- package/package.json +3 -3
package/dist/workit.js
CHANGED
|
@@ -97,7 +97,7 @@ import os from "node:os";
|
|
|
97
97
|
import path from "node:path";
|
|
98
98
|
var diagnosticLogger, setDiagnosticLogger = (logger) => {
|
|
99
99
|
diagnosticLogger = logger;
|
|
100
|
-
}, getDiagnosticLogger = () => diagnosticLogger, PRESETS, mergePreset = (preset, input = {}, current = {
|
|
100
|
+
}, getDiagnosticLogger = () => diagnosticLogger, UPDATES_MODES, isUpdatesMode = (value) => UPDATES_MODES.includes(value), PRESETS, mergePreset = (preset, input = {}, current = {
|
|
101
101
|
branchPolicy: { preset, allowed: [], protected: [] }
|
|
102
102
|
}) => {
|
|
103
103
|
const defs = PRESETS[preset];
|
|
@@ -137,7 +137,11 @@ var diagnosticLogger, setDiagnosticLogger = (logger) => {
|
|
|
137
137
|
copyFileSync(src, dest);
|
|
138
138
|
} catch (err) {
|
|
139
139
|
migrationFailed = true;
|
|
140
|
-
diagnosticLogger?.warn(EVENT.migration, {
|
|
140
|
+
diagnosticLogger?.warn(EVENT.migration, {
|
|
141
|
+
from: src,
|
|
142
|
+
ok: false,
|
|
143
|
+
...errorDetail(err)
|
|
144
|
+
});
|
|
141
145
|
console.warn(`[workit] config migration: a file could not be copied to ${dir}; it will be retried on the next run`);
|
|
142
146
|
}
|
|
143
147
|
}
|
|
@@ -157,10 +161,18 @@ var diagnosticLogger, setDiagnosticLogger = (logger) => {
|
|
|
157
161
|
try {
|
|
158
162
|
parsed = JSON.parse(raw);
|
|
159
163
|
} catch {
|
|
160
|
-
return {
|
|
164
|
+
return {
|
|
165
|
+
status: "malformed",
|
|
166
|
+
path: file,
|
|
167
|
+
error: `${file} is not valid JSON`
|
|
168
|
+
};
|
|
161
169
|
}
|
|
162
170
|
if (!isConfigObject(parsed)) {
|
|
163
|
-
return {
|
|
171
|
+
return {
|
|
172
|
+
status: "malformed",
|
|
173
|
+
path: file,
|
|
174
|
+
error: `${file} is not a JSON object`
|
|
175
|
+
};
|
|
164
176
|
}
|
|
165
177
|
const input = parsed;
|
|
166
178
|
const locale = LOCALE_RE.test(String(input.locale ?? "")) ? input.locale : DEFAULTS.locale;
|
|
@@ -176,7 +188,8 @@ var diagnosticLogger, setDiagnosticLogger = (logger) => {
|
|
|
176
188
|
commitPolicy: {
|
|
177
189
|
preset: commitPreset,
|
|
178
190
|
...typeof input.commitPolicy?.pattern === "string" ? { pattern: input.commitPolicy.pattern } : {}
|
|
179
|
-
}
|
|
191
|
+
},
|
|
192
|
+
...isUpdatesMode(input.updates) ? { updates: input.updates } : {}
|
|
180
193
|
};
|
|
181
194
|
if (!Object.hasOwn(PRESETS, input.branchPolicy?.preset))
|
|
182
195
|
unchosenBranchPolicy.add(config);
|
|
@@ -224,6 +237,7 @@ var diagnosticLogger, setDiagnosticLogger = (logger) => {
|
|
|
224
237
|
};
|
|
225
238
|
var init_config = __esm(() => {
|
|
226
239
|
init_boundary();
|
|
240
|
+
UPDATES_MODES = ["prompt", "auto", "off"];
|
|
227
241
|
PRESETS = {
|
|
228
242
|
gitflow: {
|
|
229
243
|
allowed: ["feature/*", "bugfix/*", "hotfix/*", "release/*"],
|
|
@@ -9417,7 +9431,7 @@ var package_default;
|
|
|
9417
9431
|
var init_package = __esm(() => {
|
|
9418
9432
|
package_default = {
|
|
9419
9433
|
name: "@brainervirus/workit-cli",
|
|
9420
|
-
version: "8.
|
|
9434
|
+
version: "8.44.0",
|
|
9421
9435
|
private: false,
|
|
9422
9436
|
description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
9423
9437
|
keywords: [
|
|
@@ -9455,13 +9469,13 @@ var init_package = __esm(() => {
|
|
|
9455
9469
|
},
|
|
9456
9470
|
dependencies: {
|
|
9457
9471
|
"@babel/parser": "7.29.9",
|
|
9458
|
-
"@brainervirus/workit-cursor": "^8.
|
|
9472
|
+
"@brainervirus/workit-cursor": "^8.44.0",
|
|
9459
9473
|
"@inkjs/ui": "2.0.0",
|
|
9460
9474
|
ink: "7.1.1",
|
|
9461
9475
|
react: "19.2.8"
|
|
9462
9476
|
},
|
|
9463
9477
|
devDependencies: {
|
|
9464
|
-
"@brainervirus/workit-core": "^8.
|
|
9478
|
+
"@brainervirus/workit-core": "^8.44.0"
|
|
9465
9479
|
},
|
|
9466
9480
|
engines: {
|
|
9467
9481
|
node: ">=24"
|
|
@@ -67459,6 +67473,60 @@ var init_hook_runs = __esm(() => {
|
|
|
67459
67473
|
init_heavy_words();
|
|
67460
67474
|
});
|
|
67461
67475
|
|
|
67476
|
+
// packages/workit-cli/src/update-settings.ts
|
|
67477
|
+
import { mkdirSync as mkdirSync7, readFileSync as readFileSync17, renameSync as renameSync4, writeFileSync as writeFileSync9 } from "node:fs";
|
|
67478
|
+
import os11 from "node:os";
|
|
67479
|
+
import path38 from "node:path";
|
|
67480
|
+
var workitConfigDir = (env) => env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path38.join(env.XDG_CONFIG_HOME || path38.join(env.HOME ?? os11.homedir(), ".config"), "workit"), cacheFile = (env, dir = stateDir(env)) => path38.join(dir, "update-check.json"), readUpdateCache = (env, dir) => {
|
|
67481
|
+
try {
|
|
67482
|
+
const data = JSON.parse(readFileSync17(cacheFile(env, dir), "utf8"));
|
|
67483
|
+
return isConfigObject(data) ? data : {};
|
|
67484
|
+
} catch {
|
|
67485
|
+
return {};
|
|
67486
|
+
}
|
|
67487
|
+
}, writeUpdateCache = (env, cache) => {
|
|
67488
|
+
try {
|
|
67489
|
+
const file = cacheFile(env);
|
|
67490
|
+
mkdirSync7(path38.dirname(file), { recursive: true });
|
|
67491
|
+
const temp = `${file}.${process.pid}.tmp`;
|
|
67492
|
+
writeFileSync9(temp, JSON.stringify(cache) + `
|
|
67493
|
+
`, "utf8");
|
|
67494
|
+
renameSync4(temp, file);
|
|
67495
|
+
} catch {}
|
|
67496
|
+
}, configFile = (env, dir = workitConfigDir(env)) => path38.join(dir, "config.json"), readUpdatesMode = (env, dir) => {
|
|
67497
|
+
try {
|
|
67498
|
+
const data = JSON.parse(readFileSync17(configFile(env, dir), "utf8"));
|
|
67499
|
+
return isConfigObject(data) && isUpdatesMode(data.updates) ? data.updates : "prompt";
|
|
67500
|
+
} catch {
|
|
67501
|
+
return "prompt";
|
|
67502
|
+
}
|
|
67503
|
+
}, writeUpdatesMode = (env, mode) => {
|
|
67504
|
+
const file = configFile(env);
|
|
67505
|
+
let data = {};
|
|
67506
|
+
try {
|
|
67507
|
+
const raw = readFileSync17(file, "utf8");
|
|
67508
|
+
const parsed = JSON.parse(raw);
|
|
67509
|
+
if (!isConfigObject(parsed))
|
|
67510
|
+
return `${file} is not a JSON object`;
|
|
67511
|
+
data = parsed;
|
|
67512
|
+
} catch (error) {
|
|
67513
|
+
if (error.code !== "ENOENT")
|
|
67514
|
+
return `${file} is not valid JSON`;
|
|
67515
|
+
}
|
|
67516
|
+
try {
|
|
67517
|
+
mkdirSync7(path38.dirname(file), { recursive: true });
|
|
67518
|
+
writeFileSync9(file, JSON.stringify({ ...data, updates: mode }, null, 2) + `
|
|
67519
|
+
`, "utf8");
|
|
67520
|
+
return null;
|
|
67521
|
+
} catch (error) {
|
|
67522
|
+
return error instanceof Error ? error.message : `cannot write ${file}`;
|
|
67523
|
+
}
|
|
67524
|
+
};
|
|
67525
|
+
var init_update_settings = __esm(() => {
|
|
67526
|
+
init_heavy_words();
|
|
67527
|
+
init_config();
|
|
67528
|
+
});
|
|
67529
|
+
|
|
67462
67530
|
// packages/workit-core/src/hooks/delivery-verbs.ts
|
|
67463
67531
|
var WORKIT_ALLOWED_VERBS, ALLOWED;
|
|
67464
67532
|
var init_delivery_verbs = __esm(() => {
|
|
@@ -67488,14 +67556,14 @@ import {
|
|
|
67488
67556
|
copyFileSync as copyFileSync4,
|
|
67489
67557
|
existsSync as existsSync16,
|
|
67490
67558
|
readdirSync as readdirSync9,
|
|
67491
|
-
mkdirSync as
|
|
67492
|
-
readFileSync as
|
|
67559
|
+
mkdirSync as mkdirSync8,
|
|
67560
|
+
readFileSync as readFileSync18,
|
|
67493
67561
|
realpathSync as realpathSync8,
|
|
67494
67562
|
rmSync as rmSync3,
|
|
67495
67563
|
statSync as statSync5
|
|
67496
67564
|
} from "node:fs";
|
|
67497
|
-
import
|
|
67498
|
-
import
|
|
67565
|
+
import os12 from "node:os";
|
|
67566
|
+
import path39 from "node:path";
|
|
67499
67567
|
function mergeClaudeSettings(settings, shell, skip = {}) {
|
|
67500
67568
|
const config = clone4(settings);
|
|
67501
67569
|
const owned = emptyOwned();
|
|
@@ -67615,7 +67683,7 @@ function planHostPermissions(options) {
|
|
|
67615
67683
|
plan.blocked.push(`${target.file} is not a JSON object; left untouched`);
|
|
67616
67684
|
continue;
|
|
67617
67685
|
}
|
|
67618
|
-
const shellWanted = host === "claude-code" && options.shell !== false &&
|
|
67686
|
+
const shellWanted = host === "claude-code" && options.shell !== false && path39.basename(paths.env.SHELL ?? "") === "zsh";
|
|
67619
67687
|
const bash = shellWanted ? options.bash === undefined ? findBash(paths.env) : options.bash : null;
|
|
67620
67688
|
const merged = host === "claude-code" ? mergeClaudeSettings(parsed, bash, skip) : mergeCursorCliConfig(parsed, skip);
|
|
67621
67689
|
if (merged.error) {
|
|
@@ -67715,11 +67783,11 @@ function applyHostPermissions(plan, options = {}) {
|
|
|
67715
67783
|
try {
|
|
67716
67784
|
const target = change.before === null ? change.file : realpathSync8(change.file);
|
|
67717
67785
|
if (change.before !== null) {
|
|
67718
|
-
const backups =
|
|
67719
|
-
|
|
67720
|
-
copyFileSync4(target,
|
|
67786
|
+
const backups = path39.join(paths.stateDir, "host-permissions-backup");
|
|
67787
|
+
mkdirSync8(backups, { recursive: true, mode: 448 });
|
|
67788
|
+
copyFileSync4(target, path39.join(backups, `${new Date().toISOString().replaceAll(":", "-")}-${change.host}-${path39.basename(change.file)}`));
|
|
67721
67789
|
}
|
|
67722
|
-
|
|
67790
|
+
mkdirSync8(path39.dirname(target), { recursive: true });
|
|
67723
67791
|
writeFileAtomic(target, change.after);
|
|
67724
67792
|
const previous = record.hosts[change.host];
|
|
67725
67793
|
record.hosts[change.host] = {
|
|
@@ -67782,19 +67850,19 @@ function permissionCoverage(host, commands, options = {}) {
|
|
|
67782
67850
|
const cwd = options.cwd ?? process.cwd();
|
|
67783
67851
|
let missing;
|
|
67784
67852
|
if (host === "codex") {
|
|
67785
|
-
const patterns = codexAllowPatterns(
|
|
67853
|
+
const patterns = codexAllowPatterns(path39.dirname(target.file));
|
|
67786
67854
|
missing = commands.filter((command) => {
|
|
67787
67855
|
const words = command.split(" ");
|
|
67788
67856
|
return !patterns.some((p) => p.every((word, i) => words[i] === word));
|
|
67789
67857
|
});
|
|
67790
67858
|
} else if (host === "cursor") {
|
|
67791
|
-
const rules = [target.file,
|
|
67859
|
+
const rules = [target.file, path39.join(cwd, ".cursor", "cli.json")].flatMap((file) => stringList(valueFrom(readRecord(file), "permissions", "allow")));
|
|
67792
67860
|
missing = commands.filter((command) => !rules.some((rule) => cursorRuleMatches(rule, command)));
|
|
67793
67861
|
} else {
|
|
67794
67862
|
const files = [
|
|
67795
67863
|
target.file,
|
|
67796
|
-
|
|
67797
|
-
|
|
67864
|
+
path39.join(cwd, ".claude", "settings.json"),
|
|
67865
|
+
path39.join(cwd, ".claude", "settings.local.json")
|
|
67798
67866
|
].map(readRecord);
|
|
67799
67867
|
const rules = files.flatMap((file) => stringList(valueFrom(file, "permissions", "allow")));
|
|
67800
67868
|
missing = commands.filter((command) => !rules.some((rule) => claudeRuleMatches(rule, command)));
|
|
@@ -67896,7 +67964,7 @@ ${[...rules, ...lease, grant].join(`
|
|
|
67896
67964
|
};
|
|
67897
67965
|
}, resolvePaths = (options) => {
|
|
67898
67966
|
const env = options.env ?? process.env;
|
|
67899
|
-
const home = options.home ?? env.HOME ??
|
|
67967
|
+
const home = options.home ?? env.HOME ?? os12.homedir();
|
|
67900
67968
|
return {
|
|
67901
67969
|
home,
|
|
67902
67970
|
env,
|
|
@@ -67906,25 +67974,25 @@ ${[...rules, ...lease, grant].join(`
|
|
|
67906
67974
|
const { home, env } = resolvePaths(options);
|
|
67907
67975
|
if (host === "claude-code") {
|
|
67908
67976
|
const dir = claudeConfigDir(home, env);
|
|
67909
|
-
return { file:
|
|
67977
|
+
return { file: path39.join(dir, "settings.json"), hostDir: dir };
|
|
67910
67978
|
}
|
|
67911
67979
|
if (host === "codex") {
|
|
67912
|
-
const dir = env.CODEX_HOME ||
|
|
67913
|
-
return { file:
|
|
67980
|
+
const dir = env.CODEX_HOME || path39.join(home, ".codex");
|
|
67981
|
+
return { file: path39.join(dir, "rules", "workit.rules"), hostDir: dir };
|
|
67914
67982
|
}
|
|
67915
|
-
const dir =
|
|
67916
|
-
return { file:
|
|
67983
|
+
const dir = path39.join(home, ".cursor");
|
|
67984
|
+
return { file: path39.join(dir, "cli-config.json"), hostDir: dir };
|
|
67917
67985
|
}, AGENT_SESSION_VARS, agentSessionVar = (env) => AGENT_SESSION_VARS.find((name) => (env[name] ?? "") !== "") ?? null, RECORD_FILE = "host-permissions.json", readOwnership = (options = {}) => {
|
|
67918
67986
|
const { stateDir } = resolvePaths(options);
|
|
67919
67987
|
try {
|
|
67920
|
-
const value = JSON.parse(
|
|
67988
|
+
const value = JSON.parse(readFileSync18(path39.join(stateDir, RECORD_FILE), "utf8"));
|
|
67921
67989
|
if (isRecord5(value) && isRecord5(value.hosts))
|
|
67922
67990
|
return { version: 1, hosts: value.hosts };
|
|
67923
67991
|
} catch {}
|
|
67924
67992
|
return { version: 1, hosts: {} };
|
|
67925
67993
|
}, writeOwnership = (record, stateDir) => {
|
|
67926
|
-
|
|
67927
|
-
writeFileAtomic(
|
|
67994
|
+
mkdirSync8(stateDir, { recursive: true });
|
|
67995
|
+
writeFileAtomic(path39.join(stateDir, RECORD_FILE), JSON.stringify(record, null, 2) + `
|
|
67928
67996
|
`, 384);
|
|
67929
67997
|
}, unionLists = (a, b) => {
|
|
67930
67998
|
const lists = { ...a };
|
|
@@ -67946,14 +68014,14 @@ ${[...rules, ...lease, grant].join(`
|
|
|
67946
68014
|
writeOwnership(record, paths.stateDir);
|
|
67947
68015
|
}, readText4 = (file) => {
|
|
67948
68016
|
try {
|
|
67949
|
-
return
|
|
68017
|
+
return readFileSync18(file, "utf8");
|
|
67950
68018
|
} catch {
|
|
67951
68019
|
return null;
|
|
67952
68020
|
}
|
|
67953
68021
|
}, findBash = (env) => {
|
|
67954
|
-
const dirs = ["/usr/bin", "/bin", ...(env.PATH ?? "").split(
|
|
68022
|
+
const dirs = ["/usr/bin", "/bin", ...(env.PATH ?? "").split(path39.delimiter).filter(Boolean)];
|
|
67955
68023
|
for (const dir of dirs) {
|
|
67956
|
-
const candidate =
|
|
68024
|
+
const candidate = path39.join(dir, "bash");
|
|
67957
68025
|
try {
|
|
67958
68026
|
if (statSync5(candidate).isFile())
|
|
67959
68027
|
return candidate;
|
|
@@ -67962,7 +68030,7 @@ ${[...rules, ...lease, grant].join(`
|
|
|
67962
68030
|
return null;
|
|
67963
68031
|
}, setupCommand = (hosts) => `workit setup --hosts=${hosts.join(",")}`, removeCodexRules = (file, options = {}) => {
|
|
67964
68032
|
const expected = permissionTarget("codex", options).file;
|
|
67965
|
-
if (
|
|
68033
|
+
if (path39.resolve(file) !== path39.resolve(expected) || !existsSync16(expected))
|
|
67966
68034
|
return false;
|
|
67967
68035
|
rmSync3(expected);
|
|
67968
68036
|
return true;
|
|
@@ -68004,7 +68072,7 @@ ${[...rules, ...lease, grant].join(`
|
|
|
68004
68072
|
return patterns;
|
|
68005
68073
|
}
|
|
68006
68074
|
for (const name of names)
|
|
68007
|
-
for (const m of (readText4(
|
|
68075
|
+
for (const m of (readText4(path39.join(dir, name)) ?? "").matchAll(/pattern\s*=\s*(\[[^\]]*\])\s*,\s*decision\s*=\s*"allow"/gu))
|
|
68008
68076
|
try {
|
|
68009
68077
|
const words = JSON.parse(m[1]);
|
|
68010
68078
|
if (Array.isArray(words))
|
|
@@ -68105,25 +68173,25 @@ import { createHash as createHash14 } from "node:crypto";
|
|
|
68105
68173
|
import {
|
|
68106
68174
|
existsSync as existsSync17,
|
|
68107
68175
|
lstatSync as lstatSync6,
|
|
68108
|
-
mkdirSync as
|
|
68176
|
+
mkdirSync as mkdirSync9,
|
|
68109
68177
|
mkdtempSync,
|
|
68110
68178
|
readdirSync as readdirSync10,
|
|
68111
|
-
readFileSync as
|
|
68179
|
+
readFileSync as readFileSync19,
|
|
68112
68180
|
readlinkSync as readlinkSync2,
|
|
68113
|
-
renameSync as
|
|
68181
|
+
renameSync as renameSync5,
|
|
68114
68182
|
rmSync as rmSync4,
|
|
68115
68183
|
statSync as statSync6,
|
|
68116
68184
|
unlinkSync as unlinkSync3,
|
|
68117
|
-
writeFileSync as
|
|
68185
|
+
writeFileSync as writeFileSync10
|
|
68118
68186
|
} from "node:fs";
|
|
68119
|
-
import
|
|
68120
|
-
import
|
|
68187
|
+
import os13 from "node:os";
|
|
68188
|
+
import path40 from "node:path";
|
|
68121
68189
|
var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
68122
|
-
let dir =
|
|
68190
|
+
let dir = path40.resolve(cwd);
|
|
68123
68191
|
while (true) {
|
|
68124
|
-
if (existsSync17(
|
|
68192
|
+
if (existsSync17(path40.join(dir, "packages", "workit-core", "package.json")))
|
|
68125
68193
|
return dir;
|
|
68126
|
-
const parent =
|
|
68194
|
+
const parent = path40.dirname(dir);
|
|
68127
68195
|
if (parent === dir)
|
|
68128
68196
|
return null;
|
|
68129
68197
|
dir = parent;
|
|
@@ -68148,12 +68216,13 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68148
68216
|
return found;
|
|
68149
68217
|
}, listClaudeProcesses = () => listProcessesMatching((args) => /^(\S*\/)?claude(\s|$)/.test(args)), listCodexProcesses = () => listProcessesMatching((args) => /^(\S*\/)?codex(\.js)?(\s|$)|^(\S*\/)?node(js)?\s+(\S+\s+)*?\S*\/codex(\.js)?(\s|$)/.test(args) && !/\bdaemon\s+pid-update-loop\b/.test(args)), resolve = (options) => {
|
|
68150
68218
|
const env = options.env ?? process.env;
|
|
68151
|
-
const home = options.home ?? env.HOME ??
|
|
68152
|
-
const configDir = options.configDir ?? env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ??
|
|
68153
|
-
const stateDir = options.stateDir ?? env.WORKFLOW_TOOLKIT_STATE ??
|
|
68219
|
+
const home = options.home ?? env.HOME ?? os13.homedir();
|
|
68220
|
+
const configDir = options.configDir ?? env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path40.join(home, ".config", "workit");
|
|
68221
|
+
const stateDir = options.stateDir ?? env.WORKFLOW_TOOLKIT_STATE ?? path40.join(home, ".local", "state", "workit");
|
|
68154
68222
|
const cwd = options.cwd ?? process.cwd();
|
|
68155
68223
|
const dev = options.dev?.trim() || env.WORKFLOW_TOOLKIT_DEV?.trim() || findDevFromCwd(cwd);
|
|
68156
68224
|
return {
|
|
68225
|
+
explicitDirs: { config: options.configDir, state: options.stateDir },
|
|
68157
68226
|
host: options.host ?? "cli",
|
|
68158
68227
|
home,
|
|
68159
68228
|
configDir,
|
|
@@ -68161,11 +68230,11 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68161
68230
|
cwd,
|
|
68162
68231
|
workspaceRoot: options.workspaceRoot ?? env.WORKFLOW_WORKSPACE_ROOT ?? cwd,
|
|
68163
68232
|
dev,
|
|
68164
|
-
opencodeConfig: options.opencodeConfig ??
|
|
68233
|
+
opencodeConfig: options.opencodeConfig ?? path40.join(home, ".config", "opencode", "opencode.json"),
|
|
68165
68234
|
opencodePackageCacheDir: options.opencodePackageCacheDir ?? null,
|
|
68166
|
-
cursorSettings: options.cursorSettings ??
|
|
68167
|
-
cursorMcp: options.cursorMcp ??
|
|
68168
|
-
cursorPluginDir: options.cursorPluginDir ??
|
|
68235
|
+
cursorSettings: options.cursorSettings ?? path40.join(home, ".cursor", "settings.json"),
|
|
68236
|
+
cursorMcp: options.cursorMcp ?? path40.join(home, ".cursor", "mcp.json"),
|
|
68237
|
+
cursorPluginDir: options.cursorPluginDir ?? path40.join(home, ".cursor", "plugins", "local", "workit"),
|
|
68169
68238
|
cursorHeartbeatDir: options.stateDir ?? (env.WORKFLOW_TOOLKIT_STATE || resolveStateDir()),
|
|
68170
68239
|
hookStateDir: options.stateDir ?? (env.WORKFLOW_TOOLKIT_STATE || resolveStateDir()),
|
|
68171
68240
|
codexHome: options.codexHome,
|
|
@@ -68179,14 +68248,14 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68179
68248
|
};
|
|
68180
68249
|
}, readJson = (p) => {
|
|
68181
68250
|
try {
|
|
68182
|
-
const parsed = JSON.parse(
|
|
68251
|
+
const parsed = JSON.parse(readFileSync19(p, "utf8"));
|
|
68183
68252
|
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
68184
68253
|
} catch {
|
|
68185
68254
|
return null;
|
|
68186
68255
|
}
|
|
68187
68256
|
}, parsesAsConfigObject = (p) => {
|
|
68188
68257
|
try {
|
|
68189
|
-
return isConfigObject(JSON.parse(
|
|
68258
|
+
return isConfigObject(JSON.parse(readFileSync19(p, "utf8")));
|
|
68190
68259
|
} catch {
|
|
68191
68260
|
return false;
|
|
68192
68261
|
}
|
|
@@ -68196,12 +68265,12 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68196
68265
|
...new Set(entries.filter((entry) => typeof entry === "string" && isWorkitPlugin(entry)))
|
|
68197
68266
|
];
|
|
68198
68267
|
}, commandOnPath = (name, env) => findOnPath(process.platform === "win32" ? [name, `${name}.exe`] : [name], env) !== null, pathextNames = (name, env) => process.platform === "win32" ? (env.PATHEXT ?? process.env.PATHEXT ?? ".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean).map((ext) => `${name}${ext.toLowerCase()}`) : [name], findOnPath = (names, env) => {
|
|
68199
|
-
const dirs = (env.PATH ?? process.env.PATH ?? "").split(
|
|
68268
|
+
const dirs = (env.PATH ?? process.env.PATH ?? "").split(path40.delimiter);
|
|
68200
68269
|
for (const dir of dirs) {
|
|
68201
68270
|
if (!dir)
|
|
68202
68271
|
continue;
|
|
68203
68272
|
for (const candidateName of names) {
|
|
68204
|
-
const candidate =
|
|
68273
|
+
const candidate = path40.join(dir, candidateName);
|
|
68205
68274
|
try {
|
|
68206
68275
|
const st = statSync6(candidate);
|
|
68207
68276
|
if (process.platform !== "win32" && (st.mode & 73) === 0)
|
|
@@ -68230,7 +68299,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68230
68299
|
if (env.BUN && existsSync17(env.BUN))
|
|
68231
68300
|
return env.BUN;
|
|
68232
68301
|
for (const candidate of [
|
|
68233
|
-
|
|
68302
|
+
path40.join(env.HOME || os13.homedir(), ".bun/bin/bun"),
|
|
68234
68303
|
"/usr/local/bin/bun",
|
|
68235
68304
|
"/usr/bin/bun"
|
|
68236
68305
|
]) {
|
|
@@ -68285,7 +68354,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68285
68354
|
detail: "installed package, not a dev checkout — version parity applies to checkouts only"
|
|
68286
68355
|
};
|
|
68287
68356
|
}
|
|
68288
|
-
const corePkg = readJson(
|
|
68357
|
+
const corePkg = readJson(path40.join(res.dev, "packages/workit-core/package.json"));
|
|
68289
68358
|
if (!corePkg) {
|
|
68290
68359
|
return {
|
|
68291
68360
|
id: "versions",
|
|
@@ -68295,7 +68364,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68295
68364
|
}
|
|
68296
68365
|
const refs = new Set;
|
|
68297
68366
|
for (const name of ["workit-opencode", "workit-cursor", "workit-cli"]) {
|
|
68298
|
-
const pkg = readJson(
|
|
68367
|
+
const pkg = readJson(path40.join(res.dev, "packages", name, "package.json"));
|
|
68299
68368
|
const dep = pkg?.dependencies?.["@brainervirus/workit-core"] ?? pkg?.devDependencies?.["@brainervirus/workit-core"];
|
|
68300
68369
|
if (typeof dep === "string")
|
|
68301
68370
|
refs.add(dep);
|
|
@@ -68311,7 +68380,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68311
68380
|
if (refs.size > 1) {
|
|
68312
68381
|
problems.push(`adapters pin different core versions: ${[...refs].join(", ")}`);
|
|
68313
68382
|
}
|
|
68314
|
-
const opencodePkg = readJson(
|
|
68383
|
+
const opencodePkg = readJson(path40.join(res.dev, "packages/workit-opencode/package.json"));
|
|
68315
68384
|
const sdk = opencodePkg?.dependencies?.["@opencode/plugin"] ?? opencodePkg?.devDependencies?.["@opencode/plugin"];
|
|
68316
68385
|
const sdkVersion = typeof sdk === "string" ? (sdk.match(/^\d+(?:\.\d+){0,2}/) ?? [])[0] : null;
|
|
68317
68386
|
if (sdkVersion && !semverAtLeast(sdkVersion, SUPPORT_MATRIX.opencode.minimum)) {
|
|
@@ -68338,14 +68407,14 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68338
68407
|
status: "pass",
|
|
68339
68408
|
detail: "opencode CLI not on PATH — skipping version check"
|
|
68340
68409
|
};
|
|
68341
|
-
const scratch = mkdtempSync(
|
|
68410
|
+
const scratch = mkdtempSync(path40.join(os13.tmpdir(), "workit-doctor-opencode-"));
|
|
68342
68411
|
let raw;
|
|
68343
68412
|
try {
|
|
68344
68413
|
raw = versionOf("opencode", {
|
|
68345
68414
|
...res.env,
|
|
68346
|
-
XDG_DATA_HOME:
|
|
68347
|
-
XDG_STATE_HOME:
|
|
68348
|
-
XDG_CACHE_HOME:
|
|
68415
|
+
XDG_DATA_HOME: path40.join(scratch, "data"),
|
|
68416
|
+
XDG_STATE_HOME: path40.join(scratch, "state"),
|
|
68417
|
+
XDG_CACHE_HOME: path40.join(scratch, "cache")
|
|
68349
68418
|
}, 5000);
|
|
68350
68419
|
} finally {
|
|
68351
68420
|
rmSync4(scratch, { recursive: true, force: true });
|
|
@@ -68409,7 +68478,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68409
68478
|
const tables = new Map;
|
|
68410
68479
|
let text;
|
|
68411
68480
|
try {
|
|
68412
|
-
text =
|
|
68481
|
+
text = readFileSync19(file, "utf8");
|
|
68413
68482
|
} catch {
|
|
68414
68483
|
return tables;
|
|
68415
68484
|
}
|
|
@@ -68447,19 +68516,19 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68447
68516
|
current[unquote(pair[1])] = value === "true" ? true : value === "false" ? false : unquote(value);
|
|
68448
68517
|
}
|
|
68449
68518
|
return tables;
|
|
68450
|
-
}, codexHomeOf = (res) => res.codexHome ?? (res.env.CODEX_HOME ||
|
|
68519
|
+
}, codexHomeOf = (res) => res.codexHome ?? (res.env.CODEX_HOME || path40.join(res.home, ".codex")), codexWorkitInstalls = (res) => {
|
|
68451
68520
|
const codexHome = codexHomeOf(res);
|
|
68452
|
-
const configFile =
|
|
68521
|
+
const configFile = path40.join(codexHome, "config.toml");
|
|
68453
68522
|
const installs = [];
|
|
68454
68523
|
for (const [key, table] of readTomlTables(configFile)) {
|
|
68455
68524
|
const [kind, id, ...rest] = key.split("\x00");
|
|
68456
68525
|
if (kind !== "plugins" || rest.length > 0 || !id?.startsWith("workit@") || table.enabled === false)
|
|
68457
68526
|
continue;
|
|
68458
68527
|
const marketplace = id.slice("workit@".length);
|
|
68459
|
-
const dir =
|
|
68528
|
+
const dir = path40.join(codexHome, "plugins", "cache", marketplace, "workit");
|
|
68460
68529
|
let versions = [];
|
|
68461
68530
|
try {
|
|
68462
|
-
versions = readdirSync10(dir).filter((v) => existsSync17(
|
|
68531
|
+
versions = readdirSync10(dir).filter((v) => existsSync17(path40.join(dir, v, ".codex-plugin")));
|
|
68463
68532
|
} catch {
|
|
68464
68533
|
versions = [];
|
|
68465
68534
|
}
|
|
@@ -68467,7 +68536,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68467
68536
|
installs.push({
|
|
68468
68537
|
id,
|
|
68469
68538
|
marketplace,
|
|
68470
|
-
root: version ?
|
|
68539
|
+
root: version ? path40.join(dir, version) : null,
|
|
68471
68540
|
version,
|
|
68472
68541
|
configFile
|
|
68473
68542
|
});
|
|
@@ -68489,7 +68558,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68489
68558
|
};
|
|
68490
68559
|
return `sha256:${createHash14("sha256").update(JSON.stringify(body)).digest("hex")}`;
|
|
68491
68560
|
}, codexHookTrust = (install, tables) => {
|
|
68492
|
-
const hooks = install.root ? readJson(
|
|
68561
|
+
const hooks = install.root ? readJson(path40.join(install.root, "hooks", "hooks.json"))?.hooks : null;
|
|
68493
68562
|
if (!hooks || typeof hooks !== "object")
|
|
68494
68563
|
return null;
|
|
68495
68564
|
const result = [];
|
|
@@ -68562,25 +68631,25 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68562
68631
|
status: "pass",
|
|
68563
68632
|
detail: "no Workit Codex plugin enabled — skipping"
|
|
68564
68633
|
};
|
|
68565
|
-
const agentsDir =
|
|
68634
|
+
const agentsDir = path40.join(codexHomeOf(res), "agents");
|
|
68566
68635
|
const problems = [];
|
|
68567
68636
|
const fixes = [];
|
|
68568
68637
|
const installed = [];
|
|
68569
68638
|
for (const install of installs) {
|
|
68570
|
-
const source = install.root ?
|
|
68639
|
+
const source = install.root ? path40.join(install.root, "agents") : null;
|
|
68571
68640
|
const files = source && existsSync17(source) ? readdirSync10(source).filter((f) => f.endsWith(".toml")).toSorted() : [];
|
|
68572
68641
|
if (files.length === 0) {
|
|
68573
68642
|
problems.push(`${install.id} ${install.version ?? "?"} bundles no agents`);
|
|
68574
68643
|
fixes.push(`codex plugin remove ${install.id} && codex plugin add ${install.id}`);
|
|
68575
68644
|
continue;
|
|
68576
68645
|
}
|
|
68577
|
-
const install_fix = `node ${JSON.stringify(
|
|
68578
|
-
const pluginVersion = readJson(
|
|
68646
|
+
const install_fix = `node ${JSON.stringify(path40.join(install.root, "dist", "launch-mcp.js"))} --install-agents, then start a new Codex session`;
|
|
68647
|
+
const pluginVersion = readJson(path40.join(install.root, "package.json"))?.version;
|
|
68579
68648
|
const version = typeof pluginVersion === "string" ? pluginVersion.match(SEMVER)?.[0] ?? null : null;
|
|
68580
68649
|
let stale = false;
|
|
68581
68650
|
for (const file of files) {
|
|
68582
|
-
const dest =
|
|
68583
|
-
const want = stampCodexAgent(
|
|
68651
|
+
const dest = path40.join(agentsDir, file);
|
|
68652
|
+
const want = stampCodexAgent(readFileSync19(path40.join(source, file), "utf8"), version);
|
|
68584
68653
|
let link = false;
|
|
68585
68654
|
try {
|
|
68586
68655
|
link = lstatSync6(dest).isSymbolicLink();
|
|
@@ -68594,7 +68663,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68594
68663
|
}
|
|
68595
68664
|
let have = null;
|
|
68596
68665
|
try {
|
|
68597
|
-
have =
|
|
68666
|
+
have = readFileSync19(dest, "utf8");
|
|
68598
68667
|
} catch {
|
|
68599
68668
|
have = null;
|
|
68600
68669
|
}
|
|
@@ -68633,7 +68702,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68633
68702
|
const env = res.env.PI_CODING_AGENT_DIR;
|
|
68634
68703
|
if (env)
|
|
68635
68704
|
return env === "~" ? res.home : env.replace(/^~(?=\/|\\)/, res.home);
|
|
68636
|
-
return
|
|
68705
|
+
return path40.join(res.home, ".pi", "agent");
|
|
68637
68706
|
}, npmSpecName = (spec) => {
|
|
68638
68707
|
const at = spec.indexOf("@", spec.startsWith("@") ? 1 : 0);
|
|
68639
68708
|
return at > 0 ? { name: spec.slice(0, at), pinned: true } : { name: spec, pinned: false };
|
|
@@ -68641,12 +68710,12 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68641
68710
|
const scopes = [
|
|
68642
68711
|
{
|
|
68643
68712
|
scope: "project",
|
|
68644
|
-
settingsFile:
|
|
68645
|
-
base:
|
|
68713
|
+
settingsFile: path40.join(res.cwd, ".pi", "settings.json"),
|
|
68714
|
+
base: path40.join(res.cwd, ".pi")
|
|
68646
68715
|
},
|
|
68647
68716
|
{
|
|
68648
68717
|
scope: "user",
|
|
68649
|
-
settingsFile:
|
|
68718
|
+
settingsFile: path40.join(agentDir, "settings.json"),
|
|
68650
68719
|
base: agentDir
|
|
68651
68720
|
}
|
|
68652
68721
|
];
|
|
@@ -68663,7 +68732,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68663
68732
|
const spec = npmSpecName(source.slice(4).trim());
|
|
68664
68733
|
if (spec.name !== PI_PACKAGE)
|
|
68665
68734
|
continue;
|
|
68666
|
-
const root =
|
|
68735
|
+
const root = path40.join(base, "npm", "node_modules", ...PI_PACKAGE.split("/"));
|
|
68667
68736
|
return {
|
|
68668
68737
|
scope,
|
|
68669
68738
|
settingsFile,
|
|
@@ -68675,8 +68744,8 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68675
68744
|
}
|
|
68676
68745
|
if (/^(git:|https?:|ssh:|git@)/.test(source))
|
|
68677
68746
|
continue;
|
|
68678
|
-
const local =
|
|
68679
|
-
if (readJson(
|
|
68747
|
+
const local = path40.resolve(base, source.replace(/^~(?=\/|\\)/, res.home));
|
|
68748
|
+
if (readJson(path40.join(local, "package.json"))?.name === PI_PACKAGE)
|
|
68680
68749
|
return { scope, settingsFile, source, filter, root: local, npm: null };
|
|
68681
68750
|
}
|
|
68682
68751
|
}
|
|
@@ -68687,7 +68756,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68687
68756
|
const list = patterns.filter((p) => typeof p === "string");
|
|
68688
68757
|
if (list.length === 0)
|
|
68689
68758
|
return false;
|
|
68690
|
-
const name =
|
|
68759
|
+
const name = path40.posix.basename(file);
|
|
68691
68760
|
const matches = (p) => {
|
|
68692
68761
|
const re = globToRegExp3(p);
|
|
68693
68762
|
return re.test(file) || re.test(name);
|
|
@@ -68716,12 +68785,12 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68716
68785
|
return {
|
|
68717
68786
|
id: "pi_extension",
|
|
68718
68787
|
status: "warn",
|
|
68719
|
-
detail: `Workit Pi extension missing: no ${PI_PACKAGE} entry in ${
|
|
68788
|
+
detail: `Workit Pi extension missing: no ${PI_PACKAGE} entry in ${path40.join(agentDir, "settings.json")} or ${path40.join(res.cwd, ".pi", "settings.json")}`,
|
|
68720
68789
|
fix: installCmd("user")
|
|
68721
68790
|
};
|
|
68722
68791
|
const where = `${entry.source} (${entry.scope}, ${entry.settingsFile})`;
|
|
68723
68792
|
const rebuild = `cd ${JSON.stringify(entry.root)} && bun run build`;
|
|
68724
|
-
const pkg = readJson(
|
|
68793
|
+
const pkg = readJson(path40.join(entry.root, "package.json"));
|
|
68725
68794
|
if (!pkg)
|
|
68726
68795
|
return {
|
|
68727
68796
|
id: "pi_extension",
|
|
@@ -68730,7 +68799,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68730
68799
|
fix: entry.npm ? installCmd(entry.scope, entry.source) : `restore ${entry.root}, then ${rebuild}`
|
|
68731
68800
|
};
|
|
68732
68801
|
const declared = Array.isArray(pkg.pi?.extensions) ? pkg.pi.extensions.some((e) => typeof e === "string" && e.replace(/^\.\//, "") === PI_EXTENSION) : false;
|
|
68733
|
-
if (!declared || !existsSync17(
|
|
68802
|
+
if (!declared || !existsSync17(path40.join(entry.root, PI_EXTENSION)))
|
|
68734
68803
|
return {
|
|
68735
68804
|
id: "pi_extension",
|
|
68736
68805
|
status: "warn",
|
|
@@ -68783,21 +68852,21 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68783
68852
|
detail: `Workit Pi extension ${version ?? "?"} from ${where} loads ${PI_EXTENSION}`
|
|
68784
68853
|
};
|
|
68785
68854
|
}, assetPathsFor = (host, dev) => {
|
|
68786
|
-
const pkg =
|
|
68855
|
+
const pkg = path40.join(dev, "packages", `workit-${host}`);
|
|
68787
68856
|
switch (host) {
|
|
68788
68857
|
case "opencode": {
|
|
68789
|
-
const packaged =
|
|
68790
|
-
const root = existsSync17(packaged) ? packaged :
|
|
68791
|
-
return WORKIT_METHOD_SKILLS.map((skill) =>
|
|
68858
|
+
const packaged = path40.join(pkg, "assets", "skills");
|
|
68859
|
+
const root = existsSync17(packaged) ? packaged : path40.join(dev, "packages", "workit-core", "skills");
|
|
68860
|
+
return WORKIT_METHOD_SKILLS.map((skill) => path40.join(root, skill, "SKILL.md"));
|
|
68792
68861
|
}
|
|
68793
68862
|
case "cursor":
|
|
68794
68863
|
return [
|
|
68795
|
-
|
|
68796
|
-
|
|
68797
|
-
|
|
68864
|
+
path40.join(pkg, "assets", "templates", "workit-contract.md"),
|
|
68865
|
+
path40.join(pkg, "mcp.json"),
|
|
68866
|
+
path40.join(pkg, ".cursor-plugin")
|
|
68798
68867
|
];
|
|
68799
68868
|
case "cli":
|
|
68800
|
-
return [
|
|
68869
|
+
return [path40.join(pkg, "assets", "templates", "spec-template.md")];
|
|
68801
68870
|
}
|
|
68802
68871
|
}, hostsFor = (host) => host === "cli" ? ["opencode", "cursor", "cli"] : [host], checkAssets = (res) => {
|
|
68803
68872
|
const dev = res.dev;
|
|
@@ -68828,22 +68897,22 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68828
68897
|
fix: "Reinstall or rebuild the workit package (missing assets under packages/workit-<host>)"
|
|
68829
68898
|
};
|
|
68830
68899
|
}, launcherSlotsFor = (host, dev) => {
|
|
68831
|
-
const pkg =
|
|
68900
|
+
const pkg = path40.join(dev, "packages", `workit-${host}`);
|
|
68832
68901
|
switch (host) {
|
|
68833
68902
|
case "opencode":
|
|
68834
|
-
return [[
|
|
68903
|
+
return [[path40.join(pkg, "src", "plugin.ts"), path40.join(pkg, "dist", "plugin.js")]];
|
|
68835
68904
|
case "cursor":
|
|
68836
68905
|
return [
|
|
68837
|
-
[
|
|
68838
|
-
[
|
|
68906
|
+
[path40.join(pkg, "dist", "mcp-server.js")],
|
|
68907
|
+
[path40.join(pkg, "dist", "cursor-session-start.js")]
|
|
68839
68908
|
];
|
|
68840
68909
|
case "cli":
|
|
68841
|
-
return [[
|
|
68910
|
+
return [[path40.join(pkg, "src", "index.tsx"), path40.join(pkg, "dist", "index.js")]];
|
|
68842
68911
|
}
|
|
68843
68912
|
}, validNodeEntry = (entry, runtime, env) => {
|
|
68844
68913
|
try {
|
|
68845
68914
|
const stat = statSync6(entry);
|
|
68846
|
-
if (!stat.isFile() || stat.size === 0 || !
|
|
68915
|
+
if (!stat.isFile() || stat.size === 0 || !readFileSync19(entry, "utf8").startsWith(`#!/usr/bin/env node
|
|
68847
68916
|
`)) {
|
|
68848
68917
|
return false;
|
|
68849
68918
|
}
|
|
@@ -68865,7 +68934,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68865
68934
|
if (typeof command !== "string" || !Array.isArray(args) || typeof args[0] !== "string") {
|
|
68866
68935
|
return "invalid";
|
|
68867
68936
|
}
|
|
68868
|
-
const executable =
|
|
68937
|
+
const executable = path40.basename(command).toLowerCase();
|
|
68869
68938
|
const canonical = cursorMcpServerEntry("").args;
|
|
68870
68939
|
if (executable === "npx" || executable === "npx.exe" || executable === "npx.cmd") {
|
|
68871
68940
|
if (args.length !== canonical.length || args.some((a, i) => a !== canonical[i]))
|
|
@@ -68877,10 +68946,10 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68877
68946
|
return {
|
|
68878
68947
|
kind: "node",
|
|
68879
68948
|
runtime: command,
|
|
68880
|
-
entry:
|
|
68949
|
+
entry: path40.isAbsolute(args[0]) ? args[0] : path40.resolve(path40.dirname(res.cursorMcp), args[0])
|
|
68881
68950
|
};
|
|
68882
68951
|
}, canonicalCursorHook, isCanonicalCursorHook = (command, res) => command === canonicalCursorHook || command === cursorHooksEntry(res.cursorPluginDir).command, registeredCursorHook = (res) => {
|
|
68883
|
-
const hooksFile =
|
|
68952
|
+
const hooksFile = path40.join(res.cursorPluginDir, "hooks", "hooks-cursor.json");
|
|
68884
68953
|
if (!existsSync17(hooksFile))
|
|
68885
68954
|
return "invalid";
|
|
68886
68955
|
const config = readJson(hooksFile);
|
|
@@ -68898,9 +68967,9 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68898
68967
|
if (!m)
|
|
68899
68968
|
return false;
|
|
68900
68969
|
const entry = m[1].trim();
|
|
68901
|
-
if (!
|
|
68970
|
+
if (!path40.isAbsolute(entry))
|
|
68902
68971
|
return false;
|
|
68903
|
-
if (
|
|
68972
|
+
if (path40.resolve(entry) !== path40.resolve(path40.join(res.cursorPluginDir, "dist", "cursor-session-start.js"))) {
|
|
68904
68973
|
return false;
|
|
68905
68974
|
}
|
|
68906
68975
|
return validNodeEntry(entry, "node", res.env);
|
|
@@ -68909,7 +68978,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68909
68978
|
const hosts = hostsFor(res.host);
|
|
68910
68979
|
const registered = hosts.includes("cursor") ? registeredCursorLauncher(res) : null;
|
|
68911
68980
|
const runtime = registered && registered !== "invalid" && registered.kind === "node" ? registered.runtime : "node";
|
|
68912
|
-
const missing = hosts.includes("cursor") ? ["dist/mcp-server.js", "dist/cursor-session-start.js"].map((rel) =>
|
|
68981
|
+
const missing = hosts.includes("cursor") ? ["dist/mcp-server.js", "dist/cursor-session-start.js"].map((rel) => path40.join(res.cursorPluginDir, rel)).filter((p) => !validNodeEntry(p, runtime, res.env)).map((p) => `cursor: ${p}`) : [];
|
|
68913
68982
|
if (hosts.includes("cursor")) {
|
|
68914
68983
|
if (registered === "invalid") {
|
|
68915
68984
|
missing.push(`cursor: canonical workit MCP launcher in ${res.cursorMcp}`);
|
|
@@ -68918,9 +68987,9 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68918
68987
|
}
|
|
68919
68988
|
const hook = registeredCursorHook(res);
|
|
68920
68989
|
if (hook === "invalid") {
|
|
68921
|
-
missing.push(`cursor: canonical session-start hook in ${
|
|
68990
|
+
missing.push(`cursor: canonical session-start hook in ${path40.join(res.cursorPluginDir, "hooks", "hooks-cursor.json")}`);
|
|
68922
68991
|
} else if (hook !== null && !isCanonicalCursorHook(hook, res) && !validLocalDistHook(hook, res)) {
|
|
68923
|
-
missing.push(`cursor: canonical session-start hook in ${
|
|
68992
|
+
missing.push(`cursor: canonical session-start hook in ${path40.join(res.cursorPluginDir, "hooks", "hooks-cursor.json")} (registered ${hook})`);
|
|
68924
68993
|
}
|
|
68925
68994
|
}
|
|
68926
68995
|
if (dev) {
|
|
@@ -68956,7 +69025,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
68956
69025
|
const normal = entry.replaceAll("\\", "/").replace(/\/+$/, "");
|
|
68957
69026
|
if (!normal.endsWith("local/workit") && !normal.endsWith("local/workflow-toolkit"))
|
|
68958
69027
|
continue;
|
|
68959
|
-
const dir = entry.startsWith("~") ?
|
|
69028
|
+
const dir = entry.startsWith("~") ? path40.join(res.home, entry.slice(1)) : entry;
|
|
68960
69029
|
let state = null;
|
|
68961
69030
|
try {
|
|
68962
69031
|
state = readdirSync10(dir).length === 0 ? "empty" : null;
|
|
@@ -69000,7 +69069,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69000
69069
|
status: "pass",
|
|
69001
69070
|
detail: "no Cursor plugin install — hook launcher not inspected"
|
|
69002
69071
|
};
|
|
69003
|
-
const launcher =
|
|
69072
|
+
const launcher = path40.join(res.cursorPluginDir, "hooks", "launch.mjs");
|
|
69004
69073
|
if (!existsSync17(launcher))
|
|
69005
69074
|
return {
|
|
69006
69075
|
id: "cursor_hook",
|
|
@@ -69008,7 +69077,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69008
69077
|
detail: `cursor hook launcher mode: missing — ${launcher} is absent (an install from before the pinned launcher)`,
|
|
69009
69078
|
fix: CURSOR_HOOK_FIX
|
|
69010
69079
|
};
|
|
69011
|
-
const hooksFile =
|
|
69080
|
+
const hooksFile = path40.join(res.cursorPluginDir, "hooks", "hooks-cursor.json");
|
|
69012
69081
|
const registered = readJson(hooksFile);
|
|
69013
69082
|
const sessionCommand = registered?.hooks?.sessionStart?.[0]?.command;
|
|
69014
69083
|
const offLauncher = [
|
|
@@ -69079,10 +69148,10 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69079
69148
|
return null;
|
|
69080
69149
|
}
|
|
69081
69150
|
}, silentCursorHooks = (res) => {
|
|
69082
|
-
const session = mtimeMs(
|
|
69151
|
+
const session = mtimeMs(path40.join(res.cursorHeartbeatDir, "cursor-session-last-start"));
|
|
69083
69152
|
if (session === null || Date.now() - session < SILENT_HOOK_GRACE_MS)
|
|
69084
69153
|
return null;
|
|
69085
|
-
const hook = mtimeMs(
|
|
69154
|
+
const hook = mtimeMs(path40.join(res.cursorHeartbeatDir, "cursor-hook-last-run"));
|
|
69086
69155
|
if (hook !== null && hook >= session)
|
|
69087
69156
|
return null;
|
|
69088
69157
|
return `Cursor started the Workit MCP server at ${new Date(session).toISOString()} but no Workit hook has run since${hook === null ? " (none ever)" : ""} — if the agent ran in that window, Cursor is not running the plugin hooks and Workit enforcement is off`;
|
|
@@ -69186,7 +69255,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69186
69255
|
}
|
|
69187
69256
|
return { id: "stale_pin", status: "pass", detail: "opencode pin resolves" };
|
|
69188
69257
|
}, pluginMcpSelectors = (res) => {
|
|
69189
|
-
const p =
|
|
69258
|
+
const p = path40.join(res.cursorPluginDir, "mcp.json");
|
|
69190
69259
|
if (!existsSync17(p))
|
|
69191
69260
|
return null;
|
|
69192
69261
|
const cfg = readJson(p);
|
|
@@ -69220,19 +69289,19 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69220
69289
|
return null;
|
|
69221
69290
|
}
|
|
69222
69291
|
}, installedPluginVersion = (res) => {
|
|
69223
|
-
const pkg = readJson(
|
|
69292
|
+
const pkg = readJson(path40.join(res.cursorPluginDir, "package.json"));
|
|
69224
69293
|
return typeof pkg?.version === "string" && pkg.version ? pkg.version : null;
|
|
69225
69294
|
}, installedOpenCodeCache = (res) => {
|
|
69226
69295
|
if (res.opencodePackageCacheDir !== null) {
|
|
69227
|
-
const pkg = readJson(
|
|
69296
|
+
const pkg = readJson(path40.join(res.opencodePackageCacheDir, "node_modules", "@brainervirus", "workit-opencode", "package.json"));
|
|
69228
69297
|
return typeof pkg?.version === "string" && pkg.version ? { version: pkg.version, dir: res.opencodePackageCacheDir } : null;
|
|
69229
69298
|
}
|
|
69230
69299
|
const found = openCodeInstalledPlugin(res.home, res.env);
|
|
69231
69300
|
if (!found)
|
|
69232
69301
|
return null;
|
|
69233
|
-
let dir =
|
|
69234
|
-
if (
|
|
69235
|
-
dir =
|
|
69302
|
+
let dir = path40.dirname(path40.dirname(path40.dirname(found.root)));
|
|
69303
|
+
if (path40.basename(dir) !== "workit-opencode@latest")
|
|
69304
|
+
dir = path40.dirname(dir);
|
|
69236
69305
|
return { version: found.version, dir };
|
|
69237
69306
|
}, checkOpenCodePackageCache = (res) => {
|
|
69238
69307
|
if (!existsSync17(res.opencodeConfig)) {
|
|
@@ -69336,7 +69405,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69336
69405
|
fix: "Re-run install-cursor-plugin.sh — it rewrites the workit MCP entry to the canonical @latest selector"
|
|
69337
69406
|
};
|
|
69338
69407
|
}
|
|
69339
|
-
const hooksFile =
|
|
69408
|
+
const hooksFile = path40.join(res.cursorPluginDir, "hooks", "hooks-cursor.json");
|
|
69340
69409
|
const hookCmd = readJson(hooksFile)?.hooks?.sessionStart?.[0]?.command ?? null;
|
|
69341
69410
|
const canonicalHook = canonicalCursorHook;
|
|
69342
69411
|
const staleHook = hookCmd !== null && !isCanonicalCursorHook(hookCmd, res) && !hookCmd.startsWith("node ") && hookCmd.includes("@brainervirus/workit-cursor@");
|
|
@@ -69358,7 +69427,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69358
69427
|
};
|
|
69359
69428
|
}
|
|
69360
69429
|
const installed = installedPluginVersion(res);
|
|
69361
|
-
const source = res.dev ? readJson(
|
|
69430
|
+
const source = res.dev ? readJson(path40.join(res.dev, "packages/workit-cursor/package.json"))?.version ?? null : readJson(path40.join(packageRoot(), "package.json"))?.version ?? null;
|
|
69362
69431
|
const localDist = mcpSelectors === null && hookCmd !== null && !isCanonicalCursorHook(hookCmd, res) && hookCmd.startsWith("node ");
|
|
69363
69432
|
if (localDist && installed !== null && source !== null && !semverAtLeast(installed, source)) {
|
|
69364
69433
|
return {
|
|
@@ -69370,7 +69439,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69370
69439
|
}
|
|
69371
69440
|
if (localDist && installed !== null && source !== null && res.dev) {
|
|
69372
69441
|
const entry = /^node\s+(.+)$/.exec((hookCmd ?? "").trim())?.[1]?.trim() ?? "";
|
|
69373
|
-
const sourceBundle = entry &&
|
|
69442
|
+
const sourceBundle = entry && path40.isAbsolute(entry) ? path40.join(res.dev, "packages", "workit-cursor", "dist", path40.basename(entry)) : "";
|
|
69374
69443
|
if (entry && sourceBundle) {
|
|
69375
69444
|
const installedHash = bundleHashOfFile(entry);
|
|
69376
69445
|
const sourceHash = bundleHashOfFile(sourceBundle);
|
|
@@ -69378,7 +69447,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69378
69447
|
return {
|
|
69379
69448
|
id: "stale_install",
|
|
69380
69449
|
status: "fail",
|
|
69381
|
-
detail: `stale_install: installed workit-cursor ${installed} runs different bytes than the current runtime build (${
|
|
69450
|
+
detail: `stale_install: installed workit-cursor ${installed} runs different bytes than the current runtime build (${path40.basename(entry)} hash mismatch)`,
|
|
69382
69451
|
fix: "Re-run install-cursor-plugin.sh — it refreshes the plugin directory with the current build"
|
|
69383
69452
|
};
|
|
69384
69453
|
}
|
|
@@ -69478,7 +69547,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69478
69547
|
}, checkMalformedConfig = (res) => {
|
|
69479
69548
|
const files = [];
|
|
69480
69549
|
for (const name of ["config.json", "youtrack.json", "vcs.json", "workspaces.json"]) {
|
|
69481
|
-
const p =
|
|
69550
|
+
const p = path40.join(res.configDir, name);
|
|
69482
69551
|
if (existsSync17(p))
|
|
69483
69552
|
files.push(p);
|
|
69484
69553
|
}
|
|
@@ -69699,17 +69768,17 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69699
69768
|
return { ...installSessionHook(res.cwd, res.env), workspace: workspace.name };
|
|
69700
69769
|
}, isPlaceholder = (p) => {
|
|
69701
69770
|
try {
|
|
69702
|
-
return
|
|
69771
|
+
return readFileSync19(p, "utf8").trim() === TOKEN_PLACEHOLDER2;
|
|
69703
69772
|
} catch {
|
|
69704
69773
|
return false;
|
|
69705
69774
|
}
|
|
69706
69775
|
}, checkCredentialMetadata = (res) => {
|
|
69707
69776
|
const tokenPaths = [];
|
|
69708
|
-
const youtrackJson = readJson(
|
|
69777
|
+
const youtrackJson = readJson(path40.join(res.configDir, "youtrack.json"));
|
|
69709
69778
|
if (youtrackJson) {
|
|
69710
|
-
tokenPaths.push(typeof youtrackJson.tokenFile === "string" ? youtrackJson.tokenFile :
|
|
69711
|
-
} else if (existsSync17(
|
|
69712
|
-
tokenPaths.push(
|
|
69779
|
+
tokenPaths.push(typeof youtrackJson.tokenFile === "string" ? youtrackJson.tokenFile : path40.join(res.configDir, "youtrack.token"));
|
|
69780
|
+
} else if (existsSync17(path40.join(res.configDir, "youtrack.token"))) {
|
|
69781
|
+
tokenPaths.push(path40.join(res.configDir, "youtrack.token"));
|
|
69713
69782
|
}
|
|
69714
69783
|
if (tokenPaths.length === 0) {
|
|
69715
69784
|
return {
|
|
@@ -69720,7 +69789,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69720
69789
|
}
|
|
69721
69790
|
const problems = [];
|
|
69722
69791
|
for (const raw of tokenPaths) {
|
|
69723
|
-
const p =
|
|
69792
|
+
const p = path40.isAbsolute(raw) ? raw : path40.resolve(res.configDir, raw);
|
|
69724
69793
|
if (!existsSync17(p)) {
|
|
69725
69794
|
problems.push(`${p} is missing`);
|
|
69726
69795
|
continue;
|
|
@@ -69843,7 +69912,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69843
69912
|
status: "pass",
|
|
69844
69913
|
detail: "no GitHub remote configured"
|
|
69845
69914
|
};
|
|
69846
|
-
const vcsJson = readJson(res.env.WORKFLOW_VCS_CONFIG ??
|
|
69915
|
+
const vcsJson = readJson(res.env.WORKFLOW_VCS_CONFIG ?? path40.join(res.configDir, "vcs.json"));
|
|
69847
69916
|
const workspace = workspaceProviderForIdentity(res.cwd, res.configDir, res.env);
|
|
69848
69917
|
if (workspace.error)
|
|
69849
69918
|
return {
|
|
@@ -69879,7 +69948,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69879
69948
|
status: "pass",
|
|
69880
69949
|
detail: "no GitLab remote configured"
|
|
69881
69950
|
};
|
|
69882
|
-
const vcsJson = readJson(res.env.WORKFLOW_VCS_CONFIG ??
|
|
69951
|
+
const vcsJson = readJson(res.env.WORKFLOW_VCS_CONFIG ?? path40.join(res.configDir, "vcs.json"));
|
|
69883
69952
|
const workspace = workspaceProviderForIdentity(res.cwd, res.configDir, res.env);
|
|
69884
69953
|
if (workspace.error)
|
|
69885
69954
|
return {
|
|
@@ -69909,11 +69978,11 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69909
69978
|
{ surface: "SSH", login: probes.sshLogin(remoteHost) }
|
|
69910
69979
|
]);
|
|
69911
69980
|
}, checkLogWritable = (res) => {
|
|
69912
|
-
const logsDir =
|
|
69913
|
-
const probe =
|
|
69981
|
+
const logsDir = path40.join(res.stateDir, "logs");
|
|
69982
|
+
const probe = path40.join(logsDir, "doctor-probe.tmp");
|
|
69914
69983
|
try {
|
|
69915
|
-
|
|
69916
|
-
|
|
69984
|
+
mkdirSync9(logsDir, { recursive: true, mode: 448 });
|
|
69985
|
+
writeFileSync10(probe, `{"probe":true}
|
|
69917
69986
|
`, { mode: 384 });
|
|
69918
69987
|
return {
|
|
69919
69988
|
id: "log_writable",
|
|
@@ -69992,7 +70061,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
69992
70061
|
const counts = { skip: 0, late: 0 };
|
|
69993
70062
|
let text = "";
|
|
69994
70063
|
try {
|
|
69995
|
-
text =
|
|
70064
|
+
text = readFileSync19(path40.join(stateDir, HOOK_SKIPS_FILE), "utf8");
|
|
69996
70065
|
} catch {
|
|
69997
70066
|
return counts;
|
|
69998
70067
|
}
|
|
@@ -70010,7 +70079,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
70010
70079
|
}
|
|
70011
70080
|
return counts;
|
|
70012
70081
|
}, checkHookDeadline = (res) => {
|
|
70013
|
-
const file =
|
|
70082
|
+
const file = path40.join(res.hookStateDir, HOOK_SKIPS_FILE);
|
|
70014
70083
|
const { skip, late } = countHookSkips(res.hookStateDir, Date.now() - DAY_MS);
|
|
70015
70084
|
const lateText = late > 0 ? `; ${late} answered past it in full` : "";
|
|
70016
70085
|
if (skip > 0)
|
|
@@ -70048,8 +70117,8 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
70048
70117
|
};
|
|
70049
70118
|
}, checkChecksConfig = (res) => {
|
|
70050
70119
|
const root = checkRoot(res.cwd);
|
|
70051
|
-
const current = existsSync17(
|
|
70052
|
-
const legacy = existsSync17(
|
|
70120
|
+
const current = existsSync17(path40.join(root, CHECKS_FILE));
|
|
70121
|
+
const legacy = existsSync17(path40.join(root, LEGACY_CHECKS_FILE));
|
|
70053
70122
|
if (!legacy)
|
|
70054
70123
|
return {
|
|
70055
70124
|
id: "checks_config",
|
|
@@ -70064,8 +70133,8 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
70064
70133
|
};
|
|
70065
70134
|
}, fixChecksConfig = (options = {}) => {
|
|
70066
70135
|
const root = checkRoot(resolve(options).cwd);
|
|
70067
|
-
const from =
|
|
70068
|
-
const to =
|
|
70136
|
+
const from = path40.join(root, LEGACY_CHECKS_FILE);
|
|
70137
|
+
const to = path40.join(root, CHECKS_FILE);
|
|
70069
70138
|
if (!existsSync17(from))
|
|
70070
70139
|
return { action: "none", detail: `no ${LEGACY_CHECKS_FILE} at ${root}` };
|
|
70071
70140
|
if (existsSync17(to))
|
|
@@ -70074,7 +70143,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
70074
70143
|
detail: `${CHECKS_FILE} already exists; ${LEGACY_CHECKS_FILE} left in place`
|
|
70075
70144
|
};
|
|
70076
70145
|
ensureWorkitDir(root);
|
|
70077
|
-
|
|
70146
|
+
renameSync5(from, to);
|
|
70078
70147
|
return { action: "moved", detail: `${LEGACY_CHECKS_FILE} -> ${CHECKS_FILE}` };
|
|
70079
70148
|
}, CLAUDE_PLUGIN_PACKAGE = "@brainervirus/workit-claude-code", versionBehind = (version, latest) => version !== latest && semverAtLeast(latest, version), checkClaudePlugin = (res) => {
|
|
70080
70149
|
const installs = claudeWorkitInstalls(res.home, res.env, res.cwd);
|
|
@@ -70125,7 +70194,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
70125
70194
|
status: "info",
|
|
70126
70195
|
detail: "no Workit Claude Code plugin install recorded — skipping"
|
|
70127
70196
|
};
|
|
70128
|
-
const registry = readJson(
|
|
70197
|
+
const registry = readJson(path40.join(claudeConfigDir(res.home, res.env), "plugins", "installed_plugins.json"));
|
|
70129
70198
|
const recorded = (install) => {
|
|
70130
70199
|
const entries = registry?.plugins?.[install.id];
|
|
70131
70200
|
const entry = Array.isArray(entries) ? entries.find((e) => e?.installPath === install.installPath) : null;
|
|
@@ -70218,7 +70287,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
70218
70287
|
}, HOOK_ISSUED_MARKER = "workit-issued-sessions/3", hookRecordsIssued = (root) => {
|
|
70219
70288
|
let files;
|
|
70220
70289
|
try {
|
|
70221
|
-
files = readdirSync10(
|
|
70290
|
+
files = readdirSync10(path40.join(root, "dist")).filter((f) => f.endsWith(".js"));
|
|
70222
70291
|
} catch {
|
|
70223
70292
|
return null;
|
|
70224
70293
|
}
|
|
@@ -70226,7 +70295,7 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
70226
70295
|
return null;
|
|
70227
70296
|
return files.some((file) => {
|
|
70228
70297
|
try {
|
|
70229
|
-
return
|
|
70298
|
+
return readFileSync19(path40.join(root, "dist", file), "utf8").includes(HOOK_ISSUED_MARKER);
|
|
70230
70299
|
} catch {
|
|
70231
70300
|
return false;
|
|
70232
70301
|
}
|
|
@@ -70408,6 +70477,16 @@ var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE", findDevFromCwd = (cwd) => {
|
|
|
70408
70477
|
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`,
|
|
70409
70478
|
fix: `workit setup --hosts=${host}`
|
|
70410
70479
|
};
|
|
70480
|
+
}, checkUpdates = (res) => {
|
|
70481
|
+
const mode = readUpdatesMode(res.env, res.explicitDirs.config);
|
|
70482
|
+
const cache = readUpdateCache(res.env, res.explicitDirs.state);
|
|
70483
|
+
const checked = cache.checkedAt === undefined ? "" : ` (checked ${ago(Math.max(0, Date.now() - cache.checkedAt))})`;
|
|
70484
|
+
const latest = cache.latest ? `latest CLI ${cache.latest}${checked}` : "no latest CLI version cached yet";
|
|
70485
|
+
return {
|
|
70486
|
+
id: "updates",
|
|
70487
|
+
status: "info",
|
|
70488
|
+
detail: `updates: ${mode}; ${latest}${cache.skipped ? `; ${cache.skipped} skipped` : ""}`
|
|
70489
|
+
};
|
|
70411
70490
|
}, ago = (ms) => {
|
|
70412
70491
|
const minutes = Math.max(0, Math.round(ms / 60000));
|
|
70413
70492
|
if (minutes < 1)
|
|
@@ -70487,6 +70566,7 @@ var init_doctor = __esm(() => {
|
|
|
70487
70566
|
init_skill_manifests();
|
|
70488
70567
|
init_session_hook();
|
|
70489
70568
|
init_hook_runs();
|
|
70569
|
+
init_update_settings();
|
|
70490
70570
|
init_host_permissions();
|
|
70491
70571
|
OPENCODE_V1_FIX = `OpenCode < ${SUPPORT_MATRIX.opencode.minimum} cannot load Workit (V2 plugin API only): upgrade OpenCode to ${SUPPORT_MATRIX.opencode.minimum}+`;
|
|
70492
70572
|
AGENT_MARKER_VERSION = /^# Generated by Workit (\d+\.\d+\.\d+)\b/;
|
|
@@ -70530,6 +70610,7 @@ var init_doctor = __esm(() => {
|
|
|
70530
70610
|
checkGrantEndpoint,
|
|
70531
70611
|
checkHookRuns,
|
|
70532
70612
|
checkChecksConfig,
|
|
70613
|
+
checkUpdates,
|
|
70533
70614
|
checkHostPermissions("claude-code", "claude_permissions"),
|
|
70534
70615
|
checkHostPermissions("codex", "codex_permissions"),
|
|
70535
70616
|
checkHostPermissions("cursor", "cursor_permissions"),
|
|
@@ -70569,19 +70650,19 @@ import {
|
|
|
70569
70650
|
cpSync as cpSync4,
|
|
70570
70651
|
existsSync as existsSync18,
|
|
70571
70652
|
lstatSync as lstatSync7,
|
|
70572
|
-
mkdirSync as
|
|
70653
|
+
mkdirSync as mkdirSync10,
|
|
70573
70654
|
mkdtempSync as mkdtempSync2,
|
|
70574
|
-
readFileSync as
|
|
70655
|
+
readFileSync as readFileSync20,
|
|
70575
70656
|
readdirSync as readdirSync11,
|
|
70576
70657
|
realpathSync as realpathSync9,
|
|
70577
|
-
renameSync as
|
|
70658
|
+
renameSync as renameSync6,
|
|
70578
70659
|
rmSync as rmSync5,
|
|
70579
70660
|
statSync as statSync7,
|
|
70580
|
-
writeFileSync as
|
|
70661
|
+
writeFileSync as writeFileSync11
|
|
70581
70662
|
} from "node:fs";
|
|
70582
70663
|
import { createRequire as createRequire2 } from "node:module";
|
|
70583
|
-
import
|
|
70584
|
-
import
|
|
70664
|
+
import os14 from "node:os";
|
|
70665
|
+
import path41 from "node:path";
|
|
70585
70666
|
import { isDeepStrictEqual as isDeepStrictEqual2 } from "node:util";
|
|
70586
70667
|
function parseList(raw) {
|
|
70587
70668
|
return raw.split(",").map((s) => s.trim()).filter(Boolean);
|
|
@@ -70626,7 +70707,7 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
70626
70707
|
const current = readConfigFromDir(state.configDir);
|
|
70627
70708
|
mutations.push({
|
|
70628
70709
|
type: "merge-json",
|
|
70629
|
-
path:
|
|
70710
|
+
path: path41.join(state.configDir, "config.json"),
|
|
70630
70711
|
value: {
|
|
70631
70712
|
locale: values.locale,
|
|
70632
70713
|
localeOptions: current.localeOptions,
|
|
@@ -70652,17 +70733,17 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
70652
70733
|
if (blocked.length === 0) {
|
|
70653
70734
|
mutations.push({
|
|
70654
70735
|
type: "update-workspaces",
|
|
70655
|
-
path:
|
|
70736
|
+
path: path41.join(state.configDir, "workspaces.json"),
|
|
70656
70737
|
entries: values.workspaces,
|
|
70657
70738
|
expectedRevision: diskWorkspaceResult.revision
|
|
70658
70739
|
});
|
|
70659
70740
|
}
|
|
70660
70741
|
}
|
|
70661
70742
|
if (values.baseUrl.trim()) {
|
|
70662
|
-
const ytPath =
|
|
70743
|
+
const ytPath = path41.join(state.configDir, "youtrack.json");
|
|
70663
70744
|
const ytExisting = readConfigRecord(ytPath);
|
|
70664
70745
|
const ytConfigured = configuredTokenPath(ytExisting, "tokenFile");
|
|
70665
|
-
const tokenPath = resolveTokenPath(ytConfigured,
|
|
70746
|
+
const tokenPath = resolveTokenPath(ytConfigured, path41.join(state.configDir, "youtrack.token"), values.tokenPaths?.youtrack);
|
|
70666
70747
|
const draft = youtrackDraft(values, tokenPath);
|
|
70667
70748
|
if (ytConfigured !== null && tokenPath !== ytConfigured) {
|
|
70668
70749
|
delete draft.tokenFile;
|
|
@@ -70690,7 +70771,7 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
70690
70771
|
});
|
|
70691
70772
|
}
|
|
70692
70773
|
if (values.vcsProvider !== "skip") {
|
|
70693
|
-
const vcsPath =
|
|
70774
|
+
const vcsPath = path41.join(state.configDir, "vcs.json");
|
|
70694
70775
|
mutations.push({
|
|
70695
70776
|
type: "merge-json",
|
|
70696
70777
|
path: vcsPath,
|
|
@@ -70719,7 +70800,7 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
70719
70800
|
mutations.push({
|
|
70720
70801
|
type: "install-host",
|
|
70721
70802
|
platform: "cursor",
|
|
70722
|
-
path:
|
|
70803
|
+
path: path41.join(paths.home, ".cursor", "plugins", "local", ".workit-package-bootstrap"),
|
|
70723
70804
|
commands
|
|
70724
70805
|
});
|
|
70725
70806
|
}
|
|
@@ -70732,7 +70813,7 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
70732
70813
|
mutations.push({
|
|
70733
70814
|
type: "install-host",
|
|
70734
70815
|
platform,
|
|
70735
|
-
path: platform === "claude-code" ? claudeInstallRecord(paths.home, env) : platform === "codex" ?
|
|
70816
|
+
path: platform === "claude-code" ? claudeInstallRecord(paths.home, env) : platform === "codex" ? path41.join(env.CODEX_HOME ?? path41.join(paths.home, ".codex"), "plugins", "cache", "workflow-toolkit", "workit") : path41.join(env.PI_CODING_AGENT_DIR ?? path41.join(paths.home, ".pi", "agent"), "settings.json"),
|
|
70736
70817
|
commands
|
|
70737
70818
|
});
|
|
70738
70819
|
}
|
|
@@ -70744,8 +70825,8 @@ function buildSetupPreview(values, opts = {}) {
|
|
|
70744
70825
|
projectRefused = target.refused;
|
|
70745
70826
|
if (target?.ok) {
|
|
70746
70827
|
const root = target.root;
|
|
70747
|
-
const gitignorePath =
|
|
70748
|
-
const existing = existsSync18(gitignorePath) ?
|
|
70828
|
+
const gitignorePath = path41.join(root, ".gitignore");
|
|
70829
|
+
const existing = existsSync18(gitignorePath) ? readFileSync20(gitignorePath, "utf8") : "";
|
|
70749
70830
|
const existingLines = new Set(existing.split(`
|
|
70750
70831
|
`).map((l) => l.trim()).filter(Boolean));
|
|
70751
70832
|
const entries = GITIGNORE_ENTRIES.filter((e) => e.trim() !== "" && !existingLines.has(e.trim()));
|
|
@@ -70782,10 +70863,10 @@ function deepMerge(base, patch) {
|
|
|
70782
70863
|
return out;
|
|
70783
70864
|
}
|
|
70784
70865
|
function applyMutation(m) {
|
|
70785
|
-
const dir =
|
|
70866
|
+
const dir = path41.dirname(m.path);
|
|
70786
70867
|
switch (m.type) {
|
|
70787
70868
|
case "create-file": {
|
|
70788
|
-
|
|
70869
|
+
mkdirSync10(dir, { recursive: true });
|
|
70789
70870
|
const res = writeFileExclusive(m.path, m.content, m.mode);
|
|
70790
70871
|
return res === "created" ? { platform: "core", file: m.path, status: "Installed" } : {
|
|
70791
70872
|
platform: "core",
|
|
@@ -70808,8 +70889,8 @@ function applyMutation(m) {
|
|
|
70808
70889
|
if (existing.kind === "record" && JSON.stringify(existing.value) === JSON.stringify(merged)) {
|
|
70809
70890
|
return { platform: "core", file: m.path, status: "Skipped", detail: "already configured" };
|
|
70810
70891
|
}
|
|
70811
|
-
|
|
70812
|
-
|
|
70892
|
+
mkdirSync10(dir, { recursive: true });
|
|
70893
|
+
writeFileSync11(m.path, JSON.stringify(merged, null, 2) + `
|
|
70813
70894
|
`, "utf8");
|
|
70814
70895
|
return existing.kind === "record" ? { platform: "core", file: m.path, status: "Configured" } : { platform: "core", file: m.path, status: "Installed" };
|
|
70815
70896
|
}
|
|
@@ -70850,10 +70931,10 @@ function applyMutation(m) {
|
|
|
70850
70931
|
`;
|
|
70851
70932
|
if (prev === next)
|
|
70852
70933
|
return { platform: "core", file: m.path, status: "Skipped", detail: "already configured" };
|
|
70853
|
-
|
|
70934
|
+
mkdirSync10(dir, { recursive: true });
|
|
70854
70935
|
const tmp = `${m.path}.${process.pid}.tmp`;
|
|
70855
70936
|
try {
|
|
70856
|
-
|
|
70937
|
+
writeFileSync11(tmp, next, "utf8");
|
|
70857
70938
|
if (workspacesRevision(readFileSafe(m.path)) !== m.expectedRevision) {
|
|
70858
70939
|
rmSync5(tmp, { force: true });
|
|
70859
70940
|
return {
|
|
@@ -70863,7 +70944,7 @@ function applyMutation(m) {
|
|
|
70863
70944
|
detail: "workspace config changed while applying the preview; rebuild and review it"
|
|
70864
70945
|
};
|
|
70865
70946
|
}
|
|
70866
|
-
|
|
70947
|
+
renameSync6(tmp, m.path);
|
|
70867
70948
|
} catch (error) {
|
|
70868
70949
|
rmSync5(tmp, { force: true });
|
|
70869
70950
|
return {
|
|
@@ -70888,11 +70969,11 @@ function applyMutation(m) {
|
|
|
70888
70969
|
detail: "all entries already present"
|
|
70889
70970
|
};
|
|
70890
70971
|
}
|
|
70891
|
-
|
|
70972
|
+
mkdirSync10(dir, { recursive: true });
|
|
70892
70973
|
const separator = existing && !existing.endsWith(`
|
|
70893
70974
|
`) ? `
|
|
70894
70975
|
` : "";
|
|
70895
|
-
|
|
70976
|
+
writeFileSync11(m.path, existing + separator + (existing ? `
|
|
70896
70977
|
` : "") + add.join(`
|
|
70897
70978
|
`) + `
|
|
70898
70979
|
`, "utf8");
|
|
@@ -70931,8 +71012,8 @@ function applyMutation(m) {
|
|
|
70931
71012
|
detail: "already configured"
|
|
70932
71013
|
};
|
|
70933
71014
|
}
|
|
70934
|
-
|
|
70935
|
-
|
|
71015
|
+
mkdirSync10(path41.dirname(m.path), { recursive: true });
|
|
71016
|
+
writeFileSync11(m.path, JSON.stringify(merged, null, 2) + `
|
|
70936
71017
|
`, "utf8");
|
|
70937
71018
|
return existing.kind === "record" ? { platform: "core", file: m.path, status: "Configured" } : { platform: "core", file: m.path, status: "Installed" };
|
|
70938
71019
|
}
|
|
@@ -70940,11 +71021,11 @@ function applyMutation(m) {
|
|
|
70940
71021
|
}
|
|
70941
71022
|
function adapterRoot(platform, res, preferInstalledAdapter = false) {
|
|
70942
71023
|
const candidates = [];
|
|
70943
|
-
const stagedCursor =
|
|
71024
|
+
const stagedCursor = path41.join(res.home, ".cursor", "plugins", "local", ".workit-package-bootstrap", "node_modules", "@brainervirus", "workit-cursor");
|
|
70944
71025
|
if (platform === "cursor" && preferInstalledAdapter)
|
|
70945
71026
|
candidates.push(stagedCursor);
|
|
70946
71027
|
if (res.dev) {
|
|
70947
|
-
candidates.push(
|
|
71028
|
+
candidates.push(path41.join(res.dev, "packages", `workit-${platform}`));
|
|
70948
71029
|
} else {
|
|
70949
71030
|
candidates.push(...nodeResolvedAdapters(platform));
|
|
70950
71031
|
if (platform === "cursor")
|
|
@@ -70954,10 +71035,10 @@ function adapterRoot(platform, res, preferInstalledAdapter = false) {
|
|
|
70954
71035
|
if (cached)
|
|
70955
71036
|
candidates.push(cached.root);
|
|
70956
71037
|
}
|
|
70957
|
-
let dir =
|
|
71038
|
+
let dir = path41.resolve(res.cwd);
|
|
70958
71039
|
while (true) {
|
|
70959
|
-
candidates.push(
|
|
70960
|
-
const parent =
|
|
71040
|
+
candidates.push(path41.join(dir, "packages", `workit-${platform}`));
|
|
71041
|
+
const parent = path41.dirname(dir);
|
|
70961
71042
|
if (parent === dir)
|
|
70962
71043
|
break;
|
|
70963
71044
|
dir = parent;
|
|
@@ -70979,7 +71060,7 @@ function applyOpenCode(root, res) {
|
|
|
70979
71060
|
detail: "workit-opencode package has no loadable plugin entry (src/plugin.ts or dist/plugin.js)"
|
|
70980
71061
|
};
|
|
70981
71062
|
}
|
|
70982
|
-
|
|
71063
|
+
mkdirSync10(path41.dirname(res.opencodeConfig), { recursive: true });
|
|
70983
71064
|
const existing = readExisting(res.opencodeConfig);
|
|
70984
71065
|
if (existing.kind === "malformed") {
|
|
70985
71066
|
return {
|
|
@@ -71004,7 +71085,7 @@ function applyOpenCode(root, res) {
|
|
|
71004
71085
|
detail: "already registered"
|
|
71005
71086
|
};
|
|
71006
71087
|
}
|
|
71007
|
-
|
|
71088
|
+
writeFileSync11(res.opencodeConfig, JSON.stringify(merged.config, null, 2) + `
|
|
71008
71089
|
`, "utf8");
|
|
71009
71090
|
return existing.kind === "record" ? {
|
|
71010
71091
|
platform: "opencode",
|
|
@@ -71020,31 +71101,31 @@ function applyOpenCode(root, res) {
|
|
|
71020
71101
|
}
|
|
71021
71102
|
function copyPluginDir(src, dest) {
|
|
71022
71103
|
const realSrc = realpathSync9(src);
|
|
71023
|
-
const marker =
|
|
71104
|
+
const marker = path41.join(dest, ".workit-root");
|
|
71024
71105
|
const destIsLink = existsSync18(dest) && lstatSync7(dest).isSymbolicLink();
|
|
71025
71106
|
const synced = !destIsLink && readFileSafe(marker)?.trim() === realSrc && samePluginContent(realSrc, dest, dest);
|
|
71026
71107
|
if (synced)
|
|
71027
71108
|
return "Skipped";
|
|
71028
71109
|
const hadDir = existsSync18(dest);
|
|
71029
71110
|
const rules = preservedCursorRules(realSrc, dest);
|
|
71030
|
-
const parent =
|
|
71031
|
-
|
|
71032
|
-
const swap = mkdtempSync2(
|
|
71033
|
-
const stage =
|
|
71034
|
-
const backup =
|
|
71111
|
+
const parent = path41.dirname(dest);
|
|
71112
|
+
mkdirSync10(parent, { recursive: true });
|
|
71113
|
+
const swap = mkdtempSync2(path41.join(parent, `.${path41.basename(dest)}.swap-`));
|
|
71114
|
+
const stage = path41.join(swap, "stage");
|
|
71115
|
+
const backup = path41.join(swap, "backup");
|
|
71035
71116
|
try {
|
|
71036
71117
|
cpSync4(realSrc, stage, {
|
|
71037
71118
|
recursive: true,
|
|
71038
|
-
filter: (entry) => !
|
|
71119
|
+
filter: (entry) => !path41.relative(realSrc, entry).split(path41.sep).includes("node_modules")
|
|
71039
71120
|
});
|
|
71040
|
-
const stagedHooks =
|
|
71121
|
+
const stagedHooks = path41.join(stage, CURSOR_HOOKS_FILE);
|
|
71041
71122
|
if (existsSync18(stagedHooks))
|
|
71042
|
-
|
|
71123
|
+
writeFileSync11(stagedHooks, localizedCursorHooks(readFileSync20(stagedHooks), dest));
|
|
71043
71124
|
for (const [name, content] of rules) {
|
|
71044
|
-
|
|
71045
|
-
|
|
71125
|
+
mkdirSync10(path41.join(stage, "rules"), { recursive: true });
|
|
71126
|
+
writeFileSync11(path41.join(stage, "rules", name), content);
|
|
71046
71127
|
}
|
|
71047
|
-
|
|
71128
|
+
writeFileSync11(path41.join(stage, ".workit-root"), realSrc + `
|
|
71048
71129
|
`, "utf8");
|
|
71049
71130
|
if (!samePluginContent(realSrc, stage, dest))
|
|
71050
71131
|
throw new Error("staged adapter content is incomplete");
|
|
@@ -71052,12 +71133,12 @@ function copyPluginDir(src, dest) {
|
|
|
71052
71133
|
throw new Error("staged adapter resolved to a symlink — refusing fragile cache install");
|
|
71053
71134
|
}
|
|
71054
71135
|
if (hadDir)
|
|
71055
|
-
|
|
71136
|
+
renameSync6(dest, backup);
|
|
71056
71137
|
try {
|
|
71057
|
-
|
|
71138
|
+
renameSync6(stage, dest);
|
|
71058
71139
|
} catch (error) {
|
|
71059
71140
|
if (hadDir && !existsSync18(dest))
|
|
71060
|
-
|
|
71141
|
+
renameSync6(backup, dest);
|
|
71061
71142
|
throw error;
|
|
71062
71143
|
}
|
|
71063
71144
|
rmSync5(backup, { recursive: true, force: true });
|
|
@@ -71067,7 +71148,7 @@ function copyPluginDir(src, dest) {
|
|
|
71067
71148
|
return hadDir ? "Configured" : "Installed";
|
|
71068
71149
|
}
|
|
71069
71150
|
function applyCursorSettings(root, res) {
|
|
71070
|
-
|
|
71151
|
+
mkdirSync10(path41.dirname(res.cursorSettings), { recursive: true });
|
|
71071
71152
|
const settingsExisting = readExisting(res.cursorSettings);
|
|
71072
71153
|
if (settingsExisting.kind === "malformed") {
|
|
71073
71154
|
return {
|
|
@@ -71086,7 +71167,7 @@ function applyCursorSettings(root, res) {
|
|
|
71086
71167
|
detail: "already registered"
|
|
71087
71168
|
};
|
|
71088
71169
|
}
|
|
71089
|
-
|
|
71170
|
+
writeFileSync11(res.cursorSettings, JSON.stringify(settings.config, null, 2) + `
|
|
71090
71171
|
`, "utf8");
|
|
71091
71172
|
return {
|
|
71092
71173
|
platform: "cursor",
|
|
@@ -71095,7 +71176,7 @@ function applyCursorSettings(root, res) {
|
|
|
71095
71176
|
};
|
|
71096
71177
|
}
|
|
71097
71178
|
function applyCursorMcp(root, res) {
|
|
71098
|
-
|
|
71179
|
+
mkdirSync10(path41.dirname(res.cursorMcp), { recursive: true });
|
|
71099
71180
|
const mcpExisting = readExisting(res.cursorMcp);
|
|
71100
71181
|
if (mcpExisting.kind === "malformed") {
|
|
71101
71182
|
return {
|
|
@@ -71125,7 +71206,7 @@ function applyCursorMcp(root, res) {
|
|
|
71125
71206
|
detail: "already registered"
|
|
71126
71207
|
};
|
|
71127
71208
|
}
|
|
71128
|
-
|
|
71209
|
+
writeFileSync11(res.cursorMcp, JSON.stringify(mcp.config, null, 2) + `
|
|
71129
71210
|
`, "utf8");
|
|
71130
71211
|
return {
|
|
71131
71212
|
platform: "cursor",
|
|
@@ -71201,7 +71282,7 @@ function applySetupPreview(preview, options = {}) {
|
|
|
71201
71282
|
let cursorCopyOk = false;
|
|
71202
71283
|
for (const mutation of preview.mutations) {
|
|
71203
71284
|
if (mutation.type === "install-host") {
|
|
71204
|
-
const expectedPath = mutation.platform === "cursor" ?
|
|
71285
|
+
const expectedPath = mutation.platform === "cursor" ? path41.join(res.home, ".cursor", "plugins", "local", ".workit-package-bootstrap") : mutation.platform === "codex" ? path41.join(res.env.CODEX_HOME ?? path41.join(res.home, ".codex"), "plugins", "cache", "workflow-toolkit", "workit") : mutation.platform === "pi" ? path41.join(res.env.PI_CODING_AGENT_DIR ?? path41.join(res.home, ".pi", "agent"), "settings.json") : mutation.platform === "claude-code" ? claudeInstallRecord(res.home, res.env) : "";
|
|
71205
71286
|
if (mutation.path !== expectedPath) {
|
|
71206
71287
|
entries.push({
|
|
71207
71288
|
platform: mutation.platform,
|
|
@@ -71313,7 +71394,7 @@ function applySetupPreview(preview, options = {}) {
|
|
|
71313
71394
|
if (preview.projectRefused) {
|
|
71314
71395
|
entries.push({
|
|
71315
71396
|
platform: "core",
|
|
71316
|
-
file:
|
|
71397
|
+
file: path41.resolve(res.cwd),
|
|
71317
71398
|
status: "Skipped",
|
|
71318
71399
|
detail: preview.projectRefused
|
|
71319
71400
|
});
|
|
@@ -71394,28 +71475,28 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
71394
71475
|
return configured ?? fallback;
|
|
71395
71476
|
}, readConfigRecord = (file) => {
|
|
71396
71477
|
try {
|
|
71397
|
-
const value = JSON.parse(
|
|
71478
|
+
const value = JSON.parse(readFileSync20(file, "utf8"));
|
|
71398
71479
|
return isRecord6(value) ? value : null;
|
|
71399
71480
|
} catch {
|
|
71400
71481
|
return null;
|
|
71401
71482
|
}
|
|
71402
|
-
}, claudeInstallRecord = (home, env) =>
|
|
71483
|
+
}, claudeInstallRecord = (home, env) => path41.join(claudeConfigDir(home, env), "plugins", "installed_plugins.json"), resolveSetupPaths = (options, resolvedConfigDir) => {
|
|
71403
71484
|
const env = options.env ?? process.env;
|
|
71404
|
-
const home = options.home ?? env.HOME ??
|
|
71485
|
+
const home = options.home ?? env.HOME ?? os14.homedir();
|
|
71405
71486
|
return {
|
|
71406
71487
|
home,
|
|
71407
71488
|
configDir: resolvedConfigDir,
|
|
71408
71489
|
cwd: options.cwd ?? process.cwd(),
|
|
71409
71490
|
env,
|
|
71410
|
-
opencodeConfig: options.opencodeConfig ??
|
|
71411
|
-
cursorSettings: options.cursorSettings ??
|
|
71412
|
-
cursorMcp: options.cursorMcp ??
|
|
71413
|
-
cursorPluginDir: options.cursorPluginDir ??
|
|
71491
|
+
opencodeConfig: options.opencodeConfig ?? path41.join(home, ".config", "opencode", "opencode.json"),
|
|
71492
|
+
cursorSettings: options.cursorSettings ?? path41.join(home, ".cursor", "settings.json"),
|
|
71493
|
+
cursorMcp: options.cursorMcp ?? path41.join(home, ".cursor", "mcp.json"),
|
|
71494
|
+
cursorPluginDir: options.cursorPluginDir ?? path41.join(home, ".cursor", "plugins", "local", "workit")
|
|
71414
71495
|
};
|
|
71415
71496
|
}, isRecord6 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), readExisting = (p) => {
|
|
71416
71497
|
let raw;
|
|
71417
71498
|
try {
|
|
71418
|
-
raw =
|
|
71499
|
+
raw = readFileSync20(p, "utf8");
|
|
71419
71500
|
} catch {
|
|
71420
71501
|
if (existsSync18(p))
|
|
71421
71502
|
return { kind: "malformed", error: `${p} is not readable` };
|
|
@@ -71432,7 +71513,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
71432
71513
|
return { kind: "malformed", error: `${p} is not a JSON object` };
|
|
71433
71514
|
}, readFileSafe = (p) => {
|
|
71434
71515
|
try {
|
|
71435
|
-
return
|
|
71516
|
+
return readFileSync20(p, "utf8");
|
|
71436
71517
|
} catch {
|
|
71437
71518
|
return null;
|
|
71438
71519
|
}
|
|
@@ -71447,15 +71528,15 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
71447
71528
|
}
|
|
71448
71529
|
}, isAdapter = (root, platform) => {
|
|
71449
71530
|
try {
|
|
71450
|
-
const pkg = JSON.parse(
|
|
71531
|
+
const pkg = JSON.parse(readFileSync20(path41.join(root, "package.json"), "utf8"));
|
|
71451
71532
|
return pkg.name === `@brainervirus/workit-${platform}`;
|
|
71452
71533
|
} catch {
|
|
71453
71534
|
return false;
|
|
71454
71535
|
}
|
|
71455
71536
|
}, nodeResolvedAdapters = (platform) => {
|
|
71456
71537
|
const name = `@brainervirus/workit-${platform}`;
|
|
71457
|
-
const require2 = createRequire2(
|
|
71458
|
-
return (require2.resolve.paths(name) ?? []).map((dir) =>
|
|
71538
|
+
const require2 = createRequire2(path41.join(packageRoot(), "package.json"));
|
|
71539
|
+
return (require2.resolve.paths(name) ?? []).map((dir) => path41.join(dir, name));
|
|
71459
71540
|
}, realRoot = (root) => {
|
|
71460
71541
|
try {
|
|
71461
71542
|
return realpathSync9(root);
|
|
@@ -71471,7 +71552,7 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
71471
71552
|
if (!isDevOpenCodeAdapterRoot(root, opts.dev))
|
|
71472
71553
|
return OPENCODE_NPM_PIN;
|
|
71473
71554
|
for (const rel of ["src/plugin.ts", "dist/plugin.js"]) {
|
|
71474
|
-
const entry =
|
|
71555
|
+
const entry = path41.join(root, rel);
|
|
71475
71556
|
if (existsSync18(entry))
|
|
71476
71557
|
return `file://${entry}`;
|
|
71477
71558
|
}
|
|
@@ -71489,22 +71570,22 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
71489
71570
|
for (const entry of readdirSync11(src, { withFileTypes: true })) {
|
|
71490
71571
|
if (entry.name === "node_modules")
|
|
71491
71572
|
continue;
|
|
71492
|
-
const source =
|
|
71493
|
-
const installed =
|
|
71494
|
-
const rel =
|
|
71573
|
+
const source = path41.join(src, entry.name);
|
|
71574
|
+
const installed = path41.join(dest, entry.name);
|
|
71575
|
+
const rel = path41.join(relative, entry.name);
|
|
71495
71576
|
if (entry.isDirectory()) {
|
|
71496
71577
|
if (!statSync7(installed).isDirectory() || !samePluginContent(source, installed, pluginDir, rel))
|
|
71497
71578
|
return false;
|
|
71498
71579
|
} else {
|
|
71499
|
-
const expected = rel === CURSOR_HOOKS_FILE ? localizedCursorHooks(
|
|
71500
|
-
if (!expected.equals(
|
|
71580
|
+
const expected = rel === CURSOR_HOOKS_FILE ? localizedCursorHooks(readFileSync20(source), pluginDir) : readFileSync20(source);
|
|
71581
|
+
if (!expected.equals(readFileSync20(installed)))
|
|
71501
71582
|
return false;
|
|
71502
71583
|
}
|
|
71503
71584
|
}
|
|
71504
71585
|
for (const entry of readdirSync11(dest, { withFileTypes: true })) {
|
|
71505
|
-
if (existsSync18(
|
|
71586
|
+
if (existsSync18(path41.join(src, entry.name)))
|
|
71506
71587
|
continue;
|
|
71507
|
-
const rel =
|
|
71588
|
+
const rel = path41.join(relative, entry.name);
|
|
71508
71589
|
if (rel === ".workit-root")
|
|
71509
71590
|
continue;
|
|
71510
71591
|
if (relative === "rules" && entry.isFile() && entry.name.endsWith(".mdc"))
|
|
@@ -71517,32 +71598,32 @@ var TOKEN_PLACEHOLDER3 = "YOUR_TOKEN_HERE", YT_OVERRIDES, VCS_OVERRIDES, SETUP_O
|
|
|
71517
71598
|
}
|
|
71518
71599
|
}, preservedCursorRules = (src, dest) => {
|
|
71519
71600
|
const preserved = new Map;
|
|
71520
|
-
const sourceRules =
|
|
71521
|
-
const installedRules =
|
|
71601
|
+
const sourceRules = path41.join(src, "rules");
|
|
71602
|
+
const installedRules = path41.join(dest, "rules");
|
|
71522
71603
|
try {
|
|
71523
71604
|
for (const entry of readdirSync11(installedRules, { withFileTypes: true })) {
|
|
71524
71605
|
if (!entry.isFile() || !entry.name.endsWith(".mdc"))
|
|
71525
71606
|
continue;
|
|
71526
|
-
if (existsSync18(
|
|
71607
|
+
if (existsSync18(path41.join(sourceRules, entry.name)))
|
|
71527
71608
|
continue;
|
|
71528
|
-
preserved.set(entry.name,
|
|
71609
|
+
preserved.set(entry.name, readFileSync20(path41.join(installedRules, entry.name)));
|
|
71529
71610
|
}
|
|
71530
71611
|
} catch {}
|
|
71531
71612
|
return preserved;
|
|
71532
71613
|
}, removeLegacyCursorDir = (res) => {
|
|
71533
|
-
const legacy =
|
|
71614
|
+
const legacy = path41.join(res.home, ".cursor", "plugins", "local", "workflow-toolkit");
|
|
71534
71615
|
if (legacy === res.cursorPluginDir || !existsSync18(legacy))
|
|
71535
71616
|
return;
|
|
71536
|
-
const legacyRules =
|
|
71617
|
+
const legacyRules = path41.join(legacy, "rules");
|
|
71537
71618
|
if (existsSync18(legacyRules)) {
|
|
71538
71619
|
try {
|
|
71539
|
-
|
|
71620
|
+
mkdirSync10(path41.join(res.cursorPluginDir, "rules"), { recursive: true });
|
|
71540
71621
|
for (const entry of readdirSync11(legacyRules, { withFileTypes: true })) {
|
|
71541
71622
|
if (!entry.isFile() || !entry.name.endsWith(".mdc"))
|
|
71542
71623
|
continue;
|
|
71543
|
-
const target =
|
|
71624
|
+
const target = path41.join(res.cursorPluginDir, "rules", entry.name);
|
|
71544
71625
|
if (!existsSync18(target))
|
|
71545
|
-
copyFileSync5(
|
|
71626
|
+
copyFileSync5(path41.join(legacyRules, entry.name), target);
|
|
71546
71627
|
}
|
|
71547
71628
|
} catch {}
|
|
71548
71629
|
}
|
|
@@ -71576,16 +71657,16 @@ var init_setup = __esm(() => {
|
|
|
71576
71657
|
{ envKey: "WORKFLOW_GITHUB_HOST", affects: "vcs.json github.host" }
|
|
71577
71658
|
];
|
|
71578
71659
|
SETUP_OVERRIDES = [...YT_OVERRIDES, ...VCS_OVERRIDES];
|
|
71579
|
-
CURSOR_HOOKS_FILE =
|
|
71660
|
+
CURSOR_HOOKS_FILE = path41.join("hooks", "hooks-cursor.json");
|
|
71580
71661
|
});
|
|
71581
71662
|
|
|
71582
71663
|
// packages/workit-core/src/core/workspace-branch-policy.ts
|
|
71583
|
-
import { mkdirSync as
|
|
71584
|
-
import
|
|
71664
|
+
import { mkdirSync as mkdirSync11, readFileSync as readFileSync21, renameSync as renameSync7, rmSync as rmSync6, writeFileSync as writeFileSync12 } from "node:fs";
|
|
71665
|
+
import path42 from "node:path";
|
|
71585
71666
|
import { isDeepStrictEqual as isDeepStrictEqual3 } from "node:util";
|
|
71586
71667
|
function applyWorkspaceBranchPolicy(opts) {
|
|
71587
71668
|
const { workspace_root, env = process.env } = opts;
|
|
71588
|
-
const dir =
|
|
71669
|
+
const dir = path42.join(env.WORKFLOW_TOOLKIT_CONFIG ?? configDir());
|
|
71589
71670
|
const {
|
|
71590
71671
|
status,
|
|
71591
71672
|
path: wsPath,
|
|
@@ -71597,7 +71678,7 @@ function applyWorkspaceBranchPolicy(opts) {
|
|
|
71597
71678
|
if (status === "malformed" || status === "invalid")
|
|
71598
71679
|
return { ok: false, error: workspacesError ?? `invalid workspaces.json: ${wsPath}` };
|
|
71599
71680
|
const detection = detectBranchPolicy(workspace_root);
|
|
71600
|
-
const name = String(env.WORKFLOW_BP_NAME ??
|
|
71681
|
+
const name = String(env.WORKFLOW_BP_NAME ?? path42.basename(workspace_root));
|
|
71601
71682
|
const integration = env.WORKFLOW_BP_INTEGRATION ?? detection.integration;
|
|
71602
71683
|
const policy = {
|
|
71603
71684
|
preset: detection.preset,
|
|
@@ -71646,10 +71727,10 @@ function applyWorkspaceBranchPolicy(opts) {
|
|
|
71646
71727
|
ok: false,
|
|
71647
71728
|
error: `workspaces.json changed while applying the branch policy: ${wsPath}`
|
|
71648
71729
|
};
|
|
71649
|
-
|
|
71730
|
+
mkdirSync11(path42.dirname(wsPath), { recursive: true });
|
|
71650
71731
|
const tmp = `${wsPath}.${process.pid}.tmp`;
|
|
71651
71732
|
try {
|
|
71652
|
-
|
|
71733
|
+
writeFileSync12(tmp, JSON.stringify({ ...document2, workspaces: next }, null, 2) + `
|
|
71653
71734
|
`, "utf8");
|
|
71654
71735
|
if (workspacesRevision(readFileSafe2(wsPath)) !== revision) {
|
|
71655
71736
|
rmSync6(tmp, { force: true });
|
|
@@ -71658,7 +71739,7 @@ function applyWorkspaceBranchPolicy(opts) {
|
|
|
71658
71739
|
error: `workspaces.json changed while applying the branch policy: ${wsPath}`
|
|
71659
71740
|
};
|
|
71660
71741
|
}
|
|
71661
|
-
|
|
71742
|
+
renameSync7(tmp, wsPath);
|
|
71662
71743
|
} catch (error) {
|
|
71663
71744
|
try {
|
|
71664
71745
|
rmSync6(tmp, { force: true });
|
|
@@ -71678,7 +71759,7 @@ function applyWorkspaceBranchPolicy(opts) {
|
|
|
71678
71759
|
}
|
|
71679
71760
|
var readFileSafe2 = (p) => {
|
|
71680
71761
|
try {
|
|
71681
|
-
return
|
|
71762
|
+
return readFileSync21(p, "utf8");
|
|
71682
71763
|
} catch {
|
|
71683
71764
|
return null;
|
|
71684
71765
|
}
|
|
@@ -71931,7 +72012,7 @@ var init_logic = __esm(() => {
|
|
|
71931
72012
|
|
|
71932
72013
|
// packages/workit-cli/src/wizard-state.ts
|
|
71933
72014
|
import { existsSync as existsSync19, statSync as statSync8 } from "node:fs";
|
|
71934
|
-
import
|
|
72015
|
+
import path43 from "node:path";
|
|
71935
72016
|
import { isDeepStrictEqual as isDeepStrictEqual4 } from "node:util";
|
|
71936
72017
|
function resolveBasePath(values, env = process.env) {
|
|
71937
72018
|
return env.WORKFLOW_WORKSPACE_ROOT?.trim() || values.basePath.trim();
|
|
@@ -72458,8 +72539,8 @@ var NEXT, PREV, skipsCustomBranch = (screen, preset) => (screen === "branchAllow
|
|
|
72458
72539
|
const p = value.trim();
|
|
72459
72540
|
if (!p)
|
|
72460
72541
|
return "workspace root path is required";
|
|
72461
|
-
return !
|
|
72462
|
-
}, skipsBranchPolicy = (screen, basePath) => (screen === "branchPolicy" || screen === "branchPolicyDevelop") && !existsSync19(
|
|
72542
|
+
return !path43.isAbsolute(p) || !isDirectory(p) ? `invalid workspace root "${p}" — enter an existing absolute directory` : null;
|
|
72543
|
+
}, skipsBranchPolicy = (screen, basePath) => (screen === "branchPolicy" || screen === "branchPolicyDevelop") && !existsSync19(path43.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;
|
|
72463
72544
|
var init_wizard_state = __esm(() => {
|
|
72464
72545
|
init_config();
|
|
72465
72546
|
init_workspaces();
|
|
@@ -72518,9 +72599,9 @@ var init_wizard_state = __esm(() => {
|
|
|
72518
72599
|
});
|
|
72519
72600
|
|
|
72520
72601
|
// packages/workit-cli/src/admin/uninstall.ts
|
|
72521
|
-
import { existsSync as existsSync20, readFileSync as
|
|
72522
|
-
import
|
|
72523
|
-
import
|
|
72602
|
+
import { existsSync as existsSync20, readFileSync as readFileSync22, realpathSync as realpathSync10, rmSync as rmSync7, writeFileSync as writeFileSync13 } from "node:fs";
|
|
72603
|
+
import os15 from "node:os";
|
|
72604
|
+
import path44 from "node:path";
|
|
72524
72605
|
function cleanCursorSettings(settings, pluginDir) {
|
|
72525
72606
|
const next = { ...settings };
|
|
72526
72607
|
let changed = false;
|
|
@@ -72667,7 +72748,7 @@ function planUninstall(paths = {}) {
|
|
|
72667
72748
|
}
|
|
72668
72749
|
] : []
|
|
72669
72750
|
};
|
|
72670
|
-
const home = paths.home ?? paths.env?.HOME ??
|
|
72751
|
+
const home = paths.home ?? paths.env?.HOME ?? os15.homedir();
|
|
72671
72752
|
const claudeInstalls = claudeWorkitInstalls(home, paths.env ?? process.env, paths.cwd ?? process.cwd());
|
|
72672
72753
|
const claude = {
|
|
72673
72754
|
host: "claude-code",
|
|
@@ -72693,7 +72774,7 @@ function planUninstall(paths = {}) {
|
|
|
72693
72774
|
plan.actions.push({
|
|
72694
72775
|
kind: "edit-json-remove",
|
|
72695
72776
|
path: file,
|
|
72696
|
-
detail: `remove Workit's permission block from ${
|
|
72777
|
+
detail: `remove Workit's permission block from ${path44.basename(file)}`
|
|
72697
72778
|
});
|
|
72698
72779
|
}
|
|
72699
72780
|
if (existsSync20(res.codexRules))
|
|
@@ -72727,8 +72808,8 @@ function applyUninstall(plan, paths = {}) {
|
|
|
72727
72808
|
status = outcome.status;
|
|
72728
72809
|
detail = outcome.detail;
|
|
72729
72810
|
} else if (action.kind === "remove-dir") {
|
|
72730
|
-
const resolved =
|
|
72731
|
-
const allowed = canonicalRemoveDirAllowed(resolved, res) || resolved ===
|
|
72811
|
+
const resolved = path44.resolve(action.path);
|
|
72812
|
+
const allowed = canonicalRemoveDirAllowed(resolved, res) || resolved === path44.resolve(res.codexPluginDir) && path44.basename(resolved) === "workit" && path44.basename(path44.dirname(resolved)) === "plugins";
|
|
72732
72813
|
if (!allowed) {
|
|
72733
72814
|
status = "failed";
|
|
72734
72815
|
detail = `refusing to remove non-canonical plugin directory: ${resolved}`;
|
|
@@ -72764,23 +72845,23 @@ function applyUninstall(plan, paths = {}) {
|
|
|
72764
72845
|
return { ok: entries.every((e) => e.status !== "failed"), entries };
|
|
72765
72846
|
}
|
|
72766
72847
|
var resolveUninstallPaths = (options = {}) => {
|
|
72767
|
-
const home = options.home ?? options.env?.HOME ??
|
|
72848
|
+
const home = options.home ?? options.env?.HOME ?? os15.homedir();
|
|
72768
72849
|
const permissionPaths = { home, env: options.env ?? process.env };
|
|
72769
72850
|
return {
|
|
72770
72851
|
claudeSettings: permissionTarget("claude-code", permissionPaths).file,
|
|
72771
72852
|
cursorCliConfig: permissionTarget("cursor", permissionPaths).file,
|
|
72772
72853
|
codexRules: permissionTarget("codex", permissionPaths).file,
|
|
72773
|
-
opencodeConfig: options.opencodeConfig ??
|
|
72774
|
-
cursorSettings: options.cursorSettings ??
|
|
72775
|
-
cursorMcp: options.cursorMcp ??
|
|
72776
|
-
cursorPluginDir: options.cursorPluginDir ??
|
|
72777
|
-
codexPluginDir:
|
|
72778
|
-
piConfig:
|
|
72854
|
+
opencodeConfig: options.opencodeConfig ?? path44.join(home, ".config", "opencode", "opencode.json"),
|
|
72855
|
+
cursorSettings: options.cursorSettings ?? path44.join(home, ".cursor", "settings.json"),
|
|
72856
|
+
cursorMcp: options.cursorMcp ?? path44.join(home, ".cursor", "mcp.json"),
|
|
72857
|
+
cursorPluginDir: options.cursorPluginDir ?? path44.join(home, ".cursor", "plugins", "local", "workit"),
|
|
72858
|
+
codexPluginDir: path44.join(home, ".codex", "plugins", "workit"),
|
|
72859
|
+
piConfig: path44.join(home, ".pi", "config.json")
|
|
72779
72860
|
};
|
|
72780
72861
|
}, isRecord7 = (v) => v !== null && typeof v === "object" && !Array.isArray(v), readJsonRecord = (file) => {
|
|
72781
72862
|
let raw;
|
|
72782
72863
|
try {
|
|
72783
|
-
raw =
|
|
72864
|
+
raw = readFileSync22(file, "utf8");
|
|
72784
72865
|
} catch {
|
|
72785
72866
|
if (existsSync20(file))
|
|
72786
72867
|
return { kind: "malformed", error: `${file} is not readable` };
|
|
@@ -72793,12 +72874,12 @@ var resolveUninstallPaths = (options = {}) => {
|
|
|
72793
72874
|
return { kind: "malformed", error: `${file} is not valid JSON` };
|
|
72794
72875
|
}
|
|
72795
72876
|
}, stripTrailingSep = (p) => {
|
|
72796
|
-
const j =
|
|
72797
|
-
return
|
|
72877
|
+
const j = path44.join(p);
|
|
72878
|
+
return path44.dirname(j) === j ? j : j.replace(/[\\/]+$/, "");
|
|
72798
72879
|
}, CURSOR_LEGACY_IDENTITIES, permissionPathsOf = (paths) => {
|
|
72799
72880
|
const env = paths.env ?? process.env;
|
|
72800
72881
|
return {
|
|
72801
|
-
home: paths.home ?? env.HOME ??
|
|
72882
|
+
home: paths.home ?? env.HOME ?? os15.homedir(),
|
|
72802
72883
|
env,
|
|
72803
72884
|
...paths.stateDir ? { stateDir: paths.stateDir } : {}
|
|
72804
72885
|
};
|
|
@@ -72821,8 +72902,8 @@ var resolveUninstallPaths = (options = {}) => {
|
|
|
72821
72902
|
return cleanPiConfig;
|
|
72822
72903
|
return null;
|
|
72823
72904
|
}, canonicalRemoveDirAllowed = (actionPath, res) => {
|
|
72824
|
-
const expected =
|
|
72825
|
-
if (!(actionPath === expected &&
|
|
72905
|
+
const expected = path44.resolve(res.cursorPluginDir);
|
|
72906
|
+
if (!(actionPath === expected && path44.basename(expected) === "workit" && path44.basename(path44.dirname(expected)) === "local" && path44.basename(path44.dirname(path44.dirname(expected))) === "plugins")) {
|
|
72826
72907
|
return false;
|
|
72827
72908
|
}
|
|
72828
72909
|
try {
|
|
@@ -72845,7 +72926,7 @@ var resolveUninstallPaths = (options = {}) => {
|
|
|
72845
72926
|
`;
|
|
72846
72927
|
let current;
|
|
72847
72928
|
try {
|
|
72848
|
-
current =
|
|
72929
|
+
current = readFileSync22(target, "utf8");
|
|
72849
72930
|
} catch (error) {
|
|
72850
72931
|
return {
|
|
72851
72932
|
status: "failed",
|
|
@@ -72856,7 +72937,7 @@ var resolveUninstallPaths = (options = {}) => {
|
|
|
72856
72937
|
return { status: "skipped", detail: "already clean" };
|
|
72857
72938
|
}
|
|
72858
72939
|
try {
|
|
72859
|
-
|
|
72940
|
+
writeFileSync13(target, serialized, "utf8");
|
|
72860
72941
|
} catch (error) {
|
|
72861
72942
|
return {
|
|
72862
72943
|
status: "failed",
|
|
@@ -72872,9 +72953,9 @@ var resolveUninstallPaths = (options = {}) => {
|
|
|
72872
72953
|
status: "failed",
|
|
72873
72954
|
detail: `refusing unreviewed host command: ${action.args.join(" ")}`
|
|
72874
72955
|
};
|
|
72875
|
-
const home = paths.home ?? paths.env?.HOME ??
|
|
72956
|
+
const home = paths.home ?? paths.env?.HOME ?? os15.homedir();
|
|
72876
72957
|
const env = paths.env ?? process.env;
|
|
72877
|
-
const recorded = claudeWorkitInstalls(home, env, action.cwd).some((install) => install.id === id && install.scope === scope && (install.projectPath === null ? action.cwd === null :
|
|
72958
|
+
const recorded = claudeWorkitInstalls(home, env, action.cwd).some((install) => install.id === id && install.scope === scope && (install.projectPath === null ? action.cwd === null : path44.resolve(install.projectPath) === path44.resolve(action.cwd ?? "")));
|
|
72878
72959
|
if (!recorded)
|
|
72879
72960
|
return { status: "skipped", detail: `${id} (${scope} scope) is no longer installed` };
|
|
72880
72961
|
const executable = findHostExecutable("claude", { home, env });
|
|
@@ -72898,7 +72979,7 @@ var init_uninstall = __esm(() => {
|
|
|
72898
72979
|
});
|
|
72899
72980
|
|
|
72900
72981
|
// packages/workit-cli/src/admin/detect-hosts.ts
|
|
72901
|
-
import
|
|
72982
|
+
import os16 from "node:os";
|
|
72902
72983
|
function preselectedPlatforms(detection) {
|
|
72903
72984
|
return WIZARD_HOSTS.filter((host) => detection[host].detected);
|
|
72904
72985
|
}
|
|
@@ -72913,7 +72994,7 @@ function emptyDetection() {
|
|
|
72913
72994
|
}
|
|
72914
72995
|
function detectHosts(options = {}) {
|
|
72915
72996
|
const env = options.env ?? process.env;
|
|
72916
|
-
const home = options.home ?? env.HOME ??
|
|
72997
|
+
const home = options.home ?? env.HOME ?? os16.homedir();
|
|
72917
72998
|
const plan = planUninstall({ ...options, home, env });
|
|
72918
72999
|
const configuredByHost = new Map(plan.hosts.map((h) => [h.host, h.installed]));
|
|
72919
73000
|
const found = emptyDetection();
|
|
@@ -75113,7 +75194,7 @@ var init_diagnostics = __esm(() => {
|
|
|
75113
75194
|
|
|
75114
75195
|
// packages/workit-cli/src/progress.ts
|
|
75115
75196
|
import { spawn } from "node:child_process";
|
|
75116
|
-
import
|
|
75197
|
+
import path45 from "node:path";
|
|
75117
75198
|
function createProgress(options = {}) {
|
|
75118
75199
|
const env = options.env ?? process.env;
|
|
75119
75200
|
const mode = terminalMode({ ...options, env });
|
|
@@ -75226,7 +75307,7 @@ function createProgress(options = {}) {
|
|
|
75226
75307
|
var FRAMES, FRAME_MS, CLEAR = "\r\x1B[2K", TICKER_SOURCE, defaultTicker = (label, began, stream) => {
|
|
75227
75308
|
if (stream !== process.stderr)
|
|
75228
75309
|
return;
|
|
75229
|
-
if (!/^(?:node|nodejs|bun)(?:\.exe)?$/i.test(
|
|
75310
|
+
if (!/^(?:node|nodejs|bun)(?:\.exe)?$/i.test(path45.basename(process.execPath)))
|
|
75230
75311
|
return;
|
|
75231
75312
|
try {
|
|
75232
75313
|
const child = spawn(process.execPath, ["-e", TICKER_SOURCE], {
|
|
@@ -75531,6 +75612,13 @@ var init_init = __esm(() => {
|
|
|
75531
75612
|
});
|
|
75532
75613
|
|
|
75533
75614
|
// packages/workit-cli/src/prompt.ts
|
|
75615
|
+
var exports_prompt = {};
|
|
75616
|
+
__export(exports_prompt, {
|
|
75617
|
+
askLine: () => askLine,
|
|
75618
|
+
askOrCancel: () => askOrCancel,
|
|
75619
|
+
cancelled: () => cancelled,
|
|
75620
|
+
isPromptAbort: () => isPromptAbort
|
|
75621
|
+
});
|
|
75534
75622
|
import { createInterface } from "node:readline/promises";
|
|
75535
75623
|
async function askLine(question, output = process.stdout) {
|
|
75536
75624
|
const prompt = createInterface({ input: process.stdin, output });
|
|
@@ -75674,9 +75762,9 @@ var init_setup2 = __esm(() => {
|
|
|
75674
75762
|
|
|
75675
75763
|
// packages/workit-cli/src/upgrade/shared.ts
|
|
75676
75764
|
import { spawn as spawn2 } from "node:child_process";
|
|
75677
|
-
import { existsSync as existsSync21, readFileSync as
|
|
75678
|
-
import
|
|
75679
|
-
import
|
|
75765
|
+
import { existsSync as existsSync21, readFileSync as readFileSync23 } from "node:fs";
|
|
75766
|
+
import path46 from "node:path";
|
|
75767
|
+
import os17 from "node:os";
|
|
75680
75768
|
import { createHash as createHash15 } from "node:crypto";
|
|
75681
75769
|
function errorText(error) {
|
|
75682
75770
|
return error instanceof Error ? error.message : "installed source could not be read";
|
|
@@ -75685,39 +75773,39 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75685
75773
|
const tail = stderrTail(result.stderr);
|
|
75686
75774
|
return `\`${command.command} ${command.args.join(" ")}\` failed${tail ? `: ${tail}` : ""}`;
|
|
75687
75775
|
}, fixFor = (host, selector = "") => host === "pi" ? `pi update --extension ${selector || "npm:@brainervirus/workit-pi"}` : host === "codex" ? `codex plugin marketplace upgrade ${CODEX_MARKETPLACE} && codex plugin add workit@${CODEX_MARKETPLACE}` : host === "claude-code" ? "claude plugin marketplace update workit && claude plugin update workit@workit" : host === "opencode" ? OPENCODE_UPDATE : host === "cursor" ? "workit upgrade --hosts=cursor" : CLI_FIX, upgradePaths = (deps) => {
|
|
75688
|
-
const home = deps.home ?? deps.env?.HOME ??
|
|
75776
|
+
const home = deps.home ?? deps.env?.HOME ?? os17.homedir();
|
|
75689
75777
|
const env = {
|
|
75690
75778
|
...process.env,
|
|
75691
75779
|
...deps.home || deps.env?.HOME ? {
|
|
75692
75780
|
HOME: home,
|
|
75693
|
-
CODEX_HOME:
|
|
75694
|
-
CLAUDE_CONFIG_DIR:
|
|
75695
|
-
PI_CODING_AGENT_DIR:
|
|
75696
|
-
XDG_CONFIG_HOME:
|
|
75781
|
+
CODEX_HOME: path46.join(home, ".codex"),
|
|
75782
|
+
CLAUDE_CONFIG_DIR: path46.join(home, ".claude"),
|
|
75783
|
+
PI_CODING_AGENT_DIR: path46.join(home, ".pi/agent"),
|
|
75784
|
+
XDG_CONFIG_HOME: path46.join(home, ".config"),
|
|
75697
75785
|
WORKFLOW_TOOLKIT_CONFIG: undefined,
|
|
75698
75786
|
WORKFLOW_TOOLKIT_CONFIG_DIR: undefined
|
|
75699
75787
|
} : {},
|
|
75700
75788
|
...deps.env,
|
|
75701
75789
|
HOME: home
|
|
75702
75790
|
};
|
|
75703
|
-
const xdg = env.XDG_CONFIG_HOME ||
|
|
75704
|
-
const codexHome = env.CODEX_HOME ??
|
|
75791
|
+
const xdg = env.XDG_CONFIG_HOME || path46.join(home, ".config");
|
|
75792
|
+
const codexHome = env.CODEX_HOME ?? path46.join(home, ".codex");
|
|
75705
75793
|
return {
|
|
75706
75794
|
home,
|
|
75707
75795
|
env,
|
|
75708
|
-
configDir: env
|
|
75709
|
-
opencodeConfig:
|
|
75710
|
-
piSettings:
|
|
75796
|
+
configDir: workitConfigDir(env),
|
|
75797
|
+
opencodeConfig: path46.join(xdg, "opencode/opencode.json"),
|
|
75798
|
+
piSettings: path46.join(env.PI_CODING_AGENT_DIR ?? path46.join(home, ".pi/agent"), "settings.json"),
|
|
75711
75799
|
codexHome,
|
|
75712
|
-
codexConfig:
|
|
75713
|
-
cursorRoot:
|
|
75800
|
+
codexConfig: path46.join(codexHome, "config.toml"),
|
|
75801
|
+
cursorRoot: path46.join(home, ".cursor/plugins/local/workit")
|
|
75714
75802
|
};
|
|
75715
75803
|
}, object2 = (file) => {
|
|
75716
75804
|
if (!existsSync21(file))
|
|
75717
75805
|
return null;
|
|
75718
75806
|
let data;
|
|
75719
75807
|
try {
|
|
75720
|
-
data = JSON.parse(
|
|
75808
|
+
data = JSON.parse(readFileSync23(file, "utf8"));
|
|
75721
75809
|
} catch {
|
|
75722
75810
|
throw new Error(`${file} is not valid JSON; use the native host to inspect JSONC settings`);
|
|
75723
75811
|
}
|
|
@@ -75730,7 +75818,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75730
75818
|
} catch {
|
|
75731
75819
|
return null;
|
|
75732
75820
|
}
|
|
75733
|
-
}, digest2 = (file) => existsSync21(file) ? createHash15("sha256").update(
|
|
75821
|
+
}, digest2 = (file) => existsSync21(file) ? createHash15("sha256").update(readFileSync23(file)).digest("hex") : "missing", runner = (deps) => deps.run ?? ((command, args) => {
|
|
75734
75822
|
const { home, env } = upgradePaths(deps);
|
|
75735
75823
|
let step;
|
|
75736
75824
|
try {
|
|
@@ -75761,10 +75849,10 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75761
75849
|
stderr: `Cannot safely execute batch shim ${step.command}`
|
|
75762
75850
|
});
|
|
75763
75851
|
const childEnv = { ...process.env, ...env, HOME: home };
|
|
75764
|
-
childEnv.CODEX_HOME = env.CODEX_HOME ??
|
|
75765
|
-
childEnv.PI_CODING_AGENT_DIR = env.PI_CODING_AGENT_DIR ??
|
|
75766
|
-
childEnv.CLAUDE_CONFIG_DIR = env.CLAUDE_CONFIG_DIR ??
|
|
75767
|
-
childEnv.XDG_CONFIG_HOME = env.XDG_CONFIG_HOME ??
|
|
75852
|
+
childEnv.CODEX_HOME = env.CODEX_HOME ?? path46.join(home, ".codex");
|
|
75853
|
+
childEnv.PI_CODING_AGENT_DIR = env.PI_CODING_AGENT_DIR ?? path46.join(home, ".pi", "agent");
|
|
75854
|
+
childEnv.CLAUDE_CONFIG_DIR = env.CLAUDE_CONFIG_DIR ?? path46.join(home, ".claude");
|
|
75855
|
+
childEnv.XDG_CONFIG_HOME = env.XDG_CONFIG_HOME ?? path46.join(home, ".config");
|
|
75768
75856
|
return new Promise((resolve) => {
|
|
75769
75857
|
let stdout = "";
|
|
75770
75858
|
let stderr = "";
|
|
@@ -75807,9 +75895,9 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75807
75895
|
}, piInstalledVersion = (listing, selector) => {
|
|
75808
75896
|
const lines = listing.split(/\r?\n/).map((line) => line.trim());
|
|
75809
75897
|
const index = lines.indexOf(selector);
|
|
75810
|
-
if (index < 0 || !lines[index + 1] || !
|
|
75898
|
+
if (index < 0 || !lines[index + 1] || !path46.isAbsolute(lines[index + 1]))
|
|
75811
75899
|
return;
|
|
75812
|
-
const found = objectOrNull(
|
|
75900
|
+
const found = objectOrNull(path46.join(lines[index + 1], "package.json"));
|
|
75813
75901
|
return found?.name === "@brainervirus/workit-pi" ? found.version : undefined;
|
|
75814
75902
|
}, versionAtLeast = (installed, latest) => {
|
|
75815
75903
|
if (!/^\d+\.\d+\.\d+$/.test(installed))
|
|
@@ -75828,6 +75916,7 @@ var LAUNCH_HOSTS, HOSTS2, LIVE_HOSTS, OPENCODE_PACKAGE = "@brainervirus/workit-o
|
|
|
75828
75916
|
};
|
|
75829
75917
|
var init_shared = __esm(() => {
|
|
75830
75918
|
init_host_install();
|
|
75919
|
+
init_update_settings();
|
|
75831
75920
|
LAUNCH_HOSTS = ["opencode", "cursor", "codex", "pi"];
|
|
75832
75921
|
HOSTS2 = [...LAUNCH_HOSTS, "claude-code"];
|
|
75833
75922
|
LIVE_HOSTS = new Set(["opencode", "claude-code"]);
|
|
@@ -75835,12 +75924,12 @@ var init_shared = __esm(() => {
|
|
|
75835
75924
|
});
|
|
75836
75925
|
|
|
75837
75926
|
// packages/workit-cli/src/upgrade/processes.ts
|
|
75838
|
-
import
|
|
75927
|
+
import path47 from "node:path";
|
|
75839
75928
|
var PROCESS_HOSTS, SCRIPT_RUNTIMES, classifyProcess = (proc) => {
|
|
75840
75929
|
if (proc.state.startsWith("Z") || proc.args.includes("<defunct>"))
|
|
75841
75930
|
return null;
|
|
75842
75931
|
const argv0 = proc.args.trim().split(/\s+/)[0] ?? "";
|
|
75843
|
-
const baseName = (value) =>
|
|
75932
|
+
const baseName = (value) => path47.basename(value.replaceAll("\\", "/")).replace(/^\[|\]$/g, "").replace(/\.exe$/i, "").toLowerCase();
|
|
75844
75933
|
let host = PROCESS_HOSTS[baseName(argv0)];
|
|
75845
75934
|
if (!host && SCRIPT_RUNTIMES.has(baseName(argv0))) {
|
|
75846
75935
|
const script = proc.args.trim().split(/\s+/).slice(1).find((arg) => !arg.startsWith("-"));
|
|
@@ -75890,8 +75979,8 @@ var init_processes = __esm(() => {
|
|
|
75890
75979
|
});
|
|
75891
75980
|
|
|
75892
75981
|
// packages/workit-cli/src/upgrade/apply.ts
|
|
75893
|
-
import { existsSync as existsSync22, readdirSync as readdirSync12, mkdirSync as
|
|
75894
|
-
import
|
|
75982
|
+
import { existsSync as existsSync22, readdirSync as readdirSync12, mkdirSync as mkdirSync12, copyFileSync as copyFileSync6, chmodSync as chmodSync2, cpSync as cpSync5 } from "node:fs";
|
|
75983
|
+
import path48 from "node:path";
|
|
75895
75984
|
import { createHash as createHash16 } from "node:crypto";
|
|
75896
75985
|
async function applyUpgrade(plan, deps = {}) {
|
|
75897
75986
|
const hosts = [...plan.failed];
|
|
@@ -75926,11 +76015,11 @@ async function applyUpgrade(plan, deps = {}) {
|
|
|
75926
76015
|
};
|
|
75927
76016
|
const paths = upgradePaths(deps);
|
|
75928
76017
|
const { home, configDir } = paths;
|
|
75929
|
-
const backup =
|
|
75930
|
-
|
|
76018
|
+
const backup = path48.join(home, ".local/state/workit/upgrades", new Date().toISOString().replaceAll(":", "-"));
|
|
76019
|
+
mkdirSync12(backup, { recursive: true, mode: 448 });
|
|
75931
76020
|
for (const file of Object.keys(plan.configDigests))
|
|
75932
76021
|
if (existsSync22(file)) {
|
|
75933
|
-
const target =
|
|
76022
|
+
const target = path48.join(backup, createHash16("sha256").update(file).digest("hex").slice(0, 12) + "-" + path48.basename(file));
|
|
75934
76023
|
copyFileSync6(file, target);
|
|
75935
76024
|
chmodSync2(target, 384);
|
|
75936
76025
|
}
|
|
@@ -75953,7 +76042,7 @@ async function applyUpgrade(plan, deps = {}) {
|
|
|
75953
76042
|
let cursorBackupError = null;
|
|
75954
76043
|
if (plan.entries.some((entry) => entry.host === "cursor") && existsSync22(paths.cursorRoot))
|
|
75955
76044
|
try {
|
|
75956
|
-
cpSync5(paths.cursorRoot,
|
|
76045
|
+
cpSync5(paths.cursorRoot, path48.join(backup, "cursor-package"), {
|
|
75957
76046
|
recursive: true
|
|
75958
76047
|
});
|
|
75959
76048
|
} catch (error) {
|
|
@@ -76101,7 +76190,7 @@ var briefDetail = (detail) => {
|
|
|
76101
76190
|
const lines = detail.split(/\r?\n/).filter((line) => line.trim());
|
|
76102
76191
|
return (lines.length > 6 ? [lines[0], ...lines.slice(-5)] : lines).join(" | ");
|
|
76103
76192
|
}, codexPluginRoot = (codexHome) => {
|
|
76104
|
-
const dir =
|
|
76193
|
+
const dir = path48.join(codexHome, "plugins", "cache", CODEX_MARKETPLACE, "workit");
|
|
76105
76194
|
let versions = [];
|
|
76106
76195
|
try {
|
|
76107
76196
|
versions = readdirSync12(dir).filter((version) => /^\d+\.\d+\.\d+$/.test(version));
|
|
@@ -76109,7 +76198,7 @@ var briefDetail = (detail) => {
|
|
|
76109
76198
|
return null;
|
|
76110
76199
|
}
|
|
76111
76200
|
const newest = versions.reduce((best, version) => best && versionAtLeast(best, version) ? best : version, null);
|
|
76112
|
-
return newest ?
|
|
76201
|
+
return newest ? path48.join(dir, newest) : null;
|
|
76113
76202
|
}, opencodeVersion = async (run) => {
|
|
76114
76203
|
const listing = await run("opencode", ["plugin", "list"]);
|
|
76115
76204
|
if (listing.status !== 0)
|
|
@@ -76156,8 +76245,8 @@ ${result.stderr}`;
|
|
|
76156
76245
|
if (result.exitCode !== 0)
|
|
76157
76246
|
break;
|
|
76158
76247
|
}
|
|
76159
|
-
const cursorSettings =
|
|
76160
|
-
const cursorMcp =
|
|
76248
|
+
const cursorSettings = path48.join(home, ".cursor", "settings.json");
|
|
76249
|
+
const cursorMcp = path48.join(home, ".cursor", "mcp.json");
|
|
76161
76250
|
const preview = {
|
|
76162
76251
|
ok: true,
|
|
76163
76252
|
blocked: [],
|
|
@@ -76169,7 +76258,7 @@ ${result.stderr}`;
|
|
|
76169
76258
|
{
|
|
76170
76259
|
type: "install-host",
|
|
76171
76260
|
platform: "cursor",
|
|
76172
|
-
path:
|
|
76261
|
+
path: path48.join(home, ".cursor/plugins/local/.workit-package-bootstrap"),
|
|
76173
76262
|
commands
|
|
76174
76263
|
},
|
|
76175
76264
|
{ type: "install-adapter", platform: "cursor", path: paths.cursorRoot },
|
|
@@ -76188,7 +76277,7 @@ ${result.stderr}`;
|
|
|
76188
76277
|
stderr: "command did not run"
|
|
76189
76278
|
}
|
|
76190
76279
|
});
|
|
76191
|
-
const installed = objectOrNull(
|
|
76280
|
+
const installed = objectOrNull(path48.join(paths.cursorRoot, "package.json"));
|
|
76192
76281
|
const problems = result.entries.filter((one) => one.status === "Failed").map((one) => one.detail ?? `${one.file} failed`);
|
|
76193
76282
|
if (problems.length)
|
|
76194
76283
|
return fail(`Cursor install failed: ${problems.map(briefDetail).join("; ")}`);
|
|
@@ -76258,7 +76347,7 @@ ${result.stderr}`;
|
|
|
76258
76347
|
};
|
|
76259
76348
|
}, refreshCodexAgents = async (run, codexHome) => {
|
|
76260
76349
|
const root = codexPluginRoot(codexHome);
|
|
76261
|
-
const launcher = root &&
|
|
76350
|
+
const launcher = root && path48.join(root, "dist", "launch-mcp.js");
|
|
76262
76351
|
if (!launcher || !existsSync22(launcher))
|
|
76263
76352
|
return { ok: true, note: "" };
|
|
76264
76353
|
const fix = `node ${JSON.stringify(launcher)} --install-agents`;
|
|
@@ -76278,8 +76367,8 @@ ${result.stderr}`;
|
|
|
76278
76367
|
const currentRoot = await run("npm", ["root", "--global"]);
|
|
76279
76368
|
if (currentRoot.status !== 0 || currentRoot.stdout.trim() !== cli.root)
|
|
76280
76369
|
return fail("Global npm location changed; preview again");
|
|
76281
|
-
const cliBackup =
|
|
76282
|
-
cpSync5(
|
|
76370
|
+
const cliBackup = path48.join(backup, "cli-package");
|
|
76371
|
+
cpSync5(path48.join(cli.root, "@brainervirus/workit-cli"), cliBackup, {
|
|
76283
76372
|
recursive: true
|
|
76284
76373
|
});
|
|
76285
76374
|
const install = await run("npm", [
|
|
@@ -76288,8 +76377,8 @@ ${result.stderr}`;
|
|
|
76288
76377
|
`@brainervirus/workit-cli@${cli.latest}`
|
|
76289
76378
|
]);
|
|
76290
76379
|
if (install.status !== 0)
|
|
76291
|
-
return fail(`CLI update failed${stderrTail(install.stderr) ? ` (${stderrTail(install.stderr)})` : ""}; preserved package at ${cliBackup}; use npm to repair or run node ${
|
|
76292
|
-
const installed = objectOrNull(
|
|
76380
|
+
return fail(`CLI update failed${stderrTail(install.stderr) ? ` (${stderrTail(install.stderr)})` : ""}; preserved package at ${cliBackup}; use npm to repair or run node ${path48.join(cliBackup, "dist/index.js")}`);
|
|
76381
|
+
const installed = objectOrNull(path48.join(cli.root, "@brainervirus/workit-cli/package.json"));
|
|
76293
76382
|
if (installed?.name !== "@brainervirus/workit-cli" || installed.version !== cli.latest)
|
|
76294
76383
|
return fail(`CLI update did not verify the requested version; preserved package at ${cliBackup}`);
|
|
76295
76384
|
return {
|
|
@@ -76308,10 +76397,171 @@ var init_apply = __esm(() => {
|
|
|
76308
76397
|
init_shared();
|
|
76309
76398
|
});
|
|
76310
76399
|
|
|
76400
|
+
// packages/workit-cli/src/update-check.ts
|
|
76401
|
+
var exports_update_check = {};
|
|
76402
|
+
__export(exports_update_check, {
|
|
76403
|
+
CLI_PACKAGE: () => CLI_PACKAGE2,
|
|
76404
|
+
launchUpdateCheck: () => launchUpdateCheck,
|
|
76405
|
+
readUpdateCache: () => readUpdateCache,
|
|
76406
|
+
readUpdatesMode: () => readUpdatesMode,
|
|
76407
|
+
refreshUpdateCache: () => refreshUpdateCache,
|
|
76408
|
+
writeUpdateCache: () => writeUpdateCache,
|
|
76409
|
+
writeUpdatesMode: () => writeUpdatesMode
|
|
76410
|
+
});
|
|
76411
|
+
import { spawn as spawn3, spawnSync as spawnSync17 } from "node:child_process";
|
|
76412
|
+
import { readFileSync as readFileSync24 } from "node:fs";
|
|
76413
|
+
import path49 from "node:path";
|
|
76414
|
+
async function launchUpdateCheck(context, deps) {
|
|
76415
|
+
if (!interactiveLaunch(context, deps))
|
|
76416
|
+
return;
|
|
76417
|
+
const mode = readUpdatesMode(deps.env);
|
|
76418
|
+
if (mode === "off")
|
|
76419
|
+
return;
|
|
76420
|
+
const now = (deps.now ?? Date.now)();
|
|
76421
|
+
const cache = readUpdateCache(deps.env);
|
|
76422
|
+
if (cache.checkedAt === undefined || now - cache.checkedAt >= UPDATE_TTL_MS) {
|
|
76423
|
+
writeUpdateCache(deps.env, { ...cache, checkedAt: now });
|
|
76424
|
+
(deps.refresh ?? (() => startRefresh(deps.env)))();
|
|
76425
|
+
}
|
|
76426
|
+
const installed = deps.installed ?? package_default.version;
|
|
76427
|
+
const latest = cache.latest;
|
|
76428
|
+
if (!latest || versionAtLeast(installed, latest))
|
|
76429
|
+
return;
|
|
76430
|
+
if (cache.snoozedAt !== undefined && now - cache.snoozedAt < UPDATE_TTL_MS)
|
|
76431
|
+
return;
|
|
76432
|
+
const style = createStyle({ stream: deps.stderr, env: deps.env });
|
|
76433
|
+
if (mode === "prompt") {
|
|
76434
|
+
if (cache.skipped === latest)
|
|
76435
|
+
return;
|
|
76436
|
+
let answer;
|
|
76437
|
+
try {
|
|
76438
|
+
answer = await (deps.ask ?? defaultAsk)(`${style.bold("Workit update available:")} ${installed} -> ${style.ok(latest)} ${style.command("[u]")}pgrade now / ${style.command("[s]")}kip for now / ${style.command("[n]")}ever for this version: `);
|
|
76439
|
+
} catch (error) {
|
|
76440
|
+
if (!isPromptAbort(error))
|
|
76441
|
+
return;
|
|
76442
|
+
deps.write(`
|
|
76443
|
+
Cancelled.
|
|
76444
|
+
`);
|
|
76445
|
+
return CANCELLED_EXIT2;
|
|
76446
|
+
}
|
|
76447
|
+
const choice = answer.trim().toLowerCase();
|
|
76448
|
+
if (choice === "n" || choice === "never") {
|
|
76449
|
+
writeUpdateCache(deps.env, {
|
|
76450
|
+
...readUpdateCache(deps.env),
|
|
76451
|
+
skipped: latest
|
|
76452
|
+
});
|
|
76453
|
+
return;
|
|
76454
|
+
}
|
|
76455
|
+
if (choice !== "u" && choice !== "upgrade") {
|
|
76456
|
+
writeUpdateCache(deps.env, {
|
|
76457
|
+
...readUpdateCache(deps.env),
|
|
76458
|
+
snoozedAt: now
|
|
76459
|
+
});
|
|
76460
|
+
return;
|
|
76461
|
+
}
|
|
76462
|
+
} else {
|
|
76463
|
+
deps.write(`${style.bold("Workit update:")} upgrading ${installed} -> ${latest} (CLI and host plugins; updates=auto)
|
|
76464
|
+
`);
|
|
76465
|
+
}
|
|
76466
|
+
writeUpdateCache(deps.env, { ...readUpdateCache(deps.env), snoozedAt: now });
|
|
76467
|
+
const outcome = await (deps.upgrade ?? defaultUpgrade)();
|
|
76468
|
+
if (outcome.code !== 0 && outcome.failed.length)
|
|
76469
|
+
deps.write(`${style.warn("Upgrade incomplete:")} ${outcome.failed.map((row) => `${row.host} failed${row.fix ? ` (fix: ${row.fix})` : ""}`).join("; ")}
|
|
76470
|
+
`);
|
|
76471
|
+
const onDisk = (deps.cliOnDisk ?? defaultCliOnDisk)();
|
|
76472
|
+
if (!onDisk || onDisk === installed) {
|
|
76473
|
+
if (outcome.code !== 0)
|
|
76474
|
+
deps.write(`${style.warn("Upgrade did not finish;")} running your command with ${installed}.
|
|
76475
|
+
`);
|
|
76476
|
+
return;
|
|
76477
|
+
}
|
|
76478
|
+
return (deps.reexec ?? defaultReexec)(context.argv);
|
|
76479
|
+
}
|
|
76480
|
+
var CLI_PACKAGE2 = "@brainervirus/workit-cli", UPDATE_TTL_MS, QUIET_ENV = "WORKIT_UPDATE_CHECK", REFRESH_ENV = "WORKIT_UPDATE_REFRESH", AGENT_VARIABLES, AGENT_PREFIXES, PROFILE_VARIABLES, agentHostMarker = (env) => Object.keys(env).find((key) => env[key] !== undefined && !PROFILE_VARIABLES.has(key) && (AGENT_VARIABLES.has(key) || AGENT_PREFIXES.some((prefix) => key.startsWith(prefix)))), SILENT_COMMANDS, interactiveLaunch = (context, deps) => !SILENT_COMMANDS.has(context.command) && deps.env[QUIET_ENV] !== "0" && deps.stdin.isTTY === true && deps.stdout.isTTY === true && deps.stderr.isTTY === true && terminalMode({ stream: deps.stderr, env: deps.env, json: context.json }) !== "off" && agentHostMarker(deps.env) === undefined, CANCELLED_EXIT2 = 130, defaultCliOnDisk = () => {
|
|
76481
|
+
const script = process.argv[1];
|
|
76482
|
+
if (!script)
|
|
76483
|
+
return;
|
|
76484
|
+
let dir = path49.dirname(script);
|
|
76485
|
+
for (let depth = 0;depth < 4; depth += 1, dir = path49.dirname(dir)) {
|
|
76486
|
+
try {
|
|
76487
|
+
const found = JSON.parse(readFileSync24(path49.join(dir, "package.json"), "utf8"));
|
|
76488
|
+
if (found.name === CLI_PACKAGE2 && typeof found.version === "string")
|
|
76489
|
+
return found.version;
|
|
76490
|
+
} catch {}
|
|
76491
|
+
}
|
|
76492
|
+
return;
|
|
76493
|
+
}, defaultAsk = async (question) => (await Promise.resolve().then(() => (init_prompt(), exports_prompt))).askLine(question, process.stderr), defaultUpgrade = async () => {
|
|
76494
|
+
const failed = [];
|
|
76495
|
+
const code = await (await Promise.resolve().then(() => (init_upgrade(), exports_upgrade))).runUpgradeCommand(["--yes"], {
|
|
76496
|
+
out: process.stderr,
|
|
76497
|
+
onResult: (hosts) => {
|
|
76498
|
+
for (const row of hosts)
|
|
76499
|
+
if (row.status === "failed")
|
|
76500
|
+
failed.push({ host: row.host, fix: row.fix });
|
|
76501
|
+
}
|
|
76502
|
+
});
|
|
76503
|
+
return { code, failed };
|
|
76504
|
+
}, defaultReexec = (argv) => {
|
|
76505
|
+
const script = process.argv[1];
|
|
76506
|
+
if (!script)
|
|
76507
|
+
return;
|
|
76508
|
+
const result = spawnSync17(process.execPath, [script, ...argv], {
|
|
76509
|
+
stdio: "inherit",
|
|
76510
|
+
env: { ...process.env, [QUIET_ENV]: "0" }
|
|
76511
|
+
});
|
|
76512
|
+
return result.error ? undefined : result.status ?? 1;
|
|
76513
|
+
}, startRefresh = (env) => {
|
|
76514
|
+
const script = process.argv[1];
|
|
76515
|
+
if (!script)
|
|
76516
|
+
return;
|
|
76517
|
+
try {
|
|
76518
|
+
spawn3(process.execPath, [script], {
|
|
76519
|
+
detached: true,
|
|
76520
|
+
stdio: "ignore",
|
|
76521
|
+
windowsHide: true,
|
|
76522
|
+
env: { ...env, [REFRESH_ENV]: "1", [QUIET_ENV]: "0" }
|
|
76523
|
+
}).unref();
|
|
76524
|
+
} catch {}
|
|
76525
|
+
}, refreshUpdateCache = (env, options = {}) => {
|
|
76526
|
+
let latest;
|
|
76527
|
+
try {
|
|
76528
|
+
latest = registryVersion(options.run ?? runner({ env }), CLI_PACKAGE2);
|
|
76529
|
+
} catch {
|
|
76530
|
+
latest = undefined;
|
|
76531
|
+
}
|
|
76532
|
+
const cache = readUpdateCache(env);
|
|
76533
|
+
writeUpdateCache(env, {
|
|
76534
|
+
...cache,
|
|
76535
|
+
checkedAt: (options.now ?? Date.now)(),
|
|
76536
|
+
...latest ? { latest } : {}
|
|
76537
|
+
});
|
|
76538
|
+
};
|
|
76539
|
+
var init_update_check = __esm(() => {
|
|
76540
|
+
init_package();
|
|
76541
|
+
init_prompt();
|
|
76542
|
+
init_style();
|
|
76543
|
+
init_shared();
|
|
76544
|
+
init_update_settings();
|
|
76545
|
+
UPDATE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
76546
|
+
AGENT_VARIABLES = new Set(["CLAUDECODE", "CLAUDE_CODE_ENTRYPOINT"]);
|
|
76547
|
+
AGENT_PREFIXES = ["CODEX_", "OPENCODE", "CURSOR_", "PI_"];
|
|
76548
|
+
PROFILE_VARIABLES = new Set(["CODEX_HOME", "PI_CODING_AGENT_DIR"]);
|
|
76549
|
+
SILENT_COMMANDS = new Set([
|
|
76550
|
+
undefined,
|
|
76551
|
+
"upgrade",
|
|
76552
|
+
"help",
|
|
76553
|
+
"--help",
|
|
76554
|
+
"-h",
|
|
76555
|
+
"version",
|
|
76556
|
+
"--version",
|
|
76557
|
+
"-v"
|
|
76558
|
+
]);
|
|
76559
|
+
});
|
|
76560
|
+
|
|
76311
76561
|
// packages/workit-cli/src/upgrade/plan.ts
|
|
76312
|
-
import { existsSync as existsSync23, mkdtempSync as mkdtempSync3, rmSync as rmSync8, lstatSync as lstatSync8, readFileSync as
|
|
76313
|
-
import
|
|
76314
|
-
import
|
|
76562
|
+
import { existsSync as existsSync23, mkdtempSync as mkdtempSync3, rmSync as rmSync8, lstatSync as lstatSync8, readFileSync as readFileSync25 } from "node:fs";
|
|
76563
|
+
import path50 from "node:path";
|
|
76564
|
+
import os18 from "node:os";
|
|
76315
76565
|
function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
76316
76566
|
const paths = upgradePaths(deps);
|
|
76317
76567
|
const { home, configDir } = paths;
|
|
@@ -76334,9 +76584,9 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
|
76334
76584
|
for (const file of [
|
|
76335
76585
|
paths.opencodeConfig,
|
|
76336
76586
|
paths.opencodeConfig + "c",
|
|
76337
|
-
|
|
76338
|
-
|
|
76339
|
-
|
|
76587
|
+
path50.join(home, ".cursor/settings.json"),
|
|
76588
|
+
path50.join(home, ".cursor/mcp.json"),
|
|
76589
|
+
path50.join(paths.cursorRoot, "package.json"),
|
|
76340
76590
|
paths.codexConfig,
|
|
76341
76591
|
paths.piSettings
|
|
76342
76592
|
])
|
|
@@ -76463,7 +76713,7 @@ function previewUpgrade(hosts = HOSTS2, deps = {}) {
|
|
|
76463
76713
|
var codexRegistered = (configFile) => {
|
|
76464
76714
|
let text;
|
|
76465
76715
|
try {
|
|
76466
|
-
text =
|
|
76716
|
+
text = readFileSync25(configFile, "utf8");
|
|
76467
76717
|
} catch {
|
|
76468
76718
|
return false;
|
|
76469
76719
|
}
|
|
@@ -76506,8 +76756,8 @@ var codexRegistered = (configFile) => {
|
|
|
76506
76756
|
result.push(classify("opencode", pin));
|
|
76507
76757
|
});
|
|
76508
76758
|
guard("cursor", () => {
|
|
76509
|
-
const cursor = objectOrNull(
|
|
76510
|
-
const mcp = objectOrNull(
|
|
76759
|
+
const cursor = objectOrNull(path50.join(paths.cursorRoot, "package.json"));
|
|
76760
|
+
const mcp = objectOrNull(path50.join(home, ".cursor/mcp.json"));
|
|
76511
76761
|
const args = mcp?.mcpServers?.workit?.args ?? [];
|
|
76512
76762
|
const arg = args.find((value) => typeof value === "string" && value.startsWith("--package="));
|
|
76513
76763
|
const selector = typeof arg === "string" ? arg.slice(10) : "local";
|
|
@@ -76518,7 +76768,7 @@ var codexRegistered = (configFile) => {
|
|
|
76518
76768
|
});
|
|
76519
76769
|
return;
|
|
76520
76770
|
}
|
|
76521
|
-
const settings = objectOrNull(
|
|
76771
|
+
const settings = objectOrNull(path50.join(home, ".cursor/settings.json"));
|
|
76522
76772
|
const dirs = Array.isArray(settings?.plugin_dirs) ? settings.plugin_dirs : [];
|
|
76523
76773
|
const registered = mcp?.mcpServers?.workit !== undefined || dirs.some((dir) => String(dir).replaceAll("\\", "/").replace(/\/+$/, "").endsWith("local/workit"));
|
|
76524
76774
|
if (registered)
|
|
@@ -76533,7 +76783,7 @@ var codexRegistered = (configFile) => {
|
|
|
76533
76783
|
if (typeof source !== "string")
|
|
76534
76784
|
continue;
|
|
76535
76785
|
const npm = /^(?:npm:)?@brainervirus\/workit-pi(?:@[^/]+)?$/.test(source);
|
|
76536
|
-
const local =
|
|
76786
|
+
const local = path50.isAbsolute(source) && source.replaceAll("\\", "/").endsWith("/packages/workit-pi") && object2(path50.join(source, "package.json"))?.name === "@brainervirus/workit-pi";
|
|
76537
76787
|
if (!npm && !local)
|
|
76538
76788
|
continue;
|
|
76539
76789
|
const found = classify("pi", source);
|
|
@@ -76593,15 +76843,15 @@ var codexRegistered = (configFile) => {
|
|
|
76593
76843
|
});
|
|
76594
76844
|
return result;
|
|
76595
76845
|
}, opencodeProbe = (deps, args) => {
|
|
76596
|
-
const scratch = mkdtempSync3(
|
|
76846
|
+
const scratch = mkdtempSync3(path50.join(os18.tmpdir(), "workit-upgrade-opencode-"));
|
|
76597
76847
|
try {
|
|
76598
76848
|
return runner({
|
|
76599
76849
|
...deps,
|
|
76600
76850
|
env: {
|
|
76601
76851
|
...deps.env,
|
|
76602
|
-
XDG_DATA_HOME:
|
|
76603
|
-
XDG_STATE_HOME:
|
|
76604
|
-
XDG_CACHE_HOME:
|
|
76852
|
+
XDG_DATA_HOME: path50.join(scratch, "data"),
|
|
76853
|
+
XDG_STATE_HOME: path50.join(scratch, "state"),
|
|
76854
|
+
XDG_CACHE_HOME: path50.join(scratch, "cache")
|
|
76605
76855
|
}
|
|
76606
76856
|
})("opencode", args);
|
|
76607
76857
|
} finally {
|
|
@@ -76609,7 +76859,7 @@ var codexRegistered = (configFile) => {
|
|
|
76609
76859
|
}
|
|
76610
76860
|
}, planCli = (plan, run) => {
|
|
76611
76861
|
const root = run("npm", ["root", "--global"]);
|
|
76612
|
-
if (root.status !== 0 || !
|
|
76862
|
+
if (root.status !== 0 || !path50.isAbsolute(root.stdout.trim())) {
|
|
76613
76863
|
plan.skipped.push({
|
|
76614
76864
|
host: "cli",
|
|
76615
76865
|
reason: "global npm location could not be verified",
|
|
@@ -76617,9 +76867,9 @@ var codexRegistered = (configFile) => {
|
|
|
76617
76867
|
});
|
|
76618
76868
|
return;
|
|
76619
76869
|
}
|
|
76620
|
-
const packageFile =
|
|
76870
|
+
const packageFile = path50.join(root.stdout.trim(), "@brainervirus/workit-cli/package.json");
|
|
76621
76871
|
const installed = objectOrNull(packageFile);
|
|
76622
|
-
if (installed?.name !== "@brainervirus/workit-cli" || lstatSync8(
|
|
76872
|
+
if (installed?.name !== "@brainervirus/workit-cli" || lstatSync8(path50.dirname(packageFile)).isSymbolicLink()) {
|
|
76623
76873
|
plan.skipped.push({
|
|
76624
76874
|
host: "cli",
|
|
76625
76875
|
reason: "no managed global CLI install (local links preserved); use npx @brainervirus/workit-cli@latest"
|
|
@@ -76656,6 +76906,132 @@ var init_plan = __esm(() => {
|
|
|
76656
76906
|
init_shared();
|
|
76657
76907
|
});
|
|
76658
76908
|
|
|
76909
|
+
// packages/workit-cli/src/upgrade/check.ts
|
|
76910
|
+
import path51 from "node:path";
|
|
76911
|
+
function runUpdateCheck(json, deps) {
|
|
76912
|
+
const out = deps.out ?? process.stdout;
|
|
76913
|
+
const paths = upgradePaths(deps);
|
|
76914
|
+
const run = runner(deps);
|
|
76915
|
+
const latest = (name) => registryVersion(run, name);
|
|
76916
|
+
const cliLatest = latest(CLI_PACKAGE2);
|
|
76917
|
+
if (cliLatest)
|
|
76918
|
+
writeUpdateCache(paths.env, {
|
|
76919
|
+
...readUpdateCache(paths.env),
|
|
76920
|
+
checkedAt: Date.now(),
|
|
76921
|
+
latest: cliLatest
|
|
76922
|
+
});
|
|
76923
|
+
const components = [
|
|
76924
|
+
{
|
|
76925
|
+
component: "cli",
|
|
76926
|
+
package: CLI_PACKAGE2,
|
|
76927
|
+
installed: package_default.version,
|
|
76928
|
+
latest: cliLatest ?? null,
|
|
76929
|
+
status: statusOf(package_default.version, cliLatest)
|
|
76930
|
+
}
|
|
76931
|
+
];
|
|
76932
|
+
const failed = [];
|
|
76933
|
+
const installed = sources(paths, run, HOSTS2, failed);
|
|
76934
|
+
const unreadableBy = new Map(failed.map((entry) => [entry.host, entry]));
|
|
76935
|
+
const versionBy = new Map;
|
|
76936
|
+
for (const source of installed)
|
|
76937
|
+
if (!versionBy.has(source.host) || source.installedVersion)
|
|
76938
|
+
versionBy.set(source.host, versionBy.get(source.host) ?? source.installedVersion);
|
|
76939
|
+
for (const host of HOSTS2) {
|
|
76940
|
+
const name = `@brainervirus/workit-${host}`;
|
|
76941
|
+
const unreadable = unreadableBy.get(host);
|
|
76942
|
+
if (unreadable) {
|
|
76943
|
+
components.push({
|
|
76944
|
+
component: host,
|
|
76945
|
+
package: name,
|
|
76946
|
+
installed: null,
|
|
76947
|
+
latest: null,
|
|
76948
|
+
status: "unreadable",
|
|
76949
|
+
reason: unreadable.reason
|
|
76950
|
+
});
|
|
76951
|
+
continue;
|
|
76952
|
+
}
|
|
76953
|
+
if (!versionBy.has(host))
|
|
76954
|
+
continue;
|
|
76955
|
+
const version = versionBy.get(host);
|
|
76956
|
+
const newest = latest(name);
|
|
76957
|
+
components.push({
|
|
76958
|
+
component: host,
|
|
76959
|
+
package: name,
|
|
76960
|
+
installed: version ?? null,
|
|
76961
|
+
latest: newest ?? null,
|
|
76962
|
+
status: statusOf(version, newest)
|
|
76963
|
+
});
|
|
76964
|
+
}
|
|
76965
|
+
const pending = components.some((entry) => entry.status === "update" || entry.status === "unknown");
|
|
76966
|
+
const updates = readUpdatesMode(paths.env);
|
|
76967
|
+
if (json) {
|
|
76968
|
+
out.write(JSON.stringify({ updates, components, apply: pending ? APPLY : null }, null, 2) + `
|
|
76969
|
+
`);
|
|
76970
|
+
return 0;
|
|
76971
|
+
}
|
|
76972
|
+
const style = createStyle({
|
|
76973
|
+
stream: out === process.stdout ? process.stdout : undefined,
|
|
76974
|
+
env: paths.env
|
|
76975
|
+
});
|
|
76976
|
+
const width = Math.max(...components.map((entry) => entry.component.length));
|
|
76977
|
+
const rows = components.map((entry) => {
|
|
76978
|
+
const label = LABEL[entry.status];
|
|
76979
|
+
const paint = entry.status === "current" ? style.ok : entry.status === "update" ? style.warn : style.dim;
|
|
76980
|
+
return ` ${entry.component.padEnd(width)} ${entry.installed ?? "-"} -> ${entry.latest ?? "?"} ${paint(label)}${entry.reason ? ` (${entry.reason})` : ""}
|
|
76981
|
+
`;
|
|
76982
|
+
});
|
|
76983
|
+
out.write(`${style.bold("Workit versions")} (updates: ${updates}; change with ${style.command(`workit upgrade --set-updates=${UPDATES_MODES.join("|")}`)})
|
|
76984
|
+
${rows.join("")}`);
|
|
76985
|
+
const unchecked = components.filter((entry) => entry.status === "unavailable");
|
|
76986
|
+
if (unchecked.length)
|
|
76987
|
+
out.write(`${style.warn("Could not check: registry unavailable")} for ${unchecked.map((entry) => entry.component).join(", ")}
|
|
76988
|
+
`);
|
|
76989
|
+
if (pending)
|
|
76990
|
+
out.write(`Apply with: ${style.command(APPLY)} (upgrades the CLI and every host plugin together)
|
|
76991
|
+
`);
|
|
76992
|
+
else if (!unchecked.length)
|
|
76993
|
+
out.write(`${style.ok("Everything is current.")}
|
|
76994
|
+
`);
|
|
76995
|
+
out.write(`${style.dim("check only; nothing changed.")}
|
|
76996
|
+
`);
|
|
76997
|
+
return 0;
|
|
76998
|
+
}
|
|
76999
|
+
function runSetUpdates(value, deps) {
|
|
77000
|
+
const out = deps.out ?? process.stdout;
|
|
77001
|
+
if (!isUpdatesMode(value)) {
|
|
77002
|
+
out.write(SET_USAGE);
|
|
77003
|
+
return 2;
|
|
77004
|
+
}
|
|
77005
|
+
const { env, configDir } = upgradePaths(deps);
|
|
77006
|
+
const error = writeUpdatesMode(env, value);
|
|
77007
|
+
if (error) {
|
|
77008
|
+
out.write(`updates not changed: ${error}
|
|
77009
|
+
`);
|
|
77010
|
+
return 1;
|
|
77011
|
+
}
|
|
77012
|
+
out.write(`updates: ${value} (saved in ${path51.join(configDir, "config.json")})
|
|
77013
|
+
`);
|
|
77014
|
+
return 0;
|
|
77015
|
+
}
|
|
77016
|
+
var APPLY = "workit upgrade --yes", SET_USAGE, statusOf = (installed, latest) => !latest ? "unavailable" : !installed ? "unknown" : versionAtLeast(installed, latest) ? "current" : "update", LABEL;
|
|
77017
|
+
var init_check = __esm(() => {
|
|
77018
|
+
init_config();
|
|
77019
|
+
init_package();
|
|
77020
|
+
init_style();
|
|
77021
|
+
init_update_check();
|
|
77022
|
+
init_plan();
|
|
77023
|
+
init_shared();
|
|
77024
|
+
SET_USAGE = `Usage: workit upgrade --set-updates=${UPDATES_MODES.join("|")}
|
|
77025
|
+
`;
|
|
77026
|
+
LABEL = {
|
|
77027
|
+
current: "current",
|
|
77028
|
+
update: "update available",
|
|
77029
|
+
unknown: "installed version unknown",
|
|
77030
|
+
unavailable: "registry unavailable",
|
|
77031
|
+
unreadable: "could not be read"
|
|
77032
|
+
};
|
|
77033
|
+
});
|
|
77034
|
+
|
|
76659
77035
|
// packages/workit-cli/src/upgrade/report.ts
|
|
76660
77036
|
var pad2 = (text) => text.padEnd(12), PLAIN, summary = (plan, permissions, style = PLAIN) => {
|
|
76661
77037
|
const host = (name) => ` ${style.bold(pad2(name))}`;
|
|
@@ -76683,8 +77059,8 @@ var pad2 = (text) => text.padEnd(12), PLAIN, summary = (plan, permissions, style
|
|
|
76683
77059
|
return lines.join(`
|
|
76684
77060
|
`) + `
|
|
76685
77061
|
`;
|
|
76686
|
-
},
|
|
76687
|
-
const label =
|
|
77062
|
+
}, LABEL2, reasonFor = (entry) => {
|
|
77063
|
+
const label = LABEL2[entry.status];
|
|
76688
77064
|
const head = entry.reason.slice(0, label.length);
|
|
76689
77065
|
return entry.status !== "failed" && head.toLowerCase() === label.toLowerCase() && !/^[a-z]/i.test(entry.reason[label.length] ?? "") ? entry.reason.slice(label.length).replace(/^[\s:;,-]+/, "") : entry.reason;
|
|
76690
77066
|
}, PAINT, table = (hosts, style = PLAIN) => [
|
|
@@ -76692,7 +77068,7 @@ var pad2 = (text) => text.padEnd(12), PLAIN, summary = (plan, permissions, style
|
|
|
76692
77068
|
...hosts.map((entry) => {
|
|
76693
77069
|
const paint = style[PAINT[entry.status]];
|
|
76694
77070
|
const reason = reasonFor(entry);
|
|
76695
|
-
return ` ${style.bold(pad2(entry.host))}${paint(
|
|
77071
|
+
return ` ${style.bold(pad2(entry.host))}${paint(LABEL2[entry.status])}${" ".repeat(16 - LABEL2[entry.status].length)}${entry.status === "current" ? style.dim(reason) : reason}${entry.fix && entry.status !== "updated" && entry.status !== "current" ? `
|
|
76696
77072
|
${pad2("")}${"".padEnd(16)}fix: ${style.command(entry.fix)}` : ""}`;
|
|
76697
77073
|
})
|
|
76698
77074
|
].join(`
|
|
@@ -76709,7 +77085,7 @@ var pad2 = (text) => text.padEnd(12), PLAIN, summary = (plan, permissions, style
|
|
|
76709
77085
|
var init_report = __esm(() => {
|
|
76710
77086
|
init_style();
|
|
76711
77087
|
PLAIN = createStyle({ json: true });
|
|
76712
|
-
|
|
77088
|
+
LABEL2 = {
|
|
76713
77089
|
updated: "updated",
|
|
76714
77090
|
current: "already current",
|
|
76715
77091
|
skipped: "skipped",
|
|
@@ -76724,9 +77100,23 @@ var init_report = __esm(() => {
|
|
|
76724
77100
|
});
|
|
76725
77101
|
|
|
76726
77102
|
// packages/workit-cli/src/upgrade.ts
|
|
76727
|
-
|
|
77103
|
+
var exports_upgrade = {};
|
|
77104
|
+
__export(exports_upgrade, {
|
|
77105
|
+
runLaunchCommand: () => runLaunchCommand,
|
|
77106
|
+
runUpgradeCommand: () => runUpgradeCommand
|
|
77107
|
+
});
|
|
77108
|
+
import { spawnSync as spawnSync18 } from "node:child_process";
|
|
76728
77109
|
async function runUpgradeCommand(argv, deps = {}) {
|
|
76729
77110
|
const out = deps.out ?? process.stdout;
|
|
77111
|
+
const setting = argv.find((arg) => arg.startsWith("--set-updates="));
|
|
77112
|
+
if (argv.includes("--check") || setting) {
|
|
77113
|
+
const extra = argv.filter((arg) => arg !== "--check" && arg !== "--json" && arg !== setting);
|
|
77114
|
+
if (extra.length || setting && argv.length > 1) {
|
|
77115
|
+
out.write(USAGE3);
|
|
77116
|
+
return 2;
|
|
77117
|
+
}
|
|
77118
|
+
return setting ? runSetUpdates(setting.slice("--set-updates=".length), deps) : runUpdateCheck(argv.includes("--json"), deps);
|
|
77119
|
+
}
|
|
76730
77120
|
const flags = new Set(argv);
|
|
76731
77121
|
const unknown = argv.filter((arg) => !["--apply", "--confirm", "--json", "--cli", "--preview", "--yes"].includes(arg) && !arg.startsWith("--hosts="));
|
|
76732
77122
|
const hostFlag = argv.find((arg) => arg.startsWith("--hosts="))?.slice(8);
|
|
@@ -76753,7 +77143,7 @@ async function runUpgradeCommand(argv, deps = {}) {
|
|
|
76753
77143
|
plan.ok = plan.blocked.length === 0 && plan.failed.length === 0;
|
|
76754
77144
|
const { home, env } = upgradePaths(deps);
|
|
76755
77145
|
const style = createStyle({
|
|
76756
|
-
stream: out === process.stdout ? process.stdout : undefined,
|
|
77146
|
+
stream: out === process.stdout ? process.stdout : out === process.stderr ? process.stderr : undefined,
|
|
76757
77147
|
env,
|
|
76758
77148
|
json
|
|
76759
77149
|
});
|
|
@@ -76819,6 +77209,7 @@ Nothing changed.
|
|
|
76819
77209
|
...entry.status === "written" ? {} : { fix: `workit setup --hosts=${entry.host}` }
|
|
76820
77210
|
});
|
|
76821
77211
|
}
|
|
77212
|
+
deps.onResult?.(result.hosts);
|
|
76822
77213
|
const failed = !result.ok || !permissionsOk;
|
|
76823
77214
|
const cliVersion = result.hosts.some((h) => h.host === "cli" && h.status === "updated") ? plan.cli.latest : package_default.version;
|
|
76824
77215
|
const report = progress.runSync("Checking the result with workit doctor", () => (deps.doctor ?? ((version) => runDoctor({ home, env, cliVersion: version, only: "upgrade" })))(cliVersion));
|
|
@@ -76896,12 +77287,14 @@ async function runLaunchCommand(argv, deps = {}) {
|
|
|
76896
77287
|
}
|
|
76897
77288
|
if (deps.run)
|
|
76898
77289
|
return deps.run(host, hostArgs).status ?? 1;
|
|
76899
|
-
return
|
|
77290
|
+
return spawnSync18(launch.command, launch.args, {
|
|
76900
77291
|
stdio: "inherit",
|
|
76901
77292
|
env
|
|
76902
77293
|
}).status ?? 1;
|
|
76903
77294
|
}
|
|
76904
77295
|
var USAGE3 = `Usage: workit upgrade [--hosts=opencode,cursor,codex,pi,claude-code|none] [--cli] [--preview | --yes | --apply --confirm] [--json]
|
|
77296
|
+
workit upgrade --check [--json]
|
|
77297
|
+
workit upgrade --set-updates=prompt|auto|off
|
|
76905
77298
|
`;
|
|
76906
77299
|
var init_upgrade = __esm(() => {
|
|
76907
77300
|
init_package();
|
|
@@ -76911,6 +77304,7 @@ var init_upgrade = __esm(() => {
|
|
|
76911
77304
|
init_progress();
|
|
76912
77305
|
init_style();
|
|
76913
77306
|
init_apply();
|
|
77307
|
+
init_check();
|
|
76914
77308
|
init_plan();
|
|
76915
77309
|
init_report();
|
|
76916
77310
|
init_shared();
|
|
@@ -76920,8 +77314,8 @@ var init_upgrade = __esm(() => {
|
|
|
76920
77314
|
});
|
|
76921
77315
|
|
|
76922
77316
|
// packages/workit-cli/src/verbs/upgrade.ts
|
|
76923
|
-
var
|
|
76924
|
-
__export(
|
|
77317
|
+
var exports_upgrade2 = {};
|
|
77318
|
+
__export(exports_upgrade2, {
|
|
76925
77319
|
run: () => run5
|
|
76926
77320
|
});
|
|
76927
77321
|
var run5 = (argv) => runUpgradeCommand(argv);
|
|
@@ -76940,9 +77334,9 @@ var init_launch = __esm(() => {
|
|
|
76940
77334
|
});
|
|
76941
77335
|
|
|
76942
77336
|
// packages/workit-core/src/knowledge.ts
|
|
76943
|
-
import { spawnSync as
|
|
77337
|
+
import { spawnSync as spawnSync19 } from "node:child_process";
|
|
76944
77338
|
import fs20 from "node:fs";
|
|
76945
|
-
import
|
|
77339
|
+
import path52 from "node:path";
|
|
76946
77340
|
function lintKnowledge(root) {
|
|
76947
77341
|
const seen = new Set;
|
|
76948
77342
|
const unreadable = [];
|
|
@@ -77046,7 +77440,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
77046
77440
|
const end = lines.indexOf("---", 1);
|
|
77047
77441
|
return end === -1 ? lines : [...lines.slice(0, end + 1).map(() => ""), ...lines.slice(end + 1)];
|
|
77048
77442
|
}, read = (root, file) => {
|
|
77049
|
-
const full =
|
|
77443
|
+
const full = path52.join(root, file);
|
|
77050
77444
|
try {
|
|
77051
77445
|
fs20.lstatSync(full);
|
|
77052
77446
|
} catch {
|
|
@@ -77061,7 +77455,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
77061
77455
|
return "unreadable";
|
|
77062
77456
|
}
|
|
77063
77457
|
}, trackedTopLevel = (root) => {
|
|
77064
|
-
const run =
|
|
77458
|
+
const run = spawnSync19("git", ["ls-files", "-z", "--cached"], {
|
|
77065
77459
|
cwd: root,
|
|
77066
77460
|
encoding: "utf8",
|
|
77067
77461
|
maxBuffer: 256 * 1024 * 1024,
|
|
@@ -77087,7 +77481,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
77087
77481
|
}
|
|
77088
77482
|
}, brokenLinks = (root, doc, tracked) => {
|
|
77089
77483
|
const findings = [];
|
|
77090
|
-
const base =
|
|
77484
|
+
const base = path52.dirname(path52.join(root, doc.file));
|
|
77091
77485
|
const missing = (target, line, how) => findings.push({
|
|
77092
77486
|
rule: "broken-link",
|
|
77093
77487
|
file: doc.file,
|
|
@@ -77106,7 +77500,7 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
77106
77500
|
const local = localTarget(target);
|
|
77107
77501
|
if (!local)
|
|
77108
77502
|
continue;
|
|
77109
|
-
const resolved = local.startsWith("/") ?
|
|
77503
|
+
const resolved = local.startsWith("/") ? path52.join(root, local) : path52.resolve(base, local);
|
|
77110
77504
|
if (!exists2(resolved))
|
|
77111
77505
|
missing(target, index + 1, "link");
|
|
77112
77506
|
}
|
|
@@ -77116,9 +77510,9 @@ var AGENTS_BYTE_BUDGET, STEERING_FILES, NEED_BASED_FILES, STANDARDS_FILE = "CODI
|
|
|
77116
77510
|
continue;
|
|
77117
77511
|
const relative = /^\.\.?\//.test(candidate);
|
|
77118
77512
|
const first = candidate.split("/")[0];
|
|
77119
|
-
if (!relative && !(tracked ? tracked.has(first) : exists2(
|
|
77513
|
+
if (!relative && !(tracked ? tracked.has(first) : exists2(path52.join(root, first))))
|
|
77120
77514
|
continue;
|
|
77121
|
-
const resolved = relative ?
|
|
77515
|
+
const resolved = relative ? path52.resolve(base, candidate) : path52.join(root, candidate);
|
|
77122
77516
|
if (!exists2(resolved))
|
|
77123
77517
|
missing(span, index + 1, "pointer");
|
|
77124
77518
|
}
|
|
@@ -77484,11 +77878,11 @@ var init_redact = __esm(() => {
|
|
|
77484
77878
|
});
|
|
77485
77879
|
|
|
77486
77880
|
// packages/workit-core/src/checks.ts
|
|
77487
|
-
import { spawn as
|
|
77881
|
+
import { spawn as spawn4, spawnSync as spawnSync20 } from "node:child_process";
|
|
77488
77882
|
import { createHash as createHash17 } from "node:crypto";
|
|
77489
77883
|
import fs21 from "node:fs";
|
|
77490
|
-
import
|
|
77491
|
-
import
|
|
77884
|
+
import os19 from "node:os";
|
|
77885
|
+
import path53 from "node:path";
|
|
77492
77886
|
import { StringDecoder } from "node:string_decoder";
|
|
77493
77887
|
function tailLines(text, lines = TAIL_LINES) {
|
|
77494
77888
|
const all = text.replace(/\r\n?/gu, `
|
|
@@ -77608,7 +78002,7 @@ function planSpawn(argv, options) {
|
|
|
77608
78002
|
return { file: argv[0], args: [], verbatim: false, shell: true };
|
|
77609
78003
|
if (options.platform !== "win32")
|
|
77610
78004
|
return { file: argv[0], args: argv.slice(1), verbatim: false, shell: false };
|
|
77611
|
-
const win =
|
|
78005
|
+
const win = path53.win32;
|
|
77612
78006
|
const isFile = options.isFile ?? ((file) => {
|
|
77613
78007
|
try {
|
|
77614
78008
|
return fs21.statSync(file).isFile();
|
|
@@ -77666,7 +78060,7 @@ function runCheckCommand(argv, options) {
|
|
|
77666
78060
|
if (!child?.pid)
|
|
77667
78061
|
return;
|
|
77668
78062
|
if (windows)
|
|
77669
|
-
|
|
78063
|
+
spawnSync20("taskkill", ["/pid", String(child.pid), "/T", "/F"], {
|
|
77670
78064
|
stdio: "ignore",
|
|
77671
78065
|
windowsHide: true
|
|
77672
78066
|
});
|
|
@@ -77693,7 +78087,7 @@ function runCheckCommand(argv, options) {
|
|
|
77693
78087
|
`);
|
|
77694
78088
|
redactor.end();
|
|
77695
78089
|
resolve({
|
|
77696
|
-
exitCode: spawnError ? 127 : code !== null ? code : 128 + (signal ?
|
|
78090
|
+
exitCode: spawnError ? 127 : code !== null ? code : 128 + (signal ? os19.constants.signals[signal] ?? 1 : 1),
|
|
77697
78091
|
signal: signal ?? null,
|
|
77698
78092
|
timedOut,
|
|
77699
78093
|
durationMs: Date.now() - started,
|
|
@@ -77713,7 +78107,7 @@ function runCheckCommand(argv, options) {
|
|
|
77713
78107
|
shell: plan.shell
|
|
77714
78108
|
};
|
|
77715
78109
|
try {
|
|
77716
|
-
child =
|
|
78110
|
+
child = spawn4(plan.file, plan.args, spawnOptions);
|
|
77717
78111
|
} catch (error) {
|
|
77718
78112
|
finish(null, null, error.code ?? error.message);
|
|
77719
78113
|
return;
|
|
@@ -77770,10 +78164,10 @@ function runCheckCommand(argv, options) {
|
|
|
77770
78164
|
function storeLog(storeRoot, log) {
|
|
77771
78165
|
const digest = logDigest(log);
|
|
77772
78166
|
const ref = `blobs/logs/${digest.slice("sha256:".length)}.log`;
|
|
77773
|
-
const file =
|
|
78167
|
+
const file = path53.join(storeRoot, ref);
|
|
77774
78168
|
try {
|
|
77775
78169
|
if (!fs21.existsSync(file)) {
|
|
77776
|
-
fs21.mkdirSync(
|
|
78170
|
+
fs21.mkdirSync(path53.dirname(file), { recursive: true });
|
|
77777
78171
|
const temp = `${file}.${process.pid}.${Date.now()}.tmp`;
|
|
77778
78172
|
fs21.writeFileSync(temp, log, { mode: 384 });
|
|
77779
78173
|
fs21.renameSync(temp, file);
|
|
@@ -77786,7 +78180,7 @@ function storeLog(storeRoot, log) {
|
|
|
77786
78180
|
function pruneCheckLogs(storeRoot, options = {}) {
|
|
77787
78181
|
const limits = { ...LOG_RETENTION, ...options.retention };
|
|
77788
78182
|
const now = options.now ?? Date.now();
|
|
77789
|
-
const dir =
|
|
78183
|
+
const dir = path53.join(storeRoot, "blobs", "logs");
|
|
77790
78184
|
const report = { removed: 0, removedBytes: 0, kept: 0 };
|
|
77791
78185
|
let names;
|
|
77792
78186
|
try {
|
|
@@ -77796,7 +78190,7 @@ function pruneCheckLogs(storeRoot, options = {}) {
|
|
|
77796
78190
|
}
|
|
77797
78191
|
const files = names.flatMap((name) => {
|
|
77798
78192
|
try {
|
|
77799
|
-
const stat = fs21.statSync(
|
|
78193
|
+
const stat = fs21.statSync(path53.join(dir, name));
|
|
77800
78194
|
return stat.isFile() ? [{ name, size: stat.size, mtimeMs: stat.mtimeMs }] : [];
|
|
77801
78195
|
} catch {
|
|
77802
78196
|
return [];
|
|
@@ -77815,7 +78209,7 @@ function pruneCheckLogs(storeRoot, options = {}) {
|
|
|
77815
78209
|
continue;
|
|
77816
78210
|
if (!options.dryRun)
|
|
77817
78211
|
try {
|
|
77818
|
-
fs21.rmSync(
|
|
78212
|
+
fs21.rmSync(path53.join(dir, file.name), { force: true });
|
|
77819
78213
|
} catch {
|
|
77820
78214
|
continue;
|
|
77821
78215
|
}
|
|
@@ -78468,12 +78862,12 @@ var init_workspace = __esm(() => {
|
|
|
78468
78862
|
|
|
78469
78863
|
// packages/workit-core/src/core/heavy-rules.ts
|
|
78470
78864
|
import fs22 from "node:fs";
|
|
78471
|
-
import
|
|
78865
|
+
import path54 from "node:path";
|
|
78472
78866
|
function gitTop(cwd) {
|
|
78473
|
-
for (let dir =
|
|
78474
|
-
if (fs22.existsSync(
|
|
78867
|
+
for (let dir = path54.resolve(cwd);; dir = path54.dirname(dir)) {
|
|
78868
|
+
if (fs22.existsSync(path54.join(dir, ".git")))
|
|
78475
78869
|
return dir;
|
|
78476
|
-
if (
|
|
78870
|
+
if (path54.dirname(dir) === dir)
|
|
78477
78871
|
return null;
|
|
78478
78872
|
}
|
|
78479
78873
|
}
|
|
@@ -78514,19 +78908,19 @@ var init_heavy_rules = () => {};
|
|
|
78514
78908
|
|
|
78515
78909
|
// packages/workit-core/src/core/heavy.ts
|
|
78516
78910
|
import fs23 from "node:fs";
|
|
78517
|
-
import
|
|
78518
|
-
import
|
|
78911
|
+
import os20 from "node:os";
|
|
78912
|
+
import path55 from "node:path";
|
|
78519
78913
|
function stateDir2(env, platform = process.platform) {
|
|
78520
78914
|
if (env.WORKFLOW_TOOLKIT_STATE)
|
|
78521
78915
|
return env.WORKFLOW_TOOLKIT_STATE;
|
|
78522
78916
|
if (env.XDG_STATE_HOME)
|
|
78523
|
-
return
|
|
78524
|
-
const home = env.HOME ||
|
|
78917
|
+
return path55.join(env.XDG_STATE_HOME, "workit");
|
|
78918
|
+
const home = env.HOME || os20.homedir();
|
|
78525
78919
|
if (platform === "darwin")
|
|
78526
|
-
return
|
|
78920
|
+
return path55.join(home, "Library", "Application Support", "workit");
|
|
78527
78921
|
if (platform === "win32")
|
|
78528
|
-
return
|
|
78529
|
-
return
|
|
78922
|
+
return path55.join(env.LOCALAPPDATA ?? path55.join(home, "AppData", "Local"), "workit");
|
|
78923
|
+
return path55.join(home, ".local", "state", "workit");
|
|
78530
78924
|
}
|
|
78531
78925
|
function positional(words, from, values = PM_VALUES) {
|
|
78532
78926
|
let index = from;
|
|
@@ -78666,7 +79060,7 @@ function machinePatterns(env) {
|
|
|
78666
79060
|
return isRecord8(value) ? stringList2(value.patterns) : [];
|
|
78667
79061
|
}
|
|
78668
79062
|
function repoPatterns(cwd) {
|
|
78669
|
-
return repoHeavyCommands(gitTop(cwd) ??
|
|
79063
|
+
return repoHeavyCommands(gitTop(cwd) ?? path55.resolve(cwd));
|
|
78670
79064
|
}
|
|
78671
79065
|
function heavyLines(lines, options) {
|
|
78672
79066
|
const found = [];
|
|
@@ -78745,7 +79139,7 @@ function leaseRewrite(command) {
|
|
|
78745
79139
|
return null;
|
|
78746
79140
|
return `${prefix}workit check --heavy -- ${rest}`;
|
|
78747
79141
|
}
|
|
78748
|
-
var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) =>
|
|
79142
|
+
var HEAVY_COMMANDS_FILE = "heavy-commands.json", heavyCommandsFile = (env) => path55.join(stateDir2(env), HEAVY_COMMANDS_FILE), HEAVY_SCRIPT, INFO_FLAGS, WATCH_FLAG, WATCH_SCRIPT, sub = (...names) => new Set(names), TOOLS, PM_VALUES, baseName2 = (word) => (word?.split(/[\\/]/u).at(-1) ?? "").toLowerCase().replace(/\.(?:exe|cmd|bat|ps1)$/u, ""), WORKIT, PYTHONS, NPM_INSTALL, NPM_RUN, NPM_TEST, EXEC, globWord = (word) => new RegExp(`^${word.replace(/[.+?^${}()|[\]\\]/gu, "\\$&").replaceAll("*", ".*")}$`, "u"), matches2 = (matchers, words) => matchers.length <= words.length && matchers.every((matcher, index) => index === 0 ? matcher.test(words[0]) || matcher.test(baseName2(words[0])) : matcher.test(words[index])), readJson2 = (file) => {
|
|
78749
79143
|
try {
|
|
78750
79144
|
return JSON.parse(fs23.readFileSync(file, "utf8"));
|
|
78751
79145
|
} catch {
|
|
@@ -78891,8 +79285,8 @@ var init_heavy = __esm(() => {
|
|
|
78891
79285
|
// packages/workit-core/src/core/resources.ts
|
|
78892
79286
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
78893
79287
|
import fs24 from "node:fs";
|
|
78894
|
-
import
|
|
78895
|
-
import
|
|
79288
|
+
import os21 from "node:os";
|
|
79289
|
+
import path56 from "node:path";
|
|
78896
79290
|
function memoryValue(value, host) {
|
|
78897
79291
|
const text = typeof value === "number" ? String(value) : typeof value === "string" ? value : "";
|
|
78898
79292
|
const percent = PERCENT.exec(text.trim());
|
|
@@ -79088,7 +79482,7 @@ function tryOnce(options, record, reclaimed) {
|
|
|
79088
79482
|
const text = `${JSON.stringify(record)}
|
|
79089
79483
|
`;
|
|
79090
79484
|
for (let slot = 0;slot < options.slots; slot += 1) {
|
|
79091
|
-
const file =
|
|
79485
|
+
const file = path56.join(options.dir, `slot-${slot}.json`);
|
|
79092
79486
|
for (let attempt = 0;attempt < 2; attempt += 1) {
|
|
79093
79487
|
try {
|
|
79094
79488
|
const fd = fs24.openSync(file, "wx", 384);
|
|
@@ -79133,7 +79527,7 @@ function leaseQueue(dir, probe = {}) {
|
|
|
79133
79527
|
}
|
|
79134
79528
|
const entries = [];
|
|
79135
79529
|
for (const name of names.filter((item) => item.endsWith(".json")).toSorted()) {
|
|
79136
|
-
const file =
|
|
79530
|
+
const file = path56.join(queueDir(dir), name);
|
|
79137
79531
|
const record = parseLease(readText5(file));
|
|
79138
79532
|
if (!record)
|
|
79139
79533
|
continue;
|
|
@@ -79149,9 +79543,9 @@ function leaseQueue(dir, probe = {}) {
|
|
|
79149
79543
|
function waitersAhead(options, own) {
|
|
79150
79544
|
let ahead = 0;
|
|
79151
79545
|
for (const entry of leaseQueue(options.dir, options.probe)) {
|
|
79152
|
-
if (
|
|
79546
|
+
if (path56.basename(entry.file) >= own)
|
|
79153
79547
|
break;
|
|
79154
|
-
if (!TICKET.test(
|
|
79548
|
+
if (!TICKET.test(path56.basename(entry.file)))
|
|
79155
79549
|
continue;
|
|
79156
79550
|
if (entry.stale && reclaim(entry.file, (current) => !current || staleReason(current, options.probe) !== null))
|
|
79157
79551
|
continue;
|
|
@@ -79163,7 +79557,7 @@ function liveHolders(options) {
|
|
|
79163
79557
|
return leaseSlots(options.dir, options.slots, options.probe).filter((slot) => slot.holder && !slot.stale).map((slot) => slot.holder);
|
|
79164
79558
|
}
|
|
79165
79559
|
function writeTicket(file, record) {
|
|
79166
|
-
fs24.mkdirSync(
|
|
79560
|
+
fs24.mkdirSync(path56.dirname(file), { recursive: true, mode: 448 });
|
|
79167
79561
|
fs24.writeFileSync(file, `${JSON.stringify(record)}
|
|
79168
79562
|
`, { mode: 384 });
|
|
79169
79563
|
}
|
|
@@ -79208,7 +79602,7 @@ async function acquireLease(options) {
|
|
|
79208
79602
|
const reclaimed = [];
|
|
79209
79603
|
let waitedOn = [];
|
|
79210
79604
|
const name = ticketName(started, record.id);
|
|
79211
|
-
const ticket =
|
|
79605
|
+
const ticket = path56.join(queueDir(options.dir), name);
|
|
79212
79606
|
const ticketRecord = {
|
|
79213
79607
|
...record,
|
|
79214
79608
|
maxAgeMs: options.waitMs + 60000
|
|
@@ -79329,7 +79723,7 @@ function heldLease(dir, id, options = {}) {
|
|
|
79329
79723
|
for (const name of names) {
|
|
79330
79724
|
if (!/^slot-\d+\.json$/u.test(name))
|
|
79331
79725
|
continue;
|
|
79332
|
-
const lease = parseLease(readText5(
|
|
79726
|
+
const lease = parseLease(readText5(path56.join(dir, name)));
|
|
79333
79727
|
if (lease?.id === id && !staleReason(lease, options.probe) && (options.ancestor ?? isAncestor)(lease.pid))
|
|
79334
79728
|
return lease;
|
|
79335
79729
|
}
|
|
@@ -79384,10 +79778,10 @@ async function runScoped(run, wrapper, sinks) {
|
|
|
79384
79778
|
}
|
|
79385
79779
|
function firstNotice(env, session, key, now = Date.now()) {
|
|
79386
79780
|
const id = (session ?? `ppid-${process.ppid}`).replace(/[^A-Za-z0-9_.-]/gu, "_").slice(0, 120);
|
|
79387
|
-
const dir =
|
|
79781
|
+
const dir = path56.join(stateDir2(env), "notices");
|
|
79388
79782
|
try {
|
|
79389
79783
|
fs24.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
79390
|
-
fs24.writeFileSync(
|
|
79784
|
+
fs24.writeFileSync(path56.join(dir, `${key}-${id}`), `${new Date(now).toISOString()}
|
|
79391
79785
|
`, {
|
|
79392
79786
|
flag: "wx",
|
|
79393
79787
|
mode: 384
|
|
@@ -79397,7 +79791,7 @@ function firstNotice(env, session, key, now = Date.now()) {
|
|
|
79397
79791
|
}
|
|
79398
79792
|
try {
|
|
79399
79793
|
for (const name of fs24.readdirSync(dir)) {
|
|
79400
|
-
const file =
|
|
79794
|
+
const file = path56.join(dir, name);
|
|
79401
79795
|
if (now - fs24.statSync(file).mtimeMs > NOTICE_TTL_MS)
|
|
79402
79796
|
fs24.rmSync(file, { force: true });
|
|
79403
79797
|
}
|
|
@@ -79407,7 +79801,7 @@ function firstNotice(env, session, key, now = Date.now()) {
|
|
|
79407
79801
|
function leaseSlots(dir, slots, probe = {}) {
|
|
79408
79802
|
const states = [];
|
|
79409
79803
|
for (let slot = 0;slot < slots; slot += 1) {
|
|
79410
|
-
const lease = parseLease(readText5(
|
|
79804
|
+
const lease = parseLease(readText5(path56.join(dir, `slot-${slot}.json`)));
|
|
79411
79805
|
states.push({
|
|
79412
79806
|
slot,
|
|
79413
79807
|
holder: lease ? holderOf(lease) : null,
|
|
@@ -79417,15 +79811,15 @@ function leaseSlots(dir, slots, probe = {}) {
|
|
|
79417
79811
|
return states;
|
|
79418
79812
|
}
|
|
79419
79813
|
var DEFAULT_HEAVY_CHECKS, DEFAULT_LIGHT_CHECKS, DEFAULT_SLOTS = 1, DEFAULT_WAIT_S = 1800, DEFAULT_MEMORY_SHARE = 0.4, DEFAULT_CPU_SHARE = 0.7, MAX_SLOTS = 64, UNREADABLE_TTL_MS = 30000, GUARD_TTL_MS = 30000, hostShape = () => ({
|
|
79420
|
-
totalMemBytes:
|
|
79421
|
-
cpus: Math.max(1,
|
|
79422
|
-
}), isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), SIZE, PERCENT, UNITS, leaseDir = (env) =>
|
|
79814
|
+
totalMemBytes: os21.totalmem(),
|
|
79815
|
+
cpus: Math.max(1, os21.availableParallelism?.() ?? os21.cpus().length)
|
|
79816
|
+
}), isRecord9 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), SIZE, PERCENT, UNITS, leaseDir = (env) => path56.join(stateDir2(env), "leases"), readText5 = (file) => {
|
|
79423
79817
|
try {
|
|
79424
79818
|
return fs24.readFileSync(file, "utf8");
|
|
79425
79819
|
} catch {
|
|
79426
79820
|
return null;
|
|
79427
79821
|
}
|
|
79428
|
-
}, bootId = () => readText5("/proc/sys/kernel/random/boot_id")?.trim() || null, bootTime = () => Math.round((Date.now() -
|
|
79822
|
+
}, bootId = () => readText5("/proc/sys/kernel/random/boot_id")?.trim() || null, bootTime = () => Math.round((Date.now() - os21.uptime() * 1000) / 1000) * 1000, BOOT_SLACK_MS = 120000, statFields = (pid) => {
|
|
79429
79823
|
const stat = readText5(`/proc/${pid}/stat`);
|
|
79430
79824
|
return stat ? stat.slice(stat.lastIndexOf(")") + 2).split(" ") : null;
|
|
79431
79825
|
}, processStart = (pid) => statFields(pid)?.[19] ?? null, pidAlive2 = (pid) => {
|
|
@@ -79450,7 +79844,7 @@ var DEFAULT_HEAVY_CHECKS, DEFAULT_LIGHT_CHECKS, DEFAULT_SLOTS = 1, DEFAULT_WAIT_
|
|
|
79450
79844
|
cwd: lease.cwd,
|
|
79451
79845
|
session: lease.session,
|
|
79452
79846
|
startedAt: lease.startedAt
|
|
79453
|
-
}), realClock, queueDir = (dir) =>
|
|
79847
|
+
}), realClock, queueDir = (dir) => path56.join(dir, "queue"), TICKET, ticketName = (now, id) => `${String(now).padStart(15, "0")}-${String(process.hrtime.bigint() % 10n ** 16n).padStart(16, "0")}-${id}.json`, SCOPE_START_FAILURE, NOTICE_TTL_MS;
|
|
79454
79848
|
var init_resources = __esm(() => {
|
|
79455
79849
|
init_checks3();
|
|
79456
79850
|
init_heavy();
|
|
@@ -79479,8 +79873,8 @@ __export(exports_check, {
|
|
|
79479
79873
|
run: () => run12,
|
|
79480
79874
|
workspaceResources: () => workspaceResources
|
|
79481
79875
|
});
|
|
79482
|
-
import
|
|
79483
|
-
import
|
|
79876
|
+
import os22 from "node:os";
|
|
79877
|
+
import path57 from "node:path";
|
|
79484
79878
|
function parse6(argv) {
|
|
79485
79879
|
const split = argv.indexOf("--");
|
|
79486
79880
|
const head = split >= 0 ? argv.slice(0, split) : [...argv];
|
|
@@ -79711,7 +80105,7 @@ ${footer}`;
|
|
|
79711
80105
|
}
|
|
79712
80106
|
async function workspaceResources(io) {
|
|
79713
80107
|
const env = io.env;
|
|
79714
|
-
const dir = env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ??
|
|
80108
|
+
const dir = env.WORKFLOW_TOOLKIT_CONFIG ?? env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path57.join(env.XDG_CONFIG_HOME || path57.join(env.HOME || os22.homedir(), ".config"), "workit");
|
|
79715
80109
|
try {
|
|
79716
80110
|
await Promise.resolve().then(() => init_workspaces());
|
|
79717
80111
|
const workspace = resolveWorkspaceFrom(io.cwd, dir, env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined);
|
|
@@ -79853,7 +80247,7 @@ async function run12(argv, io) {
|
|
|
79853
80247
|
if (options.shell && command.length !== 1)
|
|
79854
80248
|
return emit(io, fail2("invalid_input", '--shell takes the command as one string: workit check --shell -- "<cmd>"'));
|
|
79855
80249
|
}
|
|
79856
|
-
const relCwd = posix(
|
|
80250
|
+
const relCwd = posix(path57.relative(top, runCwd));
|
|
79857
80251
|
const configured = !options.shell && matchesNamedCheck(config, name, command, relCwd);
|
|
79858
80252
|
const shadowed = !configured && name !== null ? config.checks.find((item) => item.name === name) : undefined;
|
|
79859
80253
|
if (shadowed)
|
|
@@ -79918,7 +80312,7 @@ async function run12(argv, io) {
|
|
|
79918
80312
|
const modifiedWorktree = key.tree !== null && treeAfter !== key.tree;
|
|
79919
80313
|
const store = storeRoot(io.cwd);
|
|
79920
80314
|
const blob = store.ok ? storeLog(store.value.root, result.log) : null;
|
|
79921
|
-
const logPath = store.ok && blob ?
|
|
80315
|
+
const logPath = store.ok && blob ? path57.join(store.value.root, blob.ref) : null;
|
|
79922
80316
|
const tail = tailLines(result.log, TAIL_LINES);
|
|
79923
80317
|
const passed = result.exitCode === 0 && !result.timedOut;
|
|
79924
80318
|
const bounded = boundedArgv(command);
|
|
@@ -80033,8 +80427,8 @@ async function run12(argv, io) {
|
|
|
80033
80427
|
return recordError.code === "busy" ? 4 : recordError.code === "invalid_input" ? 2 : 5;
|
|
80034
80428
|
return 0;
|
|
80035
80429
|
}
|
|
80036
|
-
var USAGE6 = 'workit check <name> [--full] [--wait <dur> | --no-wait] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--heavy] [--full] [--wait <dur> | --no-wait] [--timeout <s>] [--task <id>] [--json] -- <cmd…>', OUTPUT_LINES = 60, MAX_UNVERIFIED_RUN_MS, RECORD_TAIL_LINES = 20, RECORD_TAIL_CHARS = 200, posix = (value) => value.split(
|
|
80037
|
-
var
|
|
80430
|
+
var USAGE6 = 'workit check <name> [--full] [--wait <dur> | --no-wait] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--heavy] [--full] [--wait <dur> | --no-wait] [--timeout <s>] [--task <id>] [--json] -- <cmd…>', OUTPUT_LINES = 60, MAX_UNVERIFIED_RUN_MS, RECORD_TAIL_LINES = 20, RECORD_TAIL_CHARS = 200, posix = (value) => value.split(path57.sep).join("/") || ".", ENGINE_CODES2, FINGERPRINT_VARS, ANSI_COLOR, WARNING_LINE, NO_WARNINGS, STDERR_TAIL_LINES = 10, STDERR_KEEP_CHARS = 65536, FAILURE_LINE, MAX_FAILURE_LINES = 15;
|
|
80431
|
+
var init_check2 = __esm(() => {
|
|
80038
80432
|
init_check_config();
|
|
80039
80433
|
init_checks3();
|
|
80040
80434
|
init_rev();
|
|
@@ -80064,7 +80458,7 @@ __export(exports_lock, {
|
|
|
80064
80458
|
run: () => run13
|
|
80065
80459
|
});
|
|
80066
80460
|
import fs25 from "node:fs";
|
|
80067
|
-
import
|
|
80461
|
+
import path58 from "node:path";
|
|
80068
80462
|
async function settingsFor(io) {
|
|
80069
80463
|
const workspace = await workspaceResources(io);
|
|
80070
80464
|
const config = loadCheckConfig(io.cwd);
|
|
@@ -80141,7 +80535,7 @@ async function runHeavy(args, io) {
|
|
|
80141
80535
|
return emit(io, fail2("invalid_input", unknown ? `unexpected ${unknown}` : "no command after --", {
|
|
80142
80536
|
unblock: "workit lock run [--shell] [--wait <dur> | --no-wait] [--timeout <s>] -- <cmd…>"
|
|
80143
80537
|
}));
|
|
80144
|
-
const check = await Promise.resolve().then(() => (
|
|
80538
|
+
const check = await Promise.resolve().then(() => (init_check2(), {}));
|
|
80145
80539
|
return run12([`--heavy`, ...head, ...args.slice(split)], io);
|
|
80146
80540
|
}
|
|
80147
80541
|
function readPatterns(file) {
|
|
@@ -80156,7 +80550,7 @@ function readPatterns(file) {
|
|
|
80156
80550
|
return { patterns: [] };
|
|
80157
80551
|
}
|
|
80158
80552
|
function writePatterns(file, value) {
|
|
80159
|
-
fs25.mkdirSync(
|
|
80553
|
+
fs25.mkdirSync(path58.dirname(file), { recursive: true, mode: 448 });
|
|
80160
80554
|
const temp = `${file}.${process.pid}.tmp`;
|
|
80161
80555
|
fs25.writeFileSync(temp, `${JSON.stringify(value, null, 2)}
|
|
80162
80556
|
`, { mode: 384 });
|
|
@@ -80234,7 +80628,7 @@ var init_lock = __esm(() => {
|
|
|
80234
80628
|
init_heavy();
|
|
80235
80629
|
init_resources();
|
|
80236
80630
|
init_output();
|
|
80237
|
-
|
|
80631
|
+
init_check2();
|
|
80238
80632
|
});
|
|
80239
80633
|
|
|
80240
80634
|
// packages/workit-cli/src/verbs/models.ts
|
|
@@ -80242,9 +80636,9 @@ var exports_models = {};
|
|
|
80242
80636
|
__export(exports_models, {
|
|
80243
80637
|
run: () => run14
|
|
80244
80638
|
});
|
|
80245
|
-
import { existsSync as existsSync25, readdirSync as readdirSync13, readFileSync as
|
|
80246
|
-
import
|
|
80247
|
-
import
|
|
80639
|
+
import { existsSync as existsSync25, readdirSync as readdirSync13, readFileSync as readFileSync26, statSync as statSync9 } from "node:fs";
|
|
80640
|
+
import os23 from "node:os";
|
|
80641
|
+
import path59 from "node:path";
|
|
80248
80642
|
async function run14(argv, io) {
|
|
80249
80643
|
const [sub, ...args] = argv.filter((arg) => arg !== "--json");
|
|
80250
80644
|
if (sub !== "show")
|
|
@@ -80305,7 +80699,7 @@ var USAGE8 = "workit models show [--role <role>] [--tier <tier>] [--host <host>]
|
|
|
80305
80699
|
const found = new Set;
|
|
80306
80700
|
let text = "";
|
|
80307
80701
|
try {
|
|
80308
|
-
text =
|
|
80702
|
+
text = readFileSync26(file, "utf8");
|
|
80309
80703
|
} catch {
|
|
80310
80704
|
return found;
|
|
80311
80705
|
}
|
|
@@ -80319,24 +80713,24 @@ var USAGE8 = "workit models show [--role <role>] [--tier <tier>] [--host <host>]
|
|
|
80319
80713
|
} catch {}
|
|
80320
80714
|
return found;
|
|
80321
80715
|
}, matches3 = (ran, configured) => ran.toLowerCase().includes(configured.toLowerCase()), usageReport = (cwd, env, days) => {
|
|
80322
|
-
const projects =
|
|
80716
|
+
const projects = path59.join(env.CLAUDE_CONFIG_DIR || path59.join(env.HOME || os23.homedir(), ".claude"), "projects");
|
|
80323
80717
|
const since = Date.now() - days * 86400000;
|
|
80324
80718
|
const types = {};
|
|
80325
80719
|
let agents = 0;
|
|
80326
80720
|
const dirs = (dir) => {
|
|
80327
80721
|
try {
|
|
80328
|
-
return readdirSync13(dir).map((name) =>
|
|
80722
|
+
return readdirSync13(dir).map((name) => path59.join(dir, name));
|
|
80329
80723
|
} catch {
|
|
80330
80724
|
return [];
|
|
80331
80725
|
}
|
|
80332
80726
|
};
|
|
80333
80727
|
for (const project of dirs(projects))
|
|
80334
80728
|
for (const session of dirs(project))
|
|
80335
|
-
for (const meta of dirs(
|
|
80729
|
+
for (const meta of dirs(path59.join(session, "subagents")).filter((f) => f.endsWith(".meta.json"))) {
|
|
80336
80730
|
try {
|
|
80337
80731
|
if (statSync9(meta).mtimeMs < since)
|
|
80338
80732
|
continue;
|
|
80339
|
-
const agentType = JSON.parse(
|
|
80733
|
+
const agentType = JSON.parse(readFileSync26(meta, "utf8")).agentType;
|
|
80340
80734
|
const transcript = meta.replace(/\.meta\.json$/, ".jsonl");
|
|
80341
80735
|
if (typeof agentType !== "string" || !existsSync25(transcript))
|
|
80342
80736
|
continue;
|
|
@@ -80476,9 +80870,9 @@ var init_youtrack_writes = __esm(() => {
|
|
|
80476
80870
|
var success2 = (data) => ({ ok: true, data }), failure3 = (code, error, unblock) => ({ ok: false, code, error, ...unblock ? { unblock } : {} });
|
|
80477
80871
|
|
|
80478
80872
|
// packages/workit-core/src/git/ops.ts
|
|
80479
|
-
import { spawnSync as
|
|
80480
|
-
import { existsSync as existsSync26, readFileSync as
|
|
80481
|
-
import
|
|
80873
|
+
import { spawnSync as spawnSync21 } from "node:child_process";
|
|
80874
|
+
import { existsSync as existsSync26, readFileSync as readFileSync27 } from "node:fs";
|
|
80875
|
+
import path60 from "node:path";
|
|
80482
80876
|
function operationInProgress(cwd) {
|
|
80483
80877
|
const markers = [
|
|
80484
80878
|
["rebase-merge", "rebase"],
|
|
@@ -80491,18 +80885,18 @@ function operationInProgress(cwd) {
|
|
|
80491
80885
|
if (!run.ok)
|
|
80492
80886
|
return null;
|
|
80493
80887
|
const found = run.stdout.split(`
|
|
80494
|
-
`).map((line) =>
|
|
80888
|
+
`).map((line) => path60.resolve(cwd, line.trim()));
|
|
80495
80889
|
const conflicted = () => git5(cwd, ["ls-files", "-u"]).stdout.trim() !== "";
|
|
80496
80890
|
for (const [index, [, operation]] of markers.entries()) {
|
|
80497
80891
|
const marker = found[index];
|
|
80498
80892
|
if (!marker || !existsSync26(marker))
|
|
80499
80893
|
continue;
|
|
80500
|
-
if (index === 1 && existsSync26(
|
|
80894
|
+
if (index === 1 && existsSync26(path60.join(marker, "applying")))
|
|
80501
80895
|
return { operation: "am", commitAllowed: false, branch: null };
|
|
80502
|
-
if (index === 0 && existsSync26(
|
|
80896
|
+
if (index === 0 && existsSync26(path60.join(marker, "amend")) && !conflicted()) {
|
|
80503
80897
|
let headName = "";
|
|
80504
80898
|
try {
|
|
80505
|
-
headName =
|
|
80899
|
+
headName = readFileSync27(path60.join(marker, "head-name"), "utf8").trim();
|
|
80506
80900
|
} catch {}
|
|
80507
80901
|
const branch = headName.startsWith("refs/heads/") ? headName.slice("refs/heads/".length) : null;
|
|
80508
80902
|
return { operation, commitAllowed: branch !== null, branch };
|
|
@@ -80837,7 +81231,7 @@ function gitCommit(cwd, input) {
|
|
|
80837
81231
|
if (paths.some((value) => value.startsWith("-") || !value.trim()))
|
|
80838
81232
|
return failure3("invalid_input", "paths must not be empty or start with -");
|
|
80839
81233
|
const tracked = new Set(nulList(git5(cwd, ["ls-files", "-z", "--", ...paths]).stdout));
|
|
80840
|
-
const addable = paths.filter((value) => existsSync26(
|
|
81234
|
+
const addable = paths.filter((value) => existsSync26(path60.resolve(cwd, value)) || [...tracked].some((file) => file === value || file.startsWith(`${value}/`)));
|
|
80841
81235
|
if (addable.length) {
|
|
80842
81236
|
const added = git5(cwd, ["add", "-A", "--", ...addable]);
|
|
80843
81237
|
if (!added.ok)
|
|
@@ -81310,7 +81704,7 @@ ${run.stdout}`;
|
|
|
81310
81704
|
} : { ok: false, lease: false, error: gitError(run) };
|
|
81311
81705
|
}
|
|
81312
81706
|
var COMMIT_TIMEOUT_MS, PUSH_TIMEOUT_MS = 120000, git5 = (cwd, args, options = {}) => {
|
|
81313
|
-
const result =
|
|
81707
|
+
const result = spawnSync21("git", args, {
|
|
81314
81708
|
cwd,
|
|
81315
81709
|
encoding: "utf8",
|
|
81316
81710
|
env: { ...options.env ?? process.env, GIT_TERMINAL_PROMPT: "0" },
|
|
@@ -81378,12 +81772,12 @@ var init_ops = __esm(() => {
|
|
|
81378
81772
|
|
|
81379
81773
|
// packages/workit-core/src/verdict-cover.ts
|
|
81380
81774
|
import fs26 from "node:fs";
|
|
81381
|
-
import
|
|
81775
|
+
import path61 from "node:path";
|
|
81382
81776
|
function chainsAbove(cwd, branch) {
|
|
81383
81777
|
const root = storeRoot(cwd);
|
|
81384
81778
|
if (!root.ok)
|
|
81385
81779
|
return [];
|
|
81386
|
-
const dir =
|
|
81780
|
+
const dir = path61.join(root.value.root, "stacks");
|
|
81387
81781
|
let names = [];
|
|
81388
81782
|
try {
|
|
81389
81783
|
names = fs26.readdirSync(dir).filter((name) => name.endsWith(".json"));
|
|
@@ -81394,7 +81788,7 @@ function chainsAbove(cwd, branch) {
|
|
|
81394
81788
|
for (const name of names.toSorted()) {
|
|
81395
81789
|
let parsed;
|
|
81396
81790
|
try {
|
|
81397
|
-
parsed = JSON.parse(fs26.readFileSync(
|
|
81791
|
+
parsed = JSON.parse(fs26.readFileSync(path61.join(dir, name), "utf8"));
|
|
81398
81792
|
} catch {
|
|
81399
81793
|
continue;
|
|
81400
81794
|
}
|
|
@@ -81550,10 +81944,10 @@ var init_check_evidence = __esm(() => {
|
|
|
81550
81944
|
|
|
81551
81945
|
// packages/workit-core/src/forge/reruns.ts
|
|
81552
81946
|
import fs27 from "node:fs";
|
|
81553
|
-
import
|
|
81947
|
+
import path62 from "node:path";
|
|
81554
81948
|
function rerunLogPath(cwd) {
|
|
81555
81949
|
const common = gitCommonDir(cwd);
|
|
81556
|
-
return common ?
|
|
81950
|
+
return common ? path62.join(common, "workit", "ci-reruns.jsonl") : null;
|
|
81557
81951
|
}
|
|
81558
81952
|
function rerunCounts(cwd, key) {
|
|
81559
81953
|
const counts = new Map;
|
|
@@ -81588,7 +81982,7 @@ function recordReruns(cwd, rows) {
|
|
|
81588
81982
|
if (!file)
|
|
81589
81983
|
return false;
|
|
81590
81984
|
try {
|
|
81591
|
-
fs27.mkdirSync(
|
|
81985
|
+
fs27.mkdirSync(path62.dirname(file), { recursive: true });
|
|
81592
81986
|
fs27.appendFileSync(file, rows.map((row) => `${JSON.stringify(row)}
|
|
81593
81987
|
`).join(""));
|
|
81594
81988
|
return true;
|
|
@@ -81601,7 +81995,7 @@ function withRerunLock(cwd, fn) {
|
|
|
81601
81995
|
if (!file)
|
|
81602
81996
|
return fn();
|
|
81603
81997
|
const lock = `${file.slice(0, -".jsonl".length)}.lock`;
|
|
81604
|
-
fs27.mkdirSync(
|
|
81998
|
+
fs27.mkdirSync(path62.dirname(lock), { recursive: true });
|
|
81605
81999
|
const until = Date.now() + LOCK_WAIT_MS2;
|
|
81606
82000
|
for (;; ) {
|
|
81607
82001
|
try {
|
|
@@ -82042,7 +82436,7 @@ var init_report2 = __esm(() => {
|
|
|
82042
82436
|
});
|
|
82043
82437
|
|
|
82044
82438
|
// packages/workit-core/src/forge/pr-ops.ts
|
|
82045
|
-
import { spawnSync as
|
|
82439
|
+
import { spawnSync as spawnSync22 } from "node:child_process";
|
|
82046
82440
|
function fillFromCommits(cwd, resolved, base) {
|
|
82047
82441
|
const tracking = `refs/remotes/${resolved.baseRemote}/${base}`;
|
|
82048
82442
|
if (!base.startsWith("-"))
|
|
@@ -82050,7 +82444,7 @@ function fillFromCommits(cwd, resolved, base) {
|
|
|
82050
82444
|
const from = resolveRef(cwd, tracking) ?? resolveRef(cwd, `refs/heads/${base}`);
|
|
82051
82445
|
if (!from)
|
|
82052
82446
|
return failure3("not_found", `base ${base} is not available locally`, `git fetch ${resolved.baseRemote} ${base}`);
|
|
82053
|
-
const log =
|
|
82447
|
+
const log = spawnSync22("git", ["log", "--reverse", "--no-merges", "--format=%s%x1f%b%x1e", `${from}..HEAD`], {
|
|
82054
82448
|
cwd,
|
|
82055
82449
|
encoding: "utf8",
|
|
82056
82450
|
timeout: GIT_TIMEOUTS.local,
|
|
@@ -82247,7 +82641,7 @@ function squashCommitList(cwd, resolved, base, head) {
|
|
|
82247
82641
|
const from = resolveRef(cwd, `refs/remotes/${resolved.baseRemote}/${base}`) ?? resolveRef(cwd, `refs/heads/${base}`);
|
|
82248
82642
|
if (!from)
|
|
82249
82643
|
return "";
|
|
82250
|
-
const log =
|
|
82644
|
+
const log = spawnSync22("git", ["log", "--reverse", "--no-merges", "--format=%B%x1e", `${from}..${head}`], {
|
|
82251
82645
|
cwd,
|
|
82252
82646
|
encoding: "utf8",
|
|
82253
82647
|
timeout: GIT_TIMEOUTS.local,
|
|
@@ -82594,10 +82988,10 @@ var init_pr_ops = __esm(() => {
|
|
|
82594
82988
|
});
|
|
82595
82989
|
|
|
82596
82990
|
// packages/workit-core/src/stack.ts
|
|
82597
|
-
import { spawnSync as
|
|
82991
|
+
import { spawnSync as spawnSync23 } from "node:child_process";
|
|
82598
82992
|
import { createHash as createHash18, randomBytes as randomBytes4 } from "node:crypto";
|
|
82599
82993
|
import fs28 from "node:fs";
|
|
82600
|
-
import
|
|
82994
|
+
import path63 from "node:path";
|
|
82601
82995
|
function worktreeOf(cwd, branch) {
|
|
82602
82996
|
const list = gitRun3(cwd, ["worktree", "list", "--porcelain"]);
|
|
82603
82997
|
if (!list.ok)
|
|
@@ -82646,7 +83040,7 @@ function gitRestack(cwd, input) {
|
|
|
82646
83040
|
error: "no store root"
|
|
82647
83041
|
};
|
|
82648
83042
|
fs28.mkdirSync(scratch, { recursive: true });
|
|
82649
|
-
dir =
|
|
83043
|
+
dir = path63.join(scratch, `${input.branch.replace(/[^A-Za-z0-9._-]+/gu, "_").slice(0, 40)}-${randomBytes4(4).toString("hex")}`);
|
|
82650
83044
|
const added = gitRun3(cwd, ["worktree", "add", "-q", dir, input.branch], GIT_TIMEOUTS.worktree);
|
|
82651
83045
|
if (!added.ok)
|
|
82652
83046
|
return {
|
|
@@ -82702,7 +83096,7 @@ function pruneScratch(cwd) {
|
|
|
82702
83096
|
if (!scratch || !fs28.existsSync(scratch))
|
|
82703
83097
|
return;
|
|
82704
83098
|
for (const name of fs28.readdirSync(scratch)) {
|
|
82705
|
-
const dir =
|
|
83099
|
+
const dir = path63.join(scratch, name);
|
|
82706
83100
|
if (!rebaseInProgress(dir) && !trackedDirt(dir))
|
|
82707
83101
|
gitRun3(cwd, ["worktree", "remove", "--force", dir]);
|
|
82708
83102
|
}
|
|
@@ -82712,7 +83106,7 @@ function stacksDir(cwd) {
|
|
|
82712
83106
|
const root = storeRoot(cwd);
|
|
82713
83107
|
if (!root.ok)
|
|
82714
83108
|
return stackFail(root.code, root.error, root.unblock);
|
|
82715
|
-
return { ok: true, data:
|
|
83109
|
+
return { ok: true, data: path63.join(root.value.root, "stacks") };
|
|
82716
83110
|
}
|
|
82717
83111
|
function parseStack(raw) {
|
|
82718
83112
|
if (!isRecord12(raw) || !Array.isArray(raw.branches))
|
|
@@ -82764,7 +83158,7 @@ function readStack(cwd, name) {
|
|
|
82764
83158
|
const dir = stacksDir(cwd);
|
|
82765
83159
|
if (!dir.ok)
|
|
82766
83160
|
return dir;
|
|
82767
|
-
const file =
|
|
83161
|
+
const file = path63.join(dir.data, fileFor(name));
|
|
82768
83162
|
let text;
|
|
82769
83163
|
try {
|
|
82770
83164
|
text = fs28.readFileSync(file, "utf8");
|
|
@@ -82785,7 +83179,7 @@ function writeStack(cwd, stack, now = new Date) {
|
|
|
82785
83179
|
const dir = stacksDir(cwd);
|
|
82786
83180
|
if (!dir.ok)
|
|
82787
83181
|
return dir;
|
|
82788
|
-
const file =
|
|
83182
|
+
const file = path63.join(dir.data, fileFor(stack.name));
|
|
82789
83183
|
const temp = `${file}.${process.pid}.tmp`;
|
|
82790
83184
|
try {
|
|
82791
83185
|
fs28.mkdirSync(dir.data, { recursive: true });
|
|
@@ -82813,7 +83207,7 @@ function listStacks(cwd) {
|
|
|
82813
83207
|
for (const name of names) {
|
|
82814
83208
|
let parsed = null;
|
|
82815
83209
|
try {
|
|
82816
|
-
parsed = parseStack(JSON.parse(fs28.readFileSync(
|
|
83210
|
+
parsed = parseStack(JSON.parse(fs28.readFileSync(path63.join(dir.data, name), "utf8")));
|
|
82817
83211
|
} catch {
|
|
82818
83212
|
parsed = null;
|
|
82819
83213
|
}
|
|
@@ -82875,7 +83269,7 @@ function takeLock(lock) {
|
|
|
82875
83269
|
host: localLockHost(),
|
|
82876
83270
|
nonce: randomBytes4(8).toString("hex")
|
|
82877
83271
|
};
|
|
82878
|
-
fs28.writeFileSync(
|
|
83272
|
+
fs28.writeFileSync(path63.join(lock, OWNER), JSON.stringify(owner));
|
|
82879
83273
|
return owner;
|
|
82880
83274
|
}
|
|
82881
83275
|
function reapLock(lock, observed) {
|
|
@@ -82912,7 +83306,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
|
|
|
82912
83306
|
return dir;
|
|
82913
83307
|
if (!validName(name))
|
|
82914
83308
|
return stackFail("invalid_input", "a stack name must be 1-200 printable characters");
|
|
82915
|
-
const lock =
|
|
83309
|
+
const lock = path63.join(dir.data, `${fileFor(name)}.lock`);
|
|
82916
83310
|
try {
|
|
82917
83311
|
fs28.mkdirSync(dir.data, { recursive: true });
|
|
82918
83312
|
} catch (error) {
|
|
@@ -82942,7 +83336,7 @@ async function withStackLock(cwd, name, fn, waitMs = LOCK_WAIT_MS3) {
|
|
|
82942
83336
|
const touch = () => {
|
|
82943
83337
|
try {
|
|
82944
83338
|
const now = new Date;
|
|
82945
|
-
fs28.utimesSync(
|
|
83339
|
+
fs28.utimesSync(path63.join(lock, OWNER), now, now);
|
|
82946
83340
|
} catch {}
|
|
82947
83341
|
};
|
|
82948
83342
|
const beat = setInterval(touch, HEARTBEAT_MS);
|
|
@@ -83130,7 +83524,7 @@ function commitKeys(cwd, range) {
|
|
|
83130
83524
|
const patches = new Map;
|
|
83131
83525
|
const diff = gitRun3(cwd, ["log", "--no-merges", "-p", "--format=commit %H", range]);
|
|
83132
83526
|
if (diff.ok && diff.stdout.trim()) {
|
|
83133
|
-
const ids =
|
|
83527
|
+
const ids = spawnSync23("git", ["patch-id", "--stable"], {
|
|
83134
83528
|
cwd,
|
|
83135
83529
|
input: diff.stdout,
|
|
83136
83530
|
encoding: "utf8",
|
|
@@ -83883,7 +84277,7 @@ var STACK_VERSION = 1, stackFail = (code, error, unblock, data) => ({
|
|
|
83883
84277
|
...unblock ? { unblock } : {},
|
|
83884
84278
|
...data ? { data } : {}
|
|
83885
84279
|
}), fromForge = (result) => stackFail(result.code, result.error, result.unblock), stackDeps, gitRun3 = (cwd, args, timeoutMs = GIT_TIMEOUTS.local) => {
|
|
83886
|
-
const run =
|
|
84280
|
+
const run = spawnSync23("git", args, {
|
|
83887
84281
|
cwd,
|
|
83888
84282
|
encoding: "utf8",
|
|
83889
84283
|
timeout: timeoutMs,
|
|
@@ -83911,7 +84305,7 @@ var STACK_VERSION = 1, stackFail = (code, error, unblock, data) => ({
|
|
|
83911
84305
|
return !status.ok || status.stdout.trim() !== "";
|
|
83912
84306
|
}, scratchDir = (cwd) => {
|
|
83913
84307
|
const dir = stacksDir(cwd);
|
|
83914
|
-
return dir.ok ?
|
|
84308
|
+
return dir.ok ? path63.join(dir.data, "worktrees") : null;
|
|
83915
84309
|
}, firstLine = (run) => (`${run.stderr}
|
|
83916
84310
|
${run.stdout}`.split(`
|
|
83917
84311
|
`).find((line) => line.trim()) ?? "git failed").trim().slice(0, 300), stackFileName = (name) => `${name.replace(/[^A-Za-z0-9._-]+/gu, "_").replace(/^[._]+/u, "").slice(0, 48).toLowerCase()}-${createHash18("sha256").update(name).digest("hex").slice(0, 12)}.json`, fileFor, validName = (name) => {
|
|
@@ -83926,12 +84320,12 @@ ${run.stdout}`.split(`
|
|
|
83926
84320
|
}, isRecord12 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), str3 = (value) => typeof value === "string" && value ? value : null, LOCK_WAIT_MS3 = 2000, HEARTBEAT_MS = 20000, HEARTBEAT_STALE_MS, OWNERLESS_STALE_MS = 30000, OWNER = "owner", readOwner = (lock) => {
|
|
83927
84321
|
let raw = null;
|
|
83928
84322
|
try {
|
|
83929
|
-
raw = fs28.readFileSync(
|
|
84323
|
+
raw = fs28.readFileSync(path63.join(lock, OWNER), "utf8");
|
|
83930
84324
|
} catch {
|
|
83931
84325
|
raw = null;
|
|
83932
84326
|
}
|
|
83933
84327
|
let age = null;
|
|
83934
|
-
for (const target of [
|
|
84328
|
+
for (const target of [path63.join(lock, OWNER), lock])
|
|
83935
84329
|
try {
|
|
83936
84330
|
age = Date.now() - fs28.statSync(target).mtimeMs;
|
|
83937
84331
|
break;
|
|
@@ -83972,10 +84366,10 @@ var init_stack = __esm(() => {
|
|
|
83972
84366
|
});
|
|
83973
84367
|
|
|
83974
84368
|
// packages/workit-core/src/fanout.ts
|
|
83975
|
-
import { spawnSync as
|
|
84369
|
+
import { spawnSync as spawnSync24 } from "node:child_process";
|
|
83976
84370
|
import { createHash as createHash19 } from "node:crypto";
|
|
83977
84371
|
import fs29 from "node:fs";
|
|
83978
|
-
import
|
|
84372
|
+
import path64 from "node:path";
|
|
83979
84373
|
function expandBraces2(pattern, limit = 64) {
|
|
83980
84374
|
for (let index = 0;index < pattern.length; index += 1) {
|
|
83981
84375
|
if (pattern[index] === "\\") {
|
|
@@ -84221,7 +84615,7 @@ function parsePlan(raw, defaults, name) {
|
|
|
84221
84615
|
id,
|
|
84222
84616
|
branch,
|
|
84223
84617
|
base: optional("base") ?? "",
|
|
84224
|
-
worktree:
|
|
84618
|
+
worktree: path64.resolve(defaults.root, optional("worktree") ?? path64.join(defaults.worktreeRoot, id)),
|
|
84225
84619
|
tier,
|
|
84226
84620
|
reason,
|
|
84227
84621
|
dependsOn: [...new Set(dependsOn ?? [])],
|
|
@@ -84350,12 +84744,12 @@ function regeneratedFiles(root, tracked) {
|
|
|
84350
84744
|
const found = new Map;
|
|
84351
84745
|
let scripts;
|
|
84352
84746
|
try {
|
|
84353
|
-
const manifest = JSON.parse(fs29.readFileSync(
|
|
84747
|
+
const manifest = JSON.parse(fs29.readFileSync(path64.join(root, "package.json"), "utf8"));
|
|
84354
84748
|
scripts = manifest.scripts ?? {};
|
|
84355
84749
|
} catch {
|
|
84356
84750
|
return found;
|
|
84357
84751
|
}
|
|
84358
|
-
const runner = fs29.existsSync(
|
|
84752
|
+
const runner = fs29.existsSync(path64.join(root, "bun.lock")) ? "bun run" : fs29.existsSync(path64.join(root, "pnpm-lock.yaml")) ? "pnpm run" : fs29.existsSync(path64.join(root, "yarn.lock")) ? "yarn run" : "npm run";
|
|
84359
84753
|
const outputs = tracked.filter((file) => !CODE.test(file));
|
|
84360
84754
|
for (const [name, command] of Object.entries(scripts)) {
|
|
84361
84755
|
if (!name.startsWith("write:") || typeof command !== "string")
|
|
@@ -84363,7 +84757,7 @@ function regeneratedFiles(root, tracked) {
|
|
|
84363
84757
|
for (const file of command.match(/[\w./-]+\.[cm]?[jt]s\b/gu) ?? []) {
|
|
84364
84758
|
let source;
|
|
84365
84759
|
try {
|
|
84366
|
-
source = fs29.readFileSync(
|
|
84760
|
+
source = fs29.readFileSync(path64.join(root, file), "utf8");
|
|
84367
84761
|
} catch {
|
|
84368
84762
|
continue;
|
|
84369
84763
|
}
|
|
@@ -84485,11 +84879,11 @@ function defaultTrunk(cwd) {
|
|
|
84485
84879
|
}
|
|
84486
84880
|
function mainCheckout(cwd) {
|
|
84487
84881
|
const common = gitCommonDir(cwd);
|
|
84488
|
-
return common &&
|
|
84882
|
+
return common && path64.basename(common) === ".git" ? path64.dirname(common) : path64.resolve(cwd);
|
|
84489
84883
|
}
|
|
84490
84884
|
function worktreeRoot(cwd) {
|
|
84491
84885
|
const main = mainCheckout(cwd);
|
|
84492
|
-
return
|
|
84886
|
+
return path64.join(path64.dirname(main), `${path64.basename(main)}-wt`);
|
|
84493
84887
|
}
|
|
84494
84888
|
function sliceHash(slice) {
|
|
84495
84889
|
const {
|
|
@@ -84509,7 +84903,7 @@ function fanoutsDir(cwd) {
|
|
|
84509
84903
|
const root = storeRoot(cwd);
|
|
84510
84904
|
if (!root.ok)
|
|
84511
84905
|
return fanoutFail(root.code, root.error, root.unblock);
|
|
84512
|
-
return { ok: true, data:
|
|
84906
|
+
return { ok: true, data: path64.join(root.value.root, "fanouts") };
|
|
84513
84907
|
}
|
|
84514
84908
|
function parseStored(raw) {
|
|
84515
84909
|
if (!isRecord13(raw) || typeof raw.name !== "string" || typeof raw.trunk !== "string")
|
|
@@ -84577,7 +84971,7 @@ function readFanout(cwd, name) {
|
|
|
84577
84971
|
const dir = fanoutsDir(cwd);
|
|
84578
84972
|
if (!dir.ok)
|
|
84579
84973
|
return dir;
|
|
84580
|
-
const file =
|
|
84974
|
+
const file = path64.join(dir.data, stackFileName(name));
|
|
84581
84975
|
let parsed = null;
|
|
84582
84976
|
try {
|
|
84583
84977
|
parsed = parseStored(JSON.parse(fs29.readFileSync(file, "utf8")));
|
|
@@ -84602,7 +84996,7 @@ function listFanouts(cwd) {
|
|
|
84602
84996
|
for (const entry of names) {
|
|
84603
84997
|
let parsed = null;
|
|
84604
84998
|
try {
|
|
84605
|
-
parsed = parseStored(JSON.parse(fs29.readFileSync(
|
|
84999
|
+
parsed = parseStored(JSON.parse(fs29.readFileSync(path64.join(dir.data, entry), "utf8")));
|
|
84606
85000
|
} catch {
|
|
84607
85001
|
parsed = null;
|
|
84608
85002
|
}
|
|
@@ -84641,7 +85035,7 @@ function writeFanout(cwd, plan) {
|
|
|
84641
85035
|
const dir = fanoutsDir(cwd);
|
|
84642
85036
|
if (!dir.ok)
|
|
84643
85037
|
return dir;
|
|
84644
|
-
const file =
|
|
85038
|
+
const file = path64.join(dir.data, stackFileName(plan.name));
|
|
84645
85039
|
const temp = `${file}.${process.pid}.tmp`;
|
|
84646
85040
|
try {
|
|
84647
85041
|
fs29.mkdirSync(dir.data, { recursive: true });
|
|
@@ -84809,7 +85203,7 @@ var FANOUT_VERSION = 1, TIERS, REASONS, FAN_IN_MODES, fanoutFail = (code, error,
|
|
|
84809
85203
|
text: edges.map((edge) => `add "${edge.dependsOn}" to "dependsOn" of slice ${edge.slice}`).join("; ")
|
|
84810
85204
|
};
|
|
84811
85205
|
}, gitRun4 = (cwd, args, timeoutMs = GIT_TIMEOUTS.local) => {
|
|
84812
|
-
const run =
|
|
85206
|
+
const run = spawnSync24("git", args, {
|
|
84813
85207
|
cwd,
|
|
84814
85208
|
encoding: "utf8",
|
|
84815
85209
|
timeout: timeoutMs,
|
|
@@ -84850,15 +85244,15 @@ var init_fanout = __esm(() => {
|
|
|
84850
85244
|
});
|
|
84851
85245
|
|
|
84852
85246
|
// packages/workit-core/src/forge/exec.ts
|
|
84853
|
-
import { spawnSync as
|
|
85247
|
+
import { spawnSync as spawnSync25 } from "node:child_process";
|
|
84854
85248
|
import fs30 from "node:fs";
|
|
84855
|
-
import
|
|
85249
|
+
import path65 from "node:path";
|
|
84856
85250
|
function findExecutable(bin, env) {
|
|
84857
|
-
const dirs = (env.PATH ?? env.Path ?? "").split(
|
|
85251
|
+
const dirs = (env.PATH ?? env.Path ?? "").split(path65.delimiter).filter(Boolean);
|
|
84858
85252
|
const exts = process.platform === "win32" ? [".exe"] : [""];
|
|
84859
85253
|
for (const dir of dirs)
|
|
84860
85254
|
for (const ext of exts) {
|
|
84861
|
-
const candidate =
|
|
85255
|
+
const candidate = path65.join(dir, `${bin}${ext}`);
|
|
84862
85256
|
try {
|
|
84863
85257
|
const stat = fs30.statSync(candidate);
|
|
84864
85258
|
if (stat.isFile())
|
|
@@ -84885,7 +85279,7 @@ function systemRunner(kind, apiHost, env = process.env) {
|
|
|
84885
85279
|
if (!exe)
|
|
84886
85280
|
return { status: null, stdout: "", stderr: "", timedOut: false, missing: true };
|
|
84887
85281
|
const token = options.token ? kind === "github" ? { GH_TOKEN: options.token, GH_ENTERPRISE_TOKEN: options.token } : { GITLAB_TOKEN: options.token } : {};
|
|
84888
|
-
const result =
|
|
85282
|
+
const result = spawnSync25(exe, [...args], {
|
|
84889
85283
|
encoding: "utf8",
|
|
84890
85284
|
env: { ...childEnv, ...token },
|
|
84891
85285
|
maxBuffer: MAX_BUFFER2,
|
|
@@ -86220,7 +86614,7 @@ var init_issue_link = __esm(() => {
|
|
|
86220
86614
|
});
|
|
86221
86615
|
|
|
86222
86616
|
// packages/workit-core/src/forge/pr-edit.ts
|
|
86223
|
-
import { spawnSync as
|
|
86617
|
+
import { spawnSync as spawnSync26 } from "node:child_process";
|
|
86224
86618
|
function openPr(cwd, resolved, pr) {
|
|
86225
86619
|
const grant = requireGrant(cwd, "pr");
|
|
86226
86620
|
if (!grant.allowed)
|
|
@@ -86385,7 +86779,7 @@ function replyToThread(cwd, resolved, input) {
|
|
|
86385
86779
|
});
|
|
86386
86780
|
}
|
|
86387
86781
|
var label2 = (resolved, number) => `${resolved.forge.kind === "github" ? "PR #" : "MR !"}${number}`, git6 = (cwd, args) => {
|
|
86388
|
-
const run =
|
|
86782
|
+
const run = spawnSync26("git", args, {
|
|
86389
86783
|
cwd,
|
|
86390
86784
|
encoding: "utf8",
|
|
86391
86785
|
timeout: GIT_TIMEOUTS.local,
|
|
@@ -86405,7 +86799,7 @@ var init_pr_edit = __esm(() => {
|
|
|
86405
86799
|
});
|
|
86406
86800
|
|
|
86407
86801
|
// packages/workit-core/src/fanout-landed.ts
|
|
86408
|
-
import { spawnSync as
|
|
86802
|
+
import { spawnSync as spawnSync27 } from "node:child_process";
|
|
86409
86803
|
function forgeBreaker(resolved) {
|
|
86410
86804
|
if (!resolved)
|
|
86411
86805
|
return { forge: null, down: () => null };
|
|
@@ -86510,7 +86904,7 @@ function trunkPatchIds(ctx, fork) {
|
|
|
86510
86904
|
"--"
|
|
86511
86905
|
]);
|
|
86512
86906
|
if (log.ok && log.stdout.trim()) {
|
|
86513
|
-
const run =
|
|
86907
|
+
const run = spawnSync27("git", ["patch-id", "--stable"], {
|
|
86514
86908
|
cwd: ctx.cwd,
|
|
86515
86909
|
input: log.stdout,
|
|
86516
86910
|
encoding: "utf8",
|
|
@@ -86632,7 +87026,7 @@ var init_fanout_landed = __esm(() => {
|
|
|
86632
87026
|
});
|
|
86633
87027
|
|
|
86634
87028
|
// packages/workit-core/src/core/live-session.ts
|
|
86635
|
-
import { spawnSync as
|
|
87029
|
+
import { spawnSync as spawnSync28 } from "node:child_process";
|
|
86636
87030
|
var LIVE_SESSION_TTL_MS, liveProbe, PIDS;
|
|
86637
87031
|
var init_live_session = __esm(() => {
|
|
86638
87032
|
init_paths();
|
|
@@ -86641,14 +87035,14 @@ var init_live_session = __esm(() => {
|
|
|
86641
87035
|
LIVE_SESSION_TTL_MS = 15 * 60000;
|
|
86642
87036
|
liveProbe = {
|
|
86643
87037
|
platform: process.platform,
|
|
86644
|
-
run: (args) =>
|
|
87038
|
+
run: (args) => spawnSync28("ps", args, { encoding: "utf8", timeout: 2000 }).stdout ?? "",
|
|
86645
87039
|
start: (pid) => processStartOf(pid)
|
|
86646
87040
|
};
|
|
86647
87041
|
PIDS = new Map;
|
|
86648
87042
|
});
|
|
86649
87043
|
|
|
86650
87044
|
// packages/workit-core/src/hooks/write-gate.ts
|
|
86651
|
-
import
|
|
87045
|
+
import path66 from "node:path";
|
|
86652
87046
|
var CASE_INSENSITIVE, PREFIXES2, SCRIPT_SHELLS, cache3, MUTATING_GIT, DRY_N, MUTATING_WORKIT_GIT, CD2, PUSHD2, POPD2, UNKNOWN_DIR;
|
|
86653
87047
|
var init_write_gate = __esm(() => {
|
|
86654
87048
|
init_task_store();
|
|
@@ -86688,7 +87082,7 @@ var init_write_gate = __esm(() => {
|
|
|
86688
87082
|
CD2 = new Set(["cd", "chdir", "set-location", "sl"]);
|
|
86689
87083
|
PUSHD2 = new Set(["pushd", "push-location"]);
|
|
86690
87084
|
POPD2 = new Set(["popd", "pop-location"]);
|
|
86691
|
-
UNKNOWN_DIR =
|
|
87085
|
+
UNKNOWN_DIR = path66.resolve(path66.parse(process.cwd()).root, ".workit-unknown-dir");
|
|
86692
87086
|
});
|
|
86693
87087
|
|
|
86694
87088
|
// packages/workit-core/src/hooks/worktree-confine.ts
|
|
@@ -86713,20 +87107,20 @@ var init_worktree_confine = __esm(() => {
|
|
|
86713
87107
|
|
|
86714
87108
|
// packages/workit-core/src/worktree-deps.ts
|
|
86715
87109
|
import fs31 from "node:fs";
|
|
86716
|
-
import
|
|
87110
|
+
import path67 from "node:path";
|
|
86717
87111
|
function moduleDirs(main) {
|
|
86718
87112
|
const out = [];
|
|
86719
87113
|
const walk = (relative, depth) => {
|
|
86720
87114
|
let entries;
|
|
86721
87115
|
try {
|
|
86722
|
-
entries = fs31.readdirSync(
|
|
87116
|
+
entries = fs31.readdirSync(path67.join(main, relative), { withFileTypes: true });
|
|
86723
87117
|
} catch {
|
|
86724
87118
|
return;
|
|
86725
87119
|
}
|
|
86726
87120
|
for (const entry of entries) {
|
|
86727
87121
|
if (!entry.isDirectory())
|
|
86728
87122
|
continue;
|
|
86729
|
-
const child =
|
|
87123
|
+
const child = path67.join(relative, entry.name);
|
|
86730
87124
|
if (entry.name === MODULES)
|
|
86731
87125
|
out.push(child);
|
|
86732
87126
|
else if (depth < MAX_DEPTH2 && !entry.name.startsWith("."))
|
|
@@ -86740,8 +87134,8 @@ function linkEntry(main, worktree, source, target) {
|
|
|
86740
87134
|
const stat = fs31.lstatSync(source);
|
|
86741
87135
|
if (stat.isSymbolicLink()) {
|
|
86742
87136
|
const link = fs31.readlinkSync(source);
|
|
86743
|
-
const outside =
|
|
86744
|
-
const to = outside ?
|
|
87137
|
+
const outside = path67.isAbsolute(link) && within(link, main) && !path67.relative(main, link).split(path67.sep).includes(MODULES);
|
|
87138
|
+
const to = outside ? path67.join(worktree, path67.relative(main, link)) : link;
|
|
86745
87139
|
fs31.symlinkSync(to, target, process.platform === "win32" ? "junction" : undefined);
|
|
86746
87140
|
return;
|
|
86747
87141
|
}
|
|
@@ -86751,8 +87145,8 @@ function mirror(main, worktree, source, target, top) {
|
|
|
86751
87145
|
fs31.mkdirSync(target);
|
|
86752
87146
|
let count = 0;
|
|
86753
87147
|
for (const entry of fs31.readdirSync(source, { withFileTypes: true })) {
|
|
86754
|
-
const from =
|
|
86755
|
-
const to =
|
|
87148
|
+
const from = path67.join(source, entry.name);
|
|
87149
|
+
const to = path67.join(target, entry.name);
|
|
86756
87150
|
if (top && entry.isDirectory() && (entry.name.startsWith("@") || entry.name === ".bin"))
|
|
86757
87151
|
count += mirror(main, worktree, from, to, false);
|
|
86758
87152
|
else {
|
|
@@ -86768,16 +87162,16 @@ function linkWorktreeDependencies(main, worktree) {
|
|
|
86768
87162
|
const dirs = [];
|
|
86769
87163
|
let entries = 0;
|
|
86770
87164
|
for (const relative of moduleDirs(main)) {
|
|
86771
|
-
const target =
|
|
86772
|
-
if (!fs31.existsSync(
|
|
87165
|
+
const target = path67.join(worktree, relative);
|
|
87166
|
+
if (!fs31.existsSync(path67.dirname(target)) || fs31.existsSync(target))
|
|
86773
87167
|
continue;
|
|
86774
|
-
if (!gitRun4(worktree, ["check-ignore", "-q", `${relative.split(
|
|
86775
|
-
notes.push(`${relative.split(
|
|
87168
|
+
if (!gitRun4(worktree, ["check-ignore", "-q", `${relative.split(path67.sep).join("/")}/`]).ok) {
|
|
87169
|
+
notes.push(`${relative.split(path67.sep).join("/")} is not ignored by git, so it was not linked from ${main}; install dependencies in the worktree yourself`);
|
|
86776
87170
|
continue;
|
|
86777
87171
|
}
|
|
86778
87172
|
try {
|
|
86779
|
-
entries += mirror(main, worktree,
|
|
86780
|
-
dirs.push(relative.split(
|
|
87173
|
+
entries += mirror(main, worktree, path67.join(main, relative), target, true);
|
|
87174
|
+
dirs.push(relative.split(path67.sep).join("/"));
|
|
86781
87175
|
} catch (error) {
|
|
86782
87176
|
fs31.rmSync(target, { recursive: true, force: true });
|
|
86783
87177
|
notes.push(`could not link ${relative} from ${main} (${error.message}); install dependencies in the worktree yourself`);
|
|
@@ -86790,8 +87184,8 @@ function linkWorktreeDependencies(main, worktree) {
|
|
|
86790
87184
|
return { linked: { from: main, dirs, entries, ms }, notes };
|
|
86791
87185
|
}
|
|
86792
87186
|
var MODULES = "node_modules", MAX_DEPTH2 = 2, within = (child, parent) => {
|
|
86793
|
-
const relative =
|
|
86794
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
87187
|
+
const relative = path67.relative(parent, child);
|
|
87188
|
+
return relative === "" || !relative.startsWith("..") && !path67.isAbsolute(relative);
|
|
86795
87189
|
};
|
|
86796
87190
|
var init_worktree_deps = __esm(() => {
|
|
86797
87191
|
init_fanout();
|
|
@@ -86800,7 +87194,7 @@ var init_worktree_deps = __esm(() => {
|
|
|
86800
87194
|
// packages/workit-core/src/fanout-worktree.ts
|
|
86801
87195
|
import { randomBytes as randomBytes5 } from "node:crypto";
|
|
86802
87196
|
import fs32 from "node:fs";
|
|
86803
|
-
import
|
|
87197
|
+
import path68 from "node:path";
|
|
86804
87198
|
function rowSample(lines) {
|
|
86805
87199
|
const out = [];
|
|
86806
87200
|
let bytes = 0;
|
|
@@ -86860,7 +87254,7 @@ function adminDir(worktree) {
|
|
|
86860
87254
|
const file = dir.stdout.trim();
|
|
86861
87255
|
let token = null;
|
|
86862
87256
|
try {
|
|
86863
|
-
token = fs32.readFileSync(
|
|
87257
|
+
token = fs32.readFileSync(path68.join(file, FANOUT_TOKEN_FILE), "utf8").trim() || null;
|
|
86864
87258
|
} catch {
|
|
86865
87259
|
token = null;
|
|
86866
87260
|
}
|
|
@@ -86868,7 +87262,7 @@ function adminDir(worktree) {
|
|
|
86868
87262
|
const stat = worktreeDeps.stat(file);
|
|
86869
87263
|
return {
|
|
86870
87264
|
path: file,
|
|
86871
|
-
id:
|
|
87265
|
+
id: path68.basename(file),
|
|
86872
87266
|
ino: stat.ino.toString(),
|
|
86873
87267
|
token,
|
|
86874
87268
|
birthMs: stat.birthtimeNs > 0n ? Number(stat.birthtimeMs) : null,
|
|
@@ -86884,7 +87278,7 @@ function markAdminDir(worktree) {
|
|
|
86884
87278
|
return null;
|
|
86885
87279
|
const token = randomBytes5(16).toString("hex");
|
|
86886
87280
|
try {
|
|
86887
|
-
fs32.writeFileSync(
|
|
87281
|
+
fs32.writeFileSync(path68.join(admin.path, FANOUT_TOKEN_FILE), `${token}
|
|
86888
87282
|
`);
|
|
86889
87283
|
} catch {
|
|
86890
87284
|
return null;
|
|
@@ -86899,7 +87293,7 @@ function excludeScratch(cwd) {
|
|
|
86899
87293
|
const common = gitCommonDir(cwd);
|
|
86900
87294
|
if (!common)
|
|
86901
87295
|
return;
|
|
86902
|
-
const file =
|
|
87296
|
+
const file = path68.join(common, "info", "exclude");
|
|
86903
87297
|
let text = "";
|
|
86904
87298
|
try {
|
|
86905
87299
|
text = fs32.readFileSync(file, "utf8");
|
|
@@ -86908,7 +87302,7 @@ function excludeScratch(cwd) {
|
|
|
86908
87302
|
}
|
|
86909
87303
|
if (text.split(/\r?\n/u).includes(EXCLUDE_LINE))
|
|
86910
87304
|
return;
|
|
86911
|
-
fs32.mkdirSync(
|
|
87305
|
+
fs32.mkdirSync(path68.dirname(file), { recursive: true });
|
|
86912
87306
|
fs32.appendFileSync(file, `${text && !text.endsWith(`
|
|
86913
87307
|
`) ? `
|
|
86914
87308
|
` : ""}# workit fanout: per-worker scratch dirs
|
|
@@ -86917,13 +87311,13 @@ ${EXCLUDE_LINE}
|
|
|
86917
87311
|
}
|
|
86918
87312
|
function worktreeDependencies(main, worktree) {
|
|
86919
87313
|
for (const [name, install] of LOCKFILES2) {
|
|
86920
|
-
const ours = readBytes(
|
|
86921
|
-
const theirs = readBytes(
|
|
87314
|
+
const ours = readBytes(path68.join(main, name));
|
|
87315
|
+
const theirs = readBytes(path68.join(worktree, name));
|
|
86922
87316
|
if (ours === null && theirs === null)
|
|
86923
87317
|
continue;
|
|
86924
87318
|
if (ours !== null && theirs !== null && ours.equals(theirs))
|
|
86925
87319
|
continue;
|
|
86926
|
-
if (fs32.existsSync(
|
|
87320
|
+
if (fs32.existsSync(path68.join(worktree, "node_modules")))
|
|
86927
87321
|
break;
|
|
86928
87322
|
const command = install(worktree);
|
|
86929
87323
|
return {
|
|
@@ -86935,7 +87329,7 @@ function worktreeDependencies(main, worktree) {
|
|
|
86935
87329
|
};
|
|
86936
87330
|
}
|
|
86937
87331
|
const stale = staleBunInstall(main);
|
|
86938
|
-
if (stale && !fs32.existsSync(
|
|
87332
|
+
if (stale && !fs32.existsSync(path68.join(worktree, "node_modules"))) {
|
|
86939
87333
|
const command = `bun install --frozen-lockfile --cwd ${worktree}`;
|
|
86940
87334
|
return {
|
|
86941
87335
|
linked: null,
|
|
@@ -86948,9 +87342,9 @@ function worktreeDependencies(main, worktree) {
|
|
|
86948
87342
|
return { ...linkWorktreeDependencies(main, worktree), install: null };
|
|
86949
87343
|
}
|
|
86950
87344
|
function staleBunInstall(main) {
|
|
86951
|
-
if (!fs32.existsSync(
|
|
87345
|
+
if (!fs32.existsSync(path68.join(main, "node_modules")))
|
|
86952
87346
|
return null;
|
|
86953
|
-
const text = readBytes(
|
|
87347
|
+
const text = readBytes(path68.join(main, "bun.lock"))?.toString("utf8");
|
|
86954
87348
|
if (!text)
|
|
86955
87349
|
return null;
|
|
86956
87350
|
let packages;
|
|
@@ -86977,7 +87371,7 @@ function staleBunInstall(main) {
|
|
|
86977
87371
|
const version = spec.slice(at + 1);
|
|
86978
87372
|
if (name !== key || version.includes(":"))
|
|
86979
87373
|
continue;
|
|
86980
|
-
const manifest = readBytes(
|
|
87374
|
+
const manifest = readBytes(path68.join(main, "node_modules", key, "package.json"));
|
|
86981
87375
|
if (!manifest) {
|
|
86982
87376
|
problems.push(`${key} missing`);
|
|
86983
87377
|
continue;
|
|
@@ -86994,7 +87388,7 @@ function staleBunInstall(main) {
|
|
|
86994
87388
|
return problems.length ? problems.join("; ") : null;
|
|
86995
87389
|
}
|
|
86996
87390
|
function ensureScratch(worktree) {
|
|
86997
|
-
const scratch =
|
|
87391
|
+
const scratch = path68.join(worktree, SCRATCH_DIR);
|
|
86998
87392
|
fs32.mkdirSync(scratch, { recursive: true });
|
|
86999
87393
|
return scratch;
|
|
87000
87394
|
}
|
|
@@ -87268,7 +87662,7 @@ function unpushedCount(cwd, branch) {
|
|
|
87268
87662
|
return count.ok ? Number(count.stdout.trim()) : null;
|
|
87269
87663
|
}
|
|
87270
87664
|
function removeScratch(worktree) {
|
|
87271
|
-
const scratch =
|
|
87665
|
+
const scratch = path68.join(worktree, SCRATCH_DIR);
|
|
87272
87666
|
let stat;
|
|
87273
87667
|
try {
|
|
87274
87668
|
stat = fs32.lstatSync(scratch);
|
|
@@ -87284,16 +87678,16 @@ var SLOW, SCRATCH_DIR = ".workit-scratch", EXCLUDE_LINE, DIRTY_ROW_BYTES = 2000,
|
|
|
87284
87678
|
try {
|
|
87285
87679
|
return fs32.realpathSync.native(target);
|
|
87286
87680
|
} catch {
|
|
87287
|
-
return
|
|
87681
|
+
return path68.resolve(target);
|
|
87288
87682
|
}
|
|
87289
87683
|
}, samePath = (a, b) => {
|
|
87290
87684
|
const left = canonical2(a);
|
|
87291
87685
|
const right = canonical2(b);
|
|
87292
87686
|
return process.platform === "win32" || process.platform === "darwin" ? left.toLowerCase() === right.toLowerCase() : left === right;
|
|
87293
87687
|
}, inside3 = (child, parent) => {
|
|
87294
|
-
const relative =
|
|
87295
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
87296
|
-
}, slicePath = (cwd, slice) =>
|
|
87688
|
+
const relative = path68.relative(canonical2(parent), canonical2(child));
|
|
87689
|
+
return relative === "" || !relative.startsWith("..") && !path68.isAbsolute(relative);
|
|
87690
|
+
}, slicePath = (cwd, slice) => path68.isAbsolute(slice.worktree) ? slice.worktree : path68.resolve(mainCheckout(cwd), slice.worktree), CLOCK_SLACK_MS = 2000, worktreeDeps, LOCKFILES2, readBytes = (file) => {
|
|
87297
87691
|
try {
|
|
87298
87692
|
return fs32.readFileSync(file);
|
|
87299
87693
|
} catch {
|
|
@@ -87325,7 +87719,7 @@ var init_fanout_worktree = __esm(() => {
|
|
|
87325
87719
|
|
|
87326
87720
|
// packages/workit-core/src/forge/merge-cleanup.ts
|
|
87327
87721
|
import fs33 from "node:fs";
|
|
87328
|
-
import
|
|
87722
|
+
import path69 from "node:path";
|
|
87329
87723
|
function cleanupMergedBranch(cwd, branch, mergedHead) {
|
|
87330
87724
|
const out = { branchDeleted: false, worktreeRemoved: null, notes: [] };
|
|
87331
87725
|
if (!branch || branch.startsWith("-"))
|
|
@@ -87385,13 +87779,13 @@ var SLOW2, isFanoutWorktree = (worktree) => {
|
|
|
87385
87779
|
if (!dir.ok)
|
|
87386
87780
|
return false;
|
|
87387
87781
|
try {
|
|
87388
|
-
return fs33.readFileSync(
|
|
87782
|
+
return fs33.readFileSync(path69.join(dir.stdout.trim(), FANOUT_TOKEN_FILE), "utf8").trim() !== "";
|
|
87389
87783
|
} catch {
|
|
87390
87784
|
return false;
|
|
87391
87785
|
}
|
|
87392
87786
|
}, inside4 = (child, parent) => {
|
|
87393
|
-
const relative =
|
|
87394
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
87787
|
+
const relative = path69.relative(fs33.realpathSync.native(parent), fs33.realpathSync.native(child));
|
|
87788
|
+
return relative === "" || !relative.startsWith("..") && !path69.isAbsolute(relative);
|
|
87395
87789
|
};
|
|
87396
87790
|
var init_merge_cleanup = __esm(() => {
|
|
87397
87791
|
init_fanout();
|
|
@@ -87672,7 +88066,7 @@ var init_duration = __esm(() => {
|
|
|
87672
88066
|
});
|
|
87673
88067
|
|
|
87674
88068
|
// packages/workit-cli/src/verbs/forge-common.ts
|
|
87675
|
-
import { readFileSync as
|
|
88069
|
+
import { readFileSync as readFileSync28 } from "node:fs";
|
|
87676
88070
|
function parseFlags(argv, spec) {
|
|
87677
88071
|
const parsed = { values: {}, booleans: new Set, lists: {}, positionals: [] };
|
|
87678
88072
|
for (let index = 0;index < argv.length; index += 1) {
|
|
@@ -87830,7 +88224,7 @@ var init_forge_common = __esm(() => {
|
|
|
87830
88224
|
forgeDeps = {
|
|
87831
88225
|
runner: undefined,
|
|
87832
88226
|
npm: undefined,
|
|
87833
|
-
readStdin: () =>
|
|
88227
|
+
readStdin: () => readFileSync28(0, "utf8"),
|
|
87834
88228
|
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
87835
88229
|
now: () => Date.now()
|
|
87836
88230
|
};
|
|
@@ -87842,8 +88236,8 @@ __export(exports_pr, {
|
|
|
87842
88236
|
checkPrTitle: () => checkPrTitle,
|
|
87843
88237
|
run: () => run15
|
|
87844
88238
|
});
|
|
87845
|
-
import { existsSync as existsSync27, readFileSync as
|
|
87846
|
-
import
|
|
88239
|
+
import { existsSync as existsSync27, readFileSync as readFileSync29 } from "node:fs";
|
|
88240
|
+
import path70 from "node:path";
|
|
87847
88241
|
function titleRules(cwd) {
|
|
87848
88242
|
let root;
|
|
87849
88243
|
try {
|
|
@@ -87854,16 +88248,16 @@ function titleRules(cwd) {
|
|
|
87854
88248
|
let text = null;
|
|
87855
88249
|
let name = "";
|
|
87856
88250
|
for (const candidate of COMMITLINT_FILES) {
|
|
87857
|
-
const full =
|
|
88251
|
+
const full = path70.join(root, candidate);
|
|
87858
88252
|
if (!existsSync27(full))
|
|
87859
88253
|
continue;
|
|
87860
|
-
text =
|
|
88254
|
+
text = readFileSync29(full, "utf8");
|
|
87861
88255
|
name = candidate;
|
|
87862
88256
|
break;
|
|
87863
88257
|
}
|
|
87864
88258
|
if (text === null) {
|
|
87865
88259
|
try {
|
|
87866
|
-
const pkg = JSON.parse(
|
|
88260
|
+
const pkg = JSON.parse(readFileSync29(path70.join(root, "package.json"), "utf8"));
|
|
87867
88261
|
if (pkg.commitlint === undefined)
|
|
87868
88262
|
return { rules: null, note: null };
|
|
87869
88263
|
text = JSON.stringify(pkg.commitlint);
|
|
@@ -87960,7 +88354,7 @@ function refuseTitle(io, title, line) {
|
|
|
87960
88354
|
function readBodyFile(io, file) {
|
|
87961
88355
|
try {
|
|
87962
88356
|
return {
|
|
87963
|
-
body: file === "-" ? forgeDeps.readStdin() :
|
|
88357
|
+
body: file === "-" ? forgeDeps.readStdin() : readFileSync29(path70.resolve(io.cwd, file), "utf8")
|
|
87964
88358
|
};
|
|
87965
88359
|
} catch {
|
|
87966
88360
|
return `cannot read --body-file ${file}`;
|
|
@@ -88849,8 +89243,8 @@ var exports_git = {};
|
|
|
88849
89243
|
__export(exports_git, {
|
|
88850
89244
|
run: () => run17
|
|
88851
89245
|
});
|
|
88852
|
-
import { readFileSync as
|
|
88853
|
-
import
|
|
89246
|
+
import { readFileSync as readFileSync30 } from "node:fs";
|
|
89247
|
+
import path71 from "node:path";
|
|
88854
89248
|
function kindHint(cwd, kind) {
|
|
88855
89249
|
let kinds = [...BRANCH_KINDS];
|
|
88856
89250
|
try {
|
|
@@ -88954,7 +89348,7 @@ function commitMessage(parsed, io) {
|
|
|
88954
89348
|
|
|
88955
89349
|
`);
|
|
88956
89350
|
try {
|
|
88957
|
-
return file === "-" ?
|
|
89351
|
+
return file === "-" ? readFileSync30(0, "utf8") : readFileSync30(path71.resolve(io.cwd, file), "utf8");
|
|
88958
89352
|
} catch (error) {
|
|
88959
89353
|
return {
|
|
88960
89354
|
error: `cannot read -F ${file}: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -89140,7 +89534,7 @@ var init_git2 = __esm(() => {
|
|
|
89140
89534
|
});
|
|
89141
89535
|
|
|
89142
89536
|
// packages/workit-core/src/forge/verify.ts
|
|
89143
|
-
import { spawnSync as
|
|
89537
|
+
import { spawnSync as spawnSync29 } from "node:child_process";
|
|
89144
89538
|
function finish(cwd, report, actor) {
|
|
89145
89539
|
const delivered = report.observations.length > 0 && report.observations.every((entry) => entry.ok);
|
|
89146
89540
|
const out = { ...report, delivered };
|
|
@@ -89353,7 +89747,7 @@ var NPM_NAME, SEMVER2, SAFE_ARG, systemNpm = (args) => {
|
|
|
89353
89747
|
};
|
|
89354
89748
|
const found = process.platform === "win32" ? findExecutable("npm.cmd", process.env) : null;
|
|
89355
89749
|
const npmCmd = found && !/["%!^]/u.test(found) ? `"${found}"` : "npm.cmd";
|
|
89356
|
-
const result = process.platform === "win32" ?
|
|
89750
|
+
const result = process.platform === "win32" ? spawnSync29(`${npmCmd} ${args.join(" ")}`, { ...options, shell: true }) : spawnSync29("npm", [...args], options);
|
|
89357
89751
|
return { status: result.status, stdout: result.stdout ?? "", stderr: result.stderr ?? "" };
|
|
89358
89752
|
}, short3 = (sha) => sha ? sha.slice(0, 12) : "(absent)", npmView = (stdout) => {
|
|
89359
89753
|
try {
|
|
@@ -90418,7 +90812,7 @@ var init_stack2 = __esm(() => {
|
|
|
90418
90812
|
// packages/workit-core/src/fanout-brief.ts
|
|
90419
90813
|
import { createHash as createHash20 } from "node:crypto";
|
|
90420
90814
|
import fs35 from "node:fs";
|
|
90421
|
-
import
|
|
90815
|
+
import path72 from "node:path";
|
|
90422
90816
|
function workerSession(lead, slice, attempt) {
|
|
90423
90817
|
const tail = attempt === null ? "" : `+try${attempt}`;
|
|
90424
90818
|
const full = `${lead}-w-${slice}${tail}`;
|
|
@@ -90501,7 +90895,7 @@ function renderBrief(cwd, plan, input) {
|
|
|
90501
90895
|
"STANDING:",
|
|
90502
90896
|
...standing.length ? standing.map((order) => ` - ${order.what}`) : [" - none recorded beyond this brief"],
|
|
90503
90897
|
exists ? `WORKTREE: ${planned} (made by \`workit fanout worktree create ${slice.id}\`; yours alone)` : `WORKTREE: ${planned} (not made yet: the lead runs \`workit fanout worktree create ${slice.id}\` before spawning, then renders this brief again)`,
|
|
90504
|
-
...exists && typeof made?.install === "string" && !fs35.existsSync(
|
|
90898
|
+
...exists && typeof made?.install === "string" && !fs35.existsSync(path72.join(planned, "node_modules")) ? [`INSTALL: \`${made.install}\` first: the main checkout's node_modules was not linked here`] : [],
|
|
90505
90899
|
...identityLines(identity, minted),
|
|
90506
90900
|
...rules(mode, branch, sliceBase, exists ? planned : null)
|
|
90507
90901
|
];
|
|
@@ -91043,7 +91437,7 @@ __export(exports_fanout, {
|
|
|
91043
91437
|
run: () => run21
|
|
91044
91438
|
});
|
|
91045
91439
|
import fs36 from "node:fs";
|
|
91046
|
-
import
|
|
91440
|
+
import path73 from "node:path";
|
|
91047
91441
|
function forgeFor(io, offline) {
|
|
91048
91442
|
if (offline)
|
|
91049
91443
|
return { forge: null, error: "--offline" };
|
|
@@ -91104,7 +91498,7 @@ function plan2(argv, io) {
|
|
|
91104
91498
|
return usage4(io, "pass --trunk or --track, not both (--track picks the trunk)", PLAN_USAGE2);
|
|
91105
91499
|
if (flags.positionals.length !== 1)
|
|
91106
91500
|
return usage4(io, flags.positionals.length ? `unexpected argument ${flags.positionals[1]}` : "missing <plan.json>", PLAN_USAGE2);
|
|
91107
|
-
const file =
|
|
91501
|
+
const file = path73.resolve(io.cwd, flags.positionals[0]);
|
|
91108
91502
|
let raw;
|
|
91109
91503
|
try {
|
|
91110
91504
|
raw = JSON.parse(fs36.readFileSync(file, "utf8"));
|
|
@@ -106680,7 +107074,7 @@ var init_ast = __esm(() => {
|
|
|
106680
107074
|
|
|
106681
107075
|
// packages/workit-cli/src/test-audit/rules.ts
|
|
106682
107076
|
import { builtinModules } from "node:module";
|
|
106683
|
-
import
|
|
107077
|
+
import path74 from "node:path";
|
|
106684
107078
|
function testCallee(call) {
|
|
106685
107079
|
let callee = call.callee;
|
|
106686
107080
|
if (callee.type === "CallExpression")
|
|
@@ -107173,12 +107567,12 @@ function checkConstantsOnly(ctx, emit) {
|
|
|
107173
107567
|
}
|
|
107174
107568
|
function checkOverMocking(ctx, emit) {
|
|
107175
107569
|
const { program } = ctx.parsed;
|
|
107176
|
-
const unit =
|
|
107570
|
+
const unit = path74.basename(ctx.file).replace(/\.(?:[cm]?[jt]sx?)$/, "").replace(/\.(?:test|spec)$/, "");
|
|
107177
107571
|
const mocked = find2(program, (node) => node.type === "CallExpression" && MODULE_MOCK.test(calleeName(node.callee) ?? "") && node.arguments[0]?.type === "StringLiteral");
|
|
107178
107572
|
const internal = mocked.filter((call) => /^(?:\.|@\/|~\/)/.test(call.arguments[0].value));
|
|
107179
107573
|
for (const call of mocked) {
|
|
107180
107574
|
const spec = call.arguments[0].value;
|
|
107181
|
-
const base =
|
|
107575
|
+
const base = path74.basename(spec.replace(/\/index(?:\.[cm]?[jt]sx?)?$/, "")).replace(/\.(?:[cm]?[jt]sx?)$/, "");
|
|
107182
107576
|
if (base === unit)
|
|
107183
107577
|
emit({
|
|
107184
107578
|
rule: "over-mocking",
|
|
@@ -107566,11 +107960,11 @@ var init_rules = __esm(() => {
|
|
|
107566
107960
|
});
|
|
107567
107961
|
|
|
107568
107962
|
// packages/workit-cli/src/test-audit/audit.ts
|
|
107569
|
-
import { spawnSync as
|
|
107570
|
-
import { existsSync as existsSync28, readdirSync as readdirSync14, readFileSync as
|
|
107571
|
-
import
|
|
107963
|
+
import { spawnSync as spawnSync30 } from "node:child_process";
|
|
107964
|
+
import { existsSync as existsSync28, readdirSync as readdirSync14, readFileSync as readFileSync31, statSync as statSync10 } from "node:fs";
|
|
107965
|
+
import path75 from "node:path";
|
|
107572
107966
|
function git7(cwd, args) {
|
|
107573
|
-
const run =
|
|
107967
|
+
const run = spawnSync30("git", ["-c", "core.quotepath=off", ...args], {
|
|
107574
107968
|
cwd,
|
|
107575
107969
|
encoding: "utf8",
|
|
107576
107970
|
maxBuffer: 64 * 1024 * 1024
|
|
@@ -107581,7 +107975,7 @@ function walkTests(dir, out) {
|
|
|
107581
107975
|
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
107582
107976
|
if (entry.name.startsWith(".") && entry.name !== "." && entry.isDirectory())
|
|
107583
107977
|
continue;
|
|
107584
|
-
const full =
|
|
107978
|
+
const full = path75.join(dir, entry.name);
|
|
107585
107979
|
if (entry.isDirectory()) {
|
|
107586
107980
|
if (!SKIP_DIRS.has(entry.name))
|
|
107587
107981
|
walkTests(full, out);
|
|
@@ -107593,7 +107987,7 @@ function expandPaths(cwd, inputs) {
|
|
|
107593
107987
|
const files = [];
|
|
107594
107988
|
const missing = [];
|
|
107595
107989
|
for (const input of inputs.length > 0 ? inputs : ["."]) {
|
|
107596
|
-
const full =
|
|
107990
|
+
const full = path75.resolve(cwd, input);
|
|
107597
107991
|
if (!existsSync28(full))
|
|
107598
107992
|
missing.push(input);
|
|
107599
107993
|
else if (statSync10(full).isDirectory())
|
|
@@ -107630,11 +108024,11 @@ function changedLines(cwd, base) {
|
|
|
107630
108024
|
for (let offset = 0;offset < count; offset += 1)
|
|
107631
108025
|
lines.add(start + offset);
|
|
107632
108026
|
}
|
|
107633
|
-
changed.set(
|
|
108027
|
+
changed.set(path75.join(root, file), lines);
|
|
107634
108028
|
}
|
|
107635
108029
|
const untracked = git7(root, ["ls-files", "--others", "--exclude-standard", "-z"]);
|
|
107636
108030
|
for (const file of untracked.stdout.split("\x00").filter(Boolean))
|
|
107637
|
-
changed.set(
|
|
108031
|
+
changed.set(path75.join(root, file), "all");
|
|
107638
108032
|
return changed;
|
|
107639
108033
|
}
|
|
107640
108034
|
function auditFiles(files, display) {
|
|
@@ -107647,7 +108041,7 @@ function auditFiles(files, display) {
|
|
|
107647
108041
|
const shown = display(file);
|
|
107648
108042
|
let parsed;
|
|
107649
108043
|
try {
|
|
107650
|
-
parsed = parseSource(
|
|
108044
|
+
parsed = parseSource(readFileSync31(file, "utf8"), file);
|
|
107651
108045
|
} catch (error) {
|
|
107652
108046
|
parseErrors.push({
|
|
107653
108047
|
file: shown,
|
|
@@ -107696,7 +108090,7 @@ function auditFiles(files, display) {
|
|
|
107696
108090
|
durationMs: Math.round(performance.now() - started)
|
|
107697
108091
|
};
|
|
107698
108092
|
}
|
|
107699
|
-
var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(
|
|
108093
|
+
var TEST_FILE, CODE_FILE, SKIP_DIRS, toPosix = (file) => file.split(path75.sep).join("/"), SEVERITY_ORDER, ruleIds;
|
|
107700
108094
|
var init_audit = __esm(() => {
|
|
107701
108095
|
init_ast();
|
|
107702
108096
|
init_rules();
|
|
@@ -107708,25 +108102,25 @@ var init_audit = __esm(() => {
|
|
|
107708
108102
|
});
|
|
107709
108103
|
|
|
107710
108104
|
// packages/workit-cli/src/test-audit/mutate.ts
|
|
107711
|
-
import { spawn as
|
|
108105
|
+
import { spawn as spawn5 } from "node:child_process";
|
|
107712
108106
|
import {
|
|
107713
108107
|
existsSync as existsSync29,
|
|
107714
108108
|
lstatSync as lstatSync9,
|
|
107715
|
-
mkdirSync as
|
|
108109
|
+
mkdirSync as mkdirSync13,
|
|
107716
108110
|
mkdtempSync as mkdtempSync4,
|
|
107717
108111
|
readdirSync as readdirSync15,
|
|
107718
|
-
readFileSync as
|
|
108112
|
+
readFileSync as readFileSync32,
|
|
107719
108113
|
readlinkSync as readlinkSync3,
|
|
107720
108114
|
realpathSync as realpathSync11,
|
|
107721
|
-
renameSync as
|
|
108115
|
+
renameSync as renameSync8,
|
|
107722
108116
|
rmSync as rmSync9,
|
|
107723
108117
|
statSync as statSync11,
|
|
107724
108118
|
symlinkSync,
|
|
107725
|
-
writeFileSync as
|
|
108119
|
+
writeFileSync as writeFileSync14,
|
|
107726
108120
|
copyFileSync as copyFileSync8
|
|
107727
108121
|
} from "node:fs";
|
|
107728
|
-
import
|
|
107729
|
-
import
|
|
108122
|
+
import os24 from "node:os";
|
|
108123
|
+
import path76 from "node:path";
|
|
107730
108124
|
function mutantsFor(source, file, lines) {
|
|
107731
108125
|
const parsed = parseSource(source, file);
|
|
107732
108126
|
const out = [];
|
|
@@ -107799,7 +108193,7 @@ function relatedTests(source, testFiles) {
|
|
|
107799
108193
|
for (const match of text.matchAll(SPECIFIER)) {
|
|
107800
108194
|
const spec = match[1];
|
|
107801
108195
|
if (spec.startsWith(".")) {
|
|
107802
|
-
if (stripExt(
|
|
108196
|
+
if (stripExt(path76.posix.join(path76.posix.dirname(file), spec)) === target)
|
|
107803
108197
|
return true;
|
|
107804
108198
|
} else if (spec.includes("/") && stripExt(spec).split("/").slice(-2).join("/") === tail)
|
|
107805
108199
|
return true;
|
|
@@ -107807,7 +108201,7 @@ function relatedTests(source, testFiles) {
|
|
|
107807
108201
|
return false;
|
|
107808
108202
|
}).map((entry) => entry.file);
|
|
107809
108203
|
}
|
|
107810
|
-
function removeStaleCopies(tmp =
|
|
108204
|
+
function removeStaleCopies(tmp = os24.tmpdir()) {
|
|
107811
108205
|
let removed = 0;
|
|
107812
108206
|
let names = [];
|
|
107813
108207
|
try {
|
|
@@ -107819,12 +108213,12 @@ function removeStaleCopies(tmp = os23.tmpdir()) {
|
|
|
107819
108213
|
for (const name of names) {
|
|
107820
108214
|
if (!name.startsWith(TEMP_PREFIX))
|
|
107821
108215
|
continue;
|
|
107822
|
-
const dir =
|
|
108216
|
+
const dir = path76.join(tmp, name);
|
|
107823
108217
|
try {
|
|
107824
108218
|
const stat = lstatSync9(dir);
|
|
107825
108219
|
if (!stat.isDirectory() || uid !== undefined && stat.uid !== uid)
|
|
107826
108220
|
continue;
|
|
107827
|
-
const pid = Number(
|
|
108221
|
+
const pid = Number(readFileSync32(path76.join(dir, PID_FILE), "utf8"));
|
|
107828
108222
|
if (Number.isInteger(pid) && pid > 0 && alive(pid))
|
|
107829
108223
|
continue;
|
|
107830
108224
|
} catch (error) {
|
|
@@ -107839,16 +108233,16 @@ function removeStaleCopies(tmp = os23.tmpdir()) {
|
|
|
107839
108233
|
return removed;
|
|
107840
108234
|
}
|
|
107841
108235
|
function linkNodeModules(origin, target, repo, copy) {
|
|
107842
|
-
|
|
108236
|
+
mkdirSync13(target, { recursive: true });
|
|
107843
108237
|
for (const entry of readdirSync15(origin, { withFileTypes: true })) {
|
|
107844
|
-
const from =
|
|
107845
|
-
const to =
|
|
108238
|
+
const from = path76.join(origin, entry.name);
|
|
108239
|
+
const to = path76.join(target, entry.name);
|
|
107846
108240
|
if (entry.name.startsWith("@") && entry.isDirectory()) {
|
|
107847
108241
|
linkNodeModules(from, to, repo, copy);
|
|
107848
108242
|
continue;
|
|
107849
108243
|
}
|
|
107850
108244
|
if (entry.name.startsWith(".") && entry.name !== ".bin" && entry.isDirectory()) {
|
|
107851
|
-
|
|
108245
|
+
mkdirSync13(to, { recursive: true });
|
|
107852
108246
|
continue;
|
|
107853
108247
|
}
|
|
107854
108248
|
if (entry.isSymbolicLink()) {
|
|
@@ -107858,9 +108252,9 @@ function linkNodeModules(origin, target, repo, copy) {
|
|
|
107858
108252
|
} catch {
|
|
107859
108253
|
continue;
|
|
107860
108254
|
}
|
|
107861
|
-
const relative =
|
|
107862
|
-
if (!relative.startsWith("..") && !
|
|
107863
|
-
symlinkSync(
|
|
108255
|
+
const relative = path76.relative(repo, real);
|
|
108256
|
+
if (!relative.startsWith("..") && !path76.isAbsolute(relative) && !relative.split(path76.sep).includes("node_modules")) {
|
|
108257
|
+
symlinkSync(path76.join(copy, relative), to, "junction");
|
|
107864
108258
|
continue;
|
|
107865
108259
|
}
|
|
107866
108260
|
}
|
|
@@ -107876,7 +108270,7 @@ function copySymlink(repo, tree, from, to) {
|
|
|
107876
108270
|
}
|
|
107877
108271
|
const realRepo = realpathSync11(repo);
|
|
107878
108272
|
if (real && inside5(realRepo, real)) {
|
|
107879
|
-
symlinkSync(
|
|
108273
|
+
symlinkSync(path76.relative(path76.dirname(to), path76.join(tree, path76.relative(realRepo, real))), to);
|
|
107880
108274
|
return;
|
|
107881
108275
|
}
|
|
107882
108276
|
if (real && statSync11(real).isFile())
|
|
@@ -107885,23 +108279,23 @@ function copySymlink(repo, tree, from, to) {
|
|
|
107885
108279
|
symlinkSync(readlinkSync3(from), to);
|
|
107886
108280
|
}
|
|
107887
108281
|
function writeInside(copy, file, content) {
|
|
107888
|
-
const target =
|
|
108282
|
+
const target = path76.join(copy, file);
|
|
107889
108283
|
try {
|
|
107890
108284
|
const stat = lstatSync9(target);
|
|
107891
|
-
if (!stat.isFile() || !inside5(realpathSync11(copy), realpathSync11(
|
|
108285
|
+
if (!stat.isFile() || !inside5(realpathSync11(copy), realpathSync11(path76.dirname(target))))
|
|
107892
108286
|
return false;
|
|
107893
108287
|
} catch {
|
|
107894
108288
|
return false;
|
|
107895
108289
|
}
|
|
107896
108290
|
const temp = `${target}.workit-mutant-${process.pid}`;
|
|
107897
|
-
|
|
107898
|
-
|
|
108291
|
+
writeFileSync14(temp, content);
|
|
108292
|
+
renameSync8(temp, target);
|
|
107899
108293
|
return true;
|
|
107900
108294
|
}
|
|
107901
108295
|
function copyWorkingTree(repo) {
|
|
107902
|
-
const dir = mkdtempSync4(
|
|
107903
|
-
|
|
107904
|
-
const tree =
|
|
108296
|
+
const dir = mkdtempSync4(path76.join(os24.tmpdir(), TEMP_PREFIX));
|
|
108297
|
+
writeFileSync14(path76.join(dir, PID_FILE), String(process.pid));
|
|
108298
|
+
const tree = path76.join(dir, "tree");
|
|
107905
108299
|
const head = git7(repo, ["rev-parse", "--verify", "--quiet", "HEAD"]).stdout.trim();
|
|
107906
108300
|
if (head && git7(dir, ["clone", "-q", "--shared", "--no-checkout", repo, tree]).ok) {
|
|
107907
108301
|
const branch = git7(repo, ["symbolic-ref", "--quiet", "--short", "HEAD"]).stdout.trim();
|
|
@@ -107912,42 +108306,42 @@ function copyWorkingTree(repo) {
|
|
|
107912
108306
|
git7(tree, ["update-ref", "--no-deref", "HEAD", head]);
|
|
107913
108307
|
git7(tree, ["reset", "-q"]);
|
|
107914
108308
|
} else
|
|
107915
|
-
|
|
108309
|
+
mkdirSync13(tree, { recursive: true });
|
|
107916
108310
|
const listed = git7(repo, ["ls-files", "-co", "--exclude-standard", "-z"]).stdout.split("\x00");
|
|
107917
108311
|
const dirs = new Set([""]);
|
|
107918
108312
|
for (const relative of listed) {
|
|
107919
108313
|
if (!relative)
|
|
107920
108314
|
continue;
|
|
107921
|
-
const from =
|
|
108315
|
+
const from = path76.join(repo, relative);
|
|
107922
108316
|
let stat;
|
|
107923
108317
|
try {
|
|
107924
108318
|
stat = lstatSync9(from);
|
|
107925
108319
|
} catch {
|
|
107926
108320
|
continue;
|
|
107927
108321
|
}
|
|
107928
|
-
const to =
|
|
107929
|
-
|
|
108322
|
+
const to = path76.join(tree, relative);
|
|
108323
|
+
mkdirSync13(path76.dirname(to), { recursive: true });
|
|
107930
108324
|
if (stat.isSymbolicLink())
|
|
107931
108325
|
copySymlink(repo, tree, from, to);
|
|
107932
108326
|
else if (stat.isFile())
|
|
107933
108327
|
copyFileSync8(from, to);
|
|
107934
|
-
let parent =
|
|
108328
|
+
let parent = path76.dirname(relative);
|
|
107935
108329
|
while (parent !== "." && !dirs.has(parent)) {
|
|
107936
108330
|
dirs.add(parent);
|
|
107937
|
-
parent =
|
|
108331
|
+
parent = path76.dirname(parent);
|
|
107938
108332
|
}
|
|
107939
108333
|
}
|
|
107940
108334
|
for (const parent of dirs) {
|
|
107941
|
-
const modules =
|
|
107942
|
-
if (existsSync29(modules) && !existsSync29(
|
|
107943
|
-
linkNodeModules(modules,
|
|
108335
|
+
const modules = path76.join(repo, parent, "node_modules");
|
|
108336
|
+
if (existsSync29(modules) && !existsSync29(path76.join(tree, parent, "node_modules")))
|
|
108337
|
+
linkNodeModules(modules, path76.join(tree, parent, "node_modules"), repo, tree);
|
|
107944
108338
|
}
|
|
107945
108339
|
return { dir, tree };
|
|
107946
108340
|
}
|
|
107947
108341
|
function runCommand(command, cwd, timeoutMs, env) {
|
|
107948
108342
|
const started = performance.now();
|
|
107949
108343
|
return new Promise((resolve) => {
|
|
107950
|
-
const child =
|
|
108344
|
+
const child = spawn5(command, {
|
|
107951
108345
|
cwd,
|
|
107952
108346
|
env,
|
|
107953
108347
|
shell: true,
|
|
@@ -107979,20 +108373,20 @@ async function runMutation(options) {
|
|
|
107979
108373
|
const tracked = git7(repo, ["ls-files", "-co", "--exclude-standard", "-z"]).stdout.split("\x00").filter(Boolean);
|
|
107980
108374
|
const testFiles = tracked.filter((file) => TEST_FILE.test(file)).map((file) => {
|
|
107981
108375
|
try {
|
|
107982
|
-
return { file, text:
|
|
108376
|
+
return { file, text: readFileSync32(path76.join(repo, file), "utf8") };
|
|
107983
108377
|
} catch {
|
|
107984
108378
|
return { file, text: "" };
|
|
107985
108379
|
}
|
|
107986
108380
|
});
|
|
107987
108381
|
const candidates = [];
|
|
107988
108382
|
for (const [absolute, lines] of [...options.changed].toSorted(([a], [b]) => a.localeCompare(b))) {
|
|
107989
|
-
const relative = toPosix(
|
|
108383
|
+
const relative = toPosix(path76.relative(repo, absolute));
|
|
107990
108384
|
if (!CODE_FILE.test(relative) || TEST_FILE.test(relative) || relative.endsWith(".d.ts"))
|
|
107991
108385
|
continue;
|
|
107992
108386
|
if (NOT_SOURCE.test(relative) || !existsSync29(absolute))
|
|
107993
108387
|
continue;
|
|
107994
108388
|
try {
|
|
107995
|
-
candidates.push(...mutantsFor(
|
|
108389
|
+
candidates.push(...mutantsFor(readFileSync32(absolute, "utf8"), relative, lines));
|
|
107996
108390
|
} catch {}
|
|
107997
108391
|
}
|
|
107998
108392
|
const mutants = candidates.map((mutant, index) => ({ ...mutant, id: index + 1 }));
|
|
@@ -108000,9 +108394,9 @@ async function runMutation(options) {
|
|
|
108000
108394
|
for (const mutant of mutants)
|
|
108001
108395
|
if (!related.has(mutant.file))
|
|
108002
108396
|
related.set(mutant.file, relatedTests(mutant.file, testFiles));
|
|
108003
|
-
const cwdRelative =
|
|
108397
|
+
const cwdRelative = path76.relative(repo, options.cwd);
|
|
108004
108398
|
const asArg = (file) => {
|
|
108005
|
-
const relative = toPosix(
|
|
108399
|
+
const relative = toPosix(path76.relative(cwdRelative, file));
|
|
108006
108400
|
return shellQuote(relative.startsWith(".") ? relative : `./${relative}`);
|
|
108007
108401
|
};
|
|
108008
108402
|
const commandFor = (tests) => options.command.replaceAll("{files}", () => tests.map(asArg).join(" "));
|
|
@@ -108038,7 +108432,7 @@ async function runMutation(options) {
|
|
|
108038
108432
|
return finish3(options, 0, results, counts, started);
|
|
108039
108433
|
removeStaleCopies();
|
|
108040
108434
|
const { dir: copyDir, tree: copy } = copyWorkingTree(repo);
|
|
108041
|
-
const copyCwd =
|
|
108435
|
+
const copyCwd = path76.join(copy, cwdRelative);
|
|
108042
108436
|
let current = null;
|
|
108043
108437
|
const restore = () => {
|
|
108044
108438
|
if (current)
|
|
@@ -108073,7 +108467,7 @@ async function runMutation(options) {
|
|
|
108073
108467
|
record({ ...mutant, status: "skipped", durationMs: 0, tests, reason: "budget" });
|
|
108074
108468
|
continue;
|
|
108075
108469
|
}
|
|
108076
|
-
const original =
|
|
108470
|
+
const original = readFileSync32(path76.join(copy, mutant.file), "utf8");
|
|
108077
108471
|
const mutated = original.slice(0, mutant.start) + mutant.replacement + original.slice(mutant.end);
|
|
108078
108472
|
current = { file: mutant.file, original };
|
|
108079
108473
|
if (!writeInside(copy, mutant.file, mutated)) {
|
|
@@ -108130,8 +108524,8 @@ var NOT_SOURCE, FLIPS, isStringy = (node) => node.type === "StringLiteral" || no
|
|
|
108130
108524
|
return error.code === "EPERM";
|
|
108131
108525
|
}
|
|
108132
108526
|
}, inside5 = (root, file) => {
|
|
108133
|
-
const relative =
|
|
108134
|
-
return relative === "" || !relative.startsWith("..") && !
|
|
108527
|
+
const relative = path76.relative(root, file);
|
|
108528
|
+
return relative === "" || !relative.startsWith("..") && !path76.isAbsolute(relative);
|
|
108135
108529
|
}, active, killTree = (child) => {
|
|
108136
108530
|
try {
|
|
108137
108531
|
if (child.pid && process.platform !== "win32")
|
|
@@ -108180,7 +108574,7 @@ __export(exports_test_audit, {
|
|
|
108180
108574
|
run: () => run23
|
|
108181
108575
|
});
|
|
108182
108576
|
import { existsSync as existsSync30 } from "node:fs";
|
|
108183
|
-
import
|
|
108577
|
+
import path77 from "node:path";
|
|
108184
108578
|
function parse8(argv) {
|
|
108185
108579
|
const options = {
|
|
108186
108580
|
paths: [],
|
|
@@ -108285,8 +108679,8 @@ async function run23(argv, io) {
|
|
|
108285
108679
|
return emit(io, fail2("invalid_input", `${options}
|
|
108286
108680
|
usage: ${USAGE16}`));
|
|
108287
108681
|
const top = git7(io.cwd, ["rev-parse", "--show-toplevel"]);
|
|
108288
|
-
const repo = top.ok ?
|
|
108289
|
-
const display = (file) => toPosix(
|
|
108682
|
+
const repo = top.ok ? path77.resolve(top.stdout.trim()) : null;
|
|
108683
|
+
const display = (file) => toPosix(path77.relative(io.cwd, file) || file);
|
|
108290
108684
|
let base = null;
|
|
108291
108685
|
let changed = null;
|
|
108292
108686
|
if (options.diff || options.mutate) {
|
|
@@ -108424,8 +108818,8 @@ var exports_youtrack = {};
|
|
|
108424
108818
|
__export(exports_youtrack, {
|
|
108425
108819
|
run: () => run25
|
|
108426
108820
|
});
|
|
108427
|
-
import { readFileSync as
|
|
108428
|
-
import
|
|
108821
|
+
import { readFileSync as readFileSync33 } from "node:fs";
|
|
108822
|
+
import path78 from "node:path";
|
|
108429
108823
|
async function run25(argv, io) {
|
|
108430
108824
|
const [sub, ...rest] = argv;
|
|
108431
108825
|
if (sub !== "note" && sub !== "time" && sub !== "meeting")
|
|
@@ -108471,7 +108865,7 @@ async function run25(argv, io) {
|
|
|
108471
108865
|
let markdown = flags.values.markdown ?? "";
|
|
108472
108866
|
if (flags.values.file)
|
|
108473
108867
|
try {
|
|
108474
|
-
markdown =
|
|
108868
|
+
markdown = readFileSync33(path78.resolve(io.cwd, flags.values.file), "utf8");
|
|
108475
108869
|
} catch (error) {
|
|
108476
108870
|
return usage4(io, `cannot read ${flags.values.file}: ${String(error)}`, USAGE18);
|
|
108477
108871
|
}
|
|
@@ -108542,8 +108936,8 @@ var exports_changelog = {};
|
|
|
108542
108936
|
__export(exports_changelog, {
|
|
108543
108937
|
run: () => run26
|
|
108544
108938
|
});
|
|
108545
|
-
import { readFileSync as
|
|
108546
|
-
import
|
|
108939
|
+
import { readFileSync as readFileSync34 } from "node:fs";
|
|
108940
|
+
import path79 from "node:path";
|
|
108547
108941
|
async function run26(argv, io) {
|
|
108548
108942
|
const [sub, ...rest] = argv;
|
|
108549
108943
|
if (sub !== "apply")
|
|
@@ -108589,7 +108983,7 @@ async function run26(argv, io) {
|
|
|
108589
108983
|
]);
|
|
108590
108984
|
}
|
|
108591
108985
|
var USAGE19 = "workit changelog apply (--entries <JSON|@file|-> | --normalize-only) [--path CHANGELOG.md] [--preview]", readEntries = (raw, cwd) => {
|
|
108592
|
-
const text = raw === "-" ?
|
|
108986
|
+
const text = raw === "-" ? readFileSync34(0, "utf8") : raw.startsWith("@") ? readFileSync34(path79.resolve(cwd, raw.slice(1)), "utf8") : raw;
|
|
108593
108987
|
return JSON.parse(text);
|
|
108594
108988
|
};
|
|
108595
108989
|
var init_changelog2 = __esm(() => {
|
|
@@ -108605,7 +108999,7 @@ __export(exports_handoff, {
|
|
|
108605
108999
|
run: () => run27
|
|
108606
109000
|
});
|
|
108607
109001
|
import fs37 from "node:fs";
|
|
108608
|
-
import
|
|
109002
|
+
import path80 from "node:path";
|
|
108609
109003
|
import { parseArgs as parseArgs2 } from "node:util";
|
|
108610
109004
|
function render3(brief) {
|
|
108611
109005
|
const lines = [
|
|
@@ -108645,9 +109039,9 @@ function bounded(brief, cwd) {
|
|
|
108645
109039
|
let file = null;
|
|
108646
109040
|
if (store.ok)
|
|
108647
109041
|
try {
|
|
108648
|
-
const dir =
|
|
109042
|
+
const dir = path80.join(store.value.root, "handoff");
|
|
108649
109043
|
fs37.mkdirSync(dir, { recursive: true });
|
|
108650
|
-
file =
|
|
109044
|
+
file = path80.join(dir, `${(brief.branch ?? "detached").replaceAll(/[^\w.-]+/gu, "-")}.txt`);
|
|
108651
109045
|
fs37.writeFileSync(file, `${[...body, ...tail].join(`
|
|
108652
109046
|
`)}
|
|
108653
109047
|
`, {
|
|
@@ -108722,7 +109116,7 @@ var init_handoff = __esm(() => {
|
|
|
108722
109116
|
});
|
|
108723
109117
|
|
|
108724
109118
|
// packages/workit-cli/src/main.ts
|
|
108725
|
-
import
|
|
109119
|
+
import path81 from "node:path";
|
|
108726
109120
|
|
|
108727
109121
|
// packages/workit-core/src/git/env-redirect.ts
|
|
108728
109122
|
var GIT_REDIRECT_ENV = [
|
|
@@ -108881,9 +109275,9 @@ var VERBS = [
|
|
|
108881
109275
|
{
|
|
108882
109276
|
name: "upgrade",
|
|
108883
109277
|
group: "setup",
|
|
108884
|
-
usage: "workit upgrade [--hosts=a,b|none] [--cli] [--preview | --yes | --apply --confirm] [--json]",
|
|
108885
|
-
summary: "Upgrade the CLI and every host after one confirmation, then verify with doctor",
|
|
108886
|
-
load: () => Promise.resolve().then(() => (init_upgrade2(),
|
|
109278
|
+
usage: "workit upgrade [--hosts=a,b|none] [--cli] [--preview | --yes | --apply --confirm | --check] [--set-updates=prompt|auto|off] [--json]",
|
|
109279
|
+
summary: "Upgrade the CLI and every host after one confirmation, then verify with doctor; --check compares installed and latest versions",
|
|
109280
|
+
load: () => Promise.resolve().then(() => (init_upgrade2(), exports_upgrade2))
|
|
108887
109281
|
},
|
|
108888
109282
|
{
|
|
108889
109283
|
name: "launch",
|
|
@@ -108993,7 +109387,7 @@ var VERBS = [
|
|
|
108993
109387
|
'workit check test --no-lease --reason "machine is idle, debugging a hang"'
|
|
108994
109388
|
],
|
|
108995
109389
|
notes: LEASE_NOTES,
|
|
108996
|
-
load: () => Promise.resolve().then(() => (
|
|
109390
|
+
load: () => Promise.resolve().then(() => (init_check2(), exports_check))
|
|
108997
109391
|
},
|
|
108998
109392
|
withSubcommands({
|
|
108999
109393
|
name: "lock",
|
|
@@ -109671,7 +110065,7 @@ var defaultIo = (json) => ({
|
|
|
109671
110065
|
});
|
|
109672
110066
|
async function main(argv, overrides = {}, options = {}) {
|
|
109673
110067
|
const parsed = parseGlobals(argv);
|
|
109674
|
-
const cwd =
|
|
110068
|
+
const cwd = path81.resolve(overrides.cwd ?? process.cwd(), parsed.cwd ?? ".");
|
|
109675
110069
|
const io = {
|
|
109676
110070
|
...defaultIo(parsed.json),
|
|
109677
110071
|
terminals: {
|
|
@@ -109717,6 +110111,18 @@ async function main(argv, overrides = {}, options = {}) {
|
|
|
109717
110111
|
const entry = findVerb(command);
|
|
109718
110112
|
if (!entry)
|
|
109719
110113
|
return unknown2(io, command);
|
|
110114
|
+
if (!io.json && overrides.stdout === undefined && overrides.stderr === undefined && process.stdin.isTTY && process.stdout.isTTY && process.stderr.isTTY) {
|
|
110115
|
+
await Promise.resolve().then(() => init_update_check());
|
|
110116
|
+
const reexecuted = await launchUpdateCheck({ argv, command, json: parsed.json }, {
|
|
110117
|
+
env: io.env,
|
|
110118
|
+
stdin: process.stdin,
|
|
110119
|
+
stdout: process.stdout,
|
|
110120
|
+
stderr: process.stderr,
|
|
110121
|
+
write: (text) => void process.stderr.write(text)
|
|
110122
|
+
});
|
|
110123
|
+
if (reexecuted !== undefined)
|
|
110124
|
+
return reexecuted;
|
|
110125
|
+
}
|
|
109720
110126
|
const route = async (routed) => {
|
|
109721
110127
|
if (wantsHelp(verbArgs)) {
|
|
109722
110128
|
const word = firstWord(verbArgs);
|
|
@@ -109887,8 +110293,14 @@ var describe4 = (entry) => ({
|
|
|
109887
110293
|
summary: entry.summary,
|
|
109888
110294
|
...entry.planned ? { planned: entry.planned } : {}
|
|
109889
110295
|
});
|
|
109890
|
-
var unknown2 = (io, command) => emit(io, fail2("invalid_input", `unknown command "${command}"`, {
|
|
110296
|
+
var unknown2 = (io, command) => emit(io, fail2("invalid_input", `unknown command "${command}"`, {
|
|
110297
|
+
unblock: commandUnblock(command)
|
|
110298
|
+
}));
|
|
109891
110299
|
if (__require.main == __require.module) {
|
|
110300
|
+
if (process.env.WORKIT_UPDATE_REFRESH === "1") {
|
|
110301
|
+
(await Promise.resolve().then(() => (init_update_check(), exports_update_check))).refreshUpdateCache(process.env);
|
|
110302
|
+
process.exit(0);
|
|
110303
|
+
}
|
|
109892
110304
|
const code = await main(process.argv.slice(2), {}, { diagnostics: true });
|
|
109893
110305
|
await flushStreams();
|
|
109894
110306
|
process.exit(code);
|