Skip to main content

coding-cli-management

Execute AI coding CLI tools (Claude Code / Gemini CLI / qodercli / Qwen Code / OpenCode) on behalf of Workers. Use when a Worker sends a coding-request: message, asking the delegating agent (Manager, team Leader, or an authorized Worker) to run coding operations in their workspace.

Source facts

Repository
agentscope-ai/AgentTeams
Last source activity
October 30, 2026 at 18:14
Detected SKILL.md language
English
Stars
5,917
Forks
730

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
5 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
coding-cli-management
description
Execute AI coding CLI tools (Claude Code / Gemini CLI / qodercli / Qwen Code / OpenCode) on behalf of Workers. Use when a Worker sends a coding-request: message, asking the delegating agent (Manager, team Leader, or an authorized Worker) to run coding operations in their workspace.
# Coding CLI Management > Language/i18n: skill instructions and templates are **English** (agent-facing). > Deployments may localize outbound messages at the channel layer; do not > hardcode localized copy in this skill. This skill enables the delegating agent (Manager, team Leader, or an authorized Worker) to execute AI coding CLI tools (claude/gemini/qodercli/qwen/opencode) on behalf of Workers. Workers generate precise prompts; the delegating agent runs the CLI in the Worker's workspace and returns the result. Operational guidance distilled from field operation, in two parts, both detailed in [`references/delegation-guidance.md`](references/delegation-guidance.md) — Part A (first increment, currently supported): task-spec discipline, auth and execution boundary, preflight checks (including runner placement), and a pitfalls list; Part B (later capabilities, not yet implemented, evaluated separately): supervision and steering (including the delivery and wake contract), approval expectations, and a pitfalls list. ## Config File Path: `~/coding-cli-config.json` — this is the **delegating agent's own** config file (the agent running this skill), not a shared one. ```json { "enabled": true, "cli": "claude", "confirmed_at": "2026-02-23T10:00:00Z" } ``` | `enabled` | `cli` | Meaning | |-----------|-------|---------| | `false` | any | Admin declined; use normal task flow | | `true` | `"claude"` / `"gemini"` / `"qodercli"` / `"qwen"` / `"opencode"` | Active — use this CLI | Optional budget / execution-boundary fields (consumed by `run-coding-cli.sh` for `qwen` only — the other runners have no equivalent and ignore them): | Field | Type / default | Meaning | |-------|----------------|---------| | `max_session_turns` | integer, default absent / `0` (flag not passed) | Caps the qwen run at N model turns (`--max-session-turns <N>`); a run that reaches the cap terminates at the budget | | `sandbox` | boolean, default `false` | Adds `--sandbox` (Docker-backed) to the qwen run. Requires docker at the execution site — leave off where docker is unavailable (as in many agent containers) | | `approval_mode` | string, default `yolo` | Approval tier for the qwen run: `yolo` → `--yolo` (the default, byte-identical to the pre-boundary wrapper); `plan` / `default` / `auto-edit` / `auto` → `--approval-mode <tier>`. In a non-interactive one-shot run only `yolo` and `plan` actually work — the ask tiers stall (see Execution boundary below). An invalid value fails the run with the valid values listed; there is no silent fallback | | `max_wall_time` | string, default absent (flag not passed) | Native qwen wall budget → `--max-wall-time <val>` (qwen value formats: `90` / `30s` / `5m` / `1h` / `1.5h`); qwen aborts an over-budget run with exit code 55. The wrapper's `--timeout` remains the hard backstop for all runners | Config example (tight one-shot boundary — read-only plan + 30-minute native wall budget): ```json { "enabled": true, "cli": "qwen", "approval_mode": "plan", "max_wall_time": "30m" } ``` The config path can be overridden with the `CODING_CLI_CONFIG` environment variable (the verify script uses this for its turn-budget case). **Per-run governance flags (qwen).** `run-coding-cli.sh` accepts optional per-run control flags for the qwen runner (other runners warn and ignore them — they have no equivalent surface): | Flag | Maps to | Effect | |---|---|---| | `--model <name>` | `-m` | per-run model override — the task-level tier of two-tier model control (platform default from the runner's settings, per-task switch here) | | `--allowed-tools <csv>` | `--allowed-tools` | tool allowlist — a **code-level** permission boundary, independent of prompt discipline | | `--allowed-mcp <csv>` | `--allowed-mcp-server-names` | MCP server allowlist — scenario isolation (e.g. only this task's toolchain MCP) | | `--safe-mode` | `--safe-mode` | disable all customizations (hooks, extensions, skills, MCP, QWEN.md) — clean-environment runs | | `--bare` | `--bare` | minimal mode | | `--approval-mode <tier>` | `--yolo` / `--approval-mode <tier>` | execution-boundary tier for the qwen run (`plan` / `default` / `auto-edit` / `auto` / `yolo`). Precedence: per-run flag > config `approval_mode` > `yolo` default. An invalid tier fails the run with the valid values listed (no fallback) | | `--max-wall-time <val>` | `--max-wall-time <val>` | native qwen wall budget (value formats `90` / `30s` / `5m` / `1h` / `1.5h`); an over-budget run aborts with exit code 55. Precedence: per-run flag > config `max_wall_time` > unset (flag not passed) | Use the runner's own init frame (`-o json` prints a `tools` array and `permission_mode`) to size an allowlist from the actual capability list rather than from memory. The five governance flags were field-verified on qwen 0.25.0 (safe-mode banner, emptied MCP list, per-run model override observed in one run). `--approval-mode` / `--max-wall-time` were field-verified on qwen 0.25.1 (one-shot plan-tier read boundary, and the native exit-55 wall-budget path observed end to end through this wrapper), and the wrapper's arg assembly for all seven is covered by `manager/tests/test-run-coding-cli-exec-boundary.sh`. **Updates.** Re-run the npm install command to upgrade in place, or use the runner's built-in `qwen update` self-update command (see `qwen update --help` for its channel behavior). Either way, re-run `verify-coding-cli.sh` afterwards (upgrade discipline above). **Runner notes (Qwen Code / OpenCode).** Headless invocations used by `run-coding-cli.sh`: `qwen --yolo "<prompt>"` and `opencode run --auto --dir <workspace> "<prompt>"`. Config surfaces: `~/.qwen` (`settings.json` `security.auth`, or provider env) and `~/.config/opencode` plus `~/.local/share/opencode/auth.json` (credentials stored by `opencode auth login`) or provider env. Both runners were verified with a headless round trip before inclusion. Qwen Code has **no fixed pin**: deployments choose their own npm channel tag (Section below, stable by default); `0.25.1` is the most recent field-verified reference (2026-10-11, Pi arm64/node 24 LTS end-to-end), `0.25.0` the previous one. Re-run `verify-coding-cli.sh` whenever the version actually used changes. **Drift boundary note (settled 2026-10-30):** the 2026-10-19 premise that `0.25.1` and earlier kept the native `--json-file` file semantics is settled by real-CLI measurement (headless one-shot, `qwen -m qwen3.6-27b-fp8 --json-file <abs path> "Reply OK"`, isolated HOME with a working `~/.qwen/settings.json`): **no published qwen writes the native `--json-file` file** — `0.24.7`, `0.25.0`, `0.25.1` and `0.25.2` all exit 0 and produce no file (`--yolo` and `-o json` change nothing), matching the already-known `0.25.3` and `0.26.3`; `0.25.1`/`0.25.2` `--help` already describe `--json-file` as dual output (TUI renders on stdout, JSON events to the file) that never lands headless. The wrapper's capture branch (the `-o json` stdout event array) is therefore the **default for every version**, and the native pass-through is reachable **only** through an explicit `CODING_CLI_JSON_BOUNDARY` override pinning an older CLI — an escape hatch with no supported version, whose post-run assertion fails loudly (`JSON-FILE-DRIFT`) when the file does not land. The legacy cassette baseline is recorded as `unsupported` with this evidence (`tests/cassettes/qwen-json-file-legacy.meta.json`); the modern baseline replays PASS on `0.26.3` against this head. **Version behavior note (0.25.1, field-verified by request capture):** the built-in default model changed to `qwen3.7-max`; a settings file carrying only `security.auth` (plus even an explicit `model.name`) still produced requests for `qwen3.7-max`. On a custom OpenAI-compatible gateway that does not serve that model this surfaces as `API Error: 403 (no body)`. Managed deployments: pass `-m <model>` per run (or the `--model` flag of `run-coding-cli.sh`) rather than relying on a settings-level default. **Platform note (16K-page arm64, e.g. Raspberry Pi 5, kernel `PAGESIZE=16384`):** the vendored ripgrep arm64 binary crashes on startup (`jemalloc: Unsupported system page size`, core dump); `qwen` logs it and falls back to the built-in grep, so runs complete — expect the stderr noise and core files, and do not treat them as run failures. Upstream issue pending. - --json-file <path> — optional structured output; the wrapper's contract: when the run ends, a parseable JSON audit file exists at <path>. The mechanism: **the wrapper itself captures the `-o json` stdout event array into <path> (stderr is diverted to the run log to keep the file pure JSON) — the default for every version** (measured 2026-10-30 with the real CLI: no published qwen, `0.24.7`-`0.26.3`, writes the native `--json-file` file in headless one-shot mode, so there is no version the pass-through serves); a post-run assertion proves the capture is non-empty and parseable before it is moved onto <path> (an empty or unparseable capture fails the run loudly, `JSON-FILE-DRIFT` / `JSON-CAPTURE-FAILED`, instead of recording ok). The native pass-through exists **only** behind an explicit `CODING_CLI_JSON_BOUNDARY` override (detected qwen version vs the override, `sort -V`; detection failure with the override set also lands there) pinning an older CLI — an escape hatch with no supported version, whose post-run assertion fails loudly when the file does not land. A pre-existing non-regular target (FIFO/device) is refused before the run on both branches (regular file paths only). Default off, raw stream still tees to the run log (the audit source of truth when the flag is absent); with the flag, the run log also carries the captured JSON array plus one structured branch-record line per json run. **Version channels and upgrades (Qwen Code).** qwen-code iterates fast (several hundred npm versions published) and ships three channels as dist-tags: `latest` (stable), `nightly` (dated + commit, published daily), and `preview`. Install or upgrade with npm (Node.js **24 LTS** — floor 22.20+ / 24.5+, OpenSSL 3.5 generation; see the Node-generation note in the install matrix), choosing the channel per the user's preference — stable by default, nightly only when the user explicitly wants newer behavior: ```bash npm install -g @qwen-code/qwen-code@latest # stable npm install -g @qwen-code/qwen-code@nightly # nightly ``` Re-running the same command upgrades in place; `qwen --version` confirms the result. **Upgrade discipline: after any version change — including a channel switch — re-run `scripts/verify-coding-cli.sh`; a channel switch is a pin promotion and needs the same verification.** The official standalone installer and Homebrew are fine for interactive use; the verify discipline above is defined for the npm channel. **Install matrix and network environment.** Three official installers; pick by what the execution site has (a Node.js generation requirement applies to the npm channel, below): | Installer | Requires | Version selection | |---|---|---| | npm: `npm install -g @qwen-code/qwen-code@<tag>` | Node.js **24 LTS** (floor 22.20+ / 24.5+, OpenSSL 3.5 generation — see note) | channel tag (`latest` / `nightly` / `preview`) — the route this skill's verify discipline is defined for | | official standalone script: `curl -fsSL https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install-qwen-standalone.sh \| bash` (Windows: `irm …install-qwen-standalone.ps1 \| iex`) | bash, no Node | the build the script ships; re-run to refresh | | Homebrew: `brew install qwen-code` | brew | brew's current release | npm and the release assets cover Linux x64/arm64, macOS x64/arm64, and Windows. Restart the terminal after a standalone install so the PATH entry takes effect. **Node generation matters on restrictive links.** The npm package runs on Node.js; early Node 22.x (22.0–22.19) bundles OpenSSL 3.0, whose TLS client fingerprint is reset by some middle boxes, while Node 22.20+, 24.5+ and 26 bundle OpenSSL 3.5 and pass. **Use Node 24 LTS as the target** — Node 25 is EOL (2026-06), do not provision it; the 22-series needs 22.20+, the 24-series 24.5+. Field-verified 2026-10 (the cctechstudio WAN line RSTs the 3.0 generation but not 3.5). The filter matches the full ClientHello fingerprint (stack + ALPN + extensions), not the OpenSSL version alone: in the same environment an h2-enabled curl was reset while a Node runtime — and even a plain `openssl s_client` — connected. If in doubt, verify with the runtime that will actually make the connection, and check the Node/OpenSSL generation first (`node -p "process.versions.openssl"`). **Model configuration.** `qwen` authenticates from `~/.qwen/settings.json` — `security.auth` with `selectedType` (`openai` / `openai-responses` / `anthropic` / `qwen-oauth` / `gemini` / `vertex-ai`) plus `apiKey` and, for OpenAI-compatible endpoints, `baseUrl` — the form headless delegation uses on self-hosted or gateway-backed deployments (or the `OPENAI_API_KEY` environment variable). The interactive `qwen auth` flow was removed in 0.25.0, so file/env configuration is the only path; `--auth-type <type>` selects the scheme per run. Any OpenAI-compatible endpoint is a valid `baseUrl` — including a **transparent local proxy**, which is the standard lever for keeping the model plane working behind a restrictive link. Per-run overrides: `-m <model>` to pick a model and `-o text|json|stream-json` for machine-readable output. Note (measured 2026-10-30): no published qwen (`0.24.7`-`0.26.3`, headless one-shot) writes the native `--json-file` file, so the wrapper no longer passes it through at all by default (it captures the `-o json` stdout instead; the pass-through exists only behind an explicit `CODING_CLI_JSON_BOUNDARY` override — see the `--json-file` flag row above). **Restricted-network note.** If installing or reaching the model endpoint fails with connection resets while plain `curl` from the same machine succeeds, suspect middle-box filtering by TLS-stack fingerprint rather than a plain outage; running a current Node (OpenSSL 3.5 generation) or routing the model plane through the local proxy above is the working fix. (Field-verified 2026-10; see #1340 notes 4/5 for the full deployment matrix.) **OpenCode is a Bun binary, not Node.** Its TLS client is Bun's (a BoringSSL-lineage stack), not Node's OpenSSL, so on the restrictive lines above OpenCode's *own* connection can be reset by the middle box even where a Node/OpenSSL-3.5 runner (Qwen Code) on the same machine passes. Field-verified 2026-10-10 on the cctechstudio WAN line: `qwen` (Node 24) reached the endpoint and completed a task while `opencode 1.18.35` was RST ("socket connection closed unexpectedly") on the identical link, at the same moment — the only variable being the client's TLS stack. For OpenCode the "use a current Node" advice does not apply (it is not Node, and its TLS stack is not user-selectable); the working lever is the **transparent local relay/proxy** in front of the model endpoint — point OpenCode's `baseURL` (or `OPENAI_BASE_URL`) at the same-machine proxy that holds a working TLS stack. Re-verified 2026-10-11 with `opencode 1.19.0` inside an arm64 worker container (node 24 LTS): Bun binary RSTs the WAN link, same-container loopback relay (node 24) → gateway → full coding task green. **Config location (1.19.0, field-verified):** provider config is loaded from the **project-level** `<workspace>/.config/opencode/opencode.json` (or `.jsonc`); a global `~/.config/opencode/opencode.json` is not picked up by `opencode run --dir <workspace>` (log shows only the project paths loaded) — an unrecognized provider then fails as `ProviderModelNotFoundError`. For headless delegation, keep the provider config project-level next to the workspace. **Unattended semantics — read before enabling.** - `qwen --yolo` automatically approves **all** tool calls — file edits and shell commands included, with no further prompts. - `opencode run --auto` auto-approves permissions, but **explicit deny rules are still enforced**. - `qodercli --yolo` bypasses prompts **only in a trusted directory**: in an untrusted workspace it silently falls back to `default` mode, where every would-ask operation is **auto-denied in headless** — the run degrades to read-only with no error. Org policy `security.disableYoloMode` disables `--yolo` entirely. - **Neither changing the working directory nor adding a timeout establishes a permission boundary.** The workspace and the timeout shape scope and duration only; the runner keeps every capability of the delegating agent's process. --- ## Execution boundary The CLI process runs **as the delegating agent** (Manager, team Leader, or an authorized Worker). It therefore inherits that agent's filesystem visibility and its environment — including any credentials present as environment variables — and nothing in this skill changes that. When deciding whether to enable CLI delegation, assess at least: - **Workspace access scope** — the run is pinned to the task workspace, but a runner in auto-approve mode can reach anything the delegating agent's account can.
View on GitHub
This SKILL.md is very large, so SkillsMP previews the first section here. View on GitHub