@songsid/agend 0.0.1
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 +210 -0
- package/README.zh-TW.md +134 -0
- package/dist/access-path.d.ts +10 -0
- package/dist/access-path.js +32 -0
- package/dist/access-path.js.map +1 -0
- package/dist/adapter-world.d.ts +25 -0
- package/dist/adapter-world.js +41 -0
- package/dist/adapter-world.js.map +1 -0
- package/dist/agent-cli-instructions.md +50 -0
- package/dist/agent-cli.d.ts +2 -0
- package/dist/agent-cli.js +200 -0
- package/dist/agent-cli.js.map +1 -0
- package/dist/agent-endpoint.d.ts +25 -0
- package/dist/agent-endpoint.js +162 -0
- package/dist/agent-endpoint.js.map +1 -0
- package/dist/backend/antigravity.d.ts +17 -0
- package/dist/backend/antigravity.js +98 -0
- package/dist/backend/antigravity.js.map +1 -0
- package/dist/backend/claude-code.d.ts +23 -0
- package/dist/backend/claude-code.js +171 -0
- package/dist/backend/claude-code.js.map +1 -0
- package/dist/backend/codex.d.ts +18 -0
- package/dist/backend/codex.js +160 -0
- package/dist/backend/codex.js.map +1 -0
- package/dist/backend/factory.d.ts +2 -0
- package/dist/backend/factory.js +28 -0
- package/dist/backend/factory.js.map +1 -0
- package/dist/backend/gemini-cli.d.ts +17 -0
- package/dist/backend/gemini-cli.js +163 -0
- package/dist/backend/gemini-cli.js.map +1 -0
- package/dist/backend/index.d.ts +7 -0
- package/dist/backend/index.js +7 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/kiro.d.ts +17 -0
- package/dist/backend/kiro.js +147 -0
- package/dist/backend/kiro.js.map +1 -0
- package/dist/backend/marker-utils.d.ts +13 -0
- package/dist/backend/marker-utils.js +64 -0
- package/dist/backend/marker-utils.js.map +1 -0
- package/dist/backend/mock.d.ts +25 -0
- package/dist/backend/mock.js +85 -0
- package/dist/backend/mock.js.map +1 -0
- package/dist/backend/opencode.d.ts +16 -0
- package/dist/backend/opencode.js +136 -0
- package/dist/backend/opencode.js.map +1 -0
- package/dist/backend/types.d.ts +86 -0
- package/dist/backend/types.js +33 -0
- package/dist/backend/types.js.map +1 -0
- package/dist/channel/access-manager.d.ts +18 -0
- package/dist/channel/access-manager.js +153 -0
- package/dist/channel/access-manager.js.map +1 -0
- package/dist/channel/adapters/telegram.d.ts +63 -0
- package/dist/channel/adapters/telegram.js +646 -0
- package/dist/channel/adapters/telegram.js.map +1 -0
- package/dist/channel/attachment-handler.d.ts +15 -0
- package/dist/channel/attachment-handler.js +88 -0
- package/dist/channel/attachment-handler.js.map +1 -0
- package/dist/channel/factory.d.ts +12 -0
- package/dist/channel/factory.js +67 -0
- package/dist/channel/factory.js.map +1 -0
- package/dist/channel/ipc-bridge.d.ts +26 -0
- package/dist/channel/ipc-bridge.js +220 -0
- package/dist/channel/ipc-bridge.js.map +1 -0
- package/dist/channel/mcp-server.d.ts +10 -0
- package/dist/channel/mcp-server.js +288 -0
- package/dist/channel/mcp-server.js.map +1 -0
- package/dist/channel/mcp-tools.d.ts +17 -0
- package/dist/channel/mcp-tools.js +110 -0
- package/dist/channel/mcp-tools.js.map +1 -0
- package/dist/channel/message-bus.d.ts +17 -0
- package/dist/channel/message-bus.js +86 -0
- package/dist/channel/message-bus.js.map +1 -0
- package/dist/channel/message-queue.d.ts +39 -0
- package/dist/channel/message-queue.js +253 -0
- package/dist/channel/message-queue.js.map +1 -0
- package/dist/channel/tool-router.d.ts +6 -0
- package/dist/channel/tool-router.js +75 -0
- package/dist/channel/tool-router.js.map +1 -0
- package/dist/channel/tool-tracker.d.ts +13 -0
- package/dist/channel/tool-tracker.js +58 -0
- package/dist/channel/tool-tracker.js.map +1 -0
- package/dist/channel/types.d.ts +118 -0
- package/dist/channel/types.js +2 -0
- package/dist/channel/types.js.map +1 -0
- package/dist/chat-export.d.ts +4 -0
- package/dist/chat-export.js +91 -0
- package/dist/chat-export.js.map +1 -0
- package/dist/classic-channel-manager.d.ts +59 -0
- package/dist/classic-channel-manager.js +193 -0
- package/dist/classic-channel-manager.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +1833 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +9 -0
- package/dist/config.js +118 -0
- package/dist/config.js.map +1 -0
- package/dist/context-guardian.d.ts +26 -0
- package/dist/context-guardian.js +73 -0
- package/dist/context-guardian.js.map +1 -0
- package/dist/cost-guard.d.ts +36 -0
- package/dist/cost-guard.js +147 -0
- package/dist/cost-guard.js.map +1 -0
- package/dist/daemon-entry.d.ts +1 -0
- package/dist/daemon-entry.js +29 -0
- package/dist/daemon-entry.js.map +1 -0
- package/dist/daemon.d.ts +152 -0
- package/dist/daemon.js +1714 -0
- package/dist/daemon.js.map +1 -0
- package/dist/daily-summary.d.ts +13 -0
- package/dist/daily-summary.js +55 -0
- package/dist/daily-summary.js.map +1 -0
- package/dist/event-log.d.ts +36 -0
- package/dist/event-log.js +100 -0
- package/dist/event-log.js.map +1 -0
- package/dist/export-import.d.ts +2 -0
- package/dist/export-import.js +162 -0
- package/dist/export-import.js.map +1 -0
- package/dist/fleet-context.d.ts +61 -0
- package/dist/fleet-context.js +4 -0
- package/dist/fleet-context.js.map +1 -0
- package/dist/fleet-dashboard-html.d.ts +6 -0
- package/dist/fleet-dashboard-html.js +443 -0
- package/dist/fleet-dashboard-html.js.map +1 -0
- package/dist/fleet-health-server.d.ts +35 -0
- package/dist/fleet-health-server.js +290 -0
- package/dist/fleet-health-server.js.map +1 -0
- package/dist/fleet-instructions.d.ts +5 -0
- package/dist/fleet-instructions.js +161 -0
- package/dist/fleet-instructions.js.map +1 -0
- package/dist/fleet-manager.d.ts +212 -0
- package/dist/fleet-manager.js +3655 -0
- package/dist/fleet-manager.js.map +1 -0
- package/dist/fleet-rpc-handlers.d.ts +42 -0
- package/dist/fleet-rpc-handlers.js +356 -0
- package/dist/fleet-rpc-handlers.js.map +1 -0
- package/dist/fleet-system-prompt.d.ts +11 -0
- package/dist/fleet-system-prompt.js +61 -0
- package/dist/fleet-system-prompt.js.map +1 -0
- package/dist/general-knowledge/skills.md +177 -0
- package/dist/hang-detector.d.ts +16 -0
- package/dist/hang-detector.js +53 -0
- package/dist/hang-detector.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/instance-lifecycle.d.ts +90 -0
- package/dist/instance-lifecycle.js +592 -0
- package/dist/instance-lifecycle.js.map +1 -0
- package/dist/instructions.d.ts +15 -0
- package/dist/instructions.js +90 -0
- package/dist/instructions.js.map +1 -0
- package/dist/logger.d.ts +7 -0
- package/dist/logger.js +84 -0
- package/dist/logger.js.map +1 -0
- package/dist/outbound-handlers.d.ts +51 -0
- package/dist/outbound-handlers.js +739 -0
- package/dist/outbound-handlers.js.map +1 -0
- package/dist/outbound-schemas.d.ts +238 -0
- package/dist/outbound-schemas.js +248 -0
- package/dist/outbound-schemas.js.map +1 -0
- package/dist/paths.d.ts +10 -0
- package/dist/paths.js +42 -0
- package/dist/paths.js.map +1 -0
- package/dist/plugin/agend/.claude-plugin/plugin.json +5 -0
- package/dist/quickstart.d.ts +1 -0
- package/dist/quickstart.js +595 -0
- package/dist/quickstart.js.map +1 -0
- package/dist/routing-engine.d.ts +22 -0
- package/dist/routing-engine.js +44 -0
- package/dist/routing-engine.js.map +1 -0
- package/dist/safe-async.d.ts +6 -0
- package/dist/safe-async.js +20 -0
- package/dist/safe-async.js.map +1 -0
- package/dist/scheduler/db.d.ts +37 -0
- package/dist/scheduler/db.js +360 -0
- package/dist/scheduler/db.js.map +1 -0
- package/dist/scheduler/db.test.d.ts +1 -0
- package/dist/scheduler/db.test.js +92 -0
- package/dist/scheduler/db.test.js.map +1 -0
- package/dist/scheduler/index.d.ts +4 -0
- package/dist/scheduler/index.js +4 -0
- package/dist/scheduler/index.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +44 -0
- package/dist/scheduler/scheduler.js +197 -0
- package/dist/scheduler/scheduler.js.map +1 -0
- package/dist/scheduler/scheduler.test.d.ts +1 -0
- package/dist/scheduler/scheduler.test.js +119 -0
- package/dist/scheduler/scheduler.test.js.map +1 -0
- package/dist/scheduler/types.d.ts +107 -0
- package/dist/scheduler/types.js +7 -0
- package/dist/scheduler/types.js.map +1 -0
- package/dist/service-installer.d.ts +17 -0
- package/dist/service-installer.js +182 -0
- package/dist/service-installer.js.map +1 -0
- package/dist/setup-wizard.d.ts +48 -0
- package/dist/setup-wizard.js +701 -0
- package/dist/setup-wizard.js.map +1 -0
- package/dist/statusline-watcher.d.ts +34 -0
- package/dist/statusline-watcher.js +73 -0
- package/dist/statusline-watcher.js.map +1 -0
- package/dist/stt.d.ts +10 -0
- package/dist/stt.js +33 -0
- package/dist/stt.js.map +1 -0
- package/dist/tmux-control.d.ts +52 -0
- package/dist/tmux-control.js +207 -0
- package/dist/tmux-control.js.map +1 -0
- package/dist/tmux-manager.d.ts +44 -0
- package/dist/tmux-manager.js +218 -0
- package/dist/tmux-manager.js.map +1 -0
- package/dist/topic-archiver.d.ts +40 -0
- package/dist/topic-archiver.js +103 -0
- package/dist/topic-archiver.js.map +1 -0
- package/dist/topic-commands.d.ts +28 -0
- package/dist/topic-commands.js +359 -0
- package/dist/topic-commands.js.map +1 -0
- package/dist/transcript-monitor.d.ts +23 -0
- package/dist/transcript-monitor.js +164 -0
- package/dist/transcript-monitor.js.map +1 -0
- package/dist/types.d.ts +211 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/dashboard.html +719 -0
- package/dist/web-api.d.ts +101 -0
- package/dist/web-api.js +648 -0
- package/dist/web-api.js.map +1 -0
- package/dist/webhook-emitter.d.ts +15 -0
- package/dist/webhook-emitter.js +41 -0
- package/dist/webhook-emitter.js.map +1 -0
- package/dist/workflow-templates/default.md +35 -0
- package/package.json +76 -0
- package/templates/launchd.plist.ejs +31 -0
- package/templates/systemd.service.ejs +16 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MCP Tool Server for agend.
|
|
4
|
+
*
|
|
5
|
+
* Runs as a SEPARATE process (CLI's child via --mcp-config).
|
|
6
|
+
* Communicates with the daemon through a Unix socket IPC connection.
|
|
7
|
+
* Provides standard MCP tools (reply, send_to_instance, etc.) — no
|
|
8
|
+
* CLI-specific channel protocol. Works with any MCP-compatible CLI.
|
|
9
|
+
*/
|
|
10
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
11
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
12
|
+
import { ListToolsRequestSchema, CallToolRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
13
|
+
import { basename, dirname, join } from "node:path";
|
|
14
|
+
import { writeFileSync, readFileSync, unlinkSync } from "node:fs";
|
|
15
|
+
import { IpcClient } from "./ipc-bridge.js";
|
|
16
|
+
import { TOOLS } from "./mcp-tools.js";
|
|
17
|
+
import { buildFleetInstructions } from "../instructions.js";
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Configuration
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
const SOCKET_PATH = process.env.AGEND_SOCKET_PATH ?? "";
|
|
22
|
+
const IPC_TIMEOUT_MS = 30_000;
|
|
23
|
+
const SLOW_IPC_TIMEOUT_MS = 60_000;
|
|
24
|
+
const SLOW_TOOLS = new Set(["start_instance", "create_instance", "delete_instance", "replace_instance"]);
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Safety nets
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Parent death detection: primary mechanism is process.ppid polling (see main).
|
|
29
|
+
// On macOS, libuv/kqueue does not reliably emit stdin 'end' when the parent
|
|
30
|
+
// dies — the broken pipe causes a CPU spin instead. ppid polling is the only
|
|
31
|
+
// cross-platform reliable method. stdin listeners are kept as a fast path
|
|
32
|
+
// for Linux (where epoll may correctly emit EOF).
|
|
33
|
+
const PARENT_PID = process.ppid;
|
|
34
|
+
function isOrphaned() {
|
|
35
|
+
return process.ppid === 1 || process.ppid !== PARENT_PID;
|
|
36
|
+
}
|
|
37
|
+
process.on("unhandledRejection", (err) => {
|
|
38
|
+
process.stderr.write(`agend: unhandled rejection: ${err}\n`);
|
|
39
|
+
});
|
|
40
|
+
process.on("uncaughtException", (err) => {
|
|
41
|
+
process.stderr.write(`agend: uncaught exception: ${err}\n`);
|
|
42
|
+
});
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// IPC client with request-response
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
let ipc = null;
|
|
47
|
+
let ipcConnected = false;
|
|
48
|
+
let requestCounter = 0;
|
|
49
|
+
let reconnecting = false;
|
|
50
|
+
let reconnectAttempts = 0;
|
|
51
|
+
const MAX_RECONNECT_ATTEMPTS = 20; // ~60s of retries
|
|
52
|
+
const pendingRequests = new Map();
|
|
53
|
+
function setupIpcListeners(client) {
|
|
54
|
+
client.on("message", (msg) => {
|
|
55
|
+
// Graceful shutdown: daemon tells us it's shutting down — skip reconnect
|
|
56
|
+
if (msg.type === "shutdown") {
|
|
57
|
+
process.stderr.write("agend: daemon shutting down — exiting gracefully\n");
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
|
60
|
+
if (typeof msg.requestId === "number" && pendingRequests.has(msg.requestId)) {
|
|
61
|
+
const pending = pendingRequests.get(msg.requestId);
|
|
62
|
+
pendingRequests.delete(msg.requestId);
|
|
63
|
+
clearTimeout(pending.timer);
|
|
64
|
+
if (msg.error) {
|
|
65
|
+
pending.reject(new Error(String(msg.error)));
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
pending.resolve(msg.result);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
client.on("disconnect", () => {
|
|
73
|
+
ipcConnected = false;
|
|
74
|
+
process.stderr.write("agend: IPC disconnected — will reconnect\n");
|
|
75
|
+
// Reject all pending requests
|
|
76
|
+
for (const [id, pending] of pendingRequests) {
|
|
77
|
+
clearTimeout(pending.timer);
|
|
78
|
+
pending.reject(new Error("IPC disconnected"));
|
|
79
|
+
pendingRequests.delete(id);
|
|
80
|
+
}
|
|
81
|
+
scheduleReconnect();
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async function connectIpc() {
|
|
85
|
+
try {
|
|
86
|
+
const client = new IpcClient(SOCKET_PATH);
|
|
87
|
+
await client.connect();
|
|
88
|
+
ipc = client;
|
|
89
|
+
ipcConnected = true;
|
|
90
|
+
reconnecting = false;
|
|
91
|
+
reconnectAttempts = 0;
|
|
92
|
+
setupIpcListeners(client);
|
|
93
|
+
// AGEND_INSTANCE_NAME: set by daemon via tmux env (internal sessions)
|
|
94
|
+
// AGEND_SESSION_NAME: set in .mcp.json env (external sessions, optional custom name)
|
|
95
|
+
// Fallback: unique name from working directory + PID (avoids collision when
|
|
96
|
+
// multiple Claude Code sessions work on the same project)
|
|
97
|
+
const sessionName = process.env.AGEND_INSTANCE_NAME
|
|
98
|
+
?? process.env.AGEND_SESSION_NAME
|
|
99
|
+
?? `external-${basename(process.cwd())}-${process.pid}`;
|
|
100
|
+
client.send({ type: "mcp_ready", sessionName });
|
|
101
|
+
process.stderr.write("agend: connected to daemon IPC\n");
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
process.stderr.write(`agend: failed to connect to daemon IPC: ${err}\n`);
|
|
105
|
+
ipcConnected = false;
|
|
106
|
+
scheduleReconnect();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function scheduleReconnect() {
|
|
110
|
+
if (reconnecting)
|
|
111
|
+
return;
|
|
112
|
+
if (isOrphaned()) {
|
|
113
|
+
process.stderr.write("agend: orphaned (parent died) during reconnect — exiting\n");
|
|
114
|
+
process.exit(0);
|
|
115
|
+
}
|
|
116
|
+
reconnectAttempts++;
|
|
117
|
+
if (reconnectAttempts > MAX_RECONNECT_ATTEMPTS) {
|
|
118
|
+
process.stderr.write(`agend: max reconnect attempts (${MAX_RECONNECT_ATTEMPTS}) exceeded — exiting\n`);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
reconnecting = true;
|
|
122
|
+
const delay = 3000;
|
|
123
|
+
process.stderr.write(`agend: reconnecting in ${delay}ms (attempt ${reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})...\n`);
|
|
124
|
+
setTimeout(() => {
|
|
125
|
+
reconnecting = false;
|
|
126
|
+
connectIpc();
|
|
127
|
+
}, delay);
|
|
128
|
+
}
|
|
129
|
+
function ipcRequest(tool, args) {
|
|
130
|
+
return new Promise((resolve, reject) => {
|
|
131
|
+
if (!ipcConnected || !ipc) {
|
|
132
|
+
reject(new Error("Not connected to daemon IPC (retrying connection in background)"));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
const timeoutMs = SLOW_TOOLS.has(tool) ? SLOW_IPC_TIMEOUT_MS : IPC_TIMEOUT_MS;
|
|
136
|
+
const requestId = ++requestCounter;
|
|
137
|
+
const timer = setTimeout(() => {
|
|
138
|
+
pendingRequests.delete(requestId);
|
|
139
|
+
reject(new Error(`IPC request timed out after ${timeoutMs}ms`));
|
|
140
|
+
}, timeoutMs);
|
|
141
|
+
pendingRequests.set(requestId, { resolve, reject, timer });
|
|
142
|
+
try {
|
|
143
|
+
ipc.send({ type: "tool_call", tool, args, requestId });
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
pendingRequests.delete(requestId);
|
|
147
|
+
clearTimeout(timer);
|
|
148
|
+
ipcConnected = false;
|
|
149
|
+
reject(new Error(`IPC send failed: ${err}`));
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
// MCP Server
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
// ---------------------------------------------------------------------------
|
|
157
|
+
// MCP instructions — thin wrapper around shared buildFleetInstructions().
|
|
158
|
+
// Phase 1 (dual track): MCP instructions kept as fallback for backends that
|
|
159
|
+
// read the MCP instructions field. Content delegates to the shared module
|
|
160
|
+
// to avoid drift between MCP and additive system prompt paths.
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
function buildMcpInstructions() {
|
|
163
|
+
const workflowEnv = process.env.AGEND_WORKFLOW;
|
|
164
|
+
let workflow;
|
|
165
|
+
if (workflowEnv === "false")
|
|
166
|
+
workflow = false;
|
|
167
|
+
else if (workflowEnv)
|
|
168
|
+
workflow = workflowEnv;
|
|
169
|
+
let decisions;
|
|
170
|
+
if (process.env.AGEND_DECISIONS) {
|
|
171
|
+
try {
|
|
172
|
+
decisions = JSON.parse(process.env.AGEND_DECISIONS);
|
|
173
|
+
}
|
|
174
|
+
catch { /* skip */ }
|
|
175
|
+
}
|
|
176
|
+
return buildFleetInstructions({
|
|
177
|
+
instanceName: process.env.AGEND_INSTANCE_NAME ?? "unknown",
|
|
178
|
+
workingDirectory: process.env.AGEND_WORKING_DIR ?? process.cwd(),
|
|
179
|
+
displayName: process.env.AGEND_DISPLAY_NAME,
|
|
180
|
+
description: process.env.AGEND_DESCRIPTION,
|
|
181
|
+
customPrompt: process.env.AGEND_CUSTOM_PROMPT,
|
|
182
|
+
workflow,
|
|
183
|
+
decisions,
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
const mcp = new Server({ name: "agend", version: "0.3.0" }, {
|
|
187
|
+
capabilities: {
|
|
188
|
+
tools: {},
|
|
189
|
+
},
|
|
190
|
+
instructions: buildMcpInstructions(),
|
|
191
|
+
});
|
|
192
|
+
// --- Tool definitions (see mcp-tools.ts) ---
|
|
193
|
+
import { TOOL_SETS } from "./mcp-tools.js";
|
|
194
|
+
export { TOOLS } from "./mcp-tools.js";
|
|
195
|
+
const toolSet = process.env.AGEND_TOOL_SET;
|
|
196
|
+
let activeTools;
|
|
197
|
+
if (!toolSet || toolSet === "full") {
|
|
198
|
+
activeTools = TOOLS;
|
|
199
|
+
}
|
|
200
|
+
else if (TOOL_SETS[toolSet]) {
|
|
201
|
+
activeTools = TOOLS.filter(t => TOOL_SETS[toolSet].includes(t.name));
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
process.stderr.write(`agend: ERROR — unknown AGEND_TOOL_SET "${toolSet}", valid: ${Object.keys(TOOL_SETS).join(", ")}. Using "full".\n`);
|
|
205
|
+
activeTools = TOOLS;
|
|
206
|
+
}
|
|
207
|
+
mcp.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: activeTools }));
|
|
208
|
+
// --- Tool call handler ---
|
|
209
|
+
mcp.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
210
|
+
const args = (req.params.arguments ?? {});
|
|
211
|
+
try {
|
|
212
|
+
const result = await ipcRequest(req.params.name, args);
|
|
213
|
+
const text = typeof result === "string" ? result : JSON.stringify(result ?? "ok");
|
|
214
|
+
return { content: [{ type: "text", text }] };
|
|
215
|
+
}
|
|
216
|
+
catch (err) {
|
|
217
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
218
|
+
return {
|
|
219
|
+
content: [{ type: "text", text: `Error: ${message}` }],
|
|
220
|
+
isError: true,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
// ---------------------------------------------------------------------------
|
|
225
|
+
// Main
|
|
226
|
+
// ---------------------------------------------------------------------------
|
|
227
|
+
async function main() {
|
|
228
|
+
if (!SOCKET_PATH) {
|
|
229
|
+
process.stderr.write("agend: AGEND_SOCKET_PATH environment variable is required\n");
|
|
230
|
+
process.exit(1);
|
|
231
|
+
}
|
|
232
|
+
// Start MCP stdio transport FIRST — must be ready before the CLI sends
|
|
233
|
+
// the initialize request. IPC connection can happen in parallel.
|
|
234
|
+
const transport = new StdioServerTransport();
|
|
235
|
+
await mcp.connect(transport);
|
|
236
|
+
// Parent death detection.
|
|
237
|
+
// Primary: ppid polling — works on all platforms, immune to libuv/kqueue bugs.
|
|
238
|
+
// Secondary: stdin end/close/error — may fire faster on Linux (epoll handles
|
|
239
|
+
// broken pipes correctly), but fails on macOS (libuv CPU spin, no EOF emit).
|
|
240
|
+
// mcp.onclose only fires on explicit transport.close(), kept for completeness.
|
|
241
|
+
mcp.onclose = () => {
|
|
242
|
+
process.stderr.write("agend: MCP transport closed — exiting\n");
|
|
243
|
+
process.exit(0);
|
|
244
|
+
};
|
|
245
|
+
process.stdin.on("end", () => {
|
|
246
|
+
process.stderr.write("agend: stdin EOF (parent exited) — exiting\n");
|
|
247
|
+
process.exit(0);
|
|
248
|
+
});
|
|
249
|
+
process.stdin.on("close", () => {
|
|
250
|
+
process.stderr.write("agend: stdin closed (parent exited) — exiting\n");
|
|
251
|
+
process.exit(0);
|
|
252
|
+
});
|
|
253
|
+
process.stdin.on("error", () => {
|
|
254
|
+
process.stderr.write("agend: stdin error (parent exited) — exiting\n");
|
|
255
|
+
process.exit(0);
|
|
256
|
+
});
|
|
257
|
+
// Primary orphan detection: poll parent PID every 5 seconds.
|
|
258
|
+
setInterval(() => {
|
|
259
|
+
if (isOrphaned()) {
|
|
260
|
+
process.stderr.write("agend: parent process died (ppid changed) — exiting\n");
|
|
261
|
+
process.exit(0);
|
|
262
|
+
}
|
|
263
|
+
}, 5_000);
|
|
264
|
+
// Write PID file so daemon can kill orphan MCP servers on crash respawn.
|
|
265
|
+
// Derived from AGEND_SOCKET_PATH (e.g. ~/.agend/instances/foo/channel.sock).
|
|
266
|
+
const pidFile = join(dirname(SOCKET_PATH), "channel.mcp.pid");
|
|
267
|
+
writeFileSync(pidFile, String(process.pid));
|
|
268
|
+
process.on("exit", () => {
|
|
269
|
+
try {
|
|
270
|
+
if (readFileSync(pidFile, "utf-8").trim() === String(process.pid))
|
|
271
|
+
unlinkSync(pidFile);
|
|
272
|
+
}
|
|
273
|
+
catch { /* already cleaned up */ }
|
|
274
|
+
});
|
|
275
|
+
// Connect to daemon IPC (will auto-reconnect on disconnect)
|
|
276
|
+
await connectIpc();
|
|
277
|
+
// Immediate orphan check — don't let an orphan announce itself to the daemon
|
|
278
|
+
if (isOrphaned()) {
|
|
279
|
+
process.stderr.write("agend: orphaned before ready — exiting\n");
|
|
280
|
+
process.exit(0);
|
|
281
|
+
}
|
|
282
|
+
process.stderr.write("agend: MCP server running\n");
|
|
283
|
+
}
|
|
284
|
+
main().catch((err) => {
|
|
285
|
+
process.stderr.write(`agend: fatal error: ${err}\n`);
|
|
286
|
+
process.exit(1);
|
|
287
|
+
});
|
|
288
|
+
//# sourceMappingURL=mcp-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-server.js","sourceRoot":"","sources":["../../src/channel/mcp-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Narrow JSON-schema fragment shape that MCP tool listings need. */
|
|
2
|
+
type JsonSchemaObject = {
|
|
3
|
+
type: "object";
|
|
4
|
+
properties?: Record<string, unknown>;
|
|
5
|
+
required?: string[];
|
|
6
|
+
additionalProperties?: unknown;
|
|
7
|
+
[k: string]: unknown;
|
|
8
|
+
};
|
|
9
|
+
type ToolDef = {
|
|
10
|
+
name: string;
|
|
11
|
+
description: string;
|
|
12
|
+
inputSchema: JsonSchemaObject;
|
|
13
|
+
};
|
|
14
|
+
export declare const TOOLS: ToolDef[];
|
|
15
|
+
/** Predefined tool profiles to reduce token overhead per instance. */
|
|
16
|
+
export declare const TOOL_SETS: Record<string, string[]>;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool definitions. Schemas come from src/outbound-schemas.ts so runtime
|
|
3
|
+
* validation and the JSON Schema surfaced to agents share one source.
|
|
4
|
+
*
|
|
5
|
+
* Kept free of runtime side effects — safe to import from tests and tools
|
|
6
|
+
* without pulling in channel infrastructure.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import * as schemas from "../outbound-schemas.js";
|
|
10
|
+
/** Strip `$schema`/`$defs` that some MCP clients reject. */
|
|
11
|
+
function toToolInputSchema(schema) {
|
|
12
|
+
const raw = z.toJSONSchema(schema);
|
|
13
|
+
const { $schema: _s, $defs: _d, ...rest } = raw;
|
|
14
|
+
if (rest.type !== "object") {
|
|
15
|
+
throw new Error("Expected object-typed zod schema for MCP tool input");
|
|
16
|
+
}
|
|
17
|
+
return rest;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build the tool list. The `[schema, description]` pairs keep the declaration
|
|
21
|
+
* terse and guarantee every tool has both a description and a schema.
|
|
22
|
+
*/
|
|
23
|
+
const DEFS = [
|
|
24
|
+
["reply", schemas.ReplyArgs,
|
|
25
|
+
"Reply on the channel. Routing is handled automatically — do not pass chat_id or thread_id."],
|
|
26
|
+
["react", schemas.ReactArgs,
|
|
27
|
+
"Add an emoji reaction to a channel message."],
|
|
28
|
+
["edit_message", schemas.EditMessageArgs,
|
|
29
|
+
"Edit a message the bot previously sent. Useful for interim progress updates."],
|
|
30
|
+
["download_attachment", schemas.DownloadAttachmentArgs,
|
|
31
|
+
"Download a file attachment from a channel message. Returns the local file path ready to Read."],
|
|
32
|
+
["create_schedule", schemas.CreateScheduleArgs,
|
|
33
|
+
"Create a cron-based schedule. When triggered, sends a message to the target instance."],
|
|
34
|
+
["list_schedules", schemas.ListSchedulesArgs,
|
|
35
|
+
"List all schedules. Optionally filter by target instance."],
|
|
36
|
+
["update_schedule", schemas.UpdateScheduleArgs,
|
|
37
|
+
"Update an existing schedule. Only include fields you want to change."],
|
|
38
|
+
["delete_schedule", schemas.DeleteScheduleArgs,
|
|
39
|
+
"Delete a schedule by ID."],
|
|
40
|
+
["task", schemas.TaskBoardArgs,
|
|
41
|
+
"Manage fleet task board. Actions: create (new task), list (show tasks), claim (assign to self), done (mark complete), update (change status/priority/assignee)."],
|
|
42
|
+
["post_decision", schemas.PostDecisionArgs,
|
|
43
|
+
"Record a decision. scope='project' (default) is visible to instances sharing this working directory. scope='fleet' is visible to ALL instances regardless of directory — use for workflow rules, review policies, and team conventions."],
|
|
44
|
+
["list_decisions", schemas.ListDecisionsArgs,
|
|
45
|
+
"List active decisions for this project. Returns decisions that were recorded by any instance sharing this working directory."],
|
|
46
|
+
["update_decision", schemas.UpdateDecisionArgs,
|
|
47
|
+
"Update or archive an existing decision."],
|
|
48
|
+
["broadcast", schemas.BroadcastArgs,
|
|
49
|
+
"Send a message to multiple instances at once. Priority: team > targets > tags > all running."],
|
|
50
|
+
["send_to_instance", schemas.SendToInstanceArgs,
|
|
51
|
+
"Send a message to another instance. Use for cross-instance communication."],
|
|
52
|
+
["request_information", schemas.RequestInformationArgs,
|
|
53
|
+
"Ask another instance a question and expect a reply. Wrapper around send_to_instance with request_kind=query and requires_reply=true."],
|
|
54
|
+
["delegate_task", schemas.DelegateTaskArgs,
|
|
55
|
+
"Delegate a task to another instance and expect a result report back. Wrapper around send_to_instance with request_kind=task and requires_reply=true."],
|
|
56
|
+
["report_result", schemas.ReportResultArgs,
|
|
57
|
+
"Report results back to an instance that delegated a task or asked a question. Wrapper around send_to_instance with request_kind=report."],
|
|
58
|
+
["create_team", schemas.CreateTeamArgs,
|
|
59
|
+
"Create a named group of instances for targeted broadcasting. Teams persist across restarts."],
|
|
60
|
+
["delete_team", schemas.DeleteTeamArgs,
|
|
61
|
+
"Dissolve a team. Does not affect the member instances."],
|
|
62
|
+
["list_teams", schemas.ListTeamsArgs,
|
|
63
|
+
"List all teams with their members and running status."],
|
|
64
|
+
["update_team", schemas.UpdateTeamArgs,
|
|
65
|
+
"Add or remove members from an existing team. Duplicates are ignored."],
|
|
66
|
+
["describe_instance", schemas.DescribeInstanceArgs,
|
|
67
|
+
"Get detailed information about a specific instance: description, working directory, status, tags, and recent activity."],
|
|
68
|
+
["list_instances", schemas.ListInstancesArgs,
|
|
69
|
+
"List all currently running instances that you can send messages to."],
|
|
70
|
+
["start_instance", schemas.StartInstanceArgs,
|
|
71
|
+
"Start a stopped instance by name."],
|
|
72
|
+
["restart_instance", schemas.RestartInstanceArgs,
|
|
73
|
+
"Restart a running instance. Reloads fleet config and restarts the instance."],
|
|
74
|
+
["create_instance", schemas.CreateInstanceArgs,
|
|
75
|
+
"Create a new instance bound to a project directory with a channel topic. If directory is omitted, a workspace is auto-created at ~/.agend/workspaces/<instance-name>."],
|
|
76
|
+
["delete_instance", schemas.DeleteInstanceArgs,
|
|
77
|
+
"Delete an instance: stop daemon, remove config, optionally delete topic."],
|
|
78
|
+
["replace_instance", schemas.ReplaceInstanceArgs,
|
|
79
|
+
"Replace an instance with a fresh one. Collects handover context from the old instance (or falls back to daemon ring buffer), deletes it, creates a new instance with the same config, and sends the handover context to the new instance."],
|
|
80
|
+
["set_display_name", schemas.SetDisplayNameArgs,
|
|
81
|
+
"Set your display name. This name will be shown in Telegram messages, activity logs, and when other agents refer to you."],
|
|
82
|
+
["set_description", schemas.SetDescriptionArgs,
|
|
83
|
+
"Set your role description. This is injected into your system prompt as your role definition. Takes effect on next context rotation."],
|
|
84
|
+
["checkout_repo", schemas.CheckoutRepoArgs,
|
|
85
|
+
"Mount another repo as a read-only worktree. Returns a local path you can Read files from. Use instance name or absolute path as source."],
|
|
86
|
+
["release_repo", schemas.ReleaseRepoArgs,
|
|
87
|
+
"Remove a previously checked-out repo worktree."],
|
|
88
|
+
["deploy_template", schemas.DeployTemplateArgs,
|
|
89
|
+
"Deploy a fleet template — creates instances and optionally a team in one operation."],
|
|
90
|
+
["teardown_deployment", schemas.TeardownDeploymentArgs,
|
|
91
|
+
"Tear down a template deployment — stops and deletes all instances and team."],
|
|
92
|
+
["list_deployments", schemas.ListDeploymentsArgs,
|
|
93
|
+
"List active template deployments with their instances and status."],
|
|
94
|
+
];
|
|
95
|
+
export const TOOLS = DEFS.map(([name, schema, description]) => ({
|
|
96
|
+
name,
|
|
97
|
+
description,
|
|
98
|
+
inputSchema: toToolInputSchema(schema),
|
|
99
|
+
}));
|
|
100
|
+
/** Predefined tool profiles to reduce token overhead per instance. */
|
|
101
|
+
export const TOOL_SETS = {
|
|
102
|
+
full: TOOLS.map(t => t.name),
|
|
103
|
+
standard: [
|
|
104
|
+
"reply", "react", "edit_message",
|
|
105
|
+
"send_to_instance", "broadcast", "list_instances", "describe_instance",
|
|
106
|
+
"list_decisions", "post_decision", "task", "set_display_name", "set_description",
|
|
107
|
+
],
|
|
108
|
+
minimal: ["reply", "send_to_instance", "list_decisions", "download_attachment"],
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=mcp-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-tools.js","sourceRoot":"","sources":["../../src/channel/mcp-tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
import type { ChannelAdapter, OutboundMessage, Target, ApprovalResponse, PermissionPrompt } from "./types.js";
|
|
3
|
+
export declare class MessageBus extends EventEmitter {
|
|
4
|
+
private adapters;
|
|
5
|
+
private logger?;
|
|
6
|
+
setLogger(logger: {
|
|
7
|
+
warn(obj: unknown, msg?: string): void;
|
|
8
|
+
error(msg: string): void;
|
|
9
|
+
}): void;
|
|
10
|
+
register(adapter: ChannelAdapter): void;
|
|
11
|
+
unregister(adapterId: string): void;
|
|
12
|
+
getAdapter(id: string): ChannelAdapter | undefined;
|
|
13
|
+
getAllAdapters(): ChannelAdapter[];
|
|
14
|
+
send(target: Target, msg: OutboundMessage): Promise<void>;
|
|
15
|
+
private sendVia;
|
|
16
|
+
requestApproval(prompt: PermissionPrompt): Promise<ApprovalResponse>;
|
|
17
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { EventEmitter } from "node:events";
|
|
2
|
+
const APPROVAL_TIMEOUT_MS = 120_000;
|
|
3
|
+
export class MessageBus extends EventEmitter {
|
|
4
|
+
adapters = new Map();
|
|
5
|
+
logger;
|
|
6
|
+
setLogger(logger) {
|
|
7
|
+
this.logger = logger;
|
|
8
|
+
}
|
|
9
|
+
register(adapter) {
|
|
10
|
+
this.adapters.set(adapter.id, adapter);
|
|
11
|
+
adapter.on("message", (msg) => this.emit("message", msg));
|
|
12
|
+
}
|
|
13
|
+
unregister(adapterId) { this.adapters.delete(adapterId); }
|
|
14
|
+
getAdapter(id) { return this.adapters.get(id); }
|
|
15
|
+
getAllAdapters() { return [...this.adapters.values()]; }
|
|
16
|
+
async send(target, msg) {
|
|
17
|
+
if (target.adapterId) {
|
|
18
|
+
const adapter = this.adapters.get(target.adapterId);
|
|
19
|
+
if (!adapter)
|
|
20
|
+
throw new Error(`Adapter ${target.adapterId} not found`);
|
|
21
|
+
await this.sendVia(adapter, target, msg);
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
const results = await Promise.allSettled([...this.adapters.values()].map(a => this.sendVia(a, target, msg)));
|
|
25
|
+
for (const r of results) {
|
|
26
|
+
if (r.status === "rejected") {
|
|
27
|
+
this.logger?.warn({ err: r.reason }, "Adapter send failed");
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async sendVia(adapter, target, msg) {
|
|
33
|
+
if (msg.filePath) {
|
|
34
|
+
await adapter.sendFile(target.chatId, msg.filePath, { threadId: target.threadId });
|
|
35
|
+
}
|
|
36
|
+
else if (msg.text) {
|
|
37
|
+
await adapter.sendText(target.chatId, msg.text, {
|
|
38
|
+
threadId: target.threadId, replyTo: msg.replyTo, format: msg.format,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
requestApproval(prompt) {
|
|
43
|
+
return new Promise((resolve) => {
|
|
44
|
+
const controller = new AbortController();
|
|
45
|
+
const handles = [];
|
|
46
|
+
let resolved = false;
|
|
47
|
+
const timeout = setTimeout(() => {
|
|
48
|
+
if (resolved)
|
|
49
|
+
return;
|
|
50
|
+
resolved = true;
|
|
51
|
+
controller.abort();
|
|
52
|
+
handles.forEach(h => h.cancel());
|
|
53
|
+
resolve({ decision: "deny", respondedBy: { channelType: "timeout", userId: "" } });
|
|
54
|
+
}, APPROVAL_TIMEOUT_MS);
|
|
55
|
+
if (this.adapters.size === 0) {
|
|
56
|
+
clearTimeout(timeout);
|
|
57
|
+
resolve({ decision: "deny", respondedBy: { channelType: "none", userId: "" } });
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
let adapterFailures = 0;
|
|
61
|
+
for (const adapter of this.adapters.values()) {
|
|
62
|
+
adapter.sendApproval(prompt, (decision) => {
|
|
63
|
+
if (resolved)
|
|
64
|
+
return;
|
|
65
|
+
resolved = true;
|
|
66
|
+
clearTimeout(timeout);
|
|
67
|
+
controller.abort();
|
|
68
|
+
handles.forEach(h => h.cancel());
|
|
69
|
+
resolve({ decision, respondedBy: { channelType: adapter.type, userId: adapter.id } });
|
|
70
|
+
}, controller.signal).then(handle => handles.push(handle)).catch(err => {
|
|
71
|
+
this.logger?.warn({ err }, "Failed to send approval prompt via adapter");
|
|
72
|
+
adapterFailures++;
|
|
73
|
+
if (adapterFailures === this.adapters.size) {
|
|
74
|
+
if (resolved)
|
|
75
|
+
return;
|
|
76
|
+
resolved = true;
|
|
77
|
+
clearTimeout(timeout);
|
|
78
|
+
this.logger?.error("All adapters failed to send approval prompt, auto-denying");
|
|
79
|
+
resolve({ decision: "deny", reason: "All channel adapters failed to send approval prompt" });
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=message-bus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"message-bus.js","sourceRoot":"","sources":["../../src/channel/message-bus.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { QueuedMessage } from "./types.js";
|
|
2
|
+
interface QueueSender {
|
|
3
|
+
send(chatId: string, threadId: string | undefined, text: string): Promise<{
|
|
4
|
+
messageId: string;
|
|
5
|
+
}>;
|
|
6
|
+
edit(chatId: string, messageId: string, text: string): Promise<void>;
|
|
7
|
+
sendFile(chatId: string, threadId: string | undefined, filePath: string): Promise<{
|
|
8
|
+
messageId: string;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
export declare class MessageQueue {
|
|
12
|
+
private sender;
|
|
13
|
+
private queues;
|
|
14
|
+
private stopped;
|
|
15
|
+
private logger?;
|
|
16
|
+
constructor(sender: QueueSender, logger?: {
|
|
17
|
+
warn(obj: unknown, msg?: string): void;
|
|
18
|
+
});
|
|
19
|
+
private queueKey;
|
|
20
|
+
private getOrCreateQueue;
|
|
21
|
+
enqueue(chatId: string, threadId: string | undefined, msg: QueuedMessage): void;
|
|
22
|
+
start(): void;
|
|
23
|
+
stop(): void;
|
|
24
|
+
private runWorker;
|
|
25
|
+
/**
|
|
26
|
+
* Synchronously extracts items from the queue and returns the extracted items
|
|
27
|
+
* plus an async work function. The work function does the actual sending.
|
|
28
|
+
* This split allows us to know which items to re-queue if the work fails.
|
|
29
|
+
*/
|
|
30
|
+
private prepareNext;
|
|
31
|
+
/**
|
|
32
|
+
* Merges all adjacent content messages at the front of the queue.
|
|
33
|
+
* Respects the 4096 char limit per chunk.
|
|
34
|
+
* Returns merged chunks plus the original consumed items (for re-queuing on error).
|
|
35
|
+
*/
|
|
36
|
+
private mergeContentMessages;
|
|
37
|
+
private sleep;
|
|
38
|
+
}
|
|
39
|
+
export {};
|