@relaymessenger/cli 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +139 -0
  3. package/claude-plugin/marketplace/.claude-plugin/marketplace.json +14 -0
  4. package/claude-plugin/marketplace/plugins/relay/.claude-plugin/plugin.json +18 -0
  5. package/claude-plugin/marketplace/plugins/relay/LICENSE +21 -0
  6. package/claude-plugin/marketplace/plugins/relay/README.md +173 -0
  7. package/claude-plugin/marketplace/plugins/relay/commands/configure.md +71 -0
  8. package/claude-plugin/marketplace/plugins/relay/runtime/server.mjs +26107 -0
  9. package/dist/api.d.ts +74 -0
  10. package/dist/api.d.ts.map +1 -0
  11. package/dist/api.js +129 -0
  12. package/dist/api.js.map +1 -0
  13. package/dist/claude-settings.d.ts +14 -0
  14. package/dist/claude-settings.d.ts.map +1 -0
  15. package/dist/claude-settings.js +47 -0
  16. package/dist/claude-settings.js.map +1 -0
  17. package/dist/cli.d.ts +3 -0
  18. package/dist/cli.d.ts.map +1 -0
  19. package/dist/cli.js +162 -0
  20. package/dist/cli.js.map +1 -0
  21. package/dist/codex.d.ts +25 -0
  22. package/dist/codex.d.ts.map +1 -0
  23. package/dist/codex.js +227 -0
  24. package/dist/codex.js.map +1 -0
  25. package/dist/doctor.d.ts +2 -0
  26. package/dist/doctor.d.ts.map +1 -0
  27. package/dist/doctor.js +122 -0
  28. package/dist/doctor.js.map +1 -0
  29. package/dist/engine/acp.d.ts +69 -0
  30. package/dist/engine/acp.d.ts.map +1 -0
  31. package/dist/engine/acp.js +402 -0
  32. package/dist/engine/acp.js.map +1 -0
  33. package/dist/engine/catalog.d.ts +26 -0
  34. package/dist/engine/catalog.d.ts.map +1 -0
  35. package/dist/engine/catalog.js +41 -0
  36. package/dist/engine/catalog.js.map +1 -0
  37. package/dist/engine/process.d.ts +12 -0
  38. package/dist/engine/process.d.ts.map +1 -0
  39. package/dist/engine/process.js +54 -0
  40. package/dist/engine/process.js.map +1 -0
  41. package/dist/engine/types.d.ts +57 -0
  42. package/dist/engine/types.d.ts.map +1 -0
  43. package/dist/engine/types.js +8 -0
  44. package/dist/engine/types.js.map +1 -0
  45. package/dist/flags.d.ts +9 -0
  46. package/dist/flags.d.ts.map +1 -0
  47. package/dist/flags.js +34 -0
  48. package/dist/flags.js.map +1 -0
  49. package/dist/install.d.ts +69 -0
  50. package/dist/install.d.ts.map +1 -0
  51. package/dist/install.js +510 -0
  52. package/dist/install.js.map +1 -0
  53. package/dist/mcp.d.ts +16 -0
  54. package/dist/mcp.d.ts.map +1 -0
  55. package/dist/mcp.js +127 -0
  56. package/dist/mcp.js.map +1 -0
  57. package/dist/pair.d.ts +20 -0
  58. package/dist/pair.d.ts.map +1 -0
  59. package/dist/pair.js +135 -0
  60. package/dist/pair.js.map +1 -0
  61. package/dist/permissions.d.ts +87 -0
  62. package/dist/permissions.d.ts.map +1 -0
  63. package/dist/permissions.js +342 -0
  64. package/dist/permissions.js.map +1 -0
  65. package/dist/receive.d.ts +54 -0
  66. package/dist/receive.d.ts.map +1 -0
  67. package/dist/receive.js +353 -0
  68. package/dist/receive.js.map +1 -0
  69. package/dist/store.d.ts +260 -0
  70. package/dist/store.d.ts.map +1 -0
  71. package/dist/store.js +550 -0
  72. package/dist/store.js.map +1 -0
  73. package/openclaw-plugin/relaymessenger-openclaw-plugin-0.1.0.tgz +0 -0
  74. package/package.json +51 -0
@@ -0,0 +1,402 @@
1
+ import { createRequire } from "node:module";
2
+ import { Readable, Writable } from "node:stream";
3
+ import crossSpawn from "cross-spawn";
4
+ import { client, ndJsonStream, PROTOCOL_VERSION, } from "@agentclientprotocol/sdk";
5
+ import { terminateProcessTree } from "./process.js";
6
+ import { EXTERNAL_ENGINE_SPECS, engineDisplayName, } from "./catalog.js";
7
+ export const ADAPTER_PACKAGES = {
8
+ claude: "@agentclientprotocol/claude-agent-acp",
9
+ codex: "@agentclientprotocol/codex-acp",
10
+ };
11
+ /** Versions must exactly match package.json; tests enforce the lock. */
12
+ export const ADAPTER_VERSIONS = {
13
+ claude: "0.59.0",
14
+ codex: "1.1.4",
15
+ };
16
+ const require = createRequire(import.meta.url);
17
+ /** Resolve the installed, lockfile-pinned executable without invoking npm. */
18
+ export function adapterEntrypoint(engine) {
19
+ if (engine === "claude") {
20
+ return require.resolve("@agentclientprotocol/claude-agent-acp/dist/index.js");
21
+ }
22
+ return require.resolve("@agentclientprotocol/codex-acp");
23
+ }
24
+ /** Shell-free, deterministic process descriptor for one ACP runtime. */
25
+ export function engineProcessSpec(engine) {
26
+ if (engine === "claude" || engine === "codex") {
27
+ return {
28
+ command: process.execPath,
29
+ args: [adapterEntrypoint(engine)],
30
+ display: `${ADAPTER_PACKAGES[engine]}@${ADAPTER_VERSIONS[engine]}`,
31
+ };
32
+ }
33
+ const spec = EXTERNAL_ENGINE_SPECS[engine];
34
+ return {
35
+ command: spec.command,
36
+ args: [...spec.args],
37
+ display: `${spec.displayName} (${spec.command} ${spec.args.join(" ")})`,
38
+ };
39
+ }
40
+ /**
41
+ * Minimized environment for the adapter subprocess. The full parent env can
42
+ * carry unrelated cloud/deploy/CI secrets; the adapter (and the agent it
43
+ * execs) only needs the platform basics plus its own provider credentials.
44
+ * Extend with RELAYMESSENGER_ENGINE_ENV="VAR1,VAR2,MYPREFIX_*". Deliberately no
45
+ * "inherit" escape hatch exists: unrelated deploy and cloud credentials must
46
+ * never be handed wholesale to a coding-agent subprocess.
47
+ */
48
+ const ENGINE_ENV_EXACT = new Set([
49
+ "PATH",
50
+ "HOME",
51
+ "USER",
52
+ "LOGNAME",
53
+ "SHELL",
54
+ "TMPDIR",
55
+ "TMP",
56
+ "TEMP",
57
+ "LANG",
58
+ "TZ",
59
+ "TERM",
60
+ "COLORTERM",
61
+ "HTTP_PROXY",
62
+ "HTTPS_PROXY",
63
+ "NO_PROXY",
64
+ "http_proxy",
65
+ "https_proxy",
66
+ "no_proxy",
67
+ // Windows process basics.
68
+ "SYSTEMROOT",
69
+ "SYSTEMDRIVE",
70
+ "COMSPEC",
71
+ "PATHEXT",
72
+ "APPDATA",
73
+ "LOCALAPPDATA",
74
+ "USERPROFILE",
75
+ "HOMEDRIVE",
76
+ "HOMEPATH",
77
+ "USERNAME",
78
+ "PROGRAMFILES",
79
+ "PROGRAMDATA",
80
+ "OS",
81
+ "WINDIR",
82
+ ]);
83
+ const ENGINE_ENV_PREFIXES = [
84
+ "LC_",
85
+ "XDG_",
86
+ // Engine/provider credentials and settings for supported local runtimes.
87
+ "ANTHROPIC_",
88
+ "CLAUDE_",
89
+ "OPENAI_",
90
+ "CODEX_",
91
+ "HERMES_",
92
+ ];
93
+ export function engineEnv(parent = process.env) {
94
+ const extra = (parent.RELAYMESSENGER_ENGINE_ENV ?? "").trim();
95
+ const extraExact = new Set();
96
+ const extraPrefixes = [];
97
+ for (const raw of extra.split(",")) {
98
+ const entry = raw.trim();
99
+ if (entry.length === 0)
100
+ continue;
101
+ if (entry.endsWith("*"))
102
+ extraPrefixes.push(entry.slice(0, -1));
103
+ else
104
+ extraExact.add(entry);
105
+ }
106
+ const allowed = (key) => {
107
+ if (ENGINE_ENV_EXACT.has(key) || ENGINE_ENV_EXACT.has(key.toUpperCase()))
108
+ return true;
109
+ if (extraExact.has(key))
110
+ return true;
111
+ return [...ENGINE_ENV_PREFIXES, ...extraPrefixes].some((prefix) => key.startsWith(prefix));
112
+ };
113
+ const env = {};
114
+ for (const [key, value] of Object.entries(parent)) {
115
+ if (value !== undefined && allowed(key))
116
+ env[key] = value;
117
+ }
118
+ return env;
119
+ }
120
+ /**
121
+ * Accumulates one turn's streamed assistant text. Chunks stream into the
122
+ * current message segment; a tool-call boundary ends the segment, so the next
123
+ * chunk starts a distinct message. Distinct segments join with a blank line —
124
+ * a plain "" join would fuse back-to-back messages into one word
125
+ * ("…the file." + "Created…" → "file.Created").
126
+ */
127
+ export class AgentTextBuffer {
128
+ segments = [];
129
+ open = false;
130
+ append(chunk) {
131
+ if (!this.open) {
132
+ this.segments.push("");
133
+ this.open = true;
134
+ }
135
+ this.segments[this.segments.length - 1] += chunk;
136
+ }
137
+ /** Mark a message boundary: the next appended chunk starts a new segment. */
138
+ endSegment() {
139
+ this.open = false;
140
+ }
141
+ /** Segments trimmed (no doubled blank lines), empty segments dropped. */
142
+ toString() {
143
+ return this.segments
144
+ .map((segment) => segment.trim())
145
+ .filter((segment) => segment.length > 0)
146
+ .join("\n\n");
147
+ }
148
+ }
149
+ /** Merge a sparse ACP tool-call update without erasing previously known fields. */
150
+ export function mergeToolCall(previous, incoming) {
151
+ const merged = { ...(previous ?? {}) };
152
+ for (const [key, value] of Object.entries(incoming)) {
153
+ if (value !== undefined)
154
+ merged[key] = value;
155
+ }
156
+ merged.toolCallId = incoming.toolCallId;
157
+ return merged;
158
+ }
159
+ /**
160
+ * Flatten the security-relevant parts of an ACP tool call — raw input,
161
+ * affected locations, content — into one preview string for the approval
162
+ * card. Length is clamped downstream (head + tail) by the card builder.
163
+ */
164
+ export function permissionDetail(toolCall) {
165
+ const parts = [];
166
+ if (toolCall.rawInput !== undefined && toolCall.rawInput !== null) {
167
+ try {
168
+ parts.push(JSON.stringify(toolCall.rawInput));
169
+ }
170
+ catch {
171
+ parts.push(String(toolCall.rawInput));
172
+ }
173
+ }
174
+ if (Array.isArray(toolCall.locations) && toolCall.locations.length > 0) {
175
+ parts.push(`paths: ${toolCall.locations.map((location) => location.path).join(", ")}`);
176
+ }
177
+ for (const content of toolCall.content ?? []) {
178
+ if (content.type === "content" && content.content.type === "text") {
179
+ parts.push(content.content.text);
180
+ }
181
+ else if (content.type === "diff") {
182
+ parts.push([
183
+ `diff ${content.path}`,
184
+ "--- before",
185
+ content.oldText ?? "(new file)",
186
+ "+++ after",
187
+ content.newText,
188
+ ].join("\n"));
189
+ }
190
+ else if (content.type === "terminal") {
191
+ parts.push(`terminal ${content.terminalId}`);
192
+ }
193
+ }
194
+ const joined = parts.filter((part) => part && part.length > 0).join("\n");
195
+ return joined.length > 0 ? joined : undefined;
196
+ }
197
+ /** True only when the phone can display the full operation being approved. */
198
+ export function permissionInputComplete(toolCall) {
199
+ if (toolCall.rawInput !== undefined && toolCall.rawInput !== null)
200
+ return true;
201
+ return (toolCall.content ?? []).some((content) => content.type === "diff" &&
202
+ typeof content.path === "string" &&
203
+ typeof content.newText === "string");
204
+ }
205
+ export class AcpEngine {
206
+ engine;
207
+ sessions;
208
+ log;
209
+ child;
210
+ connection;
211
+ ctx;
212
+ initialization;
213
+ loadSessionSupported = false;
214
+ /** Live turn state keyed by ACP session id. */
215
+ turns = new Map();
216
+ /** conversation_id → ACP session + repository for the live process. */
217
+ liveSessions = new Map();
218
+ permissionSeq = 0;
219
+ constructor(engine, sessions, log = () => { }) {
220
+ this.engine = engine;
221
+ this.sessions = sessions;
222
+ this.log = log;
223
+ }
224
+ async ensureConnected() {
225
+ if (this.ctx && this.child && this.child.exitCode === null)
226
+ return this.ctx;
227
+ if (!this.initialization) {
228
+ this.initialization = this.connect();
229
+ // A failed connect must not poison future attempts: clear the cached
230
+ // promise on rejection so the next turn re-spawns.
231
+ this.initialization.catch(() => {
232
+ this.initialization = undefined;
233
+ });
234
+ }
235
+ await this.initialization;
236
+ return this.ctx;
237
+ }
238
+ async connect() {
239
+ const processSpec = engineProcessSpec(this.engine);
240
+ this.log(`spawning ${processSpec.display}`);
241
+ const child = crossSpawn(processSpec.command, processSpec.args, {
242
+ stdio: ["pipe", "pipe", "inherit"],
243
+ env: engineEnv(),
244
+ // POSIX: own process group so dispose() reaches adapter descendants.
245
+ detached: process.platform !== "win32",
246
+ windowsHide: true,
247
+ });
248
+ this.child = child;
249
+ child.on("error", (error) => {
250
+ this.log(`${processSpec.display} spawn error: ${error.message}`);
251
+ this.resetConnection();
252
+ });
253
+ child.on("exit", (code) => {
254
+ this.log(`${processSpec.display} exited with code ${code}`);
255
+ this.resetConnection();
256
+ });
257
+ const stream = ndJsonStream(Writable.toWeb(child.stdin), Readable.toWeb(child.stdout));
258
+ const app = client({ name: "relaymessenger" })
259
+ .onRequest("session/request_permission", async (c) => this.handlePermission(c.params))
260
+ .onNotification("session/update", (c) => {
261
+ this.handleUpdate(c.params);
262
+ });
263
+ const connection = app.connect(stream);
264
+ this.connection = connection;
265
+ this.ctx = connection.agent;
266
+ const init = await this.ctx.request("initialize", {
267
+ protocolVersion: PROTOCOL_VERSION,
268
+ clientInfo: { name: "relaymessenger", version: "0.2.0" },
269
+ clientCapabilities: {},
270
+ });
271
+ if (init.protocolVersion !== PROTOCOL_VERSION) {
272
+ throw new Error(`${engineDisplayName(this.engine)} returned unsupported ACP protocol ` +
273
+ `${init.protocolVersion}; relaymessenger requires ${PROTOCOL_VERSION}`);
274
+ }
275
+ this.loadSessionSupported = init.agentCapabilities?.loadSession === true;
276
+ this.log(`initialized ${processSpec.display} (protocol v${init.protocolVersion})`);
277
+ }
278
+ resetConnection() {
279
+ this.connection?.close();
280
+ this.connection = undefined;
281
+ this.ctx = undefined;
282
+ this.initialization = undefined;
283
+ this.liveSessions.clear();
284
+ this.turns.clear();
285
+ }
286
+ handleUpdate(notification) {
287
+ const turn = this.turns.get(notification.sessionId);
288
+ if (!turn)
289
+ return;
290
+ const update = notification.update;
291
+ if (update.sessionUpdate === "agent_message_chunk" && update.content.type === "text") {
292
+ turn.text.append(update.content.text);
293
+ turn.callbacks.onDelta?.(update.content.text);
294
+ }
295
+ else if (update.sessionUpdate === "tool_call" || update.sessionUpdate === "tool_call_update") {
296
+ // A tool call between text chunks means the next text is a new message.
297
+ turn.text.endSegment();
298
+ const { sessionUpdate: _sessionUpdate, ...incoming } = update;
299
+ turn.toolCalls.set(incoming.toolCallId, mergeToolCall(turn.toolCalls.get(incoming.toolCallId), incoming));
300
+ turn.callbacks.onToolEvent?.({
301
+ kind: update.sessionUpdate,
302
+ title: "title" in update ? (update.title ?? undefined) : undefined,
303
+ });
304
+ }
305
+ }
306
+ async handlePermission(params) {
307
+ const turn = this.turns.get(params.sessionId);
308
+ if (!turn) {
309
+ // No live turn owns this session (e.g. restart race) — safest is refusal.
310
+ return { outcome: { outcome: "cancelled" } };
311
+ }
312
+ this.permissionSeq += 1;
313
+ const toolCall = mergeToolCall(turn.toolCalls.get(params.toolCall.toolCallId), params.toolCall);
314
+ turn.toolCalls.set(toolCall.toolCallId, toolCall);
315
+ const ask = {
316
+ requestId: `perm_${Date.now().toString(36)}_${this.permissionSeq}`,
317
+ toolName: toolCall.title ?? toolCall.toolCallId,
318
+ title: toolCall.title ?? undefined,
319
+ // The card must show WHAT is being approved, not just a tool title: a
320
+ // generic "Bash" with the command hidden turns Allow into a blind grant.
321
+ inputPreview: permissionDetail(toolCall),
322
+ inputComplete: permissionInputComplete(toolCall),
323
+ options: params.options.map((option) => ({
324
+ optionId: option.optionId,
325
+ label: option.name,
326
+ kind: option.kind,
327
+ })),
328
+ };
329
+ const decision = await turn.callbacks.onPermissionAsk(ask);
330
+ if (decision.behavior === "selected") {
331
+ return { outcome: { outcome: "selected", optionId: decision.optionId } };
332
+ }
333
+ return { outcome: { outcome: "cancelled" } };
334
+ }
335
+ async openSession(ctx, ref) {
336
+ const live = this.liveSessions.get(ref.conversationId);
337
+ if (live?.cwd === ref.cwd)
338
+ return live.sessionId;
339
+ if (live)
340
+ this.liveSessions.delete(ref.conversationId);
341
+ const stored = this.sessions.get(ref.conversationId);
342
+ // Reuse only bindings from the same engine AND the same working
343
+ // directory: reloading another repository's session would leak its
344
+ // history/instructions into this tree and act against the wrong files.
345
+ if (stored && stored.engine === this.engine && stored.cwd === ref.cwd && this.loadSessionSupported) {
346
+ try {
347
+ await ctx.request("session/load", {
348
+ sessionId: stored.session_id,
349
+ cwd: ref.cwd,
350
+ mcpServers: [],
351
+ });
352
+ this.liveSessions.set(ref.conversationId, { sessionId: stored.session_id, cwd: ref.cwd });
353
+ return stored.session_id;
354
+ }
355
+ catch (error) {
356
+ this.log(`session/load failed for ${ref.conversationId}, creating fresh: ${error}`);
357
+ this.sessions.delete(ref.conversationId);
358
+ }
359
+ }
360
+ const created = await ctx.request("session/new", { cwd: ref.cwd, mcpServers: [] });
361
+ this.liveSessions.set(ref.conversationId, { sessionId: created.sessionId, cwd: ref.cwd });
362
+ this.sessions.set(ref.conversationId, {
363
+ engine: this.engine,
364
+ session_id: created.sessionId,
365
+ cwd: ref.cwd,
366
+ created_at: new Date().toISOString(),
367
+ });
368
+ return created.sessionId;
369
+ }
370
+ async startTurn(ref, promptText, callbacks) {
371
+ const ctx = await this.ensureConnected();
372
+ const sessionId = await this.openSession(ctx, ref);
373
+ const turn = { callbacks, text: new AgentTextBuffer(), toolCalls: new Map() };
374
+ this.turns.set(sessionId, turn);
375
+ try {
376
+ // No request timeout: a coding-agent turn can legitimately run for a
377
+ // long time, and the JSON-RPC layer settles when the peer responds.
378
+ const response = await ctx.request("session/prompt", {
379
+ sessionId,
380
+ prompt: [{ type: "text", text: promptText }],
381
+ });
382
+ return { text: turn.text.toString(), stopReason: response.stopReason };
383
+ }
384
+ finally {
385
+ this.turns.delete(sessionId);
386
+ }
387
+ }
388
+ async abort(ref) {
389
+ const live = this.liveSessions.get(ref.conversationId);
390
+ if (!live || live.cwd !== ref.cwd || !this.ctx)
391
+ return;
392
+ await this.ctx.notify("session/cancel", { sessionId: live.sessionId });
393
+ }
394
+ async dispose() {
395
+ const child = this.child;
396
+ this.resetConnection();
397
+ this.child = undefined;
398
+ if (child)
399
+ await terminateProcessTree(child);
400
+ }
401
+ }
402
+ //# sourceMappingURL=acp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"acp.js","sourceRoot":"","sources":["../../src/engine/acp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * ACP runtime presets supported by relaymessenger.
3
+ *
4
+ * Bundled adapters are exact npm dependencies resolved by acp.ts. External
5
+ * runtimes are always user-installed binaries: relaymessenger never downloads a
6
+ * mutable CLI at startup and never passes a command through a shell.
7
+ */
8
+ export declare const ENGINE_NAMES: readonly ["claude", "codex", "hermes"];
9
+ export type EngineName = (typeof ENGINE_NAMES)[number];
10
+ export interface ExternalEngineSpec {
11
+ displayName: string;
12
+ command: string;
13
+ args: string[];
14
+ versionArgs: string[];
15
+ docsUrl: string;
16
+ /** Runtime-specific readiness check that does not reveal credentials. */
17
+ checkArgs?: string[];
18
+ /** Some ACP servers impose a shorter requestPermission deadline. */
19
+ permissionTimeoutMs?: number;
20
+ }
21
+ export declare const EXTERNAL_ENGINE_SPECS: Record<Exclude<EngineName, "claude" | "codex">, ExternalEngineSpec>;
22
+ export declare function isEngineName(value: unknown): value is EngineName;
23
+ export declare function engineDisplayName(engine: EngineName | string): string;
24
+ export declare function enginePermissionTimeoutMs(engine: EngineName): number | undefined;
25
+ export declare const ENGINE_HELP: string;
26
+ //# sourceMappingURL=catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/engine/catalog.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,YAAY,wCAIf,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,oEAAoE;IACpE,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,kBAAkB,CAWrG,CAAC;AAEF,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,UAAU,CAEhE;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,MAAM,CAIrE;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAGhF;AAED,eAAO,MAAM,WAAW,QAAyB,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * ACP runtime presets supported by relaymessenger.
3
+ *
4
+ * Bundled adapters are exact npm dependencies resolved by acp.ts. External
5
+ * runtimes are always user-installed binaries: relaymessenger never downloads a
6
+ * mutable CLI at startup and never passes a command through a shell.
7
+ */
8
+ export const ENGINE_NAMES = [
9
+ "claude",
10
+ "codex",
11
+ "hermes",
12
+ ];
13
+ export const EXTERNAL_ENGINE_SPECS = {
14
+ hermes: {
15
+ displayName: "Hermes Agent",
16
+ command: "hermes",
17
+ args: ["acp"],
18
+ versionArgs: ["--version"],
19
+ checkArgs: ["acp", "--check"],
20
+ docsUrl: "https://hermes-agent.nousresearch.com/docs/user-guide/features/acp",
21
+ // Hermes currently waits 60 seconds for an ACP permission decision.
22
+ permissionTimeoutMs: 55_000,
23
+ },
24
+ };
25
+ export function isEngineName(value) {
26
+ return typeof value === "string" && ENGINE_NAMES.includes(value);
27
+ }
28
+ export function engineDisplayName(engine) {
29
+ if (engine === "claude")
30
+ return "Claude Code";
31
+ if (engine === "codex")
32
+ return "Codex";
33
+ return EXTERNAL_ENGINE_SPECS[engine]?.displayName ?? engine;
34
+ }
35
+ export function enginePermissionTimeoutMs(engine) {
36
+ if (engine === "claude" || engine === "codex")
37
+ return undefined;
38
+ return EXTERNAL_ENGINE_SPECS[engine].permissionTimeoutMs;
39
+ }
40
+ export const ENGINE_HELP = ENGINE_NAMES.join("|");
41
+ //# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/engine/catalog.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,QAAQ;IACR,OAAO;IACP,QAAQ;CACA,CAAC;AAgBX,MAAM,CAAC,MAAM,qBAAqB,GAAwE;IACxG,MAAM,EAAE;QACN,WAAW,EAAE,cAAc;QAC3B,OAAO,EAAE,QAAQ;QACjB,IAAI,EAAE,CAAC,KAAK,CAAC;QACb,WAAW,EAAE,CAAC,WAAW,CAAC;QAC1B,SAAS,EAAE,CAAC,KAAK,EAAE,SAAS,CAAC;QAC7B,OAAO,EAAE,oEAAoE;QAC7E,oEAAoE;QACpE,mBAAmB,EAAE,MAAM;KAC5B;CACF,CAAC;AAEF,MAAM,UAAU,YAAY,CAAC,KAAc;IACzC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,YAAkC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC1F,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,MAA2B;IAC3D,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,aAAa,CAAC;IAC9C,IAAI,MAAM,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IACvC,OAAO,qBAAqB,CAAC,MAA4C,CAAC,EAAE,WAAW,IAAI,MAAM,CAAC;AACpG,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,MAAkB;IAC1D,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,OAAO;QAAE,OAAO,SAAS,CAAC;IAChE,OAAO,qBAAqB,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type ChildProcess } from "node:child_process";
2
+ /**
3
+ * Terminates the complete subprocess tree owned by an engine adapter.
4
+ *
5
+ * POSIX children are spawned as process-group leaders, so a negative PID
6
+ * reaches the adapter and every agent process below it. Windows has no
7
+ * equivalent signalable process group; taskkill /T /F is the supported tree
8
+ * termination path there. The bounded wait prevents shutdown from hanging on
9
+ * a child that ignores SIGTERM.
10
+ */
11
+ export declare function terminateProcessTree(child: ChildProcess, graceMs?: number): Promise<void>;
12
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/engine/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMlE;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,YAAY,EAAE,OAAO,SAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAsC9F"}
@@ -0,0 +1,54 @@
1
+ import { spawnSync } from "node:child_process";
2
+ function delay(ms) {
3
+ return new Promise((resolve) => setTimeout(resolve, ms));
4
+ }
5
+ /**
6
+ * Terminates the complete subprocess tree owned by an engine adapter.
7
+ *
8
+ * POSIX children are spawned as process-group leaders, so a negative PID
9
+ * reaches the adapter and every agent process below it. Windows has no
10
+ * equivalent signalable process group; taskkill /T /F is the supported tree
11
+ * termination path there. The bounded wait prevents shutdown from hanging on
12
+ * a child that ignores SIGTERM.
13
+ */
14
+ export async function terminateProcessTree(child, graceMs = 2_000) {
15
+ const pid = child.pid;
16
+ if (!pid || child.exitCode !== null || child.signalCode !== null)
17
+ return;
18
+ let exited = false;
19
+ const exit = new Promise((resolve) => {
20
+ child.once("exit", () => {
21
+ exited = true;
22
+ resolve();
23
+ });
24
+ });
25
+ if (process.platform === "win32") {
26
+ // /T includes descendants; /F is necessary for console processes that do
27
+ // not participate in a shared console control group.
28
+ spawnSync("taskkill", ["/PID", String(pid), "/T", "/F"], {
29
+ stdio: "ignore",
30
+ windowsHide: true,
31
+ });
32
+ if (!exited)
33
+ child.kill();
34
+ await Promise.race([exit, delay(graceMs)]);
35
+ return;
36
+ }
37
+ try {
38
+ process.kill(-pid, "SIGTERM");
39
+ }
40
+ catch {
41
+ child.kill("SIGTERM");
42
+ }
43
+ await Promise.race([exit, delay(graceMs)]);
44
+ if (exited)
45
+ return;
46
+ try {
47
+ process.kill(-pid, "SIGKILL");
48
+ }
49
+ catch {
50
+ child.kill("SIGKILL");
51
+ }
52
+ await Promise.race([exit, delay(1_000)]);
53
+ }
54
+ //# sourceMappingURL=process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/engine/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAqB,MAAM,oBAAoB,CAAC;AAElE,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,KAAmB,EAAE,OAAO,GAAG,KAAK;IAC7E,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC;IACtB,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,UAAU,KAAK,IAAI;QAAE,OAAO;IAEzE,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,MAAM,IAAI,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QACzC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE;YACtB,MAAM,GAAG,IAAI,CAAC;YACd,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,yEAAyE;QACzE,qDAAqD;QACrD,SAAS,CAAC,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE;YACvD,KAAK,EAAE,QAAQ;YACf,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,EAAE,CAAC;QAC1B,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC;IACD,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC3C,IAAI,MAAM;QAAE,OAAO;IAEnB,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACxB,CAAC;IACD,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Narrow engine-adapter boundary. The receive loop only knows this interface;
3
+ * AcpEngine drives every supported coding runtime over ACP stdio without the
4
+ * loop knowing which. `SessionRef` is opaque per engine — adapters own their
5
+ * own binding from conversation_id to whatever session identity they need.
6
+ */
7
+ export interface SessionRef {
8
+ conversationId: string;
9
+ /** Working directory the engine session should operate in. */
10
+ cwd: string;
11
+ }
12
+ export interface PermissionAsk {
13
+ requestId: string;
14
+ toolName?: string;
15
+ title?: string;
16
+ /**
17
+ * Security-relevant detail of the operation being approved (raw tool input,
18
+ * affected paths). Rendered on the phone card so the owner sees what they
19
+ * are allowing, not just a tool title.
20
+ */
21
+ inputPreview?: string;
22
+ /** False when the adapter cannot provide the raw operation being approved. */
23
+ inputComplete?: boolean;
24
+ options: Array<{
25
+ optionId: string;
26
+ label: string;
27
+ kind?: string;
28
+ }>;
29
+ }
30
+ export type PermissionDecision = {
31
+ behavior: "selected";
32
+ optionId: string;
33
+ } | {
34
+ behavior: "cancelled";
35
+ };
36
+ export interface TurnCallbacks {
37
+ /** Streaming assistant text; the bridge finalizes quietly, so this is informational. */
38
+ onDelta?(text: string): void;
39
+ /** Tool activity, surfaced as a typing label. */
40
+ onToolEvent?(event: {
41
+ kind: string;
42
+ title?: string;
43
+ }): void;
44
+ /** Blocking permission ask — resolve with the user's decision. */
45
+ onPermissionAsk(ask: PermissionAsk): Promise<PermissionDecision>;
46
+ }
47
+ export interface TurnResult {
48
+ text: string;
49
+ stopReason: string;
50
+ }
51
+ export interface EngineAdapter {
52
+ readonly engine: string;
53
+ startTurn(ref: SessionRef, promptText: string, callbacks: TurnCallbacks): Promise<TurnResult>;
54
+ abort(ref: SessionRef): Promise<void>;
55
+ dispose(): Promise<void>;
56
+ }
57
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/engine/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,UAAU;IACzB,cAAc,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8EAA8E;IAC9E,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpE;AAED,MAAM,MAAM,kBAAkB,GAC1B;IAAE,QAAQ,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,QAAQ,EAAE,WAAW,CAAA;CAAE,CAAC;AAE9B,MAAM,WAAW,aAAa;IAC5B,wFAAwF;IACxF,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,iDAAiD;IACjD,WAAW,CAAC,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5D,kEAAkE;IAClE,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,GAAG,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9F,KAAK,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CAC1B"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Narrow engine-adapter boundary. The receive loop only knows this interface;
3
+ * AcpEngine drives every supported coding runtime over ACP stdio without the
4
+ * loop knowing which. `SessionRef` is opaque per engine — adapters own their
5
+ * own binding from conversation_id to whatever session identity they need.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/engine/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}