@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.
Files changed (232) hide show
  1. package/README.md +210 -0
  2. package/README.zh-TW.md +134 -0
  3. package/dist/access-path.d.ts +10 -0
  4. package/dist/access-path.js +32 -0
  5. package/dist/access-path.js.map +1 -0
  6. package/dist/adapter-world.d.ts +25 -0
  7. package/dist/adapter-world.js +41 -0
  8. package/dist/adapter-world.js.map +1 -0
  9. package/dist/agent-cli-instructions.md +50 -0
  10. package/dist/agent-cli.d.ts +2 -0
  11. package/dist/agent-cli.js +200 -0
  12. package/dist/agent-cli.js.map +1 -0
  13. package/dist/agent-endpoint.d.ts +25 -0
  14. package/dist/agent-endpoint.js +162 -0
  15. package/dist/agent-endpoint.js.map +1 -0
  16. package/dist/backend/antigravity.d.ts +17 -0
  17. package/dist/backend/antigravity.js +98 -0
  18. package/dist/backend/antigravity.js.map +1 -0
  19. package/dist/backend/claude-code.d.ts +23 -0
  20. package/dist/backend/claude-code.js +171 -0
  21. package/dist/backend/claude-code.js.map +1 -0
  22. package/dist/backend/codex.d.ts +18 -0
  23. package/dist/backend/codex.js +160 -0
  24. package/dist/backend/codex.js.map +1 -0
  25. package/dist/backend/factory.d.ts +2 -0
  26. package/dist/backend/factory.js +28 -0
  27. package/dist/backend/factory.js.map +1 -0
  28. package/dist/backend/gemini-cli.d.ts +17 -0
  29. package/dist/backend/gemini-cli.js +163 -0
  30. package/dist/backend/gemini-cli.js.map +1 -0
  31. package/dist/backend/index.d.ts +7 -0
  32. package/dist/backend/index.js +7 -0
  33. package/dist/backend/index.js.map +1 -0
  34. package/dist/backend/kiro.d.ts +17 -0
  35. package/dist/backend/kiro.js +147 -0
  36. package/dist/backend/kiro.js.map +1 -0
  37. package/dist/backend/marker-utils.d.ts +13 -0
  38. package/dist/backend/marker-utils.js +64 -0
  39. package/dist/backend/marker-utils.js.map +1 -0
  40. package/dist/backend/mock.d.ts +25 -0
  41. package/dist/backend/mock.js +85 -0
  42. package/dist/backend/mock.js.map +1 -0
  43. package/dist/backend/opencode.d.ts +16 -0
  44. package/dist/backend/opencode.js +136 -0
  45. package/dist/backend/opencode.js.map +1 -0
  46. package/dist/backend/types.d.ts +86 -0
  47. package/dist/backend/types.js +33 -0
  48. package/dist/backend/types.js.map +1 -0
  49. package/dist/channel/access-manager.d.ts +18 -0
  50. package/dist/channel/access-manager.js +153 -0
  51. package/dist/channel/access-manager.js.map +1 -0
  52. package/dist/channel/adapters/telegram.d.ts +63 -0
  53. package/dist/channel/adapters/telegram.js +646 -0
  54. package/dist/channel/adapters/telegram.js.map +1 -0
  55. package/dist/channel/attachment-handler.d.ts +15 -0
  56. package/dist/channel/attachment-handler.js +88 -0
  57. package/dist/channel/attachment-handler.js.map +1 -0
  58. package/dist/channel/factory.d.ts +12 -0
  59. package/dist/channel/factory.js +67 -0
  60. package/dist/channel/factory.js.map +1 -0
  61. package/dist/channel/ipc-bridge.d.ts +26 -0
  62. package/dist/channel/ipc-bridge.js +220 -0
  63. package/dist/channel/ipc-bridge.js.map +1 -0
  64. package/dist/channel/mcp-server.d.ts +10 -0
  65. package/dist/channel/mcp-server.js +288 -0
  66. package/dist/channel/mcp-server.js.map +1 -0
  67. package/dist/channel/mcp-tools.d.ts +17 -0
  68. package/dist/channel/mcp-tools.js +110 -0
  69. package/dist/channel/mcp-tools.js.map +1 -0
  70. package/dist/channel/message-bus.d.ts +17 -0
  71. package/dist/channel/message-bus.js +86 -0
  72. package/dist/channel/message-bus.js.map +1 -0
  73. package/dist/channel/message-queue.d.ts +39 -0
  74. package/dist/channel/message-queue.js +253 -0
  75. package/dist/channel/message-queue.js.map +1 -0
  76. package/dist/channel/tool-router.d.ts +6 -0
  77. package/dist/channel/tool-router.js +75 -0
  78. package/dist/channel/tool-router.js.map +1 -0
  79. package/dist/channel/tool-tracker.d.ts +13 -0
  80. package/dist/channel/tool-tracker.js +58 -0
  81. package/dist/channel/tool-tracker.js.map +1 -0
  82. package/dist/channel/types.d.ts +118 -0
  83. package/dist/channel/types.js +2 -0
  84. package/dist/channel/types.js.map +1 -0
  85. package/dist/chat-export.d.ts +4 -0
  86. package/dist/chat-export.js +91 -0
  87. package/dist/chat-export.js.map +1 -0
  88. package/dist/classic-channel-manager.d.ts +59 -0
  89. package/dist/classic-channel-manager.js +193 -0
  90. package/dist/classic-channel-manager.js.map +1 -0
  91. package/dist/cli.d.ts +2 -0
  92. package/dist/cli.js +1833 -0
  93. package/dist/cli.js.map +1 -0
  94. package/dist/config.d.ts +9 -0
  95. package/dist/config.js +118 -0
  96. package/dist/config.js.map +1 -0
  97. package/dist/context-guardian.d.ts +26 -0
  98. package/dist/context-guardian.js +73 -0
  99. package/dist/context-guardian.js.map +1 -0
  100. package/dist/cost-guard.d.ts +36 -0
  101. package/dist/cost-guard.js +147 -0
  102. package/dist/cost-guard.js.map +1 -0
  103. package/dist/daemon-entry.d.ts +1 -0
  104. package/dist/daemon-entry.js +29 -0
  105. package/dist/daemon-entry.js.map +1 -0
  106. package/dist/daemon.d.ts +152 -0
  107. package/dist/daemon.js +1714 -0
  108. package/dist/daemon.js.map +1 -0
  109. package/dist/daily-summary.d.ts +13 -0
  110. package/dist/daily-summary.js +55 -0
  111. package/dist/daily-summary.js.map +1 -0
  112. package/dist/event-log.d.ts +36 -0
  113. package/dist/event-log.js +100 -0
  114. package/dist/event-log.js.map +1 -0
  115. package/dist/export-import.d.ts +2 -0
  116. package/dist/export-import.js +162 -0
  117. package/dist/export-import.js.map +1 -0
  118. package/dist/fleet-context.d.ts +61 -0
  119. package/dist/fleet-context.js +4 -0
  120. package/dist/fleet-context.js.map +1 -0
  121. package/dist/fleet-dashboard-html.d.ts +6 -0
  122. package/dist/fleet-dashboard-html.js +443 -0
  123. package/dist/fleet-dashboard-html.js.map +1 -0
  124. package/dist/fleet-health-server.d.ts +35 -0
  125. package/dist/fleet-health-server.js +290 -0
  126. package/dist/fleet-health-server.js.map +1 -0
  127. package/dist/fleet-instructions.d.ts +5 -0
  128. package/dist/fleet-instructions.js +161 -0
  129. package/dist/fleet-instructions.js.map +1 -0
  130. package/dist/fleet-manager.d.ts +212 -0
  131. package/dist/fleet-manager.js +3655 -0
  132. package/dist/fleet-manager.js.map +1 -0
  133. package/dist/fleet-rpc-handlers.d.ts +42 -0
  134. package/dist/fleet-rpc-handlers.js +356 -0
  135. package/dist/fleet-rpc-handlers.js.map +1 -0
  136. package/dist/fleet-system-prompt.d.ts +11 -0
  137. package/dist/fleet-system-prompt.js +61 -0
  138. package/dist/fleet-system-prompt.js.map +1 -0
  139. package/dist/general-knowledge/skills.md +177 -0
  140. package/dist/hang-detector.d.ts +16 -0
  141. package/dist/hang-detector.js +53 -0
  142. package/dist/hang-detector.js.map +1 -0
  143. package/dist/index.d.ts +8 -0
  144. package/dist/index.js +6 -0
  145. package/dist/index.js.map +1 -0
  146. package/dist/instance-lifecycle.d.ts +90 -0
  147. package/dist/instance-lifecycle.js +592 -0
  148. package/dist/instance-lifecycle.js.map +1 -0
  149. package/dist/instructions.d.ts +15 -0
  150. package/dist/instructions.js +90 -0
  151. package/dist/instructions.js.map +1 -0
  152. package/dist/logger.d.ts +7 -0
  153. package/dist/logger.js +84 -0
  154. package/dist/logger.js.map +1 -0
  155. package/dist/outbound-handlers.d.ts +51 -0
  156. package/dist/outbound-handlers.js +739 -0
  157. package/dist/outbound-handlers.js.map +1 -0
  158. package/dist/outbound-schemas.d.ts +238 -0
  159. package/dist/outbound-schemas.js +248 -0
  160. package/dist/outbound-schemas.js.map +1 -0
  161. package/dist/paths.d.ts +10 -0
  162. package/dist/paths.js +42 -0
  163. package/dist/paths.js.map +1 -0
  164. package/dist/plugin/agend/.claude-plugin/plugin.json +5 -0
  165. package/dist/quickstart.d.ts +1 -0
  166. package/dist/quickstart.js +595 -0
  167. package/dist/quickstart.js.map +1 -0
  168. package/dist/routing-engine.d.ts +22 -0
  169. package/dist/routing-engine.js +44 -0
  170. package/dist/routing-engine.js.map +1 -0
  171. package/dist/safe-async.d.ts +6 -0
  172. package/dist/safe-async.js +20 -0
  173. package/dist/safe-async.js.map +1 -0
  174. package/dist/scheduler/db.d.ts +37 -0
  175. package/dist/scheduler/db.js +360 -0
  176. package/dist/scheduler/db.js.map +1 -0
  177. package/dist/scheduler/db.test.d.ts +1 -0
  178. package/dist/scheduler/db.test.js +92 -0
  179. package/dist/scheduler/db.test.js.map +1 -0
  180. package/dist/scheduler/index.d.ts +4 -0
  181. package/dist/scheduler/index.js +4 -0
  182. package/dist/scheduler/index.js.map +1 -0
  183. package/dist/scheduler/scheduler.d.ts +44 -0
  184. package/dist/scheduler/scheduler.js +197 -0
  185. package/dist/scheduler/scheduler.js.map +1 -0
  186. package/dist/scheduler/scheduler.test.d.ts +1 -0
  187. package/dist/scheduler/scheduler.test.js +119 -0
  188. package/dist/scheduler/scheduler.test.js.map +1 -0
  189. package/dist/scheduler/types.d.ts +107 -0
  190. package/dist/scheduler/types.js +7 -0
  191. package/dist/scheduler/types.js.map +1 -0
  192. package/dist/service-installer.d.ts +17 -0
  193. package/dist/service-installer.js +182 -0
  194. package/dist/service-installer.js.map +1 -0
  195. package/dist/setup-wizard.d.ts +48 -0
  196. package/dist/setup-wizard.js +701 -0
  197. package/dist/setup-wizard.js.map +1 -0
  198. package/dist/statusline-watcher.d.ts +34 -0
  199. package/dist/statusline-watcher.js +73 -0
  200. package/dist/statusline-watcher.js.map +1 -0
  201. package/dist/stt.d.ts +10 -0
  202. package/dist/stt.js +33 -0
  203. package/dist/stt.js.map +1 -0
  204. package/dist/tmux-control.d.ts +52 -0
  205. package/dist/tmux-control.js +207 -0
  206. package/dist/tmux-control.js.map +1 -0
  207. package/dist/tmux-manager.d.ts +44 -0
  208. package/dist/tmux-manager.js +218 -0
  209. package/dist/tmux-manager.js.map +1 -0
  210. package/dist/topic-archiver.d.ts +40 -0
  211. package/dist/topic-archiver.js +103 -0
  212. package/dist/topic-archiver.js.map +1 -0
  213. package/dist/topic-commands.d.ts +28 -0
  214. package/dist/topic-commands.js +359 -0
  215. package/dist/topic-commands.js.map +1 -0
  216. package/dist/transcript-monitor.d.ts +23 -0
  217. package/dist/transcript-monitor.js +164 -0
  218. package/dist/transcript-monitor.js.map +1 -0
  219. package/dist/types.d.ts +211 -0
  220. package/dist/types.js +2 -0
  221. package/dist/types.js.map +1 -0
  222. package/dist/ui/dashboard.html +719 -0
  223. package/dist/web-api.d.ts +101 -0
  224. package/dist/web-api.js +648 -0
  225. package/dist/web-api.js.map +1 -0
  226. package/dist/webhook-emitter.d.ts +15 -0
  227. package/dist/webhook-emitter.js +41 -0
  228. package/dist/webhook-emitter.js.map +1 -0
  229. package/dist/workflow-templates/default.md +35 -0
  230. package/package.json +76 -0
  231. package/templates/launchd.plist.ejs +31 -0
  232. package/templates/systemd.service.ejs +16 -0
@@ -0,0 +1,359 @@
1
+ import { readFileSync, existsSync } from "node:fs";
2
+ import { exec } from "node:child_process";
3
+ import { promisify } from "node:util";
4
+ import { join, basename } from "node:path";
5
+ import { homedir } from "node:os";
6
+ const execAsync = promisify(exec);
7
+ import { DEFAULT_INSTANCE_CONFIG } from "./config.js";
8
+ import { formatCents } from "./cost-guard.js";
9
+ import { detectPlatform } from "./service-installer.js";
10
+ /** Sanitize a directory name into a valid instance name. Keeps Unicode letters (incl. CJK). */
11
+ export function sanitizeInstanceName(name) {
12
+ const sanitized = name.toLowerCase().replace(/[^\p{L}\d-]/gu, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
13
+ return sanitized || "project";
14
+ }
15
+ export class TopicCommands {
16
+ ctx;
17
+ constructor(ctx) {
18
+ this.ctx = ctx;
19
+ }
20
+ /** Get the adapter that should reply to a given inbound message */
21
+ getReplyAdapter(msg) {
22
+ if (msg.adapterId && this.ctx.adapters) {
23
+ return this.ctx.adapters.get(msg.adapterId) ?? this.ctx.adapter;
24
+ }
25
+ return this.ctx.adapter;
26
+ }
27
+ /** Parse and dispatch commands from the General topic */
28
+ async handleGeneralCommand(msg) {
29
+ const text = msg.text?.trim();
30
+ if (!text)
31
+ return false;
32
+ if (text === "/status" || text === "/status@" || text.startsWith("/status@")) {
33
+ await this.handleStatusCommand(msg);
34
+ return true;
35
+ }
36
+ if (text === "/restart" || text === "/restart@" || text.startsWith("/restart@")) {
37
+ await this.handleRestartCommand(msg);
38
+ return true;
39
+ }
40
+ if (text === "/sysinfo" || text === "/sysinfo@" || text.startsWith("/sysinfo@")
41
+ || text === "/sys-info" || text === "/sys_info") {
42
+ await this.handleSysInfoCommand(msg);
43
+ return true;
44
+ }
45
+ return false;
46
+ }
47
+ /** Handle /ctx in any instance topic — returns true if handled */
48
+ async handleInstanceCommand(msg, instanceName) {
49
+ const text = msg.text?.trim();
50
+ if (!text)
51
+ return false;
52
+ if (text !== "/ctx" && !text.startsWith("/ctx@"))
53
+ return false;
54
+ const adapter = this.getReplyAdapter(msg);
55
+ if (!adapter)
56
+ return false;
57
+ const backend = this.ctx.fleetConfig?.instances[instanceName]?.backend
58
+ ?? this.ctx.fleetConfig?.defaults?.backend ?? "claude-code";
59
+ let context = null;
60
+ try {
61
+ const statusFile = join(this.ctx.dataDir, "instances", instanceName, "statusline.json");
62
+ if (existsSync(statusFile)) {
63
+ const d = JSON.parse(readFileSync(statusFile, "utf-8"));
64
+ context = d.context_window?.used_percentage ?? null;
65
+ }
66
+ }
67
+ catch { /* ignore */ }
68
+ if (context == null) {
69
+ try {
70
+ const { execFileSync } = await import("node:child_process");
71
+ const { getTmuxSocketName, getTmuxSessionName } = await import("./paths.js");
72
+ const socketName = getTmuxSocketName();
73
+ const tmuxArgs = socketName
74
+ ? ["-L", socketName, "capture-pane", "-t", `${getTmuxSessionName()}:${instanceName}`, "-p"]
75
+ : ["capture-pane", "-t", `${getTmuxSessionName()}:${instanceName}`, "-p"];
76
+ const pane = execFileSync("tmux", tmuxArgs, { encoding: "utf-8", timeout: 2000, stdio: ["pipe", "pipe", "pipe"] });
77
+ const m = pane.match(/(\d+)%.*!>/m) || pane.match(/◔\s*(\d+)%/);
78
+ if (m)
79
+ context = parseInt(m[1], 10);
80
+ }
81
+ catch { /* ignore */ }
82
+ }
83
+ const reply = context != null
84
+ ? `📊 Context: ${context}% used\nBackend: ${backend}\nInstance: ${instanceName}`
85
+ : `Context info not available yet.\nBackend: ${backend}\nInstance: ${instanceName}`;
86
+ await adapter.sendText(msg.chatId, reply, { threadId: msg.threadId });
87
+ return true;
88
+ }
89
+ async handleRestartCommand(msg) {
90
+ const adapter = this.getReplyAdapter(msg);
91
+ if (!adapter)
92
+ return;
93
+ const chatId = msg.chatId;
94
+ const threadId = msg.threadId;
95
+ await adapter.sendText(chatId, "🔄 Graceful restart — waiting for instances to idle...", { threadId });
96
+ process.kill(process.pid, "SIGUSR2");
97
+ }
98
+ async handleStatusCommand(msg) {
99
+ const adapter = this.getReplyAdapter(msg);
100
+ if (!adapter || !this.ctx.fleetConfig)
101
+ return;
102
+ const lines = [];
103
+ for (const [name] of Object.entries(this.ctx.fleetConfig.instances)) {
104
+ const status = this.ctx.getInstanceStatus(name);
105
+ const paused = this.ctx.costGuard?.isLimited(name);
106
+ let contextStr = "-";
107
+ try {
108
+ const data = JSON.parse(readFileSync(join(this.ctx.dataDir, "instances", name, "statusline.json"), "utf-8"));
109
+ if (data.context_window?.used_percentage != null) {
110
+ contextStr = `${Math.round(data.context_window.used_percentage)}%`;
111
+ }
112
+ }
113
+ catch { /* file may not exist yet */ }
114
+ const costCents = this.ctx.costGuard?.getDailyCostCents(name) ?? 0;
115
+ let icon;
116
+ if (paused)
117
+ icon = "⏸";
118
+ else if (status === "running")
119
+ icon = "🟢";
120
+ else if (status === "crashed")
121
+ icon = "🔴";
122
+ else
123
+ icon = "⚪";
124
+ lines.push(`${icon} ${name} — ctx ${contextStr}, ${formatCents(costCents)} today`);
125
+ }
126
+ if (lines.length === 0) {
127
+ lines.push("No instances configured.");
128
+ }
129
+ const limitCents = this.ctx.costGuard?.getLimitCents() ?? 0;
130
+ const totalCents = this.ctx.costGuard?.getFleetTotalCents() ?? 0;
131
+ if (limitCents > 0) {
132
+ lines.push("");
133
+ lines.push(`Fleet: ${formatCents(totalCents)} / ${formatCents(limitCents)} daily`);
134
+ }
135
+ await adapter.sendText(msg.chatId, lines.join("\n"));
136
+ }
137
+ async handleSysInfoCommand(msg) {
138
+ const adapter = this.getReplyAdapter(msg);
139
+ if (!adapter)
140
+ return;
141
+ const info = this.ctx.getSysInfo();
142
+ const upHours = Math.floor(info.uptime_seconds / 3600);
143
+ const upMins = Math.floor((info.uptime_seconds % 3600) / 60);
144
+ const lines = [
145
+ `⚙️ System Info`,
146
+ `Uptime: ${upHours}h ${upMins}m`,
147
+ `Memory: ${info.memory_mb.rss} MB RSS, ${info.memory_mb.heapUsed}/${info.memory_mb.heapTotal} MB heap`,
148
+ "",
149
+ "Instances:",
150
+ ];
151
+ for (const inst of info.instances) {
152
+ const icon = inst.status === "running" ? "🟢" : inst.status === "crashed" ? "🔴" : "⚪";
153
+ const ipc = inst.ipc ? "✓" : "✗";
154
+ let detail = `${icon} ${inst.name} [IPC:${ipc}] ${formatCents(inst.costCents)}`;
155
+ if (inst.rateLimits) {
156
+ detail += ` (5h:${inst.rateLimits.five_hour_pct}% 7d:${inst.rateLimits.seven_day_pct}%)`;
157
+ }
158
+ lines.push(detail);
159
+ }
160
+ if (info.fleet_cost_limit_cents > 0) {
161
+ lines.push("");
162
+ lines.push(`Fleet cost: ${formatCents(info.fleet_cost_cents)} / ${formatCents(info.fleet_cost_limit_cents)} daily`);
163
+ }
164
+ await adapter.sendText(msg.chatId, lines.join("\n"), { threadId: msg.threadId });
165
+ }
166
+ async handleUpdateCommand(msg) {
167
+ const adapter = this.getReplyAdapter(msg);
168
+ if (!adapter)
169
+ return;
170
+ const chatId = msg.chatId;
171
+ const threadId = msg.threadId;
172
+ // Access control — only allowed users can trigger update; empty = disabled
173
+ const allowed = this.ctx.fleetConfig?.channel?.access?.allowed_users ?? [];
174
+ if (allowed.length === 0) {
175
+ await adapter.sendText(chatId, "⛔ /update disabled — no allowed_users configured", { threadId });
176
+ return;
177
+ }
178
+ if (!allowed.some(u => String(u) === String(msg.userId))) {
179
+ await adapter.sendText(chatId, "⛔ Not authorized", { threadId });
180
+ return;
181
+ }
182
+ await adapter.sendText(chatId, "📦 Updating AgEnD...", { threadId });
183
+ try {
184
+ await execAsync("npm install -g @suzuke/agend@latest", { timeout: 120_000 });
185
+ }
186
+ catch {
187
+ await adapter.sendText(chatId, "❌ npm install failed. Try manually: npm install -g @suzuke/agend@latest", { threadId });
188
+ return;
189
+ }
190
+ await adapter.sendText(chatId, "✅ Updated. Restarting service...", { threadId });
191
+ await new Promise(r => setTimeout(r, 1000));
192
+ const label = "com.agend.fleet";
193
+ const plat = detectPlatform();
194
+ if (plat === "macos") {
195
+ const plistPath = join(homedir(), "Library/LaunchAgents", `${label}.plist`);
196
+ if (existsSync(plistPath)) {
197
+ const uid = process.getuid?.() ?? 501;
198
+ try {
199
+ await execAsync(`launchctl kickstart -k gui/${uid}/${label}`, { timeout: 15_000 });
200
+ return;
201
+ }
202
+ catch {
203
+ await adapter.sendText(chatId, "⚠️ Failed to restart launchd service", { threadId });
204
+ return;
205
+ }
206
+ }
207
+ }
208
+ else {
209
+ try {
210
+ await execAsync(`systemctl --user restart ${label}`, { timeout: 15_000 });
211
+ return;
212
+ }
213
+ catch { /* no systemd service */ }
214
+ }
215
+ const pidPath = join(this.ctx.dataDir, "fleet.pid");
216
+ if (existsSync(pidPath)) {
217
+ const pid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
218
+ try {
219
+ process.kill(pid, "SIGUSR1");
220
+ }
221
+ catch {
222
+ await adapter.sendText(chatId, "⚠️ Fleet not running", { threadId });
223
+ }
224
+ }
225
+ else {
226
+ await adapter.sendText(chatId, "⚠️ No service or running fleet found", { threadId });
227
+ }
228
+ }
229
+ /** Reply with redirect when message arrives in an unbound topic */
230
+ async handleUnboundTopic(msg) {
231
+ const adapter = this.getReplyAdapter(msg);
232
+ if (!adapter)
233
+ return;
234
+ await adapter.sendText(msg.chatId, "This topic is not bound to an instance. Ask the General assistant to create one with create_instance.", { threadId: msg.threadId });
235
+ }
236
+ /** Handle topic deletion — stop daemon and remove from config */
237
+ async handleTopicDeleted(threadId) {
238
+ const target = this.ctx.routingTable.get(threadId);
239
+ if (!target)
240
+ return;
241
+ if (target.kind === "general") {
242
+ this.ctx.logger.debug({ instanceName: target.name, threadId }, "Ignoring delete event for General topic");
243
+ return;
244
+ }
245
+ this.ctx.logger.info({ instanceName: target.name, threadId }, "Topic deleted — auto-unbinding");
246
+ await this.ctx.removeInstance(target.name);
247
+ }
248
+ /** Create instance config, save fleet.yaml, start daemon, connect IPC. */
249
+ async bindAndStart(dirPath, topicId) {
250
+ if (!this.ctx.fleetConfig)
251
+ throw new Error("Fleet config not loaded");
252
+ const instanceName = `${sanitizeInstanceName(basename(dirPath))}-t${topicId}`;
253
+ this.ctx.fleetConfig.instances[instanceName] = {
254
+ working_directory: dirPath,
255
+ topic_id: topicId,
256
+ restart_policy: this.ctx.fleetConfig.defaults.restart_policy ?? DEFAULT_INSTANCE_CONFIG.restart_policy,
257
+ context_guardian: this.ctx.fleetConfig.defaults.context_guardian ?? DEFAULT_INSTANCE_CONFIG.context_guardian,
258
+ log_level: this.ctx.fleetConfig.defaults.log_level ?? DEFAULT_INSTANCE_CONFIG.log_level,
259
+ };
260
+ this.ctx.saveFleetConfig();
261
+ this.ctx.routingTable.set(String(topicId), { kind: "instance", name: instanceName });
262
+ // startInstance awaits lifecycle.start → daemon.start (IPC listening) →
263
+ // connectIpcToInstance. By the time it resolves, IPC is already wired —
264
+ // the previous code's 5s sleep + second connect was leftover paranoia.
265
+ await this.ctx.startInstance(instanceName, this.ctx.fleetConfig.instances[instanceName], true);
266
+ this.ctx.logger.info({ instanceName, topicId }, "Topic bound and started");
267
+ return instanceName;
268
+ }
269
+ /** Create Telegram topics for instances that don't have topic_id */
270
+ async autoCreateTopics() {
271
+ if (!this.ctx.fleetConfig?.channel?.group_id)
272
+ return;
273
+ const botToken = process.env[this.ctx.fleetConfig.channel.bot_token_env];
274
+ if (!botToken)
275
+ return;
276
+ let configChanged = false;
277
+ for (const [name, config] of Object.entries(this.ctx.fleetConfig.instances)) {
278
+ if (config.topic_id != null)
279
+ continue;
280
+ // General topic: use Discord general_channel_id if available, else Telegram thread_id = 1
281
+ if (config.general_topic) {
282
+ const ch = this.ctx.fleetConfig?.channel;
283
+ if (name.includes("telegram")) {
284
+ config.topic_id = 1;
285
+ }
286
+ else if (name.includes("discord") && ch?.options?.general_channel_id) {
287
+ config.topic_id = ch.options.general_channel_id;
288
+ }
289
+ else {
290
+ // Default: use discord general_channel_id if available, else Telegram thread_id 1
291
+ const discordGeneralId = ch?.options?.general_channel_id;
292
+ config.topic_id = discordGeneralId || 1;
293
+ }
294
+ configChanged = true;
295
+ this.ctx.logger.info({ name, topicId: config.topic_id }, "Bound to General topic");
296
+ continue;
297
+ }
298
+ try {
299
+ const topicName = basename(config.working_directory);
300
+ const threadId = await this.ctx.createForumTopic(topicName);
301
+ config.topic_id = threadId;
302
+ configChanged = true;
303
+ this.ctx.logger.info({ name, topicId: config.topic_id, topicName }, "Auto-created Telegram topic");
304
+ }
305
+ catch (err) {
306
+ this.ctx.logger.warn({ name, err }, "Failed to auto-create topic");
307
+ }
308
+ }
309
+ if (configChanged) {
310
+ this.ctx.saveFleetConfig();
311
+ }
312
+ }
313
+ /** Register bot commands in Telegram command menu */
314
+ async registerBotCommands() {
315
+ // Register bot commands for all Telegram adapters (channels[] support)
316
+ const channels = this.ctx.fleetConfig?.channels ?? (this.ctx.fleetConfig?.channel ? [this.ctx.fleetConfig.channel] : []);
317
+ const telegramChannels = channels.filter(ch => ch.type === "telegram");
318
+ if (telegramChannels.length === 0)
319
+ return;
320
+ for (const ch of telegramChannels) {
321
+ const botToken = process.env[ch.bot_token_env];
322
+ if (!botToken || !ch.group_id)
323
+ continue;
324
+ try {
325
+ // Register admin commands for the forum group
326
+ await fetch(`https://api.telegram.org/bot${botToken}/setMyCommands`, {
327
+ method: "POST",
328
+ headers: { "Content-Type": "application/json" },
329
+ body: JSON.stringify({
330
+ commands: [
331
+ { command: "status", description: "Show fleet status and costs" },
332
+ { command: "restart", description: "Graceful restart all instances" },
333
+ { command: "sysinfo", description: "System diagnostics" },
334
+ ],
335
+ scope: { type: "chat", chat_id: ch.group_id },
336
+ }),
337
+ });
338
+ // Register classic bot commands for private chats and all groups
339
+ await fetch(`https://api.telegram.org/bot${botToken}/setMyCommands`, {
340
+ method: "POST",
341
+ headers: { "Content-Type": "application/json" },
342
+ body: JSON.stringify({
343
+ commands: [
344
+ { command: "start", description: "Start an agent in this chat" },
345
+ { command: "stop", description: "Stop the agent" },
346
+ { command: "chat", description: "Talk to the agent" },
347
+ ],
348
+ scope: { type: "default" },
349
+ }),
350
+ });
351
+ this.ctx.logger.info({ adapterId: ch.id ?? ch.type }, "Registered bot commands: /status (forum), /start /stop /chat (default)");
352
+ }
353
+ catch (err) {
354
+ this.ctx.logger.warn({ err, adapterId: ch.id ?? ch.type }, "Failed to register bot commands (non-fatal)");
355
+ }
356
+ }
357
+ }
358
+ }
359
+ //# sourceMappingURL=topic-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"topic-commands.js","sourceRoot":"","sources":["../src/topic-commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { EventEmitter } from "node:events";
2
+ import type { Logger } from "./logger.js";
3
+ export declare class TranscriptMonitor extends EventEmitter {
4
+ private instanceDir;
5
+ private logger;
6
+ private fd;
7
+ private byteOffset;
8
+ private transcriptPath;
9
+ private pollTimer;
10
+ private offsetFile;
11
+ private polling;
12
+ constructor(instanceDir: string, logger: Logger);
13
+ private loadOffset;
14
+ private saveOffset;
15
+ resolveTranscriptPath(): Promise<string | null>;
16
+ pollIncrement(): Promise<void>;
17
+ private _doPoll;
18
+ private processEntry;
19
+ startPolling(intervalMs?: number): void;
20
+ stop(): void;
21
+ setTranscriptPath(path: string): void;
22
+ resetOffset(): void;
23
+ }
@@ -0,0 +1,164 @@
1
+ import { EventEmitter } from "node:events";
2
+ import { open, stat } from "node:fs/promises";
3
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
4
+ import { join } from "node:path";
5
+ export class TranscriptMonitor extends EventEmitter {
6
+ instanceDir;
7
+ logger;
8
+ fd = null;
9
+ byteOffset = 0;
10
+ transcriptPath = null;
11
+ pollTimer = null;
12
+ offsetFile;
13
+ polling = false; // reentry guard for pollIncrement
14
+ constructor(instanceDir, logger) {
15
+ super();
16
+ this.instanceDir = instanceDir;
17
+ this.logger = logger;
18
+ this.offsetFile = join(instanceDir, "transcript-offset");
19
+ this.loadOffset();
20
+ }
21
+ loadOffset() {
22
+ try {
23
+ if (existsSync(this.offsetFile)) {
24
+ const data = JSON.parse(readFileSync(this.offsetFile, "utf-8"));
25
+ this.byteOffset = data.offset ?? 0;
26
+ this.transcriptPath = data.path ?? null;
27
+ }
28
+ }
29
+ catch {
30
+ // Start fresh if corrupt
31
+ }
32
+ }
33
+ saveOffset() {
34
+ try {
35
+ writeFileSync(this.offsetFile, JSON.stringify({
36
+ offset: this.byteOffset,
37
+ path: this.transcriptPath,
38
+ }));
39
+ }
40
+ catch {
41
+ // Non-critical — will re-read some entries on restart
42
+ }
43
+ }
44
+ async resolveTranscriptPath() {
45
+ const statusFile = join(this.instanceDir, "statusline.json");
46
+ if (existsSync(statusFile)) {
47
+ try {
48
+ const data = JSON.parse(readFileSync(statusFile, "utf-8"));
49
+ if (data.transcript_path)
50
+ return data.transcript_path;
51
+ }
52
+ catch {
53
+ // Status file may be partially written — retry on next poll
54
+ }
55
+ }
56
+ return null;
57
+ }
58
+ async pollIncrement() {
59
+ // Reentry guard: setInterval keeps firing even when the previous poll is
60
+ // still awaiting stat/read. Two concurrent runs would race on byteOffset
61
+ // (both could read the same byte range and emit duplicate entries).
62
+ if (this.polling)
63
+ return;
64
+ this.polling = true;
65
+ try {
66
+ await this._doPoll();
67
+ }
68
+ finally {
69
+ this.polling = false;
70
+ }
71
+ }
72
+ async _doPoll() {
73
+ if (!this.transcriptPath) {
74
+ this.transcriptPath = await this.resolveTranscriptPath();
75
+ if (!this.transcriptPath)
76
+ return;
77
+ // If we have a saved offset for a different path, reset
78
+ // If no saved offset, skip to end (first run)
79
+ if (this.byteOffset === 0) {
80
+ try {
81
+ const initial = await stat(this.transcriptPath);
82
+ this.byteOffset = initial.size;
83
+ this.saveOffset();
84
+ return;
85
+ }
86
+ catch {
87
+ return;
88
+ }
89
+ }
90
+ }
91
+ if (!existsSync(this.transcriptPath))
92
+ return;
93
+ try {
94
+ const stats = await stat(this.transcriptPath);
95
+ if (stats.size <= this.byteOffset)
96
+ return;
97
+ const fh = await open(this.transcriptPath, "r");
98
+ try {
99
+ const length = stats.size - this.byteOffset;
100
+ const buffer = Buffer.alloc(length);
101
+ await fh.read(buffer, 0, length, this.byteOffset);
102
+ this.byteOffset = stats.size;
103
+ const text = buffer.toString("utf-8");
104
+ for (const line of text.split("\n")) {
105
+ if (!line.trim())
106
+ continue;
107
+ try {
108
+ const entry = JSON.parse(line);
109
+ this.processEntry(entry);
110
+ }
111
+ catch {
112
+ // Malformed JSONL line in transcript — skip
113
+ }
114
+ }
115
+ this.saveOffset();
116
+ }
117
+ finally {
118
+ await fh.close();
119
+ }
120
+ }
121
+ catch (err) {
122
+ this.logger.debug({ err }, "TranscriptMonitor poll error");
123
+ }
124
+ }
125
+ processEntry(entry) {
126
+ const msg = entry.message;
127
+ if (!msg?.role || !msg?.content)
128
+ return;
129
+ const contents = Array.isArray(msg.content) ? msg.content : [{ type: "text", text: msg.content }];
130
+ for (const block of contents) {
131
+ if (block.type === "tool_use") {
132
+ this.emit("tool_use", block.name ?? "unknown", block.input ?? {});
133
+ }
134
+ else if (block.type === "tool_result") {
135
+ this.emit("tool_result", block.tool_use_id ?? "unknown", block.content);
136
+ }
137
+ else if (block.type === "text" && msg.role === "assistant" && block.text?.trim()) {
138
+ this.emit("assistant_text", block.text);
139
+ }
140
+ }
141
+ }
142
+ startPolling(intervalMs = 2000) {
143
+ this.pollTimer = setInterval(() => this.pollIncrement(), intervalMs);
144
+ }
145
+ stop() {
146
+ if (this.pollTimer) {
147
+ clearInterval(this.pollTimer);
148
+ this.pollTimer = null;
149
+ }
150
+ this.saveOffset();
151
+ }
152
+ setTranscriptPath(path) {
153
+ if (this.transcriptPath !== path) {
154
+ this.resetOffset();
155
+ }
156
+ this.transcriptPath = path;
157
+ }
158
+ resetOffset() {
159
+ this.byteOffset = 0;
160
+ this.transcriptPath = null;
161
+ this.saveOffset();
162
+ }
163
+ }
164
+ //# sourceMappingURL=transcript-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript-monitor.js","sourceRoot":"","sources":["../src/transcript-monitor.ts"],"names":[],"mappings":"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"}