ultra-builder-pro-cli 0.5.3 → 0.6.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 (47) hide show
  1. package/CHANGELOG.md +31 -6
  2. package/README.md +14 -16
  3. package/adapters/_shared/codex-assets.cjs +32 -151
  4. package/adapters/_shared/frontmatter.cjs +2 -2
  5. package/adapters/_shared/handbook.cjs +3 -3
  6. package/adapters/_shared/path-rewrite.cjs +0 -3
  7. package/adapters/_shared/runtime-assets.cjs +11 -4
  8. package/adapters/_shared/tests/path-rewrite.test.cjs +1 -3
  9. package/adapters/_shared/tests/resolve-target.test.cjs +1 -11
  10. package/adapters/_shared/tests/runtime-assets.test.cjs +5 -6
  11. package/adapters/opencode.js +1 -6
  12. package/adapters/tests/claude.test.cjs +1 -4
  13. package/adapters/tests/codex.test.cjs +5 -6
  14. package/adapters/tests/opencode.test.cjs +1 -2
  15. package/bin/install.js +6 -9
  16. package/bin/orchestrator.js +11 -4
  17. package/docs/AGENT-CONTEXT.md +4 -5
  18. package/docs/ARCHITECTURE.md +3 -4
  19. package/docs/LEGACY-HERMES.md +5 -81
  20. package/docs/PLAN.zh-CN.md +35 -42
  21. package/docs/ROADMAP.md +3 -3
  22. package/docs/RUNTIME-COMPAT-MATRIX.md +61 -60
  23. package/mcp-server/lib/pricing.cjs +0 -6
  24. package/mcp-server/lib/state-ops.cjs +7 -0
  25. package/mcp-server/lib/telemetry.cjs +4 -0
  26. package/mcp-server/tests/server-contract.test.cjs +17 -0
  27. package/mcp-server/tests/state-ops.test.cjs +23 -0
  28. package/mcp-server/tests/telemetry.test.cjs +14 -0
  29. package/orchestrator/dispatch-rules.cjs +15 -4
  30. package/orchestrator/tests/daemon.test.cjs +13 -12
  31. package/orchestrator/tests/dispatch-rules.test.cjs +12 -10
  32. package/package.json +3 -5
  33. package/skills/ultra-init/SKILL.md +0 -1
  34. package/skills/ultra-verify/SKILL.md +22 -41
  35. package/skills/ultra-verify/evals/evals.json +22 -24
  36. package/skills/ultra-verify/references/confidence-system.md +15 -32
  37. package/skills/ultra-verify/references/cross-verify-modes.md +14 -59
  38. package/skills/ultra-verify/scripts/verify_wait.py +44 -81
  39. package/spec/mcp-tools.yaml +3 -3
  40. package/spec/schemas/skill-manifest.schema.json +2 -2
  41. package/spec/schemas/state-db.sql +2 -2
  42. package/adapters/_shared/md-to-toml.cjs +0 -54
  43. package/adapters/_shared/tests/md-to-toml.test.cjs +0 -48
  44. package/adapters/gemini.js +0 -204
  45. package/adapters/tests/gemini.test.cjs +0 -112
  46. package/skills/gemini-collab/SKILL.md +0 -51
  47. package/skills/gemini-collab/evals/evals.json +0 -42
package/CHANGELOG.md CHANGED
@@ -7,6 +7,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.6.0] — 2026-07-17
11
+
12
+ ### Changed
13
+
14
+ - Reduced the supported host matrix to Claude Code, OpenCode, and Codex.
15
+ - Reworked `ultra-verify` into independent two-model verification: the current
16
+ host remains primary, one read-only external advisor supplies a second view,
17
+ and evidence rather than model voting determines confidence.
18
+ - Restricted orchestrator routing, MCP session/event inputs, telemetry writes,
19
+ state schema enums, installer flags, package metadata, and handbooks to the
20
+ three supported runtimes.
21
+
22
+ ### Removed
23
+
24
+ - Removed the Gemini CLI adapter, `--gemini` installer surface, extension and
25
+ conformance packaging, pricing entries, `gemini-collab`, and all active Ultra
26
+ prompts and documentation that offered Gemini as an advisor or runtime.
27
+
28
+ ### Fixed
29
+
30
+ - Added a retirement regression contract so unsupported runtimes cannot
31
+ re-enter active source, package, schema, prompt, or generated plugin surfaces.
32
+ - Rejects unsupported runtime labels before state, event, or telemetry writes,
33
+ including old databases whose historical SQLite constraints were broader.
34
+
10
35
  ## [0.5.3] — 2026-07-17
11
36
 
12
37
  ### Fixed
@@ -59,7 +84,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
59
84
 
60
85
  - Added first-class native Claude Code and OpenCode plugin builders alongside
61
86
  the Codex personal plugin. All hosts build from one explicit runtime asset
62
- allowlist; Gemini remains a compatibility extension using the same boundary.
87
+ allowlist; the then-supported compatibility extension used the same boundary.
63
88
  - Added `ubp-handbook` for previewed, backed-up managed-block integration with
64
89
  user-level Claude `CLAUDE.md`, Codex `AGENTS.md`, and OpenCode `AGENTS.md`.
65
90
  - Added `ultra-tools legacy-memory inspect|archive|prune`; prune requires the
@@ -87,7 +112,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
87
112
  with the npm package, and fixed `session.subscribe_events` sid filtering.
88
113
  - Aligned session/plan input schemas with runtime behavior, including circuit
89
114
  breaker output, session spawn intent semantics, and removal of ignored inputs.
90
- - Bundled Gemini's compatibility MCP runtime durably and restored project-local
115
+ - Bundled the compatibility MCP runtime durably and restored project-local
91
116
  `.ultra/state.db` ownership across all adapters.
92
117
  - Exported the documented `ultra-tools` executable and included every README
93
118
  documentation target in the npm tarball.
@@ -193,8 +218,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
193
218
  - **Phase 4.6b — full conformance suite** (D45): 4 runtime × 5 capability
194
219
  (command / skills / hooks / MCP + no `env._source` leak / install idempotency)
195
220
  = 20 additional conformance tests; table-driven `resolve-target.test.cjs`
196
- (21 tests) covering `configDir > env > home/cwd` precedence + Gemini
197
- extensionRoot append; schema bump 5.2 → 7.1 alongside memory store.
221
+ (21 tests) covering `configDir > env > home/cwd` precedence and extension
222
+ root resolution; schema bump 5.2 → 7.1 alongside memory store.
198
223
 
199
224
  ### Changed
200
225
 
@@ -213,9 +238,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
213
238
  admission control with takeover / resume / abandon strategies (D33).
214
239
  - **Phase 4 — cross-runtime distribution** (D41, `5aa1fd0`): shared adapter
215
240
  toolkit (`adapters/_shared/` — file-ops / frontmatter / settings-merge /
216
- path-rewrite / md-to-toml); 4 runtime adapters (Claude sentinel-block
241
+ path-rewrite / md-to-toml); the initial runtime adapters (Claude sentinel-block
217
242
  settings.json merge; OpenCode `opencode.json.mcp`; Codex `config.toml`
218
- marker-block + prompts/; Gemini `extensions/ultra-builder-pro/` package);
243
+ marker-block + prompts/; plus the then-supported compatibility package);
219
244
  `docs/RUNTIME-COMPAT-MATRIX.md` with 10-section capability matrix;
220
245
  install / uninstall round-trip tests + idempotency.
221
246
  - **Phase 3 — thin-shell commands** (D40, `b3d1797`): 9 commands migrated
package/README.md CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  Multi-runtime plugin suite + autonomous coding factory for the Ultra Builder Pro
4
4
  agent engineering system. It ships native plugins for **Claude Code · OpenCode ·
5
- Codex**, retains a compatibility adapter for Gemini CLI, and orchestrates PRD →
5
+ Codex** and orchestrates PRD →
6
6
  dependency graph → parallel session execution → auto-merge with a single
7
7
  authoritative `.ultra/state.db`.
8
8
 
9
9
  <div align="center">
10
10
 
11
- [![Version](https://img.shields.io/badge/version-0.5.3-blue)](./CHANGELOG.md)
11
+ [![Version](https://img.shields.io/badge/version-0.6.0-blue)](./CHANGELOG.md)
12
12
  [![Tests](https://img.shields.io/badge/tests-passing-brightgreen)](#verification)
13
13
  [![License: MIT](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
14
14
  [![Node](https://img.shields.io/badge/node-%E2%89%A522-informational)](./package.json)
@@ -23,7 +23,7 @@ authoritative `.ultra/state.db`.
23
23
 
24
24
  - **Builds host-native plugins from one allowlist.** Claude Code, OpenCode, and
25
25
  Codex receive their own command/skill, agent, hook, and MCP representation.
26
- Gemini remains a compatibility adapter; uninstall is symmetric.
26
+ Install and uninstall are symmetric on every supported host.
27
27
  - **Shares state across runtimes.** `.ultra/state.db` (SQLite + WAL) is the
28
28
  authoritative source for tasks, sessions, events, and telemetry. `tasks.json`
29
29
  and context markdown are generated projections, not handwritten.
@@ -43,7 +43,6 @@ authoritative `.ultra/state.db`.
43
43
  npx ultra-builder-pro-cli --claude --local
44
44
  npx ultra-builder-pro-cli --opencode --local
45
45
  npx ultra-builder-pro-cli --codex --local
46
- npx ultra-builder-pro-cli --gemini --local
47
46
 
48
47
  # Or blanket-install to every supported runtime you have
49
48
  npx ultra-builder-pro-cli --all --local
@@ -59,8 +58,7 @@ After install, start a new host session/task and point it at the project.
59
58
  Claude Code and OpenCode expose native command forms. Codex exposes the same workflows as namespaced plugin
60
59
  skills such as `$ultra-builder-pro:ultra-init`, `$ultra-builder-pro:ultra-plan`,
61
60
  and `$ultra-builder-pro:ultra-dev`; `command-map.json` records the nine legacy
62
- command mappings (`ultra-review` remains a directly invocable skill). Gemini
63
- retains its compatibility command form.
61
+ command mappings (`ultra-review` remains a directly invocable skill).
64
62
  See [`docs/RUNTIME-COMPAT-MATRIX.md`](./docs/RUNTIME-COMPAT-MATRIX.md)
65
63
  for per-runtime capabilities.
66
64
 
@@ -85,15 +83,15 @@ deployment, skill-discovery, and framework guidance belong to their original plu
85
83
 
86
84
  ## Runtime capability matrix
87
85
 
88
- | Feature | Claude Code | OpenCode | Codex CLI | Gemini CLI |
89
- |------------------------------|:-----------:|:--------:|:---------:|:----------:|
90
- | Custom commands | ✅ | ✅ | ✅ | ✅ |
91
- | Skill loader | ✅ | ✅ | ✅ (personal plugin) | ✅ |
92
- | MCP server (stdio) | ✅ | ✅ | ✅ (plugin `.mcp.json`) | ✅ |
93
- | Workflow hooks | ✅ (native plugin) | ✅ (native JS plugin) | ✅ (native plugin) | ⚠︎ compatibility only |
94
- | Sub-agents | ✅ | ✅ | ✅ (9 native TOML agents) | ⚠︎ |
95
- | Session worktree isolation | ✅ (all runtimes; driven by `orchestrator/session-runner.cjs`) | ✅ | ✅ | ✅ |
96
- | Parallel dispatch + auto-merge | ✅ (`ubp-orchestrator run`) | ✅ | ✅ | ✅ |
86
+ | Feature | Claude Code | OpenCode | Codex CLI |
87
+ |------------------------------|:-----------:|:--------:|:---------:|
88
+ | Custom commands | ✅ | ✅ | ✅ |
89
+ | Skill loader | ✅ | ✅ | ✅ (personal plugin) |
90
+ | MCP server (stdio) | ✅ | ✅ | ✅ (plugin `.mcp.json`) |
91
+ | Workflow hooks | ✅ (native plugin) | ✅ (native JS plugin) | ✅ (native plugin) |
92
+ | Sub-agents | ✅ | ✅ | ✅ (9 native TOML agents) |
93
+ | Session worktree isolation | ✅ (driven by `orchestrator/session-runner.cjs`) | ✅ | ✅ |
94
+ | Parallel dispatch + auto-merge | ✅ (`ubp-orchestrator run`) | ✅ | ✅ |
97
95
 
98
96
  Full details in [`docs/RUNTIME-COMPAT-MATRIX.md`](./docs/RUNTIME-COMPAT-MATRIX.md)
99
97
  (10 sections, with per-runtime deviations called out).
@@ -124,7 +122,7 @@ Or let the skills drive it. In Codex, invoke
124
122
 
125
123
  | Binary | Purpose |
126
124
  |--------|---------|
127
- | `ultra-builder-pro-cli` / `ubp` | Installer — `--claude / --opencode / --codex / --gemini / --all`, `--local / --global`, `--uninstall`, `--skip-rtk` |
125
+ | `ultra-builder-pro-cli` / `ubp` | Installer — `--claude / --opencode / --codex / --all`, `--local / --global`, `--uninstall`, `--skip-rtk` |
128
126
  | `ubp-orchestrator` | Session dispatch daemon — `run`, `start`, `stop`, `status` |
129
127
  | `ultra-tools` | State-layer CLI — `task`, `session`, `status`, `db`, `migrate`; explicit `legacy-memory` archive/prune migration |
130
128
  | `ubp-handbook` | Preview/apply the managed Ultra contract in `CLAUDE.md` / `AGENTS.md`, with backup |
@@ -66,7 +66,6 @@ const COMMAND_NAMES = Object.freeze(CORE_PUBLIC_SKILLS.filter((name) => name !==
66
66
  const SKILL_REFERENCE_NAMES = Object.freeze([
67
67
  ...COMMAND_NAMES,
68
68
  'cc-collab',
69
- 'gemini-collab',
70
69
  'ultra-review',
71
70
  'ultra-verify',
72
71
  ]);
@@ -119,52 +118,12 @@ Do not call native Codex subagents through this skill; use Codex subagent orches
119
118
  parallel work and reserve \`cc-collab\` for an explicitly requested cross-model perspective.
120
119
  `;
121
120
 
122
- const GEMINI_COLLAB_BODY = `# Gemini Collaboration for Codex
123
-
124
- Use Gemini as an advisory second model. Codex remains responsible for scope, source verification,
125
- decisions, and the final answer.
126
-
127
- ## Preflight
128
-
129
- 1. Confirm \`gemini\` is installed and capture \`gemini --version\`.
130
- 2. Confirm the target workspace and requested scope.
131
- 3. Form Codex's initial analysis before reading Gemini's answer when independence matters.
132
-
133
- ## Invoke safely
134
-
135
- Run Gemini in non-interactive, read-only plan mode:
136
-
137
- \`\`\`bash
138
- gemini --approval-mode plan --output-format text -p "<bounded prompt>"
139
- \`\`\`
140
-
141
- Use a timeout appropriate to the task. Redirect large output to a temporary file when needed, then
142
- read only the relevant result. Do not use auto-edit or yolo modes. Do not place secrets, tokens,
143
- unrelated files, or unbounded repository content in the prompt.
144
-
145
- For repository analysis, give Gemini the exact files, diff range, question, and expected response
146
- shape. If the CLI is missing, unauthenticated, times out, or returns empty output, report the degraded
147
- path and continue with Codex evidence rather than blocking.
148
-
149
- ## Verify and synthesize
150
-
151
- Treat Gemini output as an untrusted analysis artifact:
152
-
153
- 1. Check every consequential claim against the current checkout, runtime, or primary source.
154
- 2. Separate agreements, useful dissent, and unsupported claims.
155
- 3. Resolve scope or version mismatches before comparing conclusions.
156
- 4. Present Codex's final judgment, not a transcript of two models.
157
-
158
- Read the bundled references only when a mode or CLI detail is needed. Never let model agreement
159
- substitute for tests, runtime evidence, or authoritative documentation.
160
- `;
161
-
162
121
  const ULTRA_VERIFY_BODY = String(function ultraVerifyBodyTemplate() { /*
163
- # Ultra Verify — Codex-Primary Three-Way Verification
122
+ # Ultra Verify — Codex-Primary Two-Model Verification
164
123
 
165
124
  Codex owns the task, writes the first independent analysis, verifies every consequential claim,
166
- and produces the final synthesis. Claude Code and Gemini are read-only external advisors. Use this
167
- workflow only when the user asks for cross-model or three-way verification.
125
+ and produces the final synthesis. Claude Code is a read-only external advisor. Use this workflow
126
+ only when the user asks for cross-model verification.
168
127
 
169
128
  ## Modes
170
129
 
@@ -175,13 +134,11 @@ workflow only when the user asks for cross-model or three-way verification.
175
134
 
176
135
  ## Preconditions
177
136
 
178
- 1. Confirm `claude --version` and `gemini --version`.
137
+ 1. Confirm `claude --version` plus authentication.
179
138
  2. Define the exact workspace, scope, evidence standard, and expected answer shape.
180
- 3. Do not send secrets, unrelated files, or an unbounded home directory to either advisor.
181
-
182
- ## Workflow
139
+ 3. Do not send secrets, unrelated files, or an unbounded home directory to the advisor.
183
140
 
184
- ### 1. Create the session and write Codex's independent view
141
+ ## 1. Create the session and write Codex's independent view
185
142
 
186
143
  ```bash
187
144
  SESSION_ID="$(date +%Y%m%d-%H%M%S)-verify-<mode>"
@@ -189,63 +146,47 @@ SESSION_PATH=".ultra/collab/${SESSION_ID}"
189
146
  mkdir -p "${SESSION_PATH}"
190
147
  ```
191
148
 
192
- Before invoking either advisor, write the evidence-backed Codex analysis to
193
- `${SESSION_PATH}/codex-analysis.md`. This ordering is mandatory because it prevents the external
194
- answers from priming the primary analysis.
195
-
196
- ### 2. Launch Claude Code and Gemini concurrently
149
+ Write the evidence-backed Codex analysis to `${SESSION_PATH}/codex-analysis.md` before reading
150
+ the external answer. Record the mode, scope, checkout, and evidence boundary.
197
151
 
198
- Give both advisors the same bounded raw question and evidence, without Codex's conclusions.
152
+ ## 2. Launch Claude Code read-only
199
153
 
200
- Claude Code:
154
+ Give Claude Code the bounded raw question and evidence without Codex's conclusions.
201
155
 
202
156
  ```bash
203
- claude --safe-mode -p "<BOUNDED_PROMPT>" \\
204
- --permission-mode plan \\
205
- --tools "Read,Grep,Glob,Bash" \\
206
- --output-format text \\
207
- --no-session-persistence \\
208
- > "${SESSION_PATH}/claude-output.md" \\
157
+ claude --safe-mode -p "<BOUNDED_PROMPT>" \
158
+ --permission-mode plan \
159
+ --tools "Read,Grep,Glob,Bash" \
160
+ --output-format text \
161
+ --no-session-persistence \
162
+ > "${SESSION_PATH}/claude-output.md" \
209
163
  2> "${SESSION_PATH}/claude-error.log"
210
164
  ```
211
165
 
212
- Gemini:
213
-
214
- ```bash
215
- gemini --approval-mode plan --output-format text -p "<BOUNDED_PROMPT>" \\
216
- > "${SESSION_PATH}/gemini-output.md" \\
217
- 2> "${SESSION_PATH}/gemini-error.log"
218
- ```
219
-
220
- Start the two commands with parallel `exec_command` calls and a short initial yield. If a command
221
- returns a live session id, poll it with `write_stdin` in bounded intervals. Do not use YOLO,
222
- auto-edit, permission bypass, or write-capable external tools.
166
+ Run the command in a yielded shell session. Do not enable permission bypass, mutation tools,
167
+ background writes, or session persistence.
223
168
 
224
- ### 3. Collect only completed outputs
169
+ ## 3. Collect completed output
225
170
 
226
- Wait for both CLI sessions to finish or reach their explicit timeout. The bundled
227
- `scripts/verify_wait.py` can verify file stability for automation, but Codex must not perform one
228
- blocking wait longer than 60 seconds. Read an output only when it is non-empty; retain the matching
229
- error log as evidence when a CLI fails.
171
+ The bundled `scripts/verify_wait.py` checks output stability. Poll yielded sessions in bounded
172
+ intervals and never hold one blocking tool call longer than 60 seconds. Read the output only when
173
+ it is non-empty; retain the error log when the advisor fails.
230
174
 
231
- ### 4. Verify and synthesize
175
+ ## 4. Verify and synthesize
232
176
 
233
- Compare `codex-analysis.md`, `claude-output.md`, and `gemini-output.md`:
177
+ Compare `codex-analysis.md` and `claude-output.md`:
234
178
 
235
179
  1. Verify claims against the current checkout, runtime, tests, or primary documentation.
236
- 2. Separate consensus, majority views, useful dissent, and unsupported assertions.
237
- 3. Explain scope, version, or assumption differences before scoring agreement.
180
+ 2. Separate verified agreement, useful dissent, and unsupported assertions.
181
+ 3. Explain scope, version, or assumption differences before judging the result.
238
182
  4. Write `${SESSION_PATH}/synthesis.md` and `metadata.json`, then present one Codex-owned answer.
239
183
 
240
- Use the bundled confidence rules. Three agreeing, independently verified views are consensus; two
241
- are a majority; three materially different answers are no consensus and require decomposition or
242
- more evidence. Model agreement never overrides failing tests or authoritative runtime evidence.
184
+ Model agreement never overrides failing tests or authoritative runtime evidence.
243
185
 
244
186
  ## Degraded operation
245
187
 
246
- - One advisor fails: continue with Codex plus the available advisor and name the missing view.
247
- - Both advisors fail: return Codex-only analysis with an explicit single-source warning.
248
- - Never block the user's task solely because an external CLI is absent, unauthenticated, or slow.
188
+ - Advisor failure: return Codex-only analysis with an explicit single-source warning.
189
+ - Never block the user's task solely because the external CLI is absent, unauthenticated, or slow.
249
190
 
250
191
  ## Session files
251
192
 
@@ -254,70 +195,16 @@ more evidence. Model agreement never overrides failing tests or authoritative ru
254
195
  codex-analysis.md
255
196
  claude-output.md
256
197
  claude-error.log
257
- gemini-output.md
258
- gemini-error.log
259
198
  metadata.json
260
199
  synthesis.md
261
200
  ```
262
201
 
263
- Read the bundled references for mode-specific prompts, scoring, metadata, and automation details.
264
- */ }).match(/\/\*([\s\S]*?)\*\//)[1].trim();
265
-
266
- const ULTRA_VERIFY_FLOW = String(function ultraVerifyFlowTemplate() { /*
267
- # Codex-Native Orchestration Flow
268
-
269
- ## 1. Primary analysis
270
-
271
- Create `.ultra/collab/<SESSION_ID>/` and write `codex-analysis.md` before reading any external
272
- answer. Record the mode, scope, checkout, and evidence boundary.
273
-
274
- ## 2. Parallel advisors
275
-
276
- Launch Claude Code in `--safe-mode --permission-mode plan` and Gemini in
277
- `--approval-mode plan` through separate `exec_command` calls. Redirect their output to
278
- `claude-output.md` and `gemini-output.md`. If a call yields a session id, poll with
279
- `write_stdin` in bounded intervals; do not grant either advisor mutation authority.
280
-
281
- ## 3. Completion gate
282
-
283
- Proceed only after both sessions have completed or timed out. For automation, run:
284
-
285
- ```bash
286
- python3 ~/plugins/ultra-builder-pro/skills/ultra-verify/scripts/verify_wait.py \\
287
- "${SESSION_PATH}" --timeout 1200
288
- ```
289
-
290
- Run the waiter as a yielded exec session and poll it; never hold one blocking tool call for more
291
- than 60 seconds. Its JSON reports `claude` and `gemini` as `complete`, `failed`, `empty`, or
292
- `pending`.
293
-
294
- ## 4. Synthesis
295
-
296
- Read `codex-analysis.md` plus each completed advisor output. Verify consequential claims, compute
297
- consensus using `confidence-system.md`, and write `synthesis.md` plus:
298
-
299
- ```json
300
- {
301
- "id": "<SESSION_ID>",
302
- "agent": "ultra-verify",
303
- "mode": "<mode>",
304
- "models": {"codex": "<primary>", "claude": "<advisor>", "gemini": "<advisor>"},
305
- "scope": "<scope>",
306
- "timestamp": "<ISO 8601>",
307
- "confidence": "<consensus|majority|no_consensus>",
308
- "degraded": false
309
- }
310
- ```
311
-
312
- If one advisor fails, cap the result at majority and name the missing perspective. If both fail,
313
- set `degraded: true`, `agents_responded: ["codex"]`, and mark the result single-source.
202
+ Read the bundled references for mode-specific evidence and confidence guidance.
314
203
  */ }).match(/\/\*([\s\S]*?)\*\//)[1].trim();
315
-
316
204
  function titleCase(name) {
317
205
  const special = {
318
206
  'ai-collab-base': 'AI Collaboration Base',
319
207
  'cc-collab': 'Claude Code Collaboration',
320
- 'gemini-collab': 'Gemini Collaboration',
321
208
  'use-railway': 'Use Railway',
322
209
  };
323
210
  if (special[name]) return special[name];
@@ -600,8 +487,6 @@ and does not require an interactive MCP or legacy CLI menu.
600
487
  }
601
488
 
602
489
  function adaptUltraVerifyAsset(input, rel) {
603
- if (rel === path.join('references', 'orchestration-flow.md')) return ULTRA_VERIFY_FLOW;
604
-
605
490
  let text = adaptHostText(String(input), '');
606
491
  if (rel === path.join('scripts', 'verify_wait.py')) {
607
492
  text = text.replaceAll('Codex', 'Claude Code');
@@ -621,7 +506,6 @@ function adaptUltraVerifyAsset(input, rel) {
621
506
  text = text.replaceAll('"codex": "<model>"', '"claude": "<advisor>"');
622
507
  text = text.replaceAll('["claude"]', '["codex"]');
623
508
  text = text.replaceAll('Claude Code-only', 'Codex-only');
624
- text = text.replaceAll('Gemini and Claude Code in parallel (native parallel execution)', 'Claude Code and Gemini concurrently');
625
509
  text = text.replaceAll('run_in_background', 'native concurrent execution');
626
510
  text = text.replaceAll('Bash tool', '`exec_command`');
627
511
  text = text.replaceAll('Read tool', 'targeted file reads');
@@ -661,7 +545,7 @@ function adaptHostText(input, skillName = '') {
661
545
  text = adaptCodexPrimaryText(text, skillName);
662
546
  }
663
547
 
664
- if (skillName === 'gemini-collab' || skillName === 'ai-collab-base') {
548
+ if (skillName === 'ai-collab-base') {
665
549
  text = text.replaceAll("Claude's", "Codex's");
666
550
  text = text.replaceAll('Claude-only', 'Codex-only');
667
551
  text = text.replaceAll('Claude ', 'Codex ');
@@ -716,8 +600,7 @@ function adaptHostText(input, skillName = '') {
716
600
  function adaptedDescription(sourceDescription, targetName) {
717
601
  const special = {
718
602
  'cc-collab': 'Ask Claude Code for an independent read-only analysis while Codex owns verification and synthesis. Use only when the user explicitly requests CC or Claude Code collaboration.',
719
- 'gemini-collab': 'Ask Gemini CLI for an independent read-only analysis while Codex verifies and synthesizes. Use only when the user explicitly requests Gemini collaboration.',
720
- 'ultra-verify': 'Run Codex-primary three-way verification with read-only Claude Code and Gemini advisors, then verify and synthesize the evidence.',
603
+ 'ultra-verify': 'Run Codex-primary two-model verification with a read-only Claude Code advisor, then verify and synthesize the evidence.',
721
604
  'ultra-dev': 'Execute one Ultra task with Codex-native TDD, persistent task.update state, workflow checkpoints, and the native Ultra review agents.',
722
605
  'learn': 'Extract one reusable pattern from the current Codex task into a valid user skill, with explicit user approval before writing.',
723
606
  };
@@ -730,7 +613,6 @@ function buildSkillMarkdown(sourceText, sourceName, targetName) {
730
613
  const { fm, body } = parseFrontmatter(sourceText);
731
614
  let adaptedBody;
732
615
  if (targetName === 'cc-collab') adaptedBody = CC_COLLAB_BODY;
733
- else if (targetName === 'gemini-collab') adaptedBody = GEMINI_COLLAB_BODY;
734
616
  else if (targetName === 'ultra-verify') adaptedBody = ULTRA_VERIFY_BODY;
735
617
  else adaptedBody = adaptHostText(body, targetName);
736
618
  return yaml.dump({
@@ -745,7 +627,6 @@ function buildOpenAiYaml(name, description) {
745
627
  COMMAND_NAMES.includes(name)
746
628
  || INTERNAL_SKILLS.has(name)
747
629
  || name === 'cc-collab'
748
- || name === 'gemini-collab'
749
630
  || name.startsWith('ultra-')
750
631
  );
751
632
  const short = description.replace(/\s+/g, ' ').trim().slice(0, 63).replace(/[\s.,;:]+$/, '');
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  // YAML frontmatter parsing / serialization for markdown assets.
4
- // Every runtime adapter consumes this — OpenCode lowercases keys,
5
- // Gemini extracts description for toml, Claude preserves verbatim.
4
+ // Every runtime adapter consumes this — OpenCode lowercases keys while
5
+ // Claude Code and Codex preserve their native metadata contracts.
6
6
 
7
7
  const yaml = require('js-yaml');
8
8
 
@@ -15,21 +15,21 @@ const HOSTS = Object.freeze({
15
15
  name: 'Claude Code',
16
16
  handbook: ['.claude', 'CLAUDE.md'],
17
17
  invocation: '`/ultra-init`, `/ultra-research`, `/ultra-plan`, `/ultra-dev`, `/ultra-test`, `/ultra-review`, and `/ultra-deliver`; diagnostics use `/ultra-status` and `/ultra-think`',
18
- collaboration: '`/codex-collab` and `/gemini-collab` are explicitly requested read-only advisors',
18
+ collaboration: '`/codex-collab` is an explicitly requested read-only advisor',
19
19
  coordination: 'Claude Code task UI is host coordination; it does not replace Ultra task state',
20
20
  }),
21
21
  codex: Object.freeze({
22
22
  name: 'Codex',
23
23
  handbook: ['.codex', 'AGENTS.md'],
24
24
  invocation: '`$ultra-builder-pro:ultra-init`, `$ultra-builder-pro:ultra-research`, `$ultra-builder-pro:ultra-plan`, `$ultra-builder-pro:ultra-dev`, `$ultra-builder-pro:ultra-test`, `$ultra-builder-pro:ultra-review`, and `$ultra-builder-pro:ultra-deliver`; diagnostics use `$ultra-builder-pro:ultra-status` and `$ultra-builder-pro:ultra-think`',
25
- collaboration: '`$ultra-builder-pro:cc-collab` and `$ultra-builder-pro:gemini-collab` are explicitly requested read-only advisors',
25
+ collaboration: '`$ultra-builder-pro:cc-collab` is an explicitly requested read-only advisor',
26
26
  coordination: 'The Codex plan is turn-facing coordination; it does not replace Ultra task state',
27
27
  }),
28
28
  opencode: Object.freeze({
29
29
  name: 'OpenCode',
30
30
  handbook: ['.config', 'opencode', 'AGENTS.md'],
31
31
  invocation: '`/ultra-init`, `/ultra-research`, `/ultra-plan`, `/ultra-dev`, `/ultra-test`, `/ultra-review`, and `/ultra-deliver`; diagnostics use `/ultra-status` and `/ultra-think`',
32
- collaboration: '`/cc-collab`, `/codex-collab`, and `/gemini-collab` are explicitly requested read-only advisors',
32
+ collaboration: '`/cc-collab` and `/codex-collab` are explicitly requested read-only advisors',
33
33
  coordination: 'OpenCode session coordination does not replace Ultra task state',
34
34
  }),
35
35
  });
@@ -14,7 +14,6 @@ const RUNTIME_SKILL_ROOT = {
14
14
  claude: '.claude/skills',
15
15
  opencode: '.config/opencode/skills',
16
16
  codex: '.agents/skills',
17
- gemini: '.gemini/extensions/ultra-builder-pro/skills',
18
17
  };
19
18
 
20
19
  function parseSkillRef(ref) {
@@ -52,7 +51,6 @@ function runtimeRoot(runtime) {
52
51
  case 'claude': return '.claude';
53
52
  case 'opencode': return '.config/opencode';
54
53
  case 'codex': return '.agents';
55
- case 'gemini': return '.gemini/extensions/ultra-builder-pro';
56
54
  default: throw new Error(`unknown runtime: ${runtime}`);
57
55
  }
58
56
  }
@@ -62,7 +60,6 @@ function localRoot(runtime) {
62
60
  case 'claude': return '.claude';
63
61
  case 'opencode': return '.opencode';
64
62
  case 'codex': return '.agents';
65
- case 'gemini': return '.gemini/extensions/ultra-builder-pro';
66
63
  default: throw new Error(`unknown runtime: ${runtime}`);
67
64
  }
68
65
  }
@@ -27,11 +27,12 @@ const INTERNAL_AGENT_SKILLS = Object.freeze([
27
27
  'testing-rules',
28
28
  ]);
29
29
 
30
+ const SUPPORTED_RUNTIMES = Object.freeze(['claude', 'opencode', 'codex']);
31
+
30
32
  const COLLAB_SKILLS_BY_RUNTIME = Object.freeze({
31
- claude: Object.freeze(['codex-collab', 'gemini-collab', 'ultra-verify']),
32
- codex: Object.freeze(['cc-collab', 'gemini-collab', 'ultra-verify']),
33
- opencode: Object.freeze(['cc-collab', 'codex-collab', 'gemini-collab', 'ultra-verify']),
34
- gemini: Object.freeze(['cc-collab', 'codex-collab', 'ultra-verify']),
33
+ claude: Object.freeze(['codex-collab', 'ultra-verify']),
34
+ codex: Object.freeze(['cc-collab', 'ultra-verify']),
35
+ opencode: Object.freeze(['cc-collab', 'codex-collab', 'ultra-verify']),
35
36
  });
36
37
 
37
38
  const RETIRED_SKILLS = Object.freeze([
@@ -60,11 +61,17 @@ function skillsForRuntime(runtime) {
60
61
  return [...CORE_PUBLIC_SKILLS, ...INTERNAL_AGENT_SKILLS, ...collab];
61
62
  }
62
63
 
64
+ function isSupportedRuntime(runtime) {
65
+ return SUPPORTED_RUNTIMES.includes(runtime);
66
+ }
67
+
63
68
  module.exports = {
64
69
  CORE_PUBLIC_SKILLS,
65
70
  INTERNAL_AGENT_SKILLS,
71
+ SUPPORTED_RUNTIMES,
66
72
  COLLAB_SKILLS_BY_RUNTIME,
67
73
  RETIRED_SKILLS,
68
74
  WORKFLOW_HOOK_FILES,
75
+ isSupportedRuntime,
69
76
  skillsForRuntime,
70
77
  };
@@ -26,12 +26,10 @@ test('resolveSkillRef routes to runtime-specific root under homeDir', () => {
26
26
  const claude = resolveSkillRef('@skills/ultra-init/SKILL.md', { runtime: 'claude', homeDir: home });
27
27
  const opencode = resolveSkillRef('@skills/ultra-init/SKILL.md', { runtime: 'opencode', homeDir: home });
28
28
  const codex = resolveSkillRef('@skills/ultra-init/SKILL.md', { runtime: 'codex', homeDir: home });
29
- const gemini = resolveSkillRef('@skills/ultra-init/SKILL.md', { runtime: 'gemini', homeDir: home });
30
29
 
31
30
  assert.equal(claude, path.join(home, '.claude/skills/ultra-init/SKILL.md'));
32
31
  assert.equal(opencode, path.join(home, '.config/opencode/skills/ultra-init/SKILL.md'));
33
32
  assert.equal(codex, path.join(home, '.agents/skills/ultra-init/SKILL.md'));
34
- assert.equal(gemini, path.join(home, '.gemini/extensions/ultra-builder-pro/skills/ultra-init/SKILL.md'));
35
33
 
36
34
  assert.throws(
37
35
  () => resolveSkillRef('@skills/ultra-init/SKILL.md', { runtime: 'unknown', homeDir: home }),
@@ -47,7 +45,7 @@ test('rewriteWorkflowRefInText + resolveAssetTarget give predictable paths', ()
47
45
  assert.equal(out, `see ${path.join(home, '.claude/skills/ultra-init/SKILL.md')} for details`);
48
46
 
49
47
  // Cover every runtime × every scope so runtimeRoot/localRoot branches hit
50
- for (const rt of ['claude', 'opencode', 'codex', 'gemini']) {
48
+ for (const rt of ['claude', 'opencode', 'codex']) {
51
49
  const g = resolveAssetTarget('x', { runtime: rt, scope: 'global', homeDir: home, cwd });
52
50
  const l = resolveAssetTarget('x', { runtime: rt, scope: 'local', homeDir: home, cwd });
53
51
  assert.ok(g.startsWith(home));
@@ -1,13 +1,10 @@
1
1
  'use strict';
2
2
 
3
- // Phase 4.6b reviewer suggestion — scope-precedence contract across all
4
- // four adapter.resolveTarget implementations.
3
+ // Scope-precedence contract across every supported adapter.resolveTarget.
5
4
  //
6
5
  // Each adapter honors the same ordering:
7
6
  // ctx.configDir > ctx.scope='global' → env var or homeDir/.<runtime>
8
7
  // > ctx.scope='local' → cwd/.<runtime>
9
- //
10
- // Gemini also exposes resolveExtensionRoot that appends extensions/<NAME>.
11
8
 
12
9
  const { test } = require('node:test');
13
10
  const assert = require('node:assert/strict');
@@ -16,7 +13,6 @@ const path = require('node:path');
16
13
  const claude = require('../../../adapters/claude.js');
17
14
  const opencode = require('../../../adapters/opencode.js');
18
15
  const codex = require('../../../adapters/codex.js');
19
- const gemini = require('../../../adapters/gemini.js');
20
16
 
21
17
  // Stable fake values so assertions don't depend on real $HOME / $CWD.
22
18
  const FAKE_HOME = '/fake-home';
@@ -43,7 +39,6 @@ const CASES = [
43
39
  { name: 'claude', resolve: claude.resolveTarget, localLeaf: '.claude', globalHome: '.claude', envKey: 'CLAUDE_CONFIG_DIR' },
44
40
  { name: 'opencode', resolve: opencode.resolveTarget, localLeaf: '.opencode', globalHome: path.join('.config', 'opencode'), envKey: 'OPENCODE_CONFIG_DIR' },
45
41
  { name: 'codex', resolve: codex.resolveTarget, localLeaf: '.codex', globalHome: '.codex', envKey: 'CODEX_HOME' },
46
- { name: 'gemini', resolve: gemini.resolveTarget, localLeaf: '.gemini', globalHome: '.gemini', envKey: 'GEMINI_CONFIG_DIR' },
47
42
  ];
48
43
 
49
44
  for (const tc of CASES) {
@@ -78,8 +73,3 @@ for (const tc of CASES) {
78
73
  assert.equal(out, path.join(FAKE_CWD, tc.localLeaf));
79
74
  });
80
75
  }
81
-
82
- test('gemini.resolveExtensionRoot layers extensions/<NAME> on top of resolveTarget', () => {
83
- const out = gemini.resolveExtensionRoot({ configDir: '/explicit' });
84
- assert.equal(out, path.join('/explicit', 'extensions', 'ultra-builder-pro'));
85
- });
@@ -9,6 +9,7 @@ const REPO_ROOT = path.resolve(__dirname, '..', '..', '..');
9
9
  const {
10
10
  CORE_PUBLIC_SKILLS,
11
11
  INTERNAL_AGENT_SKILLS,
12
+ SUPPORTED_RUNTIMES,
12
13
  COLLAB_SKILLS_BY_RUNTIME,
13
14
  RETIRED_SKILLS,
14
15
  WORKFLOW_HOOK_FILES,
@@ -51,19 +52,17 @@ test('runtime asset manifest exposes only Ultra-owned core and internal skills',
51
52
  assert.deepEqual(RETIRED_SKILLS, RETIRED);
52
53
 
53
54
  assert.deepEqual(COLLAB_SKILLS_BY_RUNTIME.claude, [
54
- 'codex-collab', 'gemini-collab', 'ultra-verify',
55
+ 'codex-collab', 'ultra-verify',
55
56
  ]);
56
57
  assert.deepEqual(COLLAB_SKILLS_BY_RUNTIME.codex, [
57
- 'cc-collab', 'gemini-collab', 'ultra-verify',
58
+ 'cc-collab', 'ultra-verify',
58
59
  ]);
59
60
  assert.deepEqual(COLLAB_SKILLS_BY_RUNTIME.opencode, [
60
- 'cc-collab', 'codex-collab', 'gemini-collab', 'ultra-verify',
61
- ]);
62
- assert.deepEqual(COLLAB_SKILLS_BY_RUNTIME.gemini, [
63
61
  'cc-collab', 'codex-collab', 'ultra-verify',
64
62
  ]);
63
+ assert.deepEqual(SUPPORTED_RUNTIMES, ['claude', 'opencode', 'codex']);
65
64
 
66
- for (const runtime of ['claude', 'codex', 'opencode', 'gemini']) {
65
+ for (const runtime of SUPPORTED_RUNTIMES) {
67
66
  const names = skillsForRuntime(runtime);
68
67
  for (const retired of RETIRED) assert.ok(!names.includes(retired));
69
68
  assert.ok(!names.some((name) => /impeccable/i.test(name)));