@brainervirus/workit-cli 8.19.1 → 8.20.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.
Files changed (2) hide show
  1. package/dist/index.js +430 -315
  2. 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.19.1",
68
+ version: "8.20.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.19.1",
106
+ "@brainervirus/workit-cursor": "^8.20.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.19.1"
112
+ "@brainervirus/workit-core": "^8.20.0"
113
113
  },
114
114
  engines: {
115
115
  node: ">=24"
@@ -117,55 +117,6 @@ var init_package = __esm(() => {
117
117
  };
118
118
  });
119
119
 
120
- // packages/workit-cli/src/output.ts
121
- function emit(io, envelope, human) {
122
- if (io.json) {
123
- io.stdout(`${JSON.stringify(envelope)}
124
- `);
125
- } else if (envelope.ok) {
126
- const text = human?.(envelope.data);
127
- const lines = typeof text === "string" ? [text] : text ?? [];
128
- for (const value of lines)
129
- io.stdout(`${value}
130
- `);
131
- } else {
132
- io.stderr(`workit: ${envelope.error ?? envelope.code}
133
- `);
134
- if (envelope.unblock)
135
- io.stderr(` unblock: ${envelope.unblock}
136
- `);
137
- }
138
- return exitCodeFor(envelope.code);
139
- }
140
- var EXIT, EXIT_BY_CODE, exitCodeFor = (code) => EXIT_BY_CODE[code], ok = (data) => ({ ok: true, code: "ok", data }), fail = (code, error, extra = {}) => ({
141
- ok: false,
142
- code,
143
- data: extra.data ?? {},
144
- error,
145
- ...extra.unblock ? { unblock: extra.unblock } : {}
146
- });
147
- var init_output = __esm(() => {
148
- EXIT = {
149
- ok: 0,
150
- failed: 1,
151
- usage: 2,
152
- blocked: 3,
153
- busy: 4,
154
- unavailable: 5
155
- };
156
- EXIT_BY_CODE = {
157
- ok: EXIT.ok,
158
- failed: EXIT.failed,
159
- not_found: EXIT.failed,
160
- invalid_input: EXIT.usage,
161
- not_implemented: EXIT.usage,
162
- blocked: EXIT.blocked,
163
- busy: EXIT.busy,
164
- pending: EXIT.busy,
165
- unavailable: EXIT.unavailable
166
- };
167
- });
168
-
169
120
  // packages/workit-core/src/check-config.ts
170
121
  import { spawnSync } from "node:child_process";
171
122
  import fs from "node:fs";
@@ -21482,7 +21433,7 @@ function resolveInside(root, candidate) {
21482
21433
  }
21483
21434
  return target;
21484
21435
  }
21485
- var ok2 = (data) => ({ ok: true, data, error: null }), fail2 = (error, data = null) => ({
21436
+ var ok = (data) => ({ ok: true, data, error: null }), fail = (error, data = null) => ({
21486
21437
  ok: false,
21487
21438
  data,
21488
21439
  error
@@ -21604,6 +21555,12 @@ async function parseTaskArgs(argv, deps) {
21604
21555
  json = true;
21605
21556
  continue;
21606
21557
  }
21558
+ if (family === "task" && action === "list" && token === "--status") {
21559
+ const value = inline ?? argv[++i];
21560
+ if (value !== "all")
21561
+ return parseUsage(`task list has no status filter (got --status ${value ?? ""}); it lists every task`, json);
21562
+ continue;
21563
+ }
21607
21564
  if (takesWorkerId && workerId === undefined && !argv[i].startsWith("-")) {
21608
21565
  workerId = argv[i];
21609
21566
  continue;
@@ -21885,6 +21842,55 @@ var init_task = __esm(() => {
21885
21842
  };
21886
21843
  });
21887
21844
 
21845
+ // packages/workit-cli/src/output.ts
21846
+ function emit(io, envelope, human) {
21847
+ if (io.json) {
21848
+ io.stdout(`${JSON.stringify(envelope)}
21849
+ `);
21850
+ } else if (envelope.ok) {
21851
+ const text = human?.(envelope.data);
21852
+ const lines = typeof text === "string" ? [text] : text ?? [];
21853
+ for (const value of lines)
21854
+ io.stdout(`${value}
21855
+ `);
21856
+ } else {
21857
+ io.stderr(`workit: ${envelope.error ?? envelope.code}
21858
+ `);
21859
+ if (envelope.unblock)
21860
+ io.stderr(` unblock: ${envelope.unblock}
21861
+ `);
21862
+ }
21863
+ return exitCodeFor(envelope.code);
21864
+ }
21865
+ var EXIT, EXIT_BY_CODE, exitCodeFor = (code) => EXIT_BY_CODE[code], ok2 = (data) => ({ ok: true, code: "ok", data }), fail2 = (code, error, extra = {}) => ({
21866
+ ok: false,
21867
+ code,
21868
+ data: extra.data ?? {},
21869
+ error,
21870
+ ...extra.unblock ? { unblock: extra.unblock } : {}
21871
+ });
21872
+ var init_output = __esm(() => {
21873
+ EXIT = {
21874
+ ok: 0,
21875
+ failed: 1,
21876
+ usage: 2,
21877
+ blocked: 3,
21878
+ busy: 4,
21879
+ unavailable: 5
21880
+ };
21881
+ EXIT_BY_CODE = {
21882
+ ok: EXIT.ok,
21883
+ failed: EXIT.failed,
21884
+ not_found: EXIT.failed,
21885
+ invalid_input: EXIT.usage,
21886
+ not_implemented: EXIT.usage,
21887
+ blocked: EXIT.blocked,
21888
+ busy: EXIT.busy,
21889
+ pending: EXIT.busy,
21890
+ unavailable: EXIT.unavailable
21891
+ };
21892
+ });
21893
+
21888
21894
  // packages/workit-cli/src/verbs/task.ts
21889
21895
  function isImplicitTaskForm(argv) {
21890
21896
  const [action, ...rest] = argv;
@@ -21929,7 +21935,7 @@ async function run(argv, io) {
21929
21935
  const [action, ...rest] = argv;
21930
21936
  const flags = parse4(rest);
21931
21937
  if (flags instanceof Error)
21932
- return emit(io, fail("invalid_input", flags.message, { unblock: USAGE }));
21938
+ return emit(io, fail2("invalid_input", flags.message, { unblock: USAGE }));
21933
21939
  await Promise.resolve().then(() => init_core3());
21934
21940
  const root = rootFor(io);
21935
21941
  const store = new TaskStore(root);
@@ -21951,7 +21957,7 @@ async function run(argv, io) {
21951
21957
  };
21952
21958
  const key = store.currentKey();
21953
21959
  if (!key.ok)
21954
- return emit(io, fail("unavailable", key.error));
21960
+ return emit(io, fail2("unavailable", key.error));
21955
21961
  const where = key.data.branch ? `branch ${key.data.branch}` : key.data.key;
21956
21962
  if (action === "status") {
21957
21963
  if (flags.switches.has("--all")) {
@@ -21968,7 +21974,7 @@ async function run(argv, io) {
21968
21974
  progress: entry.progress,
21969
21975
  current: entry.key === key.data.key && entry.status !== "closed"
21970
21976
  }));
21971
- return emit(io, ok({ key: key.data, tasks }), (data) => data.tasks.length ? data.tasks.map((task) => `${task.current ? "*" : " "} ${task.id} ${task.status}${task.key ? ` [${task.key}]` : task.legacy ? " [2.x; adopt with workit task adopt <id>]" : ""} — ${task.objective}`) : ["no tasks in this store"]);
21977
+ return emit(io, ok2({ key: key.data, tasks }), (data) => data.tasks.length ? data.tasks.map((task) => `${task.current ? "*" : " "} ${task.id} ${task.status}${task.key ? ` [${task.key}]` : task.legacy ? " [2.x; adopt with workit task adopt <id>]" : ""} — ${task.objective}`) : ["no tasks in this store"]);
21972
21978
  }
21973
21979
  const found = store.implicitTask({ provenance, create: false });
21974
21980
  if (!found.ok)
@@ -21985,7 +21991,7 @@ async function run(argv, io) {
21985
21991
  });
21986
21992
  const noteLines = notes.map((note) => `duplicate open task ${note.id} on ${note.key} (not used); close it: ${note.hint}`);
21987
21993
  if (!found.data)
21988
- return emit(io, ok({ key: key.data, task: null, notes }), () => [
21994
+ return emit(io, ok2({ key: key.data, task: null, notes }), () => [
21989
21995
  `no task for ${where} yet; it is created by the first note, check or recording (or: workit task start "<objective>")`,
21990
21996
  ...noteLines
21991
21997
  ]);
@@ -21998,7 +22004,7 @@ async function run(argv, io) {
21998
22004
  if (!summary.ok)
21999
22005
  return engineFailure(io, summary);
22000
22006
  const task = found.data.task;
22001
- return emit(io, ok({ key: key.data, task: summary.data, notes }), () => [
22007
+ return emit(io, ok2({ key: key.data, task: summary.data, notes }), () => [
22002
22008
  `${task.id} ${task.status} — ${task.intent.data.objective} (${where})`,
22003
22009
  ...task.progress.summary ? [`progress: ${task.progress.summary}`] : [],
22004
22010
  ...task.progress.nextAction ? [`next: ${task.progress.nextAction}`] : [],
@@ -22009,7 +22015,7 @@ async function run(argv, io) {
22009
22015
  if (action === "start" || action === "note") {
22010
22016
  const text = flags.positionals.join(" ").trim();
22011
22017
  if (!text)
22012
- return emit(io, fail("invalid_input", `task ${action} needs ${action === "start" ? "an objective" : "a note"}`, {
22018
+ return emit(io, fail2("invalid_input", `task ${action} needs ${action === "start" ? "an objective" : "a note"}`, {
22013
22019
  unblock: USAGE
22014
22020
  }));
22015
22021
  const objective = action === "start" ? text : flags.values.get("--objective") ?? undefined;
@@ -22048,7 +22054,7 @@ async function run(argv, io) {
22048
22054
  const latest = store.readTask(task.id);
22049
22055
  if (latest.ok)
22050
22056
  task = latest.data;
22051
- return emit(io, ok({
22057
+ return emit(io, ok2({
22052
22058
  key: key.data,
22053
22059
  created: found.data.created,
22054
22060
  task: {
@@ -22063,12 +22069,12 @@ async function run(argv, io) {
22063
22069
  const outcomeFlag = flags.values.get("--outcome") ?? "verified";
22064
22070
  const outcome = OUTCOMES[outcomeFlag];
22065
22071
  if (!outcome)
22066
- return emit(io, fail("invalid_input", "--outcome is verified, limited or stopped", { unblock: USAGE }));
22072
+ return emit(io, fail2("invalid_input", "--outcome is verified, limited or stopped", { unblock: USAGE }));
22067
22073
  const found = store.implicitTask({ provenance, create: false });
22068
22074
  if (!found.ok)
22069
22075
  return engineFailure(io, found);
22070
22076
  if (!found.data)
22071
- return emit(io, fail("not_found", `no open task for ${where}`));
22077
+ return emit(io, fail2("not_found", `no open task for ${where}`));
22072
22078
  const task = found.data.task;
22073
22079
  const summary = flags.values.get("--summary") ?? (task.progress.summary || `closed (${outcomeFlag})`);
22074
22080
  return runTaskCommand([
@@ -22085,15 +22091,15 @@ async function run(argv, io) {
22085
22091
  if (action === "adopt") {
22086
22092
  const [id] = flags.positionals;
22087
22093
  if (!id || flags.positionals.length !== 1)
22088
- return emit(io, fail("invalid_input", "task adopt takes one task id", { unblock: USAGE }));
22094
+ return emit(io, fail2("invalid_input", "task adopt takes one task id", { unblock: USAGE }));
22089
22095
  const adopted = store.adoptTask(id);
22090
22096
  if (!adopted.ok)
22091
22097
  return engineFailure(io, adopted, "workit task status --all");
22092
- return emit(io, ok({ key: key.data, task: { id: adopted.data.id, status: adopted.data.status } }), () => `${adopted.data.id} now tracks ${where}`);
22098
+ return emit(io, ok2({ key: key.data, task: { id: adopted.data.id, status: adopted.data.status } }), () => `${adopted.data.id} now tracks ${where}`);
22093
22099
  }
22094
- return emit(io, fail("invalid_input", `unknown task action ${action ?? ""}`, { unblock: USAGE }));
22100
+ return emit(io, fail2("invalid_input", `unknown task action ${action ?? ""}`, { unblock: USAGE }));
22095
22101
  }
22096
- var USAGE = 'workit task status [--all] | task start "<objective>" | task note "<text>" [--next "<t>"] [--objective "<t>"] | task close [--outcome verified|limited|stopped] [--summary "<t>"] [--confirm] | task adopt <id>', IMPLICIT2, VALUE_FLAGS, SWITCHES, ENGINE_CODES, engineFailure = (io, result, unblock) => emit(io, fail(ENGINE_CODES[result.code] ?? "failed", `${result.code}: ${result.error}`, {
22102
+ var USAGE = 'workit task status [--all] | task start "<objective>" | task note "<text>" [--next "<t>"] [--objective "<t>"] | task close [--outcome verified|limited|stopped] [--summary "<t>"] [--confirm] | task adopt <id>', IMPLICIT2, VALUE_FLAGS, SWITCHES, ENGINE_CODES, engineFailure = (io, result, unblock) => emit(io, fail2(ENGINE_CODES[result.code] ?? "failed", `${result.code}: ${result.error}`, {
22097
22103
  data: { code: result.code },
22098
22104
  ...unblock ? { unblock } : result.code === "busy" ? { unblock: "retry the same command" } : {}
22099
22105
  })), OUTCOMES, rootFor = (io) => io.env.WORKFLOW_WORKSPACE_ROOT || checkRoot(io.cwd);
@@ -36767,7 +36773,7 @@ function getSgrPrefix(code) {
36767
36773
  if (code.startsWith("›")) {
36768
36774
  return "›";
36769
36775
  }
36770
- return `${ESCAPE2}${ANSI_CSI2}`;
36776
+ return `${ESCAPE}${ANSI_CSI2}`;
36771
36777
  }
36772
36778
  function createSgrCode(prefix, values) {
36773
36779
  return `${prefix}${values.join(";")}${ANSI_SGR_TERMINATOR2}`;
@@ -36776,7 +36782,7 @@ function getSgrFragments(code) {
36776
36782
  const fragments = [];
36777
36783
  const sgrPrefix = getSgrPrefix(code);
36778
36784
  let parameterString;
36779
- if (code.startsWith(`${ESCAPE2}${ANSI_CSI2}`)) {
36785
+ if (code.startsWith(`${ESCAPE}${ANSI_CSI2}`)) {
36780
36786
  parameterString = code.slice(2, -1);
36781
36787
  } else if (code.startsWith("›")) {
36782
36788
  parameterString = code.slice(1, -1);
@@ -36937,7 +36943,7 @@ function parseHyperlinkCode(string, index) {
36937
36943
  endIndex: sequenceIndex + 1
36938
36944
  };
36939
36945
  }
36940
- if (character === ESCAPE2 && string[sequenceIndex + 1] === ANSI_OSC_TERMINATOR) {
36946
+ if (character === ESCAPE && string[sequenceIndex + 1] === ANSI_OSC_TERMINATOR) {
36941
36947
  const code = string.slice(index, sequenceIndex + 2);
36942
36948
  const action = sequenceIndex === uriStart + 1 ? "close" : "open";
36943
36949
  return {
@@ -37020,7 +37026,7 @@ function parseControlStringCode(string, index) {
37020
37026
  if (supportsBellTerminator && string[sequenceIndex] === ANSI_BELL) {
37021
37027
  return createControlParseResult(string.slice(index, sequenceIndex + 1), sequenceIndex + 1);
37022
37028
  }
37023
- if (string[sequenceIndex] === ESCAPE2 && string[sequenceIndex + 1] === ANSI_OSC_TERMINATOR) {
37029
+ if (string[sequenceIndex] === ESCAPE && string[sequenceIndex + 1] === ANSI_OSC_TERMINATOR) {
37024
37030
  return createControlParseResult(string.slice(index, sequenceIndex + 2), sequenceIndex + 2);
37025
37031
  }
37026
37032
  if (string[sequenceIndex] === C1_STRING_TERMINATOR) {
@@ -37245,7 +37251,7 @@ function tokenizeAnsi(string, { endCharacter = Number.POSITIVE_INFINITY } = {})
37245
37251
  }
37246
37252
  return tokens;
37247
37253
  }
37248
- var ESCAPE_CODE_POINT = 27, C1_DCS_CODE_POINT = 144, C1_SOS_CODE_POINT = 152, C1_CSI_CODE_POINT = 155, C1_ST_CODE_POINT = 156, C1_OSC_CODE_POINT = 157, C1_PM_CODE_POINT = 158, C1_APC_CODE_POINT = 159, ESCAPES2, ESCAPE2 = "\x1B", ANSI_BELL = "\x07", ANSI_CSI2 = "[", ANSI_OSC2 = "]", ANSI_DCS = "P", ANSI_SOS = "X", ANSI_PM = "^", ANSI_APC = "_", ANSI_SGR_TERMINATOR2 = "m", ANSI_OSC_TERMINATOR = "\\", ANSI_STRING_TERMINATOR, C1_OSC = "", C1_STRING_TERMINATOR = "œ", ANSI_HYPERLINK_ESC_PREFIX, ANSI_HYPERLINK_C1_PREFIX, ANSI_HYPERLINK_ESC_CLOSE, ANSI_HYPERLINK_C1_CLOSE, CODE_POINT_0, CODE_POINT_9, CODE_POINT_SEMICOLON, CODE_POINT_COLON, CODE_POINT_CSI_PARAMETER_START, CODE_POINT_CSI_PARAMETER_END, CODE_POINT_CSI_INTERMEDIATE_START, CODE_POINT_CSI_INTERMEDIATE_END, CODE_POINT_CSI_FINAL_START, CODE_POINT_CSI_FINAL_END, REGIONAL_INDICATOR_SYMBOL_LETTER_A = 127462, REGIONAL_INDICATOR_SYMBOL_LETTER_Z = 127487, SGR_RESET_CODE = 0, SGR_EXTENDED_FOREGROUND_CODE = 38, SGR_DEFAULT_FOREGROUND_CODE = 39, SGR_EXTENDED_BACKGROUND_CODE = 48, SGR_DEFAULT_BACKGROUND_CODE = 49, SGR_COLOR_TYPE_ANSI_256 = 5, SGR_COLOR_TYPE_TRUECOLOR = 2, SGR_ANSI_256_FRAGMENT_LENGTH = 3, SGR_TRUECOLOR_FRAGMENT_LENGTH = 5, SGR_ANSI_256_LAST_PARAMETER_OFFSET = 2, SGR_TRUECOLOR_LAST_PARAMETER_OFFSET = 4, VARIATION_SELECTOR_16_CODE_POINT = 65039, COMBINING_ENCLOSING_KEYCAP_CODE_POINT = 8419, EMOJI_PRESENTATION_GRAPHEME_REGEX, GRAPHEME_SEGMENTER, endCodeNumbers;
37254
+ var ESCAPE_CODE_POINT = 27, C1_DCS_CODE_POINT = 144, C1_SOS_CODE_POINT = 152, C1_CSI_CODE_POINT = 155, C1_ST_CODE_POINT = 156, C1_OSC_CODE_POINT = 157, C1_PM_CODE_POINT = 158, C1_APC_CODE_POINT = 159, ESCAPES2, ESCAPE = "\x1B", ANSI_BELL = "\x07", ANSI_CSI2 = "[", ANSI_OSC2 = "]", ANSI_DCS = "P", ANSI_SOS = "X", ANSI_PM = "^", ANSI_APC = "_", ANSI_SGR_TERMINATOR2 = "m", ANSI_OSC_TERMINATOR = "\\", ANSI_STRING_TERMINATOR, C1_OSC = "", C1_STRING_TERMINATOR = "œ", ANSI_HYPERLINK_ESC_PREFIX, ANSI_HYPERLINK_C1_PREFIX, ANSI_HYPERLINK_ESC_CLOSE, ANSI_HYPERLINK_C1_CLOSE, CODE_POINT_0, CODE_POINT_9, CODE_POINT_SEMICOLON, CODE_POINT_COLON, CODE_POINT_CSI_PARAMETER_START, CODE_POINT_CSI_PARAMETER_END, CODE_POINT_CSI_INTERMEDIATE_START, CODE_POINT_CSI_INTERMEDIATE_END, CODE_POINT_CSI_FINAL_START, CODE_POINT_CSI_FINAL_END, REGIONAL_INDICATOR_SYMBOL_LETTER_A = 127462, REGIONAL_INDICATOR_SYMBOL_LETTER_Z = 127487, SGR_RESET_CODE = 0, SGR_EXTENDED_FOREGROUND_CODE = 38, SGR_DEFAULT_FOREGROUND_CODE = 39, SGR_EXTENDED_BACKGROUND_CODE = 48, SGR_DEFAULT_BACKGROUND_CODE = 49, SGR_COLOR_TYPE_ANSI_256 = 5, SGR_COLOR_TYPE_TRUECOLOR = 2, SGR_ANSI_256_FRAGMENT_LENGTH = 3, SGR_TRUECOLOR_FRAGMENT_LENGTH = 5, SGR_ANSI_256_LAST_PARAMETER_OFFSET = 2, SGR_TRUECOLOR_LAST_PARAMETER_OFFSET = 4, VARIATION_SELECTOR_16_CODE_POINT = 65039, COMBINING_ENCLOSING_KEYCAP_CODE_POINT = 8419, EMOJI_PRESENTATION_GRAPHEME_REGEX, GRAPHEME_SEGMENTER, endCodeNumbers;
37249
37255
  var init_tokenize_ansi = __esm(() => {
37250
37256
  init_ansi_styles();
37251
37257
  init_is_fullwidth_code_point();
@@ -37259,8 +37265,8 @@ var init_tokenize_ansi = __esm(() => {
37259
37265
  C1_PM_CODE_POINT,
37260
37266
  C1_APC_CODE_POINT
37261
37267
  ]);
37262
- ANSI_STRING_TERMINATOR = `${ESCAPE2}${ANSI_OSC_TERMINATOR}`;
37263
- ANSI_HYPERLINK_ESC_PREFIX = `${ESCAPE2}${ANSI_OSC2}8;`;
37268
+ ANSI_STRING_TERMINATOR = `${ESCAPE}${ANSI_OSC_TERMINATOR}`;
37269
+ ANSI_HYPERLINK_ESC_PREFIX = `${ESCAPE}${ANSI_OSC2}8;`;
37264
37270
  ANSI_HYPERLINK_C1_PREFIX = `${C1_OSC}8;`;
37265
37271
  ANSI_HYPERLINK_ESC_CLOSE = `${ANSI_HYPERLINK_ESC_PREFIX};`;
37266
37272
  ANSI_HYPERLINK_C1_CLOSE = `${ANSI_HYPERLINK_C1_PREFIX};`;
@@ -73094,7 +73100,7 @@ __export(exports_init, {
73094
73100
  });
73095
73101
  async function run3(_argv, io) {
73096
73102
  if (io.json)
73097
- return emit(io, fail("invalid_input", "workit init is an interactive wizard and has no --json output", {
73103
+ return emit(io, fail2("invalid_input", "workit init is an interactive wizard and has no --json output", {
73098
73104
  unblock: "run `workit init` in a terminal without --json"
73099
73105
  }));
73100
73106
  await init_src2();
@@ -73982,7 +73988,7 @@ async function run6(argv, io) {
73982
73988
  if (!confirmed) {
73983
73989
  if (!io.json)
73984
73990
  return 3;
73985
- return emit(io, fail("blocked", "fix-lock --force: refusing without --yes outside an interactive terminal", {
73991
+ return emit(io, fail2("blocked", "fix-lock --force: refusing without --yes outside an interactive terminal", {
73986
73992
  data: { lock: inspectMetadataLock(root) },
73987
73993
  unblock: "workit doctor --fix-lock --force --yes"
73988
73994
  }));
@@ -74550,7 +74556,7 @@ async function run7(argv, io) {
74550
74556
  const dryRun = argv.includes("--dry-run");
74551
74557
  const pruneRecovery = argv.includes("--prune-recovery");
74552
74558
  if (pruneRecovery && !dryRun && !argv.includes("--yes"))
74553
- return emit(io, fail("blocked", "--prune-recovery deletes the 2.x recovery copies; confirm with --yes", {
74559
+ return emit(io, fail2("blocked", "--prune-recovery deletes the 2.x recovery copies; confirm with --yes", {
74554
74560
  unblock: "workit gc --prune-recovery --yes"
74555
74561
  }));
74556
74562
  const store = new TaskStore(workspaceRootFor({ cwd: io.cwd }));
@@ -74558,11 +74564,11 @@ async function run7(argv, io) {
74558
74564
  const logs = location.ok ? pruneCheckLogs(location.data.dir, { dryRun }) : null;
74559
74565
  const result = store.collectGarbage({ dryRun, pruneRecovery });
74560
74566
  if (!result.ok)
74561
- return emit(io, fail(result.code === "busy" ? "busy" : "failed", `${result.code}: ${result.error}`, {
74567
+ return emit(io, fail2(result.code === "busy" ? "busy" : "failed", `${result.code}: ${result.error}`, {
74562
74568
  data: { code: result.code, details: result.details },
74563
74569
  ...result.code === "busy" ? { unblock: "retry `workit gc`" } : {}
74564
74570
  }));
74565
- return emit(io, ok({ ...result.data, logs }), (data) => {
74571
+ return emit(io, ok2({ ...result.data, logs }), (data) => {
74566
74572
  const verb = data.dryRun ? "would" : "did";
74567
74573
  const { compacted, blobs, legacyRecovery } = data;
74568
74574
  return [
@@ -74594,7 +74600,7 @@ __export(exports_uninstall, {
74594
74600
  });
74595
74601
  async function run8(_argv, io) {
74596
74602
  if (io.json)
74597
- return emit(io, fail("invalid_input", "workit uninstall is interactive and has no --json output", {
74603
+ return emit(io, fail2("invalid_input", "workit uninstall is interactive and has no --json output", {
74598
74604
  unblock: "run `workit uninstall` in a terminal without --json"
74599
74605
  }));
74600
74606
  await init_src2();
@@ -74619,11 +74625,11 @@ function show(argv, io) {
74619
74625
  if (all || named.length === 1) {
74620
74626
  const listed = listGrants();
74621
74627
  if (listed.error)
74622
- return emit(io, fail("invalid_input", listed.error));
74628
+ return emit(io, fail2("invalid_input", listed.error));
74623
74629
  const rows = named.length ? listed.workspaces.filter((entry) => entry.name === named[0]) : listed.workspaces;
74624
74630
  if (named.length && rows.length === 0)
74625
- return emit(io, fail("not_found", `no workspace named "${named[0]}" in ${listed.path}`));
74626
- return emit(io, ok({ path: listed.path, defaults: DEFAULT_GRANTS, workspaces: rows }), () => rows.flatMap((entry) => [
74631
+ return emit(io, fail2("not_found", `no workspace named "${named[0]}" in ${listed.path}`));
74632
+ return emit(io, ok2({ path: listed.path, defaults: DEFAULT_GRANTS, workspaces: rows }), () => rows.flatMap((entry) => [
74627
74633
  `${entry.name} (${entry.glob})`,
74628
74634
  ...describe2(entry.grants, entry.configured, entry, entry.verification)
74629
74635
  ]));
@@ -74632,7 +74638,7 @@ function show(argv, io) {
74632
74638
  try {
74633
74639
  autonomy = resolveAutonomy(io.cwd);
74634
74640
  } catch (error) {
74635
- return emit(io, fail("invalid_input", error instanceof Error ? error.message : String(error)));
74641
+ return emit(io, fail2("invalid_input", error instanceof Error ? error.message : String(error)));
74636
74642
  }
74637
74643
  const tracks = releaseTracksReport(io.cwd);
74638
74644
  const tierModelIssues = workspaceTierModelIssues(io.cwd);
@@ -74641,7 +74647,7 @@ function show(argv, io) {
74641
74647
  ...tracks.tracks.length || tracks.error ? { releaseTracks: tracks } : {},
74642
74648
  ...tierModelIssues.length ? { tierModelIssues } : {}
74643
74649
  };
74644
- return emit(io, ok(shown), (data) => [
74650
+ return emit(io, ok2(shown), (data) => [
74645
74651
  ...data.note ? [`note: ${data.note}`] : [],
74646
74652
  ...tierModelIssues.map((issue) => `note: ${issue}`),
74647
74653
  data.workspace ? `workspace ${data.workspace} (${data.source === "default" ? "D4 defaults" : `from ${data.source}`})` : "no workspace matches this checkout: D4 defaults apply",
@@ -74656,10 +74662,10 @@ async function change(verb, argv, io, deps) {
74656
74662
  return usage2(io, `${verb} needs <workspace> and a kind`);
74657
74663
  const listed = listGrants();
74658
74664
  if (listed.error)
74659
- return emit(io, fail("invalid_input", listed.error));
74665
+ return emit(io, fail2("invalid_input", listed.error));
74660
74666
  const entry = listed.workspaces.find((item) => item.name === workspace);
74661
74667
  if (!entry)
74662
- return emit(io, fail("not_found", `no workspace named "${workspace}" in ${listed.path}`));
74668
+ return emit(io, fail2("not_found", `no workspace named "${workspace}" in ${listed.path}`));
74663
74669
  const changes = [];
74664
74670
  let endpoint;
74665
74671
  let verification;
@@ -74703,17 +74709,17 @@ async function change(verb, argv, io, deps) {
74703
74709
  const command = `workit grant ${verb} ${workspace} ${specs.join(" ")}`;
74704
74710
  const agent = agentMarker(io.env);
74705
74711
  if (!deps.interactive() || agent)
74706
- return emit(io, fail("blocked", `grant_raise_refused: raising ${raised.map(({ kind }) => kind).join(", ")} needs the user at an interactive terminal${agent ? ` (this shell belongs to an agent: ${agent} is set)` : ""}; grants are never raised headless`, { unblock: `ask the user to run, in their own terminal: ${command}` }));
74712
+ return emit(io, fail2("blocked", `grant_raise_refused: raising ${raised.map(({ kind }) => kind).join(", ")} needs the user at an interactive terminal${agent ? ` (this shell belongs to an agent: ${agent} is set)` : ""}; grants are never raised headless`, { unblock: `ask the user to run, in their own terminal: ${command}` }));
74707
74713
  const answer = await askOrCancel(io, () => deps.ask(`Raise ${raised.map(({ kind, value }) => `${kind}=${value}`).join(", ")} for workspace "${workspace}"? An agent there may then do this without asking. Type the workspace name to confirm: `));
74708
74714
  if (answer === null)
74709
74715
  return cancelled(io);
74710
74716
  if (answer.trim() !== workspace)
74711
- return emit(io, fail("blocked", "grant change not confirmed; nothing was written"));
74717
+ return emit(io, fail2("blocked", "grant change not confirmed; nothing was written"));
74712
74718
  }
74713
74719
  const written = writeGrants(workspace, changes, undefined, endpoint, verification);
74714
74720
  if (!written.ok)
74715
- return emit(io, fail(written.code, written.error));
74716
- return emit(io, ok(written), (data) => [
74721
+ return emit(io, fail2(written.code, written.error));
74722
+ return emit(io, ok2(written), (data) => [
74717
74723
  `${data.workspace}: grants updated in ${data.path}${data.backup ? ` (previous copy: ${data.backup})` : ""}`,
74718
74724
  ...describe2(data.grants, data.configured, data, data.verification)
74719
74725
  ]);
@@ -74734,7 +74740,7 @@ var USAGE2 = "workit grant show [<workspace>] [--all] | grant set <workspace> <k
74734
74740
  ` default endpoint: ${endpointLabel(endpoint)} (an unnamed request stops at ${STOPS_AT[endpoint.effectiveEndpoint]})`,
74735
74741
  ...endpoint.endpointIssue ? [` note: ${endpoint.endpointIssue}`] : [],
74736
74742
  ` verification: ${verification} (${verification === "independent" ? "a normal-risk behavior change needs a non-author verdict" : "a normal-risk behavior change needs a passing check and the author's --self verdict, shown as self-reviewed"})`
74737
- ], usage2 = (io, message) => emit(io, fail("invalid_input", `${message}
74743
+ ], usage2 = (io, message) => emit(io, fail2("invalid_input", `${message}
74738
74744
  usage: ${USAGE2}`)), run9 = (argv, io) => runGrant(argv, io);
74739
74745
  var init_grant = __esm(() => {
74740
74746
  init_autonomy();
@@ -75851,7 +75857,7 @@ async function prepareHeavy(io, settings, label, runCwd, timeoutMs) {
75851
75857
  });
75852
75858
  if (!acquired.ok && acquired.reason === "timeout") {
75853
75859
  const holders = acquired.holders.map((holder) => describeHolder(holder)).join("; ");
75854
- emit(io, fail("busy", `the heavy-check lease stayed busy for ${Math.round(acquired.waitedMs / 1000)} s`, {
75860
+ emit(io, fail2("busy", `the heavy-check lease stayed busy for ${Math.round(acquired.waitedMs / 1000)} s`, {
75855
75861
  data: { lease: { waitedMs: acquired.waitedMs, holders: acquired.holders } },
75856
75862
  unblock: `wait for ${holders || "the holders"} to finish, then run it again`
75857
75863
  }));
@@ -75901,7 +75907,7 @@ async function prepareHeavy(io, settings, label, runCwd, timeoutMs) {
75901
75907
  async function run10(argv, io) {
75902
75908
  const options = parse5(argv);
75903
75909
  if (options instanceof Error)
75904
- return emit(io, fail("invalid_input", options.message, { unblock: USAGE3 }));
75910
+ return emit(io, fail2("invalid_input", options.message, { unblock: USAGE3 }));
75905
75911
  const config = loadCheckConfig(io.cwd);
75906
75912
  if (config.note)
75907
75913
  io.stderr(`note: ${config.note}
@@ -75912,13 +75918,13 @@ async function run10(argv, io) {
75912
75918
  let name = options.name;
75913
75919
  if (options.command === null) {
75914
75920
  if (options.positionals.length !== 1 || options.name || options.shell)
75915
- return emit(io, fail("invalid_input", "pass a check name, or a command after --", { unblock: USAGE3 }));
75921
+ return emit(io, fail2("invalid_input", "pass a check name, or a command after --", { unblock: USAGE3 }));
75916
75922
  name = options.positionals[0];
75917
75923
  if (config.error)
75918
- return emit(io, fail("invalid_input", `check config is invalid: ${config.error}`));
75924
+ return emit(io, fail2("invalid_input", `check config is invalid: ${config.error}`));
75919
75925
  const check = config.checks.find((item) => item.name === name);
75920
75926
  if (!check)
75921
- return emit(io, fail("not_found", `no configured check named "${name}"`, {
75927
+ return emit(io, fail2("not_found", `no configured check named "${name}"`, {
75922
75928
  data: { configured: config.checks.map((item) => item.name), source: config.source },
75923
75929
  unblock: config.checks.length ? `workit check ${config.checks.map((item) => item.name).join("|")}` : `add {"checks":{"${name}":"<command>"}} to .workit/checks.json, or run workit check --name ${name} -- <cmd…>`
75924
75930
  }));
@@ -75926,14 +75932,14 @@ async function run10(argv, io) {
75926
75932
  runCwd = config.root;
75927
75933
  } else {
75928
75934
  if (options.positionals.length)
75929
- return emit(io, fail("invalid_input", `unexpected argument ${options.positionals[0]} before --`, {
75935
+ return emit(io, fail2("invalid_input", `unexpected argument ${options.positionals[0]} before --`, {
75930
75936
  unblock: USAGE3
75931
75937
  }));
75932
75938
  command = options.command;
75933
75939
  if (!command.length)
75934
- return emit(io, fail("invalid_input", "no command after --", { unblock: USAGE3 }));
75940
+ return emit(io, fail2("invalid_input", "no command after --", { unblock: USAGE3 }));
75935
75941
  if (options.shell && command.length !== 1)
75936
- return emit(io, fail("invalid_input", '--shell takes the command as one string: workit check --shell -- "<cmd>"'));
75942
+ return emit(io, fail2("invalid_input", '--shell takes the command as one string: workit check --shell -- "<cmd>"'));
75937
75943
  }
75938
75944
  const relCwd = posix(path45.relative(top, runCwd));
75939
75945
  const configured = !options.shell && matchesNamedCheck(config, name, command, relCwd);
@@ -76146,7 +76152,7 @@ function slotLines(slots) {
76146
76152
  async function status(io) {
76147
76153
  const settings = await settingsFor(io);
76148
76154
  const slots = leaseSlots(leaseDir(io.env), settings.slots);
76149
- return emit(io, ok({ dir: leaseDir(io.env), slots, waitMs: settings.waitMs }), (data) => slotLines(data.slots));
76155
+ return emit(io, ok2({ dir: leaseDir(io.env), slots, waitMs: settings.waitMs }), (data) => slotLines(data.slots));
76150
76156
  }
76151
76157
  function timeoutOf(args) {
76152
76158
  const at = args.findIndex((arg) => arg === "--timeout" || arg.startsWith("--timeout="));
@@ -76159,7 +76165,7 @@ function timeoutOf(args) {
76159
76165
  async function wait(args, io) {
76160
76166
  const timeout = timeoutOf(args);
76161
76167
  if (timeout instanceof Error)
76162
- return emit(io, fail("invalid_input", timeout.message));
76168
+ return emit(io, fail2("invalid_input", timeout.message));
76163
76169
  const settings = await settingsFor(io);
76164
76170
  const limit = timeout ?? settings.waitMs;
76165
76171
  const dir = leaseDir(io.env);
@@ -76170,11 +76176,11 @@ async function wait(args, io) {
76170
76176
  const busy = held(slots);
76171
76177
  const waitedMs = Date.now() - started;
76172
76178
  if (busy.length < slots.length)
76173
- return emit(io, ok({ free: true, waitedMs, slots }), () => [
76179
+ return emit(io, ok2({ free: true, waitedMs, slots }), () => [
76174
76180
  `workit: the heavy-check lease has a free slot${waitedMs ? ` after ${Math.round(waitedMs / 1000)} s` : ""}`
76175
76181
  ]);
76176
76182
  if (waitedMs >= limit)
76177
- return emit(io, fail("busy", `the heavy-check lease stayed busy for ${Math.round(waitedMs / 1000)} s`, {
76183
+ return emit(io, fail2("busy", `the heavy-check lease stayed busy for ${Math.round(waitedMs / 1000)} s`, {
76178
76184
  data: { free: false, waitedMs, slots },
76179
76185
  unblock: "workit lock status"
76180
76186
  }));
@@ -76191,7 +76197,7 @@ async function runHeavy(args, io) {
76191
76197
  const head = split < 0 ? args : args.slice(0, split);
76192
76198
  const unknown = head.find((arg, index) => arg !== "--shell" && arg !== "--json" && !arg.startsWith("--timeout") && !arg.startsWith("--wait") && !((head[index - 1] === "--timeout" || head[index - 1] === "--wait") && !arg.startsWith("-")));
76193
76199
  if (split < 0 || unknown)
76194
- return emit(io, fail("invalid_input", unknown ? `unexpected ${unknown}` : "no command after --", {
76200
+ return emit(io, fail2("invalid_input", unknown ? `unexpected ${unknown}` : "no command after --", {
76195
76201
  unblock: "workit lock run [--shell] [--wait <s>] [--timeout <s>] -- <cmd…>"
76196
76202
  }));
76197
76203
  const check = await Promise.resolve().then(() => (init_check(), {}));
@@ -76219,7 +76225,7 @@ async function heavy(args, io) {
76219
76225
  const [action, ...rest] = args.filter((arg) => arg !== "--json");
76220
76226
  const file = heavyCommandsFile(io.env);
76221
76227
  if (action === "list")
76222
- return emit(io, ok({ file, machine: machinePatterns(io.env), repo: repoPatterns(io.cwd) }), (data) => [
76228
+ return emit(io, ok2({ file, machine: machinePatterns(io.env), repo: repoPatterns(io.cwd) }), (data) => [
76223
76229
  "built in: test runners, builds and bundlers, lint and typecheck, installs, image builds, Sonar, browser tests (JS, Go, Rust, JVM, .NET, Python, Ruby, PHP, Elixir, Swift, C)",
76224
76230
  `machine (${data.file}): ${data.machine.length ? data.machine.join(", ") : "none"}`,
76225
76231
  `repo (checks config resources.heavyCommands): ${data.repo.length ? data.repo.join(", ") : "none"}`
@@ -76227,7 +76233,7 @@ async function heavy(args, io) {
76227
76233
  if (action === "add" || action === "remove") {
76228
76234
  const pattern = commandText(rest);
76229
76235
  if (!parsePattern(pattern))
76230
- return emit(io, fail("invalid_input", `${action} needs a command pattern`, {
76236
+ return emit(io, fail2("invalid_input", `${action} needs a command pattern`, {
76231
76237
  unblock: `workit lock heavy ${action} '<command words>'`
76232
76238
  }));
76233
76239
  const current = readPatterns(file);
@@ -76238,22 +76244,22 @@ async function heavy(args, io) {
76238
76244
  if (patterns !== current.patterns)
76239
76245
  writePatterns(file, { ...current, patterns });
76240
76246
  } catch (error) {
76241
- return emit(io, fail("unavailable", `cannot write ${file}: ${error.message}`));
76247
+ return emit(io, fail2("unavailable", `cannot write ${file}: ${error.message}`));
76242
76248
  }
76243
76249
  const changed = action === "add" ? !has : has;
76244
- return emit(io, ok({ file, pattern: normalized, changed, patterns }), () => [
76250
+ return emit(io, ok2({ file, pattern: normalized, changed, patterns }), () => [
76245
76251
  action === "add" ? `workit: ${changed ? "added" : "already had"} heavy pattern "${normalized}" (machine-wide, ${file})` : `workit: ${changed ? "removed" : "had no"} heavy pattern "${normalized}"`
76246
76252
  ]);
76247
76253
  }
76248
76254
  if (action === "test") {
76249
76255
  const command = commandText(rest);
76250
76256
  if (!command)
76251
- return emit(io, fail("invalid_input", "test needs a command", {
76257
+ return emit(io, fail2("invalid_input", "test needs a command", {
76252
76258
  unblock: "workit lock heavy test -- <cmd…>"
76253
76259
  }));
76254
76260
  const match = heavyCommand(command, { cwd: io.cwd, env: io.env });
76255
76261
  const plan = heavyPlan(command, { cwd: io.cwd, env: io.env, rules: null });
76256
- return emit(io, ok({
76262
+ return emit(io, ok2({
76257
76263
  command,
76258
76264
  heavy: Boolean(match),
76259
76265
  reason: match?.reason ?? null,
@@ -76262,7 +76268,7 @@ async function heavy(args, io) {
76262
76268
  split: plan.kind === "split" ? plan.reason : null
76263
76269
  }), (data) => !data.heavy ? ["light: the shell hook leaves it alone"] : data.rewrite ? [`heavy (${data.reason}): the shell hook runs it as ${data.rewrite}`] : data.split ? [`heavy (${data.reason}): the shell hook denies the chain: ${data.split}`] : [`heavy (${data.reason}): outside a git checkout the shell hook leaves it alone`]);
76264
76270
  }
76265
- return emit(io, fail("invalid_input", `unknown lock heavy action ${action ?? "(none)"}`, {
76271
+ return emit(io, fail2("invalid_input", `unknown lock heavy action ${action ?? "(none)"}`, {
76266
76272
  unblock: "workit lock heavy list|add <pattern>|remove <pattern>|test -- <cmd…>"
76267
76273
  }));
76268
76274
  }
@@ -76276,7 +76282,7 @@ async function run11(argv, io) {
76276
76282
  return runHeavy(rest, io);
76277
76283
  if (sub === "heavy")
76278
76284
  return heavy(rest, io);
76279
- return emit(io, fail("invalid_input", `unknown lock subcommand ${sub ?? "(none)"}`, { unblock: USAGE4 }));
76285
+ return emit(io, fail2("invalid_input", `unknown lock subcommand ${sub ?? "(none)"}`, { unblock: USAGE4 }));
76280
76286
  }
76281
76287
  var USAGE4 = "workit lock status | wait [--timeout <s>] | run [--shell] [--wait <s>] [--timeout <s>] -- <cmd…> | heavy list|add|remove|test", held = (slots) => slots.filter((slot) => slot.holder && !slot.stale), sleep2 = (ms) => new Promise((resolve) => setTimeout(resolve, ms)), commandText = (args) => {
76282
76288
  const split = args.indexOf("--");
@@ -76295,15 +76301,15 @@ async function logTimeUpdate(input, operation = defaultOperations) {
76295
76301
  try {
76296
76302
  const value = await operation.logTime(input);
76297
76303
  if (notApplied(value))
76298
- return fail2(value.error, {
76304
+ return fail(value.error, {
76299
76305
  issueId: input.issueId,
76300
76306
  loggedMinutes: 0,
76301
76307
  outcome: "not_applied",
76302
76308
  retry: "youtrack.time"
76303
76309
  });
76304
- return ok2(unwrap(value));
76310
+ return ok(unwrap(value));
76305
76311
  } catch (error) {
76306
- return fail2(message(error), {
76312
+ return fail(message(error), {
76307
76313
  issueId: input.issueId,
76308
76314
  loggedMinutes: 0,
76309
76315
  outcome: "unknown",
@@ -82161,7 +82167,7 @@ function renderStatus(doc) {
82161
82167
  lines.push(`next: ${doc.next}`);
82162
82168
  return lines;
82163
82169
  }
82164
- var forgeDeps, MAX_REASON = 500, usage3 = (io, message, line) => emit(io, fail("invalid_input", message, { unblock: line })), forgeFail = (io, result, data) => emit(io, fail(result.code, result.error, { data, unblock: result.unblock })), CONNECT_BUDGET_MS = 15000, pushIdentity = (io, branch) => checkPushIdentity(io.cwd, {
82170
+ var forgeDeps, MAX_REASON = 500, usage3 = (io, message, line) => emit(io, fail2("invalid_input", message, { unblock: line })), forgeFail = (io, result, data) => emit(io, fail2(result.code, result.error, { data, unblock: result.unblock })), CONNECT_BUDGET_MS = 15000, pushIdentity = (io, branch) => checkPushIdentity(io.cwd, {
82165
82171
  branch,
82166
82172
  env: io.env,
82167
82173
  runner: forgeDeps.runner,
@@ -82228,7 +82234,7 @@ async function status2(argv, io) {
82228
82234
  const doc = report.data.doc;
82229
82235
  const hint = nextHint(doc.next, doc.number);
82230
82236
  const issues = issuesBlock(io.cwd, doc);
82231
- return emit(io, ok({ ...doc, nextHint: hint, verdict: verdictBlock(io.cwd, doc.head.branch, doc), issues }), (data) => {
82237
+ return emit(io, ok2({ ...doc, nextHint: hint, verdict: verdictBlock(io.cwd, doc.head.branch, doc), issues }), (data) => {
82232
82238
  const lines = renderStatus(data);
82233
82239
  if (data.issues?.length)
82234
82240
  lines.splice(1, 0, `issues: ${data.issues.map((entry) => `${entry.tracker === "youtrack" ? entry.issue : entry.url ?? `${entry.repo ?? ""}#${entry.issue}`} (${entry.relation})`).join(", ")}`);
@@ -82312,18 +82318,18 @@ async function create4(argv, io) {
82312
82318
  const flow = gitFlowOf(io.cwd);
82313
82319
  const mismatch = flowMismatch(flow, kind, base, "target");
82314
82320
  if (mismatch && flow && kind)
82315
- return emit(io, fail("blocked", mismatch, {
82321
+ return emit(io, fail2("blocked", mismatch, {
82316
82322
  unblock: `workit pr create … # without --base it targets ${flowRoute(flow, kind).target}`
82317
82323
  }));
82318
82324
  } else {
82319
82325
  const resolved = vcsConfig("resolve", io.cwd, { track: flags.values.track ?? null });
82320
82326
  if (resolved.ok === false)
82321
- return emit(io, fail("blocked", String(resolved.error), {
82327
+ return emit(io, fail2("blocked", String(resolved.error), {
82322
82328
  unblock: "fix ~/.config/workit/vcs.json or pass --base <b>"
82323
82329
  }));
82324
82330
  releaseTrack = resolved.releaseTrack ?? null;
82325
82331
  if (releaseTrack?.blocking)
82326
- return emit(io, fail("blocked", releaseTrack.blocking, {
82332
+ return emit(io, fail2("blocked", releaseTrack.blocking, {
82327
82333
  unblock: "workit pr create --track <name> … # or --base <branch>"
82328
82334
  }));
82329
82335
  base = String(resolved.defaultTargetBranch ?? "") || null;
@@ -82385,7 +82391,7 @@ async function create4(argv, io) {
82385
82391
  ...releaseTrack ? { releaseTrack } : {},
82386
82392
  ...route ? { flow: route } : {}
82387
82393
  };
82388
- return emit(io, ok(created), (data) => [
82394
+ return emit(io, ok2(created), (data) => [
82389
82395
  `${data.created ? "opened" : "found open"} ${connected.data.forge.kind === "github" ? "PR #" : "MR !"}${data.number}${data.draft && data.created ? " (draft)" : ""}: ${data.branch} -> ${data.base} ${data.url}`,
82390
82396
  ...data.releaseTrack?.name ? [`release track: ${data.releaseTrack.name} (${data.releaseTrack.detail})`] : [],
82391
82397
  ...(data.releaseTrack?.warnings ?? []).map((warning) => `note: ${warning}`),
@@ -82465,11 +82471,11 @@ async function merge3(argv, io) {
82465
82471
  ...body !== undefined ? { body } : {}
82466
82472
  }, forgeDeps.sleep);
82467
82473
  if (!result.ok)
82468
- return emit(io, fail(result.code, result.error, {
82474
+ return emit(io, fail2(result.code, result.error, {
82469
82475
  unblock: result.unblock,
82470
82476
  data: "refusal" in result && result.refusal ? result.refusal : ("recorded" in result) && result.recorded ? { recorded: result.recorded } : {}
82471
82477
  }));
82472
- return emit(io, ok(result.data), (data) => [
82478
+ return emit(io, ok2(result.data), (data) => [
82473
82479
  `merged ${connected.data.forge.kind === "github" ? "PR #" : "MR !"}${data.number} (${data.method}) at head ${data.head.slice(0, 12)}${data.mergeSha ? ` -> ${data.mergeSha.slice(0, 12)}` : ""}`,
82474
82480
  data.unverified ? `UNVERIFIED: merged without a verdict (--unverified: ${data.unverified.reason}); ledger ${data.unverified.recorded}` : `verdict ${data.verdict.verdictId ?? "?"} accepted for that head`,
82475
82481
  ...data.mergeBack.length ? [
@@ -82499,7 +82505,7 @@ async function ready(argv, io) {
82499
82505
  if (!result.ok)
82500
82506
  return forgeFail(io, result);
82501
82507
  const kind = connected.data.forge.kind;
82502
- return emit(io, ok(result.data), (data) => [
82508
+ return emit(io, ok2(result.data), (data) => [
82503
82509
  `${prLabel(kind, data.number)} ${data.changed ? "is now" : "was already"} ${data.draft ? "a draft" : "ready for review"} ${data.url}`
82504
82510
  ]);
82505
82511
  }
@@ -82544,7 +82550,7 @@ async function edit(argv, io) {
82544
82550
  if (!result.ok)
82545
82551
  return result.code === "invalid_input" ? usage3(io, result.error, EDIT_USAGE) : forgeFail(io, result);
82546
82552
  const kind = connected.data.forge.kind;
82547
- return emit(io, ok(result.data), (data) => [
82553
+ return emit(io, ok2(result.data), (data) => [
82548
82554
  `edited ${prLabel(kind, data.number)} (${data.changed.join(", ")}): ${data.title} -> ${data.base} ${data.url}`
82549
82555
  ]);
82550
82556
  }
@@ -82564,7 +82570,7 @@ async function threads(argv, io) {
82564
82570
  if (!result.ok)
82565
82571
  return forgeFail(io, result);
82566
82572
  const kind = connected.data.forge.kind;
82567
- return emit(io, ok(result.data), (data) => [
82573
+ return emit(io, ok2(result.data), (data) => [
82568
82574
  `${prLabel(kind, data.number)}: ${data.threads.length} unresolved thread${data.threads.length === 1 ? "" : "s"}${data.truncated ? " (truncated at the page cap)" : ""}`,
82569
82575
  ...data.threads.map((thread) => `${thread.id} ${thread.path ? `${thread.path}${thread.line ? `:${thread.line}` : ""} ` : ""}@${thread.author ?? "?"}${thread.isBot ? " (bot)" : ""}${thread.outdated ? " (outdated)" : ""}: ${thread.body}`)
82570
82576
  ]);
@@ -82605,7 +82611,7 @@ async function reply(argv, io) {
82605
82611
  if (!result.ok)
82606
82612
  return result.code === "invalid_input" ? usage3(io, result.error, REPLY_USAGE) : forgeFail(io, result);
82607
82613
  const kind = connected.data.forge.kind;
82608
- return emit(io, ok(result.data), (data) => [
82614
+ return emit(io, ok2(result.data), (data) => [
82609
82615
  `${[data.replied ? "replied to" : null, data.resolved ? "resolved" : null].filter(Boolean).join(" and ")} thread ${data.thread} on ${prLabel(kind, data.number)}${data.replyUrl ? ` ${data.replyUrl}` : ""}`
82610
82616
  ]);
82611
82617
  }
@@ -82717,7 +82723,7 @@ async function wait2(argv, io) {
82717
82723
  }
82718
82724
  const elapsedMs = forgeDeps.now() - started;
82719
82725
  if (!status)
82720
- return emit(io, fail("unavailable", "no successful poll before the timeout", { data: { polls } }));
82726
+ return emit(io, fail2("unavailable", "no successful poll before the timeout", { data: { polls } }));
82721
82727
  const left = deadline - forgeDeps.now();
82722
82728
  const built = buildStatusDoc(io.cwd, resolved, status, {
82723
82729
  logLines: verdict.state === "failed" && left > 0 ? 60 : 0,
@@ -82741,18 +82747,18 @@ async function wait2(argv, io) {
82741
82747
  io.stdout(`${value}
82742
82748
  `);
82743
82749
  if (verdict.state === "ready")
82744
- return emit(io, ok(data), () => [
82750
+ return emit(io, ok2(data), () => [
82745
82751
  `CI ready (${verdict.reason}) after ${polls} poll${polls === 1 ? "" : "s"}, ${seconds(elapsedMs)}`,
82746
82752
  ...renderStatus(doc)
82747
82753
  ]);
82748
82754
  if (verdict.state === "failed")
82749
- return emit(io, fail("failed", `CI failed: ${doc.checks.failing.map((check) => check.name).join(", ")}`, {
82755
+ return emit(io, fail2("failed", `CI failed: ${doc.checks.failing.map((check) => check.name).join(", ")}`, {
82750
82756
  data,
82751
82757
  unblock: "fix the failure, or if it is a flake: workit ci rerun --failed --reason flake"
82752
82758
  }));
82753
82759
  if (verdict.state === "blocked")
82754
- return emit(io, fail("blocked", `CI wait blocked: ${verdict.reason}`, { data, unblock: verdict.unblock }));
82755
- return emit(io, fail("pending", `CI still ${verdict.reason.replaceAll("_", " ")} after ${seconds(elapsedMs)}`, {
82760
+ return emit(io, fail2("blocked", `CI wait blocked: ${verdict.reason}`, { data, unblock: verdict.unblock }));
82761
+ return emit(io, fail2("pending", `CI still ${verdict.reason.replaceAll("_", " ")} after ${seconds(elapsedMs)}`, {
82756
82762
  data,
82757
82763
  unblock: `workit ci wait --pr ${doc.number}${head ? ` --head ${head}` : ""}`
82758
82764
  }));
@@ -82786,12 +82792,12 @@ async function rerun(argv, io) {
82786
82792
  return forgeFail(io, connected);
82787
82793
  const resolved = connected.data;
82788
82794
  if (resolved.expectedAccount && resolved.identity.login === null)
82789
- return emit(io, fail("blocked", `identity_unverified: the credential cannot prove it is ${resolved.expectedAccount} (${resolved.identity.note ?? "no /user access"})`, {
82795
+ return emit(io, fail2("blocked", `identity_unverified: the credential cannot prove it is ${resolved.expectedAccount} (${resolved.identity.note ?? "no /user access"})`, {
82790
82796
  unblock: `use a credential for ${resolved.expectedAccount} that can read /user (vcs.tokenFile or ${resolved.forge.kind === "github" ? "gh" : "glab"} auth login --hostname ${resolved.forge.apiHost})`
82791
82797
  }));
82792
82798
  const grant = requireGrant(io.cwd, "rerun");
82793
82799
  if (!grant.allowed)
82794
- return emit(io, fail("blocked", grant.error, { unblock: grant.unblock, data: { reason: grant.reason } }));
82800
+ return emit(io, fail2("blocked", grant.error, { unblock: grant.unblock, data: { reason: grant.reason } }));
82795
82801
  const number = selectPr(io.cwd, resolved, { pr, branch: flags.values.branch ?? null });
82796
82802
  if (!number.ok)
82797
82803
  return forgeFail(io, number);
@@ -82807,7 +82813,7 @@ async function rerun(argv, io) {
82807
82813
  if (!done.ok)
82808
82814
  return forgeFail(io, done);
82809
82815
  const outcome = done.data;
82810
- return emit(io, ok(outcome), () => [
82816
+ return emit(io, ok2(outcome), () => [
82811
82817
  `rerun requested on #${outcome.pr} head ${outcome.head.slice(0, 7)} (${outcome.reason}${outcome.forced ? ", forced" : ""}): ${outcome.rerun.map((check) => check.name).join(", ")}`,
82812
82818
  ...outcome.skipped.length ? [`not rerunnable here: ${outcome.skipped.join(", ")}`] : [],
82813
82819
  ...outcome.recorded ? [] : ["warning: the rerun could not be recorded; the once-per-head guard will not see it"],
@@ -82906,7 +82912,7 @@ async function branch(argv, io) {
82906
82912
  });
82907
82913
  if (!result.ok)
82908
82914
  return forgeFail(io, result);
82909
- return emit(io, ok(result.data), (data) => [
82915
+ return emit(io, ok2(result.data), (data) => [
82910
82916
  `switched to new branch ${data.branch} from ${data.baseRef} (${short2(data.baseSha)})${data.carried ? ", carrying uncommitted changes" : ""}`,
82911
82917
  ...data.releaseTrack?.name ? [`release track: ${data.releaseTrack.name} (${data.releaseTrack.detail})`] : [],
82912
82918
  ...data.notes.map((note) => `note: ${note}`)
@@ -83007,7 +83013,7 @@ async function commit(argv, io) {
83007
83013
  if (!result.ok)
83008
83014
  return forgeFail(io, result);
83009
83015
  await ensureImplicitTask(io);
83010
- return emit(io, ok(result.data), (data) => [
83016
+ return emit(io, ok2(result.data), (data) => [
83011
83017
  `${data.branch} ${short2(data.sha)} ${data.message.split(`
83012
83018
  `, 1)[0]} (${data.files.length ? `${data.files.length} file${data.files.length === 1 ? "" : "s"}` : "empty commit"})${data.amended ? `, amends ${short2(data.amended)}` : ""}`,
83013
83019
  ...data.leftDirty ? [`${data.leftDirty} change(s) left uncommitted`] : [],
@@ -83051,7 +83057,7 @@ async function push(argv, io) {
83051
83057
  const checked = identity?.data ?? null;
83052
83058
  const grant = requireGrant(io.cwd, "push", { forge: checked?.forge != null });
83053
83059
  if (!grant.allowed)
83054
- return emit(io, fail("blocked", grant.error, {
83060
+ return emit(io, fail2("blocked", grant.error, {
83055
83061
  unblock: grant.unblock,
83056
83062
  data: { reason: grant.reason }
83057
83063
  }));
@@ -83074,7 +83080,7 @@ async function push(argv, io) {
83074
83080
  for (const warning of warnings)
83075
83081
  io.stderr(`warning: ${warning}
83076
83082
  `);
83077
- const envelope = ok({ ...result.data, identity: checked });
83083
+ const envelope = ok2({ ...result.data, identity: checked });
83078
83084
  return emit(io, warnings.length ? { ...envelope, warnings } : envelope, (data) => [
83079
83085
  data.pushed ? `pushed ${data.branch} ${short2(data.previous)} -> ${short2(data.sha)} to ${data.remote}${data.forced ? " (force-with-lease)" : ""}; remote tip verified` : `${data.remote}/${data.branch} is already at ${short2(data.sha)}; remote tip verified`,
83080
83086
  ...data.upstream ? [`upstream: ${data.remote}/${data.branch}`] : []
@@ -83086,7 +83092,7 @@ async function releasePush(names, io) {
83086
83092
  return forgeFail(io, plan);
83087
83093
  const release = requireGrant(io.cwd, "release");
83088
83094
  if (!release.allowed)
83089
- return emit(io, fail("blocked", release.error, {
83095
+ return emit(io, fail2("blocked", release.error, {
83090
83096
  unblock: release.unblock,
83091
83097
  data: { reason: release.reason }
83092
83098
  }));
@@ -83097,7 +83103,7 @@ async function releasePush(names, io) {
83097
83103
  const checked = identity?.data ?? null;
83098
83104
  const pushGrant = requireGrant(io.cwd, "push", { forge: checked?.forge != null });
83099
83105
  if (!pushGrant.allowed)
83100
- return emit(io, fail("blocked", pushGrant.error, {
83106
+ return emit(io, fail2("blocked", pushGrant.error, {
83101
83107
  unblock: pushGrant.unblock,
83102
83108
  data: { reason: pushGrant.reason }
83103
83109
  }));
@@ -83108,7 +83114,7 @@ async function releasePush(names, io) {
83108
83114
  });
83109
83115
  if (!result.ok)
83110
83116
  return forgeFail(io, result);
83111
- return emit(io, ok({ ...result.data, identity: checked }), (data) => [
83117
+ return emit(io, ok2({ ...result.data, identity: checked }), (data) => [
83112
83118
  ...data.refs.map((ref) => ref.pushed ? `pushed ${ref.name} ${short2(ref.previous)} -> ${short2(ref.sha)} to ${data.remote}; remote tip verified` : `${data.remote} ${ref.name} is already at ${short2(ref.sha)}; remote tip verified`),
83113
83119
  ..."error" in data.recorded ? [`ledger: not recorded (${data.recorded.error})`] : []
83114
83120
  ]);
@@ -83118,7 +83124,7 @@ function trailers(argv, io) {
83118
83124
  if (extra !== undefined)
83119
83125
  return usage3(io, `unexpected argument ${extra}`, "workit git trailers");
83120
83126
  const state = workspaceTrailers(io.cwd);
83121
- return emit(io, ok(state), (data) => data.enabled ? "on" : "off");
83127
+ return emit(io, ok2(state), (data) => data.enabled ? "on" : "off");
83122
83128
  }
83123
83129
  async function run14(argv, io) {
83124
83130
  const [sub, ...rest] = argv;
@@ -83828,7 +83834,7 @@ async function subVerb(load, argv, io) {
83828
83834
  try {
83829
83835
  return JSON.parse(out);
83830
83836
  } catch {
83831
- return fail("failed", (out + err).trim() || `${argv.join(" ")} printed nothing`);
83837
+ return fail2("failed", (out + err).trim() || `${argv.join(" ")} printed nothing`);
83832
83838
  }
83833
83839
  }
83834
83840
  async function start(argv, io) {
@@ -83845,7 +83851,7 @@ async function start(argv, io) {
83845
83851
  });
83846
83852
  if (!result.ok)
83847
83853
  return forgeFail(io, result);
83848
- return emit(io, ok(result.data), (data) => [
83854
+ return emit(io, ok2(result.data), (data) => [
83849
83855
  `started ${data.branch} from ${data.base} (${short4(data.baseSha)}), local only; it will be tagged ${data.tag}`,
83850
83856
  `next: commit the version bump, changelog and docs on ${data.branch} (workit git commit), then: workit release finish`,
83851
83857
  ...data.notes.map((note) => `note: ${note}`)
@@ -83854,7 +83860,7 @@ async function start(argv, io) {
83854
83860
  async function releasePr(io, plan, dryRun) {
83855
83861
  const title = `chore(release): ${plan.version}`;
83856
83862
  if (dryRun)
83857
- return emit(io, ok({
83863
+ return emit(io, ok2({
83858
83864
  ...plan,
83859
83865
  steps: [`push ${plan.branch}`, `open a PR ${plan.branch} -> ${plan.production}: ${title}`]
83860
83866
  }), () => [
@@ -83881,7 +83887,7 @@ async function releasePr(io, plan, dryRun) {
83881
83887
  branch: plan.branch,
83882
83888
  pr: pr.data.number ?? null
83883
83889
  });
83884
- return emit(io, ok({ ...plan, pr: pr.data }), () => [
83890
+ return emit(io, ok2({ ...plan, pr: pr.data }), () => [
83885
83891
  `opened the release PR ${String(pr.data.url ?? "")} into ${plan.production}`,
83886
83892
  `next: once it merges, tag the merged commit ${plan.tag} and: workit git push --release ${plan.tag}`
83887
83893
  ]);
@@ -83902,7 +83908,7 @@ async function finish2(argv, io) {
83902
83908
  const plan = planned.data;
83903
83909
  if (!plan.gitflow) {
83904
83910
  if (!dryRun && plan.state.branchDeleted)
83905
- return emit(io, fail("not_found", `${plan.branch} is gone; nothing to open a PR from`));
83911
+ return emit(io, fail2("not_found", `${plan.branch} is gone; nothing to open a PR from`));
83906
83912
  return releasePr(io, plan, dryRun);
83907
83913
  }
83908
83914
  const actor = actorFromEnv(io.env);
@@ -83918,8 +83924,8 @@ async function finish2(argv, io) {
83918
83924
  const missing = [release, push].find((grant) => !grant.allowed);
83919
83925
  const data = { ...plan, steps, grants: { release: release.allowed, push: push.allowed } };
83920
83926
  if (missing && !missing.allowed)
83921
- return emit(io, warned(fail("blocked", missing.error, { unblock: missing.unblock, data })));
83922
- return emit(io, warned(ok(data)), () => [
83927
+ return emit(io, warned(fail2("blocked", missing.error, { unblock: missing.unblock, data })));
83928
+ return emit(io, warned(ok2(data)), () => [
83923
83929
  `finish ${plan.branch} -> ${plan.production} as ${plan.tag}:`,
83924
83930
  ...steps.map((entry) => ` ${entry.done ? "done" : "todo"} ${entry.step}`)
83925
83931
  ]);
@@ -83980,7 +83986,7 @@ async function finish2(argv, io) {
83980
83986
  if (!verified.ok)
83981
83987
  return forgeFail(io, verified, { step: "verify", resume });
83982
83988
  if (!verified.data.delivered)
83983
- return emit(io, fail("failed", `release_unverified: ${plan.tag} is not on ${plan.remote ?? "the remote"}`, {
83989
+ return emit(io, fail2("failed", `release_unverified: ${plan.tag} is not on ${plan.remote ?? "the remote"}`, {
83984
83990
  data: { step: "verify", resume, report: verified.data },
83985
83991
  unblock: resume
83986
83992
  }));
@@ -83989,7 +83995,7 @@ async function finish2(argv, io) {
83989
83995
  branch: plan.branch,
83990
83996
  head: merged.data.tagTarget
83991
83997
  });
83992
- return emit(io, warned(ok({ ...plan, ran: merged.data.ran, push: pushed.data, forgeRelease, notes })), () => [
83998
+ return emit(io, warned(ok2({ ...plan, ran: merged.data.ran, push: pushed.data, forgeRelease, notes })), () => [
83993
83999
  `finished ${plan.branch}: ${plan.production} and ${plan.mergeBack.join(", ")} merged, ${plan.tag} tagged on ${short4(merged.data.tagTarget)}`,
83994
84000
  `pushed ${[...plan.pushBranches, plan.tag].join(", ")} to ${plan.remote ?? "the remote"}; remote tips verified`,
83995
84001
  ...forgeRelease ? [
@@ -84032,7 +84038,7 @@ async function publish(argv, io) {
84032
84038
  branch: located.data.branch,
84033
84039
  head: result.data.sha
84034
84040
  });
84035
- return emit(io, ok({ ...result.data, version: located.data.version }), (data) => [
84041
+ return emit(io, ok2({ ...result.data, version: located.data.version }), (data) => [
84036
84042
  `published ${data.branch} (${short4(data.sha)}) to ${data.remote}; remote tip verified`
84037
84043
  ]);
84038
84044
  }
@@ -84046,7 +84052,7 @@ async function run15(argv, io) {
84046
84052
  return publish(rest, io);
84047
84053
  return usage3(io, sub && !sub.startsWith("-") ? `unknown release subcommand "${sub}"` : "missing release subcommand", USAGE7);
84048
84054
  }
84049
- var START_USAGE = "workit release start <version> [--hotfix] [--track <t>] [--json]", FINISH_USAGE = "workit release finish [<version>] [--track <t>] [--dry-run] [--json]", PUBLISH_USAGE = "workit release publish [<version>] [--json]", USAGE7 = "workit release start|finish|publish ... (workit help release)", short4 = (sha) => sha ? sha.slice(0, 12) : "(none)", blocked = (io, grant) => emit(io, fail("blocked", grant.error, { unblock: grant.unblock, data: { reason: grant.reason } })), isLocalRemote = (cwd, remote) => {
84055
+ var START_USAGE = "workit release start <version> [--hotfix] [--track <t>] [--json]", FINISH_USAGE = "workit release finish [<version>] [--track <t>] [--dry-run] [--json]", PUBLISH_USAGE = "workit release publish [<version>] [--json]", USAGE7 = "workit release start|finish|publish ... (workit help release)", short4 = (sha) => sha ? sha.slice(0, 12) : "(none)", blocked = (io, grant) => emit(io, fail2("blocked", grant.error, { unblock: grant.unblock, data: { reason: grant.reason } })), isLocalRemote = (cwd, remote) => {
84050
84056
  const url = remote ? pushUrl(cwd, remote) : null;
84051
84057
  return !url || parseRemoteUrl(url)?.protocol === "file";
84052
84058
  }, stepsOf = (plan) => [
@@ -84128,13 +84134,13 @@ async function run16(argv, io) {
84128
84134
  return forgeFail(io, result);
84129
84135
  const report = result.data;
84130
84136
  if (report.delivered)
84131
- return emit(io, ok(report), render2);
84137
+ return emit(io, ok2(report), render2);
84132
84138
  const failed = report.observations.filter((entry) => !entry.ok);
84133
84139
  if (!io.json)
84134
84140
  for (const line of render2(report))
84135
84141
  io.stdout(`${line}
84136
84142
  `);
84137
- return emit(io, fail("failed", `not_delivered: ${failed.map((entry) => entry.note ?? `${entry.kind} is ${entry.observed ?? "absent"}, expected ${entry.expected ?? "-"}`).join("; ")}`, {
84143
+ return emit(io, fail2("failed", `not_delivered: ${failed.map((entry) => entry.note ?? `${entry.kind} is ${entry.observed ?? "absent"}, expected ${entry.expected ?? "-"}`).join("; ")}`, {
84138
84144
  data: report,
84139
84145
  unblock: expect === "pushed" ? "workit git push" : expect === "pr" ? "workit git push && workit pr create --fill" : expect === "merged" ? "workit pr status # then workit pr merge when READY and granted" : "check the release workflow; the tag/package is not published"
84140
84146
  }));
@@ -84185,11 +84191,11 @@ async function plan(argv, io) {
84185
84191
  if (trunk === null || track !== null) {
84186
84192
  const derived = releaseTrunk(io, track, flags.positionals[0] ?? null);
84187
84193
  if ("error" in derived)
84188
- return emit(io, fail("blocked", derived.error, {
84194
+ return emit(io, fail2("blocked", derived.error, {
84189
84195
  unblock: "workit stack plan --track <name> … # or --trunk <branch>"
84190
84196
  }));
84191
84197
  if (existing && track !== null && derived.trunk !== existing.trunk)
84192
- return emit(io, fail("invalid_input", `stack ${existing.name} is on trunk ${existing.trunk}; --track ${track} targets ${derived.trunk ?? "(none)"}`, { unblock: "drop --track to re-plan on the recorded trunk" }));
84198
+ return emit(io, fail2("invalid_input", `stack ${existing.name} is on trunk ${existing.trunk}; --track ${track} targets ${derived.trunk ?? "(none)"}`, { unblock: "drop --track to re-plan on the recorded trunk" }));
84193
84199
  trunk ??= derived.trunk ?? "main";
84194
84200
  }
84195
84201
  const connected = connect(io, flags.positionals[0] ?? null);
@@ -84205,7 +84211,7 @@ async function plan(argv, io) {
84205
84211
  });
84206
84212
  if (!result.ok)
84207
84213
  return stackFailed(io, result);
84208
- return emit(io, ok(result.data), (data) => [
84214
+ return emit(io, ok2(result.data), (data) => [
84209
84215
  `${data.created ? "planned" : "re-planned"} stack ${data.stack.name} on ${data.stack.trunk}:`,
84210
84216
  ...data.stack.branches.map((entry, index) => {
84211
84217
  const check = data.checks.find((item) => item.branch === entry.branch);
@@ -84229,7 +84235,7 @@ async function status3(argv, io) {
84229
84235
  const result = stackStatus({ cwd: io.cwd, resolved: connected.data, actor: actorFromEnv(io.env), sleep: forgeDeps.sleep }, selected.data);
84230
84236
  if (!result.ok)
84231
84237
  return stackFailed(io, result);
84232
- return emit(io, ok(result.data), (data) => [
84238
+ return emit(io, ok2(result.data), (data) => [
84233
84239
  `stack ${data.name} on ${data.trunk}: ${data.verdict}${data.reason ? ` (${data.reason})` : ""}`,
84234
84240
  ...data.branches.map((row, index) => ` ${index + 1}. ${row.branch} ${label3(connected.data.forge.kind, row.pr)} ${row.merged ? "merged" : `${row.next ?? "?"} · checks ${row.checks ?? "?"} · verdict ${row.verdict.accepted ? `accepted (${row.verdict.basis})` : `missing (${row.verdict.reasons.join(", ") || row.verdict.basis})`} · ${row.onParent === false ? `not on ${row.parent}` : `on ${row.parent}`}${row.baseMatches === false ? ` · PR base ${row.prBase}` : ""}`}`),
84235
84241
  ...data.next ? [`next: ${data.next}`] : []
@@ -84279,7 +84285,7 @@ async function sync(argv, io) {
84279
84285
  });
84280
84286
  if (!result.ok)
84281
84287
  return stackFailed(io, result);
84282
- return emit(io, ok(result.data), renderSync);
84288
+ return emit(io, ok2(result.data), renderSync);
84283
84289
  }
84284
84290
  async function land(argv, io) {
84285
84291
  const flags = parseFlags(argv, {
@@ -84332,7 +84338,7 @@ async function land(argv, io) {
84332
84338
  if (!result.ok)
84333
84339
  return stackFailed(io, result);
84334
84340
  const kind = connected.data.forge.kind;
84335
- return emit(io, ok(result.data), (data) => [
84341
+ return emit(io, ok2(result.data), (data) => [
84336
84342
  ...data.dryRun ? [
84337
84343
  data.wouldLand.length ? `would land: ${data.wouldLand.map((item) => `${label3(kind, item.pr)} (${item.branch})`).join(", ")}` : "would land nothing"
84338
84344
  ] : [
@@ -84356,7 +84362,7 @@ async function run17(argv, io) {
84356
84362
  return land(rest, io);
84357
84363
  return usage3(io, sub && !sub.startsWith("-") ? `unknown stack subcommand "${sub}"` : "missing stack subcommand", USAGE9);
84358
84364
  }
84359
- var PLAN_USAGE = "workit stack plan [--name <n>] [--trunk <b> | --track <t>] [<bottom> … <top>] [--json]", STATUS_USAGE2 = "workit stack status [--name <n>] [--json]", SYNC_USAGE = "workit stack sync [--name <n>] [--local] [--dry-run] [--force <branch>]… [--json]", LAND_USAGE = "workit stack land [--name <n>] [--dry-run] [--max <n>] [--method squash|merge|rebase] [--unverified --reason <why>] [--timeout 20m] [--interval 30s] [--json]", USAGE9 = "workit stack plan|status|sync|land ... (workit help stack)", short5 = (sha) => sha ? sha.slice(0, 12) : "?", stackFailed = (io, result) => emit(io, fail(result.code, result.error, { unblock: result.unblock, data: result.data ?? {} })), label3 = (forge, pr) => pr === null ? "no PR" : `${forge === "gitlab" ? "MR !" : "PR #"}${pr}`, renderSync = (data) => [
84365
+ var PLAN_USAGE = "workit stack plan [--name <n>] [--trunk <b> | --track <t>] [<bottom> … <top>] [--json]", STATUS_USAGE2 = "workit stack status [--name <n>] [--json]", SYNC_USAGE = "workit stack sync [--name <n>] [--local] [--dry-run] [--force <branch>]… [--json]", LAND_USAGE = "workit stack land [--name <n>] [--dry-run] [--max <n>] [--method squash|merge|rebase] [--unverified --reason <why>] [--timeout 20m] [--interval 30s] [--json]", USAGE9 = "workit stack plan|status|sync|land ... (workit help stack)", short5 = (sha) => sha ? sha.slice(0, 12) : "?", stackFailed = (io, result) => emit(io, fail2(result.code, result.error, { unblock: result.unblock, data: result.data ?? {} })), label3 = (forge, pr) => pr === null ? "no PR" : `${forge === "gitlab" ? "MR !" : "PR #"}${pr}`, renderSync = (data) => [
84360
84366
  `${data.dryRun ? "would sync" : "synced"} stack ${data.name}${data.merged.length ? `; merged: ${data.merged.map((item) => item.branch).join(", ")}` : ""}`,
84361
84367
  ...data.steps.map((step) => [
84362
84368
  ` ${step.branch} on ${step.parent}:`,
@@ -85597,7 +85603,7 @@ function resolveTrunk(io, raw, flag, track) {
85597
85603
  const derived = releaseTrunk(io, track, null);
85598
85604
  if ("error" in derived)
85599
85605
  return {
85600
- code: emit(io, fail("blocked", derived.error, {
85606
+ code: emit(io, fail2("blocked", derived.error, {
85601
85607
  unblock: "workit fanout plan <plan.json> --track <name> # or --trunk <branch>"
85602
85608
  }))
85603
85609
  };
@@ -85643,7 +85649,7 @@ function plan2(argv, io) {
85643
85649
  renderBlockedPlan(io, result);
85644
85650
  return code;
85645
85651
  }
85646
- return emit(io, ok(result.data), (data) => [
85652
+ return emit(io, ok2(result.data), (data) => [
85647
85653
  `${data.created ? "planned" : "re-planned"} fanout ${data.name} on ${data.trunk}${data.fanIn === "integration" ? " (integration branch: one PR)" : ""}: ${data.slices.length} slice${data.slices.length === 1 ? "" : "s"}`,
85648
85654
  ...data.slices.map((slice) => ` ${slice.id} [${slice.tier}] ${slice.branch} <- ${slice.base}${slice.dependsOn.length ? ` after ${slice.dependsOn.join(", ")}` : ""}
85649
85655
  worktree ${slice.worktree}`),
@@ -85678,7 +85684,7 @@ function brief(argv, io) {
85678
85684
  });
85679
85685
  if (!result.ok)
85680
85686
  return failed(io, result);
85681
- return emit(io, ok(result.data), (data) => data.text.trimEnd());
85687
+ return emit(io, ok2(result.data), (data) => data.text.trimEnd());
85682
85688
  }
85683
85689
  function check2(argv, io) {
85684
85690
  const flags = parseFlags(argv, { name: "value", base: "value", offline: "boolean" });
@@ -85695,13 +85701,13 @@ function check2(argv, io) {
85695
85701
  if (!result.ok)
85696
85702
  return failed(io, result);
85697
85703
  if (result.data.ready)
85698
- return emit(io, ok(result.data), renderCheck);
85704
+ return emit(io, ok2(result.data), renderCheck);
85699
85705
  if (!io.json)
85700
85706
  for (const line of renderCheck(result.data))
85701
85707
  io.stdout(`${line}
85702
85708
  `);
85703
85709
  const first = result.data.slices.find((slice) => slice.status === "blocked");
85704
- return emit(io, fail("blocked", `slice ${first?.id ?? "?"} is not ready: ${first?.reasons[0] ?? "blocked"}`, {
85710
+ return emit(io, fail2("blocked", `slice ${first?.id ?? "?"} is not ready: ${first?.reasons[0] ?? "blocked"}`, {
85705
85711
  data: result.data,
85706
85712
  unblock: result.data.next
85707
85713
  }));
@@ -85727,7 +85733,7 @@ function status4(argv, io) {
85727
85733
  });
85728
85734
  if (!result.ok)
85729
85735
  return failed(io, result);
85730
- return emit(io, ok(result.data), renderStatus2);
85736
+ return emit(io, ok2(result.data), renderStatus2);
85731
85737
  }
85732
85738
  function worktree(argv, io) {
85733
85739
  const [action, ...rest] = argv;
@@ -85751,7 +85757,7 @@ function worktree(argv, io) {
85751
85757
  });
85752
85758
  if (!result.ok)
85753
85759
  return failed(io, result);
85754
- return emit(io, ok(result.data), (data) => [
85760
+ return emit(io, ok2(result.data), (data) => [
85755
85761
  `${data.created ? "created" : "kept"} worktree for slice ${data.slice} (${data.mode}): ${data.path}`,
85756
85762
  ` branch ${data.branch} <- ${data.base} at ${short6(data.head)}`,
85757
85763
  ` scratch ${data.scratch} (put it in the worker brief: temp files go here)`,
@@ -85772,7 +85778,7 @@ function worktree(argv, io) {
85772
85778
  `);
85773
85779
  return code;
85774
85780
  }
85775
- return emit(io, ok(result.data), (data) => [
85781
+ return emit(io, ok2(result.data), (data) => [
85776
85782
  data.removed ? `released slice ${data.slice}: removed ${data.path}${data.dirty.length ? ` (dropped ${data.dirty.length} uncommitted change${data.dirty.length === 1 ? "" : "s"}, recorded in the ledger)` : ""}; branch ${data.branch} kept` : `slice ${data.slice}: nothing released`,
85777
85783
  ...data.notes.map((note) => `note: ${note}`)
85778
85784
  ]);
@@ -85791,7 +85797,7 @@ async function run18(argv, io) {
85791
85797
  return worktree(rest, io);
85792
85798
  return usage3(io, sub && !sub.startsWith("-") ? `unknown fanout subcommand "${sub}"` : "missing fanout subcommand", USAGE10);
85793
85799
  }
85794
- var PLAN_USAGE2 = "workit fanout plan <plan.json> [--name <n>] [--trunk <b> | --track <t>] [--take-lead] [--json]", BRIEF_USAGE = "workit fanout brief <slice> [--name <n>] [--mode new|resume] [--attempt <n>] [--json]", CHECK_USAGE = "workit fanout check [<slice>…] [--name <n>] [--base <ref>] [--offline] [--json]", STATUS_USAGE3 = "workit fanout status [--name <n>] [--stuck-after 30m] [--offline] [--json]", WORKTREE_USAGE = "workit fanout worktree create <slice> [--name <n>] | worktree release <slice> [--name <n>] [--force] [--json]", USAGE10 = "workit fanout plan|brief|check|status|worktree ... (workit help fanout)", failed = (io, result) => emit(io, fail(result.code, result.error, { unblock: result.unblock, data: result.data ?? {} })), renderCheck = (data) => [
85800
+ var PLAN_USAGE2 = "workit fanout plan <plan.json> [--name <n>] [--trunk <b> | --track <t>] [--take-lead] [--json]", BRIEF_USAGE = "workit fanout brief <slice> [--name <n>] [--mode new|resume] [--attempt <n>] [--json]", CHECK_USAGE = "workit fanout check [<slice>…] [--name <n>] [--base <ref>] [--offline] [--json]", STATUS_USAGE3 = "workit fanout status [--name <n>] [--stuck-after 30m] [--offline] [--json]", WORKTREE_USAGE = "workit fanout worktree create <slice> [--name <n>] | worktree release <slice> [--name <n>] [--force] [--json]", USAGE10 = "workit fanout plan|brief|check|status|worktree ... (workit help fanout)", failed = (io, result) => emit(io, fail2(result.code, result.error, { unblock: result.unblock, data: result.data ?? {} })), renderCheck = (data) => [
85795
85801
  `fanout ${data.name} against ${data.trunkRef}: ${data.ready ? "ready to land" : "blocked"}`,
85796
85802
  ...data.slices.map((slice) => slice.status === "landed" ? ` -- ${slice.id} (${slice.branch}) landed (${slice.landed?.how}${slice.landed?.pr ? ` #${slice.landed.pr}` : ""})` : ` ${slice.status === "ready" ? "ok " : "x "}${slice.id} (${slice.branch}) ${slice.changed} file${slice.changed === 1 ? "" : "s"} · verdict ${slice.verdict.accepted ? "accepted" : slice.verdict.basis}${slice.reasons.length ? `
85797
85803
  ${slice.reasons.join(`
@@ -85914,7 +85920,7 @@ async function run19(argv, io) {
85914
85920
  if (rest.length)
85915
85921
  return usage4(io, `unexpected argument: ${rest[0]}`);
85916
85922
  const integrity = ledger.value.integrity ?? { chained: 0, legacy: 0, unverified: [] };
85917
- return emit(io, ok({
85923
+ return emit(io, ok2({
85918
85924
  path: ledger.value.path,
85919
85925
  intact: integrity.unverified.length === 0,
85920
85926
  chained: integrity.chained,
@@ -85931,7 +85937,7 @@ async function run19(argv, io) {
85931
85937
  type: values.type,
85932
85938
  last: last ?? 50
85933
85939
  });
85934
- return emit(io, ok({ path: ledger.value.path, skipped: ledger.value.skipped, rows: listed }), (data) => data.rows.length ? data.rows.map((row) => {
85940
+ return emit(io, ok2({ path: ledger.value.path, skipped: ledger.value.skipped, rows: listed }), (data) => data.rows.length ? data.rows.map((row) => {
85935
85941
  const line = summarizeRow(row);
85936
85942
  return `#${line.seq} ${line.at} ${line.type}${line.branch ? ` [${line.branch}]` : ""}${line.labels.length ? ` (${line.labels.join(", ")})` : ""} ${line.summary}`;
85937
85943
  }) : "ledger is empty");
@@ -85945,14 +85951,22 @@ async function run19(argv, io) {
85945
85951
  return failed2(io, target);
85946
85952
  const branch = target.value ?? currentBranch(io.cwd);
85947
85953
  if (!branch)
85948
- return emit(io, fail("invalid_input", "HEAD is detached; name the branch", {
85954
+ return emit(io, fail2("invalid_input", "HEAD is detached; name the branch", {
85949
85955
  unblock: "pass --branch <branch>"
85950
85956
  }));
85951
- return emit(io, ok(checkVerdicts(io.cwd, branch, rows)), verdictLines);
85957
+ return emit(io, ok2(checkVerdicts(io.cwd, branch, rows)), verdictLines);
85952
85958
  }
85953
85959
  const target = targetBranch(io, rows, values.branch, pr);
85954
85960
  if (!target.ok)
85955
85961
  return failed2(io, target);
85962
+ if (values.head !== undefined) {
85963
+ const actual = target.value === null ? headSha(io.cwd) : resolveRef(io.cwd, target.value);
85964
+ const wanted = values.head.trim().toLowerCase();
85965
+ if (!actual || wanted.length < 4 || !actual.startsWith(wanted))
85966
+ return emit(io, fail2("invalid_input", `--head ${values.head} is not the head of ${target.value ?? "this checkout"}${actual ? ` (${actual.slice(0, 12)})` : ""}`, {
85967
+ unblock: "a verdict is keyed to the branch head: check out the commit to judge (or pass --branch/--pr), or drop --head"
85968
+ }));
85969
+ }
85956
85970
  const acting = actorFor(io, values);
85957
85971
  if (acting instanceof Error)
85958
85972
  return usage4(io, acting.message);
@@ -85992,7 +86006,7 @@ async function run19(argv, io) {
85992
86006
  const token = values.token ?? io.env.WORKIT_SESSION_TOKEN ?? null;
85993
86007
  const refusal = claimed === null ? null : sessionClaimRefusal(io.env, claimed, io.cwd, { token, flag: acting.source === "flag" });
85994
86008
  if (refusal)
85995
- return emit(io, fail("blocked", refusal.error, { unblock: refusal.unblock }));
86009
+ return emit(io, fail2("blocked", refusal.error, { unblock: refusal.unblock }));
85996
86010
  const bound = claimed !== null && issuedTokenMatches(io.cwd, claimed, token);
85997
86011
  const verdict = await recorded(recordVerdict({ ...context, ...bound ? { sessionBound: true } : {} }, {
85998
86012
  result: rest[0],
@@ -86031,10 +86045,10 @@ function standingFanout(io, values) {
86031
86045
  async function standing(io, values, args) {
86032
86046
  const [action, ...rest] = args;
86033
86047
  if (action !== "add" && action !== "list" && action !== "clear")
86034
- return emit(io, fail("invalid_input", action ? `unknown standing action "${action}"` : "missing add, list or clear", { unblock: STANDING_USAGE }));
86048
+ return emit(io, fail2("invalid_input", action ? `unknown standing action "${action}"` : "missing add, list or clear", { unblock: STANDING_USAGE }));
86035
86049
  const target = standingFanout(io, values);
86036
86050
  if (target instanceof Error)
86037
- return emit(io, fail("invalid_input", target.message, { unblock: STANDING_USAGE }));
86051
+ return emit(io, fail2("invalid_input", target.message, { unblock: STANDING_USAGE }));
86038
86052
  const fanout = target.name;
86039
86053
  const lead = target.plan?.leadSession ?? null;
86040
86054
  const leads = target.plan ? planLeads(target.plan) : null;
@@ -86049,7 +86063,7 @@ async function standing(io, values, args) {
86049
86063
  at: row.at,
86050
86064
  what: row.what
86051
86065
  }));
86052
- return emit(io, ok({ fanout, orders }), (data) => data.orders.length ? [
86066
+ return emit(io, ok2({ fanout, orders }), (data) => data.orders.length ? [
86053
86067
  `standing orders for fanout ${fanout}:`,
86054
86068
  ...data.orders.map((o) => ` ${o.id} ${o.what}`)
86055
86069
  ] : `no standing orders for fanout ${fanout}`);
@@ -86063,7 +86077,7 @@ async function standing(io, values, args) {
86063
86077
  ...values.supersedes ? { supersedes: values.supersedes } : {}
86064
86078
  };
86065
86079
  if (action === "add" && target.plan === null)
86066
- return emit(io, fail("not_found", `no fanout plan named ${fanout}`, {
86080
+ return emit(io, fail2("not_found", `no fanout plan named ${fanout}`, {
86067
86081
  unblock: "workit fanout plan <plan.json> first, or name an existing plan with --fanout"
86068
86082
  }));
86069
86083
  if (action === "add")
@@ -86097,7 +86111,7 @@ var USAGE11 = "workit ledger decision|ruling|verdict|standing|list|check ... (wo
86097
86111
  return;
86098
86112
  const parsed = Number(value);
86099
86113
  return Number.isInteger(parsed) && parsed > 0 ? parsed : new Error(`${flag} must be a positive integer`);
86100
- }, failed2 = (io, result) => emit(io, fail(result.code, result.error, result.unblock ? { unblock: result.unblock } : {})), fromResult = (io, result, human) => result.ok ? emit(io, ok(result.value), human) : failed2(io, result), usage4 = (io, error) => emit(io, fail("invalid_input", error, { unblock: USAGE11 })), passedTestOn = (cwd, verdict) => {
86114
+ }, failed2 = (io, result) => emit(io, fail2(result.code, result.error, result.unblock ? { unblock: result.unblock } : {})), fromResult = (io, result, human) => result.ok ? emit(io, ok2(result.value), human) : failed2(io, result), usage4 = (io, error) => emit(io, fail2("invalid_input", error, { unblock: USAGE11 })), passedTestOn = (cwd, verdict) => {
86101
86115
  const ledger = readLedger(cwd);
86102
86116
  return ledger.ok && ledger.value.rows.some((row) => row.type === "check" && row.observer === "workit_cli" && row.name === "test" && row.result === "passed" && row.dirty !== true && row.branch === verdict.branch && row.head === verdict.head);
86103
86117
  }, verdictLines = (check) => {
@@ -86159,6 +86173,7 @@ var init_ledger2 = __esm(() => {
86159
86173
  evidence: { type: "string", multiple: true },
86160
86174
  self: { type: "boolean" },
86161
86175
  branch: { type: "string" },
86176
+ head: { type: "string" },
86162
86177
  base: { type: "string" },
86163
86178
  pr: { type: "string" },
86164
86179
  type: { type: "string" },
@@ -102735,7 +102750,7 @@ function human(data) {
102735
102750
  async function run20(argv, io) {
102736
102751
  const options = parse7(argv);
102737
102752
  if (typeof options === "string")
102738
- return emit(io, fail("invalid_input", `${options}
102753
+ return emit(io, fail2("invalid_input", `${options}
102739
102754
  usage: ${USAGE12}`));
102740
102755
  const top = git7(io.cwd, ["rev-parse", "--show-toplevel"]);
102741
102756
  const repo = top.ok ? path59.resolve(top.stdout.trim()) : null;
@@ -102744,12 +102759,12 @@ usage: ${USAGE12}`));
102744
102759
  let changed = null;
102745
102760
  if (options.diff || options.mutate) {
102746
102761
  if (!repo)
102747
- return emit(io, fail("unavailable", "--diff and --mutate need a git repository", {
102762
+ return emit(io, fail2("unavailable", "--diff and --mutate need a git repository", {
102748
102763
  unblock: "run inside a git work tree"
102749
102764
  }));
102750
102765
  base = resolveBase(io.cwd, options.base);
102751
102766
  if (!base)
102752
- return emit(io, fail("invalid_input", `cannot resolve a base to diff against${options.base ? `: ${options.base}` : ""}`, {
102767
+ return emit(io, fail2("invalid_input", `cannot resolve a base to diff against${options.base ? `: ${options.base}` : ""}`, {
102753
102768
  unblock: "workit test-audit --diff <base-branch-or-sha>"
102754
102769
  }));
102755
102770
  changed = changedLines(io.cwd, base);
@@ -102760,7 +102775,7 @@ usage: ${USAGE12}`));
102760
102775
  else {
102761
102776
  const expanded = expandPaths(io.cwd, options.paths);
102762
102777
  if (expanded.missing.length > 0)
102763
- return emit(io, fail("not_found", `no such path: ${expanded.missing.join(", ")}`));
102778
+ return emit(io, fail2("not_found", `no such path: ${expanded.missing.join(", ")}`));
102764
102779
  files = expanded.files;
102765
102780
  }
102766
102781
  const report = auditFiles(files, display);
@@ -102778,7 +102793,7 @@ usage: ${USAGE12}`));
102778
102793
  if (options.mutate && repo && base && changed) {
102779
102794
  const runner = testCommand(repo, io.cwd, options.testCmd);
102780
102795
  if (!runner)
102781
- return emit(io, fail("unavailable", "no test command for --mutate", {
102796
+ return emit(io, fail2("unavailable", "no test command for --mutate", {
102782
102797
  unblock: 'workit test-audit --mutate --test-cmd "<runner> {files}" (or configure a `test` check in .workit/checks.json)'
102783
102798
  }));
102784
102799
  try {
@@ -102797,7 +102812,7 @@ usage: ${USAGE12}`));
102797
102812
  });
102798
102813
  } catch (error) {
102799
102814
  if (error instanceof BaselineFailed)
102800
- return emit(io, fail("failed", error.message, {
102815
+ return emit(io, fail2("failed", error.message, {
102801
102816
  data: { command: error.command, tail: error.tail },
102802
102817
  unblock: "make the related tests pass before mutating"
102803
102818
  }));
@@ -102818,9 +102833,9 @@ usage: ${USAGE12}`));
102818
102833
  for (const line of human(data))
102819
102834
  io.stdout(`${line}
102820
102835
  `);
102821
- return emit(io, fail("failed", problems.join("; "), { data }));
102836
+ return emit(io, fail2("failed", problems.join("; "), { data }));
102822
102837
  }
102823
- return emit(io, ok(data), human);
102838
+ return emit(io, ok2(data), human);
102824
102839
  }
102825
102840
  var USAGE12 = "workit test-audit [paths…] [--diff [base]] [--rule <ids>] [--min-severity <level>] [--fail-on <level>] [--mutate [--test-cmd <cmd>] [--max-mutants <n>] [--budget <s>] [--timeout <s>]] [--json]", LEVELS, VALUE_FLAGS2, quote = (arg) => /^[\w./@:=+-]+$/.test(arg) ? arg : `'${arg.replace(/'/g, "'\\''")}'`;
102826
102841
  var init_test_audit = __esm(() => {
@@ -102848,16 +102863,16 @@ __export(exports_knowledge, {
102848
102863
  async function run21(argv, io) {
102849
102864
  const [sub, ...rest] = argv.filter((arg) => arg !== "--json");
102850
102865
  if (sub !== "lint" || rest.length > 0)
102851
- return emit(io, fail("invalid_input", `usage: ${USAGE13}`));
102866
+ return emit(io, fail2("invalid_input", `usage: ${USAGE13}`));
102852
102867
  const report = lintKnowledge(checkRoot(io.cwd));
102853
102868
  if (report.unreadable.length > 0)
102854
- return emit(io, fail("unavailable", `knowledge lint: cannot read ${report.unreadable.join(", ")}`, {
102869
+ return emit(io, fail2("unavailable", `knowledge lint: cannot read ${report.unreadable.join(", ")}`, {
102855
102870
  data: report,
102856
102871
  unblock: `make ${report.unreadable.join(", ")} readable, then re-run workit knowledge lint`
102857
102872
  }));
102858
102873
  const summary = `knowledge lint: ${report.findings.length} finding${report.findings.length === 1 ? "" : "s"} in ${report.files.length} file${report.files.length === 1 ? "" : "s"} (${report.files.map((file) => `${file.file} ${file.bytes} B`).join(", ") || "no knowledge files"}; AGENTS.md budget ${report.budget} B)`;
102859
102874
  if (io.json)
102860
- return emit(io, report.findings.length === 0 ? ok(report) : fail("failed", summary, { data: report }));
102875
+ return emit(io, report.findings.length === 0 ? ok2(report) : fail2("failed", summary, { data: report }));
102861
102876
  for (const finding of report.findings)
102862
102877
  io.stdout(`${finding.file}${finding.line === null ? "" : `:${finding.line}`} [${finding.rule}] ${finding.message}
102863
102878
  `);
@@ -102932,7 +102947,7 @@ async function run22(argv, io) {
102932
102947
  return usage3(io, "the note is empty", USAGE14);
102933
102948
  const missing = step("comment", "comments", { operation: "note", issueId, markdown }, markdown, async (text) => commentResult(await postComment(issueId, text, root))) ?? (minutes ? step("time", "workItems", { operation: "note.time", issueId, markdown, minutes, ...markedDay }, "workit update", (text) => logTimeUpdate({ issueId, minutes, text, dateMs, workspace_root: root })) : null);
102934
102949
  if (missing)
102935
- return emit(io, fail("unavailable", missing));
102950
+ return emit(io, fail2("unavailable", missing));
102936
102951
  } else {
102937
102952
  if (!minutes)
102938
102953
  return usage3(io, `${sub} needs --minutes <n>`, USAGE14);
@@ -102941,7 +102956,7 @@ async function run22(argv, io) {
102941
102956
  const text = flags.values.text ?? "";
102942
102957
  const missing = step(sub, "workItems", { operation: sub, issueId, minutes, text, ...markedDay }, text, (marked) => logTimeUpdate({ issueId, minutes, text: marked, dateMs, workspace_root: root }));
102943
102958
  if (missing)
102944
- return emit(io, fail("unavailable", missing));
102959
+ return emit(io, fail2("unavailable", missing));
102945
102960
  }
102946
102961
  const results = [];
102947
102962
  for (const entry of steps) {
@@ -102954,14 +102969,14 @@ async function run22(argv, io) {
102954
102969
  } : {}
102955
102970
  });
102956
102971
  if (outcome.status === "failed" || outcome.status === "unknown")
102957
- return emit(io, fail(outcome.status === "unknown" ? "unavailable" : "failed", outcome.error, {
102972
+ return emit(io, fail2(outcome.status === "unknown" ? "unavailable" : "failed", outcome.error, {
102958
102973
  data: { issueId, steps: results, ...outcome.data ? { detail: outcome.data } : {} },
102959
102974
  ...outcome.status === "unknown" ? {
102960
102975
  unblock: `check ${issueId} in YouTrack; re-running is safe (the marker skips a write that already landed)`
102961
102976
  } : {}
102962
102977
  }));
102963
102978
  }
102964
- return emit(io, ok({ issueId, date: date.data.localDate, steps: results }), (data) => [
102979
+ return emit(io, ok2({ issueId, date: date.data.localDate, steps: results }), (data) => [
102965
102980
  `${issueId}: ${data.steps.map((entry) => `${entry.step} ${entry.status.replace("_", " ")}`).join(", ")} (${data.date})`,
102966
102981
  ...data.steps.flatMap((entry) => entry.note ? [` note (${entry.step}): ${entry.note}`] : [])
102967
102982
  ]);
@@ -103027,14 +103042,14 @@ async function run23(argv, io) {
103027
103042
  if (flags.booleans.has("preview")) {
103028
103043
  const preview = changelogApplyPreview(input);
103029
103044
  if (preview.error)
103030
- return emit(io, fail("invalid_input", String(preview.error)));
103045
+ return emit(io, fail2("invalid_input", String(preview.error)));
103031
103046
  const { after, ...summary } = preview;
103032
- return emit(io, ok({ ...summary, after }), () => [String(after)]);
103047
+ return emit(io, ok2({ ...summary, after }), () => [String(after)]);
103033
103048
  }
103034
103049
  const applied = changelogApply(input);
103035
103050
  if (applied.error)
103036
- return emit(io, fail("failed", String(applied.error)));
103037
- return emit(io, ok(applied), () => [
103051
+ return emit(io, fail2("failed", String(applied.error)));
103052
+ return emit(io, ok2(applied), () => [
103038
103053
  `changelog updated: ${String(applied.path ?? "CHANGELOG.md")}`
103039
103054
  ]);
103040
103055
  }
@@ -103099,27 +103114,27 @@ async function resumeBrief(argv, io) {
103099
103114
  strict: true
103100
103115
  }));
103101
103116
  } catch (error) {
103102
- return emit(io, fail("invalid_input", error.message, { unblock: USAGE16 }));
103117
+ return emit(io, fail2("invalid_input", error.message, { unblock: USAGE16 }));
103103
103118
  }
103104
103119
  const last = values.last === undefined ? 10 : Number(values.last);
103105
103120
  if (!Number.isInteger(last) || last < 1)
103106
- return emit(io, fail("invalid_input", "--last must be a positive integer", { unblock: USAGE16 }));
103121
+ return emit(io, fail2("invalid_input", "--last must be a positive integer", { unblock: USAGE16 }));
103107
103122
  const built = buildHandoff(io.cwd, {
103108
103123
  last,
103109
103124
  note: values.note ?? null,
103110
103125
  next: values.next ?? null
103111
103126
  });
103112
103127
  if (!built.ok)
103113
- return emit(io, fail(built.code, built.error, built.unblock ? { unblock: built.unblock } : {}));
103128
+ return emit(io, fail2(built.code, built.error, built.unblock ? { unblock: built.unblock } : {}));
103114
103129
  const data = built.value;
103115
103130
  let recorded = null;
103116
103131
  if (values.record) {
103117
103132
  const row = recordHandoff({ cwd: io.cwd, actor: actorFromEnv(io.env), branch: data.branch }, { note: data.note, next: data.next });
103118
103133
  if (!row.ok)
103119
- return emit(io, fail(row.code, row.error, { data: { ...data, recorded } }));
103134
+ return emit(io, fail2(row.code, row.error, { data: { ...data, recorded } }));
103120
103135
  recorded = row.value.id;
103121
103136
  }
103122
- return emit(io, ok({ ...data, recorded }), human2);
103137
+ return emit(io, ok2({ ...data, recorded }), human2);
103123
103138
  }
103124
103139
  async function run24(argv, io) {
103125
103140
  if (!argv.some((arg) => arg === "--task" || arg.startsWith("--task=")))
@@ -103137,100 +103152,6 @@ var init_handoff = __esm(() => {
103137
103152
  init_package();
103138
103153
  import path62 from "node:path";
103139
103154
 
103140
- // packages/workit-cli/src/help.ts
103141
- var HELP_FLAGS = new Set(["--help", "-h"]);
103142
- var ESCAPE = "A value that starts with - goes as --flag=value (or after a bare --).";
103143
- var options = (args) => {
103144
- const end = args.indexOf("--");
103145
- return end < 0 ? args : args.slice(0, end);
103146
- };
103147
- var wantsHelp = (args) => options(args).some((arg) => HELP_FLAGS.has(arg));
103148
- var firstWord = (args) => options(args).find((arg) => !arg.startsWith("-"));
103149
- var valueFlags = (lines) => {
103150
- const out = new Map;
103151
- const group = /(?<![\w-])(--?[a-zA-Z][\w-]*(?:\|--?[a-zA-Z][\w-]*)*) (?=[<"a-z0-9])/gu;
103152
- for (const line of lines)
103153
- for (const match of line.matchAll(group)) {
103154
- const names = match[1].split("|");
103155
- const long = names.find((name) => name.startsWith("--")) ?? names[0];
103156
- for (const name of names)
103157
- out.set(name, long);
103158
- }
103159
- return out;
103160
- };
103161
- function helpAsValue(args, lines) {
103162
- const before = options(args);
103163
- const takes = valueFlags(lines);
103164
- for (let index = 1;index < before.length; index += 1) {
103165
- const flag = before[index];
103166
- const long = takes.get(before[index - 1]);
103167
- if (HELP_FLAGS.has(flag) && long)
103168
- return `\`${flag}\` looks like the value of ${before[index - 1]}; use ${long}=${flag} or put it after --`;
103169
- }
103170
- return null;
103171
- }
103172
- function takesPositionals(lines) {
103173
- const flag = /(?<![\w-])--?[a-zA-Z][\w-]*(?:\|--?[a-zA-Z][\w-]*)*(?:[ =](?!-)(?:<[^>]*>|"[^"]*"|[\w.,@/|=-]+)…?)?/gu;
103174
- return lines.some((line) => /<|"|\w…|\s…/u.test(line.replace(flag, "")));
103175
- }
103176
- var usageLines = (entry) => entry.subcommands?.length ? entry.subcommands.map((sub) => sub.usage) : [entry.usage];
103177
- var examplesFor = (entry, sub) => (entry.examples ?? []).filter((example) => sub ? new RegExp(`^workit ${entry.name} ${sub.name}(?![\\w-])`, "u").test(example) : true);
103178
- var exampleBlock = (examples) => examples.length ? ["", "examples:", ...examples.map((line) => ` ${line}`)] : [];
103179
- var noteBlock = (entry) => (entry.notes ?? []).flatMap((note) => ["", note]);
103180
- function verbHelp(entry) {
103181
- const subs = entry.subcommands ?? [];
103182
- const usages = usageLines(entry);
103183
- const examples = examplesFor(entry);
103184
- const text = [
103185
- ...subs.length ? [
103186
- `workit ${entry.name}: ${entry.summary}`,
103187
- "",
103188
- ...subs.flatMap((sub) => [`usage: ${sub.usage}`, ` ${sub.summary}`])
103189
- ] : [`usage: ${entry.usage}`, "", entry.summary],
103190
- ...noteBlock(entry),
103191
- ...exampleBlock(examples),
103192
- "",
103193
- ...subs.length ? [`More: workit help ${entry.name} <${subs.map((sub) => sub.name).join("|")}>`] : [],
103194
- ESCAPE
103195
- ].join(`
103196
- `);
103197
- return {
103198
- name: entry.name,
103199
- group: entry.group,
103200
- usage: usages[0],
103201
- usages,
103202
- summary: entry.summary,
103203
- examples,
103204
- text
103205
- };
103206
- }
103207
- function subcommandHelp(entry, sub) {
103208
- const examples = examplesFor(entry, sub);
103209
- return {
103210
- name: entry.name,
103211
- group: entry.group,
103212
- subcommand: sub.name,
103213
- usage: sub.usage,
103214
- usages: [sub.usage],
103215
- summary: sub.summary,
103216
- examples,
103217
- text: [
103218
- `usage: ${sub.usage}`,
103219
- "",
103220
- sub.summary,
103221
- ...noteBlock(entry),
103222
- ...exampleBlock(examples),
103223
- "",
103224
- ...sub.aliases?.length ? [`aliases: ${sub.aliases.join(", ")}`] : [],
103225
- ESCAPE
103226
- ].join(`
103227
- `)
103228
- };
103229
- }
103230
-
103231
- // packages/workit-cli/src/main.ts
103232
- init_output();
103233
-
103234
103155
  // packages/workit-cli/src/verbs/registry.ts
103235
103156
  var TASK_FAMILY_NAMES = [
103236
103157
  "task",
@@ -103300,7 +103221,7 @@ var familySubcommands = (name) => {
103300
103221
  const implicit = name === "task" ? TASK_IMPLICIT : [];
103301
103222
  const grammar = Object.entries(FAMILY_ACTIONS[name]).filter(([action]) => !implicit.some((entry) => entry.name === action)).map(([action, summary]) => ({
103302
103223
  name: action,
103303
- usage: name === "policy" && action !== "explain" ? `workit policy ${action} ${POLICY_JUDGE} ${FAMILY_OPTIONS}` : name === "worker" && action !== "assign" ? `workit worker ${action} [<workerId>] ${FAMILY_OPTIONS}` : `workit ${name} ${action} ${FAMILY_OPTIONS}`,
103224
+ usage: name === "task" && action === "list" ? `workit task list [--status all] ${FAMILY_OPTIONS}` : name === "policy" && action !== "explain" ? `workit policy ${action} ${POLICY_JUDGE} ${FAMILY_OPTIONS}` : name === "worker" && action !== "assign" ? `workit worker ${action} [<workerId>] ${FAMILY_OPTIONS}` : `workit ${name} ${action} ${FAMILY_OPTIONS}`,
103304
103225
  summary
103305
103226
  }));
103306
103227
  return [...implicit, ...grammar];
@@ -103356,6 +103277,7 @@ var VERBS = [
103356
103277
  {
103357
103278
  name: "launch",
103358
103279
  group: "setup",
103280
+ passthrough: true,
103359
103281
  usage: "workit launch <host> [--auto-upgrade] [-- <host args…>]",
103360
103282
  summary: "Upgrade before host startup, then start the host",
103361
103283
  load: () => Promise.resolve().then(() => (init_launch(), exports_launch))
@@ -103410,6 +103332,9 @@ var VERBS = [
103410
103332
  name: "check",
103411
103333
  group: "delivery",
103412
103334
  usage: 'workit check <name> [--task <id>] [--base <ref>] [--no-lease --reason "<why>"] | workit check [--name <n>] [--shell] [--timeout <s>] [--task <id>] [--base <ref>] [--heavy [--wait <s>]] [--no-lease --reason "<why>"] -- <cmd…>',
103335
+ flagHints: {
103336
+ list: "workit check <name> runs a configured check; a name that is not configured prints the valid ones (workit check test|lint|typecheck|check)"
103337
+ },
103413
103338
  summary: "Run a configured or ad-hoc check and record CLI-observed evidence (exit = the command's); heavy checks wait for the machine-wide heavy-check lease",
103414
103339
  examples: [
103415
103340
  "workit check test",
@@ -103468,6 +103393,9 @@ var VERBS = [
103468
103393
  },
103469
103394
  {
103470
103395
  name: "create",
103396
+ flagHints: {
103397
+ head: "pr create opens the PR for the current branch: git switch <branch>, then workit pr create (--base sets the target)"
103398
+ },
103471
103399
  usage: "workit pr create [--base <b> | --track <t>] (--title <t> [--body <text> | --body-file <f|->] | --fill) [--issue <#n|ID|url>]… [--refs] [--label <l>]… [--reviewer <login>]… [--draft]",
103472
103400
  summary: "Open a PR/MR for the pushed branch, verified against the local HEAD, linking its issues"
103473
103401
  },
@@ -103539,6 +103467,7 @@ var VERBS = [
103539
103467
  },
103540
103468
  {
103541
103469
  name: "push",
103470
+ deferredFlags: ["force"],
103542
103471
  usage: "workit git push [-u|--set-upstream] [--force-with-lease [--expect <sha>] [--overwrite-unintegrated]] [--release <main|develop|v-tag>…]",
103543
103472
  summary: "Push the current branch and verify the remote tip (never a blind --force); --release finishes a git-flow release"
103544
103473
  },
@@ -103640,26 +103569,31 @@ var VERBS = [
103640
103569
  subcommands: [
103641
103570
  {
103642
103571
  name: "plan",
103572
+ flagAliases: { fanout: "name" },
103643
103573
  usage: "workit fanout plan <plan.json> [--name <n>] [--trunk <b> | --track <t>] [--take-lead]",
103644
103574
  summary: "Register the slices of a plan file"
103645
103575
  },
103646
103576
  {
103647
103577
  name: "brief",
103578
+ flagAliases: { fanout: "name" },
103648
103579
  usage: "workit fanout brief <slice> [--mode new|resume] [--attempt <n>] [--name <n>]",
103649
103580
  summary: "Render one worker's brief with the standing orders"
103650
103581
  },
103651
103582
  {
103652
103583
  name: "check",
103584
+ flagAliases: { fanout: "name" },
103653
103585
  usage: "workit fanout check [<slice>…] [--name <n>] [--base <ref>] [--offline]",
103654
103586
  summary: "Gate fan-in: out-of-scope edits, trunk and sibling merge conflicts"
103655
103587
  },
103656
103588
  {
103657
103589
  name: "status",
103590
+ flagAliases: { fanout: "name" },
103658
103591
  usage: "workit fanout status [--name <n>] [--stuck-after 30m] [--offline]",
103659
103592
  summary: "Each slice's state: STUCK, PR, CI, verdict, landed, landing order"
103660
103593
  },
103661
103594
  {
103662
103595
  name: "worktree",
103596
+ flagAliases: { fanout: "name" },
103663
103597
  usage: "workit fanout worktree create|release <slice> [--name <n>] [--force]",
103664
103598
  summary: "Make or release a slice's worktree (--force applies to release only)"
103665
103599
  }
@@ -103673,6 +103607,7 @@ var VERBS = [
103673
103607
  withSubcommands({
103674
103608
  name: "ledger",
103675
103609
  group: "delivery",
103610
+ sharedParser: true,
103676
103611
  summary: "Record and query decisions, rulings, SHA-keyed verdicts (patch-id carry-over across rebases) and a fanout's standing orders",
103677
103612
  subcommands: [
103678
103613
  {
@@ -103687,7 +103622,11 @@ var VERBS = [
103687
103622
  },
103688
103623
  {
103689
103624
  name: "verdict",
103690
- usage: `workit ledger verdict <result> --how "<method/evidence>" [--kind unit|live|perf|review] [--base <ref>] [--surface ui|cli|api] [--evidence <ref>]… [--self] ${LEDGER_ACTOR} | ledger verdict [<branch>]`,
103625
+ flagAliases: { sha: "head" },
103626
+ flagHints: {
103627
+ repo: "a verdict is recorded in the checkout you run it from: cd into the repo or pass --cwd <dir>"
103628
+ },
103629
+ usage: `workit ledger verdict <result> --how "<method/evidence>" [--head <sha>] [--kind unit|live|perf|review] [--base <ref>] [--surface ui|cli|api] [--evidence <ref>]… [--self] ${LEDGER_ACTOR} | ledger verdict [<branch>]`,
103691
103630
  summary: "Record a SHA-keyed verdict on the branch head (result: verified, tests-verified, type-check-only, blocked, failed), or show the current verdicts"
103692
103631
  },
103693
103632
  {
@@ -103708,6 +103647,7 @@ var VERBS = [
103708
103647
  },
103709
103648
  {
103710
103649
  name: "standing",
103650
+ flagAliases: { name: "fanout" },
103711
103651
  usage: `workit ledger standing add "<order>" | standing list | standing clear [<id>] [--fanout <name>] [--supersedes <id>] [--session <id> [--token <t>] | --as <role>]`,
103712
103652
  summary: "The lead's standing orders for a fanout's workers"
103713
103653
  },
@@ -103791,7 +103731,179 @@ var BY_NAME = new Map(VERBS.map((entry) => [entry.name, entry]));
103791
103731
  var findVerb = (name) => BY_NAME.get(name);
103792
103732
  var findSubcommand = (entry, name) => entry.subcommands?.find((sub) => sub.name === name || sub.aliases?.includes(name));
103793
103733
 
103734
+ // packages/workit-cli/src/help.ts
103735
+ var HELP_FLAGS = new Set(["--help", "-h"]);
103736
+ var ESCAPE2 = "A value that starts with - goes as --flag=value (or after a bare --).";
103737
+ var options = (args) => {
103738
+ const end = args.indexOf("--");
103739
+ return end < 0 ? args : args.slice(0, end);
103740
+ };
103741
+ var wantsHelp = (args) => options(args).some((arg) => HELP_FLAGS.has(arg));
103742
+ var firstWord = (args) => options(args).find((arg) => !arg.startsWith("-"));
103743
+ var valueFlags = (lines) => {
103744
+ const out = new Map;
103745
+ const group = /(?<![\w-])(--?[a-zA-Z][\w-]*(?:\|--?[a-zA-Z][\w-]*)*) (?=[<"a-z0-9])/gu;
103746
+ for (const line of lines)
103747
+ for (const match of line.matchAll(group)) {
103748
+ const names = match[1].split("|");
103749
+ const long = names.find((name) => name.startsWith("--")) ?? names[0];
103750
+ for (const name of names)
103751
+ out.set(name, long);
103752
+ }
103753
+ return out;
103754
+ };
103755
+ function helpAsValue(args, lines) {
103756
+ const before = options(args);
103757
+ const takes = valueFlags(lines);
103758
+ for (let index = 1;index < before.length; index += 1) {
103759
+ const flag = before[index];
103760
+ const long = takes.get(before[index - 1]);
103761
+ if (HELP_FLAGS.has(flag) && long)
103762
+ return `\`${flag}\` looks like the value of ${before[index - 1]}; use ${long}=${flag} or put it after --`;
103763
+ }
103764
+ return null;
103765
+ }
103766
+ function takesPositionals(lines) {
103767
+ const flag = /(?<![\w-])--?[a-zA-Z][\w-]*(?:\|--?[a-zA-Z][\w-]*)*(?:[ =](?!-)(?:<[^>]*>|"[^"]*"|[\w.,@/|=-]+)…?)?/gu;
103768
+ return lines.some((line) => /<|"|\w…|\s…/u.test(line.replace(flag, "")));
103769
+ }
103770
+ var usageLines = (entry) => entry.subcommands?.length ? entry.subcommands.map((sub) => sub.usage) : [entry.usage];
103771
+ var examplesFor = (entry, sub) => (entry.examples ?? []).filter((example) => sub ? new RegExp(`^workit ${entry.name} ${sub.name}(?![\\w-])`, "u").test(example) : true);
103772
+ var exampleBlock = (examples) => examples.length ? ["", "examples:", ...examples.map((line) => ` ${line}`)] : [];
103773
+ var noteBlock = (entry) => (entry.notes ?? []).flatMap((note) => ["", note]);
103774
+ function verbHelp(entry) {
103775
+ const subs = entry.subcommands ?? [];
103776
+ const usages = usageLines(entry);
103777
+ const examples = examplesFor(entry);
103778
+ const text = [
103779
+ ...subs.length ? [
103780
+ `workit ${entry.name}: ${entry.summary}`,
103781
+ "",
103782
+ ...subs.flatMap((sub) => [`usage: ${sub.usage}`, ` ${sub.summary}`])
103783
+ ] : [`usage: ${entry.usage}`, "", entry.summary],
103784
+ ...noteBlock(entry),
103785
+ ...exampleBlock(examples),
103786
+ "",
103787
+ ...subs.length ? [`More: workit help ${entry.name} <${subs.map((sub) => sub.name).join("|")}>`] : [],
103788
+ ESCAPE2
103789
+ ].join(`
103790
+ `);
103791
+ return {
103792
+ name: entry.name,
103793
+ group: entry.group,
103794
+ usage: usages[0],
103795
+ usages,
103796
+ summary: entry.summary,
103797
+ examples,
103798
+ text
103799
+ };
103800
+ }
103801
+ function subcommandHelp(entry, sub) {
103802
+ const examples = examplesFor(entry, sub);
103803
+ return {
103804
+ name: entry.name,
103805
+ group: entry.group,
103806
+ subcommand: sub.name,
103807
+ usage: sub.usage,
103808
+ usages: [sub.usage],
103809
+ summary: sub.summary,
103810
+ examples,
103811
+ text: [
103812
+ `usage: ${sub.usage}`,
103813
+ "",
103814
+ sub.summary,
103815
+ ...noteBlock(entry),
103816
+ ...exampleBlock(examples),
103817
+ "",
103818
+ ...sub.aliases?.length ? [`aliases: ${sub.aliases.join(", ")}`] : [],
103819
+ ESCAPE2
103820
+ ].join(`
103821
+ `)
103822
+ };
103823
+ }
103824
+ var distance = (left, right) => {
103825
+ let row = Array.from({ length: right.length + 1 }, (_, index) => index);
103826
+ for (let i = 1;i <= left.length; i += 1) {
103827
+ const next = [i];
103828
+ for (let j = 1;j <= right.length; j += 1)
103829
+ next[j] = Math.min(row[j] + 1, next[j - 1] + 1, row[j - 1] + (left[i - 1] === right[j - 1] ? 0 : 1));
103830
+ row = next;
103831
+ }
103832
+ return row[right.length];
103833
+ };
103834
+ function closest(word, candidates) {
103835
+ let best = null;
103836
+ let bestScore = Infinity;
103837
+ for (const candidate of candidates) {
103838
+ const near = distance(word, candidate);
103839
+ const score = candidate.startsWith(word) || word.startsWith(candidate) ? Math.min(near, 1) : near;
103840
+ if (score < bestScore) {
103841
+ best = candidate;
103842
+ bestScore = score;
103843
+ }
103844
+ }
103845
+ return best !== null && bestScore <= Math.max(2, Math.floor(word.length / 3)) ? best : null;
103846
+ }
103847
+ var COMMAND_HINTS = {
103848
+ status: "workit task status (this branch's task) or workit pr status (its PR); workit handoff prints the whole picture",
103849
+ context: "workit handoff prints the branch, HEAD, dirty state, verdict and next command"
103850
+ };
103851
+ function commandUnblock(command) {
103852
+ const near = closest(command, VERBS.filter((entry) => !entry.planned).map((entry) => entry.name));
103853
+ return COMMAND_HINTS[command] ?? (near ? `did you mean workit ${near}? (workit help)` : "workit help");
103854
+ }
103855
+ var LONG_FLAG = /^--([a-zA-Z][\w-]*)(=|$)/u;
103856
+ var GLOBAL_FLAGS = new Set(["json", "cwd", "help"]);
103857
+ function checkFlags(entry, args) {
103858
+ const word = firstWord(args);
103859
+ const sub = word === undefined ? undefined : findSubcommand(entry, word);
103860
+ const lines = sub && !entry.sharedParser && !/ …/u.test(sub.usage) ? [sub.usage] : usageLines(entry);
103861
+ const takes = valueFlags(lines);
103862
+ const known = new Set;
103863
+ for (const line of lines)
103864
+ for (const match of line.matchAll(/(?<![\w-])--([a-zA-Z][\w-]*)/gu))
103865
+ known.add(match[1]);
103866
+ const aliases = { ...entry.flagAliases, ...sub?.flagAliases };
103867
+ const hints = { ...entry.flagHints, ...sub?.flagHints };
103868
+ for (const flag of sub?.deferredFlags ?? [])
103869
+ known.add(flag);
103870
+ const where = `workit help ${entry.name}${sub ? ` ${sub.name}` : ""}`;
103871
+ const out = [];
103872
+ for (let index = 0;index < args.length; index += 1) {
103873
+ const arg = args[index];
103874
+ if (arg === "--") {
103875
+ out.push(...args.slice(index));
103876
+ break;
103877
+ }
103878
+ if (entry.passthrough && !arg.startsWith("-")) {
103879
+ out.push(...args.slice(index));
103880
+ break;
103881
+ }
103882
+ if (takes.has(arg) && index + 1 < args.length && args[index + 1] !== "--") {
103883
+ out.push(arg, args[index += 1]);
103884
+ continue;
103885
+ }
103886
+ const match = LONG_FLAG.exec(arg);
103887
+ if (!match || GLOBAL_FLAGS.has(match[1]) || known.has(match[1])) {
103888
+ out.push(arg);
103889
+ continue;
103890
+ }
103891
+ const canonical = aliases[match[1]];
103892
+ if (canonical !== undefined) {
103893
+ out.push(`--${canonical}${arg.slice(match[0].length - match[2].length)}`);
103894
+ continue;
103895
+ }
103896
+ const near = closest(match[1], known);
103897
+ return {
103898
+ error: `unknown option --${match[1]}`,
103899
+ unblock: hints[match[1]] ?? (near ? `did you mean --${near}? (${where})` : where)
103900
+ };
103901
+ }
103902
+ return { args: out };
103903
+ }
103904
+
103794
103905
  // packages/workit-cli/src/main.ts
103906
+ init_output();
103795
103907
  var GROUP_TITLES = {
103796
103908
  setup: "Setup",
103797
103909
  task: "Task control",
@@ -103870,11 +103982,11 @@ async function main(argv, overrides = {}, options = {}) {
103870
103982
  const cwd = path62.resolve(overrides.cwd ?? process.cwd(), parsed.cwd ?? ".");
103871
103983
  const io = { ...defaultIo(parsed.json), ...overrides, json: parsed.json, cwd };
103872
103984
  if (parsed.error)
103873
- return emit(io, fail("invalid_input", parsed.error));
103985
+ return emit(io, fail2("invalid_input", parsed.error));
103874
103986
  const [command, ...verbArgs] = parsed.rest;
103875
103987
  const args = parsed.json && !verbArgs.includes("--json") ? withJsonFlag(verbArgs) : verbArgs;
103876
103988
  if (command === "--version" || command === "-v" || command === "version") {
103877
- return emit(io, ok({ version: package_default.version }), (data) => data.version);
103989
+ return emit(io, ok2({ version: package_default.version }), (data) => data.version);
103878
103990
  }
103879
103991
  if (command === undefined || command === "help" || command === "--help" || command === "-h") {
103880
103992
  const [topic, sub] = command === "help" ? words2(args) : [];
@@ -103886,12 +103998,12 @@ async function main(argv, overrides = {}, options = {}) {
103886
103998
  return help(io, verbHelp(entry));
103887
103999
  const found = findSubcommand(entry, sub);
103888
104000
  if (!found)
103889
- return emit(io, fail("invalid_input", `unknown ${topic} subcommand "${sub}"`, {
104001
+ return emit(io, fail2("invalid_input", `unknown ${topic} subcommand "${sub}"`, {
103890
104002
  unblock: `workit help ${topic}`
103891
104003
  }));
103892
104004
  return help(io, subcommandHelp(entry, found));
103893
104005
  }
103894
- return emit(io, ok({ version: package_default.version, verbs: listed().map(describe3) }), () => helpText());
104006
+ return emit(io, ok2({ version: package_default.version, verbs: listed().map(describe3) }), () => helpText());
103895
104007
  }
103896
104008
  const entry = findVerb(command);
103897
104009
  if (!entry)
@@ -103901,7 +104013,7 @@ async function main(argv, overrides = {}, options = {}) {
103901
104013
  const sub = word === undefined ? undefined : findSubcommand(entry, word);
103902
104014
  const asValue = helpAsValue(verbArgs, sub ? [sub.usage] : usageLines(entry));
103903
104015
  if (asValue)
103904
- return emit(io, fail("invalid_input", asValue, {
104016
+ return emit(io, fail2("invalid_input", asValue, {
103905
104017
  unblock: `workit help ${entry.name}${sub ? ` ${sub.name}` : ""}`
103906
104018
  }));
103907
104019
  return help(io, sub ? subcommandHelp(entry, sub) : verbHelp(entry));
@@ -103909,11 +104021,14 @@ async function main(argv, overrides = {}, options = {}) {
103909
104021
  const ended = endOfOptions(io, entry, args);
103910
104022
  if (typeof ended === "number")
103911
104023
  return ended;
104024
+ const checked = checkFlags(entry, ended);
104025
+ if ("error" in checked)
104026
+ return emit(io, fail2("invalid_input", checked.error, { unblock: checked.unblock }));
103912
104027
  if (parsed.cwd !== null) {
103913
104028
  try {
103914
104029
  process.chdir(io.cwd);
103915
104030
  } catch {
103916
- return emit(io, fail("invalid_input", `--cwd: cannot enter ${io.cwd}`));
104031
+ return emit(io, fail2("invalid_input", `--cwd: cannot enter ${io.cwd}`));
103917
104032
  }
103918
104033
  if (process.env.WORKFLOW_WORKSPACE_ROOT !== undefined) {
103919
104034
  process.env.WORKFLOW_WORKSPACE_ROOT = io.cwd;
@@ -103925,7 +104040,7 @@ async function main(argv, overrides = {}, options = {}) {
103925
104040
  globalThis[Symbol.for("workit.migrationReporter")] = (report) => io.stderr(`workit: migrated ${report.tasks} task${report.tasks === 1 ? "" : "s"} from ${report.from} to ${report.to} (backup: ${report.backup})
103926
104041
  `);
103927
104042
  const verb = await entry.load();
103928
- const runVerb = (target) => guarded(target, () => verb.run(ended, target));
104043
+ const runVerb = (target) => guarded(target, () => verb.run(checked.args, target));
103929
104044
  if (!io.json)
103930
104045
  return runVerb(io);
103931
104046
  return runJsonPure(io, command, runVerb);
@@ -103936,7 +104051,7 @@ async function guarded(io, run) {
103936
104051
  } catch (error) {
103937
104052
  if (!(error instanceof Error) || error.name !== "WorkspaceConfigError")
103938
104053
  throw error;
103939
- return emit(io, fail("blocked", error.message, {
104054
+ return emit(io, fail2("blocked", error.message, {
103940
104055
  unblock: "fix ~/.config/workit/workspaces.json (workit init → Workspaces)"
103941
104056
  }));
103942
104057
  }
@@ -103991,7 +104106,7 @@ async function runJsonPure(io, command, run) {
103991
104106
  io.stderr(buffered.endsWith(`
103992
104107
  `) ? buffered : `${buffered}
103993
104108
  `);
103994
- const envelope = code === 0 ? ok(text ? { text } : {}) : fail(CODE_FOR_EXIT[code] ?? "failed", text.split(`
104109
+ const envelope = code === 0 ? ok2(text ? { text } : {}) : fail2(CODE_FOR_EXIT[code] ?? "failed", text.split(`
103995
104110
  `)[0] || `${command} exited with ${code}`);
103996
104111
  io.stdout(`${JSON.stringify(envelope)}
103997
104112
  `);
@@ -104012,17 +104127,17 @@ function endOfOptions(io, entry, args) {
104012
104127
  if (entry.subcommands?.length && !sub) {
104013
104128
  if (entry.optionalSubcommand || word !== undefined)
104014
104129
  return args;
104015
- return emit(io, fail("invalid_input", `missing ${entry.name} subcommand`, { unblock }));
104130
+ return emit(io, fail2("invalid_input", `missing ${entry.name} subcommand`, { unblock }));
104016
104131
  }
104017
104132
  if (takesPositionals(sub ? [sub.usage] : [entry.usage]))
104018
104133
  return args;
104019
104134
  const extra = args.slice(end + 1);
104020
104135
  if (extra.length)
104021
- return emit(io, fail("invalid_input", `${entry.name}${sub ? ` ${sub.name}` : ""} takes no positional arguments (got: ${extra.join(" ")})`, { unblock }));
104136
+ return emit(io, fail2("invalid_input", `${entry.name}${sub ? ` ${sub.name}` : ""} takes no positional arguments (got: ${extra.join(" ")})`, { unblock }));
104022
104137
  return args.slice(0, end);
104023
104138
  }
104024
104139
  var words2 = (args) => args.filter((arg) => !arg.startsWith("-"));
104025
- var help = (io, doc) => emit(io, ok(doc), (data) => data.text);
104140
+ var help = (io, doc) => emit(io, ok2(doc), (data) => data.text);
104026
104141
  var describe3 = (entry) => ({
104027
104142
  name: entry.name,
104028
104143
  group: entry.group,
@@ -104031,7 +104146,7 @@ var describe3 = (entry) => ({
104031
104146
  summary: entry.summary,
104032
104147
  ...entry.planned ? { planned: entry.planned } : {}
104033
104148
  });
104034
- var unknown2 = (io, command) => emit(io, fail("invalid_input", `unknown command "${command}"`, { unblock: "workit help" }));
104149
+ var unknown2 = (io, command) => emit(io, fail2("invalid_input", `unknown command "${command}"`, { unblock: commandUnblock(command) }));
104035
104150
  if (__require.main == __require.module) {
104036
104151
  process.exit(await main(process.argv.slice(2), {}, { diagnostics: true }));
104037
104152
  }