Common problems and the things ctx-wire deliberately does not do. For the command list see COMMANDS.md; for config and environment variables see CONFIGURATION.md.
- Hook not firing / commands not filtered. Run
ctx-wire doctor. If thePATHcheck warns thatctx-wireresolves to a different binary, reinstall (ctx-wire init <agent>orjust install). If a hook shows "not installed", runctx-wire init <agent>and restart the agent so it reloads its hook config. - Commands fail or the agent errors after an upgrade (
EAGAIN/posix_spawn, a process storm, or "command not found"). An upgrade replaces the ctx-wire binary but not the PATH shims, so a duplicate or stale install can leave old shims on PATH that misbehave. ctx-wire self-heals this: it regenerates managed shims to the current template on the next human-facing command (doctor,gain,version,update).ctx-wire doctoralso reports duplicate ctx-wire binaries or shim dirs on PATH, andctx-wire init <agent>regenerates the shims immediately. - Command is a pipeline, redirection, or shell builtin. These pass through
unchanged by design (see Known limitations).
ctx-wire explain '<cmd>'shows the exact reason. Wrap the producer explicitly if you want it filtered, e.g.ctx-wire run rg TODO . | head. - Codex hook present but nothing happens. Codex requires its hooks feature
enabled and the hook trusted.
ctx-wire doctorreports the feature flag; enable[features] hooks = truein~/.codex/config.toml, then run codex and trust the hook via/hooks. ctx-wire never bypasses Codex trust. gainshows(untagged)commands in the Per Agent breakdown. Directctx-wire runcommands are attributed by walking the process tree withps, and some sandboxes (Codex's, for example) blockps, so the agent comes back empty. For Codex,ctx-wire init codexfixes this by settingCTX_WIRE_AGENT = "codex"inshell_environment_policy.set(ctx-wire doctorreports the state as "codex agent attribution"). For other wrappers, exportCTX_WIRE_AGENT=<agent>in the environment the agent uses for shell commands.- A rules-based agent still runs raw commands. Cline, Windsurf, Kilo Code,
and Antigravity use rules files, not terminal hooks. They improve default
agent behavior, but the agent can still ignore the guidance. Use
ctx-wire explain <cmd>and explicitctx-wire run ...when you need certainty. - A hook-capable agent (Claude, Cursor, Codex, Gemini, Copilot, OpenCode, Pi,
Hermes) stopped filtering after an upgrade. The shim no longer auto-wires
under these agents, they are covered by their own hook or plugin, so if that
hook/plugin is not installed or not active you now get no coverage instead of
the old silent shim fallback. Run
ctx-wire doctor: the hooks section shows whether the agent's hook is configured; if it says "not configured", runctx-wire init <agent>(and for OpenCode/Pi/Hermes enable the plugin in the agent's own config). To force broad shim coverage regardless, setCTX_WIRE_SHIMS=1. - VS Code / Visual Studio Copilot is not filtering. MCP is opt-in: the agent
must choose ctx-wire's
run_commandorread_filetool. There is no transparent interception for these (see Known limitations). ctx-wire gainis empty. Nothing has been recorded yet in this window, or recording is disabled (CTX_WIRE_GAIN=0). Make sure commands are actually being routed throughctx-wire run(check withctx-wire doctorandctx-wire explain <cmd>), then retry after some agent activity.- Storage path not writable.
ctx-wire doctorreports gain/tee writability. ctx-wire falls back to a per-user temp directory when the primary data dir is unwritable (common in agent sandboxes), so capture keeps working;gainreads both locations. A[fail]line means neither the primary nor the fallback is writable.
- MCP and rules files are opt-in, not transparent. MCP can only expose a
callable tool; it cannot replace an editor's built-in terminal. So for VS Code
and Visual Studio Copilot, the agent must choose ctx-wire's
run_commandorread_filetool (steered by the tool descriptions). Cline, Windsurf, Kilo Code, and Antigravity are prompt/rules guidance only. OpenCode, Pi, and Hermes depend on their plugin surfaces. The hook-based agents (Claude Code, Cursor, Codex, Gemini CLI) get transparent interception. - Pipelines wrap only the final stage; redirections are passthrough. For a
pipeline, ctx-wire wraps just the last stage (e.g.
rg TODO . | wc -lbecomesrg TODO . | ctx-wire run wc -l), so the producers run raw and computing consumers likewc/grep/jqstill see the true stream while the agent-facing final output is filtered. If the last stage is not wrappable (a redirect, builtin, or subshell), the whole pipeline passes through unchanged. A segment with a top-level>/<redirect is left unwrapped, because wrapping it would route ctx-wire's output into the redirect target and change what you capture. Subshells(...), brace groups{ ...; }, and shell builtins/keywords are passed through for the same safety reason. The rewriter is a conservative, POSIX-ish recognizer, not a full shell parser;ctx-wire explainreports the exact decision. - Commands that hide another command are passed through, not rewritten. A
command with command/process substitution (
$(...), backticks,<(...)), or a second command smuggled in via a newline or a background&, is left unwrapped so the host agent evaluates the original itself. ctx-wire will not auto-approve or filter a command whose embedded command it cannot attest, so e.g.git log --pretty=$(...)runs raw rather than through a filter. Plain variable expansion ($VAR,${VAR}) and fd redirects (2>&1) are unaffected. - JSON payloads are not reduced. This is enforced by content, not just by
command: if a filter would truncate a complete, valid JSON document on stdout,
ctx-wire emits the document whole instead (up to ~1 MiB; a larger one is
replaced with a notice rather than cut mid-structure), because capping or
truncating JSON produces invalid output that breaks downstream parsers. So a
single-line JSON flowing through
cat, a helper script, or a statusline stays intact. Commands whose job is to compact JSON (jq) opt out withreduce_json = trueand keep capping. Known JSON commands (go list -json,terraform show -json, thetofuequivalents) also have explicit passthrough filters; their non-JSON variants are still compacted. - Unfiltered output is bounded by a passthrough ceiling. A command with no
matching filter streams unmodified up to a generous cap (~64 KB at the
default truncate level); beyond it the head and the tail of each stream are
kept, the omitted middle is replaced by an explicit
[ctx-wire: N bytes omitted ...]marker, and the full scrubbed output is spooled to disk; recover it withctx-wire fetch <hash>(printed as the[full output: ...]hint). Deterministic head+tail only, never a summary. Disable withCTX_WIRE_TRUNCATE=noneor[output] truncate = "none";light/aggressivescale it. - Project filters require trust. A project-local
.ctx-wire/filters.tomlis ignored until you approve it withctx-wire trust(recorded by SHA-256). If the file changes after approval, it reverts to untrusted until re-approved. Revoke approval at any time withctx-wire untrust. Bad filter files are skipped (fail-open) and never break a command.