Skip to content

Architecture

claude-ops bot edited this page Apr 14, 2026 · 3 revisions

Architecture

How claude-ops works internally — structure, data flow, token efficiency, and the security model.

Token Efficiency Agents Skills Daemon


System overview

flowchart TB
    subgraph CC["Claude Code"]
        direction TB
        S[Skills · 25]
        A[Agents · 13]
        H[Hooks · PreToolUse · SessionStart · Stop]
        S & A & H --> RC[Runtime Context Layer]
        RC --> P[preferences.json]
        RC --> DH[daemon-health.json]
        RC --> M[memories/]
        RC --> SEC[secrets<br/>Doppler · 1Password · keychain]
    end

    subgraph D["ops-daemon · launchd"]
        direction TB
        BW[briefing-pre-warm<br/>every 2 min]
        WS[wacli-sync<br/>continuous]
        ME[memory-extractor<br/>every 30 min]
        ID[inbox-digest<br/>every 4h]
        SH[store-health<br/>daily 9am]
        CI[competitor-intel<br/>weekly Mon 10am]
        ML[message-listener<br/>continuous]
    end

    CC <--> D

    classDef primary fill:#6366f1,color:#fff
    classDef daemon fill:#f59e0b,color:#fff
    class S,A,H,RC primary
    class BW,WS,ME,ID,SH,CI,ML daemon
Loading

Plugin structure

claude-ops/                       ← marketplace root (repo)
├── .claude-plugin/
│   └── marketplace.json          # Points to ./claude-ops as the plugin source
├── README.md
├── SECURITY.md
├── LICENSE
│
└── claude-ops/                   ← plugin root (where Claude Code loads from)
    ├── .claude-plugin/
    │   └── plugin.json           # Plugin manifest + userConfig schema
    │
    ├── skills/                   # 25 slash-command skills
    │   ├── ops/                  # Router
    │   ├── ops-dash/             # Pixel-art dashboard
    │   ├── ops-go/               # Morning briefing
    │   ├── ops-next/             # Priority advisor
    │   ├── ops-inbox/            # Deep-context inbox
    │   ├── ops-comms/            # Cross-channel messaging
    │   ├── ops-merge/            # Autonomous PR pipeline (auto-rebase on origin/main ← v1.0)
    │   ├── ops-fires/            # Production incidents
    │   ├── ops-deploy/           # Deploy status
    │   ├── ops-revenue/          # Real revenue (Stripe + RevenueCat) + cost
    │   ├── ops-projects/         # Portfolio dashboard
    │   ├── ops-linear/           # Sprint management
    │   ├── ops-triage/           # Cross-platform triage
    │   ├── ops-ecom/             # Shopify hub
    │   ├── ops-marketing/        # Marketing analytics
    │   ├── ops-voice/            # Calls + TTS + transcription
    │   ├── ops-monitor/          # APM (Datadog/New Relic/OTEL)   ← v1.0
    │   ├── ops-settings/         # Post-setup credential manager  ← v1.0
    │   ├── ops-integrate/        # Onboard any SaaS API            ← v1.0
    │   ├── ops-orchestrate/      # Multi-project engine
    │   ├── ops-yolo/             # C-suite + autonomous
    │   ├── ops-speedup/          # OS+hardware-adaptive optimizer
    │   ├── ops-doctor/           # Auto-repair
    │   ├── setup/                # Interactive setup wizard
    │   └── uninstall/            # Complete removal
    │
    ├── agents/                   # 13 autonomous agents
    │   ├── comms-scanner.md      # Sonnet 4.6 · inbox classifier
    │   ├── infra-monitor.md      # Sonnet 4.6 · full-AWS scanner (17 services)
    │   ├── project-scanner.md    # Sonnet 4.6 · git/PR/CI
    │   ├── revenue-tracker.md    # Sonnet 4.6 · Stripe + RevenueCat + AWS cost
    │   ├── triage-agent.md       # Sonnet 4.6 · worktree fixer
    │   ├── daemon-agent.md       # Sonnet 4.6 · daemon lifecycle
    │   ├── doctor-agent.md       # Sonnet 4.6 · plugin auto-repair
    │   ├── memory-extractor.md   # Haiku 4.5 · contact profiles
    │   ├── monitor-agent.md      # Haiku 4.5 · APM probe (Datadog/NR/OTEL) ← v1.0
    │   ├── yolo-ceo.md           # Opus 4.6 · strategic (parallel peer, not synthesizer)
    │   ├── yolo-cto.md           # Opus 4.6 · technical analysis
    │   ├── yolo-cfo.md           # Opus 4.6 · financial analysis
    │   └── yolo-coo.md           # Opus 4.6 · operations
    │
    ├── bin/                      # 22 executables
    │   ├── ops-gather            # Master parallel data gatherer
    │   ├── ops-git               # Git status per project → JSON
    │   ├── ops-infra             # ECS cluster health → JSON
    │   ├── ops-prs               # Open PRs per repo → JSON
    │   ├── ops-ci                # GitHub Actions failures (24h) → JSON
    │   ├── ops-unread            # Channel unread counts → JSON
    │   ├── ops-merge-scan        # PR merge-readiness data → JSON
    │   ├── ops-setup-detect      # Config state → JSON
    │   ├── ops-setup-install     # Idempotent CLI installer
    │   ├── ops-setup-preflight   # Background autofix before wizard
    │   ├── ops-setup-complete    # Completion summary
    │   ├── ops-doctor            # Diagnostics + ops-autofix invocation
    │   ├── ops-autofix           # Silent known-issue repairs
    │   ├── ops-dash              # Pixel-art dashboard renderer
    │   ├── ops-speedup           # System diagnostics (cross-platform)
    │   ├── ops-ecom-health       # Shopify store health probe
    │   ├── ops-marketing-dash    # Marketing metrics aggregator
    │   ├── ops-shopify-create    # Non-interactive Shopify app scaffolding
    │   ├── ops-slack-autolink.mjs    # Scout + Playwright Slack token
    │   ├── ops-telegram-autolink.mjs # Zero-browser Telegram MTProto auth
    │   ├── ops-pretool-wacli-health  # PreToolUse health hook
    │   ├── ops-post-session-cleanup  # Stop hook (worktrees + temp)
    │   └── ops-welcome           # SessionStart greeting
    │
    ├── hooks/
    │   └── hooks.json            # PreToolUse + SessionStart + Stop
    │
    ├── telegram-server/          # Bundled gram.js MTProto MCP server
    ├── templates/                # Project templates
    │   ├── shopify-admin-app/    # Remix template, all admin scopes
    │   ├── nestjs-api/           # NestJS API (JWT · BullMQ · Prisma · Fastify · multi-stage Docker) ← v1.0
    │   └── nextjs-saas/          # Next.js SaaS (Auth.js v5 · Stripe · Prisma · Tailwind · shadcn/ui) ← v1.0
    ├── sdk/                      # @claude-ops/sdk npm package ← v1.0
    │   ├── src/types/            # SkillManifest · AgentManifest · PluginManifest · HooksConfig
    │   └── bin/create-ops-skill  # Scaffolder CLI
    ├── lib/                      # Cross-OS foundation (macOS · Linux · WSL · Windows) ← v1.1
    │   ├── os-detect.sh · os-detect.mjs
    │   ├── credential-store.sh · credential-store.mjs
    │   └── opener.sh · opener.mjs
    ├── output-styles/            # ops-briefing output style
    ├── tests/                    # Bash-based validation suite
    │
    ├── scripts/
    │   ├── registry.json         # Per-user project registry (gitignored)
    │   ├── registry.example.json # Template
    │   ├── setup.sh              # SessionStart config detection
    │   ├── ops-daemon.sh         # Daemon main process
    │   ├── ops-memory-extractor.sh
    │   ├── ops-message-listener.sh
    │   ├── ops-cron-inbox-digest.sh
    │   ├── ops-cron-store-health.sh
    │   ├── ops-cron-competitor-intel.sh
    │   ├── daemon-services.default.json
    │   ├── com.claude-ops.daemon.plist
    │   └── wacli-keepalive.sh
    │
    ├── docs/                     # Reference docs
    │   ├── skills-reference.md
    │   ├── agents-reference.md
    │   ├── daemon-guide.md
    │   └── memories-system.md
    │
    ├── CHANGELOG.md
    ├── CLAUDE.md                 # Five non-negotiable plugin rules
    └── .mcp.json                 # MCP server declarations

Token efficiency: the ! shell pre-execution pattern

The most important architectural decision in claude-ops is how data is gathered.

The problem

Without optimization, a morning briefing skill would need to:

  1. Load into model context
  2. Call Bash to check ECS health → wait
  3. Call Bash to check PRs → wait
  4. … repeat for each data source

Sequential, slow (20+ seconds), and burns tokens for each intermediate step.

The solution: ! fence blocks

All data-gathering skills use ```! fence blocks in their SKILL.md prompts:

```!
${CLAUDE_PLUGIN_ROOT}/bin/ops-infra 2>/dev/null || echo '{}'
```

Claude Code executes shell commands inside ```! blocks before the model context is loaded. Output is injected directly into the skill prompt as pre-populated context.

Note

All data is gathered in parallel before the model receives a single token. The model sees a fully populated dashboard to analyze, not a sequence of tool calls to make.

Result: /ops:go delivers a complete briefing in <3s from daemon cache, <10s cold.

ops-gather — master parallel gatherer

The bin/ops-gather script runs all individual gatherers simultaneously using bash background processes:

"$SCRIPT_DIR/ops-git" > "$TMPDIR_OPS/git.json" 2>/dev/null &
"$SCRIPT_DIR/ops-infra" > "$TMPDIR_OPS/infra.json" 2>/dev/null &
"$SCRIPT_DIR/ops-prs" > "$TMPDIR_OPS/prs.json" 2>/dev/null &
"$SCRIPT_DIR/ops-ci" > "$TMPDIR_OPS/ci.json" 2>/dev/null &
"$SCRIPT_DIR/ops-unread" > "$TMPDIR_OPS/unread.json" 2>/dev/null &
wait

Total wall-clock time is the max of any individual script, not their sum.


Data flow — morning briefing

sequenceDiagram
    participant U as User
    participant CC as Claude Code
    participant D as ops-daemon
    participant G as ops-gather
    participant AWS as aws CLI
    participant GH as gh CLI
    participant W as wacli
    participant G2 as gog
    participant M as Model

    Note over D: Daemon pre-warms<br/>every 2 min
    D->>G: ops-gather (cron */2 * * * *)
    G->>AWS: ECS + Cost Explorer
    G->>GH: PRs + CI
    G->>W: unread counts
    G->>G2: email unread
    G-->>D: cache JSON

    U->>CC: /ops:go
    CC->>G: ! bin/ops-gather (pre-exec)
    G-->>CC: pre-populated dashboard (from cache)
    CC->>M: Skill prompt + data
    M-->>U: Unified briefing (<3s)
Loading

YOLO mode agent flow

sequenceDiagram
    participant U as User
    participant Y as /ops:yolo<br/>(main orchestrator)
    participant T as TeamCreate
    participant CEO as yolo-ceo
    participant CTO as yolo-cto
    participant CFO as yolo-cfo
    participant COO as yolo-coo

    U->>Y: /ops:yolo
    Y->>Y: Pre-gather all data
    Y->>T: TeamCreate("yolo-csuite")
    par Parallel analysis (4 peer agents)
        T->>CEO: spawn (Opus 4.6, high effort)
    and
        T->>CTO: spawn (Opus 4.6, high effort)
    and
        T->>CFO: spawn (Opus 4.6, high effort)
    and
        T->>COO: spawn (Opus 4.6, high effort)
    end
    CEO-->>Y: /tmp/yolo-session/ceo-analysis.md
    CTO-->>Y: /tmp/yolo-session/cto-analysis.md
    CFO-->>Y: /tmp/yolo-session/cfo-analysis.md
    COO-->>Y: /tmp/yolo-session/coo-analysis.md
    Y->>Y: Synthesize all 4 into Hard Truths
    Y-->>U: Hard Truths Report
    opt User types YOLO
        U->>Y: YOLO
        Y->>Y: Autonomous loop<br/>(inbox → merge → fires → triage)
    end
Loading

Important

The main /ops:yolo skill is the synthesizer. All four C-suite agents (including yolo-ceo) run as peers in parallel. Each writes its own analysis file. The skill's orchestrator (running in the main Claude Code context) reads all four and synthesizes them into the unified Hard Truths report.


Triage pipeline

flowchart TD
    T["/ops:triage"] --> S[Sentry MCP<br/>search_issues]
    T --> L[Linear MCP<br/>list_issues]
    T --> GH[gh issue list]
    S & L & GH --> J[Join issues]
    J --> G[Grep codebase<br/>for error pattern]
    G --> F{Already fixed?}
    F -->|yes| R[Auto-resolve<br/>update_issue]
    F -->|no| TC[TeamCreate<br/>triage-fixers]
    TC --> WT[worktree-isolated<br/>triage-agent]
    WT --> PR[Open PR + Linear comment]

    classDef ok fill:#22c55e,color:#fff
    classDef warn fill:#f59e0b,color:#fff
    classDef primary fill:#6366f1,color:#fff
    class T,S,L,GH,J,G,TC,WT primary
    class R ok
    class F,PR warn
Loading

Project registry

All skills that need to know about your projects read from scripts/registry.json. This file is gitignored — it's per-user config, not part of the plugin source.

Schema:

{
  "version": "1.0",
  "owner": "Your Name",
  "projects": [
    {
      "alias": "myapp",
      "paths": ["~/Projects/myapp"],
      "repos": ["github-org/myapp"],
      "org": "github-org",
      "type": "monorepo",
      "infra": {
        "ecs_clusters": ["myapp-production"],
        "platform": "aws"
      },
      "revenue": {
        "model": "saas",
        "stage": "growth",
        "mrr": 5000
      },
      "gsd": true,
      "priority": 1
    }
  ]
}

The registry drives:

  • Git repos scanned in ops-git
  • ECS clusters monitored in ops-infra
  • GitHub repos queried in ops-prs and ops-ci
  • Projects displayed in /ops:projects
  • Revenue context in /ops:revenue and YOLO CFO analysis

Security model

Credentials never stored in files

All sensitive values (Telegram session string, API keys, tokens) are stored in Claude Code's plugin settings (userConfig in plugin.json). Claude Code stores these encrypted in ~/.claude.json. They are passed to the Telegram MCP server as environment variables via .mcp.json's env block — never written to disk as plaintext.

Secrets resolution chain

flowchart LR
    A[Skill needs secret] --> B{Doppler<br/>configured?}
    B -->|yes| C[doppler secrets get]
    B -->|no| D{Password<br/>manager<br/>configured?}
    D -->|yes| E[op / dcli / bw / keychain]
    D -->|no| F[$ENV_VAR]
    F --> G{Found?}
    G -->|yes| H[use]
    G -->|no| I[userConfig in plugin.json]
    C & E & H & I --> J[secret resolved]

    classDef primary fill:#6366f1,color:#fff
    classDef secondary fill:#22c55e,color:#fff
    class A,B,D,G primary
    class C,E,F,I,J,H secondary
Loading

umask 077 in setup

The setup wizard uses umask 077 when writing preferences.json — file is mode 600 (owner read/write only). Data dir at ~/.claude/plugins/data/ops-ops-marketplace/ is created with the same mask.

Append-only shell profile writes

The setup wizard only appends to shell profiles (~/.zshrc, ~/.bashrc). Never rewrites or truncates them. The export line is idempotent — if already present, it is not added again.

Registry is gitignored

scripts/registry.json is listed in .gitignore and is never committed. Public repo hygiene (Rule 0) is enforced by tests/test-no-secrets.sh which runs before every commit.

Token auto-scan shows before use

When the setup wizard finds a credential in your environment or dotfiles during auto-scan, it shows you the discovered value and source before using it. Tokens are never silently consumed.


Hooks

Hook Fires Purpose
PreToolUse Before any tool call ops-pretool-wacli-health — pre-flights WhatsApp health file before wacli calls
SessionStart On Claude Code session start scripts/setup.sh surfaces the first 3 items as a session reminder (non-blocking)
Stop On session end ops-post-session-cleanup removes stale worktrees and temp files

Telegram MCP server (bundled)

The telegram-server/ directory contains a Node.js MCP server built on gram.js (MTProto protocol). Declared in .mcp.json:

{
  "mcpServers": {
    "claude_ops_telegram": {
      "command": "node",
      "args": ["telegram-server/index.js"],
      "env": {
        "TELEGRAM_API_ID": "${user_config.telegram_api_id}",
        "TELEGRAM_API_HASH": "${user_config.telegram_api_hash}",
        "TELEGRAM_PHONE": "${user_config.telegram_phone}",
        "TELEGRAM_SESSION": "${user_config.telegram_session}"
      }
    }
  }
}

${user_config.*} placeholders are resolved by Claude Code from plugin settings at runtime. The server starts only when Telegram credentials are configured.

Tools exposed:

  • list_dialogs — recent conversations with unread counts
  • get_messages — messages from a specific chat by username or chat ID
  • send_message — send to a contact
  • search_messages — full-text search across all chats

Note

Why MTProto instead of Bot API: The Bot API only works with bots, which cannot read user DMs. MTProto authenticates as your personal account, giving access to all your conversations.

Clone this wiki locally