-
Notifications
You must be signed in to change notification settings - Fork 4
Architecture
How claude-ops works internally — structure, data flow, token efficiency, and the security model.
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
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
The most important architectural decision in claude-ops is how data is gathered.
Without optimization, a morning briefing skill would need to:
- Load into model context
- Call Bash to check ECS health → wait
- Call Bash to check PRs → wait
- … repeat for each data source
Sequential, slow (20+ seconds), and burns tokens for each intermediate step.
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.
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 &
waitTotal wall-clock time is the max of any individual script, not their sum.
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)
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
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.
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
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-prsandops-ci - Projects displayed in
/ops:projects - Revenue context in
/ops:revenueand YOLO CFO analysis
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.
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
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.
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.
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.
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.
| 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 |
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.