@rk0429/agentic-relay 3.6.0 → 3.7.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.
package/README.md CHANGED
@@ -11,8 +11,10 @@ Phase 4 visualization commands.
11
11
  - Phase 2 task management from `docs/requirements.md`
12
12
  - Phase 3 task-type routing from `docs/requirements.md`
13
13
  - Phase 4 visualization UI from `docs/requirements.md`
14
+ - Phase 5 unified relay CLI from `docs/requirements.md`
14
15
  - `relay mcp serve` over stdio
15
16
  - `relay visualize` for a colorized task tree and active-agent dashboard
17
+ - `relay [backend] [--resume <session_id>] [-p <prompt>]` for interactive and non-interactive backend access
16
18
  - VSCode Explorer views for task trees and active agents with `fs.watch` refresh
17
19
  - Parallel `spawn_agents`
18
20
  - Backend routing, depth guard, response persistence, and session metadata
@@ -27,12 +29,23 @@ Phase 4 visualization commands.
27
29
  ```bash
28
30
  pnpm install
29
31
  pnpm build
32
+ pnpm relay
33
+ pnpm relay codex
34
+ pnpm relay claude -p "hello"
35
+ pnpm relay claude --resume <session_id>
30
36
  pnpm relay mcp serve
31
37
  pnpm relay visualize
32
38
  ```
33
39
 
34
40
  Responses are stored under `.relay/` in the current working directory.
35
41
 
42
+ `relay` chooses the default backend in `claude -> codex -> gemini` order when
43
+ no backend is specified. Interactive mode shows a short Ink launch banner and
44
+ then hands control to the selected backend CLI. Prompt mode (`-p/--prompt`)
45
+ uses relay-managed session persistence, so Claude and Codex sessions can later
46
+ be resumed with `--resume <session_id>`. Gemini follows the documented
47
+ constraint and rejects `-p` together with `--resume`.
48
+
36
49
  `relay visualize` renders:
37
50
 
38
51
  - A colorized task tree with task ID, title, status, assigned agent, and dependencies
@@ -0,0 +1,54 @@
1
+ import type { BackendType, RelaySessionMetadata } from "../core/types.js";
2
+ import { RelayStore } from "../infrastructure/store/relay-store.js";
3
+ import { BackendRegistry } from "../infrastructure/backends/backend-registry.js";
4
+ import type { CliBackendExecutor } from "../infrastructure/backends/cli-backend-executor.js";
5
+ import type { InteractiveProcessInput, InteractiveProcessRunner } from "../infrastructure/process/process-executor.js";
6
+ export interface RelayCliBannerInfo {
7
+ backend: BackendType;
8
+ availableBackends: BackendType[];
9
+ resumeSessionId?: string;
10
+ managedSessionId?: string;
11
+ }
12
+ export interface RelayCliInteractivePlan {
13
+ banner: RelayCliBannerInfo;
14
+ launch: InteractiveProcessInput;
15
+ persistSession: boolean;
16
+ metadata?: RelaySessionMetadata;
17
+ cleanup: () => Promise<void>;
18
+ }
19
+ export interface RelayCliPromptResult {
20
+ backend: BackendType;
21
+ relaySessionId: string;
22
+ output: string;
23
+ responsePath: string;
24
+ }
25
+ export declare class RelayCliService {
26
+ private readonly dependencies;
27
+ constructor(dependencies: {
28
+ store: RelayStore;
29
+ backendRegistry: BackendRegistry;
30
+ backendExecutor: CliBackendExecutor;
31
+ interactiveRunner: InteractiveProcessRunner;
32
+ cwd: string;
33
+ env: NodeJS.ProcessEnv;
34
+ now?: () => Date;
35
+ relaySessionIdFactory?: () => string;
36
+ });
37
+ runPrompt(options: {
38
+ backend?: BackendType;
39
+ prompt: string;
40
+ resumeSessionId?: string;
41
+ }): Promise<RelayCliPromptResult>;
42
+ launchInteractive(options: {
43
+ backend?: BackendType;
44
+ resumeSessionId?: string;
45
+ }): Promise<number>;
46
+ runPreparedInteractive(plan: RelayCliInteractivePlan): Promise<number>;
47
+ prepareInteractive(options: {
48
+ backend?: BackendType;
49
+ resumeSessionId?: string;
50
+ }): Promise<RelayCliInteractivePlan>;
51
+ private resolveBackend;
52
+ private now;
53
+ private createRelaySessionId;
54
+ }
@@ -0,0 +1,174 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { mkdtemp, rm, writeFile } from "node:fs/promises";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { BackendUnavailableError, NotFoundError, ValidationError, } from "../core/errors.js";
6
+ export class RelayCliService {
7
+ dependencies;
8
+ constructor(dependencies) {
9
+ this.dependencies = dependencies;
10
+ }
11
+ async runPrompt(options) {
12
+ const resolution = await this.resolveBackend(options.backend, options.resumeSessionId);
13
+ if (resolution.backend === "gemini" && resolution.resumeMetadata) {
14
+ throw new ValidationError("Gemini CLI does not support prompt mode with --resume. Run `relay gemini --resume <session_id>` without -p instead.");
15
+ }
16
+ const now = this.now().toISOString();
17
+ const relaySessionId = resolution.resumeMetadata?.relaySessionId ?? this.createRelaySessionId();
18
+ const request = {
19
+ relaySessionId,
20
+ backend: resolution.backend,
21
+ prompt: options.prompt,
22
+ backendSessionId: resolution.resumeMetadata?.backendSessionId,
23
+ cwd: this.dependencies.cwd,
24
+ env: this.dependencies.env,
25
+ };
26
+ const result = await this.dependencies.backendExecutor.execute(request);
27
+ const responsePath = await this.dependencies.store.writeResponse(relaySessionId, result.output);
28
+ await this.dependencies.store.writeSessionMetadata({
29
+ relaySessionId,
30
+ backend: resolution.backend,
31
+ backendSessionId: result.backendSessionId,
32
+ cwd: this.dependencies.cwd,
33
+ createdAt: resolution.resumeMetadata?.createdAt ?? now,
34
+ updatedAt: now,
35
+ });
36
+ return {
37
+ backend: resolution.backend,
38
+ relaySessionId,
39
+ output: result.output,
40
+ responsePath,
41
+ };
42
+ }
43
+ async launchInteractive(options) {
44
+ const plan = await this.prepareInteractive(options);
45
+ return this.runPreparedInteractive(plan);
46
+ }
47
+ async runPreparedInteractive(plan) {
48
+ try {
49
+ const exitCode = await this.dependencies.interactiveRunner.run(plan.launch);
50
+ if (plan.persistSession && plan.metadata) {
51
+ await this.dependencies.store.writeSessionMetadata(plan.metadata);
52
+ }
53
+ return exitCode;
54
+ }
55
+ finally {
56
+ await plan.cleanup();
57
+ }
58
+ }
59
+ async prepareInteractive(options) {
60
+ const resolution = await this.resolveBackend(options.backend, options.resumeSessionId);
61
+ const now = this.now().toISOString();
62
+ const availableBackends = resolution.availableBackends;
63
+ const profile = this.dependencies.backendRegistry.getProfile(resolution.backend);
64
+ const env = { ...this.dependencies.env };
65
+ let cleanup = async () => { };
66
+ let metadata;
67
+ let persistSession = false;
68
+ const args = resolution.backend === "claude"
69
+ ? buildClaudeInteractiveArgs(resolution.resumeMetadata?.backendSessionId, profile.controlPolicy.cliFlags, () => {
70
+ const relaySessionId = this.createRelaySessionId();
71
+ metadata = {
72
+ relaySessionId,
73
+ backend: resolution.backend,
74
+ backendSessionId: relaySessionId,
75
+ cwd: this.dependencies.cwd,
76
+ createdAt: now,
77
+ updatedAt: now,
78
+ };
79
+ persistSession = true;
80
+ return relaySessionId;
81
+ })
82
+ : resolution.backend === "codex"
83
+ ? buildCodexInteractiveArgs(resolution.resumeMetadata?.backendSessionId, profile.controlPolicy.cliFlags)
84
+ : await buildGeminiInteractiveArgs(resolution.resumeMetadata?.backendSessionId, profile.controlPolicy.settingsOverrides ?? {}).then((built) => {
85
+ cleanup = built.cleanup;
86
+ Object.assign(env, built.env);
87
+ return built.args;
88
+ });
89
+ if (resolution.resumeMetadata) {
90
+ metadata = {
91
+ ...resolution.resumeMetadata,
92
+ updatedAt: now,
93
+ };
94
+ persistSession = true;
95
+ }
96
+ return {
97
+ banner: {
98
+ backend: resolution.backend,
99
+ availableBackends,
100
+ resumeSessionId: resolution.resumeMetadata?.relaySessionId,
101
+ managedSessionId: metadata && !resolution.resumeMetadata ? metadata.relaySessionId : undefined,
102
+ },
103
+ launch: {
104
+ command: profile.command,
105
+ args,
106
+ cwd: this.dependencies.cwd,
107
+ env,
108
+ },
109
+ persistSession,
110
+ metadata,
111
+ cleanup,
112
+ };
113
+ }
114
+ async resolveBackend(requestedBackend, resumeSessionId) {
115
+ const availableBackends = await this.dependencies.backendRegistry.detectInstalled();
116
+ if (availableBackends.length === 0) {
117
+ throw new BackendUnavailableError("agentic-relay: no supported backend CLI is installed.");
118
+ }
119
+ const resumeMetadata = resumeSessionId
120
+ ? await this.dependencies.store.readSessionMetadata(resumeSessionId)
121
+ : null;
122
+ if (resumeSessionId && !resumeMetadata) {
123
+ throw new NotFoundError(`Relay session ${resumeSessionId} does not exist.`);
124
+ }
125
+ const backend = requestedBackend ?? resumeMetadata?.backend ?? availableBackends[0];
126
+ if (!backend) {
127
+ throw new BackendUnavailableError("agentic-relay: no supported backend CLI is installed.");
128
+ }
129
+ if (requestedBackend && resumeMetadata && resumeMetadata.backend !== requestedBackend) {
130
+ throw new ValidationError(`Relay session ${resumeSessionId} belongs to ${resumeMetadata.backend}, not ${requestedBackend}.`);
131
+ }
132
+ if (!availableBackends.includes(backend)) {
133
+ throw new BackendUnavailableError(`${backend} CLI is not installed.`);
134
+ }
135
+ return {
136
+ backend,
137
+ availableBackends,
138
+ resumeMetadata: resumeMetadata ?? undefined,
139
+ };
140
+ }
141
+ now() {
142
+ return this.dependencies.now?.() ?? new Date();
143
+ }
144
+ createRelaySessionId() {
145
+ return this.dependencies.relaySessionIdFactory?.() ?? randomUUID();
146
+ }
147
+ }
148
+ function buildClaudeInteractiveArgs(resumeBackendSessionId, cliFlags, createRelaySessionId) {
149
+ const args = resumeBackendSessionId
150
+ ? ["--resume", resumeBackendSessionId]
151
+ : ["--session-id", createRelaySessionId()];
152
+ args.push(...cliFlags);
153
+ return args;
154
+ }
155
+ function buildCodexInteractiveArgs(resumeBackendSessionId, cliFlags) {
156
+ return resumeBackendSessionId
157
+ ? ["resume", resumeBackendSessionId, ...cliFlags]
158
+ : [...cliFlags];
159
+ }
160
+ async function buildGeminiInteractiveArgs(resumeBackendSessionId, settingsOverrides) {
161
+ const tempDir = await mkdtemp(path.join(os.tmpdir(), "agentic-relay-gemini-"));
162
+ const settingsPath = path.join(tempDir, "gemini-settings.json");
163
+ await writeFile(settingsPath, `${JSON.stringify(settingsOverrides, null, 2)}\n`, "utf8");
164
+ return {
165
+ args: resumeBackendSessionId ? ["--resume", resumeBackendSessionId] : [],
166
+ env: {
167
+ GEMINI_CLI_SYSTEM_SETTINGS_PATH: settingsPath,
168
+ },
169
+ cleanup: async () => {
170
+ await rm(tempDir, { recursive: true, force: true });
171
+ },
172
+ };
173
+ }
174
+ //# sourceMappingURL=relay-cli-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-cli-service.js","sourceRoot":"","sources":["../../src/application/relay-cli-service.ts"],"names":[],"mappings":"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"}
package/dist/bin/relay.js CHANGED
@@ -2,19 +2,27 @@
2
2
  import path from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { ProjectionService } from "../application/projection-service.js";
5
+ import { RelayCliService } from "../application/relay-cli-service.js";
5
6
  import { SpawnAgentsService } from "../application/spawn-agents-service.js";
6
7
  import { TaskService } from "../application/task-service.js";
7
8
  import { BackendRegistry } from "../infrastructure/backends/backend-registry.js";
8
9
  import { CliBackendExecutor } from "../infrastructure/backends/cli-backend-executor.js";
9
- import { ChildProcessExecutor } from "../infrastructure/process/process-executor.js";
10
+ import { ChildProcessExecutor, ChildProcessInteractiveRunner, } from "../infrastructure/process/process-executor.js";
11
+ import { ValidationError } from "../core/errors.js";
10
12
  import { RelayStore } from "../infrastructure/store/relay-store.js";
13
+ import { showLaunchBanner } from "../interfaces/cli/launch-banner.js";
14
+ import { parseRelayCliArgs } from "../interfaces/cli/relay-cli-args.js";
11
15
  import { renderVisualization } from "../interfaces/cli/visualization-renderer.js";
12
16
  import { createRelayMcpServer, serveRelayMcpServer, } from "../interfaces/mcp/relay-mcp-server.js";
13
17
  async function main() {
14
- const args = process.argv.slice(2);
18
+ const command = parseRelayCliArgs(process.argv.slice(2));
15
19
  const cwd = process.cwd();
16
20
  const store = new RelayStore(path.join(cwd, ".relay"));
17
- if (args[0] === "visualize") {
21
+ if (command.kind === "help") {
22
+ printHelp();
23
+ return;
24
+ }
25
+ if (command.kind === "visualize") {
18
26
  const projectionService = new ProjectionService({
19
27
  store,
20
28
  });
@@ -22,42 +30,77 @@ async function main() {
22
30
  process.stdout.write(renderVisualization(snapshot));
23
31
  return;
24
32
  }
25
- if (args[0] !== "mcp" || args[1] !== "serve") {
26
- printHelp();
27
- process.exitCode = 1;
28
- return;
29
- }
30
33
  const backendRegistry = new BackendRegistry();
31
- const installed = await backendRegistry.detectInstalled();
32
- if (installed.length === 0) {
33
- console.error("agentic-relay: no supported backend CLI is installed.");
34
- process.exitCode = 1;
35
- return;
36
- }
34
+ const backendExecutor = new CliBackendExecutor(backendRegistry, new ChildProcessExecutor());
37
35
  const taskService = new TaskService({
38
36
  store,
39
37
  });
40
- const service = new SpawnAgentsService({
41
- backendRegistry,
42
- backendExecutor: new CliBackendExecutor(backendRegistry, new ChildProcessExecutor()),
38
+ if (command.kind === "mcp") {
39
+ const installed = await backendRegistry.detectInstalled();
40
+ if (installed.length === 0) {
41
+ console.error("agentic-relay: no supported backend CLI is installed.");
42
+ process.exitCode = 1;
43
+ return;
44
+ }
45
+ const service = new SpawnAgentsService({
46
+ backendRegistry,
47
+ backendExecutor,
48
+ store,
49
+ taskService,
50
+ cwd,
51
+ env: process.env,
52
+ });
53
+ const server = createRelayMcpServer({
54
+ service,
55
+ taskService,
56
+ allowSpawnAgents: process.env.RELAY_ALLOW_SPAWN_AGENTS !== "0",
57
+ });
58
+ await serveRelayMcpServer(server);
59
+ return;
60
+ }
61
+ const cliService = new RelayCliService({
43
62
  store,
44
- taskService,
63
+ backendRegistry,
64
+ backendExecutor,
65
+ interactiveRunner: new ChildProcessInteractiveRunner(),
45
66
  cwd,
46
67
  env: process.env,
47
68
  });
48
- const server = createRelayMcpServer({
49
- service,
50
- taskService,
51
- allowSpawnAgents: process.env.RELAY_ALLOW_SPAWN_AGENTS !== "0",
69
+ if (command.prompt) {
70
+ const result = await cliService.runPrompt({
71
+ backend: command.backend,
72
+ prompt: command.prompt,
73
+ resumeSessionId: command.resumeSessionId,
74
+ });
75
+ process.stdout.write(result.output.endsWith("\n") ? result.output : `${result.output}\n`);
76
+ return;
77
+ }
78
+ const plan = await cliService.prepareInteractive({
79
+ backend: command.backend,
80
+ resumeSessionId: command.resumeSessionId,
52
81
  });
53
- await serveRelayMcpServer(server);
82
+ await showLaunchBanner(plan.banner);
83
+ const exitCode = await cliService.runPreparedInteractive(plan);
84
+ process.exitCode = exitCode;
54
85
  }
55
86
  function printHelp() {
56
87
  const scriptName = path.basename(fileURLToPath(import.meta.url));
57
- console.error(`Usage: ${scriptName} mcp serve | ${scriptName} visualize`);
88
+ console.error([
89
+ `Usage: ${scriptName} [backend] [--resume <session_id>] [-p <prompt>]`,
90
+ ` ${scriptName} visualize`,
91
+ ` ${scriptName} mcp serve`,
92
+ "",
93
+ "Backends: claude, codex, gemini",
94
+ ].join("\n"));
58
95
  }
59
96
  main().catch((error) => {
60
- console.error(error instanceof Error ? error.message : "agentic-relay failed unexpectedly.");
97
+ const message = error instanceof Error ? error.message : "agentic-relay failed unexpectedly.";
98
+ if (error instanceof ValidationError) {
99
+ console.error(message);
100
+ process.exitCode = 1;
101
+ return;
102
+ }
103
+ console.error(message);
61
104
  process.exitCode = 1;
62
105
  });
63
106
  //# sourceMappingURL=relay.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"relay.js","sourceRoot":"","sources":["../../src/bin/relay.ts"],"names":[],"mappings":";AACA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAC7D,OAAO,EAAE,eAAe,EAAE,MAAM,gDAAgD,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oDAAoD,CAAC;AACxF,OAAO,EAAE,oBAAoB,EAAE,MAAM,+CAA+C,CAAC;AACrF,OAAO,EAAE,UAAU,EAAE,MAAM,wCAAwC,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6CAA6C,CAAC;AAClF,OAAO,EACL,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,uCAAuC,CAAC;AAE/C,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEvD,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE,CAAC;QAC5B,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC;YAC9C,KAAK;SACN,CAAC,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,wBAAwB,EAAE,CAAC;QACpE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC;QACpD,OAAO;IACT,CAAC;IAED,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;QAC7C,SAAS,EAAE,CAAC;QACZ,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC;IAC9C,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,eAAe,EAAE,CAAC;IAC1D,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC3B,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACvE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,WAAW,CAAC;QAClC,KAAK;KACN,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,IAAI,kBAAkB,CAAC;QACrC,eAAe;QACf,eAAe,EAAE,IAAI,kBAAkB,CACrC,eAAe,EACf,IAAI,oBAAoB,EAAE,CAC3B;QACD,KAAK;QACL,WAAW;QACX,GAAG;QACH,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,oBAAoB,CAAC;QAClC,OAAO;QACP,WAAW;QACX,gBAAgB,EAAE,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,GAAG;KAC/D,CAAC,CAAC;IAEH,MAAM,mBAAmB,CAAC,MAAM,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,SAAS;IAChB,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,KAAK,CAAC,UAAU,UAAU,gBAAgB,UAAU,YAAY,CAAC,CAAC;AAC5E,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACrB,OAAO,CAAC,KAAK,CACX,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,oCAAoC,CAC9E,CAAC;IACF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"relay.js","sourceRoot":"","sources":["../../src/bin/relay.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./application/projection-service.js";
2
+ export * from "./application/relay-cli-service.js";
2
3
  export * from "./application/spawn-agents-service.js";
3
4
  export * from "./application/task-service.js";
4
5
  export * from "./core/errors.js";
@@ -9,4 +10,5 @@ export * from "./infrastructure/backends/cli-backend-executor.js";
9
10
  export * from "./infrastructure/process/process-executor.js";
10
11
  export * from "./infrastructure/store/relay-store.js";
11
12
  export * from "./interfaces/cli/visualization-renderer.js";
13
+ export * from "./interfaces/cli/relay-cli-args.js";
12
14
  export * from "./interfaces/mcp/relay-mcp-server.js";
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./application/projection-service.js";
2
+ export * from "./application/relay-cli-service.js";
2
3
  export * from "./application/spawn-agents-service.js";
3
4
  export * from "./application/task-service.js";
4
5
  export * from "./core/errors.js";
@@ -9,5 +10,6 @@ export * from "./infrastructure/backends/cli-backend-executor.js";
9
10
  export * from "./infrastructure/process/process-executor.js";
10
11
  export * from "./infrastructure/store/relay-store.js";
11
12
  export * from "./interfaces/cli/visualization-renderer.js";
13
+ export * from "./interfaces/cli/relay-cli-args.js";
12
14
  export * from "./interfaces/mcp/relay-mcp-server.js";
13
15
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC;AACpD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+CAA+C,CAAC;AAC9D,cAAc,mDAAmD,CAAC;AAClE,cAAc,8CAA8C,CAAC;AAC7D,cAAc,uCAAuC,CAAC;AACtD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,sCAAsC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qCAAqC,CAAC;AACpD,cAAc,oCAAoC,CAAC;AACnD,cAAc,uCAAuC,CAAC;AACtD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kBAAkB,CAAC;AACjC,cAAc,iBAAiB,CAAC;AAChC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+CAA+C,CAAC;AAC9D,cAAc,mDAAmD,CAAC;AAClE,cAAc,8CAA8C,CAAC;AAC7D,cAAc,uCAAuC,CAAC;AACtD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,oCAAoC,CAAC;AACnD,cAAc,sCAAsC,CAAC"}
@@ -5,6 +5,12 @@ export interface ProcessExecutionInput {
5
5
  env: NodeJS.ProcessEnv;
6
6
  signal?: AbortSignal;
7
7
  }
8
+ export interface InteractiveProcessInput {
9
+ command: string;
10
+ args: string[];
11
+ cwd: string;
12
+ env: NodeJS.ProcessEnv;
13
+ }
8
14
  export interface ProcessExecutionOutput {
9
15
  exitCode: number;
10
16
  stdout: string;
@@ -13,6 +19,12 @@ export interface ProcessExecutionOutput {
13
19
  export interface ProcessExecutor {
14
20
  execute(input: ProcessExecutionInput): Promise<ProcessExecutionOutput>;
15
21
  }
22
+ export interface InteractiveProcessRunner {
23
+ run(input: InteractiveProcessInput): Promise<number>;
24
+ }
16
25
  export declare class ChildProcessExecutor implements ProcessExecutor {
17
26
  execute(input: ProcessExecutionInput): Promise<ProcessExecutionOutput>;
18
27
  }
28
+ export declare class ChildProcessInteractiveRunner implements InteractiveProcessRunner {
29
+ run(input: InteractiveProcessInput): Promise<number>;
30
+ }
@@ -51,4 +51,24 @@ export class ChildProcessExecutor {
51
51
  });
52
52
  }
53
53
  }
54
+ export class ChildProcessInteractiveRunner {
55
+ async run(input) {
56
+ return new Promise((resolve, reject) => {
57
+ const child = spawn(input.command, input.args, {
58
+ cwd: input.cwd,
59
+ env: input.env,
60
+ stdio: "inherit",
61
+ });
62
+ child.on("error", (error) => {
63
+ reject(new RelayError("PROCESS_SPAWN_FAILED", error.message, {
64
+ command: input.command,
65
+ args: input.args,
66
+ }));
67
+ });
68
+ child.on("close", (exitCode) => {
69
+ resolve(exitCode ?? 1);
70
+ });
71
+ });
72
+ }
73
+ }
54
74
  //# sourceMappingURL=process-executor.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"process-executor.js","sourceRoot":"","sources":["../../../src/infrastructure/process/process-executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAoBlD,MAAM,OAAO,oBAAoB;IAC/B,KAAK,CAAC,OAAO,CAAC,KAA4B;QACxC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE;gBAC7C,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;aAClC,CAAC,CAAC;YAEH,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,OAAO,GAAG,KAAK,CAAC;YAEpB,MAAM,KAAK,GAAG,GAAG,EAAE;gBACjB,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO;gBACT,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACtB,OAAO,GAAG,IAAI,CAAC;gBACf,MAAM,CAAC,IAAI,UAAU,CAAC,SAAS,EAAE,4BAA4B,CAAC,CAAC,CAAC;YAClE,CAAC,CAAC;YAEF,KAAK,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAE/D,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAsB,EAAE,EAAE;gBACjD,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC7B,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAsB,EAAE,EAAE;gBACjD,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC7B,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1B,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO;gBACT,CAAC;gBACD,OAAO,GAAG,IAAI,CAAC;gBACf,MAAM,CACJ,IAAI,UAAU,CAAC,sBAAsB,EAAE,KAAK,CAAC,OAAO,EAAE;oBACpD,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,IAAI,EAAE,KAAK,CAAC,IAAI;iBACjB,CAAC,CACH,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE;gBAC7B,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO;gBACT,CAAC;gBACD,OAAO,GAAG,IAAI,CAAC;gBACf,KAAK,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBAClD,OAAO,CAAC;oBACN,QAAQ,EAAE,QAAQ,IAAI,CAAC;oBACvB,MAAM;oBACN,MAAM;iBACP,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
1
+ {"version":3,"file":"process-executor.js","sourceRoot":"","sources":["../../../src/infrastructure/process/process-executor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AA+BlD,MAAM,OAAO,oBAAoB;IAC/B,KAAK,CAAC,OAAO,CAAC,KAA4B;QACxC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE;gBAC7C,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;aAClC,CAAC,CAAC;YAEH,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,MAAM,GAAG,EAAE,CAAC;YAChB,IAAI,OAAO,GAAG,KAAK,CAAC;YAEpB,MAAM,KAAK,GAAG,GAAG,EAAE;gBACjB,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO;gBACT,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACtB,OAAO,GAAG,IAAI,CAAC;gBACf,MAAM,CAAC,IAAI,UAAU,CAAC,SAAS,EAAE,4BAA4B,CAAC,CAAC,CAAC;YAClE,CAAC,CAAC;YAEF,KAAK,CAAC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAE/D,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAsB,EAAE,EAAE;gBACjD,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC7B,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAsB,EAAE,EAAE;gBACjD,MAAM,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YAC7B,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1B,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO;gBACT,CAAC;gBACD,OAAO,GAAG,IAAI,CAAC;gBACf,MAAM,CACJ,IAAI,UAAU,CAAC,sBAAsB,EAAE,KAAK,CAAC,OAAO,EAAE;oBACpD,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,IAAI,EAAE,KAAK,CAAC,IAAI;iBACjB,CAAC,CACH,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE;gBAC7B,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO;gBACT,CAAC;gBACD,OAAO,GAAG,IAAI,CAAC;gBACf,KAAK,CAAC,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBAClD,OAAO,CAAC;oBACN,QAAQ,EAAE,QAAQ,IAAI,CAAC;oBACvB,MAAM;oBACN,MAAM;iBACP,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AAED,MAAM,OAAO,6BAA6B;IACxC,KAAK,CAAC,GAAG,CAAC,KAA8B;QACtC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE;gBAC7C,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,KAAK,EAAE,SAAS;aACjB,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAC1B,MAAM,CACJ,IAAI,UAAU,CAAC,sBAAsB,EAAE,KAAK,CAAC,OAAO,EAAE;oBACpD,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,IAAI,EAAE,KAAK,CAAC,IAAI;iBACjB,CAAC,CACH,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE;gBAC7B,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;YACzB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ import type { RelayCliBannerInfo } from "../../application/relay-cli-service.js";
2
+ export declare function showLaunchBanner(info: RelayCliBannerInfo): Promise<void>;
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ import { Box, Text, render } from "ink";
3
+ export async function showLaunchBanner(info) {
4
+ const instance = render(React.createElement(LaunchBanner, { info }));
5
+ await new Promise((resolve) => setTimeout(resolve, 50));
6
+ instance.unmount();
7
+ }
8
+ function LaunchBanner(props) {
9
+ const { info } = props;
10
+ return React.createElement(Box, { flexDirection: "column", paddingBottom: 1 }, React.createElement(Text, { color: "cyanBright" }, "agentic-relay"), React.createElement(Text, null, `backend: ${info.backend} | available: ${info.availableBackends.join(", ")}`), info.resumeSessionId
11
+ ? React.createElement(Text, { color: "yellow" }, `resume: ${info.resumeSessionId}`)
12
+ : info.managedSessionId
13
+ ? React.createElement(Text, { color: "green" }, `session: ${info.managedSessionId}`)
14
+ : React.createElement(Text, { color: "gray" }, "session: backend-managed"));
15
+ }
16
+ //# sourceMappingURL=launch-banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-banner.js","sourceRoot":"","sources":["../../../src/interfaces/cli/launch-banner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAGxC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,IAAwB;IAC7D,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,YAAY,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACrE,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;IACxD,QAAQ,CAAC,OAAO,EAAE,CAAC;AACrB,CAAC;AAED,SAAS,YAAY,CAAC,KAAmC;IACvD,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IAEvB,OAAO,KAAK,CAAC,aAAa,CACxB,GAAG,EACH,EAAE,aAAa,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC,EAAE,EAC7C,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,eAAe,CAAC,EACnE,KAAK,CAAC,aAAa,CACjB,IAAI,EACJ,IAAI,EACJ,YAAY,IAAI,CAAC,OAAO,iBAAiB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC7E,EACD,IAAI,CAAC,eAAe;QAClB,CAAC,CAAC,KAAK,CAAC,aAAa,CACjB,IAAI,EACJ,EAAE,KAAK,EAAE,QAAQ,EAAE,EACnB,WAAW,IAAI,CAAC,eAAe,EAAE,CAClC;QACH,CAAC,CAAC,IAAI,CAAC,gBAAgB;YACrB,CAAC,CAAC,KAAK,CAAC,aAAa,CACjB,IAAI,EACJ,EAAE,KAAK,EAAE,OAAO,EAAE,EAClB,YAAY,IAAI,CAAC,gBAAgB,EAAE,CACpC;YACH,CAAC,CAAC,KAAK,CAAC,aAAa,CACjB,IAAI,EACJ,EAAE,KAAK,EAAE,MAAM,EAAE,EACjB,0BAA0B,CAC3B,CACR,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type BackendType } from "../../core/types.js";
2
+ export type RelayCliCommand = {
3
+ kind: "help";
4
+ } | {
5
+ kind: "mcp";
6
+ } | {
7
+ kind: "visualize";
8
+ } | {
9
+ kind: "relay";
10
+ backend?: BackendType;
11
+ prompt?: string;
12
+ resumeSessionId?: string;
13
+ };
14
+ export declare function parseRelayCliArgs(argv: string[]): RelayCliCommand;
@@ -0,0 +1,58 @@
1
+ import { ValidationError } from "../../core/errors.js";
2
+ import { BACKEND_TYPES } from "../../core/types.js";
3
+ export function parseRelayCliArgs(argv) {
4
+ if (argv.length === 0) {
5
+ return { kind: "relay" };
6
+ }
7
+ if (argv[0] === "mcp" && argv[1] === "serve") {
8
+ return { kind: "mcp" };
9
+ }
10
+ if (argv[0] === "visualize") {
11
+ return { kind: "visualize" };
12
+ }
13
+ if (argv[0] === "-h" || argv[0] === "--help") {
14
+ return { kind: "help" };
15
+ }
16
+ const args = [...argv];
17
+ let backend;
18
+ if (args[0] && isBackendType(args[0])) {
19
+ backend = args.shift();
20
+ }
21
+ let prompt;
22
+ let resumeSessionId;
23
+ for (let index = 0; index < args.length; index += 1) {
24
+ const current = args[index];
25
+ if (current === "-p" || current === "--prompt") {
26
+ prompt = readOptionValue(args, ++index, current);
27
+ continue;
28
+ }
29
+ if (current === "--resume") {
30
+ resumeSessionId = readOptionValue(args, ++index, current);
31
+ continue;
32
+ }
33
+ if (current === "-h" || current === "--help") {
34
+ return { kind: "help" };
35
+ }
36
+ if (current?.startsWith("-")) {
37
+ throw new ValidationError(`Unknown option: ${current}`);
38
+ }
39
+ throw new ValidationError(`Unknown command or argument: ${current}`);
40
+ }
41
+ return {
42
+ kind: "relay",
43
+ backend,
44
+ prompt,
45
+ resumeSessionId,
46
+ };
47
+ }
48
+ function isBackendType(value) {
49
+ return BACKEND_TYPES.includes(value);
50
+ }
51
+ function readOptionValue(args, index, option) {
52
+ const value = args[index];
53
+ if (!value) {
54
+ throw new ValidationError(`${option} requires a value.`);
55
+ }
56
+ return value;
57
+ }
58
+ //# sourceMappingURL=relay-cli-args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"relay-cli-args.js","sourceRoot":"","sources":["../../../src/interfaces/cli/relay-cli-args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAoB,MAAM,qBAAqB,CAAC;AAmBtE,MAAM,UAAU,iBAAiB,CAAC,IAAc;IAC9C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC;QAC7C,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC;IAED,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,WAAW,EAAE,CAAC;QAC5B,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC/B,CAAC;IAED,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAC1B,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;IACvB,IAAI,OAAgC,CAAC;IACrC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACtC,OAAO,GAAG,IAAI,CAAC,KAAK,EAAiB,CAAC;IACxC,CAAC;IAED,IAAI,MAA0B,CAAC;IAC/B,IAAI,eAAmC,CAAC;IAExC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YAC/C,MAAM,GAAG,eAAe,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YACjD,SAAS;QACX,CAAC;QACD,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YAC3B,eAAe,GAAG,eAAe,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;YAC1D,SAAS;QACX,CAAC;QACD,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,QAAQ,EAAE,CAAC;YAC7C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAC1B,CAAC;QACD,IAAI,OAAO,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,eAAe,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,MAAM,IAAI,eAAe,CAAC,gCAAgC,OAAO,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,OAAO;QACL,IAAI,EAAE,OAAO;QACb,OAAO;QACP,MAAM;QACN,eAAe;KAChB,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,aAAa,CAAC,QAAQ,CAAC,KAAoB,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,eAAe,CAAC,IAAc,EAAE,KAAa,EAAE,MAAc;IACpE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,eAAe,CAAC,GAAG,MAAM,oBAAoB,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -73,7 +73,7 @@ const deleteTaskInputSchema = {
73
73
  export function createRelayMcpServer(options) {
74
74
  const server = new McpServer({
75
75
  name: "agentic-relay",
76
- version: "3.6.0",
76
+ version: "3.7.0",
77
77
  });
78
78
  if (options.allowSpawnAgents) {
79
79
  server.tool("spawn_agents", "Launch one or more child agent CLI processes in parallel.", spawnAgentsInputSchema, async (args, extra) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rk0429/agentic-relay",
3
- "version": "3.6.0",
3
+ "version": "3.7.0",
4
4
  "displayName": "agentic-relay",
5
5
  "description": "Unified MCP relay for Claude Code, Codex CLI, and Gemini CLI",
6
6
  "type": "module",
@@ -97,10 +97,13 @@
97
97
  },
98
98
  "dependencies": {
99
99
  "@modelcontextprotocol/sdk": "1.27.1",
100
+ "ink": "6.3.1",
101
+ "react": "19.2.0",
100
102
  "zod": "4.3.6"
101
103
  },
102
104
  "devDependencies": {
103
105
  "@types/node": "24.7.2",
106
+ "@types/react": "19.2.2",
104
107
  "@types/vscode": "^1.110.0",
105
108
  "tsx": "4.21.0",
106
109
  "typescript": "5.9.3",