{"id":50564212,"url":"https://github.com/wbnns/cx","last_synced_at":"2026-06-04T13:01:49.191Z","repository":{"id":338031654,"uuid":"1156173337","full_name":"wbnns/cx","owner":"wbnns","description":"[cx] Claude Extender","archived":false,"fork":false,"pushed_at":"2026-03-05T13:22:53.000Z","size":328,"stargazers_count":8,"open_issues_count":1,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-05T17:22:22.995Z","etag":null,"topics":["agent-management","agentic-workflow","claude","claude-code"],"latest_commit_sha":null,"homepage":"https://cx.wbnns.com/","language":"TypeScript","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/wbnns.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"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-02-12T10:49:13.000Z","updated_at":"2026-03-05T13:54:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/wbnns/cx","commit_stats":null,"previous_names":["wbnns/cx"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/wbnns/cx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wbnns%2Fcx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wbnns%2Fcx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wbnns%2Fcx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wbnns%2Fcx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wbnns","download_url":"https://codeload.github.com/wbnns/cx/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wbnns%2Fcx/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33905359,"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-04T02:00:06.755Z","response_time":64,"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-management","agentic-workflow","claude","claude-code"],"created_at":"2026-06-04T13:01:48.284Z","updated_at":"2026-06-04T13:01:49.185Z","avatar_url":"https://github.com/wbnns.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# cx: Claude Extender\n\nAutonomous agent management for [Claude Code](https://docs.anthropic.com/en/docs/claude-code). Create agents that run on schedules, watch for conditions, or maintain persistent sessions — all defined as markdown files in your **cx directory**.\n\n## What It Does\n\ncx runs a background daemon that manages your agents:\n\n- **Scheduled agents** run on cron schedules (daily surf report, weekly digest, etc.)\n- **Watcher agents** run lightweight check scripts and trigger Claude only when conditions are met (new emails, page changes, price alerts)\n- **Persistent agents** maintain long-running sessions with heartbeats and checkpoints\n- **Issue agents** receive issue links (Linear, GitHub Issues, etc.) via Telegram, spin up Claude in a git worktree, open PRs, and autonomously remediate reviewer feedback until the PR is clean\n\nEvery agent is a markdown file with YAML frontmatter. Instructions go in the body, configuration goes in the frontmatter. Run logs, memory, and costs are all stored as markdown — browsable as plain markdown with full backlinks and search.\n\n## Quick Start\n\n```bash\n# Install from source\ngit clone https://github.com/wbnns/cx.git \u0026\u0026 cd cx\nnpm install \u0026\u0026 npm run build \u0026\u0026 sudo npm link\n\n# Initialize from your cx directory\ncd ~/my-project\ncx init\n\n# Configure secrets\ncx secrets set global ANTHROPIC_API_KEY sk-ant-...\n\n# Create your first agent\ncx create surf-report --mode scheduled\ncx edit surf-report    # write instructions\n\n# Start the daemon and trigger a manual run\ncx daemon start\ncx start surf-report\n```\n\n## Agent File Format\n\nAgents are markdown files in `cx/agents/` with YAML frontmatter:\n\n```yaml\n---\nname: gmail-watcher\ntype: agent\nstatus: active\nexecution:\n  mode: scheduled\n  schedule:\n    expression: \"0 6 * * *\"\n    type: cron\n    timezone: Atlantic/Azores\ntools:\n  - mcp__gmail__list_unread\n  - mcp__gmail__read_email\n  - mcp__gmail__archive\n  - mcp__gmail__mark_read\nnotifications:\n  - channel: telegram\n    events: [completion, failure]\nmemory:\n  enabled: true\nenv_ref: email\nmcp_config: /home/deploy/nova/cx/tools/gmail-mcp-config.json\n---\n\n# Gmail Watcher\n\nCheck for new unread emails.\nSummarize anything important and archive the rest.\n```\n\nThe `name` field provides a human-readable identifier. The `mcp_config` field points to a JSON file that tells Claude Code which MCP tool servers to start. Tools prefixed with `mcp__\u003cserver\u003e__` correspond to tools exposed by those servers — see [MCP Tools](#mcp-tools) below.\n\n## Four Agent Modes\n\n### Scheduled\n\nRuns on a cron schedule. Good for daily reports, periodic checks, recurring tasks.\n\n```yaml\nexecution:\n  mode: scheduled\n  schedule:\n    expression: \"0 9 * * 1-5\"  # weekdays at 9am\n    timezone: America/New_York\n```\n\n### Watcher\n\nRuns a cheap check script frequently; triggers Claude only when something happens. Good for email monitoring, page changes, price alerts.\n\n```yaml\nexecution:\n  mode: watcher\n  watcher:\n    script: email-checker.js\n    poll_interval_seconds: 300\n    cooldown_seconds: 3600\n    pass_context: true\n```\n\nWatcher scripts are plain JS or Python in `cx/watchers/`:\n\n```javascript\nmodule.exports = async function check(config) {\n  const data = await fetchSomething();\n  return {\n    triggered: data.hasNewItems,\n    context: { items: data.items }  // passed to Claude\n  };\n};\n```\n\n### Persistent\n\nMaintains a long-running Claude session with heartbeats and checkpoints. Good for ongoing research, monitoring dashboards, or tasks that build state over time.\n\n```yaml\nexecution:\n  mode: persistent\n  persistent:\n    heartbeat_interval_seconds: 1800\n    checkpoint_interval_minutes: 60\n    restart_policy: on_failure\n    max_session_duration_hours: 24\n```\n\n### Issue (Linear Agent)\n\nTriggered by sending an issue link (e.g., Linear, GitHub Issues) to the Telegram bot. A standalone service creates a git worktree, fetches the issue details, spawns Claude to implement the work, opens a PR, and then monitors for reviewer feedback — remediating comments and fixing CI failures in a loop until the PR is clean.\n\n```\nUser sends Linear URL to Telegram\n        │\n        ▼\ntelegram-bot.js detects issue URL\n        │ POST to linear-agent service\n        ▼\nlinear-agent.mjs\n        ├─ Create git worktree from main\n        ├─ Fetch issue details via API\n        ├─ Spawn Claude to implement the work\n        ├─ Detect and report PR URL\n        ├─ Monitor for review comments (every 10 min)\n        │   └─ Remediate feedback, re-request reviews\n        ├─ Check CI after feedback is quiet\n        │   └─ Fix PR-related failures, re-request reviews\n        └─ Notify completion via Telegram\n```\n\nThe service runs as a systemd unit (`cx-linear-agent.service`) and handles concurrent jobs. While this implementation uses Linear, the pattern works with any issue tracker — the issue-fetching function can be swapped for GitHub Issues, Jira, or any system with an API.\n\n## MCP Tools\n\nAgents can use custom tools via [MCP (Model Context Protocol)](https://modelcontextprotocol.io/) servers. An MCP server is a small program that exposes tools over stdio — Claude Code starts it automatically and calls its tools during a run.\n\n### Wiring an MCP server to an agent\n\n1. **Write the server** — a Node.js (or Python) script that implements `ListTools` and `CallTool` handlers using `@modelcontextprotocol/sdk`. Place it in `cx/tools/`.\n\n2. **Create a config JSON** pointing to the server:\n\n```json\n{\n  \"mcpServers\": {\n    \"gmail\": {\n      \"command\": \"node\",\n      \"args\": [\"/home/deploy/nova/cx/tools/gmail-mcp-server.js\"]\n    }\n  }\n}\n```\n\n3. **Reference it in the agent's frontmatter** with `mcp_config`:\n\n```yaml\nmcp_config: /home/deploy/nova/cx/tools/gmail-mcp-config.json\n```\n\n4. **List the tools** in the agent's `tools` array using the `mcp__\u003cserver\u003e__\u003ctool\u003e` naming convention:\n\n```yaml\ntools:\n  - mcp__gmail__list_unread\n  - mcp__gmail__read_email\n  - mcp__gmail__archive\n```\n\nThe server name (`gmail`) matches the key in the config JSON. The tool name (`list_unread`) matches what the server's `ListTools` handler returns.\n\nMCP servers and their configs live in `cx/tools/` by convention, with a shared `package.json` for dependencies.\n\n## CLI Commands\n\n| Command | Description |\n|---------|-------------|\n| `cx init` | Initialize cx in current directory |\n| `cx create \u003cname\u003e` | Create a new agent |\n| `cx edit \u003cname\u003e` | Open agent file in `$EDITOR` |\n| `cx list` | List all agents |\n| `cx status` | Quick status overview |\n| `cx start \u003cname\u003e` | Manually trigger an agent |\n| `cx stop \u003cname\u003e` | Stop a running agent |\n| `cx pause \u003cname\u003e` | Pause an agent |\n| `cx resume \u003cname\u003e` | Resume a paused agent |\n| `cx delete \u003cname\u003e` | Delete an agent (moves to `.trash/`) |\n| `cx logs \u003cname\u003e` | View run logs |\n| `cx memory \u003cname\u003e` | View agent memory |\n| `cx compact \u003cname\u003e` | Trigger memory compaction |\n| `cx costs` | View cost breakdown |\n| `cx secrets` | Manage secret groups |\n| `cx daemon` | Manage background daemon |\n| `cx test-watcher \u003cname\u003e` | Test a watcher script |\n| `cx install-deps` | Install watcher dependencies |\n\n## Memory System\n\nEach agent has persistent memory in `cx/memory/\u003cagent\u003e/current.md`. After every run, the result is appended. This file is included in the next run's context, so agents remember what they've done.\n\nWhen memory exceeds a token threshold, cx automatically compacts it — summarizing old entries into an archive and keeping `current.md` focused.\n\n**Persistent Notes** at the top of `current.md` survive compaction. Use them for long-term facts the agent should always know.\n\n## Secrets\n\nSecrets are stored outside the cx directory at `~/.config/cx/secrets/` so they're never synced or committed:\n\n```bash\ncx secrets set global API_KEY sk-xxx\ncx secrets set email GMAIL_USER you@gmail.com\ncx secrets list\n```\n\nReference a secret group in an agent's frontmatter with `env_ref: \u003cgroup\u003e`. The secrets are injected as environment variables at runtime.\n\n## Cost Management\n\ncx tracks every API call:\n\n```bash\ncx costs                      # totals by agent\ncx costs --period 2026-02     # filter by month\ncx costs --by category        # group by category\n```\n\nSet limits in `config.yaml` and per-agent in frontmatter:\n\n```yaml\n# config.yaml\ncost_limits:\n  daily_usd: 25\n  monthly_budget_usd: 100\n\n# agent frontmatter\nresource_limits:\n  max_cost_usd: 0.15          # per run\n  max_cost_per_day_usd: 5.00  # persistent agents\n```\n\n## Directory Structure\n\n```\nmy-project/\n  cx/\n    agents/           # Agent markdown files\n    services/         # Standalone agent services (e.g., linear-agent.mjs)\n    tools/            # MCP servers, bots, and supporting scripts\n    watchers/         # Watcher check scripts\n    memory/           # Agent memory (current + archives)\n    runs/             # Run logs organized by date\n    _templates/       # Templates for new agents\n    .trash/           # Deleted agents (recoverable)\n    costs.md          # Cost ledger\n    dashboard.md      # Dashboard\n```\n\n## Configuration\n\nGlobal config lives at `~/.config/cx/config.yaml`:\n\n```yaml\ncx_path: ~/my-project\nclaude_path: claude\ndefault_model: sonnet\ndefault_permission_mode: dangerouslySkipPermissions\ntimezone: America/Los_Angeles\ndaemon:\n  tick_interval_seconds: 30\n  log_file: ~/.config/cx/daemon.log\nnotifications:\n  telegram:\n    bot_token: \"YOUR_BOT_TOKEN\"\n    default_chat_id: \"YOUR_CHAT_ID\"\ncost_limits:\n  daily_usd: 25\n  monthly_budget_usd: 100\ncompaction:\n  default_model: haiku\n```\n\n## Requirements\n\n- Node.js 20+\n- Claude Code CLI (authenticated)\n\n## Documentation\n\nSee the full [User Guide](docs/user-guide.md) for detailed documentation including watcher script examples, memory management, the complete configuration reference, and troubleshooting.\n\n## Disclaimer\n\ncx is an independent open-source project and is not affiliated with, endorsed by, or sponsored by Anthropic, PBC. Claude and Claude Code are trademarks of Anthropic, PBC.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwbnns%2Fcx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwbnns%2Fcx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwbnns%2Fcx/lists"}