@ask-llm/plugin 0.16.2 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/CHANGELOG.md +25 -0
- package/README.md +10 -6
- package/agents/codex-reviewer.md +6 -1
- package/agents/codex-verifier.md +5 -3
- package/agents/sol-reviewer.md +7 -3
- package/package.json +7 -7
- package/scripts/sol-review-transport.mjs +116 -35
- package/skills/codex-image/SKILL.md +4 -4
- package/skills/codex-pair/SKILL.md +4 -3
- package/skills/pairing-contract.md +1 -1
- package/skills/sol-review/SKILL.md +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @ask-llm/plugin
|
|
2
2
|
|
|
3
|
+
## 0.17.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#327](https://github.com/Lykhoyda/ask-llm/pull/327) [`4e0e436`](https://github.com/Lykhoyda/ask-llm/commit/4e0e436b43f7a1bff897bd690c71765420ff32ae) Thanks [@Lykhoyda](https://github.com/Lykhoyda)! - Add Codex `preferred` and `sandbox` to unified `ask-llm` (fail closed on other providers) and let plugin Codex workflows use fully pinned unified MCP when no `ask-codex` leaf is present, without stripping provider options ([#266](https://github.com/Lykhoyda/ask-llm/issues/266)).
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`124d93d`](https://github.com/Lykhoyda/ask-llm/commit/124d93dd6dae941ffac37d6583be7cbf0eb0c30f), [`4e0e436`](https://github.com/Lykhoyda/ask-llm/commit/4e0e436b43f7a1bff897bd690c71765420ff32ae)]:
|
|
12
|
+
- @ask-llm/antigravity-mcp@0.7.6
|
|
13
|
+
- @ask-llm/mcp@0.10.0
|
|
14
|
+
|
|
15
|
+
## 0.16.3
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- [#323](https://github.com/Lykhoyda/ask-llm/pull/323) [`2d335c8`](https://github.com/Lykhoyda/ask-llm/commit/2d335c84db3ff9507cda128e0fc40154ba19bb08) Thanks [@Lykhoyda](https://github.com/Lykhoyda)! - No functional change. Republish the eight public packages so each new tarball's npm gitHead matches the version-introducing commit and per-package source tags can be created. The versions currently on npm were published from a later SHA than the version bump, and gitHead is immutable.
|
|
20
|
+
- Updated dependencies [[`2d335c8`](https://github.com/Lykhoyda/ask-llm/commit/2d335c84db3ff9507cda128e0fc40154ba19bb08)]:
|
|
21
|
+
- @ask-llm/antigravity-mcp@0.7.5
|
|
22
|
+
- @ask-llm/codex-mcp@0.7.8
|
|
23
|
+
- @ask-llm/gemini-mcp@1.9.1
|
|
24
|
+
- @ask-llm/grok-mcp@0.1.5
|
|
25
|
+
- @ask-llm/ollama-mcp@0.6.2
|
|
26
|
+
- @ask-llm/mcp@0.9.3
|
|
27
|
+
|
|
3
28
|
## 0.16.2
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -23,16 +23,20 @@ Part of the [Ask LLM](https://github.com/Lykhoyda/ask-llm) monorepo.
|
|
|
23
23
|
|
|
24
24
|
### MCP Servers
|
|
25
25
|
|
|
26
|
-
The
|
|
26
|
+
The recommended cross-provider server is `@ask-llm/mcp`. Keep `npx -y @ask-llm/mcp` as the primary registration; `npm install -g @ask-llm/mcp` is a first-class alternative when you want a pinned global binary. Split provider packages (`@ask-llm/codex-mcp`, `@ask-llm/grok-mcp`, and the others) remain an advanced optimization for a richer per-provider tool surface.
|
|
27
|
+
|
|
28
|
+
The plugin bundles only the Codex MCP registration under Claude Code's plugin namespace. After installation or upgrade, fully restart Claude Code and run `/mcp`; `plugin:ask-llm:codex` should be connected. Codex-facing workflows prefer that bundled `ask-codex` leaf (or a user-scoped `ask-codex`), then a fully pinned unified `ask-llm` call (`provider: "codex"` plus model and Codex options), then the disclosed `codex exec` fallback. An older unified schema that cannot honor those options is reported rather than stripped.
|
|
27
29
|
|
|
28
30
|
`/grok-pair` does not add servers to the plugin. Register the unified Ask LLM server at user scope (the recommended install: it exposes `ask-cursor-agent` for the Cursor Agent route plus the unified `ask-llm` tool, which pair skills call only fully pinned) and, optionally, the split Grok server for the `ask-grok` leaf:
|
|
29
31
|
|
|
30
32
|
```bash
|
|
31
33
|
claude mcp add --scope user ask-llm -- npx -y @ask-llm/mcp
|
|
34
|
+
# first-class alternative after `npm install -g @ask-llm/mcp`:
|
|
35
|
+
# claude mcp add --scope user ask-llm -- ask-llm-mcp
|
|
32
36
|
claude mcp add --scope user grok -- npx -y @ask-llm/grok-mcp
|
|
33
37
|
```
|
|
34
38
|
|
|
35
|
-
Existing user-scoped Codex registrations remain compatible and keep their shorter names. Other providers are registered explicitly at user scope:
|
|
39
|
+
Existing user-scoped Codex registrations remain compatible and keep their shorter names. Other providers are registered explicitly at user scope only when you want their split leaves:
|
|
36
40
|
|
|
37
41
|
```bash
|
|
38
42
|
claude mcp add --scope user gemini -- npx -y @ask-llm/gemini-mcp
|
|
@@ -40,6 +44,8 @@ claude mcp add --scope user ollama -- npx -y @ask-llm/ollama-mcp
|
|
|
40
44
|
claude mcp add --scope user antigravity -- npx -y @ask-llm/antigravity-mcp
|
|
41
45
|
```
|
|
42
46
|
|
|
47
|
+
If Codex is missing entirely, provision the unified server first (`claude mcp add --scope user ask-llm -- npx -y @ask-llm/mcp`) or the split Codex leaf with `claude mcp add --scope user codex -- npx -y @ask-llm/codex-mcp`. If `/mcp` shows the bundled registration but it is disconnected, run `npx -y @ask-llm/mcp doctor` and restart Claude Code. `/sol-review` preserves source-plugin and session-local MCP/settings context when reading the active `claude mcp list` inventory, reports missing, unavailable, and unsupported-schema states separately, and discloses the explicit `codex exec` fallback after failed health, an incomplete unified schema, or MCP transport failure.
|
|
48
|
+
|
|
43
49
|
### Cursor Agent
|
|
44
50
|
|
|
45
51
|
Cursor's supported Agent Skills surface exposes exactly `/codex-pair` and `/grok-pair` (the manifest sets `agents: []`, `commands: []`, and `hooks: {}` so Claude agents and the Claude-format hooks file are never auto-discovered, and the other skills stay Claude/Pi-only until they get Cursor adapters); its MCP surface is `mcp.json`, which bundles only the unified `ask-llm` server. For a source checkout:
|
|
@@ -48,9 +54,7 @@ Cursor's supported Agent Skills surface exposes exactly `/codex-pair` and `/grok
|
|
|
48
54
|
agent --plugin-dir ./packages/claude-plugin
|
|
49
55
|
```
|
|
50
56
|
|
|
51
|
-
`/codex-pair` requires explicit `model=` and `effort=` values before consent, then uses a separately user-installed `ask-codex` leaf when exposed, otherwise the bundled unified `ask-llm` fully pinned (`provider: "codex"`, model, effort, include directories, session), with resumable Thread ID, cancellation, and result relay. It never guesses MCP-process environment defaults and does not pretend Claude-only hooks are active. `/grok-pair` gives Cursor-native `.cursor/mcp.json` and Tools & MCP reload guidance; it never sends Cursor users to `claude mcp add`. If installing only MCP configuration, the recommended minimal entry is `ask-llm` → `npx -y @ask-llm/mcp` in project `.cursor/mcp.json` or user `~/.cursor/mcp.json` (keep one registration per server — do not duplicate it when the plugin is loaded); add `codex` → `@ask-llm/codex-mcp` or `grok` → `@ask-llm/grok-mcp` only when you specifically want their `ask-codex`/`ask-grok` leaves, then reload MCP/restart Cursor Agent. When Cursor hosts `/grok-pair`, it never recursively invokes Cursor Agent.
|
|
52
|
-
|
|
53
|
-
If Codex is missing entirely, register it explicitly with `claude mcp add --scope user codex -- npx -y @ask-llm/codex-mcp`. If `/mcp` shows the bundled registration but it is disconnected, run `npx -y @ask-llm/mcp doctor` and restart Claude Code. `/sol-review` preserves source-plugin and session-local MCP/settings context when reading the active `claude mcp list` inventory, reports missing and unavailable states separately, and discloses the explicit `codex exec` fallback after failed health or MCP transport failure.
|
|
57
|
+
`/codex-pair` requires explicit `model=` and `effort=` values before consent, then uses a separately user-installed `ask-codex` leaf when exposed, otherwise the bundled unified `ask-llm` fully pinned (`provider: "codex"`, model, effort, include directories, sandbox, session), with resumable Thread ID, cancellation, and result relay. It never guesses MCP-process environment defaults and does not pretend Claude-only hooks are active. `/grok-pair` gives Cursor-native `.cursor/mcp.json` and Tools & MCP reload guidance; it never sends Cursor users to `claude mcp add`. If installing only MCP configuration, the recommended minimal entry is `ask-llm` → `npx -y @ask-llm/mcp` in project `.cursor/mcp.json` or user `~/.cursor/mcp.json` (keep one registration per server — do not duplicate it when the plugin is loaded); add `codex` → `@ask-llm/codex-mcp` or `grok` → `@ask-llm/grok-mcp` only when you specifically want their `ask-codex`/`ask-grok` leaves, then reload MCP/restart Cursor Agent. When Cursor hosts `/grok-pair`, it never recursively invokes Cursor Agent.
|
|
54
58
|
|
|
55
59
|
### Pi
|
|
56
60
|
|
|
@@ -80,7 +84,7 @@ See the [Pi host guide](https://lykhoyda.github.io/ask-llm/plugin/pi) for securi
|
|
|
80
84
|
| `/gemini-review` | Gemini-only code review with confidence filtering |
|
|
81
85
|
| `/codex-review` | Codex-only code review (precision-first, ≥80 confidence — default for routine PR review) |
|
|
82
86
|
| `/fable-review` | Isolated, read-only review requesting native Fable, with runtime verification limits disclosed |
|
|
83
|
-
| `/sol-review` | Model-pinned GPT-5.6 Sol review
|
|
87
|
+
| `/sol-review` | Model-pinned GPT-5.6 Sol review: prefer bundled or user-scoped `ask-codex`, then fully pinned unified `ask-llm`, then the disclosed CLI fallback |
|
|
84
88
|
| `/ollama-review` | Local review — no data leaves your machine |
|
|
85
89
|
| `/brainstorm` | Explicit multi-model brainstorm (default external: Antigravity + Codex); supports an exact no-Gemini Grok + GPT-5.6 Sol panel through Cursor Agent |
|
|
86
90
|
| `/grok-review` | Grok review through explicit xAI API or Grok CLI harness; no fallback |
|
package/agents/codex-reviewer.md
CHANGED
|
@@ -10,6 +10,7 @@ tools:
|
|
|
10
10
|
- Read
|
|
11
11
|
- mcp__codex__ask-codex
|
|
12
12
|
- mcp__plugin_ask-llm_codex__ask-codex
|
|
13
|
+
- mcp__ask-llm__ask-llm
|
|
13
14
|
---
|
|
14
15
|
|
|
15
16
|
<!-- PORTABLE-CONTRACT:START -->
|
|
@@ -62,7 +63,11 @@ You are a code review coordinator that leverages OpenAI Codex for independent an
|
|
|
62
63
|
|
|
63
64
|
### Phase 2: Review Prompt Construction
|
|
64
65
|
|
|
65
|
-
When calling
|
|
66
|
+
When calling Codex, leave `model` and `preferred` unset and set `reasoningEffort: "high"` plus `sandbox: "read-only"`. This uses GPT-5.6 Sol at high effort and transparently falls back to GPT-5.6 Terra on quota.
|
|
67
|
+
|
|
68
|
+
Prefer an exact `ask-codex` leaf (`mcp__codex__ask-codex` or `mcp__plugin_ask-llm_codex__ask-codex`). If none is exposed, call `mcp__ask-llm__ask-llm` with `provider: "codex"` and the same options. Inspect the unified input schema first: if it lacks `reasoningEffort`, `includeDirs`, `preferred`, or `sandbox`, stop and tell the user to upgrade `@ask-llm/mcp` (`npx -y @ask-llm/mcp@latest` or `npm install -g @ask-llm/mcp`); do not omit those fields to make the call succeed. Never make an unpinned generic `ask-llm` call.
|
|
69
|
+
|
|
70
|
+
Structure the prompt to request confidence scoring AND severity classification:
|
|
66
71
|
|
|
67
72
|
```
|
|
68
73
|
Review the following code changes. For each issue found, rate:
|
package/agents/codex-verifier.md
CHANGED
|
@@ -9,6 +9,8 @@ tools:
|
|
|
9
9
|
- Grep
|
|
10
10
|
- Read
|
|
11
11
|
- mcp__codex__ask-codex
|
|
12
|
+
- mcp__plugin_ask-llm_codex__ask-codex
|
|
13
|
+
- mcp__ask-llm__ask-llm
|
|
12
14
|
---
|
|
13
15
|
|
|
14
16
|
<!-- PORTABLE-CONTRACT:START -->
|
|
@@ -35,7 +37,7 @@ If the assistant said "I added retry logic to the executor," `codex-reviewer` lo
|
|
|
35
37
|
|
|
36
38
|
## Tool surface (read-only by contract)
|
|
37
39
|
|
|
38
|
-
Allowed: `Read`, `Grep`, `Glob`, `Bash` (read-only commands only — `cat`, `head`, `tail`, `wc`, `diff`, `git diff|log|show|status|blame`, `jq`, language-native test runners in dry-run/list mode), `mcp__codex__ask-codex`.
|
|
40
|
+
Allowed: `Read`, `Grep`, `Glob`, `Bash` (read-only commands only — `cat`, `head`, `tail`, `wc`, `diff`, `git diff|log|show|status|blame`, `jq`, language-native test runners in dry-run/list mode), `mcp__codex__ask-codex`, `mcp__plugin_ask-llm_codex__ask-codex`, `mcp__ask-llm__ask-llm`.
|
|
39
41
|
|
|
40
42
|
Forbidden: anything that mutates state. Never run `rm`, `mv`, `chmod`, redirections (`>`, `>>`, `tee`), package installs (`npm install`, `pip install`), or DB writes (`INSERT`, `UPDATE`, `DELETE`, `DROP`). No `Write`, no `Edit`, no `NotebookEdit`.
|
|
41
43
|
|
|
@@ -77,9 +79,9 @@ Evidence sources, in order of cost:
|
|
|
77
79
|
- `Bash`: `git log --diff-filter=A -- <path>` — confirm a file was added in this branch.
|
|
78
80
|
- `Bash`: `git diff <ref> -- <path>` — confirm what specifically changed.
|
|
79
81
|
- `Bash`: `node -e "..."` (dry-run only, no side effects) — evaluate a small expression to confirm a constant value.
|
|
80
|
-
- `mcp__codex__ask-codex` — when the verification needs Codex's broader code-tracing (e.g., "does function X actually call function Y in the new path?"), send a focused single-claim prompt.
|
|
82
|
+
- `mcp__codex__ask-codex` or `mcp__plugin_ask-llm_codex__ask-codex` — when the verification needs Codex's broader code-tracing (e.g., "does function X actually call function Y in the new path?"), send a focused single-claim prompt. Prefer any exact `ask-codex` leaf; if only unified `mcp__ask-llm__ask-llm` is exposed, call it with `provider: "codex"`, `reasoningEffort: "high"`, `sandbox: "read-only"`, and `preferred` unset. If the unified schema lacks those Codex options, stop and report that `@ask-llm/mcp` must be upgraded; do not omit the fields.
|
|
81
83
|
|
|
82
|
-
When you call `
|
|
84
|
+
When you call an exact `ask-codex` leaf or the fully pinned unified `ask-llm` equivalent for verification, scope the prompt narrowly:
|
|
83
85
|
|
|
84
86
|
```
|
|
85
87
|
Verify this single claim against actual source: <claim>.
|
package/agents/sol-reviewer.md
CHANGED
|
@@ -29,19 +29,23 @@ You are a code review coordinator for a model-pinned OpenAI GPT-5.6 Sol review.
|
|
|
29
29
|
|
|
30
30
|
1. Inspect `git diff` and `git diff --cached`. Read each affected file around the changed lines.
|
|
31
31
|
2. Apply the nearest `CLAUDE.md` instructions and inspect any ADR explicitly cited by changed code.
|
|
32
|
-
3. Call
|
|
32
|
+
3. Call an available Ask LLM Codex transport with:
|
|
33
33
|
- `model: "gpt-5.6-sol"`
|
|
34
34
|
- `reasoningEffort: "high"`
|
|
35
|
+
- `sandbox: "read-only"`
|
|
35
36
|
- `preferred` unset
|
|
36
37
|
- a prompt containing the scoped conventions, relevant ADR summaries, and the diff
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
Transport ladder (do not skip rungs, and never strip an option to make a call succeed):
|
|
40
|
+
1. Prefer any exact `ask-codex` leaf whose server identity maps to an active `@ask-llm/codex-mcp` registration (`mcp__codex__ask-codex` or plugin-namespaced `mcp__plugin_ask-llm_codex__ask-codex`).
|
|
41
|
+
2. Otherwise call `mcp__ask-llm__ask-llm` (or another namespaced `__ask-llm` leaf whose server maps to `@ask-llm/mcp`) with `provider: "codex"` plus the same model, reasoningEffort, sandbox, preferred, and any `includeDirs`. Inspect the advertised input schema first. If it lacks `reasoningEffort`, `includeDirs`, `preferred`, or `sandbox`, stop: the installed `@ask-llm/mcp` is too old to honor Codex options. Upgrade with `npx -y @ask-llm/mcp@latest` or `npm install -g @ask-llm/mcp`; do not omit those fields.
|
|
42
|
+
3. If no authoritative MCP tool is available in this subagent context, pass the same prompt on stdin to the shipped fallback runner:
|
|
39
43
|
|
|
40
44
|
```bash
|
|
41
45
|
node "${CLAUDE_PLUGIN_ROOT}/scripts/sol-review-transport.mjs" --fallback --plugin-dir "${CLAUDE_PLUGIN_ROOT}" --cli-path "$(command -v codex || true)"
|
|
42
46
|
```
|
|
43
47
|
|
|
44
|
-
Before executing Codex, the runner queries the active Claude MCP inventory again with the active plugin preserved; mirror any session-local `--mcp-config`, `--settings`, `--setting-sources`, and `--strict-mcp-config` flags on the runner command. This makes a parent `preferred` result followed by an absent or disconnected subagent tool a registered-but-unavailable state with the corresponding remediation. If the MCP call itself fails at the transport/service boundary, rerun the same fallback command with `--mcp-failed`; do not use that flag for a provider/model response. The runner then executes `codex exec -m gpt-5.6-sol -c model_reasoning_effort="high" -s read-only --ignore-user-config --ignore-rules --skip-git-repo-check`. The model pin, reasoning-effort override, read-only sandbox, and isolation flags are load-bearing; never drop or substitute them. On a quota or rate-limit failure only, the runner retries once with `${ASK_CODEX_FALLBACK_MODEL:-gpt-5.6-terra}` and identical flags, matching the MCP executor's configurable quota ladder. It writes the review result to stdout unchanged so the validated findings can be relayed without loss. If the `codex` CLI is also unavailable, stop and report that the Sol review could not run. Do not review on another transport, on any model outside the Sol-to-fallback ladder, or in another sandbox mode.
|
|
48
|
+
Before executing Codex, the runner queries the active Claude MCP inventory again with the active plugin preserved; mirror any session-local `--mcp-config`, `--settings`, `--setting-sources`, and `--strict-mcp-config` flags on the runner command. When the resolved tool is unified `ask-llm`, pass `--tool "<resolved tool name>" --tool-schema "<advertised input JSON schema>"` so an older schema is classified as `unsupported-schema` rather than being called. This makes a parent `preferred` or `unified` result followed by an absent or disconnected subagent tool a registered-but-unavailable state with the corresponding remediation. If the MCP call itself fails at the transport/service boundary, rerun the same fallback command with `--mcp-failed`; do not use that flag for a provider/model response. The runner then executes `codex exec -m gpt-5.6-sol -c model_reasoning_effort="high" -s read-only --ignore-user-config --ignore-rules --skip-git-repo-check`. The model pin, reasoning-effort override, read-only sandbox, and isolation flags are load-bearing; never drop or substitute them. On a quota or rate-limit failure only, the runner retries once with `${ASK_CODEX_FALLBACK_MODEL:-gpt-5.6-terra}` and identical flags, matching the MCP executor's configurable quota ladder. It writes the review result to stdout unchanged so the validated findings can be relayed without loss. If the `codex` CLI is also unavailable, stop and report that the Sol review could not run. Do not review on another transport, on any model outside the Sol-to-fallback ladder, or in another sandbox mode.
|
|
45
49
|
4. Ask Sol for concrete correctness, security, data-loss, concurrency, resource-lifecycle, and compatibility failures with confidence scores and reproduction conditions.
|
|
46
50
|
5. Read the reported source locations and trace each reproduction path. Drop style preferences, speculative improvements, pre-existing issues, linter/type-checker findings, and behavior documented as intentional.
|
|
47
51
|
6. Report only validated findings with confidence of at least 80/100. Never invent findings to fill a report.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ask-llm/plugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Ask LLM review, comparison, brainstorming, image, verification, and pairing workflows for Claude Code, Cursor Agent, and Pi",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -83,12 +83,12 @@
|
|
|
83
83
|
]
|
|
84
84
|
},
|
|
85
85
|
"dependencies": {
|
|
86
|
-
"@ask-llm/antigravity-mcp": "^0.7.
|
|
87
|
-
"@ask-llm/codex-mcp": "^0.7.
|
|
88
|
-
"@ask-llm/gemini-mcp": "^1.9.
|
|
89
|
-
"@ask-llm/grok-mcp": "^0.1.
|
|
90
|
-
"@ask-llm/mcp": "^0.
|
|
91
|
-
"@ask-llm/ollama-mcp": "^0.6.
|
|
86
|
+
"@ask-llm/antigravity-mcp": "^0.7.6",
|
|
87
|
+
"@ask-llm/codex-mcp": "^0.7.8",
|
|
88
|
+
"@ask-llm/gemini-mcp": "^1.9.1",
|
|
89
|
+
"@ask-llm/grok-mcp": "^0.1.5",
|
|
90
|
+
"@ask-llm/mcp": "^0.10.0",
|
|
91
|
+
"@ask-llm/ollama-mcp": "^0.6.2"
|
|
92
92
|
},
|
|
93
93
|
"peerDependencies": {
|
|
94
94
|
"@earendil-works/pi-ai": "*",
|
|
@@ -7,9 +7,18 @@ import { prepareCommandInvocation } from "./lib/process.mjs";
|
|
|
7
7
|
|
|
8
8
|
export const ASK_CODEX_PACKAGE = "@ask-llm/codex-mcp";
|
|
9
9
|
export const ASK_CODEX_TOOL = "ask-codex";
|
|
10
|
+
export const ASK_LLM_PACKAGE = "@ask-llm/mcp";
|
|
11
|
+
export const ASK_LLM_TOOL = "ask-llm";
|
|
12
|
+
export const UNIFIED_CODEX_OPTION_KEYS = ["reasoningEffort", "includeDirs", "preferred", "sandbox"];
|
|
10
13
|
export const SOL_MODEL = "gpt-5.6-sol";
|
|
11
14
|
export const TERRA_MODEL = "gpt-5.6-terra";
|
|
12
15
|
|
|
16
|
+
const MISSING_REGISTRATION_REMEDIATION =
|
|
17
|
+
"Run `claude mcp add --scope user ask-llm -- npx -y @ask-llm/mcp`, fully restart Claude Code, then verify with `/mcp`. Split Codex remains an advanced optimization: `claude mcp add --scope user codex -- npx -y @ask-llm/codex-mcp`.";
|
|
18
|
+
const SERVICE_REMEDIATION = "Run `npx -y @ask-llm/mcp doctor`, inspect `/mcp`, then fully restart Claude Code.";
|
|
19
|
+
const UPGRADE_UNIFIED_REMEDIATION =
|
|
20
|
+
"Upgrade `@ask-llm/mcp` with `npx -y @ask-llm/mcp@latest` or `npm install -g @ask-llm/mcp`, fully restart Claude Code, then verify with `/mcp`.";
|
|
21
|
+
|
|
13
22
|
const scriptPath = fileURLToPath(import.meta.url);
|
|
14
23
|
const quotaSignals = [
|
|
15
24
|
"rate_limit_exceeded",
|
|
@@ -38,6 +47,29 @@ export function isAskCodexRegistration(server) {
|
|
|
38
47
|
);
|
|
39
48
|
}
|
|
40
49
|
|
|
50
|
+
export function isAskLlmToolName(name) {
|
|
51
|
+
return name === ASK_LLM_TOOL || /^mcp__.+__ask-llm$/.test(name);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function isAskLlmRegistration(server) {
|
|
55
|
+
if (!server || typeof server !== "object") return false;
|
|
56
|
+
const command = typeof server.command === "string" ? server.command : "";
|
|
57
|
+
const args = Array.isArray(server.args) ? server.args.filter((arg) => typeof arg === "string") : [];
|
|
58
|
+
const commandLine = typeof server.commandLine === "string" ? server.commandLine : "";
|
|
59
|
+
return (
|
|
60
|
+
/(?:^|[/\\])ask-llm-mcp(?:\.cmd|\.exe)?$/.test(command) ||
|
|
61
|
+
args.includes(ASK_LLM_PACKAGE) ||
|
|
62
|
+
/(?:^|\s)@ask-llm\/mcp(?:@[^\s]+)?(?:\s|$)/.test(commandLine) ||
|
|
63
|
+
/(?:^|[/\\])ask-llm-mcp(?:\.cmd|\.exe)?(?:\s|$)/.test(commandLine)
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function unifiedSchemaHonorsCodexOptions(schema) {
|
|
68
|
+
const properties = schema?.properties;
|
|
69
|
+
if (!properties || typeof properties !== "object") return false;
|
|
70
|
+
return UNIFIED_CODEX_OPTION_KEYS.every((key) => Object.hasOwn(properties, key));
|
|
71
|
+
}
|
|
72
|
+
|
|
41
73
|
export function parseClaudeMcpList(output) {
|
|
42
74
|
const servers = {};
|
|
43
75
|
for (const line of output.split(/\r?\n/)) {
|
|
@@ -77,8 +109,8 @@ export function readActiveMcpServers({
|
|
|
77
109
|
return parseClaudeMcpList(result.stdout || "");
|
|
78
110
|
}
|
|
79
111
|
|
|
80
|
-
function expectedToolName(serverName) {
|
|
81
|
-
return `mcp__${serverName.replaceAll(":", "_")}__${
|
|
112
|
+
function expectedToolName(serverName, tool = ASK_CODEX_TOOL) {
|
|
113
|
+
return `mcp__${serverName.replaceAll(":", "_")}__${tool}`;
|
|
82
114
|
}
|
|
83
115
|
|
|
84
116
|
function isAvailableMcpServer(server) {
|
|
@@ -86,12 +118,34 @@ function isAvailableMcpServer(server) {
|
|
|
86
118
|
return !status || /^✔\s*Connected\b/i.test(status) || /^cached\b.*\bconnects on first use\b/i.test(status);
|
|
87
119
|
}
|
|
88
120
|
|
|
121
|
+
function withCliFallback({ state, reason, remediation, cliPath }) {
|
|
122
|
+
if (!cliPath) {
|
|
123
|
+
return {
|
|
124
|
+
state,
|
|
125
|
+
transport: null,
|
|
126
|
+
toolName: null,
|
|
127
|
+
diagnostic: `${reason} The explicit CLI fallback is also unavailable.`,
|
|
128
|
+
remediation: `${remediation} Install the fallback with \`npm install -g @openai/codex\` if needed.`,
|
|
129
|
+
fallbackDisclosure: null,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
state,
|
|
134
|
+
transport: "cli",
|
|
135
|
+
toolName: null,
|
|
136
|
+
diagnostic: reason,
|
|
137
|
+
remediation,
|
|
138
|
+
fallbackDisclosure: `Transport disclosure: ${reason} Running the review through the explicit \`codex exec\` CLI fallback; validated findings will be relayed unchanged.`,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
89
142
|
export function classifySolReviewTransport({
|
|
90
143
|
availableTools = [],
|
|
91
144
|
mcpServers = {},
|
|
92
145
|
cliPath = "",
|
|
93
146
|
inventoryError = null,
|
|
94
147
|
mcpFailed = false,
|
|
148
|
+
toolSchemas = {},
|
|
95
149
|
}) {
|
|
96
150
|
if (inventoryError) {
|
|
97
151
|
const reason = `Ask LLM Codex MCP availability could not be determined because the active Claude MCP inventory could not be inspected: ${inventoryError}`;
|
|
@@ -116,28 +170,60 @@ export function classifySolReviewTransport({
|
|
|
116
170
|
};
|
|
117
171
|
}
|
|
118
172
|
|
|
119
|
-
const
|
|
120
|
-
const
|
|
121
|
-
const
|
|
122
|
-
|
|
123
|
-
|
|
173
|
+
const codexRegistrations = Object.entries(mcpServers).filter(([, server]) => isAskCodexRegistration(server));
|
|
174
|
+
const availableCodexRegistrations = codexRegistrations.filter(([, server]) => isAvailableMcpServer(server));
|
|
175
|
+
const registeredCodexToolNames = new Set(
|
|
176
|
+
availableCodexRegistrations.map(([name]) => expectedToolName(name, ASK_CODEX_TOOL)),
|
|
177
|
+
);
|
|
178
|
+
const askCodexToolName = availableTools.find(
|
|
179
|
+
(name) => isAskCodexToolName(name) && registeredCodexToolNames.has(name),
|
|
180
|
+
);
|
|
181
|
+
if (askCodexToolName && !mcpFailed) {
|
|
124
182
|
return {
|
|
125
183
|
state: "preferred",
|
|
126
184
|
transport: "mcp",
|
|
127
|
-
toolName,
|
|
128
|
-
diagnostic: `Ask LLM Codex transport available as ${
|
|
185
|
+
toolName: askCodexToolName,
|
|
186
|
+
diagnostic: `Ask LLM Codex transport available as ${askCodexToolName}.`,
|
|
187
|
+
remediation: null,
|
|
188
|
+
fallbackDisclosure: null,
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const unifiedRegistrations = Object.entries(mcpServers).filter(([, server]) => isAskLlmRegistration(server));
|
|
193
|
+
const availableUnifiedRegistrations = unifiedRegistrations.filter(([, server]) => isAvailableMcpServer(server));
|
|
194
|
+
const registeredUnifiedToolNames = new Set(
|
|
195
|
+
availableUnifiedRegistrations.map(([name]) => expectedToolName(name, ASK_LLM_TOOL)),
|
|
196
|
+
);
|
|
197
|
+
const askLlmToolName = availableTools.find((name) => isAskLlmToolName(name) && registeredUnifiedToolNames.has(name));
|
|
198
|
+
if (askLlmToolName && !mcpFailed) {
|
|
199
|
+
const schema = toolSchemas[askLlmToolName];
|
|
200
|
+
if (!unifiedSchemaHonorsCodexOptions(schema)) {
|
|
201
|
+
const schemaMissing = !schema;
|
|
202
|
+
return withCliFallback({
|
|
203
|
+
state: "unsupported-schema",
|
|
204
|
+
reason: schemaMissing
|
|
205
|
+
? "Ask LLM unified MCP is registered, but its `ask-llm` schema was not provided so Codex options (reasoningEffort, includeDirs, preferred, sandbox) cannot be verified. Pass `--tool-schema` with the advertised input JSON schema; never omit those fields to make the call succeed."
|
|
206
|
+
: "Ask LLM unified MCP is registered, but its `ask-llm` schema cannot honor Codex options (reasoningEffort, includeDirs, preferred, sandbox). Upgrade `@ask-llm/mcp`; never omit those fields to make the call succeed.",
|
|
207
|
+
remediation: UPGRADE_UNIFIED_REMEDIATION,
|
|
208
|
+
cliPath,
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
state: "unified",
|
|
213
|
+
transport: "mcp",
|
|
214
|
+
toolName: askLlmToolName,
|
|
215
|
+
diagnostic: `Ask LLM unified transport available as ${askLlmToolName}. Call it with provider "codex" and pass reasoningEffort, includeDirs, preferred, and sandbox; do not strip unsupported fields.`,
|
|
129
216
|
remediation: null,
|
|
130
217
|
fallbackDisclosure: null,
|
|
131
218
|
};
|
|
132
219
|
}
|
|
133
220
|
|
|
134
|
-
const registered =
|
|
221
|
+
const registered = codexRegistrations.length > 0 || unifiedRegistrations.length > 0;
|
|
135
222
|
const state = registered || mcpFailed ? "unavailable" : "missing-registration";
|
|
136
|
-
const remediation =
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const unavailableRegistration = registrations.find(([, server]) => !isAvailableMcpServer(server));
|
|
223
|
+
const remediation = registered || mcpFailed ? SERVICE_REMEDIATION : MISSING_REGISTRATION_REMEDIATION;
|
|
224
|
+
const unavailableRegistration =
|
|
225
|
+
codexRegistrations.find(([, server]) => !isAvailableMcpServer(server)) ||
|
|
226
|
+
unifiedRegistrations.find(([, server]) => !isAvailableMcpServer(server));
|
|
141
227
|
const reason = mcpFailed
|
|
142
228
|
? "Ask LLM Codex MCP invocation failed in this session, so the preferred transport is unavailable."
|
|
143
229
|
: unavailableRegistration
|
|
@@ -146,25 +232,7 @@ export function classifySolReviewTransport({
|
|
|
146
232
|
? "Ask LLM Codex MCP is registered, but its `ask-codex` tool is unavailable in this session."
|
|
147
233
|
: "Ask LLM Codex MCP registration is missing from this Claude Code installation.";
|
|
148
234
|
|
|
149
|
-
|
|
150
|
-
return {
|
|
151
|
-
state,
|
|
152
|
-
transport: null,
|
|
153
|
-
toolName: null,
|
|
154
|
-
diagnostic: `${reason} The explicit CLI fallback is also unavailable.`,
|
|
155
|
-
remediation: `${remediation} Install the fallback with \`npm install -g @openai/codex\` if needed.`,
|
|
156
|
-
fallbackDisclosure: null,
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
return {
|
|
161
|
-
state,
|
|
162
|
-
transport: "cli",
|
|
163
|
-
toolName: null,
|
|
164
|
-
diagnostic: reason,
|
|
165
|
-
remediation,
|
|
166
|
-
fallbackDisclosure: `Transport disclosure: ${reason} Running the review through the explicit \`codex exec\` CLI fallback; validated findings will be relayed unchanged.`,
|
|
167
|
-
};
|
|
235
|
+
return withCliFallback({ state, reason, remediation, cliPath });
|
|
168
236
|
}
|
|
169
237
|
|
|
170
238
|
export function codexFallbackArgs(model) {
|
|
@@ -255,6 +323,7 @@ function parseArgs(args) {
|
|
|
255
323
|
mcpList: null,
|
|
256
324
|
fallback: false,
|
|
257
325
|
mcpFailed: false,
|
|
326
|
+
toolSchema: null,
|
|
258
327
|
claudeContextArgs: [],
|
|
259
328
|
};
|
|
260
329
|
const claudeContextValueFlags = new Set(["--plugin-dir", "--mcp-config", "--settings", "--setting-sources"]);
|
|
@@ -265,7 +334,14 @@ function parseArgs(args) {
|
|
|
265
334
|
else if (arg === "--tool") parsed.tools.push(args[++index] ?? "");
|
|
266
335
|
else if (arg === "--cli-path") parsed.cliPath = args[++index] ?? "";
|
|
267
336
|
else if (arg === "--mcp-list") parsed.mcpList = args[++index] ?? "";
|
|
268
|
-
else if (arg === "--
|
|
337
|
+
else if (arg === "--tool-schema") {
|
|
338
|
+
const raw = args[++index] ?? "";
|
|
339
|
+
try {
|
|
340
|
+
parsed.toolSchema = JSON.parse(raw);
|
|
341
|
+
} catch {
|
|
342
|
+
throw new Error("Invalid --tool-schema JSON");
|
|
343
|
+
}
|
|
344
|
+
} else if (arg === "--strict-mcp-config") parsed.claudeContextArgs.push(arg);
|
|
269
345
|
else if (claudeContextValueFlags.has(arg)) {
|
|
270
346
|
const value = args[++index];
|
|
271
347
|
if (value === undefined) throw new Error(`Missing value for ${arg}`);
|
|
@@ -295,12 +371,17 @@ function readMcpServers(parsed) {
|
|
|
295
371
|
async function main() {
|
|
296
372
|
const parsed = parseArgs(process.argv.slice(2));
|
|
297
373
|
const { mcpServers, inventoryError } = readMcpServers(parsed);
|
|
374
|
+
const toolSchemas = {};
|
|
375
|
+
if (parsed.toolSchema) {
|
|
376
|
+
for (const name of parsed.tools) toolSchemas[name] = parsed.toolSchema;
|
|
377
|
+
}
|
|
298
378
|
const decision = classifySolReviewTransport({
|
|
299
379
|
availableTools: parsed.tools,
|
|
300
380
|
mcpServers,
|
|
301
381
|
cliPath: parsed.cliPath,
|
|
302
382
|
inventoryError,
|
|
303
383
|
mcpFailed: parsed.mcpFailed,
|
|
384
|
+
toolSchemas,
|
|
304
385
|
});
|
|
305
386
|
|
|
306
387
|
if (parsed.fallback) {
|
|
@@ -38,7 +38,7 @@ Codex's `image_generation` tool selects the image model server-side; as of 2026-
|
|
|
38
38
|
|
|
39
39
|
- `codex-cli` >= 0.125.0 installed and authenticated
|
|
40
40
|
- `image_generation` feature flag enabled (default: stable + true). Verify with `codex features list | grep image_generation`
|
|
41
|
-
- The `ask-codex` MCP tool available (from `@ask-llm/codex-mcp` or the `@ask-llm/mcp`
|
|
41
|
+
- The `ask-codex` MCP tool available (from `@ask-llm/codex-mcp`) or the unified `mcp__ask-llm__ask-llm` tool (from `@ask-llm/mcp`) whose schema includes `sandbox`
|
|
42
42
|
|
|
43
43
|
## Instructions
|
|
44
44
|
|
|
@@ -65,9 +65,9 @@ Example slug derivation:
|
|
|
65
65
|
- "Generate an image of a dark terminal with two reviewers" → `dark-terminal-with-two-reviewers.png`
|
|
66
66
|
- "Make me a cat picture" → `cat-picture.png`
|
|
67
67
|
|
|
68
|
-
### Phase 3: Dispatch to
|
|
68
|
+
### Phase 3: Dispatch to Codex
|
|
69
69
|
|
|
70
|
-
Call
|
|
70
|
+
Call an exact `ask-codex` leaf when exposed (NOT raw `codex exec` — that bypasses ADR-044 quota fallback, ADR-042 stdin handling, and ADR-047 PATH resolution). If only unified `mcp__ask-llm__ask-llm` is exposed, use that instead with `provider: "codex"`. If the unified schema lacks `sandbox`, stop and tell the user to upgrade `@ask-llm/mcp` (`npx -y @ask-llm/mcp@latest` or `npm install -g @ask-llm/mcp`); do not omit `sandbox` to make the call succeed. Use this prompt template:
|
|
71
71
|
|
|
72
72
|
```
|
|
73
73
|
Use your image_generation tool to create the following image and save it as a PNG file.
|
|
@@ -80,7 +80,7 @@ Save the file to this absolute path: <path from Phase 2>
|
|
|
80
80
|
After saving, confirm the absolute path of the created file and its byte size in your reply. If image_generation fails or the file cannot be written, explain what went wrong and do not invent a fake path.
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
**Sandbox:** pass `sandbox: "workspace-write"` on this `ask-codex`
|
|
83
|
+
**Sandbox:** pass `sandbox: "workspace-write"` on this `ask-codex` or fully pinned `ask-llm({ provider: "codex", ... })` call. Codex defaults to the read-only review sandbox (ADR-136), under which it cannot write the PNG to disk; image generation is the sanctioned exception that needs Codex to write the output file itself. The unified server will not silently strip `sandbox`; an older `@ask-llm/mcp` that cannot honor it must fail closed.
|
|
84
84
|
|
|
85
85
|
**Default model:** let `ask-codex` use its default (`gpt-5.6-sol`). The image_generation tool is invoked by the model regardless of which Codex chat model is selected — model selection here is about the orchestrating agent, not the image model itself.
|
|
86
86
|
|
|
@@ -19,7 +19,7 @@ Pi requires project trust, this repository marker, and explicit user-owned allow
|
|
|
19
19
|
|
|
20
20
|
Cursor discovers this `SKILL.md` through its supported Agent Skills surface; `/codex-pair` attaches it as an explicit command. Do **not** use Claude Code's `PostToolUse`, `Stop`, `SessionStart`, `SessionEnd`, `CLAUDE_PLUGIN_ROOT`, `AskUserQuestion`, or plugin tool namespaces. This adapter is an on-demand iterative pairing session, not a claim that Claude hooks were registered in Cursor.
|
|
21
21
|
|
|
22
|
-
1. Read `../pairing-contract.md`. The Cursor plugin bundle registers only the unified `ask-llm` server; if the user separately installed `@ask-llm/codex-mcp`, prefer that deterministic `ask-codex` leaf. Resolve an exposed MCP tool whose exact leaf is `ask-codex`; do not assume its server prefix. When only the unified `ask-llm` leaf is registered, it may serve as the transport with `provider: "codex"` and every option (model, reasoning effort, include directories, session) pinned explicitly; its schema rejects unsupported combinations instead of stripping them
|
|
22
|
+
1. Read `../pairing-contract.md`. The Cursor plugin bundle registers only the unified `ask-llm` server; if the user separately installed `@ask-llm/codex-mcp`, prefer that deterministic `ask-codex` leaf. Resolve an exposed MCP tool whose exact leaf is `ask-codex`; do not assume its server prefix. When only the unified `ask-llm` leaf is registered, it may serve as the transport with `provider: "codex"` and every option (model, reasoning effort, include directories, sandbox, session) pinned explicitly; its schema rejects unsupported combinations instead of stripping them. Inspect the advertised schema before the first call: if `sandbox` or another required Codex option is missing, stop and upgrade `@ask-llm/mcp` rather than omitting the field. Never make an unpinned generic call. If neither tool is exposed, stop with the recommended user-installed unified server:
|
|
23
23
|
```json
|
|
24
24
|
{"mcpServers":{"ask-llm":{"command":"npx","args":["-y","@ask-llm/mcp"]}}}
|
|
25
25
|
```
|
|
@@ -48,13 +48,14 @@ Cursor discovers this `SKILL.md` through its supported Agent Skills surface; `/c
|
|
|
48
48
|
"model": "<required exact ID>",
|
|
49
49
|
"reasoningEffort": "<required effort>",
|
|
50
50
|
"includeDirs": ["<validated relative directory>"],
|
|
51
|
-
"sessionId": ""
|
|
51
|
+
"sessionId": "",
|
|
52
|
+
"sandbox": "read-only"
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
]
|
|
55
56
|
```
|
|
56
57
|
The prompt assigns Codex the independent reviewer role and requests actionable severity/file/line evidence. Capture the returned structured `sessionId`/Thread ID and actual model. Relay feedback before changing code; verify every finding against source and label it accepted, rejected, or deferred.
|
|
57
|
-
5. At meaningful checkpoints, call the same tool with the captured `sessionId`, same model/effort, and bounded delta.
|
|
58
|
+
5. At meaningful checkpoints, call the same tool with the captured `sessionId`, same model/effort, and bounded delta. Keep `sandbox: "read-only"` on both `ask-codex` and unified `ask-llm`. If the unified schema lacks `sandbox`, stop and upgrade `@ask-llm/mcp` rather than omitting it. Omit `includeDirs` on resumed calls because `codex exec resume` does not support them (every Codex transport — split `ask-codex`, unified `ask-llm`, and Pi — rejects that combination at the shared executor instead of dropping the directories); never silently strip them from the first call. If no session ID was returned, stop with a session diagnostic instead of pretending continuity.
|
|
58
59
|
6. A Cursor interrupt cancels the MCP request. Report `cancelled` and never retry another tool/model/provider. Preserve earlier feedback on later failure and report `failed (partial)`. On success report `completed` with host, provider, requested/actual model, effort, session reuse count, context/include directories, accepted/rejected/deferred actions, and any reported Codex quota fallback. Never conceal fallback or rewrite a model.
|
|
59
60
|
|
|
60
61
|
<!-- HOST-ADAPTER:CLAUDE-CODE:START -->
|
|
@@ -20,7 +20,7 @@ Additional directories must be explicit relative workspace paths: no absolute pa
|
|
|
20
20
|
|
|
21
21
|
## Transport, options, and attribution
|
|
22
22
|
|
|
23
|
-
Select one route before the first call and keep it immutable for the run. Resolve tools by their exact leaf capability (`ask-codex`, `ask-grok`, or `ask-cursor-agent`), not by assuming a Claude plugin namespace. The unified `ask-llm` tool is an acceptable transport only when the call pins provider, harness where applicable, exact model, reasoning effort, include directories, and session explicitly and its schema rejects unsupported combinations rather than stripping them; it is never an unpinned generic call and never a fallback for a failed split tool. A missing tool is a setup failure, never permission to use a generic call.
|
|
23
|
+
Select one route before the first call and keep it immutable for the run. Resolve tools by their exact leaf capability (`ask-codex`, `ask-grok`, or `ask-cursor-agent`), not by assuming a Claude plugin namespace. The unified `ask-llm` tool is an acceptable transport only when the call pins provider, harness where applicable, exact model, reasoning effort, include directories, sandbox where the route supports it, and session explicitly and its schema rejects unsupported combinations rather than stripping them; it is never an unpinned generic call and never a fallback for a failed split tool. If the advertised schema lacks a required Codex option (`reasoningEffort`, `includeDirs`, `preferred`, `sandbox`), stop and upgrade `@ask-llm/mcp` rather than omitting the field. A missing tool is a setup failure, never permission to use a generic call.
|
|
24
24
|
|
|
25
25
|
Every call and final report must keep these separate:
|
|
26
26
|
|
|
@@ -33,13 +33,13 @@ Run a read-only, precision-first review explicitly pinned to GPT-5.6 Sol at high
|
|
|
33
33
|
3. If the combined diff is empty, report that there are no changes to review.
|
|
34
34
|
4. Read the root and file-scoped `CLAUDE.md` files plus any ADRs cited by changed code.
|
|
35
35
|
5. Preflight the transport through the shipped executable contract:
|
|
36
|
-
- Search the current tool surface for
|
|
37
|
-
- Run `node "${CLAUDE_PLUGIN_ROOT}/scripts/sol-review-transport.mjs" --plugin-dir "${CLAUDE_PLUGIN_ROOT}" --cli-path "$(command -v codex || true)"`, adding `--tool "<resolved tool name>"`
|
|
38
|
-
- Preserve the returned `state`, `diagnostic`, `remediation`, and `fallbackDisclosure`. The executable reads `claude mcp list` with that session context: `missing-registration` means that active inventory has no supported registration; `unavailable` means it contains the registration but the current tool surface does not expose a usable tool, reports failed health, or the MCP invocation failed; `inventory-unavailable` means the active inventory could not be inspected, so registration and service health are unknown. Do not collapse those states into a generic "no MCP" message. If `transport` is null, stop and show the executable remediation instead of launching the agent.
|
|
36
|
+
- Search the current tool surface for an exact `ask-codex` leaf first, then an `ask-llm` leaf. The executable correlates each client-assigned server prefix with an active `@ask-llm/codex-mcp` or `@ask-llm/mcp` registration; similarly named tools and tools from unrelated servers are not authoritative.
|
|
37
|
+
- Run `node "${CLAUDE_PLUGIN_ROOT}/scripts/sol-review-transport.mjs" --plugin-dir "${CLAUDE_PLUGIN_ROOT}" --cli-path "$(command -v codex || true)"`, adding `--tool "<resolved tool name>"` when an exact `ask-codex` or `ask-llm` tool resolved. For unified `ask-llm`, also pass `--tool-schema "<advertised input JSON schema>"` so a missing `reasoningEffort`/`includeDirs`/`preferred`/`sandbox` property is `unsupported-schema`, not a silent strip. Mirror any session-local `--mcp-config`, `--settings`, `--setting-sources`, and `--strict-mcp-config` flags so the nested inventory sees the same configuration as the active session.
|
|
38
|
+
- Preserve the returned `state`, `diagnostic`, `remediation`, and `fallbackDisclosure`. The executable reads `claude mcp list` with that session context: `preferred` is a usable `ask-codex` leaf; `unified` is a usable `mcp__ask-llm__ask-llm` (or namespaced) leaf whose advertised schema honors Codex options and that must be called with `provider: "codex"` and the complete Codex option set; `missing-registration` means that active inventory has no supported registration; `unavailable` means it contains the registration but the current tool surface does not expose a usable tool, reports failed health, or the MCP invocation failed; `unsupported-schema` means unified MCP is present but its schema was not supplied or cannot honor Codex options — pass `--tool-schema` or upgrade `@ask-llm/mcp` rather than omitting fields; `inventory-unavailable` means the active inventory could not be inspected, so registration and service health are unknown. Do not collapse those states into a generic "no MCP" message. If `transport` is null, stop and show the executable remediation instead of launching the agent.
|
|
39
39
|
- Parent availability remains advisory because subagents do not always inherit the session's MCP servers. The reviewer's fallback runner re-reads the active inventory and reclassifies the absent subagent tool before executing the CLI fallback.
|
|
40
40
|
6. Launch the `sol-reviewer` agent with the diff and a compact context brief containing the changed files, applicable conventions, referenced ADRs, the user's requested review focus, and the complete preflight result.
|
|
41
41
|
7. Return the agent's validated findings without adding unverified issues.
|
|
42
42
|
|
|
43
|
-
The reviewer must call `ask-codex` with `model: "gpt-5.6-sol"` and `
|
|
43
|
+
The reviewer must call `ask-codex` with `model: "gpt-5.6-sol"`, `reasoningEffort: "high"`, and `sandbox: "read-only"`, or the unified `ask-llm` equivalent with `provider: "codex"` and those same fields, or use the shipped CLI fallback runner when no usable MCP tool is available, its schema cannot honor those options, or its invocation fails at the transport/service boundary. That runner executes the sanctioned `codex exec -m gpt-5.6-sol -c model_reasoning_effort="high" -s read-only --ignore-user-config --ignore-rules --skip-git-repo-check` contract and relays its result unchanged. This explicit pin distinguishes `/sol-review` from `/codex-review`, which follows the configured Codex default. Both fallback kinds must be disclosed in the report: a Terra quota fallback means the requested Sol review did not complete on Sol, and a CLI transport fallback must report missing registration, registered-service unavailability, an unsupported unified schema, or an unreadable inventory without claiming a state that could not be determined.
|
|
44
44
|
|
|
45
45
|
<!-- HOST-ADAPTER:CLAUDE-CODE:END -->
|