@brainervirus/workit-cli 8.13.1 → 8.14.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/dist/index.js +103 -12
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -65,7 +65,7 @@ var package_default;
|
|
|
65
65
|
var init_package = __esm(() => {
|
|
66
66
|
package_default = {
|
|
67
67
|
name: "@brainervirus/workit-cli",
|
|
68
|
-
version: "8.
|
|
68
|
+
version: "8.14.0",
|
|
69
69
|
private: false,
|
|
70
70
|
description: "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
71
71
|
keywords: [
|
|
@@ -103,13 +103,13 @@ var init_package = __esm(() => {
|
|
|
103
103
|
},
|
|
104
104
|
dependencies: {
|
|
105
105
|
"@babel/parser": "7.29.9",
|
|
106
|
-
"@brainervirus/workit-cursor": "^8.
|
|
106
|
+
"@brainervirus/workit-cursor": "^8.14.0",
|
|
107
107
|
"@inkjs/ui": "2.0.0",
|
|
108
108
|
ink: "7.1.1",
|
|
109
109
|
react: "19.2.8"
|
|
110
110
|
},
|
|
111
111
|
devDependencies: {
|
|
112
|
-
"@brainervirus/workit-core": "^8.
|
|
112
|
+
"@brainervirus/workit-core": "^8.14.0"
|
|
113
113
|
},
|
|
114
114
|
engines: {
|
|
115
115
|
node: ">=24"
|
|
@@ -14022,23 +14022,79 @@ var nonBlank, branchPreset, commitPreset, workspaceBranchPolicySchema, workspace
|
|
|
14022
14022
|
}, resolveRuntimeReleaseTracks = (cwd) => {
|
|
14023
14023
|
const matched = matchRuntimeWorkspace(cwd);
|
|
14024
14024
|
return matched ? { workspace: matched.selected.name, releaseTracks: matched.selected.releaseTracks } : null;
|
|
14025
|
-
},
|
|
14025
|
+
}, inheritedSetting = (cwd, dir, has) => {
|
|
14026
14026
|
let matched;
|
|
14027
14027
|
try {
|
|
14028
14028
|
matched = matchRuntimeWorkspace(cwd, dir);
|
|
14029
14029
|
} catch {
|
|
14030
|
-
return
|
|
14030
|
+
return null;
|
|
14031
14031
|
}
|
|
14032
14032
|
if (!matched)
|
|
14033
|
-
return
|
|
14033
|
+
return null;
|
|
14034
14034
|
const { selected, matches } = matched;
|
|
14035
14035
|
const enclosing = matches.filter((entry) => entry !== selected).toSorted((a, b) => globSpecificity(b.glob) - globSpecificity(a.glob));
|
|
14036
|
-
|
|
14036
|
+
return { workspace: selected.name, source: [selected, ...enclosing].find(has) ?? null };
|
|
14037
|
+
}, workspaceTrailers = (cwd, dir) => {
|
|
14038
|
+
const found = inheritedSetting(cwd, dir, (entry) => typeof entry.trailers === "boolean");
|
|
14037
14039
|
return {
|
|
14038
|
-
enabled: source?.trailers !== false,
|
|
14039
|
-
workspace:
|
|
14040
|
-
from: source?.name ?? null
|
|
14040
|
+
enabled: found?.source?.trailers !== false,
|
|
14041
|
+
workspace: found?.workspace ?? null,
|
|
14042
|
+
from: found?.source?.name ?? null
|
|
14041
14043
|
};
|
|
14044
|
+
}, hostFamily = (host) => host.replace(/_(?:cli|desktop)$/u, ""), TIER_KEYS, TIER_HOSTS, workspaceTierModelIssues = (cwd, dir) => {
|
|
14045
|
+
let matched;
|
|
14046
|
+
try {
|
|
14047
|
+
matched = matchRuntimeWorkspace(cwd, dir);
|
|
14048
|
+
} catch {
|
|
14049
|
+
return [];
|
|
14050
|
+
}
|
|
14051
|
+
const issues = [];
|
|
14052
|
+
for (const entry of matched?.matches ?? []) {
|
|
14053
|
+
const models = entry.fanout?.tierModels;
|
|
14054
|
+
if (models === undefined)
|
|
14055
|
+
continue;
|
|
14056
|
+
const where = `workspace ${entry.name} fanout.tierModels`;
|
|
14057
|
+
if (!models || typeof models !== "object" || Array.isArray(models)) {
|
|
14058
|
+
issues.push(`${where} is not an object; ignored`);
|
|
14059
|
+
continue;
|
|
14060
|
+
}
|
|
14061
|
+
for (const [tier, value] of Object.entries(models)) {
|
|
14062
|
+
if (!TIER_KEYS.has(tier))
|
|
14063
|
+
issues.push(`${where}.${tier}: unknown tier; ignored`);
|
|
14064
|
+
else if (typeof value === "string") {
|
|
14065
|
+
if (!value.trim())
|
|
14066
|
+
issues.push(`${where}.${tier}: empty model name; ignored`);
|
|
14067
|
+
} else if (!value || typeof value !== "object" || Array.isArray(value))
|
|
14068
|
+
issues.push(`${where}.${tier}: not a model name or a per-host object; ignored`);
|
|
14069
|
+
else
|
|
14070
|
+
for (const [host, model] of Object.entries(value)) {
|
|
14071
|
+
if (!TIER_HOSTS.has(host))
|
|
14072
|
+
issues.push(`${where}.${tier}.${host}: unknown host; ignored`);
|
|
14073
|
+
else if (typeof model !== "string" || !model.trim())
|
|
14074
|
+
issues.push(`${where}.${tier}.${host}: not a model name; ignored`);
|
|
14075
|
+
}
|
|
14076
|
+
}
|
|
14077
|
+
}
|
|
14078
|
+
return issues;
|
|
14079
|
+
}, workspaceTierModel = (cwd, tier, host, dir) => {
|
|
14080
|
+
const pick = (entry) => {
|
|
14081
|
+
const fanout = entry.fanout;
|
|
14082
|
+
const models = fanout?.tierModels;
|
|
14083
|
+
if (!models || typeof models !== "object" || !Object.hasOwn(models, tier))
|
|
14084
|
+
return null;
|
|
14085
|
+
const value = models[tier];
|
|
14086
|
+
if (typeof value === "string")
|
|
14087
|
+
return value.trim() || null;
|
|
14088
|
+
if (!value || typeof value !== "object")
|
|
14089
|
+
return null;
|
|
14090
|
+
const byHost = value;
|
|
14091
|
+
const family = host ? hostFamily(host) : null;
|
|
14092
|
+
const named = (family && Object.hasOwn(byHost, family) ? byHost[family] : undefined) ?? (host && Object.hasOwn(byHost, host) ? byHost[host] : undefined) ?? (Object.hasOwn(byHost, "default") ? byHost.default : undefined);
|
|
14093
|
+
return typeof named === "string" && named.trim() ? named.trim() : null;
|
|
14094
|
+
};
|
|
14095
|
+
const found = inheritedSetting(cwd, dir, (entry) => pick(entry) !== null);
|
|
14096
|
+
const model = found?.source ? pick(found.source) : null;
|
|
14097
|
+
return model && found?.source ? { model, workspace: found.source.name } : null;
|
|
14042
14098
|
}, resolveRuntimeWorkspaceCandidate = (cwd, kind) => {
|
|
14043
14099
|
const matched = matchRuntimeWorkspace(cwd);
|
|
14044
14100
|
if (!matched)
|
|
@@ -14190,6 +14246,8 @@ var init_workspaces = __esm(() => {
|
|
|
14190
14246
|
defaultEndpoint: unknown().optional(),
|
|
14191
14247
|
verification: _enum(["self", "independent"]).optional(),
|
|
14192
14248
|
trailers: boolean2().optional(),
|
|
14249
|
+
liveSessionGuard: boolean2().optional(),
|
|
14250
|
+
fanout: object({ tierModels: unknown().optional() }).passthrough().optional(),
|
|
14193
14251
|
autonomy: object(Object.fromEntries(["push", "pr", "merge", "release", "rerun"].map((kind) => [
|
|
14194
14252
|
kind,
|
|
14195
14253
|
union([boolean2(), literal("verified")]).optional()
|
|
@@ -14239,6 +14297,17 @@ var init_workspaces = __esm(() => {
|
|
|
14239
14297
|
runtimeWorkspaceIndexSchema = object({
|
|
14240
14298
|
workspaces: array(object({ name: nonBlank, glob: nonBlank }).passthrough()).optional()
|
|
14241
14299
|
}).passthrough();
|
|
14300
|
+
TIER_KEYS = new Set(["mundane", "standard", "hard"]);
|
|
14301
|
+
TIER_HOSTS = new Set([
|
|
14302
|
+
"claude_code",
|
|
14303
|
+
"opencode",
|
|
14304
|
+
"codex",
|
|
14305
|
+
"codex_cli",
|
|
14306
|
+
"codex_desktop",
|
|
14307
|
+
"cursor",
|
|
14308
|
+
"pi",
|
|
14309
|
+
"default"
|
|
14310
|
+
]);
|
|
14242
14311
|
});
|
|
14243
14312
|
|
|
14244
14313
|
// packages/workit-core/src/core/release-tracks.ts
|
|
@@ -73303,9 +73372,15 @@ function show(argv, io) {
|
|
|
73303
73372
|
return emit(io, fail("invalid_input", error instanceof Error ? error.message : String(error)));
|
|
73304
73373
|
}
|
|
73305
73374
|
const tracks = releaseTracksReport(io.cwd);
|
|
73306
|
-
const
|
|
73375
|
+
const tierModelIssues = workspaceTierModelIssues(io.cwd);
|
|
73376
|
+
const shown = {
|
|
73377
|
+
...autonomy,
|
|
73378
|
+
...tracks.tracks.length || tracks.error ? { releaseTracks: tracks } : {},
|
|
73379
|
+
...tierModelIssues.length ? { tierModelIssues } : {}
|
|
73380
|
+
};
|
|
73307
73381
|
return emit(io, ok(shown), (data) => [
|
|
73308
73382
|
...data.note ? [`note: ${data.note}`] : [],
|
|
73383
|
+
...tierModelIssues.map((issue) => `note: ${issue}`),
|
|
73309
73384
|
data.workspace ? `workspace ${data.workspace} (${data.source === "default" ? "D4 defaults" : `from ${data.source}`})` : "no workspace matches this checkout: D4 defaults apply",
|
|
73310
73385
|
...describe2(data.grants, data.configured, data, data.verification),
|
|
73311
73386
|
...describeReleaseTracks(tracks).map((line) => ` ${line}`),
|
|
@@ -73401,6 +73476,7 @@ usage: ${USAGE2}`)), run9 = (argv, io) => runGrant(argv, io);
|
|
|
73401
73476
|
var init_grant = __esm(() => {
|
|
73402
73477
|
init_autonomy();
|
|
73403
73478
|
init_release_tracks();
|
|
73479
|
+
init_workspaces();
|
|
73404
73480
|
init_output();
|
|
73405
73481
|
init_prompt();
|
|
73406
73482
|
AGENT_ENV = [
|
|
@@ -82374,6 +82450,7 @@ function renderBrief(cwd, plan, input) {
|
|
|
82374
82450
|
what: String(row.what)
|
|
82375
82451
|
}));
|
|
82376
82452
|
const identity = identityOf(input.actor.host);
|
|
82453
|
+
const model = workspaceTierModel(cwd, slice.tier, input.actor.host);
|
|
82377
82454
|
const minted = workerSession(sessionSafe(input.actor.session), slice.id, input.attempt);
|
|
82378
82455
|
const session = identity === "declared" ? minted : null;
|
|
82379
82456
|
const fanIn = plan.fanIn === "integration" ? [
|
|
@@ -82397,6 +82474,7 @@ function renderBrief(cwd, plan, input) {
|
|
|
82397
82474
|
...slice.acceptance.map((line) => ` - ${line}`),
|
|
82398
82475
|
`VERIFY: ${slice.verify.join("; ")}`,
|
|
82399
82476
|
`TIER: ${slice.tier}`,
|
|
82477
|
+
...model ? [` model: ${model.model} (fanout.tierModels in workspace ${model.workspace})`] : [],
|
|
82400
82478
|
`TIMEBOX: ${slice.timebox ?? DEFAULT_TIMEBOX}; past it without a new commit you will be replaced`,
|
|
82401
82479
|
scratchLine,
|
|
82402
82480
|
`FORBIDDEN: ${slice.forbidden.join("; ")}`,
|
|
@@ -82417,6 +82495,7 @@ function renderBrief(cwd, plan, input) {
|
|
|
82417
82495
|
branch,
|
|
82418
82496
|
base: slice.base,
|
|
82419
82497
|
tier: slice.tier,
|
|
82498
|
+
model: model?.model ?? null,
|
|
82420
82499
|
scratch,
|
|
82421
82500
|
session,
|
|
82422
82501
|
standing,
|
|
@@ -82459,6 +82538,7 @@ var DEFAULT_TIMEBOX = "30 minutes", REPORT, identityOf = (host) => {
|
|
|
82459
82538
|
];
|
|
82460
82539
|
}, sessionSafe = (text) => text.replace(/[^A-Za-z0-9_.:@/+-]/gu, "-"), SESSION_MAX = 128;
|
|
82461
82540
|
var init_fanout_brief = __esm(() => {
|
|
82541
|
+
init_workspaces();
|
|
82462
82542
|
init_ledger();
|
|
82463
82543
|
init_fanout();
|
|
82464
82544
|
init_fanout_worktree();
|
|
@@ -83076,6 +83156,15 @@ function fanoutStatus(cwd, plan, options) {
|
|
|
83076
83156
|
if (row.waitsFor.length && !suggested.includes(id))
|
|
83077
83157
|
row.reasons.push(`waits for ${row.waitsFor.join(", ")}`);
|
|
83078
83158
|
}
|
|
83159
|
+
const host = options.host === undefined ? actorFromEnv(process.env).host : options.host;
|
|
83160
|
+
const spawnModels = {};
|
|
83161
|
+
for (const id of spawnable) {
|
|
83162
|
+
const tier = plan.slices.find((slice) => slice.id === id)?.tier;
|
|
83163
|
+
const model = tier ? workspaceTierModel(cwd, tier, host) : null;
|
|
83164
|
+
if (model)
|
|
83165
|
+
spawnModels[id] = model.model;
|
|
83166
|
+
}
|
|
83167
|
+
const spawnList = spawnable.map((id) => spawnModels[id] ? `${id} (model ${spawnModels[id]})` : id).join(", ");
|
|
83079
83168
|
const stuck = order.filter((id) => out.get(id)?.stuck);
|
|
83080
83169
|
const down = breaker.down();
|
|
83081
83170
|
if (down)
|
|
@@ -83085,7 +83174,7 @@ function fanoutStatus(cwd, plan, options) {
|
|
|
83085
83174
|
const row = out.get(id);
|
|
83086
83175
|
return !row.landed && row.reasons.length === 1 && row.reasons[0] === "no PR";
|
|
83087
83176
|
});
|
|
83088
|
-
const next = stuck.length ? `replace ${stuck.join(", ")}: stop the worker, then workit fanout worktree release ${stuck[0]} (records git status first) and respawn it in MODE: resume` : suggested.length ? online ? `land in this order: ${suggested.join(", ")} (workit fanout check first; workit pr merge each)` : `land in this order: ${suggested.join(", ")} once each has a PR (offline: PRs unchecked; open a missing one with workit git push && workit pr create --fill, then workit fanout status online)` : noPr.length ? `open PRs for ${noPr.join(", ")}: workit git push && workit pr create --fill on each branch` : spawnable.length ? `spawn ${
|
|
83177
|
+
const next = stuck.length ? `replace ${stuck.join(", ")}: stop the worker, then workit fanout worktree release ${stuck[0]} (records git status first) and respawn it in MODE: resume` : suggested.length ? online ? `land in this order: ${suggested.join(", ")} (workit fanout check first; workit pr merge each)` : `land in this order: ${suggested.join(", ")} once each has a PR (offline: PRs unchecked; open a missing one with workit git push && workit pr create --fill, then workit fanout status online)` : noPr.length ? `open PRs for ${noPr.join(", ")}: workit git push && workit pr create --fill on each branch` : spawnable.length ? `spawn ${spawnList} (workit fanout worktree create <slice> on hosts without native worktrees)` : order.every((id) => out.get(id)?.landed) ? "every slice has landed" : "wait for workers, then workit fanout status again";
|
|
83089
83178
|
return {
|
|
83090
83179
|
ok: true,
|
|
83091
83180
|
data: {
|
|
@@ -83099,6 +83188,7 @@ function fanoutStatus(cwd, plan, options) {
|
|
|
83099
83188
|
slices: order.map((id) => out.get(id)),
|
|
83100
83189
|
landingOrder: suggested,
|
|
83101
83190
|
spawnable,
|
|
83191
|
+
spawnModels,
|
|
83102
83192
|
stuck,
|
|
83103
83193
|
next,
|
|
83104
83194
|
notes
|
|
@@ -83112,6 +83202,7 @@ var DEFAULT_STUCK_MS, isoOf = (seconds) => {
|
|
|
83112
83202
|
var init_fanout_status = __esm(() => {
|
|
83113
83203
|
init_duration();
|
|
83114
83204
|
init_report();
|
|
83205
|
+
init_workspaces();
|
|
83115
83206
|
init_ledger();
|
|
83116
83207
|
init_fanout_check();
|
|
83117
83208
|
init_fanout_landed();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-cli",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.14.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Workit CLI — setup wizard, doctor, and task control for agentic coding workflows",
|
|
6
6
|
"keywords": [
|
|
@@ -38,13 +38,13 @@
|
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"@babel/parser": "7.29.9",
|
|
41
|
-
"@brainervirus/workit-cursor": "^8.
|
|
41
|
+
"@brainervirus/workit-cursor": "^8.14.0",
|
|
42
42
|
"@inkjs/ui": "2.0.0",
|
|
43
43
|
"ink": "7.1.1",
|
|
44
44
|
"react": "19.2.8"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@brainervirus/workit-core": "^8.
|
|
47
|
+
"@brainervirus/workit-core": "^8.14.0"
|
|
48
48
|
},
|
|
49
49
|
"engines": {
|
|
50
50
|
"node": ">=24"
|