@ritualai/cli 0.7.11 → 0.7.13

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.
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.printStaleBundleWarning = printStaleBundleWarning;
4
+ exports.shouldSkipWarning = shouldSkipWarning;
5
+ exports.buildWarningLine = buildWarningLine;
6
+ const skill_bundles_1 = require("./skill-bundles");
7
+ const package_info_1 = require("./package-info");
8
+ /**
9
+ * Pre-flight warning when the project's Ritual SKILL bundles drift
10
+ * from the installed CLI version.
11
+ *
12
+ * Why this exists (PR C, 2026-05-15): `ritual doctor` already reports
13
+ * drift, but users don't routinely run it. Eiman hit a CLI bug
14
+ * (#319 — dev URL leak in `/ritual init` output) that was already
15
+ * fixed in 0.7.11 — but her SKILL bundle on disk was older, so the
16
+ * fix only landed when she happened to re-run `ritual init`. A
17
+ * one-line stderr warning at every CLI entry catches the
18
+ * "upgraded the CLI, forgot to refresh skills" gap immediately.
19
+ *
20
+ * Design constraints:
21
+ * - Best-effort: never throws, never blocks. Filesystem races,
22
+ * unreadable manifests, missing dirs all silently no-op.
23
+ * - Skip during `init` (the fix command itself) and `doctor`
24
+ * (which already prints the same info, in more detail).
25
+ * - Skip during `--version` / `-V` / `--help` / `-h` — those exit
26
+ * immediately and a multi-line warning would feel out of place.
27
+ * - Single line when one bundle drifts, single summary line when
28
+ * multiple. Concise; the user doesn't need the doctor-style
29
+ * per-provider breakdown to know what to do.
30
+ * - Writes to stderr so it doesn't pollute scriptable stdout.
31
+ *
32
+ * The fix command is always `ritual init --skills-only` whether the
33
+ * bundle is stamped-and-drifted or pre-stamp-unknown — same code
34
+ * path, same outcome.
35
+ */
36
+ function printStaleBundleWarning(argv) {
37
+ if (shouldSkipWarning(argv))
38
+ return;
39
+ let stale;
40
+ try {
41
+ const bundles = (0, skill_bundles_1.findLocalSkillBundles)(process.cwd(), (0, package_info_1.readPackageVersionSafe)());
42
+ stale = (0, skill_bundles_1.findStaleBundles)(bundles);
43
+ }
44
+ catch {
45
+ return;
46
+ }
47
+ if (stale.length === 0)
48
+ return;
49
+ const line = buildWarningLine(stale);
50
+ process.stderr.write(line);
51
+ }
52
+ const SKIP_COMMANDS = new Set(['init', 'doctor']);
53
+ const SKIP_FLAGS = new Set(['--version', '-V', '--help', '-h']);
54
+ /**
55
+ * Skip rules — kept narrow so any new command opts in automatically:
56
+ * - `init` skips: the warning would print right before the user's
57
+ * fix command runs.
58
+ * - `doctor` skips: it already renders bundle drift in detail.
59
+ * - `--version` / `--help` skips: short-circuit invocations.
60
+ *
61
+ * Note we look at the FIRST non-flag positional only — `ritual graph
62
+ * status` should still warn, since that's an arbitrary subcommand
63
+ * that has no special relationship to skill bundles.
64
+ */
65
+ function shouldSkipWarning(argv) {
66
+ for (const a of argv) {
67
+ if (SKIP_FLAGS.has(a))
68
+ return true;
69
+ }
70
+ const firstPositional = argv.find((a) => !a.startsWith('-'));
71
+ if (firstPositional && SKIP_COMMANDS.has(firstPositional))
72
+ return true;
73
+ return false;
74
+ }
75
+ function buildWarningLine(stale) {
76
+ if (stale.length === 1) {
77
+ const s = stale[0];
78
+ const detail = s.drift.kind === 'drift'
79
+ ? `bundle ${s.drift.bundleVersion} vs CLI ${s.drift.cliVersion}`
80
+ : 'pre-0.7.11 bundle, no version stamp';
81
+ return `⚠ Ritual SKILL bundle is out of date (${detail}). Run \`ritual init --skills-only\` to refresh.\n\n`;
82
+ }
83
+ return `⚠ ${stale.length} Ritual SKILL bundles need refresh. Run \`ritual init --skills-only\`.\n\n`;
84
+ }
85
+ //# sourceMappingURL=stale-bundle-warning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stale-bundle-warning.js","sourceRoot":"","sources":["../../src/lib/stale-bundle-warning.ts"],"names":[],"mappings":";;AA+BA,0DAcC;AAgBD,8CAOC;AAED,4CAYC;AAlFD,mDAA0E;AAC1E,iDAAwD;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,SAAgB,uBAAuB,CAAC,IAAc;IACrD,IAAI,iBAAiB,CAAC,IAAI,CAAC;QAAE,OAAO;IAEpC,IAAI,KAAK,CAAC;IACV,IAAI,CAAC;QACJ,MAAM,OAAO,GAAG,IAAA,qCAAqB,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,IAAA,qCAAsB,GAAE,CAAC,CAAC;QAC/E,KAAK,GAAG,IAAA,gCAAgB,EAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO;IACR,CAAC;IACD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAE/B,MAAM,IAAI,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAClD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC;AAEhE;;;;;;;;;;GAUG;AACH,SAAgB,iBAAiB,CAAC,IAAc;IAC/C,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACtB,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IACpC,CAAC;IACD,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7D,IAAI,eAAe,IAAI,aAAa,CAAC,GAAG,CAAC,eAAe,CAAC;QAAE,OAAO,IAAI,CAAC;IACvE,OAAO,KAAK,CAAC;AACd,CAAC;AAED,SAAgB,gBAAgB,CAC/B,KAA0C;IAE1C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACnB,MAAM,MAAM,GACX,CAAC,CAAC,KAAK,CAAC,IAAI,KAAK,OAAO;YACvB,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,aAAa,WAAW,CAAC,CAAC,KAAK,CAAC,UAAU,EAAE;YAChE,CAAC,CAAC,qCAAqC,CAAC;QAC1C,OAAO,yCAAyC,MAAM,sDAAsD,CAAC;IAC9G,CAAC;IACD,OAAO,KAAK,KAAK,CAAC,MAAM,4EAA4E,CAAC;AACtG,CAAC"}
package/package.json CHANGED
@@ -1,74 +1,75 @@
1
1
  {
2
- "name": "@ritualai/cli",
3
- "version": "0.7.11",
4
- "description": "Ritual CLI — scaffold AI coding agent skills + register MCP servers. Connects Claude Code, Cursor, Windsurf, Kiro, Gemini CLI, VS Code/Copilot, and Codex to Ritual Cloud.",
5
- "private": false,
6
- "license": "Apache-2.0",
7
- "homepage": "https://ritual.work/ritual-mcp/docs/",
8
- "repository": {
9
- "type": "git",
10
- "url": "git+https://github.com/Ritual-Mobile/ritual-enterprise.git",
11
- "directory": "apps/cli"
12
- },
13
- "author": "Ritual",
14
- "publishConfig": {
15
- "access": "public"
16
- },
17
- "bin": {
18
- "ritual": "./dist/index.js"
19
- },
20
- "main": "./dist/index.js",
21
- "files": [
22
- "dist",
23
- "skills",
24
- "README.md"
25
- ],
26
- "dependencies": {
27
- "commander": "^14.0.3",
28
- "open": "^10.1.0"
29
- },
30
- "devDependencies": {
31
- "@types/jest": "^29.5.0",
32
- "@types/node": "^20.0.0",
33
- "jest": "^29.7.0",
34
- "ts-jest": "^29.1.0",
35
- "tsx": "^4.19.0",
36
- "typescript": "^5.0.0",
37
- "@ritual/shared-types": "^1.0.0"
38
- },
39
- "engines": {
40
- "node": ">=20.0.0"
41
- },
42
- "keywords": [
43
- "ritual",
44
- "mcp",
45
- "ai-coding-agent",
46
- "claude-code",
47
- "cursor",
48
- "windsurf",
49
- "kiro",
50
- "gemini-cli",
51
- "copilot",
52
- "codex"
53
- ],
54
- "jest": {
55
- "preset": "ts-jest",
56
- "testEnvironment": "node",
57
- "roots": [
58
- "<rootDir>/src",
59
- "<rootDir>/test"
60
- ],
61
- "testMatch": [
62
- "**/?(*.)+(spec|test).ts"
63
- ]
64
- },
65
- "scripts": {
66
- "build:skills": "node scripts/build-skills.js",
67
- "build:ts": "tsc -p tsconfig.json",
68
- "build": "pnpm run build:skills && pnpm run build:ts",
69
- "dev": "tsx src/index.ts",
70
- "clean": "rm -rf dist skills",
71
- "typecheck": "tsc --noEmit -p tsconfig.json",
72
- "test": "jest --passWithNoTests"
73
- }
74
- }
2
+ "name": "@ritualai/cli",
3
+ "version": "0.7.13",
4
+ "description": "Ritual CLI — scaffold AI coding agent skills + register MCP servers. Connects Claude Code, Cursor, Windsurf, Kiro, Gemini CLI, VS Code/Copilot, and Codex to Ritual Cloud.",
5
+ "private": false,
6
+ "license": "Apache-2.0",
7
+ "homepage": "https://ritual.work/ritual-mcp/docs/",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Ritual-Mobile/ritual-enterprise.git",
11
+ "directory": "apps/cli"
12
+ },
13
+ "author": "Ritual",
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "bin": {
18
+ "ritual": "./dist/index.js"
19
+ },
20
+ "main": "./dist/index.js",
21
+ "files": [
22
+ "dist",
23
+ "skills",
24
+ "README.md"
25
+ ],
26
+ "scripts": {
27
+ "build:skills": "node scripts/build-skills.js",
28
+ "build:ts": "tsc -p tsconfig.json",
29
+ "build": "pnpm run build:skills && pnpm run build:ts",
30
+ "dev": "tsx src/index.ts",
31
+ "clean": "rm -rf dist skills",
32
+ "typecheck": "tsc --noEmit -p tsconfig.json",
33
+ "test": "jest --passWithNoTests",
34
+ "prepublishOnly": "pnpm run clean && pnpm run build"
35
+ },
36
+ "dependencies": {
37
+ "commander": "^14.0.3",
38
+ "open": "^10.1.0"
39
+ },
40
+ "devDependencies": {
41
+ "@ritual/shared-types": "workspace:^",
42
+ "@types/jest": "^29.5.0",
43
+ "@types/node": "^20.0.0",
44
+ "jest": "^29.7.0",
45
+ "ts-jest": "^29.1.0",
46
+ "tsx": "^4.19.0",
47
+ "typescript": "^5.0.0"
48
+ },
49
+ "engines": {
50
+ "node": ">=20.0.0"
51
+ },
52
+ "keywords": [
53
+ "ritual",
54
+ "mcp",
55
+ "ai-coding-agent",
56
+ "claude-code",
57
+ "cursor",
58
+ "windsurf",
59
+ "kiro",
60
+ "gemini-cli",
61
+ "copilot",
62
+ "codex"
63
+ ],
64
+ "jest": {
65
+ "preset": "ts-jest",
66
+ "testEnvironment": "node",
67
+ "roots": [
68
+ "<rootDir>/src",
69
+ "<rootDir>/test"
70
+ ],
71
+ "testMatch": [
72
+ "**/?(*.)+(spec|test).ts"
73
+ ]
74
+ }
75
+ }
@@ -1,4 +1,4 @@
1
1
  {
2
- "cliVersion": "0.7.11",
3
- "builtAt": "2026-05-14T12:14:29.050Z"
2
+ "cliVersion": "0.7.13",
3
+ "builtAt": "2026-05-15T14:17:47.561Z"
4
4
  }
@@ -197,7 +197,7 @@ Steps:
197
197
  > - {state-specific call-to-action — see table below}
198
198
  >
199
199
  > Recommended: resume one if it matches this work.
200
- > Reply with a number/name to resume, `suggest` to find high-leverage candidates from repo + workspace history, or `proceed` to start fresh.
200
+ > Reply with a number/name to resume, `suggest` to find high-leverage candidates from repo + workspace history, `delete N` to remove a duplicate/misfire, or `proceed` to start fresh.
201
201
 
202
202
  If `raw_input = null`, frame this as the user's no-arg start screen:
203
203
 
@@ -211,6 +211,7 @@ Steps:
211
211
  > Reply with:
212
212
  > - a number/name to resume
213
213
  > - `suggest` to have me look for high-leverage candidates from repo + workspace history
214
+ > - `delete N` to remove a duplicate/misfire from this list (soft-delete; recoverable)
214
215
  > - a feature/problem description to start fresh
215
216
  > - `none` to exit
216
217
 
@@ -285,6 +286,30 @@ Steps:
285
286
 
286
287
  6. **If the user picks "start fresh":** continue to Step 2 normally. The new exploration will sit alongside the existing ones; they're independent rows in the workspace.
287
288
 
289
+ 6a. **If the user picks `delete N` / "remove this from the list":**
290
+
291
+ This path handles duplicates and misfires that pollute the resume picker. Common shape: user accidentally created a near-duplicate exploration (started fresh thinking the original was unrecoverable), or a NOT_STARTED row from a typo / wrong-scope misfire that never converged. Eiman hit this in `nebula` on 2026-05-14 — two `Nerve-center /home dashboard` rows, no way to clear the unwanted one. This option fixes that.
292
+
293
+ Steps:
294
+
295
+ a. **Resolve `N` to an exploration_id.** The user replied `delete 2` referencing the numbered list rendered in step 3. Pick the exploration at that index. If they typed a name instead (`delete "Nerve-center duplicate"`), match by `name` (case-insensitive, exact or prefix).
296
+
297
+ b. **Show the target + ask for explicit confirmation** *(CLI Tenet #2 — single decisive proposal, not a 4-option menu)*:
298
+
299
+ > About to archive: **{name}** ({recommendationCount} rec{s}, {openDeferralsCount} open deferral{s}, last updated {relative time}).
300
+ >
301
+ > This soft-deletes the row — the full record (matters, questions, recs, attestations, decisions) is preserved for audit. The exploration disappears from this and future resume pickers. Restore is admin-only and not exposed in the CLI today.
302
+ >
303
+ > **(y/N)** — y to archive, anything else to cancel.
304
+
305
+ c. **[USER PAUSE]** — wait for `y` / `yes` (case-insensitive). Anything else = cancel back to the picker without calling the tool. Don't lecture; just say "Cancelled. Here's the picker again:" and re-render the menu.
306
+
307
+ d. **Call `mcp__ritual__archive_exploration(exploration_id)`.** On error (404 / 403 / 5xx), surface the failure and re-render the menu — don't silently swallow.
308
+
309
+ e. **Re-render the menu.** After successful archive, refresh the list (call `mcp__ritual__list_explorations` again) and show the updated picker. Lead with: "Archived **{name}**. Updated workspace:" — don't make the user re-derive what happened. Then return to step 4 ([USER PAUSE]) — the user can pick resume / suggest / fresh / `delete M` again.
310
+
311
+ f. **Anti-pattern**: do NOT auto-pick "start fresh" or "resume the survivor" after a delete. The user chose to clean up, not to commit to a next step.
312
+
288
313
  6b. **If the user picks `suggest` / "help me find the highest-leverage thing":**
289
314
 
290
315
  This path is for the "I have context but no concrete problem yet" case. The agent does a light workspace scan FIRST so suggestions land on real codebase and prior-deferral signals, not generic advice. This is **not** focused feature recon because no problem has been selected yet; focused recon still happens after the user picks a candidate.
@@ -1488,7 +1513,11 @@ For each question's loop:
1488
1513
 
1489
1514
  #### Step 9 — Review and accept recommendations (grouped, role-aware)
1490
1515
 
1491
- Call `mcp__ritual__get_recommendations(exploration_id)`. Response is an array of recommendations. Each rec includes:
1516
+ **Use `mcp__ritual__get_recommendations_preview(exploration_id)` for the Step 9.1 landing screen.** It returns a server-rendered preview with `previewText` (terminal-formatted, hard-wrapped at 78 cols — print verbatim), `idMap` (`R1..RN` → uuid lookup for resolving `accept R3` / `detail R7`), `actions` (role-aware structured command list), `categoryGroups` (structured grouped list for non-terminal surfaces), `actionHint`, `scopeLine`, and `totalCount`. The server already handles role detection (admin vs collaborator) and filters out `approved`/`rejected` recs.
1517
+
1518
+ Use `mcp__ritual__get_recommendations(exploration_id)` (the raw array) only when you need fields not in the preview — full `metadata.acceptance_criteria[]`, `metadata.explainability` rationale chain, `metadata.labels[]`, etc. The detail card in 9.3 (`detail R{N}`) loads from the raw tool keyed by the uuid you got from `idMap`.
1519
+
1520
+ Each raw rec includes:
1492
1521
 
1493
1522
  - top-level: `id`, `title`, `content` (summary), `status`, `priority`, `points`, `confidence`
1494
1523
  - `metadata.category.name` — **the load-bearing grouping key** (one rec → one category)
@@ -1496,21 +1525,62 @@ Call `mcp__ritual__get_recommendations(exploration_id)`. Response is an array of
1496
1525
  - `metadata.explainability` — `rationale` (chained `→` arrow string), `faq_references[]`, `problem_alignment`, `inferred_elements`, optional `initial_input_analysis`
1497
1526
  - `metadata.labels[]` — secondary tags
1498
1527
 
1499
- **Role model — load-bearing**: only **admins** can accept recommendations (call `accept_recommendations`). **Collaborators** can read, comment, and proceed to implement, but they cannot move recs from `draft`/`pending_review` to `approved`. Respect this so a collaborator running `/ritual build` doesn't hit a 403 mid-flow and lose context.
1528
+ **Role model — load-bearing**: only **admins** can accept recommendations (call `accept_recommendations`). **Collaborators** can read, comment, and proceed to implement, but they cannot move recs from `draft`/`pending_review` to `approved`. The preview API handles this automatically the `actions` list and `actionHint` are gated on the caller's workspace role; admins see `accept recommended` while everyone else sees `request admin review` plus the optional `continue` (implement-ahead) path. Respect what the preview returns; don't substitute it.
1500
1529
 
1501
1530
  If you don't already know the user's role on this workspace, prefer the workspace member endpoint or cached role from `/ritual init`. When unavailable, ask plainly: *"Are you the workspace admin or a collaborator?"* Do not attempt acceptance blindly unless the user explicitly says to accept.
1502
1531
 
1503
1532
  **Vocabulary**: do NOT use "Reasoning chain" or "reasoning_chain" in user-facing copy. The user-visible label is **"Why this"** — a 4-line Problem / Discovery / Tradeoff / Recommendation breakdown derived from the rationale field. "Reasoning chain" sounds like internal model chain-of-thought; "Why this" is product-native.
1504
1533
 
1505
- ##### 9.1 — Landing screen: grouped category summary + compact scope
1534
+ ##### 9.1 — Landing screen: server-rendered preview (primary path)
1506
1535
 
1507
1536
  The recommendations review is the most-read screen in the whole build flow.
1508
1537
 
1538
+ **Primary path — print the server preview verbatim:**
1539
+
1540
+ ```text
1541
+ 1. Call mcp__ritual__get_recommendations_preview(exploration_id).
1542
+
1543
+ 2. Response shape:
1544
+ {
1545
+ terminalPreviewText: "...", // present for surface=terminal (default)
1546
+ uiPreview: { // always present
1547
+ stage: "recommendations",
1548
+ stageIndex: 4, stageCount: 6,
1549
+ scopeLine, stats, categoryGroups,
1550
+ idMap, actions
1551
+ }
1552
+ }
1553
+
1554
+ 3. Print response.terminalPreviewText VERBATIM. Do not re-render,
1555
+ re-wrap, re-number, or add a leading "Here are your recommendations..."
1556
+ line. The server already laid out the build rail, scope, grouped recs,
1557
+ and role-aware action hint at 78-col wrap.
1558
+
1559
+ 4. Remember response.uiPreview.idMap so you can resolve user input — when
1560
+ they reply `accept R3` or `detail R7`, look up `R{N}` → uuid in
1561
+ idMap and use that uuid in the follow-up MCP call (accept_recommendations,
1562
+ get_recommendations).
1563
+
1564
+ 5. response.uiPreview.actions is for mobile/web button rendering — terminal
1565
+ flow ignores it (action hint copy is already inside terminalPreviewText).
1566
+ Each action carries `style: "primary" | "secondary"` so a non-terminal
1567
+ UI knows which is the call-to-action.
1568
+ ```
1569
+
1570
+ The server controls the rendering shape (category numbering, R-IDs, titles-only, 78-col wrap, role-aware action hint). Your job is to print and look up — not to invent labels, re-group, or add commentary.
1571
+
1572
+ **Fallback path — if the preview tool is unavailable or returns a non-200**: render per the contract block below. The contract is the same shape the server uses, so a mismatch between server-rendered and agent-rendered output is unlikely. The fallback exists for older MCP servers that haven't deployed the preview endpoint yet.
1573
+
1509
1574
  ```text
1510
1575
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1511
- STEP 9.1 RENDERING CONTRACT — non-negotiable
1576
+ STEP 9.1 RENDERING CONTRACT (FALLBACK) — non-negotiable
1512
1577
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1513
1578
 
1579
+ Use this contract ONLY if get_recommendations_preview is unavailable
1580
+ (older MCP server) or returns an error. Otherwise, print the preview
1581
+ verbatim per the Primary path above.
1582
+
1583
+
1514
1584
  Landing view is for SELECTION, not reading. Full prose belongs in 9.3.
1515
1585
 
1516
1586
  ✓ DO:
@@ -2228,6 +2298,7 @@ This subcommand exclusively uses vNext MCP tools, in the order they appear:
2228
2298
  3. `mcp__ritual__list_explorations` (Step 1.5 — resume vs start, with state badges)
2229
2299
  4. `mcp__ritual__suggest_high_leverage_problems` (Step 1.5 step 6b — option 3, "help me find the highest-leverage thing")
2230
2300
  5. `mcp__ritual__check_exploration_overlap` (Step 1.5 step 8 — pre-creation overlap detection before "start fresh")
2301
+ 5a. `mcp__ritual__archive_exploration` (Step 1.5 step 6a — soft-delete a duplicate/misfire when user picks `delete N` from the resume menu)
2231
2302
  6. `mcp__ritual__list_templates` (Step 2)
2232
2303
  7. `mcp__ritual__generate_considerations` (Step 4)
2233
2304
  8. `mcp__ritual__refine_considerations` (Step 4.2, iteration only)
@@ -2255,7 +2326,7 @@ This subcommand exclusively uses vNext MCP tools, in the order they appear:
2255
2326
  24c. `mcp__ritual__list_knowledge_sources` (used inline by Step 3.5 to show already-attached refs on resume; also called by `/ritual context-pulse` CP2 for Reference Grounding count)
2256
2327
  25. `mcp__ritual__sync_implementation` (Step 12)
2257
2328
 
2258
- 31 of the 40 vNext tools. The other 9 (`ping`, `get_exploration`, `list_agentic_runs`, `add_collaborator`, `check_anti_goals`, `query_knowledge_graph`, `get_workspace_overview`, `get_knowledge_source`, `remove_knowledge_source`) are situational, not part of the linear build flow.
2329
+ 32 of the 43 vNext tools. The other 11 (`ping`, `get_exploration`, `list_agentic_runs`, `add_collaborator`, `check_anti_goals`, `query_knowledge_graph`, `get_workspace_overview`, `get_knowledge_source`, `remove_knowledge_source`, `get_recommendation_attestation`, `score_context_pulse`) are situational, not part of the linear build flow.
2259
2330
 
2260
2331
  ### After this subcommand
2261
2332
 
@@ -1,4 +1,4 @@
1
1
  {
2
- "cliVersion": "0.7.11",
3
- "builtAt": "2026-05-14T12:14:29.050Z"
2
+ "cliVersion": "0.7.13",
3
+ "builtAt": "2026-05-15T14:17:47.561Z"
4
4
  }
@@ -197,7 +197,7 @@ Steps:
197
197
  > - {state-specific call-to-action — see table below}
198
198
  >
199
199
  > Recommended: resume one if it matches this work.
200
- > Reply with a number/name to resume, `suggest` to find high-leverage candidates from repo + workspace history, or `proceed` to start fresh.
200
+ > Reply with a number/name to resume, `suggest` to find high-leverage candidates from repo + workspace history, `delete N` to remove a duplicate/misfire, or `proceed` to start fresh.
201
201
 
202
202
  If `raw_input = null`, frame this as the user's no-arg start screen:
203
203
 
@@ -211,6 +211,7 @@ Steps:
211
211
  > Reply with:
212
212
  > - a number/name to resume
213
213
  > - `suggest` to have me look for high-leverage candidates from repo + workspace history
214
+ > - `delete N` to remove a duplicate/misfire from this list (soft-delete; recoverable)
214
215
  > - a feature/problem description to start fresh
215
216
  > - `none` to exit
216
217
 
@@ -285,6 +286,30 @@ Steps:
285
286
 
286
287
  6. **If the user picks "start fresh":** continue to Step 2 normally. The new exploration will sit alongside the existing ones; they're independent rows in the workspace.
287
288
 
289
+ 6a. **If the user picks `delete N` / "remove this from the list":**
290
+
291
+ This path handles duplicates and misfires that pollute the resume picker. Common shape: user accidentally created a near-duplicate exploration (started fresh thinking the original was unrecoverable), or a NOT_STARTED row from a typo / wrong-scope misfire that never converged. Eiman hit this in `nebula` on 2026-05-14 — two `Nerve-center /home dashboard` rows, no way to clear the unwanted one. This option fixes that.
292
+
293
+ Steps:
294
+
295
+ a. **Resolve `N` to an exploration_id.** The user replied `delete 2` referencing the numbered list rendered in step 3. Pick the exploration at that index. If they typed a name instead (`delete "Nerve-center duplicate"`), match by `name` (case-insensitive, exact or prefix).
296
+
297
+ b. **Show the target + ask for explicit confirmation** *(CLI Tenet #2 — single decisive proposal, not a 4-option menu)*:
298
+
299
+ > About to archive: **{name}** ({recommendationCount} rec{s}, {openDeferralsCount} open deferral{s}, last updated {relative time}).
300
+ >
301
+ > This soft-deletes the row — the full record (matters, questions, recs, attestations, decisions) is preserved for audit. The exploration disappears from this and future resume pickers. Restore is admin-only and not exposed in the CLI today.
302
+ >
303
+ > **(y/N)** — y to archive, anything else to cancel.
304
+
305
+ c. **[USER PAUSE]** — wait for `y` / `yes` (case-insensitive). Anything else = cancel back to the picker without calling the tool. Don't lecture; just say "Cancelled. Here's the picker again:" and re-render the menu.
306
+
307
+ d. **Call `mcp__ritual__archive_exploration(exploration_id)`.** On error (404 / 403 / 5xx), surface the failure and re-render the menu — don't silently swallow.
308
+
309
+ e. **Re-render the menu.** After successful archive, refresh the list (call `mcp__ritual__list_explorations` again) and show the updated picker. Lead with: "Archived **{name}**. Updated workspace:" — don't make the user re-derive what happened. Then return to step 4 ([USER PAUSE]) — the user can pick resume / suggest / fresh / `delete M` again.
310
+
311
+ f. **Anti-pattern**: do NOT auto-pick "start fresh" or "resume the survivor" after a delete. The user chose to clean up, not to commit to a next step.
312
+
288
313
  6b. **If the user picks `suggest` / "help me find the highest-leverage thing":**
289
314
 
290
315
  This path is for the "I have context but no concrete problem yet" case. The agent does a light workspace scan FIRST so suggestions land on real codebase and prior-deferral signals, not generic advice. This is **not** focused feature recon because no problem has been selected yet; focused recon still happens after the user picks a candidate.
@@ -1488,7 +1513,11 @@ For each question's loop:
1488
1513
 
1489
1514
  #### Step 9 — Review and accept recommendations (grouped, role-aware)
1490
1515
 
1491
- Call `mcp__ritual__get_recommendations(exploration_id)`. Response is an array of recommendations. Each rec includes:
1516
+ **Use `mcp__ritual__get_recommendations_preview(exploration_id)` for the Step 9.1 landing screen.** It returns a server-rendered preview with `previewText` (terminal-formatted, hard-wrapped at 78 cols — print verbatim), `idMap` (`R1..RN` → uuid lookup for resolving `accept R3` / `detail R7`), `actions` (role-aware structured command list), `categoryGroups` (structured grouped list for non-terminal surfaces), `actionHint`, `scopeLine`, and `totalCount`. The server already handles role detection (admin vs collaborator) and filters out `approved`/`rejected` recs.
1517
+
1518
+ Use `mcp__ritual__get_recommendations(exploration_id)` (the raw array) only when you need fields not in the preview — full `metadata.acceptance_criteria[]`, `metadata.explainability` rationale chain, `metadata.labels[]`, etc. The detail card in 9.3 (`detail R{N}`) loads from the raw tool keyed by the uuid you got from `idMap`.
1519
+
1520
+ Each raw rec includes:
1492
1521
 
1493
1522
  - top-level: `id`, `title`, `content` (summary), `status`, `priority`, `points`, `confidence`
1494
1523
  - `metadata.category.name` — **the load-bearing grouping key** (one rec → one category)
@@ -1496,21 +1525,62 @@ Call `mcp__ritual__get_recommendations(exploration_id)`. Response is an array of
1496
1525
  - `metadata.explainability` — `rationale` (chained `→` arrow string), `faq_references[]`, `problem_alignment`, `inferred_elements`, optional `initial_input_analysis`
1497
1526
  - `metadata.labels[]` — secondary tags
1498
1527
 
1499
- **Role model — load-bearing**: only **admins** can accept recommendations (call `accept_recommendations`). **Collaborators** can read, comment, and proceed to implement, but they cannot move recs from `draft`/`pending_review` to `approved`. Respect this so a collaborator running `/ritual build` doesn't hit a 403 mid-flow and lose context.
1528
+ **Role model — load-bearing**: only **admins** can accept recommendations (call `accept_recommendations`). **Collaborators** can read, comment, and proceed to implement, but they cannot move recs from `draft`/`pending_review` to `approved`. The preview API handles this automatically the `actions` list and `actionHint` are gated on the caller's workspace role; admins see `accept recommended` while everyone else sees `request admin review` plus the optional `continue` (implement-ahead) path. Respect what the preview returns; don't substitute it.
1500
1529
 
1501
1530
  If you don't already know the user's role on this workspace, prefer the workspace member endpoint or cached role from `/ritual init`. When unavailable, ask plainly: *"Are you the workspace admin or a collaborator?"* Do not attempt acceptance blindly unless the user explicitly says to accept.
1502
1531
 
1503
1532
  **Vocabulary**: do NOT use "Reasoning chain" or "reasoning_chain" in user-facing copy. The user-visible label is **"Why this"** — a 4-line Problem / Discovery / Tradeoff / Recommendation breakdown derived from the rationale field. "Reasoning chain" sounds like internal model chain-of-thought; "Why this" is product-native.
1504
1533
 
1505
- ##### 9.1 — Landing screen: grouped category summary + compact scope
1534
+ ##### 9.1 — Landing screen: server-rendered preview (primary path)
1506
1535
 
1507
1536
  The recommendations review is the most-read screen in the whole build flow.
1508
1537
 
1538
+ **Primary path — print the server preview verbatim:**
1539
+
1540
+ ```text
1541
+ 1. Call mcp__ritual__get_recommendations_preview(exploration_id).
1542
+
1543
+ 2. Response shape:
1544
+ {
1545
+ terminalPreviewText: "...", // present for surface=terminal (default)
1546
+ uiPreview: { // always present
1547
+ stage: "recommendations",
1548
+ stageIndex: 4, stageCount: 6,
1549
+ scopeLine, stats, categoryGroups,
1550
+ idMap, actions
1551
+ }
1552
+ }
1553
+
1554
+ 3. Print response.terminalPreviewText VERBATIM. Do not re-render,
1555
+ re-wrap, re-number, or add a leading "Here are your recommendations..."
1556
+ line. The server already laid out the build rail, scope, grouped recs,
1557
+ and role-aware action hint at 78-col wrap.
1558
+
1559
+ 4. Remember response.uiPreview.idMap so you can resolve user input — when
1560
+ they reply `accept R3` or `detail R7`, look up `R{N}` → uuid in
1561
+ idMap and use that uuid in the follow-up MCP call (accept_recommendations,
1562
+ get_recommendations).
1563
+
1564
+ 5. response.uiPreview.actions is for mobile/web button rendering — terminal
1565
+ flow ignores it (action hint copy is already inside terminalPreviewText).
1566
+ Each action carries `style: "primary" | "secondary"` so a non-terminal
1567
+ UI knows which is the call-to-action.
1568
+ ```
1569
+
1570
+ The server controls the rendering shape (category numbering, R-IDs, titles-only, 78-col wrap, role-aware action hint). Your job is to print and look up — not to invent labels, re-group, or add commentary.
1571
+
1572
+ **Fallback path — if the preview tool is unavailable or returns a non-200**: render per the contract block below. The contract is the same shape the server uses, so a mismatch between server-rendered and agent-rendered output is unlikely. The fallback exists for older MCP servers that haven't deployed the preview endpoint yet.
1573
+
1509
1574
  ```text
1510
1575
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1511
- STEP 9.1 RENDERING CONTRACT — non-negotiable
1576
+ STEP 9.1 RENDERING CONTRACT (FALLBACK) — non-negotiable
1512
1577
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
1513
1578
 
1579
+ Use this contract ONLY if get_recommendations_preview is unavailable
1580
+ (older MCP server) or returns an error. Otherwise, print the preview
1581
+ verbatim per the Primary path above.
1582
+
1583
+
1514
1584
  Landing view is for SELECTION, not reading. Full prose belongs in 9.3.
1515
1585
 
1516
1586
  ✓ DO:
@@ -2228,6 +2298,7 @@ This subcommand exclusively uses vNext MCP tools, in the order they appear:
2228
2298
  3. `mcp__ritual__list_explorations` (Step 1.5 — resume vs start, with state badges)
2229
2299
  4. `mcp__ritual__suggest_high_leverage_problems` (Step 1.5 step 6b — option 3, "help me find the highest-leverage thing")
2230
2300
  5. `mcp__ritual__check_exploration_overlap` (Step 1.5 step 8 — pre-creation overlap detection before "start fresh")
2301
+ 5a. `mcp__ritual__archive_exploration` (Step 1.5 step 6a — soft-delete a duplicate/misfire when user picks `delete N` from the resume menu)
2231
2302
  6. `mcp__ritual__list_templates` (Step 2)
2232
2303
  7. `mcp__ritual__generate_considerations` (Step 4)
2233
2304
  8. `mcp__ritual__refine_considerations` (Step 4.2, iteration only)
@@ -2255,7 +2326,7 @@ This subcommand exclusively uses vNext MCP tools, in the order they appear:
2255
2326
  24c. `mcp__ritual__list_knowledge_sources` (used inline by Step 3.5 to show already-attached refs on resume; also called by `/ritual context-pulse` CP2 for Reference Grounding count)
2256
2327
  25. `mcp__ritual__sync_implementation` (Step 12)
2257
2328
 
2258
- 31 of the 40 vNext tools. The other 9 (`ping`, `get_exploration`, `list_agentic_runs`, `add_collaborator`, `check_anti_goals`, `query_knowledge_graph`, `get_workspace_overview`, `get_knowledge_source`, `remove_knowledge_source`) are situational, not part of the linear build flow.
2329
+ 32 of the 43 vNext tools. The other 11 (`ping`, `get_exploration`, `list_agentic_runs`, `add_collaborator`, `check_anti_goals`, `query_knowledge_graph`, `get_workspace_overview`, `get_knowledge_source`, `remove_knowledge_source`, `get_recommendation_attestation`, `score_context_pulse`) are situational, not part of the linear build flow.
2259
2330
 
2260
2331
  ### After this subcommand
2261
2332
 
@@ -1,4 +1,4 @@
1
1
  {
2
- "cliVersion": "0.7.11",
3
- "builtAt": "2026-05-14T12:14:29.050Z"
2
+ "cliVersion": "0.7.13",
3
+ "builtAt": "2026-05-15T14:17:47.561Z"
4
4
  }