obsidian-agent-fleet 0.3.2 → 0.4.3
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 +117 -30
- package/bin/cli.js +2 -9
- package/package.json +27 -22
- package/plugin/main.js +11028 -4484
- package/plugin/manifest.json +1 -1
- package/plugin/styles.css +99 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Agent Fleet for Obsidian
|
|
2
2
|
|
|
3
|
-
**Turn Obsidian into an AI-powered command center. Create autonomous agents, schedule tasks, chat in real-time, and
|
|
3
|
+
**Turn Obsidian into an AI-powered command center. Create autonomous agents, schedule tasks, chat in real-time, connect via Slack, and hook into any MCP service — all from your vault.**
|
|
4
4
|
|
|
5
5
|

|
|
6
6
|
|
|
@@ -12,17 +12,21 @@ Agent Fleet is an Obsidian plugin that lets you build, configure, and run AI age
|
|
|
12
12
|
|
|
13
13
|
### Core Capabilities
|
|
14
14
|
|
|
15
|
-
🤖 **AI Agents** — Create specialized agents with system prompts, skills, permissions, and memory. Each agent is a folder of markdown files you fully own and control.
|
|
15
|
+
🤖 **AI Agents** — Create specialized agents with system prompts, skills, permissions, heartbeat schedules, and memory. Each agent is a folder of markdown files you fully own and control.
|
|
16
16
|
|
|
17
17
|
💬 **Interactive Chat** — Dock a chat panel anywhere in Obsidian. Switch between agents. Attach documents and images. Send follow-up messages while the agent works.
|
|
18
18
|
|
|
19
|
+
📡 **Slack Channels** — Chat with your agents from Slack. Multi-agent routing via `@agent-name` prefix. Native "is thinking..." indicator via Slack Assistants API. Session persistence across restarts.
|
|
20
|
+
|
|
21
|
+
💓 **Heartbeat** — Autonomous periodic agent runs. Define what an agent does when no one is asking — monitoring, reports, health checks — with results posted to Slack.
|
|
22
|
+
|
|
19
23
|
📋 **Task Board** — Kanban view with scheduling, priority, real-time progress tracking, and abort. Tasks run on cron schedules or on-demand.
|
|
20
24
|
|
|
21
25
|
🔌 **MCP Integration** — Discover, authenticate, and inspect MCP servers. One-click OAuth 2.1 authentication. Assign MCP tools to specific agents.
|
|
22
26
|
|
|
23
27
|
🧠 **Agent Memory** — Agents persist context across sessions using `[REMEMBER]` tags stored as markdown.
|
|
24
28
|
|
|
25
|
-
📊 **Dashboard** — Overview with run charts, success rates, activity timeline, fleet status, and streaming output from active agents.
|
|
29
|
+
📊 **Dashboard** — Overview with run charts, success rates, token/cost tracking, activity timeline, fleet status, and streaming output from active agents.
|
|
26
30
|
|
|
27
31
|
---
|
|
28
32
|
|
|
@@ -67,11 +71,12 @@ _fleet/
|
|
|
67
71
|
│ └── fleet-orchestrator/ ← default agent (manages the fleet)
|
|
68
72
|
├── skills/ ← 18 built-in skills
|
|
69
73
|
├── tasks/
|
|
74
|
+
├── channels/
|
|
70
75
|
├── runs/
|
|
71
76
|
└── memory/
|
|
72
77
|
```
|
|
73
78
|
|
|
74
|
-
The **Fleet Orchestrator** agent is ready — click Chat to ask it to create new agents, tasks, or
|
|
79
|
+
The **Fleet Orchestrator** agent is ready — click Chat to ask it to create new agents, tasks, skills, or channels.
|
|
75
80
|
|
|
76
81
|
### Update
|
|
77
82
|
|
|
@@ -94,7 +99,8 @@ agents/my-agent/
|
|
|
94
99
|
├── agent.md ← Identity: name, description, system prompt
|
|
95
100
|
├── config.md ← Runtime: model, timeout, permissions
|
|
96
101
|
├── SKILLS.md ← Agent-specific skills
|
|
97
|
-
|
|
102
|
+
├── CONTEXT.md ← Project context
|
|
103
|
+
└── HEARTBEAT.md ← Autonomous periodic run instruction (optional)
|
|
98
104
|
```
|
|
99
105
|
|
|
100
106
|
**What you can configure:**
|
|
@@ -113,6 +119,7 @@ agents/my-agent/
|
|
|
113
119
|
| **Skills** | Shared skills from the skill library |
|
|
114
120
|
| **MCP Servers** | Which MCP servers the agent can access |
|
|
115
121
|
| **Memory** | Persistent context across sessions via `[REMEMBER]` tags |
|
|
122
|
+
| **Heartbeat** | Autonomous periodic run with schedule and instruction |
|
|
116
123
|
|
|
117
124
|
**Permission Modes:**
|
|
118
125
|
|
|
@@ -125,6 +132,76 @@ agents/my-agent/
|
|
|
125
132
|
|
|
126
133
|
---
|
|
127
134
|
|
|
135
|
+
### Heartbeat
|
|
136
|
+
|
|
137
|
+
A heartbeat gives an agent autonomous behavior — what it does when no one is asking. Think periodic monitoring, daily reports, health checks, or trend analysis.
|
|
138
|
+
|
|
139
|
+
**Setup:** Create a `HEARTBEAT.md` file in the agent's folder, or configure it in the dashboard's agent edit page:
|
|
140
|
+
|
|
141
|
+
```yaml
|
|
142
|
+
---
|
|
143
|
+
enabled: true
|
|
144
|
+
schedule: "0 */6 * * *" # every 6 hours
|
|
145
|
+
notify: true # Obsidian notice on completion
|
|
146
|
+
channel: my-slack # post results to Slack (optional)
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
Check all monitored endpoints for availability and response time.
|
|
150
|
+
Compare with previous checks using your memory. Report anomalies.
|
|
151
|
+
If everything is healthy, respond with a one-line "all clear".
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
**Key behaviors:**
|
|
155
|
+
- The **"Run Now" button** on any agent with a heartbeat uses the heartbeat instruction (no more generic fallback)
|
|
156
|
+
- **Agent memory integration** — heartbeats can use `[REMEMBER]` tags to track trends across runs
|
|
157
|
+
- **Slack delivery** — results automatically posted to a configured Slack channel
|
|
158
|
+
- **Dashboard** — heartbeat status shown on the agent's Overview tab with enable/disable toggle, schedule, and next run time
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
### Slack Channels
|
|
163
|
+
|
|
164
|
+
Chat with your agents from Slack — every message flows through the same Claude CLI session pipeline, with full tool use, session persistence, and agent memory.
|
|
165
|
+
|
|
166
|
+
**Setup:**
|
|
167
|
+
1. Create a Slack app at [api.slack.com](https://api.slack.com/apps) with Socket Mode + Agents & AI Apps enabled
|
|
168
|
+
2. Add credentials in Settings → Agent Fleet → Channel Credentials
|
|
169
|
+
3. Create `_fleet/channels/my-slack.md` with agent binding + user allowlist
|
|
170
|
+
4. DM the bot from Slack
|
|
171
|
+
|
|
172
|
+
```yaml
|
|
173
|
+
---
|
|
174
|
+
name: my-slack
|
|
175
|
+
type: slack
|
|
176
|
+
default_agent: fleet-orchestrator
|
|
177
|
+
allowed_agents:
|
|
178
|
+
- fleet-orchestrator
|
|
179
|
+
- site-monitor
|
|
180
|
+
- code-reviewer
|
|
181
|
+
enabled: true
|
|
182
|
+
credential_ref: my-slack-creds
|
|
183
|
+
allowed_users:
|
|
184
|
+
- U0AQW6P37N1
|
|
185
|
+
per_user_sessions: true
|
|
186
|
+
channel_context: |
|
|
187
|
+
You are being contacted via Slack. Keep replies concise.
|
|
188
|
+
---
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Features:**
|
|
192
|
+
- **Socket Mode** — outbound WebSocket, works behind NAT/firewalls, no public URL needed
|
|
193
|
+
- **Slack Assistants API** — native "is thinking..." indicator, threaded conversations, thread titles
|
|
194
|
+
- **Multi-agent routing** — type `@agent-name: message` to switch agents mid-thread. Each agent gets its own isolated session. `/agents` slash command lists available agents.
|
|
195
|
+
- **Session persistence** — conversations survive Obsidian restarts via `claude --resume`
|
|
196
|
+
- **Idle hibernation** — subprocess eviction after configurable idle time, transparent resume on next message
|
|
197
|
+
- **Allowlist** — only approved Slack users (by user ID) can reach the bot
|
|
198
|
+
- **Rate limiting** — per-conversation sliding window to prevent budget burn
|
|
199
|
+
- **Markdown → mrkdwn** — automatic formatting conversion with fence-aware chunking for long replies
|
|
200
|
+
|
|
201
|
+
**Important:** Obsidian must be running for channels to work. When Obsidian is closed, the bot goes offline.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
128
205
|
### Interactive Chat
|
|
129
206
|
|
|
130
207
|
The chat panel is a first-class Obsidian view — dock it in the sidebar, center, or any split.
|
|
@@ -140,10 +217,6 @@ The chat panel is a first-class Obsidian view — dock it in the sidebar, center
|
|
|
140
217
|
- **Code Block Copy** — hover any code block for a copy button
|
|
141
218
|
- **Tool Activity** — see which tools the agent is using in real-time
|
|
142
219
|
|
|
143
|
-
**Keyboard shortcuts:**
|
|
144
|
-
- `Ctrl+Enter` / `Cmd+Enter` — send message
|
|
145
|
-
- Ribbon icon (💬) or command palette to open chat
|
|
146
|
-
|
|
147
220
|
---
|
|
148
221
|
|
|
149
222
|
### Task Board
|
|
@@ -167,14 +240,6 @@ A kanban view for managing agent tasks with five columns:
|
|
|
167
240
|
- **Run Now** — execute any task immediately regardless of schedule
|
|
168
241
|
- **Drag & Drop** — move tasks between backlog and scheduled columns
|
|
169
242
|
|
|
170
|
-
**Creating tasks:**
|
|
171
|
-
|
|
172
|
-
Full-page form with:
|
|
173
|
-
1. Title + Agent + Priority + Tags
|
|
174
|
-
2. Instructions (what the agent should do)
|
|
175
|
-
3. Optional schedule with frequency picker
|
|
176
|
-
4. "Catch up if missed" toggle for scheduled tasks
|
|
177
|
-
|
|
178
243
|
---
|
|
179
244
|
|
|
180
245
|
### MCP Servers
|
|
@@ -201,9 +266,6 @@ One-click browser-based auth for MCP servers:
|
|
|
201
266
|
- Detail slideover with full tool list, descriptions, input schemas, parameters
|
|
202
267
|
- Assign MCP servers to specific agents in the agent editor
|
|
203
268
|
|
|
204
|
-
**Progress Indicator:**
|
|
205
|
-
Animated loading during discovery with phase-specific feedback (scanning → details → tools → done).
|
|
206
|
-
|
|
207
269
|
---
|
|
208
270
|
|
|
209
271
|
### Skills
|
|
@@ -245,20 +307,21 @@ skills/my-skill/
|
|
|
245
307
|
|
|
246
308
|
The main overview with:
|
|
247
309
|
|
|
248
|
-
- **Stat Cards** — active agents, runs today, tokens used, scheduled tasks
|
|
310
|
+
- **Stat Cards** — active agents, runs today, tokens used (with cost), scheduled tasks
|
|
249
311
|
- **Run Activity Chart** — 14-day bar chart with green (success), yellow (cancelled), red (failure)
|
|
250
312
|
- **Success Rate Donut** — overall success percentage
|
|
251
313
|
- **Active Agent Cards** — fixed-height streaming output from running agents with agent→task title
|
|
252
314
|
- **Activity Timeline** — recent runs with status, duration, tokens
|
|
253
315
|
- **Fleet Status** — agent list with quick-run capability
|
|
254
316
|
|
|
255
|
-
**
|
|
256
|
-
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
-
|
|
260
|
-
-
|
|
261
|
-
-
|
|
317
|
+
**Sidebar navigation:**
|
|
318
|
+
- Dashboard / Agents / Tasks Board / Run History / Approvals / Skills / MCP Servers / Channels
|
|
319
|
+
|
|
320
|
+
**Agent detail page tabs:**
|
|
321
|
+
- Overview (stats, heartbeat status, skills, permissions, recent runs)
|
|
322
|
+
- Config (all settings, system prompt, heartbeat instruction)
|
|
323
|
+
- Runs (full history for this agent)
|
|
324
|
+
- Memory (learned context)
|
|
262
325
|
|
|
263
326
|
---
|
|
264
327
|
|
|
@@ -269,7 +332,7 @@ Agents persist context across sessions:
|
|
|
269
332
|
1. Agent includes `[REMEMBER]important context[/REMEMBER]` in its output
|
|
270
333
|
2. Extracted and appended to `_fleet/memory/<agent-name>.md`
|
|
271
334
|
3. Injected into the agent's prompt on every future run
|
|
272
|
-
4.
|
|
335
|
+
4. Memory is agent-scoped — shared across all conversations including Slack channels
|
|
273
336
|
|
|
274
337
|
---
|
|
275
338
|
|
|
@@ -287,7 +350,9 @@ started: 2026-04-03T09:00:00
|
|
|
287
350
|
completed: 2026-04-03T09:02:30
|
|
288
351
|
duration_seconds: 150
|
|
289
352
|
tokens_used: 4500
|
|
353
|
+
cost_usd: 0.07
|
|
290
354
|
model: claude-opus-4-6
|
|
355
|
+
tags: [heartbeat]
|
|
291
356
|
---
|
|
292
357
|
|
|
293
358
|
## Prompt
|
|
@@ -319,15 +384,24 @@ Click any run in the dashboard to see full details in a slideover panel.
|
|
|
319
384
|
| Catch Up Missed Tasks | `true` | Run overdue tasks on startup |
|
|
320
385
|
| Notification Level | `all` | `all`, `failures-only`, `none` |
|
|
321
386
|
|
|
387
|
+
### Channel Settings
|
|
388
|
+
|
|
389
|
+
| Setting | Default | Description |
|
|
390
|
+
|---------|---------|-------------|
|
|
391
|
+
| Max Concurrent Sessions | `5` | Live claude subprocesses across all channels |
|
|
392
|
+
| Idle Timeout | `15` min | Hibernate sessions after inactivity |
|
|
393
|
+
| Rate Limit | `20` msgs / `5` min | Per-conversation sliding window |
|
|
394
|
+
|
|
322
395
|
### File Structure
|
|
323
396
|
|
|
324
397
|
All data lives in `_fleet/` as plain markdown:
|
|
325
398
|
|
|
326
399
|
```
|
|
327
400
|
_fleet/
|
|
328
|
-
├── agents/ Agent folders (agent.md, config.md, etc.)
|
|
401
|
+
├── agents/ Agent folders (agent.md, config.md, HEARTBEAT.md, etc.)
|
|
329
402
|
├── skills/ Shared skill folders (skill.md, tools.md, etc.)
|
|
330
403
|
├── tasks/ Task files with frontmatter
|
|
404
|
+
├── channels/ Channel bindings (Slack, etc.)
|
|
331
405
|
├── runs/ Execution logs by date
|
|
332
406
|
│ └── YYYY-MM-DD/
|
|
333
407
|
├── memory/ Agent memory files
|
|
@@ -358,6 +432,15 @@ Yes, up to `maxConcurrentRuns` (default 2). Additional tasks queue until a slot
|
|
|
358
432
|
**Q: Does the chat remember previous conversations?**
|
|
359
433
|
Yes. Each agent has persistent chat sessions that survive Obsidian restarts via Claude CLI `--resume`.
|
|
360
434
|
|
|
435
|
+
**Q: Does the Slack bot work when Obsidian is closed?**
|
|
436
|
+
No. The bot runs inside Obsidian via Socket Mode — when Obsidian is closed, the bot goes offline. Slack buffers messages briefly during short disconnects.
|
|
437
|
+
|
|
438
|
+
**Q: Can I use multiple agents in Slack?**
|
|
439
|
+
Yes. Type `@agent-name: message` to switch agents within a Slack thread. Each agent maintains its own session. Use `/agents` to see available agents.
|
|
440
|
+
|
|
441
|
+
**Q: What is a heartbeat?**
|
|
442
|
+
An autonomous periodic run — what an agent does on a schedule without user input. Configured via `HEARTBEAT.md` in the agent's folder. Results can be posted to a Slack channel automatically.
|
|
443
|
+
|
|
361
444
|
---
|
|
362
445
|
|
|
363
446
|
## Links
|
|
@@ -365,3 +448,7 @@ Yes. Each agent has persistent chat sessions that survive Obsidian restarts via
|
|
|
365
448
|
- [Releases](https://github.com/denberek/obsidian-agent-fleet/releases)
|
|
366
449
|
- [npm package](https://www.npmjs.com/package/obsidian-agent-fleet)
|
|
367
450
|
- [Report Issues](https://github.com/denberek/obsidian-agent-fleet/issues)
|
|
451
|
+
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
© 2026 Denis Berekchiyan. All rights reserved.
|
package/bin/cli.js
CHANGED
|
@@ -37,7 +37,6 @@ function getVaults() {
|
|
|
37
37
|
|
|
38
38
|
function resolveClaudePath() {
|
|
39
39
|
const { execSync } = require("child_process");
|
|
40
|
-
// Try to resolve claude full path via login shell (picks up nvm/fnm/etc)
|
|
41
40
|
const shells = ["/bin/zsh", "/bin/bash", "/bin/sh"];
|
|
42
41
|
for (const shell of shells) {
|
|
43
42
|
if (!fs.existsSync(shell)) continue;
|
|
@@ -57,14 +56,12 @@ function writePluginSettings(vaultPath, claudePath) {
|
|
|
57
56
|
const dataPath = path.join(vaultPath, ".obsidian", "plugins", PLUGIN_ID, "data.json");
|
|
58
57
|
|
|
59
58
|
let settings = {};
|
|
60
|
-
// Preserve existing settings if they exist
|
|
61
59
|
if (fs.existsSync(dataPath)) {
|
|
62
60
|
try {
|
|
63
61
|
settings = JSON.parse(fs.readFileSync(dataPath, "utf8"));
|
|
64
62
|
} catch { /* start fresh */ }
|
|
65
63
|
}
|
|
66
64
|
|
|
67
|
-
// Only set claudeCliPath if we found it and user hasn't manually set one
|
|
68
65
|
if (claudePath && (!settings.claudeCliPath || settings.claudeCliPath === "claude")) {
|
|
69
66
|
settings.claudeCliPath = claudePath;
|
|
70
67
|
}
|
|
@@ -75,10 +72,8 @@ function writePluginSettings(vaultPath, claudePath) {
|
|
|
75
72
|
function installToVault(vaultPath) {
|
|
76
73
|
const pluginDir = path.join(vaultPath, ".obsidian", "plugins", PLUGIN_ID);
|
|
77
74
|
|
|
78
|
-
// Ensure directories exist
|
|
79
75
|
fs.mkdirSync(pluginDir, { recursive: true });
|
|
80
76
|
|
|
81
|
-
// Copy plugin files
|
|
82
77
|
const files = ["main.js", "manifest.json", "styles.css"];
|
|
83
78
|
for (const file of files) {
|
|
84
79
|
const src = path.join(PLUGIN_DIR, file);
|
|
@@ -100,17 +95,16 @@ function main() {
|
|
|
100
95
|
const vaults = getVaults();
|
|
101
96
|
|
|
102
97
|
if (vaults.length === 0) {
|
|
103
|
-
if (isAuto) return;
|
|
98
|
+
if (isAuto) return;
|
|
104
99
|
console.error("❌ No Obsidian vaults found.");
|
|
105
100
|
console.error(" Make sure Obsidian is installed and has at least one vault.");
|
|
106
101
|
console.error("");
|
|
107
102
|
console.error(" Manual install:");
|
|
108
|
-
console.error(" Copy the files from node_modules/agent-fleet/plugin/");
|
|
103
|
+
console.error(" Copy the files from node_modules/obsidian-agent-fleet/plugin/");
|
|
109
104
|
console.error(" to <your-vault>/.obsidian/plugins/agent-fleet/");
|
|
110
105
|
process.exit(1);
|
|
111
106
|
}
|
|
112
107
|
|
|
113
|
-
// Resolve Claude CLI full path
|
|
114
108
|
const claudePath = resolveClaudePath();
|
|
115
109
|
if (!isAuto) {
|
|
116
110
|
if (claudePath) {
|
|
@@ -120,7 +114,6 @@ function main() {
|
|
|
120
114
|
}
|
|
121
115
|
}
|
|
122
116
|
|
|
123
|
-
// Install to all vaults
|
|
124
117
|
let installed = 0;
|
|
125
118
|
for (const vault of vaults) {
|
|
126
119
|
try {
|
package/package.json
CHANGED
|
@@ -1,31 +1,36 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "obsidian-agent-fleet",
|
|
3
|
-
"version": "0.3
|
|
4
|
-
"description": "
|
|
5
|
-
"
|
|
6
|
-
"license": "UNLICENSED",
|
|
3
|
+
"version": "0.4.3",
|
|
4
|
+
"description": "Obsidian plugin for file-backed AI agents, task scheduling, channels (Slack), heartbeat, and interactive chat.",
|
|
5
|
+
"main": "plugin/main.js",
|
|
7
6
|
"bin": {
|
|
8
|
-
"
|
|
7
|
+
"agent-fleet": "bin/cli.js"
|
|
9
8
|
},
|
|
10
9
|
"files": [
|
|
11
|
-
"bin/",
|
|
12
|
-
"plugin/",
|
|
10
|
+
"bin/cli.js",
|
|
11
|
+
"plugin/main.js",
|
|
12
|
+
"plugin/manifest.json",
|
|
13
|
+
"plugin/styles.css",
|
|
13
14
|
"README.md"
|
|
14
15
|
],
|
|
15
|
-
"keywords": [
|
|
16
|
-
"obsidian",
|
|
17
|
-
"ai",
|
|
18
|
-
"agent",
|
|
19
|
-
"claude",
|
|
20
|
-
"task",
|
|
21
|
-
"automation"
|
|
22
|
-
],
|
|
23
|
-
"repository": {
|
|
24
|
-
"type": "git",
|
|
25
|
-
"url": "https://github.com/denberek/obsidian-agent-fleet"
|
|
26
|
-
},
|
|
27
|
-
"homepage": "https://github.com/denberek/obsidian-agent-fleet",
|
|
28
16
|
"scripts": {
|
|
29
|
-
"
|
|
17
|
+
"build": "node esbuild.config.mjs production",
|
|
18
|
+
"dev": "node esbuild.config.mjs",
|
|
19
|
+
"test": "vitest run",
|
|
20
|
+
"typecheck": "tsc --noEmit"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "^24.5.2",
|
|
24
|
+
"@types/ws": "^8.18.1",
|
|
25
|
+
"builtin-modules": "^4.0.0",
|
|
26
|
+
"esbuild": "^0.25.9",
|
|
27
|
+
"obsidian": "^1.8.10",
|
|
28
|
+
"tslib": "^2.8.1",
|
|
29
|
+
"typescript": "^5.9.2",
|
|
30
|
+
"vitest": "^3.2.4"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"croner": "^8.1.2",
|
|
34
|
+
"ws": "^8.20.0"
|
|
30
35
|
}
|
|
31
|
-
}
|
|
36
|
+
}
|