{"id":50405302,"url":"https://github.com/simonpainter/wtf","last_synced_at":"2026-05-31T01:04:38.104Z","repository":{"id":361500388,"uuid":"1254677896","full_name":"simonpainter/wtf","owner":"simonpainter","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-30T23:26:27.000Z","size":254,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-31T00:14:15.991Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/simonpainter.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-30T21:48:57.000Z","updated_at":"2026-05-30T23:26:31.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/simonpainter/wtf","commit_stats":null,"previous_names":["simonpainter/wtf"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/simonpainter/wtf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonpainter%2Fwtf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonpainter%2Fwtf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonpainter%2Fwtf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonpainter%2Fwtf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/simonpainter","download_url":"https://codeload.github.com/simonpainter/wtf/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/simonpainter%2Fwtf/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33715214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-30T02:00:06.278Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-05-31T01:04:37.507Z","updated_at":"2026-05-31T01:04:38.095Z","avatar_url":"https://github.com/simonpainter.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# wtf\n\n`wtf` explains why your last shell command failed and what to do next.\n\nIt captures:\n\n- the command text\n- its exit status\n- the command's stderr (cleaned of terminal control sequences)\n\nThen it sends that context to an installed agent CLI (**opencode**, **GitHub Copilot CLI**, **Claude Code**, or **OpenAI Codex**) and prints a short plain-English answer.\n\n## Inspiration and approach differences\n\nThis project is directly inspired by:\n\n- https://codeberg.org/ryanbastic/wtf\n- https://github.com/bendusz/wtf\n- Original post: https://www.linkedin.com/feed/update/urn:li:activity:7464652533538631680/\n\nThe three versions share the same core idea (explain terminal failures quickly), but take different approaches:\n\n| Version | Core approach |\n| --- | --- |\n| **This repo (`simonpainter/wtf`)** | Captures command context from shell hooks and captured stderr without re-running the command, then routes to one of multiple CLIs (`opencode`, `copilot`, `claude`). Focus is portable shell-only implementation, multi-agent support, and predictable \"explain only\" behavior. |\n| **`ryanbastic/wtf` (Codeberg)** | Minimal, Claude-first implementation of the original \"type `wtf` after failure\" flow. Emphasizes simplicity and fast setup around captured last-command context. |\n| **`bendusz/wtf` (GitHub)** | Safety-gated re-run model: it can re-execute the last command (allowlist + prompts) to capture fresh output, and optionally propose/run a fix (`--fix`) after confirmation. Emphasizes controlled automation and remediation workflow. |\n\n## Example\n\n```sh\n$ docker run myimage\ndocker: Error response from daemon: No such image: myimage:latest\n$ wtf\nAsking opencode…\nDocker can't find a local image called \"myimage\" because it hasn't been built or pulled yet. Build it with `docker build -t myimage .` from the directory with your Dockerfile, or `docker pull myimage` if it exists in a registry.\n```\n\n## Requirements\n\n- macOS or Linux\n- zsh or bash\n- one agent CLI on your `PATH`: `opencode`, `copilot`, `claude`, or `codex`\n- standard utilities: `sed`, `tail`, `tr`, and `stat` (or compatible equivalents)\n\n## Install\n\n### Recommended\n\n```sh\n./install.sh\n```\n\nThis does the following:\n\n1. Copies `wtf.sh` to `~/.wtf.sh`\n2. Ensures `~/.zshrc` exists and adds:\n   ```sh\n   [ -f ~/.wtf.sh ] \u0026\u0026 . ~/.wtf.sh\n   ```\n3. Adds the same line to `~/.bashrc` only if `.bashrc` already exists\n\nOpen a new shell (or run `. ~/.wtf.sh`) after installing.\n\n### Manual\n\n```sh\ncp wtf.sh ~/.wtf.sh\necho '[ -f ~/.wtf.sh ] \u0026\u0026 . ~/.wtf.sh' \u003e\u003e ~/.zshrc\n```\n\n## Usage\n\nRun any command as usual. If it fails or behaves unexpectedly, run:\n\n```sh\nwtf\n```\n\nIf no prior command has been captured yet, `wtf` exits with:\n\n```text\nNothing to explain yet — run a command first, then type wtf.\n```\n\n## Configuration\n\nAll configuration is via environment variables.\n\n| Variable | Default | Description |\n| --- | --- | --- |\n| `WTF_AGENT` | auto-detect | Force one of `opencode`, `copilot`, `claude`, or `codex`. If set to an unavailable CLI, auto-detection is used instead. |\n| `WTF_TIMEOUT` | `90` | Seconds to allow the agent command to run. Set to `0` to disable. |\n\n### Agent selection order\n\nIf `WTF_AGENT` is not set, agent detection order is:\n\n1. `opencode`\n2. `copilot`\n3. `claude`\n4. `codex`\n\nIf you have multiple agent CLIs installed, you can switch explicitly. For example, to force OpenAI Codex:\n\n```sh\nexport WTF_AGENT=\"codex\"\n```\n\n### Timeout behavior\n\n- Timeout is enforced only when `timeout` or `gtimeout` is installed.\n- On macOS, `gtimeout` is usually available via GNU coreutils:\n  ```sh\n  brew install coreutils\n  ```\n- If timeout is reached, `wtf` exits with a timeout message.\n\n## How it works\n\n1. `wtf.sh` tees shell stderr into a per-shell temp file (`/tmp` or `$TMPDIR`).\n2. A shell hook captures command start (command text + stderr byte offset).\n3. Another hook captures command end (exit status + stderr slice for that command).\n4. `wtf` builds a structured prompt and invokes one CLI command:\n   - `opencode run`\n   - `copilot -p ... -s`\n   - `claude -p`\n   - `codex`\n5. Output is cleaned and printed.\n\n`wtf` does **not** rerun your original command.\n\n## Shell-specific notes\n\n- **zsh**: uses `preexec` and `precmd` hooks.\n- **bash**: uses a `DEBUG` trap and `PROMPT_COMMAND`.\n- A priming guard avoids capturing noise from initial shell startup.\n- `wtf` itself is excluded from capture so it always explains the last real command.\n\n## Tests\n\nA small shell test suite is included at:\n\n```sh\n./tests/test.sh\n```\n\nCurrent coverage includes:\n\n- agent selection (forced and auto-detect order)\n- no-prior-command behavior\n- install script behavior and idempotency\n\n## Contributing and community\n\n- See [CONTRIBUTING.md](CONTRIBUTING.md) for development and PR guidance.\n- See [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) for community expectations.\n- See [SECURITY.md](SECURITY.md) for responsible vulnerability reporting.\n- This project is licensed under the [MIT License](LICENSE).\n\n## Uninstall\n\n```sh\nrm ~/.wtf.sh\n```\n\nThen remove this line from your shell rc files:\n\n```sh\n[ -f ~/.wtf.sh ] \u0026\u0026 . ~/.wtf.sh\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimonpainter%2Fwtf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsimonpainter%2Fwtf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsimonpainter%2Fwtf/lists"}