@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 +13 -0
- package/dist/application/relay-cli-service.d.ts +54 -0
- package/dist/application/relay-cli-service.js +174 -0
- package/dist/application/relay-cli-service.js.map +1 -0
- package/dist/bin/relay.js +68 -25
- package/dist/bin/relay.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/process/process-executor.d.ts +12 -0
- package/dist/infrastructure/process/process-executor.js +20 -0
- package/dist/infrastructure/process/process-executor.js.map +1 -1
- package/dist/interfaces/cli/launch-banner.d.ts +2 -0
- package/dist/interfaces/cli/launch-banner.js +16 -0
- package/dist/interfaces/cli/launch-banner.js.map +1 -0
- package/dist/interfaces/cli/relay-cli-args.d.ts +14 -0
- package/dist/interfaces/cli/relay-cli-args.js +58 -0
- package/dist/interfaces/cli/relay-cli-args.js.map +1 -0
- package/dist/interfaces/mcp/relay-mcp-server.js +1 -1
- package/package.json +4 -1
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
|
|
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 (
|
|
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
|
|
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
|
-
|
|
41
|
-
backendRegistry
|
|
42
|
-
|
|
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
|
-
|
|
63
|
+
backendRegistry,
|
|
64
|
+
backendExecutor,
|
|
65
|
+
interactiveRunner: new ChildProcessInteractiveRunner(),
|
|
45
66
|
cwd,
|
|
46
67
|
env: process.env,
|
|
47
68
|
});
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
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
|
package/dist/bin/relay.js.map
CHANGED
|
@@ -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,
|
|
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;
|
|
1
|
+
{"version":3,"file":"process-executor.js","sourceRoot":"","sources":["../../../src/infrastructure/process/process-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -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.
|
|
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.
|
|
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",
|