platforms/codex/skills/workspace-cli-bridge/SKILL.md
Use the company WorkSpace `ws` CLI reliably as a delegated coding agent from Codex. Trigger when the user wants Codex to command `ws`, WorkSpace CLI, or the company opencode-derived coding tool to generate code, inspect a repo, run a bounded implementation task, or use a requested WorkSpace model while Codex reviews the output.
npx skillsauth add codingsamss/ai-dotfiles workspace-cli-bridgeInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Use ws as a secondary implementation agent while Codex remains the reviewer and integrator. The reliable path is to attach to a local WorkSpace server, not to cold-start ws run.
On this machine, prefer a terminal-managed ws serve for Codex delegation when it has the company workspace provider loaded. If a terminal-managed server has an empty provider list, quickly inspect the App-managed server before declaring ws unusable. The App-managed server can accept no-tool prompts and may have the live company provider even when terminal-managed ws serve does not; however, it can still hang on bash/file writes, so treat it as write-capable only after a tiny bash/write preflight.
The local node shim only controls whether the ws command starts. Repointing $HOME/.local/bin/node to the Workspace App bundle node fixes a silent CLI startup failure, but it does not make an App-managed server bash-safe and it does not by itself create the old bash-proxy failure. Server choice is the stability boundary.
First discover the currently listening local WorkSpace server port. Do not hard-code the observed port because WorkSpace may start ws serve with --port=0, which can change after a restart.
Prefer terminal-managed servers over App-managed servers when the terminal-managed server exposes the requested provider/model. App-managed servers usually include --cors vscode-file://vscode-app in their command line. If the terminal-managed server provider list is empty but the App-managed server exposes workspace models, use the App-managed server for quick no-tool validation and only proceed to shell/edit work after the preflight checks in Fast Provider Triage.
discover_workspace_attach_url() {
for pid in $(pgrep -f '[w]s serve'); do
cmd="$(ps -p "$pid" -o command= 2>/dev/null)"
case "$cmd" in
*"--cors vscode-file://vscode-app"*) continue ;;
esac
url="$(
lsof -Pan -p "$pid" -iTCP -sTCP:LISTEN 2>/dev/null |
awk '$9 ~ /^127\.0\.0\.1:[0-9]+$/ { print "http://" $9; exit }'
)"
if [ -n "$url" ]; then
printf '%s\n' "$url"
return 0
fi
done
return 1
}
WORKSPACE_ATTACH_URL="$(discover_workspace_attach_url)"
if [ -z "$WORKSPACE_ATTACH_URL" ]; then
echo "No terminal-managed WorkSpace ws server is listening on 127.0.0.1. Start one with: ws serve --hostname=127.0.0.1 --port=0" >&2
exit 1
fi
WORKSPACE_MODEL="${WORKSPACE_MODEL:-workspace/gpt-5.4}"
Then attach to the discovered URL:
ws run \
--attach "$WORKSPACE_ATTACH_URL" \
--dir "<target-repo-or-workdir>" \
--agent build \
--model "$WORKSPACE_MODEL" \
--format json \
--title "<short-task-title>" \
"<bounded task prompt>"
Default to workspace/gpt-5.4 when that model is listed by the attached server. If the user explicitly asks for another model, set WORKSPACE_MODEL to that exact provider/model ID for the whole delegation batch, for example:
WORKSPACE_MODEL="workspace/claude-sonnet-4.6"
Run the no-tool provider preflight with the requested model before real work. If the requested model is unavailable, report the exact model error and do not silently fall back to workspace/gpt-5.4 unless the user asks you to.
Use --agent build for code edits. Use --agent plan for planning-only work. Do not use general or explore for ws run; they are subagents in this CLI and may fall back to the default agent.
Always pass --dir. Do not let ws default to $HOME or the current chat workspace when the task targets a specific repo.
Prefer a directory already covered by the attached WorkSpace server. Passing an unrelated external directory such as /tmp/... can hang before JSON events because the server may wait on external-directory permission or project switching. If a no-op connectivity check is needed, use the active workspace directory rather than an arbitrary temp directory.
Creating or editing files outside the active workspace, for example under $HOME/Desktop, can also hang after the model starts because the file write needs external-directory permission. Treat this as a permission-boundary test, not as proof that the selected $WORKSPACE_MODEL is unavailable.
Use this quick path when ws run reports Model not found, Provider not found: workspace, no providers found, or exits with no JSON events:
discover_app_workspace_attach_url() {
for pid in $(pgrep -f '[w]s serve'); do
cmd="$(ps -p "$pid" -o command= 2>/dev/null)"
case "$cmd" in
*"--cors vscode-file://vscode-app"*) ;;
*) continue ;;
esac
url="$(
lsof -Pan -p "$pid" -iTCP -sTCP:LISTEN 2>/dev/null |
awk '$9 ~ /^127\.0\.0\.1:[0-9]+$/ { print "http://" $9; exit }'
)"
if [ -n "$url" ]; then
printf '%s\n' "$url"
return 0
fi
done
return 1
}
inspect_workspace_models() {
local url="$1"
curl -s "$url/config/providers" |
jq -r '.providers[]? | select(.id=="workspace") | .models | to_entries[] | [.key, .value.name, .value.status] | @tsv'
}
Expected App-managed result on this machine can include:
gpt-5.4 GPT-5.4 active
gpt-5.2-codex GPT-5.2-Codex active
claude-sonnet-4.6 Claude-4.6-Sonnet active
qwen3.6-plus Qwen3.6-Plus active
Important distinction:
GPT_5.4 / GPT-5.4 are display names.ws run --model value must use the provider/id form, for example workspace/gpt-5.4.ProviderModelNotFoundError for workspace/gpt-5.4 if its /provider output is empty; in that case the model may still work through the App-managed server.Fast validation sequence:
APP_ATTACH_URL="$(discover_app_workspace_attach_url)"
WORKSPACE_MODEL="${WORKSPACE_MODEL:-workspace/gpt-5.4}"
curl -s "$APP_ATTACH_URL/provider" | jq '{providers: [.all[]?.id], defaults: .default}'
inspect_workspace_models "$APP_ATTACH_URL" | sed -n '1,20p'
ws run \
--attach "$APP_ATTACH_URL" \
--dir "<target-dir>" \
--agent build \
--model "$WORKSPACE_MODEL" \
--format json \
--title app-provider-no-tool-check \
"Do not read or modify files and do not run commands. Reply only: OK."
Treat a JSON text event containing OK as proof that the App-managed server can call the selected model. This validates model connectivity only; it does not prove bash or file writes are safe.
For tasks that need edits through an App-managed server, run a minimal write preflight inside the target repo before delegating real work:
ws run \
--attach "$APP_ATTACH_URL" \
--dir "<target-dir>" \
--agent build \
--model "$WORKSPACE_MODEL" \
--format json \
--title app-write-check \
"Use bash exactly once to create, read, and remove .ws_write_check.tmp in the current directory. Do not touch any other file. Reply with the command output and exit code."
If the App-managed preflight hangs after bash/tool approval, stop only that ws run process and do not use the App-managed server for edits. If it completes, proceed with a bounded prompt, keep stdout small, and ask ws to write files directly rather than streaming large logs.
Check that the local server is listening and capture its attach URL:
WORKSPACE_ATTACH_URL="$(discover_workspace_attach_url)"
WORKSPACE_MODEL="${WORKSPACE_MODEL:-workspace/gpt-5.4}"
printf '%s\n' "$WORKSPACE_ATTACH_URL"
printf '%s\n' "$WORKSPACE_MODEL"
Expected server shape:
http://127.0.0.1:<port>
workspace/gpt-5.4
WorkSpace ws does not automatically read Codex's skill registry from ~/.codex/skills, and it does not use ~/.config/opencode/opencode.json as its active config in this local build.
Observed ws skill list --print-logs loads config from:
$HOME/.local/share/workspace-code-prd/workspace-cli/config.json
$HOME/.local/share/workspace-code-prd/workspace-cli/opencode.json
$HOME/.local/share/workspace-code-prd/workspace-cli/opencode.jsonc
If those files do not define skills.paths, ws skill list only shows the built-in skills. To expose Codex local skills to ws, keep this file:
{
"skills": {
"paths": [
"$HOME/.codex/skills"
]
}
}
at:
$HOME/.local/share/workspace-code-prd/workspace-cli/opencode.json
This was verified locally: before the file existed, ws skill list showed 5 built-ins; after adding $HOME/.codex/skills, it showed 25 skills including midea-recall-diagnose and workspace-cli-bridge.
The TUI /skills command palette is not authoritative for full discovery. It shows a filtered, scrollable suggestion list based on the current input. If a known local skill such as midea-recall-diagnose is not visible while typing /skills, verify with ws skill list or type a narrower prefix such as /midea.
Project-local skills also work without global config when placed under:
<project>/.agents/skills/<skill-name>/SKILL.md
Use project-local skills for repo-specific instructions. Use the global WorkSpace config above only when the goal is to let ws see the same local skill pool Codex uses.
Do not start and stop ws serve for every single ws run. Treat terminal-managed ws serve as a short-lived local backend for a task batch:
ws delegation batch, discover an existing terminal-managed server and reuse it.ws now, start one terminal-managed ws serve.--session <session-id> for follow-up turns.ws work is expected, close the terminal-managed server started for that batch.This keeps context available across follow-ups without making every interaction pay startup cost. Do not close the App-managed server; leave it for the GUI.
If nothing is listening, start a terminal-managed server only when the user wants Codex to drive ws now:
ws serve --hostname=127.0.0.1 --port=0
Keep the server running, capture the printed http://127.0.0.1:<port> URL, and attach to that URL. The server prints a warning if OPENCODE_SERVER_PASSWORD is unset; this is acceptable for local-only 127.0.0.1 testing but should not be exposed beyond localhost.
If a freshly started terminal-managed server returns ProviderModelNotFoundError for $WORKSPACE_MODEL, inspect its /provider output before retrying. If /provider is empty and logs contain unknown certificate verification error Failed to fetch user config, the terminal server did not load the company provider; do not waste time retrying the same terminal command. Use Fast Provider Triage to check the App-managed server, and only use it for edits after the write preflight.
For a low-cost live check:
ws run \
--attach "$WORKSPACE_ATTACH_URL" \
--dir "<target-dir>" \
--agent build \
--model "$WORKSPACE_MODEL" \
--format json \
--title connectivity-check \
"Do not read or modify files and do not run commands. Reply only: OK."
Treat a JSON text event containing OK as proof that the selected $WORKSPACE_MODEL path is usable.
For any task that may use shell tools, also run a bash preflight:
ws run \
--attach "$WORKSPACE_ATTACH_URL" \
--dir "<target-dir>" \
--agent build \
--model "$WORKSPACE_MODEL" \
--format json \
--title bash-check \
"Use the bash tool exactly once to run: git status --short. Do not modify files. Reply with stdout and exit code."
The expected result is a completed tool_use for bash with exit code 0. If logs show permission=bash ... action=allow followed by bash.proxy.execute.requested but no completion, stop only that ws run and switch to a terminal-managed server.
Do not rely on cold-start model discovery:
ws models workspace
ws run --model "$WORKSPACE_MODEL" ...
Known terminal-managed failure modes:
Provider not found: workspace
Model not found: workspace/gpt-5.4
ProviderModelNotFoundError
no providers found
unknown certificate verification error Failed to fetch user config
This can happen because ws run checks the requested model before the company workspace provider is injected, or because terminal-managed ws serve failed to fetch user config and therefore exposes an empty provider list. Retrying the same command without --attach is not a reliable fix. Compare terminal /provider with the App-managed /config/providers before concluding the model is unavailable.
Never pass --dangerously-skip-permissions.
Avoid ws debug agent ... for routine checks. It can initialize checkpoints and update local Git hooks.
If ws --version or ws --env=prd --version exits immediately with no output, or an interactive shell prints zsh: killed ws, verify the shim node:
readlink "$HOME/.local/bin/node"
$HOME/.local/share/workspace-code-prd/bin/node/darwin-arm64/node --version
/Applications/Workspace\ CLI-PRD.app/Contents/Resources/app/extensions/midea-workspace.workspace-code/bin/node/darwin-arm64/node --version
If the cache node fails but the App bundle node works, use the durable repair: keep a backup of the bad cache node, replace the cache node with a symlink to the App bundle node, then allow the normal ~/.local/bin/node -> cache node shim to remain in place.
ts="$(date +%Y%m%d%H%M%S)"
cache_node="$HOME/.local/share/workspace-code-prd/bin/node/darwin-arm64/node"
app_node="/Applications/Workspace CLI-PRD.app/Contents/Resources/app/extensions/midea-workspace.workspace-code/bin/node/darwin-arm64/node"
mv "$cache_node" "${cache_node}.bad.${ts}"
ln -s "$app_node" "$cache_node"
ln -sfn "$cache_node" "$HOME/.local/bin/node"
ws --version
This only repairs the local ws wrapper runtime; it does not change project files.
The shim can be regenerated by WorkSpace App restart and point back to the cache node. That is expected after the durable repair: ~/.local/bin/node may point to the cache node, while the cache node itself points to the App bundle node.
Make every prompt bounded and reviewable:
Goal:
- <one concrete outcome>
Scope:
- Work only in <paths/modules>.
- Do not touch <forbidden files/areas>.
Implementation constraints:
- Follow existing project style.
- Keep the patch minimal.
- Do not commit, push, reset, or delete files.
- Do not read secrets or .env files unless explicitly required.
Verification:
- Run <safe test/lint command> if appropriate.
- If the command is not safe to run, say why and leave it for Codex/user.
Output:
- Summarize changed files.
- Report commands run and failures.
For Java services, keep the existing user convention: do not start mvn or launch the service unless the user explicitly asks. Provide the command or ask the user to start it.
After ws returns, Codex must review the result locally before accepting it:
git status --short
git diff --stat
git diff
Run the narrowest relevant verification command when safe. If verification is blocked by environment, service startup, credentials, or high cost, report the exact blocker.
Default to reusing the existing ws session for follow-up edits, retries, or refinements on the same target task or files. This is the common case when the user says things like "continue", "重新改下", "让他再改", or gives a correction to the previous ws result.
Start a new ws session only when the user explicitly asks for a fresh session, independent second opinion, or separate context, or when the task clearly changes to a different repo/module/objective. If reuse could bias an independent review, ask briefly before choosing.
When continuing a successful ws conversation, reuse its session:
ws run \
--attach "$WORKSPACE_ATTACH_URL" \
--dir "<target-dir>" \
--session "<session-id>" \
--agent build \
--model "$WORKSPACE_MODEL" \
--format json \
"<follow-up prompt>"
Prefer explicit --session over --continue when reproducibility matters.
ws run may update .git/hooks/post-commit through the WorkSpace checkpoint/AI stats integration. Git will not show this in git status because hooks live under .git/. If hook behavior matters for the repo, inspect .git/hooks/post-commit and ask before removing or disabling it.
If a ws run emits an error event but leaves a process running, terminate only the ws run process you started. Do not kill the long-running WorkSpace server unless the user asks.
If a ws run --attach ... --dir <external-dir> produces no JSON events and no model error for 20-30 seconds, suspect an external-directory/project-switch wait. Stop that ws run process and retry with the active workspace directory or a repo already opened by WorkSpace.
If ws starts responding but then hangs while trying to write a file outside the active workspace, stop that ws run process and report the external-directory permission boundary. Do not bypass it with --dangerously-skip-permissions.
Keep internal provider URLs, tokens, and auth.json contents out of prompts, commits, and skill files. Refer to the selected model as $WORKSPACE_MODEL, which defaults to workspace/gpt-5.4, unless a task specifically requires deeper local diagnostics.
development
Query Midea MX / 美信 local message cache through the MX local HTTP query service from Codex. Use when the user asks to read MX sessions, search chat history, search messages globally or inside a group/session, list recent messages, or page message history. This is read-only and does not require send authorization. Never fall back to reading SQLite or app cache files directly.
development
Safely search MX users or groups and send Midea MX / 美信 IM messages from Codex. Use when the user asks to notify someone, send a message to a person or group, use a configured group alias, @ users, @ all, or send MX file/image messages. Read lookups need no extra authorization; every live send needs explicit user authorization for that exact target and message.
tools
MX channel output rules. Always active in MX conversations.
development
Safely work with Midea MX / 美信 interactions from Codex. Use when the user asks to search MX users or groups, prepare or send an MX message, notify someone in MX, inspect MX message-query capabilities, search MX chat history, or understand MX ocToken / UA auth behavior. Prefer dry-run before any live send.