Install
$ agentstack add skill-agent-sh-agentsys-consult ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ● Shell / process execution Used
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
consult
Cross-tool AI consultation: query another AI CLI tool and return the response.
When to Use
Invoke this skill when:
- User wants a second opinion from a different AI tool
- User asks to consult, ask, or cross-check with gemini/codex/claude/opencode/copilot
- User needs to compare responses across AI tools
- User wants to validate a decision with an external AI
Arguments
Parse from $ARGUMENTS:
| Flag | Values | Default | Description | |------|--------|---------|-------------| | --tool | gemini, codex, claude, opencode, copilot | (picker) | Target tool | | --effort | low, medium, high, max | medium | Thinking effort level | | --model | any model name | (from effort) | Override model selection | | --context | diff, file=PATH, none | none | Auto-include context | | --continue | (flag) or SESSION_ID | false | Resume previous session |
Question text is everything in $ARGUMENTS except the flags above.
Provider Configurations
Claude
Command: env -u CLAUDECODE claude -p "QUESTION" --output-format json --model "MODEL" --max-turns TURNS --allowedTools "Read,Glob,Grep"
Session resume: --resume "SESSION_ID"
Models: claude-haiku-4-5, claude-sonnet-4-6, claude-opus-4-6
| Effort | Model | Max Turns | |--------|-------|-----------| | low | claude-haiku-4-5 | 1 | | medium | claude-sonnet-4-6 | 3 | | high | claude-opus-4-6 | 5 | | max | claude-opus-4-6 | 10 |
Parse output: JSON.parse(stdout).result Session ID: JSON.parse(stdout).session_id Continuable: Yes ACP adapter: npx -y @anthropic-ai/claude-code-acp (see ACP Transport section)
Gemini
Command: gemini -p "QUESTION" --output-format json -m "MODEL"
Session resume: --resume "SESSION_ID"
Models: gemini-2.5-flash, gemini-2.5-pro, gemini-3-flash-preview, gemini-3-pro-preview, gemini-3.1-pro-preview
| Effort | Model | |--------|-------| | low | gemini-3-flash-preview | | medium | gemini-3-flash-preview | | high | gemini-3.1-pro-preview | | max | gemini-3.1-pro-preview |
Parse output: JSON.parse(stdout).response Session ID: JSON.parse(stdout).session_id Continuable: Yes (via --resume) ACP adapter: gemini (native ACP - Gemini CLI is ACP-compatible)
Codex
Command: codex exec "QUESTION" --json -m "MODEL" {SKIP_GIT_FLAG} -c model_reasoning_effort="LEVEL"
Session resume: codex exec resume "SESSION_ID" "QUESTION" --json -m "MODEL" {SKIP_GIT_FLAG} -c model_reasoning_effort="LEVEL"
Session resume (latest): codex exec resume --last "QUESTION" --json -m "MODEL" {SKIP_GIT_FLAG} -c model_reasoning_effort="LEVEL"
Note: codex exec is the non-interactive/headless mode. There is no -q flag. The TUI mode is codex (no subcommand). {SKIP_GIT_FLAG} is resolved by the trust gate in Command Building Step 1b:
- inside trusted git repo: empty string
- trusted non-repo execution:
--skip-git-repo-check
Models: gpt-5.3-codex
| Effort | Model | Reasoning | |--------|-------|-----------| | low | gpt-5.3-codex | low | | medium | gpt-5.3-codex | medium | | high | gpt-5.3-codex | high | | max | gpt-5.3-codex | high |
Parse output: JSON.parse(stdout).message or raw text Session ID: Codex prints a resume hint at session end (e.g., codex resume SESSION_ID). Extract the session ID from stdout or from JSON.parse(stdout).session_id if available. Continuable: Yes. Sessions are stored as JSONL rollout files at ~/.codex/sessions/. Non-interactive resume uses codex exec resume "SESSION_ID" "follow-up prompt" --json -m "MODEL" {SKIP_GIT_FLAG} -c model_reasoning_effort="LEVEL". Use --last instead of a session ID to resume the most recent session. ACP adapter: npx -y @zed-industries/codex-acp (see ACP Transport section)
OpenCode
Command: opencode run "QUESTION" --format json --model "MODEL" --variant "VARIANT"
Session resume: opencode run "QUESTION" --format json --model "MODEL" --variant "VARIANT" --continue (most recent) or --session "SESSION_ID"
With thinking: add --thinking flag
Models: 75+ via providers (format: provider/model). Key providers: opencode/ (free), github-copilot/, amazon-bedrock/, google/. Examples: github-copilot/gemini-3.1-pro-preview, opencode/big-pickle, amazon-bedrock/anthropic.claude-opus-4-6-v1. Run opencode models to list all.
Free models: opencode/big-pickle, opencode/gpt-5-nano, opencode/minimax-m2.5-free, opencode/trinity-large-preview-free
| Effort | Model | Variant | |--------|-------|---------| | low | (user-selected or default) | low | | medium | (user-selected or default) | medium | | high | (user-selected or default) | high | | max | (user-selected or default) | high + --thinking |
Parse output: OpenCode outputs newline-delimited JSON events. Each line is a JSON object with a type field. Extract the response text from events where type === "text" - the text is in part.text (NOT part.content). Concatenate all part.text values from type: "text" events. Event types: step_start, tool_use, text, step_finish. The sessionID is in every event's top-level sessionID field.
Session ID: Available in every event as event.sessionID (e.g., ses_xxxxx). Use --session SESSION_ID to resume. Continuable: Yes (via --continue or --session). Sessions are stored in a SQLite database in the OpenCode data directory. Use --session SESSION_ID for a specific session, or --continue for the most recent. ACP adapter: opencode acp (see ACP Transport section)
Copilot
Command: copilot -p "QUESTION"
Models: claude-sonnet-4-6 (default), claude-opus-4-6, claude-haiku-4-5, gpt-5
| Effort | Notes | |--------|-------| | all | No effort control available. Model selectable via --model flag. |
Parse output: Raw text from stdout Continuable: No ACP adapter: copilot --acp --stdio (see ACP Transport section)
Kiro
ACP-only provider. No CLI mode for external consultation.
Command: node acp/run.js --provider="kiro" --question-file="{AI_STATE_DIR}/consult/question.tmp" --timeout=120000
Kiro is available only via ACP transport. It requires kiro-cli on PATH.
Parse output: Via ACP runner (JSON.parse(stdout)) Continuable: No ACP adapter: kiro-cli acp (native ACP)
Input Validation
Before building commands, validate all user-provided arguments:
- --tool: MUST be one of: gemini, codex, claude, opencode, copilot, kiro. Reject all other values.
- --effort: MUST be one of: low, medium, high, max. Default to medium.
- --model: Allow any string, but quote it in the command.
- --continue=SESSIONID: If provided, SESSIONID MUST match
^(?!-)[A-Za-z0-9._:-]+$. Reject values that contain spaces, leading dashes, or shell metacharacters. - --context=file=PATH: MUST resolve within the project directory. Reject absolute paths outside cwd. Additional checks:
- Block UNC paths (Windows): Reject paths starting with
\\or//(network shares) - Resolve canonical path: Use the Read tool to read the file (do NOT use shell commands). Before reading, resolve the path: join
cwd + PATH, then normalize (collapse.,.., resolve symlinks) - Verify containment: The resolved canonical path MUST start with the current working directory. If it escapes (via
.., symlinks, or junction points), reject with:[ERROR] Path escapes project directory: {PATH} - No shell access: Read file content using the Read tool only. Never pass user-provided paths to shell commands (prevents injection via path values)
Command Building
Given the parsed arguments, build the complete CLI command. All user-provided values MUST be quoted in the shell command to prevent injection.
Step 1: Resolve Model
If --model is specified, use it directly. Otherwise, use the effort-based model from the provider table above.
Step 1b: Trust Gate for Codex --skip-git-repo-check
Before using any Codex template, resolve {SKIP_GIT_FLAG} with this gate:
- Verify the consultation is running from the current project working directory (the same workspace where
/consultwas invoked), not an arbitrary external path. - Verify the resolved active tool is Codex (flag, NLP, picker, or restored
--continuesession). - Run
git rev-parse --is-inside-work-treein the current working directory:
- if true: set
{SKIP_GIT_FLAG}to empty string - if false and checks 1-2 passed: set
{SKIP_GIT_FLAG}to--skip-git-repo-check
- If checks 1-2 fail, reject execution with
[ERROR] Refusing Codex --skip-git-repo-check outside trusted working directory.
Codex templates in this skill assume this trust gate has already passed.
Step 2: Build Command String
Use the command template from the provider's configuration section. Substitute QUESTION, MODEL, TURNS, LEVEL, VARIANT, and SKIPGITFLAG with resolved literal values. {SKIP_GIT_FLAG} MUST be set by Step 1b only. Do not read SKIP_GIT_FLAG from inherited shell environment.
If continuing a session:
- Claude or Gemini: append
--resume "SESSION_ID"to the command. - Codex: use
codex exec resume "SESSION_ID" "QUESTION" --json -m "MODEL" {SKIP_GIT_FLAG} -c model_reasoning_effort="LEVEL"instead of the standard command. Use--lastinstead of a session ID for the most recent session. - OpenCode: append
--session SESSION_IDto the command. If no session_id is saved, use--continueinstead (resumes most recent session).
If OpenCode at max effort: append --thinking.
Step 3: Context Packaging
If --context=diff: Run git diff 2>/dev/null and prepend output to the question. If --context=file=PATH: Read the file using the Read tool and prepend its content to the question.
Step 4: Safe Question Passing
User-provided question text MUST NOT be interpolated into shell command strings. Shell escaping is insufficient -- $(), backticks, and other expansion sequences can execute arbitrary commands even inside double quotes.
Required approach -- pass question via stdin or temp file:
- Write the question to a temporary file using the Write tool (e.g.,
{AI_STATE_DIR}/consult/question.tmp)
Platform state directory:
- Claude Code:
.claude/ - OpenCode:
.opencode/ - Codex CLI:
.codex/
- Build the command using the temp file as input instead of inline text:
| Provider | Safe command pattern | |----------|---------------------| | Claude | env -u CLAUDECODE claude -p - --output-format json --model "MODEL" --max-turns TURNS --allowedTools "Read,Glob,Grep" nul -- returns 0 if found
- Unix:
which TOOL 2>/dev/null-- returns 0 if found
Check each tool (claude, gemini, codex, opencode, copilot, kiro) and return only the available ones.
ACP Transport
ACP (Agent Client Protocol) is an alternative transport to CLI subprocess invocation. When available, ACP provides structured JSON-RPC 2.0 communication, session persistence, and streaming responses via a universal protocol supported by all major AI coding tools.
ACP Provider Adapters
| Provider | ACP Command | Type | Detection | |----------|-------------|------|-----------| | Claude | npx -y @anthropic-ai/claude-code-acp | adapter | npx available | | Gemini | gemini (native ACP) | native | gemini available | | Codex | npx -y @zed-industries/codex-acp | adapter | npx available | | Copilot | copilot --acp --stdio | native | copilot available | | Kiro | kiro-cli acp | native | kiro-cli available | | OpenCode | opencode acp | native | opencode available |
Transport Selection
- Check ACP availability for the target provider (see ACP Detection below)
- If ACP available: use ACP transport (preferred - standardized protocol, session persistence)
- If ACP unavailable: fall back to CLI transport (existing behavior above)
The output envelope is identical regardless of transport. Downstream consumers (session management, debate orchestrator, output parsing) are transport-agnostic.
ACP Command Template
All ACP providers use the same command pattern via the ACP runner script:
node acp/run.js --provider="PROVIDER" --question-file="{AI_STATE_DIR}/consult/question.tmp" --timeout=TIMEOUT_MS [--model="MODEL"] [--session-id="SESSION_ID"]
| Provider | ACP Safe Command Pattern | |----------|------------------------| | Claude | node acp/run.js --provider="claude" --question-file="{AI_STATE_DIR}/consult/question.tmp" --timeout=120000 --model="MODEL" | | Gemini | node acp/run.js --provider="gemini" --question-file="{AI_STATE_DIR}/consult/question.tmp" --timeout=120000 --model="MODEL" | | Codex | node acp/run.js --provider="codex" --question-file="{AI_STATE_DIR}/consult/question.tmp" --timeout=120000 --model="MODEL" | | OpenCode | node acp/run.js --provider="opencode" --question-file="{AI_STATE_DIR}/consult/question.tmp" --timeout=120000 --model="MODEL" | | Copilot | node acp/run.js --provider="copilot" --question-file="{AI_STATE_DIR}/consult/question.tmp" --timeout=120000 | | Kiro | node acp/run.js --provider="kiro" --question-file="{AI_STATE_DIR}/consult/question.tmp" --timeout=120000 |
Parse output: Same as CLI transport - JSON.parse(stdout). The ACP runner outputs the same envelope format. Session ID: From JSON.parse(stdout).session_id (ACP session ID) Resume: Pass --session-id="SESSION_ID" flag on the ACP command Continuable: Claude, Gemini, Codex, OpenCode (yes). Copilot, Kiro (no).
ACP Detection
Run ACP detection alongside CLI detection. For each provider:
node acp/run.js --detect --provider="PROVIDER"
Returns on success (exit 0):
{"provider": "claude", "acp_available": true, "name": "Claude"}
Returns on failure (exit 1):
{"provider": "claude", "acp_available": false, "name": "Claude", "reason": "npx not found on PATH"}
Kiro note: Kiro is ACP-only - it has no CLI mode for external consultation. It only appears as available when kiro-cli is on PATH and ACP detection succeeds.
Session Management
Save Session
After successful consultation, save to {AI_STATE_DIR}/consult/last-session.json:
{
"tool": "claude",
"model": "opus",
"effort": "high",
"session_id": "abc-123-def-456",
"timestamp": "2026-02-10T12:00:00Z",
"question": "original question text",
"continuable": true,
"transport": "acp"
}
The transport field is "acp" or "cli". When resuming a session with --continue, use the same transport that created it. If the field is absent, assume "cli" (backward compatible).
AI_STATE_DIR uses the platform state directory:
- Claude Code:
.claude/ - OpenCode:
.opencode/ - Codex CLI:
.codex/
Load Session
For --continue, read the session file and restore:
- tool (from saved state)
- session_id (for --resume flag)
- model (reuse same model)
Before using restored values, re-validate them:
- tool must still be in allow-list: gemini, codex, claude, opencode, copilot, kiro
- session_id must match
^(?!-)[A-Za-z0-9._:-]+$ - model must match
^[A-Za-z0-9._:/-]+$(reject spaces and shell metacharacters) - if either check fails, reject with
[ERROR] Invalid restored session dataand do not build a command
If session file not found, warn and proceed as fresh consultation.
Output Sanitization
Before including any consulted tool's response in the output, scan the response text and redact matches for these patterns:
| Pattern | Description | Replacement | |---------|-------------|-------------| | sk-[a-zA-Z0-9_-]{20,} | Anthropic API keys | [REDACTED_API_KEY] | | sk-proj-[a-zA-Z0-9_-]{20,} | OpenAI project keys | [REDACTED_API_KEY] | | sk-ant-[a-zA-Z0-9_-]{20,} | Anthropic API keys (ant prefix) | [REDACTED_API_KEY] | | AIza[a-zA-Z0-9_-]{30,} | Google API keys | [REDACTED_API_KEY] | | ghp_[a-zA-Z0-9]{36,} | GitHub personal access tokens | [REDACTED_TOKEN] | | gho_[a-zA-Z0-9]{36,} | GitHub OAuth tokens | [REDACTED_TOKEN] | | `githubpat[a-
…
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: agent-sh
- Source: agent-sh/agentsys
- License: MIT
- Homepage: https://agent-sh.github.io/agentsys/
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.