{"id":48751368,"url":"https://github.com/autonoco/buttons","last_synced_at":"2026-06-27T02:00:45.991Z","repository":{"id":350811823,"uuid":"1208113441","full_name":"autonoco/buttons","owner":"autonoco","description":"CLI workflow engine for agents.","archived":false,"fork":false,"pushed_at":"2026-06-22T09:47:04.000Z","size":793,"stargazers_count":2,"open_issues_count":2,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-22T10:25:20.974Z","etag":null,"topics":["agent-cli","agent-tools","agent-workflows"],"latest_commit_sha":null,"homepage":"https://docs.buttons.sh","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/autonoco.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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-04-11T20:49:41.000Z","updated_at":"2026-06-22T09:46:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/autonoco/buttons","commit_stats":null,"previous_names":["autonoco/buttons"],"tags_count":100,"template":false,"template_full_name":null,"purl":"pkg:github/autonoco/buttons","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/autonoco%2Fbuttons","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/autonoco%2Fbuttons/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/autonoco%2Fbuttons/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/autonoco%2Fbuttons/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/autonoco","download_url":"https://codeload.github.com/autonoco/buttons/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/autonoco%2Fbuttons/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34839005,"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-06-27T02:00:06.362Z","response_time":126,"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":["agent-cli","agent-tools","agent-workflows"],"created_at":"2026-04-12T19:28:09.434Z","updated_at":"2026-06-27T02:00:45.984Z","avatar_url":"https://github.com/autonoco.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Buttons\n\n[![CI](https://github.com/autonoco/buttons/actions/workflows/ci.yml/badge.svg)](https://github.com/autonoco/buttons/actions/workflows/ci.yml)\n[![License](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE)\n[![Release](https://img.shields.io/github/v/release/autonoco/buttons)](https://github.com/autonoco/buttons/releases)\n\nn8n for agents. A CLI workflow engine where AI agents build and run their own automations.\n\nEach button is a self-contained, reusable action. Create it once, press it forever. Buttons wraps code, APIs, and agent instructions into a single interface with typed args and structured output.\n\n## Install\n\nButtons ships as a single static binary for **macOS** and **Linux** (amd64 + arm64). Windows support is tracked in [autonoco/autono#350](https://github.com/autonoco/autono/issues/350).\n\n### curl (macOS / Linux)\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/autonoco/buttons/main/install.sh | sh\n```\n\nInstalls to `/usr/local/bin` by default (uses `sudo` if needed). The script verifies the SHA256 checksum of every download. Override with env vars:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/autonoco/buttons/main/install.sh | BUTTONS_VERSION=v0.70.0 sh\ncurl -fsSL https://raw.githubusercontent.com/autonoco/buttons/main/install.sh | BUTTONS_INSTALL_DIR=$HOME/.local/bin sh\n```\n\n### Homebrew\n\n```bash\nbrew install autonoco/tap/buttons\n```\n\nTap is auto-updated by goreleaser on every release. `brew upgrade buttons` to update.\n\n### Go\n\n```bash\ngo install github.com/autonoco/buttons@latest\n```\n\nInstalls to `$(go env GOPATH)/bin` (usually `~/go/bin`).\n\n### npm / pnpm / bun\n\n```bash\nnpm install -g @autono/buttons\n```\n\nThin JS shim that resolves the platform binary via `optionalDependencies`.\n\n### Docker\n\n```bash\ndocker pull ghcr.io/autonoco/buttons:latest\ndocker run --rm -v $PWD/.buttons:/home/buttons/.buttons \\\n  ghcr.io/autonoco/buttons:latest press weather --arg city=Miami\n```\n\nMulti-arch Alpine image, ~5 MB, published to GHCR. Mount a volume to persist state between invocations.\n\n## Updating\n\n```bash\nbuttons update           # download and install the latest release\nbuttons update --check   # check only\nbuttons update --json    # structured output\n```\n\nThe command downloads the latest release, verifies the SHA256, and atomically replaces the running binary. Homebrew installs are auto-detected — you'll be told to `brew upgrade buttons` instead. Docker users re-pull the image.\n\n## Verify the installation\n\n```bash\nbuttons version\nbuttons --version\n```\n\n## Quick Start\n\n```bash\n# Create a button from an API\nbuttons create weather --url 'https://wttr.in/{{city}}?format=j1' --arg city:string:required -d \"get weather\"\n\n# See what it does\nbuttons weather\n\n# Press it\nbuttons press weather --arg city=Miami\n\n# See the history\nbuttons history weather\n```\n\n## Creating Buttons\n\nThree button types. Use `--prompt` as a modifier on any of them to attach an instruction for the consuming agent.\n\n### Code\n\n```bash\n# Scaffold + edit (default). Creates main.sh with a placeholder, tells you where to edit it.\nbuttons create deploy --arg env:string:required\n# Then edit ~/.buttons/buttons/deploy/main.sh and press:\nbuttons press deploy --arg env=staging\n\n# Or skip the scaffold with --code for one-liners\nbuttons create greet --code 'echo \"Hello, $BUTTONS_ARG_NAME!\"' --arg name:string:required\n\n# Python scaffold\nbuttons create transform --runtime python --arg input:string:required\n\n# Node scaffold\nbuttons create parse --runtime node\n\n# Or import an existing script file\nbuttons create etl --file ./scripts/etl.sh --arg source:string:required\n```\n\n### API\n\n```bash\n# GET with URL templates\nbuttons create weather --url 'https://wttr.in/{{city}}?format=j1' --arg city:string:required\n\n# POST with JSON body\nbuttons create notify --url https://hooks.slack.com/services/xxx \\\n  --method POST \\\n  --header \"Content-Type: application/json\" \\\n  --body '{\"text\": \"{{message}}\"}' \\\n  --arg message:string:required\n\n# GraphQL\nbuttons create repos --url https://api.github.com/graphql \\\n  --method POST \\\n  --header \"Authorization: Bearer {{token}}\" \\\n  --header \"Content-Type: application/json\" \\\n  --body '{\"query\": \"{ repository(owner: \\\"{{owner}}\\\", name: \\\"{{repo}}\\\") { stargazerCount } }\"}' \\\n  --arg token:string:required --arg owner:string:required --arg repo:string:required\n```\n\n### File\n\nImport an existing script. The file is copied into the button folder.\n\n```bash\nbuttons create deploy -f ./scripts/deploy.sh --arg env:string:required\n```\n\n### Agent (standalone or modifier)\n\nThe `--prompt` flag attaches an instruction for the consuming agent. Use it standalone or combine it with code/API buttons.\n\n```bash\n# Standalone: just an instruction\nbuttons create deploy-checklist \\\n  --prompt \"Before deploying, verify: 1) All tests pass 2) Staging is green 3) Team notified\"\n\n# Code + prompt: run the command, agent knows what to do with the output\nbuttons create check-logs \\\n  --code 'northflank logs --service api --env production --tail 100' \\\n  --prompt \"Summarize any errors or warnings from these logs\"\n\n# API + prompt: call the API, agent interprets the result\nbuttons create analyze-weather \\\n  --url 'https://wttr.in/{{city}}?format=j1' \\\n  --arg city:string:required \\\n  --prompt \"Extract temperature and conditions as a one-line summary\"\n```\n\nWhen pressed, the result includes both the output and the `prompt`:\n\n```json\n{\n  \"ok\": true,\n  \"data\": {\n    \"status\": \"ok\",\n    \"stdout\": \"ERROR 2026-04-18 connection timeout to db-primary...\",\n    \"prompt\": \"Summarize any errors or warnings from these logs\",\n    \"button\": \"check-logs\"\n  }\n}\n```\n\n## Pressing Buttons\n\n```bash\nbuttons press weather --arg city=Miami\nbuttons press weather --arg city=Miami --json\nbuttons press weather --arg city=Miami --dry-run   # validate args + render command, don't execute\nbuttons press slow-task --timeout 120\n```\n\n### Arguments\n\n```bash\n# Define at creation\nbuttons create deploy --code '...' --arg env:string:required --arg verbose:bool:optional\n\n# Pass at press time\nbuttons press deploy --arg env=production --arg verbose=true\n```\n\nTypes: `string`, `int`, `bool`, `enum`. Enum declares a fixed set of valid values — the CLI rejects anything outside the set and the board renders a picker:\n\n```bash\nbuttons create deploy --code '...' --arg env:enum:required:staging|prod|canary\n```\n\nCode buttons get args as `BUTTONS_ARG_\u003cNAME\u003e` env vars. API buttons use `{{arg}}` template substitution.\n\n## Discovering Buttons\n\n```bash\nbuttons                    # interactive card-grid board in a TTY, plain table when piped\nbuttons \u003cname\u003e             # full-screen detail page (args, last run, script); press `e` to edit\nbuttons logs \u003cname\u003e        # live log viewer — follow mode with `f`, jump with `g`/`G`, `Esc` to exit\nbuttons list --json        # machine-readable list\n```\n\nOn the board, pressing a button with required arguments opens an inline form instead of erroring out. Fill it in, hit Enter, the press fires.\n\n## Configuration\n\nPersonal defaults live in `~/.buttons/settings.json`. Manage them with `buttons config`:\n\n```bash\nbuttons config                                # show current values\nbuttons config set default-timeout 600        # default for future `buttons create`\nbuttons config set theme amber                # board TUI theme: default | paper | phosphor | amber\nbuttons config unset theme                    # revert to built-in default\n```\n\nEnv var overrides: `BUTTONS_HOME` (relocate the data directory), `BUTTONS_THEME` (one-shot theme override — useful for A/B).\n\n## Secrets (Batteries)\n\nBatteries are key/value pairs injected into every button press as `BUTTONS_BAT_\u003cKEY\u003e=\u003cvalue\u003e`. Use them to keep API tokens out of button scripts.\n\n```bash\nbuttons batteries set APIFY_TOKEN apify_api_xxx       # local by default inside a project, global otherwise\nbuttons batteries set OPENAI_KEY sk-... --global      # ~/.buttons/batteries.json\nbuttons batteries list\nbuttons batteries get APIFY_TOKEN\nbuttons batteries rm OLD_KEY\n```\n\nLocal (`.buttons/batteries.json`) overrides global on key collisions. Keys must match `[A-Z][A-Z0-9_]*`.\n\n## History\n\nEvery press is recorded as a JSON file in the button's `pressed/` folder.\n\n```bash\nbuttons history\nbuttons history weather\nbuttons history --last 5\nbuttons history weather --json\n```\n\n## Deleting Buttons\n\n```bash\nbuttons delete deploy\nbuttons delete deploy -F          # skip confirmation\nbuttons delete deploy --json      # JSON mode implies force\nbuttons rm deploy                 # rm is an alias for delete\n```\n\n## Button Folder Structure\n\nEach button is a self-contained folder:\n\n```\n~/.buttons/buttons/weather/\n  button.json     # spec (args, runtime, timeout)\n  main.sh         # code file (.sh, .py, .js based on runtime)\n  AGENT.md        # agent instruction/context\n  pressed/        # run history\n    2026-04-18T09-53-45.json\n```\n\nOverride storage location with `BUTTONS_HOME`.\n\n## JSON Output\n\nEvery command supports `--json`. Piped output auto-detects non-TTY and outputs JSON automatically.\n\n```json\n{\"ok\": true, \"data\": {\"status\": \"ok\", \"stdout\": \"...\", \"prompt\": \"...\", \"button\": \"weather\"}}\n{\"ok\": false, \"error\": {\"code\": \"MISSING_ARG\", \"message\": \"...\", \"hint\": \"...\", \"spec\": [...]}}\n```\n\nError codes: `NOT_FOUND`, `MISSING_ARG`, `VALIDATION_ERROR`, `TIMEOUT`, `SCRIPT_ERROR`, `RUNTIME_MISSING`, `STORAGE_ERROR`, `NOT_APPLICABLE`, `INTERNAL_ERROR`, `NOT_IMPLEMENTED`.\n\n## Create Flags\n\nBy default, `buttons create \u003cname\u003e` scaffolds a shell button with a placeholder `main.sh` the agent can edit. Shortcut flags below let you skip the placeholder.\n\n| Flag | Short | Description |\n|------|-------|-------------|\n| `--runtime` | | Scaffold runtime: shell, python, node (default: shell) |\n| `--code` | | Inline script body (shortcut for one-liners) |\n| `--file` | `-f` | Copy an existing script file into the button folder |\n| `--url` | | HTTP API endpoint (supports `{{arg}}` templates) |\n| `--method` | | HTTP method (default: GET) |\n| `--header` | | HTTP header as `Key: Value` (repeatable) |\n| `--body` | | HTTP request body (supports `{{arg}}` templates) |\n| `--prompt` | | Prompt instruction written to AGENT.md (standalone or modifier on any source) |\n| `--arg` | | Argument: `name:type:required\\|optional` (enums: `name:enum:required:a\\|b\\|c`) |\n| `--description` | `-d` | Button description |\n| `--timeout` | | Execution timeout in seconds (default: 300) |\n| `--max-response-size` | | Max HTTP response body for `--url` buttons, e.g. `10M`, `1G` (default: `10M`) |\n| `--allow-private-networks` | | Allow `--url` buttons to reach private network addresses (localhost, 10/8, 172.16/12, 192.168/16, 169.254/16). Required for local dev targets. |\n\n## Security\n\n- Every execution runs under `context.WithTimeout` (default 300s)\n- Process group kill: SIGTERM then SIGKILL after 5s grace\n- Args passed as env vars, never interpolated into shell\n- HTTP buttons block private networks by default and cap response bodies\n\nSee [SECURITY.md](SECURITY.md) for the full threat model and how to report vulnerabilities.\n\n## Documentation\n\nFull CLI reference, concepts, and changelog live in the [`docs/`](docs/) directory (published via Mintlify).\n\n## License\n\nButtons is licensed under the [Apache License, Version 2.0](LICENSE).\n\nCopyright 2026 Darley Ventures LLC dba Autono.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fautonoco%2Fbuttons","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fautonoco%2Fbuttons","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fautonoco%2Fbuttons/lists"}