myaiforone 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -0
- package/agents/_template/CLAUDE.md +18 -0
- package/agents/_template/agent.json +7 -0
- package/agents/platform/agentcreator/CLAUDE.md +300 -0
- package/agents/platform/appcreator/CLAUDE.md +158 -0
- package/agents/platform/gym/CLAUDE.md +486 -0
- package/agents/platform/gym/agent.json +40 -0
- package/agents/platform/gym/programs/agent-building/program.json +160 -0
- package/agents/platform/gym/programs/automations-mastery/program.json +129 -0
- package/agents/platform/gym/programs/getting-started/program.json +124 -0
- package/agents/platform/gym/programs/mcp-integrations/program.json +116 -0
- package/agents/platform/gym/programs/multi-model-strategy/program.json +115 -0
- package/agents/platform/gym/programs/prompt-engineering/program.json +136 -0
- package/agents/platform/gym/souls/alex.md +12 -0
- package/agents/platform/gym/souls/jordan.md +12 -0
- package/agents/platform/gym/souls/morgan.md +12 -0
- package/agents/platform/gym/souls/riley.md +12 -0
- package/agents/platform/gym/souls/sam.md +12 -0
- package/agents/platform/hub/CLAUDE.md +372 -0
- package/agents/platform/promptcreator/CLAUDE.md +130 -0
- package/agents/platform/skillcreator/CLAUDE.md +163 -0
- package/bin/cli.js +566 -0
- package/config.example.json +310 -0
- package/dist/agent-registry.d.ts +32 -0
- package/dist/agent-registry.d.ts.map +1 -0
- package/dist/agent-registry.js +144 -0
- package/dist/agent-registry.js.map +1 -0
- package/dist/channels/discord.d.ts +17 -0
- package/dist/channels/discord.d.ts.map +1 -0
- package/dist/channels/discord.js +114 -0
- package/dist/channels/discord.js.map +1 -0
- package/dist/channels/imessage.d.ts +23 -0
- package/dist/channels/imessage.d.ts.map +1 -0
- package/dist/channels/imessage.js +214 -0
- package/dist/channels/imessage.js.map +1 -0
- package/dist/channels/slack.d.ts +19 -0
- package/dist/channels/slack.d.ts.map +1 -0
- package/dist/channels/slack.js +167 -0
- package/dist/channels/slack.js.map +1 -0
- package/dist/channels/telegram.d.ts +19 -0
- package/dist/channels/telegram.d.ts.map +1 -0
- package/dist/channels/telegram.js +274 -0
- package/dist/channels/telegram.js.map +1 -0
- package/dist/channels/types.d.ts +44 -0
- package/dist/channels/types.d.ts.map +1 -0
- package/dist/channels/types.js +18 -0
- package/dist/channels/types.js.map +1 -0
- package/dist/channels/whatsapp.d.ts +23 -0
- package/dist/channels/whatsapp.d.ts.map +1 -0
- package/dist/channels/whatsapp.js +189 -0
- package/dist/channels/whatsapp.js.map +1 -0
- package/dist/config.d.ts +134 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +127 -0
- package/dist/config.js.map +1 -0
- package/dist/cron.d.ts +8 -0
- package/dist/cron.d.ts.map +1 -0
- package/dist/cron.js +35 -0
- package/dist/cron.js.map +1 -0
- package/dist/decrypt-keys.d.ts +7 -0
- package/dist/decrypt-keys.d.ts.map +1 -0
- package/dist/decrypt-keys.js +53 -0
- package/dist/decrypt-keys.js.map +1 -0
- package/dist/encrypt-keys.d.ts +8 -0
- package/dist/encrypt-keys.d.ts.map +1 -0
- package/dist/encrypt-keys.js +62 -0
- package/dist/encrypt-keys.js.map +1 -0
- package/dist/executor.d.ts +31 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +2009 -0
- package/dist/executor.js.map +1 -0
- package/dist/gemini-executor.d.ts +27 -0
- package/dist/gemini-executor.d.ts.map +1 -0
- package/dist/gemini-executor.js +160 -0
- package/dist/gemini-executor.js.map +1 -0
- package/dist/goals.d.ts +24 -0
- package/dist/goals.d.ts.map +1 -0
- package/dist/goals.js +189 -0
- package/dist/goals.js.map +1 -0
- package/dist/gym/activity-digest.d.ts +30 -0
- package/dist/gym/activity-digest.d.ts.map +1 -0
- package/dist/gym/activity-digest.js +506 -0
- package/dist/gym/activity-digest.js.map +1 -0
- package/dist/gym/dimension-scorer.d.ts +76 -0
- package/dist/gym/dimension-scorer.d.ts.map +1 -0
- package/dist/gym/dimension-scorer.js +236 -0
- package/dist/gym/dimension-scorer.js.map +1 -0
- package/dist/gym/gym-router.d.ts +7 -0
- package/dist/gym/gym-router.d.ts.map +1 -0
- package/dist/gym/gym-router.js +718 -0
- package/dist/gym/gym-router.js.map +1 -0
- package/dist/gym/index.d.ts +11 -0
- package/dist/gym/index.d.ts.map +1 -0
- package/dist/gym/index.js +11 -0
- package/dist/gym/index.js.map +1 -0
- package/dist/heartbeat.d.ts +21 -0
- package/dist/heartbeat.d.ts.map +1 -0
- package/dist/heartbeat.js +163 -0
- package/dist/heartbeat.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +254 -0
- package/dist/index.js.map +1 -0
- package/dist/keystore.d.ts +22 -0
- package/dist/keystore.d.ts.map +1 -0
- package/dist/keystore.js +178 -0
- package/dist/keystore.js.map +1 -0
- package/dist/logger.d.ts +9 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +45 -0
- package/dist/logger.js.map +1 -0
- package/dist/memory/daily.d.ts +22 -0
- package/dist/memory/daily.d.ts.map +1 -0
- package/dist/memory/daily.js +82 -0
- package/dist/memory/daily.js.map +1 -0
- package/dist/memory/embeddings.d.ts +15 -0
- package/dist/memory/embeddings.d.ts.map +1 -0
- package/dist/memory/embeddings.js +154 -0
- package/dist/memory/embeddings.js.map +1 -0
- package/dist/memory/index.d.ts +32 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +159 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/search.d.ts +21 -0
- package/dist/memory/search.d.ts.map +1 -0
- package/dist/memory/search.js +77 -0
- package/dist/memory/search.js.map +1 -0
- package/dist/memory/store.d.ts +23 -0
- package/dist/memory/store.d.ts.map +1 -0
- package/dist/memory/store.js +144 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/ollama-executor.d.ts +17 -0
- package/dist/ollama-executor.d.ts.map +1 -0
- package/dist/ollama-executor.js +112 -0
- package/dist/ollama-executor.js.map +1 -0
- package/dist/openai-executor.d.ts +38 -0
- package/dist/openai-executor.d.ts.map +1 -0
- package/dist/openai-executor.js +197 -0
- package/dist/openai-executor.js.map +1 -0
- package/dist/router.d.ts +11 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +185 -0
- package/dist/router.js.map +1 -0
- package/dist/test-message.d.ts +2 -0
- package/dist/test-message.d.ts.map +1 -0
- package/dist/test-message.js +60 -0
- package/dist/test-message.js.map +1 -0
- package/dist/utils/imsg-db-reader.d.ts +24 -0
- package/dist/utils/imsg-db-reader.d.ts.map +1 -0
- package/dist/utils/imsg-db-reader.js +92 -0
- package/dist/utils/imsg-db-reader.js.map +1 -0
- package/dist/utils/imsg-rpc.d.ts +25 -0
- package/dist/utils/imsg-rpc.d.ts.map +1 -0
- package/dist/utils/imsg-rpc.js +149 -0
- package/dist/utils/imsg-rpc.js.map +1 -0
- package/dist/utils/message-formatter.d.ts +3 -0
- package/dist/utils/message-formatter.d.ts.map +1 -0
- package/dist/utils/message-formatter.js +69 -0
- package/dist/utils/message-formatter.js.map +1 -0
- package/dist/web-ui.d.ts +12 -0
- package/dist/web-ui.d.ts.map +1 -0
- package/dist/web-ui.js +5784 -0
- package/dist/web-ui.js.map +1 -0
- package/dist/whatsapp-chats.d.ts +2 -0
- package/dist/whatsapp-chats.d.ts.map +1 -0
- package/dist/whatsapp-chats.js +76 -0
- package/dist/whatsapp-chats.js.map +1 -0
- package/dist/whatsapp-login.d.ts +2 -0
- package/dist/whatsapp-login.d.ts.map +1 -0
- package/dist/whatsapp-login.js +90 -0
- package/dist/whatsapp-login.js.map +1 -0
- package/dist/wiki-sync.d.ts +21 -0
- package/dist/wiki-sync.d.ts.map +1 -0
- package/dist/wiki-sync.js +147 -0
- package/dist/wiki-sync.js.map +1 -0
- package/docs/AddNewAgentGuide.md +100 -0
- package/docs/AddNewMcpGuide.md +72 -0
- package/docs/Architecture.md +795 -0
- package/docs/CLAUDE-AI-SETUP.md +166 -0
- package/docs/Setup.md +297 -0
- package/docs/ai-gym-architecture.md +1040 -0
- package/docs/ai-gym-build-plan.md +343 -0
- package/docs/ai-gym-onboarding.md +122 -0
- package/docs/appcreator_plan.md +348 -0
- package/docs/platform-mcp-audit.md +320 -0
- package/docs/server-deployment-plan.md +503 -0
- package/docs/superpowers/plans/2026-03-25-marketplace.md +1281 -0
- package/docs/superpowers/specs/2026-03-25-marketplace-design.md +287 -0
- package/docs/user-guide.md +2016 -0
- package/mcp-catalog.json +628 -0
- package/package.json +63 -0
- package/public/MyAIforOne-logomark-512.svg +16 -0
- package/public/MyAIforOne-logomark-transparent.svg +15 -0
- package/public/activity.html +314 -0
- package/public/admin.html +1674 -0
- package/public/agent-dashboard.html +670 -0
- package/public/api-docs.html +1106 -0
- package/public/automations.html +722 -0
- package/public/canvas.css +223 -0
- package/public/canvas.js +588 -0
- package/public/changelog.html +231 -0
- package/public/gym.html +2766 -0
- package/public/home.html +1930 -0
- package/public/index.html +2809 -0
- package/public/lab.html +1643 -0
- package/public/library.html +1442 -0
- package/public/marketplace.html +1101 -0
- package/public/mcp-docs.html +441 -0
- package/public/mini.html +390 -0
- package/public/monitor.html +584 -0
- package/public/org.html +4304 -0
- package/public/projects.html +734 -0
- package/public/settings.html +645 -0
- package/public/tasks.html +932 -0
- package/public/trainers/alex.svg +12 -0
- package/public/trainers/jordan.svg +12 -0
- package/public/trainers/morgan.svg +12 -0
- package/public/trainers/riley.svg +12 -0
- package/public/trainers/sam.svg +12 -0
- package/public/user-guide.html +218 -0
- package/registry/agents.json +3 -0
- package/registry/apps.json +20 -0
- package/registry/installed-drafts.json +3 -0
- package/registry/mcps.json +1084 -0
- package/registry/prompts/personal/mcp-test-prompt.md +6 -0
- package/registry/prompts/personal/memory-recall.md +6 -0
- package/registry/prompts/platform/brainstorm.md +15 -0
- package/registry/prompts/platform/code-review.md +16 -0
- package/registry/prompts/platform/explain.md +16 -0
- package/registry/prompts.json +58 -0
- package/registry/skills/external/brainstorming.md +5 -0
- package/registry/skills/external/code-review.md +40 -0
- package/registry/skills/external/frontend-patterns.md +642 -0
- package/registry/skills/external/frontend-slides.md +184 -0
- package/registry/skills/external/systematic-debugging.md +5 -0
- package/registry/skills/external/tdd.md +328 -0
- package/registry/skills/external/verification-before-completion.md +5 -0
- package/registry/skills/external/writing-plans.md +5 -0
- package/registry/skills/platform/ai41_app_build.md +930 -0
- package/registry/skills/platform/ai41_app_deploy.md +168 -0
- package/registry/skills/platform/ai41_app_orchestrator.md +239 -0
- package/registry/skills/platform/ai41_app_patterns.md +359 -0
- package/registry/skills/platform/ai41_app_register.md +85 -0
- package/registry/skills/platform/ai41_app_scaffold.md +421 -0
- package/registry/skills/platform/ai41_app_verify.md +107 -0
- package/registry/skills/platform/opProjectCreate.md +239 -0
- package/registry/skills/platform/op_devbrowser.md +136 -0
- package/registry/skills/platform/sop_brandguidelines.md +103 -0
- package/registry/skills/platform/sop_docx.md +117 -0
- package/registry/skills/platform/sop_frontenddesign.md +44 -0
- package/registry/skills/platform/sop_frontenddesign_v2.md +659 -0
- package/registry/skills/platform/sop_mcpbuilder.md +133 -0
- package/registry/skills/platform/sop_pdf.md +172 -0
- package/registry/skills/platform/sop_pptx.md +133 -0
- package/registry/skills/platform/sop_skillcreator.md +104 -0
- package/registry/skills/platform/sop_themefactory.md +128 -0
- package/registry/skills/platform/sop_webapptesting.md +75 -0
- package/registry/skills/platform/sop_webartifactsbuilder.md +97 -0
- package/registry/skills/platform/sop_xlsx.md +134 -0
- package/registry/skills.json +1055 -0
- package/scripts/discover-chats.sh +11 -0
- package/scripts/install-service-windows.ps1 +87 -0
- package/scripts/install-service.sh +52 -0
- package/scripts/seed-registry.ts +195 -0
- package/scripts/test-send.sh +5 -0
- package/scripts/tray-indicator.ps1 +35 -0
- package/scripts/uninstall-service-windows.ps1 +23 -0
- package/scripts/uninstall-service.sh +15 -0
- package/scripts/xbar-myagent.5s.sh +32 -0
- package/server/mcp-server/dist/index.d.ts +11 -0
- package/server/mcp-server/dist/index.js +1332 -0
- package/server/mcp-server/dist/lib/api-client.d.ts +165 -0
- package/server/mcp-server/dist/lib/api-client.js +241 -0
- package/server/mcp-server/index.ts +1545 -0
- package/server/mcp-server/lib/api-client.ts +366 -0
- package/server/mcp-server/tsconfig.json +14 -0
- package/src/agent-registry.ts +180 -0
- package/src/channels/discord.ts +129 -0
- package/src/channels/imessage.ts +261 -0
- package/src/channels/slack.ts +208 -0
- package/src/channels/telegram.ts +307 -0
- package/src/channels/types.ts +62 -0
- package/src/channels/whatsapp.ts +227 -0
- package/src/config.ts +281 -0
- package/src/cron.ts +43 -0
- package/src/decrypt-keys.ts +60 -0
- package/src/encrypt-keys.ts +70 -0
- package/src/executor.ts +2190 -0
- package/src/gemini-executor.ts +212 -0
- package/src/goals.ts +240 -0
- package/src/gym/activity-digest.ts +546 -0
- package/src/gym/dimension-scorer.ts +297 -0
- package/src/gym/gym-router.ts +801 -0
- package/src/gym/index.ts +19 -0
- package/src/heartbeat.ts +220 -0
- package/src/index.ts +275 -0
- package/src/keystore.ts +190 -0
- package/src/logger.ts +51 -0
- package/src/memory/daily.ts +101 -0
- package/src/memory/embeddings.ts +185 -0
- package/src/memory/index.ts +218 -0
- package/src/memory/search.ts +124 -0
- package/src/memory/store.ts +189 -0
- package/src/ollama-executor.ts +126 -0
- package/src/openai-executor.ts +259 -0
- package/src/router.ts +230 -0
- package/src/test-message.ts +72 -0
- package/src/utils/imsg-db-reader.ts +109 -0
- package/src/utils/imsg-rpc.ts +178 -0
- package/src/utils/message-formatter.ts +90 -0
- package/src/web-ui.ts +5778 -0
- package/src/whatsapp-chats.ts +91 -0
- package/src/whatsapp-login.ts +110 -0
- package/src/wiki-sync.ts +199 -0
- package/tsconfig.json +19 -0
|
@@ -0,0 +1,795 @@
|
|
|
1
|
+
# MyAgent — Architecture
|
|
2
|
+
|
|
3
|
+
## What This Is
|
|
4
|
+
|
|
5
|
+
A gateway that lets you communicate with Claude Code sessions from your phone via Slack, iMessage, Telegram, Discord, and WhatsApp. Each "agent" is a persistent Claude Code session with a defined purpose, scoped tools, MCPs, and skills — accessed by @mentioning an alias in a chat.
|
|
6
|
+
|
|
7
|
+
Everything runs as a single Node.js process on your Mac, managed by launchd.
|
|
8
|
+
|
|
9
|
+
## How It Works
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
Phone → Slack/iMessage/Telegram/Discord → internet → your Mac (gateway) → claude -p → response → back to phone
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
1. You send a message from your phone (e.g., `@agentmgr what's in my Bobby project?`)
|
|
16
|
+
2. The gateway service running on your Mac detects the message
|
|
17
|
+
3. The router checks pairing (if enabled), then matches channel + chat ID + @mention alias to an agent
|
|
18
|
+
4. The executor spawns `claude -p` with the agent's system prompt, workspace, MCPs, and tools
|
|
19
|
+
5. For streaming agents, real-time status updates and text stream back via SSE
|
|
20
|
+
6. Long responses are automatically chunked to fit channel limits
|
|
21
|
+
7. The response is sent back to the originating channel
|
|
22
|
+
8. The process exits, but the **session persists** — next message resumes where you left off
|
|
23
|
+
|
|
24
|
+
## Channels
|
|
25
|
+
|
|
26
|
+
| Channel | Library | Auth | How it connects |
|
|
27
|
+
|---------|---------|------|-----------------|
|
|
28
|
+
| **Slack** | @slack/socket-mode | Bot + App tokens | Outbound WebSocket (no public URL needed) |
|
|
29
|
+
| **Telegram** | grammY | Bot token from @BotFather | Long polling (no public URL needed) |
|
|
30
|
+
| **iMessage** | imsg CLI | Local macOS access | Watches Messages database via JSON-RPC subprocess |
|
|
31
|
+
| **Discord** | discord.js | Bot token | Outbound WebSocket (no public URL needed) |
|
|
32
|
+
| **WhatsApp** | @whiskeysockets/baileys | QR code pairing | WhatsApp Web protocol (unofficial) |
|
|
33
|
+
|
|
34
|
+
All channels connect outbound from your Mac — no inbound ports need to be exposed to the internet.
|
|
35
|
+
|
|
36
|
+
## Agents = Scoped Sessions
|
|
37
|
+
|
|
38
|
+
An agent is not a different AI. It's the **same Claude** with different guardrails per session:
|
|
39
|
+
|
|
40
|
+
| What the agent defines | Example |
|
|
41
|
+
|------------------------|---------|
|
|
42
|
+
| **Purpose** (system prompt) | "You manage the financeiscooked show content" |
|
|
43
|
+
| **Workspace** (file access) | `~/Desktop/APPs/financeiscooked` |
|
|
44
|
+
| **MCPs** (API integrations) | financeiscooked platform API, context7 |
|
|
45
|
+
| **Tools** (what Claude can do) | Read, Edit, Write, Bash — or read-only |
|
|
46
|
+
| **Skills** (indexed instructions) | opcodereview, sop_pdf, etc. |
|
|
47
|
+
| **Session** (conversation memory) | Persistent UUID-based session with full history |
|
|
48
|
+
| **Streaming** (real-time output) | Tool status updates + live text in Web UI |
|
|
49
|
+
| **Org** (team structure) | Organization, department, title, reporting chain |
|
|
50
|
+
|
|
51
|
+
Multiple agents can share the same Slack channel, Telegram group, or iMessage thread — they're differentiated by their @mention alias (e.g., `@producer` vs `@oldproducer` vs `@agentmgr`).
|
|
52
|
+
|
|
53
|
+
### Sticky Routing
|
|
54
|
+
|
|
55
|
+
After you @mention an agent, follow-up messages without a mention automatically route to the same agent for 5 minutes. This lets you have a natural conversation without typing the alias every message.
|
|
56
|
+
|
|
57
|
+
- `@bobby check the build` → routes to bobby, starts 5-min timer
|
|
58
|
+
- "what about the tests?" → still bobby (within 5 min)
|
|
59
|
+
- "looks good" → still bobby
|
|
60
|
+
- (5 minutes of silence) → timer expires, next message needs a mention
|
|
61
|
+
|
|
62
|
+
Each sender has their own sticky — Alice talking to `@bobby` doesn't affect Bob's messages.
|
|
63
|
+
|
|
64
|
+
Configure per channel:
|
|
65
|
+
```json
|
|
66
|
+
"telegram": {
|
|
67
|
+
"config": {
|
|
68
|
+
"stickyRouting": true,
|
|
69
|
+
"stickyTimeoutMs": 300000
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Defaults: `stickyRouting: true`, `stickyTimeoutMs: 300000` (5 min). Set `stickyRouting: false` to require @mention on every message.
|
|
75
|
+
|
|
76
|
+
## Session Persistence
|
|
77
|
+
|
|
78
|
+
Agents can be **persistent**, **streaming**, or **single-shot**:
|
|
79
|
+
|
|
80
|
+
### Persistent (`"persistent": true`)
|
|
81
|
+
- First message generates a UUID and creates a Claude Code session via `--session-id`
|
|
82
|
+
- Every subsequent message resumes the session via `--resume <uuid>`
|
|
83
|
+
- Claude maintains full conversation history — it remembers everything you've discussed
|
|
84
|
+
- Session state stored by Claude Code in `~/.claude/projects/` (not configurable)
|
|
85
|
+
- A pointer (UUID) stored in the agent's `memory/session.json`
|
|
86
|
+
- Claude Code handles context compression automatically as sessions grow
|
|
87
|
+
|
|
88
|
+
### Streaming (`"streaming": true`)
|
|
89
|
+
- Uses `--output-format stream-json --verbose` to get real-time output
|
|
90
|
+
- **Web UI**: Streams text live via SSE as Claude writes. Shows tool status ("Using Read...", "Using Bash...") in the thinking indicator
|
|
91
|
+
- **Phone channels**: Sends typing indicators while processing. Final response sent when done
|
|
92
|
+
- Session management works the same as persistent (sessions are maintained)
|
|
93
|
+
- If `persistent` is also true, sessions resume across messages with streaming output
|
|
94
|
+
|
|
95
|
+
### Per-Sender Sessions (`"perSenderSessions": true`)
|
|
96
|
+
- Each sender gets their own isolated session file (`session-<senderId>.json`)
|
|
97
|
+
- Useful when multiple people talk to the same agent — each gets a private conversation thread
|
|
98
|
+
- Requires `persistent: true` to have any effect
|
|
99
|
+
|
|
100
|
+
### Single-shot (`"persistent": false`, the default)
|
|
101
|
+
- Every message is a fresh Claude invocation
|
|
102
|
+
- Last 5 messages from `conversation_log.jsonl` injected as text context
|
|
103
|
+
- No session continuity beyond that
|
|
104
|
+
|
|
105
|
+
### Session Lifecycle Commands
|
|
106
|
+
- **`/opcompact <what to save>`** — Tell the agent to save important information to `context.md`. This context survives session resets and is injected into the system prompt of new sessions.
|
|
107
|
+
- **`/opreset`** — Clear the session. Deletes session file, next message starts fresh. The agent's identity (CLAUDE.md) and saved context (context.md) remain.
|
|
108
|
+
|
|
109
|
+
## Advanced Memory
|
|
110
|
+
|
|
111
|
+
When `"advancedMemory": true` is set on an agent, it gets a semantic long-term memory system that goes beyond basic session persistence and `context.md`. This is the recommended default for general-purpose agents.
|
|
112
|
+
|
|
113
|
+
### How It Differs from Basic Memory
|
|
114
|
+
|
|
115
|
+
| Feature | Basic (persistent session) | Advanced Memory |
|
|
116
|
+
|---------|---------------------------|-----------------|
|
|
117
|
+
| **Short-term** | Claude session history | Same — session history |
|
|
118
|
+
| **Long-term** | Manual `/opcompact` → `context.md` | Automatic daily journals + semantic recall |
|
|
119
|
+
| **Recall** | Full `context.md` injected every time | Relevant memories retrieved by similarity search |
|
|
120
|
+
| **Scaling** | `context.md` grows until you edit it | Old entries auto-compact; vector search stays fast |
|
|
121
|
+
|
|
122
|
+
### Daily Memory
|
|
123
|
+
|
|
124
|
+
Memories are stored as markdown files in `memory/daily/YYYY-MM-DD.md` inside the agent's memory directory. Each day gets its own file with timestamped entries.
|
|
125
|
+
|
|
126
|
+
At the start of every conversation turn, the system automatically loads **today's** and **yesterday's** daily files as immediate context, so the agent always knows what happened recently.
|
|
127
|
+
|
|
128
|
+
### Semantic Search
|
|
129
|
+
|
|
130
|
+
When the agent needs to recall something older than yesterday, it searches the memory store using a **hybrid retrieval** strategy:
|
|
131
|
+
|
|
132
|
+
1. **Cosine similarity** — vector dot-product against stored embeddings
|
|
133
|
+
2. **BM25 keyword scoring** — term-frequency weighting for exact-match recall
|
|
134
|
+
3. **Temporal decay** — recent memories get a relevance boost over older ones
|
|
135
|
+
|
|
136
|
+
The three scores are combined into a single ranking. Top results are injected into the prompt as recalled context.
|
|
137
|
+
|
|
138
|
+
### Embedding Providers
|
|
139
|
+
|
|
140
|
+
- **OpenAI** (default when `OPENAI_API_KEY` is set) — uses `text-embedding-3-small` for high-quality vectors
|
|
141
|
+
- **TF-IDF fallback** — if no OpenAI key is available, a local TF-IDF vectorizer generates embeddings with no external calls
|
|
142
|
+
|
|
143
|
+
### Vector Store
|
|
144
|
+
|
|
145
|
+
- **JSON** (default) — stores embeddings in a JSON file in the memory directory. Zero dependencies.
|
|
146
|
+
- **SQLite** (auto-upgrade) — when the JSON store grows past a threshold, it automatically migrates to SQLite for faster lookups.
|
|
147
|
+
|
|
148
|
+
### Auto-Compaction
|
|
149
|
+
|
|
150
|
+
To prevent unbounded context growth, advanced memory monitors conversation length:
|
|
151
|
+
|
|
152
|
+
- **Warning at 20 messages** — the agent is nudged to summarize and save important context to daily memory
|
|
153
|
+
- **Forced compaction at 40 messages** — the system automatically triggers a compaction, writing a summary to daily memory and resetting the conversation
|
|
154
|
+
|
|
155
|
+
### Config Flag
|
|
156
|
+
|
|
157
|
+
Enable on any agent:
|
|
158
|
+
```json
|
|
159
|
+
"advancedMemory": true
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
No additional configuration needed. The embedding provider and vector store are auto-detected based on available environment variables and data size.
|
|
163
|
+
|
|
164
|
+
## Organization & Team Structure
|
|
165
|
+
|
|
166
|
+
Agents can be placed in an organizational hierarchy for the Org Chart dashboard:
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
"org": [
|
|
170
|
+
{ "organization": "Finance Is Cooked", "function": "Content Production", "title": "Show Producer", "reportsTo": "@agentmgr" },
|
|
171
|
+
{ "organization": "Personal", "function": "Operations", "title": "General Manager" }
|
|
172
|
+
]
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
- **organization** — Which org this agent belongs to (agents can be in multiple orgs)
|
|
176
|
+
- **function** — Department/team label (shown as a tag on the agent card)
|
|
177
|
+
- **title** — Role title (shown above the agent name)
|
|
178
|
+
- **reportsTo** — Alias of the agent this one reports to (drives the hierarchy tree)
|
|
179
|
+
|
|
180
|
+
The Org Chart page (`/org`) visualizes this:
|
|
181
|
+
- Dropdown to select an organization
|
|
182
|
+
- Tree hierarchy driven by `reportsTo` — agents without a `reportsTo` sit at the top
|
|
183
|
+
- Department shown as a purple tag on each card
|
|
184
|
+
- Heartbeat animation on active agents (green ❤ pulsing top-right)
|
|
185
|
+
- "All Agents" view groups agents by organization with section headers
|
|
186
|
+
- Click any agent to Chat or view Config
|
|
187
|
+
|
|
188
|
+
## Multi-Account Support
|
|
189
|
+
|
|
190
|
+
Multiple Anthropic accounts — each with their own Claude Code subscription — can be assigned to different agents. This lets you spread usage across subscriptions, isolate billing, or use different plan tiers per agent type.
|
|
191
|
+
|
|
192
|
+
### How It Works
|
|
193
|
+
|
|
194
|
+
Each account is a separate Claude Code login, isolated by pointing `CLAUDE_CONFIG_DIR` to a dedicated config directory. When the gateway spawns `claude -p` for an agent, it sets `CLAUDE_CONFIG_DIR` to the directory for that agent's assigned account so Claude authenticates as the correct subscription.
|
|
195
|
+
|
|
196
|
+
### Setup
|
|
197
|
+
|
|
198
|
+
One-time login per account:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
CLAUDE_CONFIG_DIR=~/.claude-account-X claude
|
|
202
|
+
# then run /login inside the session to authenticate
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Repeat for each account (`~/.claude-account-1`, `~/.claude-account-2`, etc.). Each directory holds its own credentials independently.
|
|
206
|
+
|
|
207
|
+
### Config
|
|
208
|
+
|
|
209
|
+
Register accounts in the service block, then assign them to agents:
|
|
210
|
+
|
|
211
|
+
```json
|
|
212
|
+
"service": {
|
|
213
|
+
"claudeAccounts": {
|
|
214
|
+
"main": { "configDir": "~/.claude" },
|
|
215
|
+
"account2": { "configDir": "~/.claude-account-2" },
|
|
216
|
+
"account3": { "configDir": "~/.claude-account-3" }
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Per agent, set the default account:
|
|
222
|
+
|
|
223
|
+
```json
|
|
224
|
+
"claudeAccount": "account2"
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
If omitted, the agent uses the default Claude config directory (no `CLAUDE_CONFIG_DIR` override).
|
|
228
|
+
|
|
229
|
+
### UI
|
|
230
|
+
|
|
231
|
+
- **Chat header dropdown** — switch the active account for an agent on the fly (in-memory override, does not persist to config)
|
|
232
|
+
- **Agent edit modal dropdown** — set the default account for an agent (persisted to config)
|
|
233
|
+
|
|
234
|
+
### The `/relogin` Command
|
|
235
|
+
|
|
236
|
+
If an account's session expires mid-conversation, send `/relogin` in chat. The gateway will prompt you through re-authentication for the agent's assigned account without leaving the chat interface.
|
|
237
|
+
|
|
238
|
+
### Use Cases
|
|
239
|
+
|
|
240
|
+
| Scenario | How |
|
|
241
|
+
|----------|-----|
|
|
242
|
+
| **Spread usage** | Assign high-traffic agents to separate subscriptions to avoid rate limits |
|
|
243
|
+
| **Isolate billing** | Give each team or project its own account for clean cost attribution |
|
|
244
|
+
| **Different plan tiers** | Use a Pro account for lightweight agents, Max for heavy autonomous ones |
|
|
245
|
+
|
|
246
|
+
## Multi-Model Executor
|
|
247
|
+
|
|
248
|
+
When `multiModelEnabled: true` is set in the service config, agents can use open-source models via Ollama instead of Claude Code.
|
|
249
|
+
|
|
250
|
+
### Executor Dispatch
|
|
251
|
+
|
|
252
|
+
The executor resolves which backend to use via a four-step fallback chain:
|
|
253
|
+
|
|
254
|
+
1. **`multiModelEnabled`** — if `false` (default), all agents use Claude. Full stop.
|
|
255
|
+
2. **Per-agent `executor` field** — e.g., `"executor": "ollama:gemma2"` overrides everything for that agent.
|
|
256
|
+
3. **`platformDefaultExecutor`** — service-level default (e.g., `"ollama:llama3"`) applied when an agent has no `executor` field.
|
|
257
|
+
4. **Hard default** — if none of the above are set, the agent uses `claude -p`.
|
|
258
|
+
|
|
259
|
+
### Two Executor Paths
|
|
260
|
+
|
|
261
|
+
| | Claude | Ollama |
|
|
262
|
+
|--|--------|--------|
|
|
263
|
+
| **Trigger** | `executor` is unset or `"claude"` | `executor` starts with `"ollama:"` |
|
|
264
|
+
| **How it runs** | Spawns `claude -p` with system prompt, workspace, allowed tools, MCP config, and session flags | HTTP POST to Ollama API (`/api/chat`) at `service.ollamaBaseUrl` (default `http://localhost:11434`) |
|
|
265
|
+
| **Tool use** | Full — Read, Write, Bash, Glob, Grep, etc. | None |
|
|
266
|
+
| **MCP access** | Yes — temp `.mcp.json` generated and passed via `--mcp-config` | None |
|
|
267
|
+
| **Sessions** | Persistent via `--session-id` / `--resume` | None — each message is stateless |
|
|
268
|
+
| **Streaming** | Yes — `--output-format stream-json` | Text response only |
|
|
269
|
+
|
|
270
|
+
### Ollama Limitations
|
|
271
|
+
|
|
272
|
+
Ollama-backed agents are **text-in / text-out only**. They cannot use tools (Read, Write, Bash), MCP servers, persistent sessions, or streaming. This makes them suitable for Q&A, content generation, and advisory roles — not for agents that need to read files, run commands, or call APIs.
|
|
273
|
+
|
|
274
|
+
### Health Check
|
|
275
|
+
|
|
276
|
+
Before dispatching to Ollama, the executor calls `checkOllamaHealth()` which:
|
|
277
|
+
|
|
278
|
+
1. Hits `GET /api/tags` on the Ollama server to confirm it is reachable
|
|
279
|
+
2. Checks that the requested model (e.g., `gemma2`) is in the list of locally available models
|
|
280
|
+
3. Returns an error message to the user if either check fails, rather than silently failing
|
|
281
|
+
|
|
282
|
+
### Model Override API
|
|
283
|
+
|
|
284
|
+
Agents can have their executor model changed at runtime without editing `config.json`:
|
|
285
|
+
|
|
286
|
+
| Endpoint | Method | Description |
|
|
287
|
+
|----------|--------|-------------|
|
|
288
|
+
| `/api/agents/:agentId/model` | GET | Returns the agent's current executor model |
|
|
289
|
+
| `/api/agents/:agentId/model` | PUT | Sets the executor model (e.g., `{ "executor": "ollama:gemma2" }`) |
|
|
290
|
+
| `/api/agents/:agentId/model` | DELETE | Clears the per-agent override, reverting to platform default |
|
|
291
|
+
|
|
292
|
+
MCP tools provide the same functionality for agent-to-agent use:
|
|
293
|
+
|
|
294
|
+
| Tool | Description |
|
|
295
|
+
|------|-------------|
|
|
296
|
+
| `get_model` | Read the current executor for an agent |
|
|
297
|
+
| `set_model` | Set an agent's executor (e.g., `"ollama:gemma2"` or `"claude"`) |
|
|
298
|
+
| `clear_model` | Remove the per-agent override |
|
|
299
|
+
|
|
300
|
+
### Config
|
|
301
|
+
|
|
302
|
+
Service-level settings:
|
|
303
|
+
```json
|
|
304
|
+
"service": {
|
|
305
|
+
"multiModelEnabled": true,
|
|
306
|
+
"platformDefaultExecutor": "claude",
|
|
307
|
+
"ollamaBaseUrl": "http://localhost:11434"
|
|
308
|
+
}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Per-agent override:
|
|
312
|
+
```json
|
|
313
|
+
"executor": "ollama:gemma2"
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
When `multiModelEnabled` is `false` (the default), the entire Ollama path is disabled. All agents use `claude -p` regardless of their `executor` field.
|
|
317
|
+
|
|
318
|
+
## Skills
|
|
319
|
+
|
|
320
|
+
Skills are markdown instruction files in `~/.claude/commands/`. In an interactive terminal session, Claude loads these via the `Skill` tool. Since `claude -p` doesn't have the `Skill` tool, the gateway uses a workaround:
|
|
321
|
+
|
|
322
|
+
1. A **skill index** (name + description + file path) is appended to the agent's system prompt
|
|
323
|
+
2. The skills directory is added via `--add-dir ~/.claude/commands/`
|
|
324
|
+
3. When a task matches a skill, the agent uses the `Read` tool to load the full skill file and follows its instructions
|
|
325
|
+
|
|
326
|
+
Configure per agent: `"skills": ["opcodereview", "sop_pdf", "opAgents_AddNew"]`
|
|
327
|
+
|
|
328
|
+
## MCPs (Model Context Protocol)
|
|
329
|
+
|
|
330
|
+
MCP servers are registered once in the top-level `mcps` block of `config.json`, then referenced by name in each agent's config. The gateway:
|
|
331
|
+
|
|
332
|
+
1. Reads the agent's MCP list
|
|
333
|
+
2. Generates a temporary `.mcp.json` file with the server configs
|
|
334
|
+
3. Passes `--mcp-config <path> --strict-mcp-config` to `claude -p`
|
|
335
|
+
4. Adds `mcp__<name>__*` to the allowed tools list
|
|
336
|
+
5. Cleans up the temp file after execution
|
|
337
|
+
|
|
338
|
+
Since everything runs locally on your Mac, stdio MCPs (local processes like context7, playwright) and HTTP/SSE MCPs (remote servers like granola) both work.
|
|
339
|
+
|
|
340
|
+
## Web UI — MyAgent
|
|
341
|
+
|
|
342
|
+
Two pages served by the built-in Express server:
|
|
343
|
+
|
|
344
|
+
### Chat Page (`/ui`)
|
|
345
|
+
- Left sidebar: agent cards with org/department filter dropdowns
|
|
346
|
+
- Right panel: live chat with any agent
|
|
347
|
+
- Streaming agents show real-time text + tool status as Claude works
|
|
348
|
+
- Non-streaming agents show "Thinking..." then full response
|
|
349
|
+
- Session reset button for persistent agents
|
|
350
|
+
- Dashboard link to org page
|
|
351
|
+
|
|
352
|
+
### Org Chart Page (`/org`)
|
|
353
|
+
- Organization dropdown to filter by org
|
|
354
|
+
- Tree hierarchy visualization driven by `reportsTo`
|
|
355
|
+
- Animated connector lines between hierarchy levels (flowing cyan pulse)
|
|
356
|
+
- Agent cards show title, name, alias, department tag, message count
|
|
357
|
+
- Heartbeat ❤ animation on active agents
|
|
358
|
+
- "All Agents" view groups by organization with section headers
|
|
359
|
+
- **+ New Agent** button opens create form
|
|
360
|
+
- **Config** button opens edit modal (same form, pre-filled)
|
|
361
|
+
- Create/edit modals with: name, alias, workspace, persistent/streaming toggles, tool pills, MCP pills, org entries (with datalist autocomplete), routes with @mention toggle
|
|
362
|
+
- Light/dark mode toggle (respects system preference)
|
|
363
|
+
|
|
364
|
+
### API Endpoints
|
|
365
|
+
| Endpoint | Method | Description |
|
|
366
|
+
|----------|--------|-------------|
|
|
367
|
+
| `/ui` | GET | Chat page |
|
|
368
|
+
| `/org` | GET | Org chart page |
|
|
369
|
+
| `/api/dashboard` | GET | All agents, channels, status, uptime |
|
|
370
|
+
| `/api/agents/:id` | GET | Agent detail + last 50 messages |
|
|
371
|
+
| `/api/agents` | POST | Create new agent (form data) |
|
|
372
|
+
| `/api/agents/:id` | PUT | Update existing agent |
|
|
373
|
+
| `/api/chat/:id` | POST | Send message, get response |
|
|
374
|
+
| `/api/chat/:id/stream` | POST | Send message, get SSE stream |
|
|
375
|
+
| `/api/mcps` | GET | List registered MCPs |
|
|
376
|
+
| `/webhook/:id` | POST | External webhook trigger |
|
|
377
|
+
| `/health` | GET | Health check |
|
|
378
|
+
|
|
379
|
+
## Features
|
|
380
|
+
|
|
381
|
+
### Response Chunking
|
|
382
|
+
Long responses automatically split to fit channel limits:
|
|
383
|
+
- Slack: 3900 chars
|
|
384
|
+
- Telegram: 4096 chars
|
|
385
|
+
- iMessage: 3000 chars
|
|
386
|
+
- Discord: 2000 chars
|
|
387
|
+
|
|
388
|
+
Splits prefer newline boundaries to avoid breaking mid-sentence.
|
|
389
|
+
|
|
390
|
+
### Typing Indicators
|
|
391
|
+
When a message is being processed:
|
|
392
|
+
- **Telegram**: Sends native `typing` chat action
|
|
393
|
+
- **Discord**: Sends native typing indicator
|
|
394
|
+
- **Slack/iMessage**: Sends "On it..." text message (no native bot typing API)
|
|
395
|
+
|
|
396
|
+
### DM Pairing / Approval Codes
|
|
397
|
+
Optional security gate for new senders. Set in config:
|
|
398
|
+
```json
|
|
399
|
+
"service": {
|
|
400
|
+
"pairingCode": "mysecretcode"
|
|
401
|
+
}
|
|
402
|
+
```
|
|
403
|
+
First-time senders must send the pairing code before agents respond. Paired senders persisted in `data/paired-senders.json`.
|
|
404
|
+
|
|
405
|
+
### Cron / Scheduled Messages
|
|
406
|
+
Agents can receive scheduled messages:
|
|
407
|
+
```json
|
|
408
|
+
"cron": [
|
|
409
|
+
{
|
|
410
|
+
"schedule": "0 9 * * 1-5",
|
|
411
|
+
"message": "Give me a status update on the current episode",
|
|
412
|
+
"channel": "slack",
|
|
413
|
+
"chatId": "C0AFJMHKZDG"
|
|
414
|
+
}
|
|
415
|
+
]
|
|
416
|
+
```
|
|
417
|
+
Uses standard cron expressions. The agent processes the message and replies on the specified channel.
|
|
418
|
+
|
|
419
|
+
### Autonomous Goals
|
|
420
|
+
|
|
421
|
+
Agents with `"autonomousCapable": true` can be assigned goals — ongoing responsibilities that the agent checks on a recurring heartbeat schedule, with optional budget limits and channel reporting.
|
|
422
|
+
|
|
423
|
+
#### The `autonomousCapable` Flag
|
|
424
|
+
|
|
425
|
+
Set on the agent config to indicate whether this agent can accept goal assignments:
|
|
426
|
+
```json
|
|
427
|
+
"autonomousCapable": true
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
When `false`, the Goals tab in the Org UI is still visible but serves as documentation only — no heartbeats will fire.
|
|
431
|
+
|
|
432
|
+
#### Goal Config Fields
|
|
433
|
+
|
|
434
|
+
Each goal in the `goals` array has:
|
|
435
|
+
|
|
436
|
+
| Field | Required | Description |
|
|
437
|
+
|-------|----------|-------------|
|
|
438
|
+
| `id` | YES | Kebab-case identifier, auto-generated from description (editable) |
|
|
439
|
+
| `enabled` | YES | Whether the goal is active (`true`/`false`) |
|
|
440
|
+
| `description` | YES | What the agent is responsible for |
|
|
441
|
+
| `successCriteria` | no | How to determine the goal is complete |
|
|
442
|
+
| `instructions` | no | Step-by-step guidance for the agent |
|
|
443
|
+
| `heartbeat` | YES | Cron expression for check-in frequency |
|
|
444
|
+
| `budget` | no | `{ "maxDailyUsd": 5.00 }` — max daily spend |
|
|
445
|
+
| `reportTo` | no | `"channel:chatId"` — where to send results (e.g., `"telegram:-5274444946"`) |
|
|
446
|
+
|
|
447
|
+
Example:
|
|
448
|
+
```json
|
|
449
|
+
"goals": [
|
|
450
|
+
{
|
|
451
|
+
"id": "monitor-deploy-health",
|
|
452
|
+
"enabled": true,
|
|
453
|
+
"description": "Monitor production deployment health",
|
|
454
|
+
"successCriteria": "All services returning 200 on health checks",
|
|
455
|
+
"instructions": "1. Check /health on each service\n2. If any fail, report immediately\n3. If all pass, log success silently",
|
|
456
|
+
"heartbeat": "0 9 * * 1-5",
|
|
457
|
+
"budget": { "maxDailyUsd": 2.00 },
|
|
458
|
+
"reportTo": "slack:C0AFJMHKZDG"
|
|
459
|
+
}
|
|
460
|
+
]
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
#### Heartbeat System
|
|
464
|
+
|
|
465
|
+
The `heartbeat` field uses the same cron expression format as scheduled messages. The Org UI provides a human-friendly picker (Every Day/Weekday/Week/Hour at HH:MM AM/PM) that converts to cron syntax.
|
|
466
|
+
|
|
467
|
+
When a heartbeat fires, the agent receives the goal description + instructions as a message and processes it like any other task. Results are sent to the `reportTo` channel if configured.
|
|
468
|
+
|
|
469
|
+
#### Budget Tracking
|
|
470
|
+
|
|
471
|
+
When `budget.maxDailyUsd` is set, the agent tracks spending in `agentHome/goals/budget/`. If the daily limit is reached, the goal pauses until the next day. Budget files are stored per-goal per-day.
|
|
472
|
+
|
|
473
|
+
#### Channel Reporting
|
|
474
|
+
|
|
475
|
+
The `reportTo` field follows the format `"channel:chatId"` (e.g., `"telegram:-5274444946"` or `"slack:C0AFJMHKZDG"`). When set, goal execution results are sent to that channel/chat instead of (or in addition to) the agent's default routes.
|
|
476
|
+
|
|
477
|
+
#### Three States
|
|
478
|
+
|
|
479
|
+
An autonomous-capable agent with goals can be in one of three states:
|
|
480
|
+
|
|
481
|
+
| State | Condition | Behavior |
|
|
482
|
+
|-------|-----------|----------|
|
|
483
|
+
| **Not Capable** | `autonomousCapable: false` | Goals are config-only, no heartbeats fire |
|
|
484
|
+
| **Idle** | `autonomousCapable: true`, no enabled goals | Agent responds to messages only, no autonomous activity |
|
|
485
|
+
| **Active** | `autonomousCapable: true`, 1+ enabled goals | Agent responds to messages AND executes goals on heartbeat schedules |
|
|
486
|
+
|
|
487
|
+
### Task System
|
|
488
|
+
|
|
489
|
+
Agents have per-agent kanban task boards stored in `tasks.json` in the agent's home directory. Tasks are **deliberate** — they are explicitly created, not generated automatically.
|
|
490
|
+
|
|
491
|
+
#### Board Structure
|
|
492
|
+
|
|
493
|
+
Each board has 5 columns representing the task lifecycle:
|
|
494
|
+
|
|
495
|
+
```
|
|
496
|
+
Proposed → Approved → In Progress → Review → Done
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
Tasks start in **Proposed** or **Approved** depending on who creates them, and move through the pipeline as work progresses.
|
|
500
|
+
|
|
501
|
+
#### Creating Tasks
|
|
502
|
+
|
|
503
|
+
There are three ways to create a task:
|
|
504
|
+
|
|
505
|
+
| Method | How | Starting Column |
|
|
506
|
+
|--------|-----|-----------------|
|
|
507
|
+
| **Web UI** | Drag-and-drop board at `/tasks` | User chooses |
|
|
508
|
+
| **Chat command** | `/task add <description>` | Depends on hierarchy |
|
|
509
|
+
| **Agent-to-agent** | One agent assigns a task to another | Depends on hierarchy |
|
|
510
|
+
|
|
511
|
+
#### Hierarchy-Based Assignment
|
|
512
|
+
|
|
513
|
+
Task approval follows the org hierarchy:
|
|
514
|
+
|
|
515
|
+
- **Superior → subordinate**: Task is **auto-approved** (lands in Approved)
|
|
516
|
+
- **Peer → peer**: Task is a **proposal** (lands in Proposed, needs approval)
|
|
517
|
+
|
|
518
|
+
#### Task Commands
|
|
519
|
+
|
|
520
|
+
| Command | Description |
|
|
521
|
+
|---------|-------------|
|
|
522
|
+
| `/task list` | Show active tasks for the current agent |
|
|
523
|
+
| `/task add <description>` | Create a new task |
|
|
524
|
+
| `/task done <id>` | Mark a task as complete (moves to Done) |
|
|
525
|
+
|
|
526
|
+
#### Active Task Context
|
|
527
|
+
|
|
528
|
+
Active tasks (Approved + In Progress) are injected as **read-only context** into the agent's system prompt at the start of each conversation turn. This lets the agent be aware of its current responsibilities without needing to be told.
|
|
529
|
+
|
|
530
|
+
#### Projects
|
|
531
|
+
|
|
532
|
+
Task boards support **projects** — logical groupings within a board. Each project has an `id`, `name`, and `color`. Every board starts with a default "General" project. Tasks are tagged with a project ID for filtering.
|
|
533
|
+
|
|
534
|
+
#### Web UI
|
|
535
|
+
|
|
536
|
+
The task board is available at `/tasks` with:
|
|
537
|
+
- Per-agent board view
|
|
538
|
+
- Drag-and-drop between columns
|
|
539
|
+
- Project filtering
|
|
540
|
+
- Task creation and editing
|
|
541
|
+
|
|
542
|
+
#### Config
|
|
543
|
+
|
|
544
|
+
Tasks are stored in `tasks.json` in the agent's home directory (`agentHome`):
|
|
545
|
+
|
|
546
|
+
```json
|
|
547
|
+
{
|
|
548
|
+
"agentId": "myagent",
|
|
549
|
+
"projects": [{ "id": "general", "name": "General", "color": "#6b7280" }],
|
|
550
|
+
"tasks": []
|
|
551
|
+
}
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
### Webhook Triggers
|
|
555
|
+
External services can trigger agents via HTTP:
|
|
556
|
+
```bash
|
|
557
|
+
curl -X POST http://localhost:4888/webhook/claudeManager \
|
|
558
|
+
-H "Content-Type: application/json" \
|
|
559
|
+
-H "x-webhook-secret: yoursecret" \
|
|
560
|
+
-d '{"text": "PR #42 was merged, update the tracker"}'
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
### Voice Note Transcription
|
|
564
|
+
Telegram voice messages and audio files automatically transcribed via OpenAI Whisper API. Requires `OPENAI_API_KEY` environment variable. If not set, voice messages are silently ignored.
|
|
565
|
+
|
|
566
|
+
### Media Output (File Sending)
|
|
567
|
+
All channel drivers support sending files back:
|
|
568
|
+
- **Telegram**: Photos as photos, other files as documents
|
|
569
|
+
- **Slack**: Files uploaded via Slack API
|
|
570
|
+
- **Discord**: Files as message attachments
|
|
571
|
+
|
|
572
|
+
## Infrastructure
|
|
573
|
+
|
|
574
|
+
**Everything runs on your Mac as a single Node.js process.**
|
|
575
|
+
|
|
576
|
+
| Component | Where | Port | Notes |
|
|
577
|
+
|-----------|-------|------|-------|
|
|
578
|
+
| Gateway service | launchd | — | Main process: channels, router, executor |
|
|
579
|
+
| Slack connection | Outbound WSS | — | Socket Mode to Slack servers |
|
|
580
|
+
| Telegram connection | Outbound HTTPS | — | Long polling to Telegram API |
|
|
581
|
+
| iMessage watcher | Local subprocess | — | `imsg` CLI watches Messages.db |
|
|
582
|
+
| Discord connection | Outbound WSS | — | discord.js gateway |
|
|
583
|
+
| WhatsApp connection | Outbound WSS | — | Baileys protocol |
|
|
584
|
+
| Web UI + API + Webhooks | localhost | 4888 | Express server (not exposed to internet) |
|
|
585
|
+
| Cron scheduler | In-memory | — | node-cron timers |
|
|
586
|
+
| `claude -p` | Spawned per message | — | Claude Code CLI in print mode |
|
|
587
|
+
| MCP servers | Spawned per message | — | stdio subprocesses or HTTP calls |
|
|
588
|
+
|
|
589
|
+
**Your Mac must be on and awake** for agents to be reachable.
|
|
590
|
+
|
|
591
|
+
## File Structure
|
|
592
|
+
|
|
593
|
+
```
|
|
594
|
+
channelToAgentToClaude/ # The gateway project
|
|
595
|
+
├── config.json # Channels, MCPs, agents, routes, web UI, cron (gitignored)
|
|
596
|
+
├── config.example.json # Template for new installs
|
|
597
|
+
├── src/
|
|
598
|
+
│ ├── index.ts # Entry point — wires everything together
|
|
599
|
+
│ ├── config.ts # Config loader + validation + interfaces
|
|
600
|
+
│ ├── router.ts # Routes messages + DM pairing
|
|
601
|
+
│ ├── executor.ts # Spawns claude -p, sessions, streaming, skills, commands
|
|
602
|
+
│ ├── web-ui.ts # Express server: UI pages, API, chat, webhooks
|
|
603
|
+
│ ├── cron.ts # Scheduled message triggers
|
|
604
|
+
│ ├── channels/
|
|
605
|
+
│ │ ├── types.ts # ChannelDriver interface + splitText utility
|
|
606
|
+
│ │ ├── imessage.ts # iMessage driver (imsg CLI)
|
|
607
|
+
│ │ ├── slack.ts # Slack driver (Socket Mode)
|
|
608
|
+
│ │ ├── telegram.ts # Telegram driver (grammY + voice transcription)
|
|
609
|
+
│ │ ├── discord.ts # Discord driver (discord.js)
|
|
610
|
+
│ │ └── whatsapp.ts # WhatsApp driver (Baileys)
|
|
611
|
+
│ └── utils/
|
|
612
|
+
│ ├── imsg-rpc.ts # JSON-RPC client for imsg
|
|
613
|
+
│ └── message-formatter.ts # Message formatting with context + history
|
|
614
|
+
├── public/
|
|
615
|
+
│ ├── index.html # Chat UI page
|
|
616
|
+
│ └── org.html # Org chart page
|
|
617
|
+
├── agents/ # Agent identity files (project-scoped agents)
|
|
618
|
+
│ ├── _template/
|
|
619
|
+
│ ├── fic-show/
|
|
620
|
+
│ └── fic-platform/
|
|
621
|
+
├── Comprehensive Test Suite/ # 7 test files, 43 tests
|
|
622
|
+
│ ├── run-all-tests.js
|
|
623
|
+
│ ├── config/
|
|
624
|
+
│ ├── router/
|
|
625
|
+
│ ├── executor/
|
|
626
|
+
│ ├── web-ui/
|
|
627
|
+
│ ├── cron/
|
|
628
|
+
│ ├── types/
|
|
629
|
+
│ └── message-formatter/
|
|
630
|
+
├── data/
|
|
631
|
+
│ ├── whatsapp-auth/ # WhatsApp session credentials
|
|
632
|
+
│ └── paired-senders.json # DM pairing store
|
|
633
|
+
├── docs/
|
|
634
|
+
│ ├── Architecture.md # This file
|
|
635
|
+
│ ├── Setup.md # Setup guide for new installs
|
|
636
|
+
│ ├── AddNewAgentGuide.md
|
|
637
|
+
│ └── AddNewMcpGuide.md
|
|
638
|
+
└── logs/
|
|
639
|
+
└── service.log
|
|
640
|
+
|
|
641
|
+
~/Desktop/MyAIforOne Drive/PersonalAgents/ # Agent homes (personal agents)
|
|
642
|
+
└── claudeManager/
|
|
643
|
+
├── CLAUDE.md # System prompt
|
|
644
|
+
├── memory/
|
|
645
|
+
│ ├── context.md # Persistent context (survives resets)
|
|
646
|
+
│ ├── session.json # Session UUID pointer
|
|
647
|
+
│ └── conversation_log.jsonl # Audit trail
|
|
648
|
+
└── goals/ # Budget tracking and goal execution logs
|
|
649
|
+
├── budget/ # Daily budget usage per goal
|
|
650
|
+
└── logs/ # Execution logs from goal heartbeats
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
## Config Reference
|
|
654
|
+
|
|
655
|
+
### Service
|
|
656
|
+
```json
|
|
657
|
+
"service": {
|
|
658
|
+
"logLevel": "debug",
|
|
659
|
+
"logFile": "./logs/service.log",
|
|
660
|
+
"pairingCode": "optional-secret",
|
|
661
|
+
"webUI": {
|
|
662
|
+
"enabled": true,
|
|
663
|
+
"port": 4888,
|
|
664
|
+
"webhookSecret": "optional-secret"
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
```
|
|
668
|
+
|
|
669
|
+
### Channels
|
|
670
|
+
```json
|
|
671
|
+
"telegram": {
|
|
672
|
+
"enabled": true,
|
|
673
|
+
"driver": "telegram",
|
|
674
|
+
"config": { "botToken": "123:ABC..." }
|
|
675
|
+
},
|
|
676
|
+
"slack": {
|
|
677
|
+
"enabled": true,
|
|
678
|
+
"driver": "slack",
|
|
679
|
+
"config": { "botToken": "xoxb-...", "appToken": "xapp-...", "mode": "socket" }
|
|
680
|
+
},
|
|
681
|
+
"discord": {
|
|
682
|
+
"enabled": false,
|
|
683
|
+
"driver": "discord",
|
|
684
|
+
"config": { "botToken": "..." }
|
|
685
|
+
},
|
|
686
|
+
"imessage": {
|
|
687
|
+
"enabled": true,
|
|
688
|
+
"driver": "imessage",
|
|
689
|
+
"config": { "cliPath": "imsg", "debounceMs": 2000 }
|
|
690
|
+
},
|
|
691
|
+
"whatsapp": {
|
|
692
|
+
"enabled": false,
|
|
693
|
+
"driver": "whatsapp",
|
|
694
|
+
"config": { "authDir": "./data/whatsapp-auth" }
|
|
695
|
+
}
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
### MCP Registry
|
|
699
|
+
```json
|
|
700
|
+
"mcps": {
|
|
701
|
+
"context7": { "type": "stdio", "command": "npx", "args": ["-y", "@upstash/context7-mcp"] },
|
|
702
|
+
"playwright": { "type": "stdio", "command": "npx", "args": ["@playwright/mcp@latest"] },
|
|
703
|
+
"granola": { "type": "sse", "url": "https://mcp.granola.ai/mcp" }
|
|
704
|
+
}
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
### Agent (full example)
|
|
708
|
+
```json
|
|
709
|
+
"claudeManager": {
|
|
710
|
+
"name": "Claude Manager Agent",
|
|
711
|
+
"description": "General-purpose Claude agent",
|
|
712
|
+
"workspace": "~",
|
|
713
|
+
"claudeMd": "~/Desktop/MyAIforOne Drive/PersonalAgents/claudeManager/CLAUDE.md",
|
|
714
|
+
"memoryDir": "~/Desktop/MyAIforOne Drive/PersonalAgents/claudeManager/memory",
|
|
715
|
+
"claudeAccount": "main",
|
|
716
|
+
"mcps": ["context7", "playwright", "granola"],
|
|
717
|
+
"persistent": true,
|
|
718
|
+
"streaming": true,
|
|
719
|
+
"advancedMemory": true,
|
|
720
|
+
"perSenderSessions": false,
|
|
721
|
+
"skills": ["opcodereview", "sop_pdf"],
|
|
722
|
+
"mentionAliases": ["@agentmgr"],
|
|
723
|
+
"autoCommit": false,
|
|
724
|
+
"allowedTools": ["Read", "Edit", "Write", "Glob", "Grep", "Bash", "WebFetch", "WebSearch"],
|
|
725
|
+
"timeout": 120000,
|
|
726
|
+
"org": [
|
|
727
|
+
{ "organization": "Finance Is Cooked", "function": "Operations", "title": "Chief of Staff" },
|
|
728
|
+
{ "organization": "Personal", "function": "Operations", "title": "General Manager" }
|
|
729
|
+
],
|
|
730
|
+
"cron": [
|
|
731
|
+
{
|
|
732
|
+
"schedule": "0 9 * * 1-5",
|
|
733
|
+
"message": "Good morning. Any tasks pending?",
|
|
734
|
+
"channel": "telegram",
|
|
735
|
+
"chatId": "-5274444946"
|
|
736
|
+
}
|
|
737
|
+
],
|
|
738
|
+
"routes": [
|
|
739
|
+
{
|
|
740
|
+
"channel": "telegram",
|
|
741
|
+
"match": { "type": "chat_id", "value": "-5274444946" },
|
|
742
|
+
"permissions": { "allowFrom": ["*"], "requireMention": true }
|
|
743
|
+
}
|
|
744
|
+
]
|
|
745
|
+
}
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
## Adding a New Agent
|
|
749
|
+
|
|
750
|
+
Three ways:
|
|
751
|
+
|
|
752
|
+
1. **Web UI**: Go to `/org` → click **"+ New Agent"** → fill out the form
|
|
753
|
+
2. **Chat**: Message `@agentmgr` with "create a new agent" (uses the `/opAgents_AddNew` skill)
|
|
754
|
+
3. **Manual**: See `docs/AddNewAgentGuide.md` or `docs/Setup.md`
|
|
755
|
+
|
|
756
|
+
## Running
|
|
757
|
+
|
|
758
|
+
```bash
|
|
759
|
+
npm run build # Compile TypeScript
|
|
760
|
+
npm start # Run directly
|
|
761
|
+
npm run dev # Dev mode with auto-reload
|
|
762
|
+
npm test # Run test suite (43 tests)
|
|
763
|
+
```
|
|
764
|
+
|
|
765
|
+
### As a launchd service (auto-start on login)
|
|
766
|
+
```bash
|
|
767
|
+
# Start
|
|
768
|
+
launchctl load ~/Library/LaunchAgents/com.agenticledger.channelToAgentToClaude.plist
|
|
769
|
+
|
|
770
|
+
# Stop
|
|
771
|
+
launchctl unload ~/Library/LaunchAgents/com.agenticledger.channelToAgentToClaude.plist
|
|
772
|
+
|
|
773
|
+
# Restart
|
|
774
|
+
launchctl unload ~/Library/LaunchAgents/com.agenticledger.channelToAgentToClaude.plist && \
|
|
775
|
+
sleep 1 && \
|
|
776
|
+
launchctl load ~/Library/LaunchAgents/com.agenticledger.channelToAgentToClaude.plist
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
## Tech Stack
|
|
780
|
+
|
|
781
|
+
| Layer | Technology |
|
|
782
|
+
|-------|------------|
|
|
783
|
+
| **Language** | TypeScript 5.7 |
|
|
784
|
+
| **Runtime** | Node.js 22+ |
|
|
785
|
+
| **iMessage** | `imsg` CLI (JSON-RPC) |
|
|
786
|
+
| **Slack** | @slack/socket-mode, @slack/web-api |
|
|
787
|
+
| **Telegram** | grammY |
|
|
788
|
+
| **Discord** | discord.js |
|
|
789
|
+
| **WhatsApp** | @whiskeysockets/baileys |
|
|
790
|
+
| **Web UI** | Express + vanilla HTML/CSS/JS (no framework) |
|
|
791
|
+
| **Voice** | OpenAI Whisper API |
|
|
792
|
+
| **Scheduling** | node-cron |
|
|
793
|
+
| **AI Engine** | `claude -p` (Claude Code CLI) |
|
|
794
|
+
| **Service** | launchd (macOS native) |
|
|
795
|
+
| **Tests** | Node.js built-in test runner |
|