svamp-cli 0.1.29 → 0.1.31

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 (98) hide show
  1. package/dist/cli.mjs +8 -8
  2. package/dist/{commands-CgT3AgJ0.mjs → commands-78RHC879.mjs} +162 -55
  3. package/dist/index.mjs +1 -1
  4. package/dist/{package-DPXkSwHu.mjs → package-BtoCHVOd.mjs} +1 -1
  5. package/dist/{run-BCSNMhiz.mjs → run-dBWhjQRf.mjs} +66 -61
  6. package/package.json +1 -1
  7. package/dist/agent-cli.mjs +0 -453
  8. package/dist/commands-1CYZC6Xh.mjs +0 -481
  9. package/dist/commands-B1DcpgLW.mjs +0 -481
  10. package/dist/commands-BGmdgMAC.mjs +0 -485
  11. package/dist/commands-BOeSil-P.mjs +0 -459
  12. package/dist/commands-BU4GZQuH.mjs +0 -481
  13. package/dist/commands-Ba66PxtQ.mjs +0 -481
  14. package/dist/commands-C0-xqIIc.mjs +0 -481
  15. package/dist/commands-C7Qy5n6d.mjs +0 -481
  16. package/dist/commands-CKTIJoV0.mjs +0 -636
  17. package/dist/commands-CKpC8R9T.mjs +0 -481
  18. package/dist/commands-CNqOjR1y.mjs +0 -481
  19. package/dist/commands-CVKh1tWr.mjs +0 -485
  20. package/dist/commands-CYBblX73.mjs +0 -485
  21. package/dist/commands-CZBYmj16.mjs +0 -485
  22. package/dist/commands-CcWIvCA4.mjs +0 -481
  23. package/dist/commands-Cfwf-cQG.mjs +0 -481
  24. package/dist/commands-CtO1WRt4.mjs +0 -862
  25. package/dist/commands-DCNO2m66.mjs +0 -471
  26. package/dist/commands-DDB3y1L1.mjs +0 -611
  27. package/dist/commands-DRIFvhmC.mjs +0 -481
  28. package/dist/commands-DXmw2dzy.mjs +0 -481
  29. package/dist/commands-DkSvlKFF.mjs +0 -485
  30. package/dist/commands-DnDd4Sew.mjs +0 -481
  31. package/dist/commands-DnpnAFQW.mjs +0 -485
  32. package/dist/commands-Do-TVYFm.mjs +0 -481
  33. package/dist/commands-GEXri0yz.mjs +0 -484
  34. package/dist/commands-Kzm0_XNH.mjs +0 -481
  35. package/dist/commands-MQvNbIid.mjs +0 -481
  36. package/dist/commands-_uCC3U1U.mjs +0 -481
  37. package/dist/commands-y2WG29W9.mjs +0 -485
  38. package/dist/hyphaClient-DLkclazm.mjs +0 -39
  39. package/dist/package-ASJ9pMHk.mjs +0 -60
  40. package/dist/package-B2FOzHaM.mjs +0 -57
  41. package/dist/package-Bk_PFVA0.mjs +0 -57
  42. package/dist/package-Bnij-ZtR.mjs +0 -57
  43. package/dist/package-BtRbHfjz.mjs +0 -57
  44. package/dist/package-C5B0twb8.mjs +0 -57
  45. package/dist/package-CC5d8_0L.mjs +0 -57
  46. package/dist/package-CCJ045H0.mjs +0 -60
  47. package/dist/package-CKOQ5lA7.mjs +0 -57
  48. package/dist/package-CS219SXn.mjs +0 -57
  49. package/dist/package-Cd-9ktpd.mjs +0 -60
  50. package/dist/package-CgBD49cA.mjs +0 -57
  51. package/dist/package-CvnNnsm7.mjs +0 -60
  52. package/dist/package-DpqWz9Cr.mjs +0 -60
  53. package/dist/package-JqEt5Ib4.mjs +0 -57
  54. package/dist/package-k18Su1iE.mjs +0 -58
  55. package/dist/package-nzkXV1aM.mjs +0 -57
  56. package/dist/package-pNo6GC3a.mjs +0 -60
  57. package/dist/package-pZp14zKI.mjs +0 -57
  58. package/dist/run-4fyJcaRE.mjs +0 -3856
  59. package/dist/run-B6oqR83K.mjs +0 -4631
  60. package/dist/run-BI32lPRK.mjs +0 -3870
  61. package/dist/run-BQHneHfW.mjs +0 -3834
  62. package/dist/run-Bb4fyIWZ.mjs +0 -3812
  63. package/dist/run-BglwnB-A.mjs +0 -3889
  64. package/dist/run-BjVWuitO.mjs +0 -3919
  65. package/dist/run-BzUE-JUT.mjs +0 -3708
  66. package/dist/run-BzqS97Sx.mjs +0 -3666
  67. package/dist/run-C6snRxyh.mjs +0 -3826
  68. package/dist/run-C8CI8Ujj.mjs +0 -3693
  69. package/dist/run-CL-FS4Yc.mjs +0 -3933
  70. package/dist/run-CS1Z4GcM.mjs +0 -3786
  71. package/dist/run-CT7uizQo.mjs +0 -4492
  72. package/dist/run-CUIj4xbE.mjs +0 -4880
  73. package/dist/run-CW26vPqj.mjs +0 -3919
  74. package/dist/run-CkTufc0D.mjs +0 -3875
  75. package/dist/run-Cmostc0S.mjs +0 -3902
  76. package/dist/run-Cp3kKdzm.mjs +0 -3865
  77. package/dist/run-CuN6K7pN.mjs +0 -4824
  78. package/dist/run-D0bCTY72.mjs +0 -3816
  79. package/dist/run-D4N6FQON.mjs +0 -4673
  80. package/dist/run-D4dlA0jo.mjs +0 -4813
  81. package/dist/run-DMD0N00A.mjs +0 -4737
  82. package/dist/run-DMW8ibIw.mjs +0 -3958
  83. package/dist/run-DO52unxE.mjs +0 -3950
  84. package/dist/run-DQ5FOQ_c.mjs +0 -4788
  85. package/dist/run-DT7FgL8L.mjs +0 -4339
  86. package/dist/run-DYhBROuo.mjs +0 -3934
  87. package/dist/run-DZmxHj-e.mjs +0 -4774
  88. package/dist/run-DjfPjgOb.mjs +0 -3904
  89. package/dist/run-DlL4JALM.mjs +0 -4719
  90. package/dist/run-Dp2JPkGI.mjs +0 -3913
  91. package/dist/run-Dptna3Je.mjs +0 -3867
  92. package/dist/run-DwK3dfHd.mjs +0 -3875
  93. package/dist/run-M_SMt96j.mjs +0 -3913
  94. package/dist/run-MlpxQUPN.mjs +0 -3869
  95. package/dist/run-PuTIelbv.mjs +0 -3706
  96. package/dist/run-h37iSCUB.mjs +0 -3934
  97. package/dist/run-lpV0oguG.mjs +0 -3897
  98. package/dist/run-oHmTMcv8.mjs +0 -4721
@@ -1,481 +0,0 @@
1
- import { existsSync, readFileSync } from 'node:fs';
2
- import { join } from 'node:path';
3
- import os from 'node:os';
4
- import { c as connectToHypha } from './run-DMW8ibIw.mjs';
5
- import 'os';
6
- import 'fs/promises';
7
- import 'fs';
8
- import 'path';
9
- import 'url';
10
- import 'child_process';
11
- import 'crypto';
12
- import 'node:crypto';
13
- import 'node:child_process';
14
- import '@agentclientprotocol/sdk';
15
-
16
- const SVAMP_HOME = process.env.SVAMP_HOME || join(os.homedir(), ".svamp");
17
- const DAEMON_STATE_FILE = join(SVAMP_HOME, "daemon.state.json");
18
- const ENV_FILE = join(SVAMP_HOME, ".env");
19
- function loadDotEnv() {
20
- if (!existsSync(ENV_FILE)) return;
21
- const lines = readFileSync(ENV_FILE, "utf-8").split("\n");
22
- for (const line of lines) {
23
- const trimmed = line.trim();
24
- if (!trimmed || trimmed.startsWith("#")) continue;
25
- const eqIdx = trimmed.indexOf("=");
26
- if (eqIdx === -1) continue;
27
- const key = trimmed.slice(0, eqIdx).trim();
28
- const value = trimmed.slice(eqIdx + 1).trim().replace(/^["']|["']$/g, "");
29
- if (!process.env[key]) {
30
- process.env[key] = value;
31
- }
32
- }
33
- }
34
- function readDaemonState() {
35
- if (!existsSync(DAEMON_STATE_FILE)) return null;
36
- try {
37
- return JSON.parse(readFileSync(DAEMON_STATE_FILE, "utf-8"));
38
- } catch {
39
- return null;
40
- }
41
- }
42
- function isDaemonAlive(state) {
43
- try {
44
- process.kill(state.pid, 0);
45
- return true;
46
- } catch {
47
- return false;
48
- }
49
- }
50
- async function connectAndGetMachine() {
51
- loadDotEnv();
52
- const state = readDaemonState();
53
- if (!state || !isDaemonAlive(state)) {
54
- console.error('Daemon is not running. Start it with "svamp daemon start".');
55
- process.exit(1);
56
- }
57
- const serverUrl = process.env.HYPHA_SERVER_URL || state.hyphaServerUrl;
58
- const token = process.env.HYPHA_TOKEN;
59
- if (!serverUrl) {
60
- console.error('No Hypha server URL. Run "svamp login <url>" first.');
61
- process.exit(1);
62
- }
63
- const origLog = console.log;
64
- const origWarn = console.warn;
65
- const origInfo = console.info;
66
- const origError = console.error;
67
- const stdoutWrite = process.stdout.write.bind(process.stdout);
68
- const stderrWrite = process.stderr.write.bind(process.stderr);
69
- const isHyphaLog = (chunk) => typeof chunk === "string" && (chunk.includes("WebSocket connection") || chunk.includes("Connection established") || chunk.includes("registering service built-in") || chunk.includes("registered service") || chunk.includes("registered all") || chunk.includes("Subscribing to client_") || chunk.includes("subscribed to client_") || chunk.includes("subscribe to client_") || chunk.includes("Cleaning up all sessions") || chunk.includes("WebSocket connection disconnected") || chunk.includes("local RPC disconnection") || chunk.includes("Timeout registering service") || chunk.includes("Failed to subscribe to client_disconnected") || chunk.includes("Timeout subscribing to client_disconnected"));
70
- console.log = () => {
71
- };
72
- console.warn = () => {
73
- };
74
- console.info = () => {
75
- };
76
- console.error = (...args) => {
77
- if (args.some((a) => isHyphaLog(a))) return;
78
- origError(...args);
79
- };
80
- process.stdout.write = (chunk, ...args) => {
81
- if (isHyphaLog(chunk)) return true;
82
- return stdoutWrite(chunk, ...args);
83
- };
84
- process.stderr.write = (chunk, ...args) => {
85
- if (isHyphaLog(chunk)) return true;
86
- return stderrWrite(chunk, ...args);
87
- };
88
- const restoreConsole = () => {
89
- console.log = origLog;
90
- console.warn = origWarn;
91
- console.info = origInfo;
92
- console.error = origError;
93
- };
94
- let server;
95
- try {
96
- server = await connectToHypha({
97
- serverUrl,
98
- token,
99
- name: "svamp-session-cli"
100
- });
101
- } catch (err) {
102
- restoreConsole();
103
- console.error(`Failed to connect to Hypha: ${err.message}`);
104
- process.exit(1);
105
- }
106
- let machine;
107
- if (state.machineId) {
108
- try {
109
- machine = await server.getService(`svamp-machine-${state.machineId}`);
110
- } catch {
111
- }
112
- }
113
- if (!machine) {
114
- try {
115
- const services = await server.listServices();
116
- const machineServices = services.filter((svc) => {
117
- const sid = svc.id || svc.name || "";
118
- return sid.includes("svamp-machine-");
119
- });
120
- if (machineServices.length === 0) {
121
- restoreConsole();
122
- console.error("No machine service found. Is the daemon registered on Hypha?");
123
- await server.disconnect();
124
- process.exit(1);
125
- }
126
- const svcId = machineServices[0].id || machineServices[0].name;
127
- machine = await server.getService(svcId);
128
- } catch (err) {
129
- restoreConsole();
130
- console.error(`Failed to discover machine service: ${err.message}`);
131
- await server.disconnect();
132
- process.exit(1);
133
- }
134
- }
135
- restoreConsole();
136
- return { server, machine };
137
- }
138
- function resolveSessionId(sessions, partial) {
139
- const exact = sessions.find((s) => s.sessionId === partial);
140
- if (exact) return exact;
141
- const matches = sessions.filter((s) => s.sessionId.startsWith(partial));
142
- if (matches.length === 1) return matches[0];
143
- if (matches.length === 0) {
144
- console.error(`No session found matching: ${partial}`);
145
- console.error('Run "svamp session list" to see active sessions.');
146
- process.exit(1);
147
- }
148
- console.error(`Ambiguous session ID "${partial}". Matches:`);
149
- for (const s of matches) {
150
- console.error(` ${s.sessionId}`);
151
- }
152
- process.exit(1);
153
- }
154
- function truncate(str, max) {
155
- if (str.length <= max) return str;
156
- return "..." + str.slice(str.length - max + 3);
157
- }
158
- function renderMessage(msg) {
159
- const content = msg.content;
160
- if (!content) return;
161
- const role = content.role;
162
- if (role === "user") {
163
- const data = content.content;
164
- let text;
165
- if (typeof data === "string") {
166
- try {
167
- const parsed = JSON.parse(data);
168
- text = parsed?.text || parsed?.content?.text || data;
169
- } catch {
170
- text = data;
171
- }
172
- } else if (data?.text) {
173
- text = data.text;
174
- } else if (data?.type === "text") {
175
- text = data.text || "";
176
- } else {
177
- text = typeof data === "object" ? JSON.stringify(data) : String(data || "");
178
- }
179
- console.log(`\x1B[36m[user]\x1B[0m ${text}`);
180
- } else if (role === "agent" || role === "assistant") {
181
- const data = content.content?.data || content.content;
182
- if (!data) return;
183
- if (data.type === "assistant" && Array.isArray(data.content)) {
184
- for (const block of data.content) {
185
- if (block.type === "text" && block.text) {
186
- process.stdout.write(block.text);
187
- if (!block.text.endsWith("\n")) process.stdout.write("\n");
188
- } else if (block.type === "tool_use") {
189
- const argsStr = JSON.stringify(block.input || {}).slice(0, 120);
190
- console.log(`\x1B[33m[tool]\x1B[0m ${block.name}(${argsStr})`);
191
- } else if (block.type === "tool_result") {
192
- const resultStr = typeof block.content === "string" ? block.content : JSON.stringify(block.content || "");
193
- console.log(`\x1B[90m[result]\x1B[0m ${resultStr.slice(0, 200)}${resultStr.length > 200 ? "..." : ""}`);
194
- } else if (block.type === "thinking") {
195
- const text = block.thinking || block.text || "";
196
- if (text) console.log(`\x1B[90m[thinking] ${text.slice(0, 200)}\x1B[0m`);
197
- }
198
- }
199
- } else if (data.type === "result") {
200
- if (data.result) console.log(`\x1B[32m[done]\x1B[0m ${data.result}`);
201
- } else if (data.type === "output") {
202
- const inner = data.data;
203
- if (inner?.type === "assistant" && Array.isArray(inner.content)) {
204
- for (const block of inner.content) {
205
- if (block.type === "text" && block.text) {
206
- process.stdout.write(block.text);
207
- if (!block.text.endsWith("\n")) process.stdout.write("\n");
208
- } else if (block.type === "tool_use") {
209
- const argsStr = JSON.stringify(block.input || {}).slice(0, 120);
210
- console.log(`\x1B[33m[tool]\x1B[0m ${block.name}(${argsStr})`);
211
- } else if (block.type === "tool_result") {
212
- const resultStr = typeof block.content === "string" ? block.content : JSON.stringify(block.content || "");
213
- console.log(`\x1B[90m[result]\x1B[0m ${resultStr.slice(0, 200)}${resultStr.length > 200 ? "..." : ""}`);
214
- }
215
- }
216
- } else if (inner?.type === "result") {
217
- if (inner.result) console.log(`\x1B[32m[done]\x1B[0m ${inner.result}`);
218
- }
219
- }
220
- } else if (role === "session") {
221
- const data = content.content?.data;
222
- if (data?.type === "system" && data?.subtype === "init") {
223
- console.log(`\x1B[90m[session init]\x1B[0m`);
224
- }
225
- }
226
- }
227
- async function sessionList() {
228
- const { server, machine } = await connectAndGetMachine();
229
- try {
230
- const sessions = await machine.listSessions();
231
- if (sessions.length === 0) {
232
- console.log("No active sessions.");
233
- return;
234
- }
235
- const enriched = [];
236
- for (const s of sessions) {
237
- let flavor = "claude";
238
- let name = "";
239
- if (s.metadata) {
240
- flavor = s.metadata.flavor || "claude";
241
- name = s.metadata.name || "";
242
- }
243
- if (!name && s.active) {
244
- try {
245
- const svc = await server.getService(`svamp-session-${s.sessionId}`);
246
- const { metadata } = await svc.getMetadata();
247
- flavor = metadata?.flavor || flavor;
248
- name = metadata?.name || "";
249
- } catch {
250
- }
251
- }
252
- enriched.push({ ...s, flavor, name });
253
- }
254
- const header = `${"ID".padEnd(10)} ${"AGENT".padEnd(10)} ${"STATUS".padEnd(9)} ${"NAME".padEnd(25)} ${"DIRECTORY".padEnd(35)}`;
255
- console.log(header);
256
- console.log("-".repeat(header.length));
257
- for (const s of enriched) {
258
- const id = s.sessionId.slice(0, 8);
259
- const agent = (s.flavor || "claude").padEnd(10);
260
- const status = s.active ? "\x1B[32mactive\x1B[0m " : "\x1B[90minactive\x1B[0m";
261
- const name = truncate(s.name || "-", 25).padEnd(25);
262
- const dir = truncate(s.directory || "-", 33).padEnd(35);
263
- console.log(`${id.padEnd(10)} ${agent} ${status} ${name} ${dir}`);
264
- }
265
- } finally {
266
- await server.disconnect();
267
- }
268
- }
269
- async function sessionSpawn(agent, directory) {
270
- const { server, machine } = await connectAndGetMachine();
271
- try {
272
- console.log(`Spawning ${agent} session in ${directory}...`);
273
- const result = await machine.spawnSession({
274
- directory,
275
- agent
276
- });
277
- if (result.type === "success") {
278
- console.log(`Session started: ${result.sessionId}`);
279
- if (result.message) console.log(` ${result.message}`);
280
- } else if (result.type === "requestToApproveDirectoryCreation") {
281
- console.error(`Directory ${result.directory} does not exist. Create it first or use an existing directory.`);
282
- process.exit(1);
283
- } else {
284
- console.error(`Failed: ${result.errorMessage || "Unknown error"}`);
285
- process.exit(1);
286
- }
287
- } finally {
288
- await server.disconnect();
289
- }
290
- }
291
- async function sessionStop(sessionId) {
292
- const { server, machine } = await connectAndGetMachine();
293
- try {
294
- const sessions = await machine.listSessions();
295
- const match = resolveSessionId(sessions, sessionId);
296
- const success = await machine.stopSession(match.sessionId);
297
- if (success) {
298
- console.log(`Session ${match.sessionId.slice(0, 8)} stopped.`);
299
- } else {
300
- console.error("Failed to stop session (not found on daemon).");
301
- process.exit(1);
302
- }
303
- } finally {
304
- await server.disconnect();
305
- }
306
- }
307
- async function sessionInfo(sessionId) {
308
- const { server, machine } = await connectAndGetMachine();
309
- try {
310
- const sessions = await machine.listSessions();
311
- const match = resolveSessionId(sessions, sessionId);
312
- const fullId = match.sessionId;
313
- let metadata = {};
314
- let activity = {};
315
- try {
316
- const svc = await server.getService(`svamp-session-${fullId}`);
317
- const metaResult = await svc.getMetadata();
318
- metadata = metaResult.metadata || {};
319
- activity = await svc.getActivityState();
320
- } catch {
321
- }
322
- console.log(`Session: ${fullId}`);
323
- console.log(`Agent: ${metadata.flavor || "claude"}`);
324
- console.log(`Name: ${metadata.name || "(unnamed)"}`);
325
- console.log(`Directory: ${metadata.path || match.directory || "-"}`);
326
- console.log(`Host: ${metadata.host || "-"}`);
327
- console.log(`State: ${metadata.lifecycleState || "unknown"}`);
328
- console.log(`Active: ${activity.active ?? "-"}`);
329
- console.log(`Thinking: ${activity.thinking ?? "-"}`);
330
- console.log(`Started by: ${metadata.startedBy || match.startedBy || "-"}`);
331
- if (metadata.summary?.text) {
332
- console.log(`Summary: ${metadata.summary.text}`);
333
- }
334
- if (metadata.claudeSessionId) {
335
- console.log(`Claude ID: ${metadata.claudeSessionId}`);
336
- }
337
- if (metadata.sessionLink?.url) {
338
- console.log(`Link: ${metadata.sessionLink.url}`);
339
- }
340
- } finally {
341
- await server.disconnect();
342
- }
343
- }
344
- async function sessionMessages(sessionId, last) {
345
- const { server, machine } = await connectAndGetMachine();
346
- try {
347
- const sessions = await machine.listSessions();
348
- const match = resolveSessionId(sessions, sessionId);
349
- const fullId = match.sessionId;
350
- const svc = await server.getService(`svamp-session-${fullId}`);
351
- const { messages } = await svc.getMessages(0, 1e3);
352
- const toShow = last ? messages.slice(-last) : messages;
353
- if (toShow.length === 0) {
354
- console.log("No messages yet.");
355
- return;
356
- }
357
- for (const msg of toShow) {
358
- renderMessage(msg);
359
- }
360
- } finally {
361
- await server.disconnect();
362
- }
363
- }
364
- async function sessionAttach(sessionId) {
365
- const { server, machine } = await connectAndGetMachine();
366
- const sessions = await machine.listSessions();
367
- const match = resolveSessionId(sessions, sessionId);
368
- const fullId = match.sessionId;
369
- let svc;
370
- try {
371
- svc = await server.getService(`svamp-session-${fullId}`);
372
- } catch (err) {
373
- console.error(`Could not find session service: ${err.message}`);
374
- await server.disconnect();
375
- process.exit(1);
376
- }
377
- const { metadata } = await svc.getMetadata();
378
- const flavor = metadata?.flavor || "claude";
379
- const name = metadata?.name || fullId.slice(0, 8);
380
- console.log(`Attached to ${flavor} session "${name}". Commands: /quit /abort /kill
381
- `);
382
- const seenMessageIds = /* @__PURE__ */ new Set();
383
- let replayDone = false;
384
- await svc.registerListener({
385
- onUpdate: (update) => {
386
- if (update.type === "new-message") {
387
- const msg = update.message;
388
- if (!msg?.id) return;
389
- if (seenMessageIds.has(msg.id)) return;
390
- seenMessageIds.add(msg.id);
391
- if (!replayDone) return;
392
- renderMessage(msg);
393
- } else if (update.type === "activity") {
394
- if (!replayDone) return;
395
- if (update.thinking) {
396
- process.stdout.write("\x1B[90m[thinking...]\x1B[0m\r");
397
- } else if (!update.active) {
398
- process.stdout.write("\n> ");
399
- }
400
- } else if (update.type === "update-session") ;
401
- }
402
- });
403
- await new Promise((r) => setTimeout(r, 500));
404
- replayDone = true;
405
- console.log(`\x1B[90m(${seenMessageIds.size} messages in history)\x1B[0m`);
406
- process.stdout.write("> ");
407
- const readline = await import('readline');
408
- const rl = readline.createInterface({
409
- input: process.stdin,
410
- output: process.stdout,
411
- terminal: true
412
- });
413
- rl.on("line", async (line) => {
414
- const trimmed = line.trim();
415
- if (!trimmed) {
416
- process.stdout.write("> ");
417
- return;
418
- }
419
- if (trimmed === "/quit" || trimmed === "/detach") {
420
- console.log("Detaching (session continues running)...");
421
- rl.close();
422
- await server.disconnect();
423
- process.exit(0);
424
- }
425
- if (trimmed === "/abort" || trimmed === "/cancel") {
426
- try {
427
- await svc.abort();
428
- console.log("Abort sent.");
429
- } catch (err) {
430
- console.error(`Abort failed: ${err.message}`);
431
- }
432
- process.stdout.write("> ");
433
- return;
434
- }
435
- if (trimmed === "/kill") {
436
- try {
437
- await svc.killSession();
438
- console.log("Session killed.");
439
- } catch (err) {
440
- console.error(`Kill failed: ${err.message}`);
441
- }
442
- rl.close();
443
- await server.disconnect();
444
- process.exit(0);
445
- }
446
- if (trimmed === "/info") {
447
- try {
448
- const { metadata: m } = await svc.getMetadata();
449
- const act = await svc.getActivityState();
450
- console.log(` Agent: ${m?.flavor || "claude"}, State: ${m?.lifecycleState || "?"}, Active: ${act?.active}, Thinking: ${act?.thinking}`);
451
- } catch (err) {
452
- console.error(`Info failed: ${err.message}`);
453
- }
454
- process.stdout.write("> ");
455
- return;
456
- }
457
- try {
458
- await svc.sendMessage(
459
- JSON.stringify({
460
- role: "user",
461
- content: { type: "text", text: trimmed }
462
- })
463
- );
464
- } catch (err) {
465
- console.error(`Send failed: ${err.message}`);
466
- process.stdout.write("> ");
467
- }
468
- });
469
- rl.on("close", async () => {
470
- await server.disconnect();
471
- process.exit(0);
472
- });
473
- process.on("SIGINT", async () => {
474
- console.log("\nDetaching (session continues running)...");
475
- rl.close();
476
- await server.disconnect();
477
- process.exit(0);
478
- });
479
- }
480
-
481
- export { sessionAttach, sessionInfo, sessionList, sessionMessages, sessionSpawn, sessionStop };