@cleocode/cleo 2026.5.103 → 2026.5.105

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -10984,6 +10984,45 @@ var init_plan = __esm({
10984
10984
  }
10985
10985
  });
10986
10986
 
10987
+ // packages/contracts/src/render/envelope.ts
10988
+ var init_envelope = __esm({
10989
+ "packages/contracts/src/render/envelope.ts"() {
10990
+ "use strict";
10991
+ }
10992
+ });
10993
+
10994
+ // packages/contracts/src/render/list.ts
10995
+ var init_list = __esm({
10996
+ "packages/contracts/src/render/list.ts"() {
10997
+ "use strict";
10998
+ }
10999
+ });
11000
+
11001
+ // packages/contracts/src/render/table.ts
11002
+ var init_table = __esm({
11003
+ "packages/contracts/src/render/table.ts"() {
11004
+ "use strict";
11005
+ }
11006
+ });
11007
+
11008
+ // packages/contracts/src/render/tree.ts
11009
+ var init_tree = __esm({
11010
+ "packages/contracts/src/render/tree.ts"() {
11011
+ "use strict";
11012
+ }
11013
+ });
11014
+
11015
+ // packages/contracts/src/render/index.ts
11016
+ var init_render = __esm({
11017
+ "packages/contracts/src/render/index.ts"() {
11018
+ "use strict";
11019
+ init_envelope();
11020
+ init_list();
11021
+ init_table();
11022
+ init_tree();
11023
+ }
11024
+ });
11025
+
10987
11026
  // packages/contracts/src/session.ts
10988
11027
  var init_session2 = __esm({
10989
11028
  "packages/contracts/src/session.ts"() {
@@ -11194,6 +11233,7 @@ var init_src2 = __esm({
11194
11233
  init_peer();
11195
11234
  init_evidence_atoms();
11196
11235
  init_plan();
11236
+ init_render();
11197
11237
  init_session2();
11198
11238
  init_session_journal();
11199
11239
  init_status_registry();
@@ -11203,253 +11243,6 @@ var init_src2 = __esm({
11203
11243
  }
11204
11244
  });
11205
11245
 
11206
- // packages/cleo/src/cli/renderers/colors.ts
11207
- function ansi(code) {
11208
- return colorsEnabled ? code : "";
11209
- }
11210
- function statusSymbol(status) {
11211
- const map2 = unicodeEnabled ? TASK_STATUS_SYMBOLS_UNICODE : TASK_STATUS_SYMBOLS_ASCII;
11212
- return map2[status] ?? "?";
11213
- }
11214
- function statusColor(status) {
11215
- switch (status) {
11216
- case "pending":
11217
- return CYAN;
11218
- case "active":
11219
- return GREEN;
11220
- case "blocked":
11221
- return RED;
11222
- case "done":
11223
- return DIM;
11224
- case "cancelled":
11225
- return DIM;
11226
- case "archived":
11227
- return DIM;
11228
- default:
11229
- return "";
11230
- }
11231
- }
11232
- function prioritySymbol(priority) {
11233
- if (unicodeEnabled) {
11234
- switch (priority) {
11235
- case "critical":
11236
- return "\u{1F534}";
11237
- // red circle emoji
11238
- case "high":
11239
- return "\u{1F7E1}";
11240
- // yellow circle emoji
11241
- case "medium":
11242
- return "\u{1F535}";
11243
- // blue circle emoji
11244
- case "low":
11245
- return "\u26AA";
11246
- // white circle emoji
11247
- default:
11248
- return "";
11249
- }
11250
- }
11251
- switch (priority) {
11252
- case "critical":
11253
- return "!";
11254
- case "high":
11255
- return "H";
11256
- case "medium":
11257
- return "M";
11258
- case "low":
11259
- return "L";
11260
- default:
11261
- return "";
11262
- }
11263
- }
11264
- function priorityColor(priority) {
11265
- switch (priority) {
11266
- case "critical":
11267
- return RED;
11268
- case "high":
11269
- return YELLOW;
11270
- case "medium":
11271
- return BLUE;
11272
- case "low":
11273
- return DIM;
11274
- default:
11275
- return "";
11276
- }
11277
- }
11278
- function hRule(width = 65) {
11279
- return BOX.h.repeat(width);
11280
- }
11281
- function shortDate(isoDate) {
11282
- if (!isoDate) return "";
11283
- return isoDate.split("T")[0] ?? isoDate;
11284
- }
11285
- var colorsEnabled, unicodeEnabled, BOLD, DIM, NC, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, BOX;
11286
- var init_colors = __esm({
11287
- "packages/cleo/src/cli/renderers/colors.ts"() {
11288
- "use strict";
11289
- init_src2();
11290
- colorsEnabled = (() => {
11291
- if (process.env["NO_COLOR"] !== void 0) return false;
11292
- if (process.env["FORCE_COLOR"] !== void 0) return true;
11293
- return process.stdout.isTTY === true;
11294
- })();
11295
- unicodeEnabled = (() => {
11296
- const lang = process.env["LANG"] ?? "";
11297
- if (lang === "C" || lang === "POSIX") return false;
11298
- return lang.includes("UTF") || process.platform === "darwin";
11299
- })();
11300
- BOLD = ansi("\x1B[1m");
11301
- DIM = ansi("\x1B[2m");
11302
- NC = ansi("\x1B[0m");
11303
- RED = ansi("\x1B[0;31m");
11304
- GREEN = ansi("\x1B[0;32m");
11305
- YELLOW = ansi("\x1B[1;33m");
11306
- BLUE = ansi("\x1B[0;34m");
11307
- MAGENTA = ansi("\x1B[0;35m");
11308
- CYAN = ansi("\x1B[0;36m");
11309
- BOX = unicodeEnabled ? {
11310
- tl: "\u256D",
11311
- tr: "\u256E",
11312
- bl: "\u2570",
11313
- br: "\u256F",
11314
- h: "\u2500",
11315
- v: "\u2502",
11316
- ml: "\u251C",
11317
- mr: "\u2524"
11318
- } : { tl: "+", tr: "+", bl: "+", br: "+", h: "-", v: "|", ml: "+", mr: "+" };
11319
- }
11320
- });
11321
-
11322
- // packages/cleo/src/cli/renderers/format-helpers.ts
11323
- function terminalWidth() {
11324
- const cols = process.stdout.columns ?? 100;
11325
- return Math.max(40, cols);
11326
- }
11327
- function visibleLength(s) {
11328
- return s.replace(ANSI_REGEX, "").length;
11329
- }
11330
- function padVisible(s, width) {
11331
- const visible = visibleLength(s);
11332
- if (visible >= width) return s;
11333
- return s + " ".repeat(width - visible);
11334
- }
11335
- function truncateVisible(s, max) {
11336
- if (max <= 0) return "";
11337
- if (visibleLength(s) <= max) return s;
11338
- const ellipsis = "\u2026";
11339
- const target = max - 1;
11340
- let out = "";
11341
- let visible = 0;
11342
- let i = 0;
11343
- while (i < s.length && visible < target) {
11344
- const ch = s[i];
11345
- if (ch === "\x1B" && s[i + 1] === "[") {
11346
- const end = s.indexOf("m", i + 2);
11347
- if (end === -1) break;
11348
- out += s.slice(i, end + 1);
11349
- i = end + 1;
11350
- continue;
11351
- }
11352
- out += ch;
11353
- visible++;
11354
- i++;
11355
- }
11356
- return `${out}${ellipsis}`;
11357
- }
11358
- function dataTable(rows, columns, opts = {}) {
11359
- if (rows.length === 0 || columns.length === 0) return "";
11360
- const indent = opts.indent ?? 2;
11361
- const sep2 = opts.separator ?? " ";
11362
- const totalWidth = opts.totalWidth ?? terminalWidth();
11363
- const showHeader = opts.showHeader !== false;
11364
- const cells = rows.map((row, i) => columns.map((col) => col.get(row, i)));
11365
- const natWidths = columns.map((col, c) => {
11366
- const headerW = visibleLength(col.header);
11367
- const cellW = Math.max(...cells.map((r) => visibleLength(r[c] ?? "")));
11368
- return Math.max(headerW, cellW);
11369
- });
11370
- const capped = natWidths.map((w, c) => {
11371
- const cap = columns[c]?.maxWidth ?? Number.MAX_SAFE_INTEGER;
11372
- const min = columns[c]?.minWidth ?? 0;
11373
- return Math.max(min, Math.min(w, cap));
11374
- });
11375
- const sepW = sep2.length * (columns.length - 1) + indent;
11376
- let totalUsed = capped.reduce((a, b) => a + b, 0) + sepW;
11377
- const widths = [...capped];
11378
- while (totalUsed > totalWidth) {
11379
- let widest = 0;
11380
- for (let c = 1; c < widths.length; c++) {
11381
- if ((widths[c] ?? 0) > (widths[widest] ?? 0)) widest = c;
11382
- }
11383
- const wCur = widths[widest] ?? 0;
11384
- const minAllowed = columns[widest]?.minWidth ?? 6;
11385
- if (wCur <= minAllowed) break;
11386
- widths[widest] = wCur - 1;
11387
- totalUsed--;
11388
- }
11389
- const pad = " ".repeat(indent);
11390
- const lines = [];
11391
- if (showHeader) {
11392
- const header = columns.map(
11393
- (c, i) => `${BOLD}${padVisible(truncateVisible(c.header, widths[i] ?? 0), widths[i] ?? 0)}${NC}`
11394
- ).join(sep2);
11395
- lines.push(`${pad}${header}`);
11396
- }
11397
- for (const row of cells) {
11398
- const formatted = row.map((cell, i) => padVisible(truncateVisible(cell ?? "", widths[i] ?? 0), widths[i] ?? 0)).join(sep2);
11399
- lines.push(`${pad}${formatted}`);
11400
- }
11401
- return lines.join("\n");
11402
- }
11403
- function pagerFooter(input2) {
11404
- const { shown, page } = input2;
11405
- const total = page?.total ?? input2.total ?? shown;
11406
- const filtered = input2.filtered;
11407
- const hasMore = page?.hasMore === true || shown < total;
11408
- const filterActive = typeof filtered === "number" && filtered !== total;
11409
- if (!hasMore && !filterActive) return "";
11410
- const parts = [`${shown} of ${total}`];
11411
- if (filterActive) parts.push(`${filtered} after filter`);
11412
- if (typeof page?.offset === "number") parts.push(`offset ${page.offset}`);
11413
- if (typeof page?.limit === "number") parts.push(`--limit ${page.limit}`);
11414
- if (hasMore) parts.push("--json for full set");
11415
- return `${DIM}\u2500\u2500\u2500 ${parts.join(" \xB7 ")} \u2500\u2500\u2500${NC}`;
11416
- }
11417
- function metaFooter(meta) {
11418
- if (!meta || typeof meta !== "object") return "";
11419
- const lines = [];
11420
- const deprecated = meta["deprecated"];
11421
- if (deprecated && typeof deprecated === "object") {
11422
- const since = deprecated.since ? ` since ${deprecated.since}` : "";
11423
- const removeIn = deprecated.removeIn ? ` \xB7 removed in ${deprecated.removeIn}` : "";
11424
- const replacement = deprecated.replacement ? ` \xB7 use \`${deprecated.replacement}\`` : "";
11425
- lines.push(`${DIM}deprecated${since}${removeIn}${replacement}${NC}`);
11426
- }
11427
- const nexus = meta["_nexus"];
11428
- const duration = meta["duration_ms"];
11429
- const chips = [];
11430
- if (nexus && typeof nexus === "object") {
11431
- if (typeof nexus["scope"] === "string") chips.push(`scope=${nexus["scope"]}`);
11432
- if (typeof nexus["projectName"] === "string") {
11433
- chips.push(`project=${nexus["projectName"]}`);
11434
- } else if (typeof nexus["projectId"] === "string") {
11435
- const pid = String(nexus["projectId"]);
11436
- chips.push(`project=${pid.length > 16 ? `${pid.slice(0, 13)}\u2026` : pid}`);
11437
- }
11438
- if (nexus["indexFreshness"] === "stale") chips.push(`${DIM}index=stale${NC}`);
11439
- }
11440
- if (typeof duration === "number" && duration > 0) chips.push(`${duration} ms`);
11441
- if (chips.length > 0) lines.push(`${DIM}[${chips.join(" \xB7 ")}]${NC}`);
11442
- return lines.join("\n");
11443
- }
11444
- var ANSI_REGEX;
11445
- var init_format_helpers = __esm({
11446
- "packages/cleo/src/cli/renderers/format-helpers.ts"() {
11447
- "use strict";
11448
- init_colors();
11449
- ANSI_REGEX = /\x1b\[[0-9;]*m/g;
11450
- }
11451
- });
11452
-
11453
11246
  // packages/cleo/src/cli/renderers/lafs-validator.ts
11454
11247
  function validateLafsShape(envelope) {
11455
11248
  const report = {
@@ -11659,6 +11452,122 @@ var init_tree_context = __esm({
11659
11452
  }
11660
11453
  });
11661
11454
 
11455
+ // packages/cleo/src/cli/renderers/colors.ts
11456
+ function ansi(code) {
11457
+ return colorsEnabled ? code : "";
11458
+ }
11459
+ function statusSymbol(status) {
11460
+ const map2 = unicodeEnabled ? TASK_STATUS_SYMBOLS_UNICODE : TASK_STATUS_SYMBOLS_ASCII;
11461
+ return map2[status] ?? "?";
11462
+ }
11463
+ function statusColor(status) {
11464
+ switch (status) {
11465
+ case "pending":
11466
+ return CYAN;
11467
+ case "active":
11468
+ return GREEN;
11469
+ case "blocked":
11470
+ return RED;
11471
+ case "done":
11472
+ return DIM;
11473
+ case "cancelled":
11474
+ return DIM;
11475
+ case "archived":
11476
+ return DIM;
11477
+ default:
11478
+ return "";
11479
+ }
11480
+ }
11481
+ function prioritySymbol(priority) {
11482
+ if (unicodeEnabled) {
11483
+ switch (priority) {
11484
+ case "critical":
11485
+ return "\u{1F534}";
11486
+ // red circle emoji
11487
+ case "high":
11488
+ return "\u{1F7E1}";
11489
+ // yellow circle emoji
11490
+ case "medium":
11491
+ return "\u{1F535}";
11492
+ // blue circle emoji
11493
+ case "low":
11494
+ return "\u26AA";
11495
+ // white circle emoji
11496
+ default:
11497
+ return "";
11498
+ }
11499
+ }
11500
+ switch (priority) {
11501
+ case "critical":
11502
+ return "!";
11503
+ case "high":
11504
+ return "H";
11505
+ case "medium":
11506
+ return "M";
11507
+ case "low":
11508
+ return "L";
11509
+ default:
11510
+ return "";
11511
+ }
11512
+ }
11513
+ function priorityColor(priority) {
11514
+ switch (priority) {
11515
+ case "critical":
11516
+ return RED;
11517
+ case "high":
11518
+ return YELLOW;
11519
+ case "medium":
11520
+ return BLUE;
11521
+ case "low":
11522
+ return DIM;
11523
+ default:
11524
+ return "";
11525
+ }
11526
+ }
11527
+ function hRule(width = 65) {
11528
+ return BOX.h.repeat(width);
11529
+ }
11530
+ function shortDate(isoDate) {
11531
+ if (!isoDate) return "";
11532
+ return isoDate.split("T")[0] ?? isoDate;
11533
+ }
11534
+ var colorsEnabled, unicodeEnabled, BOLD, DIM, NC, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, BOX;
11535
+ var init_colors = __esm({
11536
+ "packages/cleo/src/cli/renderers/colors.ts"() {
11537
+ "use strict";
11538
+ init_src2();
11539
+ colorsEnabled = (() => {
11540
+ if (process.env["NO_COLOR"] !== void 0) return false;
11541
+ if (process.env["FORCE_COLOR"] !== void 0) return true;
11542
+ return process.stdout.isTTY === true;
11543
+ })();
11544
+ unicodeEnabled = (() => {
11545
+ const lang = process.env["LANG"] ?? "";
11546
+ if (lang === "C" || lang === "POSIX") return false;
11547
+ return lang.includes("UTF") || process.platform === "darwin";
11548
+ })();
11549
+ BOLD = ansi("\x1B[1m");
11550
+ DIM = ansi("\x1B[2m");
11551
+ NC = ansi("\x1B[0m");
11552
+ RED = ansi("\x1B[0;31m");
11553
+ GREEN = ansi("\x1B[0;32m");
11554
+ YELLOW = ansi("\x1B[1;33m");
11555
+ BLUE = ansi("\x1B[0;34m");
11556
+ MAGENTA = ansi("\x1B[0;35m");
11557
+ CYAN = ansi("\x1B[0;36m");
11558
+ BOX = unicodeEnabled ? {
11559
+ tl: "\u256D",
11560
+ tr: "\u256E",
11561
+ bl: "\u2570",
11562
+ br: "\u256F",
11563
+ h: "\u2500",
11564
+ v: "\u2502",
11565
+ ml: "\u251C",
11566
+ mr: "\u2524"
11567
+ } : { tl: "+", tr: "+", bl: "+", br: "+", h: "-", v: "|", ml: "+", mr: "+" };
11568
+ }
11569
+ });
11570
+
11662
11571
  // packages/cleo/src/cli/renderers/system.ts
11663
11572
  import { formatTree, formatWaves } from "@cleocode/core/formatters";
11664
11573
  function cliColorize(text, style) {
@@ -13489,7 +13398,12 @@ __export(renderers_exports, {
13489
13398
  renderWaves: () => renderWaves
13490
13399
  });
13491
13400
  import { randomUUID } from "node:crypto";
13492
- import { drainWarnings, formatSuccess } from "@cleocode/core";
13401
+ import {
13402
+ drainWarnings,
13403
+ formatSuccess,
13404
+ metaFooter,
13405
+ pagerFooter
13406
+ } from "@cleocode/core";
13493
13407
  import { applyFieldFilter, extractFieldFromResult } from "@cleocode/lafs";
13494
13408
  function generateRequestId() {
13495
13409
  return randomUUID();
@@ -13695,7 +13609,6 @@ var init_renderers = __esm({
13695
13609
  "use strict";
13696
13610
  init_field_context();
13697
13611
  init_format_context();
13698
- init_format_helpers();
13699
13612
  init_lafs_validator();
13700
13613
  init_normalizer();
13701
13614
  init_system2();
@@ -29580,7 +29493,7 @@ var init_release2 = __esm({
29580
29493
  *
29581
29494
  * Supported operations:
29582
29495
  * - `gate` — check IVTR phase state for all tasks in a release epic
29583
- * - `ivtr-suggest` — check if all epic tasks are released and suggest `release ship`
29496
+ * - `ivtr-suggest` — check if all epic tasks are released and suggest `cleo release plan` + `cleo release open`
29584
29497
  *
29585
29498
  * The legacy `verify` query (run gates + audit child tasks) was removed
29586
29499
  * in T9540 — use `cleo verify <task> --gate X --evidence …` per
@@ -37217,7 +37130,7 @@ function formatExpiry(expiresAt) {
37217
37130
  return `expires in ${days}d`;
37218
37131
  }
37219
37132
  var authListCommand;
37220
- var init_list = __esm({
37133
+ var init_list2 = __esm({
37221
37134
  "packages/cleo/src/cli/commands/auth/list.ts"() {
37222
37135
  "use strict";
37223
37136
  init_dist();
@@ -37625,7 +37538,7 @@ var init_auth = __esm({
37625
37538
  "packages/cleo/src/cli/commands/auth/index.ts"() {
37626
37539
  "use strict";
37627
37540
  init_consent();
37628
- init_list();
37541
+ init_list2();
37629
37542
  init_migrate_project_secrets();
37630
37543
  init_remove();
37631
37544
  }
@@ -39573,7 +39486,7 @@ __export(changeset_exports, {
39573
39486
  });
39574
39487
  import { existsSync as existsSync11 } from "node:fs";
39575
39488
  import { join as join14 } from "node:path";
39576
- import { changesets, getProjectRoot as getProjectRoot28 } from "@cleocode/core";
39489
+ import { changesets, dataTable, getProjectRoot as getProjectRoot28 } from "@cleocode/core";
39577
39490
  function isValidKind(raw) {
39578
39491
  return typeof raw === "string" && CHANGESET_KINDS.includes(raw);
39579
39492
  }
@@ -39599,7 +39512,6 @@ var init_changeset = __esm({
39599
39512
  "use strict";
39600
39513
  init_src2();
39601
39514
  init_dist();
39602
- init_format_helpers();
39603
39515
  init_renderers();
39604
39516
  addCommand4 = defineCommand({
39605
39517
  meta: {
@@ -49466,7 +49378,7 @@ __export(list_exports, {
49466
49378
  });
49467
49379
  import { createPage as createPage2 } from "@cleocode/core";
49468
49380
  var listArgs, listCommand11;
49469
- var init_list2 = __esm({
49381
+ var init_list3 = __esm({
49470
49382
  "packages/cleo/src/cli/commands/list.ts"() {
49471
49383
  "use strict";
49472
49384
  init_src2();
@@ -57934,74 +57846,94 @@ var init_relates = __esm({
57934
57846
  }
57935
57847
  });
57936
57848
 
57937
- // packages/cleo/src/cli/commands/release.ts
57938
- var release_exports = {};
57939
- __export(release_exports, {
57940
- SHIP_DEPRECATION_NOTICE: () => SHIP_DEPRECATION_NOTICE,
57941
- releaseCommand: () => releaseCommand
57942
- });
57943
- import { pushWarning as pushWarning4, release as release2 } from "@cleocode/core";
57944
- var SHIP_DEPRECATION_NOTICE, shipCommand, listCommand19, showCommand10, cancelCommand2, rollbackCommand, rollbackFullCommand, prStatusCommand, channelCommand, planCommand3, openCommand2, reconcileCommand4, releaseCommand;
57945
- var init_release3 = __esm({
57946
- "packages/cleo/src/cli/commands/release.ts"() {
57849
+ // packages/cleo/src/cli/lib/define-cli-command.ts
57850
+ var init_define_cli_command = __esm({
57851
+ "packages/cleo/src/cli/lib/define-cli-command.ts"() {
57947
57852
  "use strict";
57948
57853
  init_dist();
57949
- init_cli();
57854
+ }
57855
+ });
57856
+
57857
+ // packages/cleo/src/cli/commands/release/ship-e2e-smoke.ts
57858
+ import { release as release2 } from "@cleocode/core";
57859
+ var shipE2eSmokeCommand;
57860
+ var init_ship_e2e_smoke = __esm({
57861
+ "packages/cleo/src/cli/commands/release/ship-e2e-smoke.ts"() {
57862
+ "use strict";
57863
+ init_define_cli_command();
57950
57864
  init_renderers();
57951
- SHIP_DEPRECATION_NOTICE = "[DEPRECATED] `cleo release ship` is a deprecated alias and will be removed no earlier than the third release cycle after T9498. Use `cleo release plan <version> --epic <id>` followed by `cleo release open <version>`; publish runs via GHA workflow. Docs: T9345-CHILD-1.";
57952
- shipCommand = defineCommand({
57865
+ shipE2eSmokeCommand = defineCommand({
57953
57866
  meta: {
57954
- name: "ship",
57955
- description: "[DEPRECATED] Forwards to `release plan` + `release open`"
57867
+ name: "ship-e2e-smoke",
57868
+ description: "One-shot end-to-end release smoke: plan \u2192 open \u2192 wait-for-PR \u2192 wait-for-tag \u2192 verify-npm-published. Dry-run by default; pass --execute to perform real mutations (T10103)."
57956
57869
  },
57957
57870
  args: {
57958
57871
  version: {
57959
57872
  type: "positional",
57960
- description: "Version string (e.g. 2026.4.77)",
57873
+ description: "Candidate release version (e.g. v2026.6.0 or 2026.6.0)",
57961
57874
  required: true
57962
57875
  },
57963
57876
  epic: {
57964
57877
  type: "string",
57965
- description: "Epic task ID (forwarded to release plan / release open)",
57878
+ description: "Epic task ID (forwarded to release plan)",
57966
57879
  required: true
57967
57880
  },
57968
- "dry-run": {
57881
+ execute: {
57969
57882
  type: "boolean",
57970
- description: "Preview all actions without writing anything (plan dry-run only)"
57883
+ description: "Actually perform mutations (default: dry-run preview only)"
57884
+ },
57885
+ "poll-interval-ms": {
57886
+ type: "string",
57887
+ description: "Polling interval for wait-* steps (default 5000)"
57888
+ },
57889
+ "total-timeout-ms": {
57890
+ type: "string",
57891
+ description: "Wall-clock budget across all polling waits (default 1800000 = 30 min)"
57971
57892
  }
57972
57893
  },
57973
57894
  async run({ args }) {
57974
- pushWarning4({
57975
- code: "W_DEPRECATED_COMMAND",
57976
- message: SHIP_DEPRECATION_NOTICE,
57977
- deprecated: "cleo release ship",
57978
- replacement: "cleo release plan <version> --epic <id> && cleo release open <version>"
57979
- });
57980
- await dispatchFromCli(
57981
- "mutate",
57982
- "release",
57983
- "plan",
57984
- {
57985
- version: args.version,
57986
- epicId: args.epic,
57987
- dryRun: args["dry-run"] === true
57988
- },
57989
- { command: "release" }
57990
- );
57991
- if (args["dry-run"] === true) {
57895
+ const pollIntervalMs = args["poll-interval-ms"] ? Number.parseInt(args["poll-interval-ms"], 10) : void 0;
57896
+ const totalTimeoutMs = args["total-timeout-ms"] ? Number.parseInt(args["total-timeout-ms"], 10) : void 0;
57897
+ const params = {
57898
+ version: args.version,
57899
+ epicId: args.epic,
57900
+ execute: args.execute === true,
57901
+ ...pollIntervalMs !== void 0 ? { pollIntervalMs } : {},
57902
+ ...totalTimeoutMs !== void 0 ? { totalTimeoutMs } : {}
57903
+ };
57904
+ const env = release2.createDefaultSmokeEnvironment();
57905
+ const result = await release2.runShipE2eSmoke(params, env);
57906
+ if (result.success) {
57907
+ cliOutput(result, { command: "release", operation: "release.ship-e2e-smoke" });
57992
57908
  return;
57993
57909
  }
57994
- await dispatchFromCli(
57995
- "mutate",
57996
- "release",
57997
- "open",
57998
- {
57999
- version: args.version
58000
- },
58001
- { command: "release" }
57910
+ const failed = result.steps.find((s) => s.status === "failed");
57911
+ cliError(
57912
+ `ship-e2e-smoke step "${failed?.name ?? "unknown"}" failed: ${failed?.error ?? "see envelope"}`,
57913
+ "E_SHIP_E2E_SMOKE_FAILED",
57914
+ { name: "E_SHIP_E2E_SMOKE_FAILED", details: result },
57915
+ { operation: "release.ship-e2e-smoke" }
58002
57916
  );
57917
+ process.exit(1);
58003
57918
  }
58004
57919
  });
57920
+ }
57921
+ });
57922
+
57923
+ // packages/cleo/src/cli/commands/release.ts
57924
+ var release_exports = {};
57925
+ __export(release_exports, {
57926
+ releaseCommand: () => releaseCommand
57927
+ });
57928
+ import { release as release3 } from "@cleocode/core";
57929
+ var listCommand19, showCommand10, cancelCommand2, rollbackCommand, rollbackFullCommand, prStatusCommand, channelCommand, planCommand3, openCommand2, reconcileCommand4, releaseCommand;
57930
+ var init_release3 = __esm({
57931
+ "packages/cleo/src/cli/commands/release.ts"() {
57932
+ "use strict";
57933
+ init_cli();
57934
+ init_define_cli_command();
57935
+ init_renderers();
57936
+ init_ship_e2e_smoke();
58005
57937
  listCommand19 = defineCommand({
58006
57938
  meta: { name: "list", description: "List all releases" },
58007
57939
  async run() {
@@ -58265,7 +58197,7 @@ var init_release3 = __esm({
58265
58197
  json: { type: "boolean", description: "Emit LAFS envelope" }
58266
58198
  },
58267
58199
  async run({ args }) {
58268
- const result = await release2.releaseReconcileV2(args.version, {
58200
+ const result = await release3.releaseReconcileV2(args.version, {
58269
58201
  fromWorkflow: args["from-workflow"] === true,
58270
58202
  rollback: args.rollback === true
58271
58203
  });
@@ -58289,25 +58221,24 @@ var init_release3 = __esm({
58289
58221
  releaseCommand = defineCommand({
58290
58222
  meta: {
58291
58223
  name: "release",
58292
- description: "Release lifecycle management \u2014 4-verb pipeline: plan \u2192 open \u2192 reconcile / rollback. Deprecated: ship (forwards to plan + open; see SPEC-T9345 \xA712)."
58224
+ description: "Release lifecycle management \u2014 4-verb pipeline: plan \u2192 open \u2192 reconcile / rollback. Use `ship-e2e-smoke` for end-to-end validation (dry-run by default)."
58293
58225
  },
58294
58226
  subCommands: {
58295
58227
  // Canonical SPEC-T9345 4-verb pipeline — list these first so `--help`
58296
- // surfaces them as the documented default (T9538 / R-420).
58228
+ // surfaces them as the documented default.
58297
58229
  plan: planCommand3,
58298
58230
  open: openCommand2,
58299
58231
  reconcile: reconcileCommand4,
58300
58232
  rollback: rollbackCommand,
58233
+ // End-to-end smoke walker — see docs/release/verb-matrix.md.
58234
+ "ship-e2e-smoke": shipE2eSmokeCommand,
58301
58235
  // Read-only helpers — not deprecated.
58302
58236
  list: listCommand19,
58303
58237
  show: showCommand10,
58304
58238
  cancel: cancelCommand2,
58305
58239
  "pr-status": prStatusCommand,
58306
58240
  channel: channelCommand,
58307
- "rollback-full": rollbackFullCommand,
58308
- // Deprecated verbs (kept for the migration window — SPEC-T9345 §12).
58309
- // R-420: ship → plan + open
58310
- ship: shipCommand
58241
+ "rollback-full": rollbackFullCommand
58311
58242
  },
58312
58243
  async run({ cmd, rawArgs }) {
58313
58244
  const firstArg = rawArgs?.find((a) => !a.startsWith("-"));
@@ -67266,7 +67197,7 @@ var COMMAND_MANIFEST = [
67266
67197
  exportName: "listCommand",
67267
67198
  name: "list",
67268
67199
  description: "List tasks with optional filters",
67269
- load: async () => (await Promise.resolve().then(() => (init_list2(), list_exports))).listCommand
67200
+ load: async () => (await Promise.resolve().then(() => (init_list3(), list_exports))).listCommand
67270
67201
  },
67271
67202
  {
67272
67203
  exportName: "costCommand",