@rk0429/agentic-relay 2.0.8 → 2.0.9

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 (2) hide show
  1. package/dist/relay.mjs +94 -325
  2. package/package.json +1 -1
package/dist/relay.mjs CHANGED
@@ -204,129 +204,6 @@ var init_version_check = __esm({
204
204
  }
205
205
  });
206
206
 
207
- // src/mcp-server/deferred-cleanup-task-store.ts
208
- import { isTerminal } from "@modelcontextprotocol/sdk/experimental/tasks/interfaces.js";
209
- import { randomBytes } from "crypto";
210
- var DeferredCleanupTaskStore;
211
- var init_deferred_cleanup_task_store = __esm({
212
- "src/mcp-server/deferred-cleanup-task-store.ts"() {
213
- "use strict";
214
- DeferredCleanupTaskStore = class {
215
- tasks = /* @__PURE__ */ new Map();
216
- cleanupTimers = /* @__PURE__ */ new Map();
217
- generateTaskId() {
218
- return randomBytes(16).toString("hex");
219
- }
220
- async createTask(taskParams, requestId, request, _sessionId) {
221
- const taskId = this.generateTaskId();
222
- if (this.tasks.has(taskId)) {
223
- throw new Error(`Task with ID ${taskId} already exists`);
224
- }
225
- const actualTtl = taskParams.ttl ?? null;
226
- const createdAt = (/* @__PURE__ */ new Date()).toISOString();
227
- const task = {
228
- taskId,
229
- status: "working",
230
- ttl: actualTtl,
231
- createdAt,
232
- lastUpdatedAt: createdAt,
233
- pollInterval: taskParams.pollInterval ?? 1e3
234
- };
235
- this.tasks.set(taskId, { task, request, requestId });
236
- return { ...task };
237
- }
238
- async getTask(taskId, _sessionId) {
239
- const stored = this.tasks.get(taskId);
240
- return stored ? { ...stored.task } : null;
241
- }
242
- async storeTaskResult(taskId, status, result, _sessionId) {
243
- const stored = this.tasks.get(taskId);
244
- if (!stored) {
245
- throw new Error(`Task with ID ${taskId} not found`);
246
- }
247
- if (isTerminal(stored.task.status)) {
248
- throw new Error(
249
- `Cannot store result for task ${taskId} in terminal status '${stored.task.status}'. Task results can only be stored once.`
250
- );
251
- }
252
- stored.result = result;
253
- stored.task.status = status;
254
- stored.task.lastUpdatedAt = (/* @__PURE__ */ new Date()).toISOString();
255
- this.scheduleCleanup(taskId, stored.task.ttl);
256
- }
257
- async getTaskResult(taskId, _sessionId) {
258
- const stored = this.tasks.get(taskId);
259
- if (!stored) {
260
- throw new Error(`Task with ID ${taskId} not found`);
261
- }
262
- if (!stored.result) {
263
- throw new Error(`Task ${taskId} has no result stored`);
264
- }
265
- return stored.result;
266
- }
267
- async updateTaskStatus(taskId, status, statusMessage, _sessionId) {
268
- const stored = this.tasks.get(taskId);
269
- if (!stored) {
270
- throw new Error(`Task with ID ${taskId} not found`);
271
- }
272
- if (isTerminal(stored.task.status)) {
273
- throw new Error(
274
- `Cannot update task ${taskId} from terminal status '${stored.task.status}'.`
275
- );
276
- }
277
- stored.task.status = status;
278
- if (statusMessage) {
279
- stored.task.statusMessage = statusMessage;
280
- }
281
- stored.task.lastUpdatedAt = (/* @__PURE__ */ new Date()).toISOString();
282
- if (isTerminal(status)) {
283
- this.scheduleCleanup(taskId, stored.task.ttl);
284
- }
285
- }
286
- async listTasks(cursor, _sessionId) {
287
- const PAGE_SIZE = 10;
288
- const allTaskIds = Array.from(this.tasks.keys());
289
- let startIndex = 0;
290
- if (cursor) {
291
- const cursorIndex = allTaskIds.indexOf(cursor);
292
- if (cursorIndex >= 0) {
293
- startIndex = cursorIndex + 1;
294
- } else {
295
- throw new Error(`Invalid cursor: ${cursor}`);
296
- }
297
- }
298
- const pageTaskIds = allTaskIds.slice(startIndex, startIndex + PAGE_SIZE);
299
- const tasks = pageTaskIds.map((id) => {
300
- const stored = this.tasks.get(id);
301
- return { ...stored.task };
302
- });
303
- const nextCursor = startIndex + PAGE_SIZE < allTaskIds.length ? pageTaskIds[pageTaskIds.length - 1] : void 0;
304
- return { tasks, nextCursor };
305
- }
306
- /** Cleanup all timers (for testing or graceful shutdown) */
307
- cleanup() {
308
- for (const timer of this.cleanupTimers.values()) {
309
- clearTimeout(timer);
310
- }
311
- this.cleanupTimers.clear();
312
- this.tasks.clear();
313
- }
314
- scheduleCleanup(taskId, ttl) {
315
- if (!ttl) return;
316
- const existingTimer = this.cleanupTimers.get(taskId);
317
- if (existingTimer) {
318
- clearTimeout(existingTimer);
319
- }
320
- const timer = setTimeout(() => {
321
- this.tasks.delete(taskId);
322
- this.cleanupTimers.delete(taskId);
323
- }, ttl);
324
- this.cleanupTimers.set(taskId, timer);
325
- }
326
- };
327
- }
328
- });
329
-
330
207
  // src/core/agent-event-store.ts
331
208
  import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
332
209
  import { join as join6 } from "path";
@@ -8109,24 +7986,6 @@ var init_backend_selector = __esm({
8109
7986
  }
8110
7987
  });
8111
7988
 
8112
- // src/types/mcp.ts
8113
- var DEFAULT_TASK_TTL, DEFAULT_POLL_INTERVAL;
8114
- var init_mcp = __esm({
8115
- "src/types/mcp.ts"() {
8116
- "use strict";
8117
- DEFAULT_TASK_TTL = 5 * 60 * 1e3;
8118
- DEFAULT_POLL_INTERVAL = 3e3;
8119
- }
8120
- });
8121
-
8122
- // src/types/index.ts
8123
- var init_types2 = __esm({
8124
- "src/types/index.ts"() {
8125
- "use strict";
8126
- init_mcp();
8127
- }
8128
- });
8129
-
8130
7989
  // src/mcp-server/response-formatter.ts
8131
7990
  import * as fs from "fs";
8132
7991
  import * as path from "path";
@@ -8290,7 +8149,6 @@ __export(server_exports, {
8290
8149
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
8291
8150
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
8292
8151
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
8293
- import { InMemoryTaskMessageQueue } from "@modelcontextprotocol/sdk/experimental/tasks/stores/in-memory.js";
8294
8152
  import { createServer } from "http";
8295
8153
  import { mkdirSync as mkdirSync3 } from "fs";
8296
8154
  import path2 from "path";
@@ -8317,20 +8175,20 @@ function extractRelayContextFromUrl(url) {
8317
8175
  }
8318
8176
  return void 0;
8319
8177
  }
8320
- function createMcpServerOptions() {
8321
- const taskStore = new DeferredCleanupTaskStore();
8322
- return {
8323
- capabilities: { tasks: { requests: { tools: { call: {} } } } },
8324
- taskStore,
8325
- taskMessageQueue: new InMemoryTaskMessageQueue(),
8326
- defaultTaskPollInterval: DEFAULT_POLL_INTERVAL
8327
- };
8178
+ function combineAbortSignals(...signals) {
8179
+ const activeSignals = signals.filter((signal) => signal !== void 0);
8180
+ if (activeSignals.length === 0) {
8181
+ return void 0;
8182
+ }
8183
+ if (activeSignals.length === 1) {
8184
+ return activeSignals[0];
8185
+ }
8186
+ return AbortSignal.any(activeSignals);
8328
8187
  }
8329
8188
  var spawnAgentsParallelInputShape, MAX_CHILD_HTTP_SESSIONS, DEFAULT_TASKS_DB_PATH, RelayMCPServer;
8330
8189
  var init_server = __esm({
8331
8190
  "src/mcp-server/server.ts"() {
8332
8191
  "use strict";
8333
- init_deferred_cleanup_task_store();
8334
8192
  init_agent_event_store();
8335
8193
  init_session_health_monitor();
8336
8194
  init_recursion_guard();
@@ -8346,7 +8204,6 @@ var init_server = __esm({
8346
8204
  init_metadata_validation();
8347
8205
  init_logger();
8348
8206
  init_version_check();
8349
- init_types2();
8350
8207
  init_response_formatter();
8351
8208
  init_tasks();
8352
8209
  spawnAgentsParallelInputShape = {
@@ -8453,8 +8310,7 @@ var init_server = __esm({
8453
8310
  this.agentEventStore
8454
8311
  );
8455
8312
  this.server = new McpServer(
8456
- { name: "agentic-relay", version: "2.0.8" },
8457
- createMcpServerOptions()
8313
+ { name: "agentic-relay", version: "2.0.9" }
8458
8314
  );
8459
8315
  this.registerTools(this.server);
8460
8316
  this.sessionHealthMonitor.start();
@@ -8481,173 +8337,87 @@ var init_server = __esm({
8481
8337
  get childHttpServer() {
8482
8338
  return this._childHttpServer;
8483
8339
  }
8484
- /**
8485
- * Run spawn_agent in the background and store the result in taskStore.
8486
- * Fire-and-forget: errors are caught and stored as failed task results.
8487
- */
8488
- runSpawnAgentInBackground(taskId, params, extra, relayContext, signal) {
8489
- const run = async () => {
8490
- try {
8491
- const result = await executeSpawnAgent(
8492
- params,
8493
- this.registry,
8494
- this.sessionManager,
8495
- this.guard,
8496
- this.hooksEngine,
8497
- this.contextMonitor,
8498
- this.backendSelector,
8499
- this._childHttpUrl,
8500
- void 0,
8501
- this.agentEventStore,
8502
- this.hookMemoryDir,
8503
- void 0,
8504
- this.taskLifecycleManager,
8505
- relayContext,
8506
- signal
8507
- );
8508
- const controlOptions = {
8509
- inlineSummaryLength: this.inlineSummaryLength ?? DEFAULT_INLINE_SUMMARY_LENGTH,
8510
- sessionId: result.sessionId,
8511
- responseOutputDir: this.responseOutputDir
8512
- };
8513
- const { text, isError } = await formatSpawnAgentResponse(result, controlOptions);
8514
- const callToolResult = {
8515
- content: [{ type: "text", text }],
8516
- isError
8517
- };
8518
- await extra.taskStore.storeTaskResult(
8519
- taskId,
8520
- "completed",
8521
- callToolResult
8522
- );
8523
- } catch (outerError) {
8524
- try {
8525
- const message = outerError instanceof Error ? outerError.message : String(outerError);
8526
- await extra.taskStore.storeTaskResult(
8527
- taskId,
8528
- "failed",
8529
- {
8530
- content: [{ type: "text", text: `Error: ${message}` }],
8531
- isError: true
8532
- }
8533
- );
8534
- } catch (storeError) {
8535
- logger.error(
8536
- `Failed to store task result for ${taskId}: ${storeError instanceof Error ? storeError.message : String(storeError)}`
8537
- );
8538
- }
8539
- }
8540
- };
8541
- void run();
8542
- }
8543
- /**
8544
- * Run spawn_agents_parallel in the background and store the result in taskStore.
8545
- * Fire-and-forget: errors are caught and stored as failed task results.
8546
- */
8547
- runSpawnAgentsParallelInBackground(taskId, agents, extra, relayContext, signal) {
8548
- const run = async () => {
8549
- try {
8550
- const result = await executeSpawnAgentsParallel(
8551
- agents,
8552
- this.registry,
8553
- this.sessionManager,
8554
- this.guard,
8555
- this.hooksEngine,
8556
- this.contextMonitor,
8557
- this.backendSelector,
8558
- this._childHttpUrl,
8559
- void 0,
8560
- this.agentEventStore,
8561
- this.hookMemoryDir,
8562
- void 0,
8563
- this.taskLifecycleManager,
8564
- relayContext,
8565
- signal
8566
- );
8567
- const controlOptions = {
8568
- inlineSummaryLength: this.inlineSummaryLength ?? DEFAULT_INLINE_SUMMARY_LENGTH,
8569
- responseOutputDir: this.responseOutputDir
8570
- };
8571
- const { text, isError } = await formatParallelResponse(result, controlOptions);
8572
- const callToolResult = {
8573
- content: [{ type: "text", text }],
8574
- isError
8575
- };
8576
- await extra.taskStore.storeTaskResult(
8577
- taskId,
8578
- "completed",
8579
- callToolResult
8580
- );
8581
- } catch (outerError) {
8582
- try {
8583
- const message = outerError instanceof Error ? outerError.message : String(outerError);
8584
- await extra.taskStore.storeTaskResult(
8585
- taskId,
8586
- "failed",
8587
- {
8588
- content: [{ type: "text", text: `Error: ${message}` }],
8589
- isError: true
8590
- }
8591
- );
8592
- } catch (storeError) {
8593
- logger.error(
8594
- `Failed to store parallel task result for ${taskId}: ${storeError instanceof Error ? storeError.message : String(storeError)}`
8595
- );
8596
- }
8597
- }
8598
- };
8599
- void run();
8600
- }
8601
- registerTools(server, relayContext, signal) {
8602
- server.experimental.tasks.registerToolTask(
8340
+ registerTools(server, relayContext, sessionSignal) {
8341
+ server.tool(
8603
8342
  "spawn_agent",
8604
- {
8605
- description: "Spawn a sub-agent on a backend CLI (Claude Code, Codex CLI, or Gemini CLI). The agent executes the given prompt in non-interactive mode and returns the result. Backend is auto-selected by priority: agentType mapping (coder/researcher\u2192codex, documenter\u2192claude) > taskType mapping > default (claude). metadata with metadata.taskId is required for task-first delegation. Use 'agentDefinition' to inject an agent .md file, 'skillContext' for a SKILL.md, or 'systemPrompt' for custom instructions.",
8606
- inputSchema: spawnAgentInputSchema.shape,
8607
- execution: { taskSupport: "optional" }
8608
- },
8609
- {
8610
- createTask: async (params, extra) => {
8611
- const task = await extra.taskStore.createTask({
8612
- ttl: DEFAULT_TASK_TTL,
8613
- pollInterval: DEFAULT_POLL_INTERVAL
8614
- });
8615
- this.runSpawnAgentInBackground(task.taskId, params, extra, relayContext, signal);
8616
- return { task };
8617
- },
8618
- getTask: async (_params, extra) => {
8619
- return await extra.taskStore.getTask(extra.taskId);
8620
- },
8621
- getTaskResult: async (_params, extra) => {
8622
- return await extra.taskStore.getTaskResult(
8623
- extra.taskId
8343
+ "Spawn a sub-agent on a backend CLI (Claude Code, Codex CLI, or Gemini CLI). The agent executes the given prompt in non-interactive mode and returns the result. Backend is auto-selected by priority: agentType mapping (coder/researcher\u2192codex, documenter\u2192claude) > taskType mapping > default (claude). metadata with metadata.taskId is required for task-first delegation. Use 'agentDefinition' to inject an agent .md file, 'skillContext' for a SKILL.md, or 'systemPrompt' for custom instructions.",
8344
+ spawnAgentInputSchema.shape,
8345
+ async (params, extra) => {
8346
+ try {
8347
+ const result = await executeSpawnAgent(
8348
+ params,
8349
+ this.registry,
8350
+ this.sessionManager,
8351
+ this.guard,
8352
+ this.hooksEngine,
8353
+ this.contextMonitor,
8354
+ this.backendSelector,
8355
+ this._childHttpUrl,
8356
+ void 0,
8357
+ this.agentEventStore,
8358
+ this.hookMemoryDir,
8359
+ void 0,
8360
+ this.taskLifecycleManager,
8361
+ relayContext,
8362
+ combineAbortSignals(extra.signal, sessionSignal)
8624
8363
  );
8364
+ const controlOptions = {
8365
+ inlineSummaryLength: this.inlineSummaryLength ?? DEFAULT_INLINE_SUMMARY_LENGTH,
8366
+ sessionId: result.sessionId,
8367
+ responseOutputDir: this.responseOutputDir
8368
+ };
8369
+ const { text, isError } = await formatSpawnAgentResponse(result, controlOptions);
8370
+ return {
8371
+ content: [{ type: "text", text }],
8372
+ isError
8373
+ };
8374
+ } catch (error) {
8375
+ const message = error instanceof Error ? error.message : String(error);
8376
+ return {
8377
+ content: [{ type: "text", text: `Error: ${message}` }],
8378
+ isError: true
8379
+ };
8625
8380
  }
8626
8381
  }
8627
8382
  );
8628
- server.experimental.tasks.registerToolTask(
8383
+ server.tool(
8629
8384
  "spawn_agents_parallel",
8630
- {
8631
- description: "Spawn multiple sub-agents in parallel across available backends. Use this when you have 2+ independent tasks that can execute concurrently. Each agent entry accepts the same parameters as spawn_agent. Results are returned as an array with per-agent status (success/failure). RecursionGuard batch pre-validation ensures the batch fits within call limits. Failed results include 'originalInput' for retry via retry_failed_agents.",
8632
- inputSchema: spawnAgentsParallelInputShape,
8633
- execution: { taskSupport: "optional" }
8634
- },
8635
- {
8636
- createTask: async (params, extra) => {
8637
- const task = await extra.taskStore.createTask({
8638
- ttl: DEFAULT_TASK_TTL,
8639
- pollInterval: DEFAULT_POLL_INTERVAL
8640
- });
8641
- this.runSpawnAgentsParallelInBackground(task.taskId, params.agents, extra, relayContext, signal);
8642
- return { task };
8643
- },
8644
- getTask: async (_params, extra) => {
8645
- return await extra.taskStore.getTask(extra.taskId);
8646
- },
8647
- getTaskResult: async (_params, extra) => {
8648
- return await extra.taskStore.getTaskResult(
8649
- extra.taskId
8385
+ "Spawn multiple sub-agents in parallel across available backends. Use this when you have 2+ independent tasks that can execute concurrently. Each agent entry accepts the same parameters as spawn_agent. Results are returned as an array with per-agent status (success/failure). RecursionGuard batch pre-validation ensures the batch fits within call limits. Failed results include 'originalInput' for retry via retry_failed_agents.",
8386
+ spawnAgentsParallelInputShape,
8387
+ async (params, extra) => {
8388
+ try {
8389
+ const result = await executeSpawnAgentsParallel(
8390
+ params.agents,
8391
+ this.registry,
8392
+ this.sessionManager,
8393
+ this.guard,
8394
+ this.hooksEngine,
8395
+ this.contextMonitor,
8396
+ this.backendSelector,
8397
+ this._childHttpUrl,
8398
+ void 0,
8399
+ this.agentEventStore,
8400
+ this.hookMemoryDir,
8401
+ void 0,
8402
+ this.taskLifecycleManager,
8403
+ relayContext,
8404
+ combineAbortSignals(extra.signal, sessionSignal)
8650
8405
  );
8406
+ const controlOptions = {
8407
+ inlineSummaryLength: this.inlineSummaryLength ?? DEFAULT_INLINE_SUMMARY_LENGTH,
8408
+ responseOutputDir: this.responseOutputDir
8409
+ };
8410
+ const { text, isError } = await formatParallelResponse(result, controlOptions);
8411
+ return {
8412
+ content: [{ type: "text", text }],
8413
+ isError
8414
+ };
8415
+ } catch (error) {
8416
+ const message = error instanceof Error ? error.message : String(error);
8417
+ return {
8418
+ content: [{ type: "text", text: `Error: ${message}` }],
8419
+ isError: true
8420
+ };
8651
8421
  }
8652
8422
  }
8653
8423
  );
@@ -8660,7 +8430,7 @@ var init_server = __esm({
8660
8430
  originalInput: spawnAgentInputSchema
8661
8431
  })).min(1).describe("Array of failed results with their original input configurations")
8662
8432
  },
8663
- async (params) => {
8433
+ async (params, extra) => {
8664
8434
  try {
8665
8435
  const agents = params.failedResults.map((r) => ({ ...r.originalInput }));
8666
8436
  const result = await executeSpawnAgentsParallel(
@@ -8678,7 +8448,7 @@ var init_server = __esm({
8678
8448
  void 0,
8679
8449
  this.taskLifecycleManager,
8680
8450
  relayContext,
8681
- signal
8451
+ combineAbortSignals(extra.signal, sessionSignal)
8682
8452
  );
8683
8453
  const controlOptions = {
8684
8454
  inlineSummaryLength: this.inlineSummaryLength ?? DEFAULT_INLINE_SUMMARY_LENGTH,
@@ -8972,8 +8742,7 @@ var init_server = __esm({
8972
8742
  sessionIdGenerator: () => randomUUID()
8973
8743
  });
8974
8744
  const server = new McpServer(
8975
- { name: "agentic-relay", version: "2.0.8" },
8976
- createMcpServerOptions()
8745
+ { name: "agentic-relay", version: "2.0.9" }
8977
8746
  );
8978
8747
  this.registerTools(server, childRelayContext, abortController.signal);
8979
8748
  transport.onclose = () => {
@@ -8984,7 +8753,7 @@ var init_server = __esm({
8984
8753
  if (ctrl) {
8985
8754
  ctrl.abort();
8986
8755
  sessionAbortControllers.delete(sid2);
8987
- logger.debug(`Child MCP session closed, background tasks aborted: ${sid2}`);
8756
+ logger.debug(`Child MCP session closed, in-flight requests aborted: ${sid2}`);
8988
8757
  } else {
8989
8758
  logger.debug(`Child MCP session closed: ${sid2}`);
8990
8759
  }
@@ -9748,7 +9517,7 @@ __export(types_exports, {
9748
9517
  DEFAULT_TUI_CONFIG: () => DEFAULT_TUI_CONFIG
9749
9518
  });
9750
9519
  var DEFAULT_TUI_CONFIG;
9751
- var init_types3 = __esm({
9520
+ var init_types2 = __esm({
9752
9521
  "src/tui/types.ts"() {
9753
9522
  "use strict";
9754
9523
  DEFAULT_TUI_CONFIG = {
@@ -9772,7 +9541,7 @@ var TUIConfigManager;
9772
9541
  var init_tui_config_manager = __esm({
9773
9542
  "src/tui/services/tui-config-manager.ts"() {
9774
9543
  "use strict";
9775
- init_types3();
9544
+ init_types2();
9776
9545
  TUIConfigManager = class {
9777
9546
  constructor(configManager2) {
9778
9547
  this.configManager = configManager2;
@@ -10099,7 +9868,7 @@ function App({ registry: registry2, sessionManager: sessionManager2, hooksEngine
10099
9868
  setTuiConfig(updated);
10100
9869
  setStatusMessage(`Config updated: ${key} = ${JSON.stringify(value)}`);
10101
9870
  } else if (subCmd === "reset") {
10102
- const { DEFAULT_TUI_CONFIG: DEFAULT_TUI_CONFIG2 } = await Promise.resolve().then(() => (init_types3(), types_exports));
9871
+ const { DEFAULT_TUI_CONFIG: DEFAULT_TUI_CONFIG2 } = await Promise.resolve().then(() => (init_types2(), types_exports));
10103
9872
  for (const [section, sectionValue] of Object.entries(DEFAULT_TUI_CONFIG2)) {
10104
9873
  for (const [k, v] of Object.entries(sectionValue)) {
10105
9874
  await tuiConfigManager.set(`${section}.${k}`, v);
@@ -13617,7 +13386,7 @@ function createMCPCommand(configManager2, registry2, sessionManager2, hooksEngin
13617
13386
  responseOutputDir,
13618
13387
  relayConfig
13619
13388
  );
13620
- await server.start({ transport, port, currentVersion: "2.0.8" });
13389
+ await server.start({ transport, port, currentVersion: "2.0.9" });
13621
13390
  }
13622
13391
  })
13623
13392
  },
@@ -13777,7 +13546,7 @@ function createVersionCommand(registry2) {
13777
13546
  description: "Show relay and backend versions"
13778
13547
  },
13779
13548
  async run() {
13780
- const relayVersion = "2.0.8";
13549
+ const relayVersion = "2.0.9";
13781
13550
  console.log(`agentic-relay v${relayVersion}`);
13782
13551
  console.log("");
13783
13552
  console.log("Backends:");
@@ -14174,7 +13943,7 @@ var subCommandNames = /* @__PURE__ */ new Set(["claude", "codex", "gemini", "upd
14174
13943
  var main = defineCommand11({
14175
13944
  meta: {
14176
13945
  name: "relay",
14177
- version: "2.0.8",
13946
+ version: "2.0.9",
14178
13947
  description: "Unified CLI proxy for Claude Code, Codex CLI, and Gemini CLI"
14179
13948
  },
14180
13949
  args: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rk0429/agentic-relay",
3
- "version": "2.0.8",
3
+ "version": "2.0.9",
4
4
  "description": "Unified CLI proxy for Claude Code, Codex CLI, and Gemini CLI with MCP-based multi-layer sub-agent orchestration",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",