daemora 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.
Files changed (115) hide show
  1. package/README.md +666 -0
  2. package/SOUL.md +104 -0
  3. package/config/hooks.json +14 -0
  4. package/config/mcp.json +145 -0
  5. package/package.json +86 -0
  6. package/skills/.gitkeep +0 -0
  7. package/skills/apple-notes.md +193 -0
  8. package/skills/apple-reminders.md +189 -0
  9. package/skills/camsnap.md +162 -0
  10. package/skills/coding.md +14 -0
  11. package/skills/documents.md +13 -0
  12. package/skills/email.md +13 -0
  13. package/skills/gif-search.md +196 -0
  14. package/skills/healthcheck.md +225 -0
  15. package/skills/image-gen.md +147 -0
  16. package/skills/model-usage.md +182 -0
  17. package/skills/obsidian.md +207 -0
  18. package/skills/pdf.md +211 -0
  19. package/skills/research.md +13 -0
  20. package/skills/skill-creator.md +142 -0
  21. package/skills/spotify.md +149 -0
  22. package/skills/summarize.md +230 -0
  23. package/skills/things.md +199 -0
  24. package/skills/tmux.md +204 -0
  25. package/skills/trello.md +183 -0
  26. package/skills/video-frames.md +202 -0
  27. package/skills/weather.md +127 -0
  28. package/src/a2a/A2AClient.js +136 -0
  29. package/src/a2a/A2AServer.js +316 -0
  30. package/src/a2a/AgentCard.js +79 -0
  31. package/src/agents/SubAgentManager.js +369 -0
  32. package/src/agents/Supervisor.js +192 -0
  33. package/src/channels/BaseChannel.js +104 -0
  34. package/src/channels/DiscordChannel.js +288 -0
  35. package/src/channels/EmailChannel.js +172 -0
  36. package/src/channels/GoogleChatChannel.js +316 -0
  37. package/src/channels/HttpChannel.js +26 -0
  38. package/src/channels/LineChannel.js +168 -0
  39. package/src/channels/SignalChannel.js +186 -0
  40. package/src/channels/SlackChannel.js +329 -0
  41. package/src/channels/TeamsChannel.js +272 -0
  42. package/src/channels/TelegramChannel.js +347 -0
  43. package/src/channels/WhatsAppChannel.js +219 -0
  44. package/src/channels/index.js +198 -0
  45. package/src/cli.js +1267 -0
  46. package/src/config/agentProfiles.js +120 -0
  47. package/src/config/channels.js +32 -0
  48. package/src/config/default.js +206 -0
  49. package/src/config/models.js +123 -0
  50. package/src/config/permissions.js +167 -0
  51. package/src/core/AgentLoop.js +446 -0
  52. package/src/core/Compaction.js +143 -0
  53. package/src/core/CostTracker.js +116 -0
  54. package/src/core/EventBus.js +46 -0
  55. package/src/core/Task.js +67 -0
  56. package/src/core/TaskQueue.js +206 -0
  57. package/src/core/TaskRunner.js +226 -0
  58. package/src/daemon/DaemonManager.js +301 -0
  59. package/src/hooks/HookRunner.js +230 -0
  60. package/src/index.js +482 -0
  61. package/src/mcp/MCPAgentRunner.js +112 -0
  62. package/src/mcp/MCPClient.js +186 -0
  63. package/src/mcp/MCPManager.js +412 -0
  64. package/src/models/ModelRouter.js +180 -0
  65. package/src/safety/AuditLog.js +135 -0
  66. package/src/safety/CircuitBreaker.js +126 -0
  67. package/src/safety/FilesystemGuard.js +169 -0
  68. package/src/safety/GitRollback.js +139 -0
  69. package/src/safety/HumanApproval.js +156 -0
  70. package/src/safety/InputSanitizer.js +72 -0
  71. package/src/safety/PermissionGuard.js +83 -0
  72. package/src/safety/Sandbox.js +70 -0
  73. package/src/safety/SecretScanner.js +100 -0
  74. package/src/safety/SecretVault.js +250 -0
  75. package/src/scheduler/Heartbeat.js +115 -0
  76. package/src/scheduler/Scheduler.js +228 -0
  77. package/src/services/models/outputSchema.js +15 -0
  78. package/src/services/openai.js +25 -0
  79. package/src/services/sessions.js +65 -0
  80. package/src/setup/theme.js +110 -0
  81. package/src/setup/wizard.js +788 -0
  82. package/src/skills/SkillLoader.js +168 -0
  83. package/src/storage/TaskStore.js +69 -0
  84. package/src/systemPrompt.js +526 -0
  85. package/src/tenants/TenantContext.js +19 -0
  86. package/src/tenants/TenantManager.js +379 -0
  87. package/src/tools/ToolRegistry.js +141 -0
  88. package/src/tools/applyPatch.js +144 -0
  89. package/src/tools/browserAutomation.js +223 -0
  90. package/src/tools/createDocument.js +265 -0
  91. package/src/tools/cronTool.js +105 -0
  92. package/src/tools/editFile.js +139 -0
  93. package/src/tools/executeCommand.js +123 -0
  94. package/src/tools/glob.js +67 -0
  95. package/src/tools/grep.js +121 -0
  96. package/src/tools/imageAnalysis.js +120 -0
  97. package/src/tools/index.js +173 -0
  98. package/src/tools/listDirectory.js +47 -0
  99. package/src/tools/manageAgents.js +47 -0
  100. package/src/tools/manageMCP.js +159 -0
  101. package/src/tools/memory.js +478 -0
  102. package/src/tools/messageChannel.js +45 -0
  103. package/src/tools/projectTracker.js +259 -0
  104. package/src/tools/readFile.js +52 -0
  105. package/src/tools/screenCapture.js +112 -0
  106. package/src/tools/searchContent.js +76 -0
  107. package/src/tools/searchFiles.js +75 -0
  108. package/src/tools/sendEmail.js +118 -0
  109. package/src/tools/sendFile.js +63 -0
  110. package/src/tools/textToSpeech.js +161 -0
  111. package/src/tools/transcribeAudio.js +82 -0
  112. package/src/tools/useMCP.js +29 -0
  113. package/src/tools/webFetch.js +150 -0
  114. package/src/tools/webSearch.js +134 -0
  115. package/src/tools/writeFile.js +26 -0
package/README.md ADDED
@@ -0,0 +1,666 @@
1
+ # Daemora
2
+
3
+ **A fully autonomous, self-hosted AI agent — production-secure, multi-tenant, multi-channel.**
4
+
5
+ [![npm](https://img.shields.io/npm/v/daemora?color=black&label=npm)](https://npmjs.com/package/daemora)
6
+ [![license](https://img.shields.io/badge/license-AGPL--3.0-black)](LICENSE)
7
+ [![node](https://img.shields.io/badge/node-20%2B-black)](https://nodejs.org)
8
+ [![platform](https://img.shields.io/badge/platform-macOS%20%7C%20Linux%20%7C%20Windows-black)](#)
9
+
10
+ Daemora runs on your own machine. It connects to your messaging apps, accepts tasks in plain language, executes them autonomously with 36 built-in tools, and reports back — without you watching over it.
11
+
12
+ Unlike cloud AI assistants, nothing leaves your infrastructure except the tokens you intentionally send to model APIs. You own the data, the keys, and the security boundary.
13
+
14
+ ---
15
+
16
+ ## What Daemora Can Do
17
+
18
+ | Capability | Description |
19
+ |---|---|
20
+ | **Code** | Write, edit, run, test, and debug code across multiple files. Takes screenshots of UIs to verify output. Fixes failing tests. Ships working software. |
21
+ | **Research** | Search the web, read pages, analyse images, cross-reference sources, write reports. Spawns parallel sub-agents for speed. |
22
+ | **Automation** | Schedule recurring tasks via cron. Monitor repos, inboxes, or APIs. React to events. Runs while you sleep. |
23
+ | **Communicate** | Send emails, Telegram messages, Slack posts, Discord messages — autonomously, when the task calls for it. |
24
+ | **Tools** | Connect to any MCP server — create Notion pages, open GitHub issues, update Linear tasks, manage Shopify products, query databases. |
25
+ | **Multi-Agent** | Spawn parallel sub-agents (researcher + coder + writer working simultaneously). Each inherits the parent's model and API keys. |
26
+ | **Multi-Tenant** | Run one instance for your whole team. Per-user memory, cost caps, tool allowlists, filesystem isolation, and encrypted API keys. |
27
+
28
+ ---
29
+
30
+ ## Architecture
31
+
32
+ ```
33
+ ┌─────────────────────────────────────────────────────────────────┐
34
+ │ INPUT CHANNELS │
35
+ │ Telegram · WhatsApp · Discord · Slack · Email · LINE · │
36
+ │ Signal · Microsoft Teams · Google Chat │
37
+ └───────────────────────────┬─────────────────────────────────────┘
38
+
39
+
40
+ ┌─────────────────────────────────────────────────────────────────┐
41
+ │ MULTI-TENANT LAYER │
42
+ │ TenantManager + TenantContext (AsyncLocalStorage) │
43
+ │ Per-user: model, tools, MCP servers, filesystem, cost caps, │
44
+ │ encrypted API keys, isolated memory │
45
+ └───────────────────────────┬─────────────────────────────────────┘
46
+
47
+
48
+ ┌─────────────────────────────────────────────────────────────────┐
49
+ │ TASK QUEUE │
50
+ │ Priority queue · Per-session serialisation │
51
+ │ Steer/inject: follow-up messages injected into running loop │
52
+ │ Cost budget check · Tenant suspension check │
53
+ └───────────────────────────┬─────────────────────────────────────┘
54
+
55
+
56
+ ┌─────────────────────────────────────────────────────────────────┐
57
+ │ AGENT LOOP │
58
+ │ Vercel AI SDK (generateText + tool_use) │
59
+ │ System prompt: SOUL.md + memory + daily log + task context │
60
+ │ Model: OpenAI · Anthropic · Google · Ollama (local) │
61
+ │ Context compaction when approaching model limits │
62
+ └──────────────┬─────────────────────────────────┬────────────────┘
63
+ │ │
64
+ ▼ ▼
65
+ ┌──────────────────────────┐ ┌──────────────────────────────┐
66
+ │ BUILT-IN TOOLS │ │ SUB-AGENTS │
67
+ │ File I/O · Shell │ │ spawnAgent · parallelAgents │
68
+ │ Web · Browser │ │ delegateToAgent │
69
+ │ Email · Messaging │ │ Profiles: coder / researcher│
70
+ │ Vision · TTS │ │ / writer / analyst │
71
+ │ Memory · Documents │ │ Inherit model + API keys │
72
+ │ Cron · Agents · MCP │ │ Max depth: 3 Max: 7 agents │
73
+ └──────────────────────────┘ └──────────────┬───────────────┘
74
+
75
+
76
+ ┌──────────────────────────────┐
77
+ │ MCP SERVERS │
78
+ │ Per-server specialist agent │
79
+ │ GitHub · Notion · Linear │
80
+ │ Slack · Postgres · Puppeteer│
81
+ │ stdio / HTTP / SSE │
82
+ └──────────────────────────────┘
83
+ ```
84
+
85
+ ### Security Architecture (10 Layers)
86
+
87
+ ```
88
+ LAYER 1 Permission Tiers ───── minimal / standard / full
89
+ LAYER 2 Filesystem Sandbox ─── ALLOWED_PATHS · BLOCKED_PATHS · hardcoded blocks
90
+ LAYER 3 Secret Vault ────────── AES-256-GCM · scrypt key derivation · passphrase on start
91
+ LAYER 4 Channel Allowlists ─── per-channel user ID whitelist
92
+ LAYER 5 A2A Security ────────── bearer token · agent allowlist · rate limiting
93
+ LAYER 6 Audit Trail ─────────── append-only JSONL · secrets redacted · tenantId tagged
94
+ LAYER 7 Supervisor Agent ────── runaway loop detection · cost overruns · dangerous patterns
95
+ LAYER 8 Input Sanitisation ─── untrusted-input wrapping · prompt injection detection
96
+ LAYER 9 Multi-Tenant Isolation ─ AsyncLocalStorage · no cross-tenant data leakage
97
+ LAYER 10 Security Audit CLI ─── daemora doctor · 8 checks · scored output
98
+ ```
99
+
100
+ ---
101
+
102
+ ## Sequence Diagrams
103
+
104
+ ### Task Lifecycle — from message to response
105
+
106
+ ```mermaid
107
+ sequenceDiagram
108
+ actor User as User (Telegram)
109
+ participant Ch as Channel
110
+ participant TQ as TaskQueue
111
+ participant TC as TenantContext
112
+ participant AL as AgentLoop
113
+ participant T as Tools
114
+ participant MC as MCP Server
115
+
116
+ User->>Ch: "Fix the auth bug and open a PR"
117
+ Ch->>TQ: enqueue(task, sessionId)
118
+ Ch-->>User: ⏳ reaction
119
+
120
+ TQ->>TC: run({ tenant, model, apiKeys })
121
+ TC->>AL: runAgentLoop(systemPrompt, messages)
122
+
123
+ AL->>T: readFile("src/auth.js")
124
+ T-->>AL: file contents
125
+
126
+ AL->>T: editFile("src/auth.js", patch)
127
+ T-->>AL: success
128
+
129
+ AL->>T: executeCommand("npm test")
130
+ T-->>AL: all tests passing
131
+
132
+ AL->>MC: useMCP("github", "open a PR for this fix")
133
+ MC-->>AL: PR #42 created
134
+
135
+ AL-->>TC: "Fixed auth bug, opened PR #42"
136
+ TC-->>Ch: task complete
137
+ Ch->>User: "Fixed. PR #42 is open ✅"
138
+ Ch-->>User: ✅ reaction
139
+ ```
140
+
141
+ ---
142
+
143
+ ### Multi-Agent — parallel sub-agents
144
+
145
+ ```mermaid
146
+ sequenceDiagram
147
+ actor User
148
+ participant AL as AgentLoop (Main)
149
+ participant SM as SubAgentManager
150
+ participant R as Researcher Agent
151
+ participant W as Writer Agent
152
+ participant C as Coder Agent
153
+
154
+ User->>AL: "Research top 5 competitors, write a report, save it to docs/"
155
+
156
+ AL->>SM: parallelAgents([researcher × 5, writer])
157
+
158
+ par Concurrent execution
159
+ SM->>R: spawn(profile=researcher, "Competitor A")
160
+ R->>R: webSearch + webFetch
161
+ R-->>AL: notes on Competitor A
162
+ and
163
+ SM->>R: spawn(profile=researcher, "Competitor B")
164
+ R->>R: webSearch + webFetch
165
+ R-->>AL: notes on Competitor B
166
+ and
167
+ SM->>W: spawn(profile=writer, "draft outline")
168
+ W->>W: structure + draft
169
+ W-->>AL: draft report
170
+ end
171
+
172
+ AL->>C: spawnAgent(profile=coder, "save report to docs/competitors.md")
173
+ C->>C: writeFile("docs/competitors.md")
174
+ C-->>AL: done
175
+
176
+ AL->>User: "Report saved → docs/competitors.md"
177
+ ```
178
+
179
+ ---
180
+
181
+ ### Steer/Inject — follow-up message mid-task
182
+
183
+ ```mermaid
184
+ sequenceDiagram
185
+ actor User
186
+ participant TQ as TaskQueue
187
+ participant TR as TaskRunner
188
+ participant AL as AgentLoop
189
+
190
+ User->>TQ: "Fix the login bug"
191
+ TQ->>TR: dequeue task-1
192
+ TR->>AL: runAgentLoop(task-1)
193
+ Note over AL: tool call: readFile("auth.js") ...
194
+
195
+ User->>TQ: "Also fix the signup form while you're at it"
196
+ Note over TR: Session already active — inject, don't queue
197
+ TR->>AL: steerQueue.push(user message)
198
+ TR->>TQ: merge(task-2) — silent complete, no duplicate reply
199
+
200
+ Note over AL: drains steerQueue between tool calls
201
+ AL->>AL: both tasks now in context
202
+
203
+ AL-->>User: "Fixed login bug AND signup form validation ✅"
204
+ ```
205
+
206
+ ---
207
+
208
+ ## Quick Start
209
+
210
+ ```bash
211
+ npm install -g daemora
212
+ daemora setup # interactive wizard — models, channels, vault, MCP
213
+ daemora start # start the agent
214
+ ```
215
+
216
+ Then message your bot. That's it.
217
+
218
+ ---
219
+
220
+ ## Installation
221
+
222
+ ### npm (recommended)
223
+
224
+ ```bash
225
+ npm install -g daemora
226
+ daemora setup
227
+ daemora start
228
+ ```
229
+
230
+ ### Clone from source
231
+
232
+ ```bash
233
+ git clone https://github.com/umarfarooq/daemora-agent.git
234
+ cd daemora-agent
235
+ npm install
236
+ cp .env.example .env
237
+ # Add your API keys to .env
238
+ daemora setup
239
+ daemora start
240
+ ```
241
+
242
+ ### Run as a system daemon (always on)
243
+
244
+ ```bash
245
+ daemora daemon install # Register as a system service (launchctl / systemd / Task Scheduler)
246
+ daemora daemon start # Start in background
247
+ daemora daemon status # Check status
248
+ daemora daemon logs # View logs
249
+ daemora daemon stop # Stop
250
+ ```
251
+
252
+ ---
253
+
254
+ ## Configuration
255
+
256
+ Copy `.env.example` to `.env` and fill in what you need.
257
+
258
+ ### AI Models
259
+
260
+ At least one provider is required:
261
+
262
+ ```env
263
+ OPENAI_API_KEY=sk-...
264
+ ANTHROPIC_API_KEY=sk-ant-...
265
+ GOOGLE_AI_API_KEY=...
266
+
267
+ # Default model (used when no model is specified)
268
+ DEFAULT_MODEL=openai:gpt-4.1-mini
269
+ ```
270
+
271
+ **Supported models:**
272
+
273
+ | Model ID | Description |
274
+ |---|---|
275
+ | `openai:gpt-4.1` | Most capable OpenAI model |
276
+ | `openai:gpt-4.1-mini` | Fast and cheap — good default |
277
+ | `anthropic:claude-opus-4-6` | Best for complex reasoning |
278
+ | `anthropic:claude-sonnet-4-6` | Balanced — great for code |
279
+ | `google:gemini-2.5-pro` | Best for long context |
280
+ | `google:gemini-2.0-flash` | Fastest Google model |
281
+ | `ollama:llama3.2` | Local — no API key needed |
282
+
283
+ ### Task-Type Model Routing (optional)
284
+
285
+ Route different task types to the best model automatically:
286
+
287
+ ```env
288
+ CODE_MODEL=anthropic:claude-sonnet-4-6
289
+ RESEARCH_MODEL=google:gemini-2.0-flash
290
+ WRITER_MODEL=openai:gpt-4.1
291
+ ANALYST_MODEL=openai:gpt-4.1
292
+ ```
293
+
294
+ When a sub-agent is spawned with `profile: "coder"`, it automatically uses `CODE_MODEL`. Sub-agents without an explicit model inherit from their parent.
295
+
296
+ ### Channels
297
+
298
+ Enable only what you need:
299
+
300
+ ```env
301
+ # Telegram
302
+ TELEGRAM_BOT_TOKEN=...
303
+ TELEGRAM_ALLOWLIST=123456789,987654321 # optional: restrict to specific users
304
+
305
+ # WhatsApp (via Twilio)
306
+ TWILIO_ACCOUNT_SID=...
307
+ TWILIO_AUTH_TOKEN=...
308
+ TWILIO_WHATSAPP_FROM=whatsapp:+14155238886
309
+
310
+ # Discord
311
+ DISCORD_BOT_TOKEN=...
312
+
313
+ # Slack
314
+ SLACK_BOT_TOKEN=xoxb-...
315
+ SLACK_APP_TOKEN=xapp-...
316
+
317
+ # Email (IMAP + SMTP)
318
+ EMAIL_USER=you@gmail.com
319
+ EMAIL_PASSWORD=your-app-password
320
+ EMAIL_IMAP_HOST=imap.gmail.com
321
+ EMAIL_SMTP_HOST=smtp.gmail.com
322
+ ```
323
+
324
+ Each channel supports an `{CHANNEL}_ALLOWLIST` and `{CHANNEL}_MODEL` override.
325
+
326
+ ### Cost Limits
327
+
328
+ ```env
329
+ MAX_COST_PER_TASK=0.50 # Max $ per task (agent stops mid-task if exceeded)
330
+ MAX_DAILY_COST=10.00 # Max $ per day across all tasks
331
+ ```
332
+
333
+ ### Security
334
+
335
+ ```env
336
+ PERMISSION_TIER=standard # minimal | standard | full
337
+ ALLOWED_PATHS=/home/user/work # Sandbox: restrict file access to these directories
338
+ BLOCKED_PATHS=/home/user/.secrets # Always block these, even inside allowed paths
339
+ RESTRICT_COMMANDS=true # Block shell commands referencing paths outside sandbox
340
+
341
+ # Per-tenant API key encryption (required for production multi-tenant mode)
342
+ # Generate: openssl rand -hex 32
343
+ DAEMORA_TENANT_KEY=
344
+ ```
345
+
346
+ ---
347
+
348
+ ## MCP Servers
349
+
350
+ MCP (Model Context Protocol) lets Daemora control external tools. Each connected server gets a specialist sub-agent with focused context.
351
+
352
+ ```bash
353
+ # Add a server (interactive)
354
+ daemora mcp add
355
+
356
+ # Add a server (command line)
357
+ daemora mcp add github npx -y @modelcontextprotocol/server-github
358
+ daemora mcp add notion npx -y @notionhq/notion-mcp-server
359
+ daemora mcp add myserver https://api.example.com/mcp # HTTP
360
+ daemora mcp add myserver https://api.example.com/sse --sse # SSE
361
+
362
+ # Manage servers
363
+ daemora mcp list # Show all configured servers
364
+ daemora mcp enable github # Enable a server
365
+ daemora mcp disable github # Disable without removing
366
+ daemora mcp reload github # Reconnect after config changes
367
+ daemora mcp remove github # Remove permanently
368
+ ```
369
+
370
+ **Popular MCP servers:**
371
+
372
+ | Service | Install Command |
373
+ |---|---|
374
+ | GitHub | `npx -y @modelcontextprotocol/server-github` |
375
+ | Notion | `npx -y @notionhq/notion-mcp-server` |
376
+ | Linear | `npx -y @linear/mcp-server` |
377
+ | Slack | `npx -y @modelcontextprotocol/server-slack` |
378
+ | PostgreSQL | `npx -y @modelcontextprotocol/server-postgres` |
379
+ | Filesystem | `npx -y @modelcontextprotocol/server-filesystem` |
380
+ | Brave Search | `npx -y @anthropic-ai/brave-search-mcp-server` |
381
+ | Puppeteer | `npx -y @modelcontextprotocol/server-puppeteer` |
382
+
383
+ ---
384
+
385
+ ## Built-in Tools
386
+
387
+ 36 tools the agent uses autonomously:
388
+
389
+ | Category | Tools |
390
+ |---|---|
391
+ | **Files** | readFile, writeFile, editFile, listDirectory, applyPatch |
392
+ | **Search** | searchFiles, searchContent, glob, grep |
393
+ | **Shell** | executeCommand (foreground + background) |
394
+ | **Web** | webFetch, webSearch, browserAction (navigate, click, fill, screenshot) |
395
+ | **Vision** | imageAnalysis, screenCapture |
396
+ | **Communication** | sendEmail, messageChannel, sendFile, transcribeAudio, textToSpeech |
397
+ | **Documents** | createDocument (Markdown, PDF, DOCX) |
398
+ | **Memory** | readMemory, writeMemory, searchMemory, pruneMemory, readDailyLog, writeDailyLog |
399
+ | **Agents** | spawnAgent, parallelAgents, delegateToAgent, manageAgents |
400
+ | **MCP** | useMCP, manageMCP |
401
+ | **Scheduling** | cron (add, list, run, update, delete) |
402
+ | **Tracking** | projectTracker |
403
+
404
+ ---
405
+
406
+ ## Skills
407
+
408
+ Skills inject behaviour instructions when a task matches certain keywords. Create a `.md` file in `skills/` with a YAML frontmatter:
409
+
410
+ ```yaml
411
+ ---
412
+ name: deploy
413
+ description: Handle deployment tasks for web apps and APIs
414
+ triggers: deploy, release, ship, production, go live
415
+ ---
416
+
417
+ # Deployment Checklist
418
+
419
+ Always follow this order when deploying:
420
+
421
+ 1. Run the full test suite — never deploy broken code
422
+ 2. Check for .env differences between dev and prod
423
+ 3. Build the production bundle
424
+ 4. Use zero-downtime deployment if possible (blue/green, rolling)
425
+ 5. Verify the deployment is healthy before reporting done
426
+ 6. Notify the user with the live URL
427
+ ```
428
+
429
+ **21 built-in skills** cover: coding, research, email, weather, Spotify, Obsidian, Apple Notes, Apple Reminders, Things, Trello, Tmux, PDF, image generation, video frames, health checks, GIF search, webcam capture, and more.
430
+
431
+ ---
432
+
433
+ ## Multi-Tenant Mode
434
+
435
+ Run Daemora as a shared agent serving multiple users. Each user gets isolated memory, filesystem, API keys, cost limits, and optionally their own model tier.
436
+
437
+ ```bash
438
+ # List all tenants (auto-created on first message per user)
439
+ daemora tenant list
440
+
441
+ # Set a per-user daily cost cap
442
+ daemora tenant set telegram:123 maxDailyCost 2.00
443
+
444
+ # Restrict which tools a tenant can use
445
+ daemora tenant set telegram:123 tools readFile,webSearch,sendEmail
446
+
447
+ # Restrict which MCP servers a tenant can access
448
+ daemora tenant set telegram:123 mcpServers github,notion
449
+
450
+ # Assign a model tier
451
+ daemora tenant plan telegram:123 pro
452
+
453
+ # Store a tenant's own OpenAI key (AES-256-GCM encrypted at rest)
454
+ daemora tenant apikey set telegram:123 OPENAI_API_KEY sk-their-key
455
+
456
+ # Suspend a user
457
+ daemora tenant suspend telegram:123 "Exceeded usage policy"
458
+ ```
459
+
460
+ Per-tenant isolation:
461
+
462
+ | Isolation | Mechanism |
463
+ |---|---|
464
+ | Memory | `data/tenants/{id}/MEMORY.md` — never shared across users |
465
+ | Filesystem | `allowedPaths` and `blockedPaths` scoped per user |
466
+ | API keys | AES-256-GCM encrypted; passed through call stack, never via `process.env` |
467
+ | Cost tracking | Per-tenant daily cost recorded in audit log |
468
+ | MCP servers | `mcpServers` field restricts which servers a tenant can call |
469
+ | Tools | `tools` allowlist limits which tools the agent can use for this user |
470
+
471
+ All isolation runs via `AsyncLocalStorage` — concurrent tasks from different users cannot read each other's context.
472
+
473
+ ---
474
+
475
+ ## Security
476
+
477
+ ```bash
478
+ # Run a full security audit
479
+ daemora doctor
480
+ ```
481
+
482
+ | Feature | Description |
483
+ |---|---|
484
+ | **Permission tiers** | `minimal` / `standard` / `full` — controls which tools the agent can call |
485
+ | **Filesystem sandbox** | Directory scoping via `ALLOWED_PATHS`, hardcoded blocks for `.ssh`, `.env`, `.aws` |
486
+ | **Secret vault** | AES-256-GCM encrypted secrets, passphrase required on start |
487
+ | **Channel allowlists** | Per-channel user ID whitelist — blocks unknown senders |
488
+ | **Secret scanning** | Redacts API keys and tokens from tool output before the model sees them |
489
+ | **Dynamic redaction** | Per-tenant API keys are also redacted from all tool outputs |
490
+ | **Supervisor agent** | Detects runaway loops, cost overruns, `rm -rf`, `curl | bash` patterns |
491
+ | **Audit log** | Every tool call logged to `data/audit/` — append-only JSONL, secrets stripped |
492
+ | **Input sanitisation** | User messages wrapped in `<untrusted-input>` tags; prompt injection patterns flagged |
493
+ | **A2A security** | Agent-to-agent protocol: bearer token, agent allowlist, rate limiting |
494
+ | **Tenant isolation** | AsyncLocalStorage — no cross-tenant data leakage in concurrent requests |
495
+ | **Per-tenant API key isolation** | Keys never touch `process.env` — passed through call stack only |
496
+ | **Git rollback** | Snapshot before write operations — undo with `git stash pop` |
497
+
498
+ ---
499
+
500
+ ## CLI Reference
501
+
502
+ ```
503
+ daemora start Start the agent server
504
+ daemora setup Interactive setup wizard
505
+ daemora doctor Security audit — 8-check scored report
506
+
507
+ daemora mcp list List all MCP servers
508
+ daemora mcp add Add an MCP server (interactive)
509
+ daemora mcp add <name> <cmd> Add an MCP server (non-interactive)
510
+ daemora mcp remove <name> Remove an MCP server
511
+ daemora mcp enable <name> Enable a disabled server
512
+ daemora mcp disable <name> Disable without removing
513
+ daemora mcp reload <name> Reconnect a server
514
+
515
+ daemora daemon install Install as a system daemon
516
+ daemora daemon start Start the daemon
517
+ daemora daemon stop Stop the daemon
518
+ daemora daemon status Check daemon status
519
+ daemora daemon logs View daemon logs
520
+
521
+ daemora vault set <key> Store an encrypted secret
522
+ daemora vault get <key> Retrieve a secret
523
+ daemora vault list List all secret keys
524
+ daemora vault unlock Unlock the vault
525
+
526
+ daemora sandbox show Show current sandbox rules
527
+ daemora sandbox add <path> Allow a directory (activates scoped mode)
528
+ daemora sandbox remove <path> Remove from allowed list
529
+ daemora sandbox block <path> Always block a path
530
+ daemora sandbox restrict Enable command restriction
531
+ daemora sandbox clear Back to unrestricted mode
532
+
533
+ daemora tenant list List all tenants
534
+ daemora tenant show <id> Show tenant config
535
+ daemora tenant set <id> <k> <v> Set a tenant config value
536
+ daemora tenant plan <id> <plan> Set tenant plan (free/pro/admin)
537
+ daemora tenant suspend <id> Suspend a tenant
538
+ daemora tenant unsuspend <id> Unsuspend a tenant
539
+ daemora tenant apikey set <id> <KEY> <value> Store per-tenant API key (encrypted)
540
+ daemora tenant apikey delete <id> <KEY> Remove a per-tenant API key
541
+ daemora tenant apikey list <id> List stored key names (values never shown)
542
+
543
+ daemora help Show full help
544
+ ```
545
+
546
+ ---
547
+
548
+ ## HTTP API
549
+
550
+ The agent exposes a REST API on `http://localhost:8081`.
551
+
552
+ ```bash
553
+ # System health
554
+ curl http://localhost:8081/health
555
+
556
+ # List recent tasks
557
+ curl http://localhost:8081/tasks
558
+
559
+ # Get task status
560
+ curl http://localhost:8081/tasks/{taskId}
561
+
562
+ # Today's API costs
563
+ curl http://localhost:8081/costs/today
564
+
565
+ # List tenants
566
+ curl http://localhost:8081/tenants
567
+
568
+ # List MCP servers
569
+ curl http://localhost:8081/mcp
570
+ ```
571
+
572
+ > POST /chat and POST /tasks (unauthenticated task submission) are disabled by default — use a channel (Telegram, Slack, etc.) instead.
573
+
574
+ ---
575
+
576
+ ## Self-Hosting
577
+
578
+ Daemora runs entirely on your own machine. Nothing is sent to any third party beyond the AI model APIs you configure.
579
+
580
+ **Requirements:**
581
+ - Node.js 20+
582
+ - 512 MB RAM minimum
583
+ - macOS, Linux, or Windows WSL
584
+
585
+ **Production setup:**
586
+
587
+ ```bash
588
+ npm install -g daemora
589
+ daemora setup
590
+ daemora daemon install
591
+ daemora daemon start
592
+ daemora doctor # verify security configuration
593
+ ```
594
+
595
+ Use nginx or Caddy as a reverse proxy for HTTPS if exposing the API port.
596
+
597
+ ---
598
+
599
+ ## Tech Stack
600
+
601
+ | Layer | Technology |
602
+ |---|---|
603
+ | Runtime | Node.js 20+ — ES modules, no build step |
604
+ | AI SDK | Vercel AI SDK (`ai`) — model-agnostic, 25+ providers |
605
+ | Models | OpenAI, Anthropic, Google Gemini, Ollama (local) |
606
+ | MCP | `@modelcontextprotocol/sdk` — stdio, HTTP, SSE |
607
+ | Channels | grammy, twilio, discord.js, @slack/bolt, nodemailer/imap, botbuilder, google-auth-library |
608
+ | Scheduling | node-cron |
609
+ | Vault | Node.js `crypto` built-in — AES-256-GCM + scrypt, no binary deps |
610
+ | Sandbox | Node.js tool-level path enforcement — no Docker required |
611
+ | Storage | File-based (Markdown + JSON) — no database |
612
+
613
+ ---
614
+
615
+ ## vs OpenClaw
616
+
617
+ Daemora was built in response to OpenClaw's security weaknesses. Key differences:
618
+
619
+ | Feature | Daemora | OpenClaw |
620
+ |---|---|---|
621
+ | Multi-tenant isolation | Full (AsyncLocalStorage) | None |
622
+ | Per-tenant memory | Isolated per user | Shared — User A sees User B's memories |
623
+ | Per-tenant API keys | AES-256-GCM, call stack only | None |
624
+ | Filesystem sandbox | Directory scoping + blocklist | None |
625
+ | Secret vault | AES-256-GCM encrypted | Plaintext `.env` only |
626
+ | Audit log | Full, per-tenant, secrets stripped | Partial |
627
+ | Security audit | `daemora doctor` (8 checks, scored) | None |
628
+ | A2A protocol | Auth + allowlist + rate limiting | None |
629
+ | Supervisor agent | Built-in | Manual |
630
+ | Task-type model routing | CODE_MODEL / RESEARCH_MODEL / etc. | None |
631
+ | Sub-agent model inheritance | Inherits parent model | Falls back to default |
632
+ | Setup | `npm install -g daemora && daemora start` | Complex multi-step with Docker/WSL |
633
+ | Codebase size | ~5k LOC, no build | 80k+ LOC, TypeScript build |
634
+
635
+ ---
636
+
637
+ ## Contributing
638
+
639
+ ```bash
640
+ git clone https://github.com/umarfarooq/daemora-agent.git
641
+ cd daemora-agent
642
+ npm install
643
+ cp .env.example .env
644
+ # Add your API keys to .env
645
+ daemora setup
646
+ daemora start
647
+ ```
648
+
649
+ Contributions are welcome. Please open an issue before submitting large PRs.
650
+
651
+ ---
652
+
653
+ ## License
654
+
655
+ **AGPL-3.0** — Daemora is open source. If you modify Daemora and distribute it, or run it as a network service, you must open-source your changes under AGPL-3.0.
656
+
657
+ See [LICENSE](LICENSE) for the full text.
658
+
659
+ ---
660
+
661
+ ## Links
662
+
663
+ - **Website:** https://daemora.com
664
+ - **npm:** https://npmjs.com/package/daemora
665
+ - **GitHub:** https://github.com/umarfarooq/daemora-agent
666
+ - **Issues:** https://github.com/umarfarooq/daemora-agent/issues