agent-relay 6.0.22 → 6.2.1

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 (117) hide show
  1. package/dist/index.cjs +338 -49
  2. package/dist/src/cli/bootstrap.d.ts.map +1 -1
  3. package/dist/src/cli/bootstrap.js +62 -0
  4. package/dist/src/cli/bootstrap.js.map +1 -1
  5. package/dist/src/cli/commands/agent-management.d.ts +8 -0
  6. package/dist/src/cli/commands/agent-management.d.ts.map +1 -1
  7. package/dist/src/cli/commands/agent-management.js +34 -0
  8. package/dist/src/cli/commands/agent-management.js.map +1 -1
  9. package/dist/src/cli/commands/drive.d.ts +222 -0
  10. package/dist/src/cli/commands/drive.d.ts.map +1 -0
  11. package/dist/src/cli/commands/drive.js +565 -0
  12. package/dist/src/cli/commands/drive.js.map +1 -0
  13. package/dist/src/cli/commands/messaging.d.ts +25 -0
  14. package/dist/src/cli/commands/messaging.d.ts.map +1 -1
  15. package/dist/src/cli/commands/messaging.js +702 -138
  16. package/dist/src/cli/commands/messaging.js.map +1 -1
  17. package/dist/src/cli/commands/new.d.ts +112 -0
  18. package/dist/src/cli/commands/new.d.ts.map +1 -0
  19. package/dist/src/cli/commands/new.js +189 -0
  20. package/dist/src/cli/commands/new.js.map +1 -0
  21. package/dist/src/cli/commands/on/provision.d.ts +1 -1
  22. package/dist/src/cli/commands/on/provision.d.ts.map +1 -1
  23. package/dist/src/cli/commands/on/provision.js +1 -1
  24. package/dist/src/cli/commands/on/provision.js.map +1 -1
  25. package/dist/src/cli/commands/on/start.d.ts +1 -1
  26. package/dist/src/cli/commands/on/start.d.ts.map +1 -1
  27. package/dist/src/cli/commands/on/start.js +2 -2
  28. package/dist/src/cli/commands/on/start.js.map +1 -1
  29. package/dist/src/cli/commands/passthrough.d.ts +142 -0
  30. package/dist/src/cli/commands/passthrough.d.ts.map +1 -0
  31. package/dist/src/cli/commands/passthrough.js +398 -0
  32. package/dist/src/cli/commands/passthrough.js.map +1 -0
  33. package/dist/src/cli/commands/rm.d.ts +52 -0
  34. package/dist/src/cli/commands/rm.d.ts.map +1 -0
  35. package/dist/src/cli/commands/rm.js +96 -0
  36. package/dist/src/cli/commands/rm.js.map +1 -0
  37. package/dist/src/cli/commands/view.d.ts +98 -0
  38. package/dist/src/cli/commands/view.d.ts.map +1 -0
  39. package/dist/src/cli/commands/view.js +238 -0
  40. package/dist/src/cli/commands/view.js.map +1 -0
  41. package/dist/src/cli/lib/agent-management-listing.d.ts +35 -7
  42. package/dist/src/cli/lib/agent-management-listing.d.ts.map +1 -1
  43. package/dist/src/cli/lib/agent-management-listing.js +188 -40
  44. package/dist/src/cli/lib/agent-management-listing.js.map +1 -1
  45. package/dist/src/cli/lib/attach.d.ts +56 -0
  46. package/dist/src/cli/lib/attach.d.ts.map +1 -0
  47. package/dist/src/cli/lib/attach.js +73 -0
  48. package/dist/src/cli/lib/attach.js.map +1 -0
  49. package/dist/src/cli/lib/broker-connection.d.ts +40 -0
  50. package/dist/src/cli/lib/broker-connection.d.ts.map +1 -0
  51. package/dist/src/cli/lib/broker-connection.js +82 -0
  52. package/dist/src/cli/lib/broker-connection.js.map +1 -0
  53. package/dist/src/cli/lib/formatting.d.ts +4 -0
  54. package/dist/src/cli/lib/formatting.d.ts.map +1 -1
  55. package/dist/src/cli/lib/formatting.js +31 -1
  56. package/dist/src/cli/lib/formatting.js.map +1 -1
  57. package/dist/src/cli/lib/sdk-client.d.ts +9 -0
  58. package/dist/src/cli/lib/sdk-client.d.ts.map +1 -0
  59. package/dist/src/cli/lib/sdk-client.js +28 -0
  60. package/dist/src/cli/lib/sdk-client.js.map +1 -0
  61. package/dist/src/cli/lib/spawn-and-attach.d.ts +132 -0
  62. package/dist/src/cli/lib/spawn-and-attach.d.ts.map +1 -0
  63. package/dist/src/cli/lib/spawn-and-attach.js +334 -0
  64. package/dist/src/cli/lib/spawn-and-attach.js.map +1 -0
  65. package/package.json +12 -10
  66. package/dist/packages/cloud/src/api-client.d.ts +0 -33
  67. package/dist/packages/cloud/src/api-client.d.ts.map +0 -1
  68. package/dist/packages/cloud/src/api-client.js +0 -123
  69. package/dist/packages/cloud/src/api-client.js.map +0 -1
  70. package/dist/packages/cloud/src/auth.d.ts +0 -13
  71. package/dist/packages/cloud/src/auth.d.ts.map +0 -1
  72. package/dist/packages/cloud/src/auth.js +0 -299
  73. package/dist/packages/cloud/src/auth.js.map +0 -1
  74. package/dist/packages/cloud/src/connect.d.ts +0 -45
  75. package/dist/packages/cloud/src/connect.d.ts.map +0 -1
  76. package/dist/packages/cloud/src/connect.js +0 -166
  77. package/dist/packages/cloud/src/connect.js.map +0 -1
  78. package/dist/packages/cloud/src/index.d.ts +0 -10
  79. package/dist/packages/cloud/src/index.d.ts.map +0 -1
  80. package/dist/packages/cloud/src/index.js +0 -10
  81. package/dist/packages/cloud/src/index.js.map +0 -1
  82. package/dist/packages/cloud/src/lib/ssh-interactive.d.ts +0 -70
  83. package/dist/packages/cloud/src/lib/ssh-interactive.d.ts.map +0 -1
  84. package/dist/packages/cloud/src/lib/ssh-interactive.js +0 -440
  85. package/dist/packages/cloud/src/lib/ssh-interactive.js.map +0 -1
  86. package/dist/packages/cloud/src/lib/ssh-runtime.d.ts +0 -35
  87. package/dist/packages/cloud/src/lib/ssh-runtime.d.ts.map +0 -1
  88. package/dist/packages/cloud/src/lib/ssh-runtime.js +0 -52
  89. package/dist/packages/cloud/src/lib/ssh-runtime.js.map +0 -1
  90. package/dist/packages/cloud/src/proactive-runtime.d.ts +0 -24
  91. package/dist/packages/cloud/src/proactive-runtime.d.ts.map +0 -1
  92. package/dist/packages/cloud/src/proactive-runtime.js +0 -315
  93. package/dist/packages/cloud/src/proactive-runtime.js.map +0 -1
  94. package/dist/packages/cloud/src/types.d.ts +0 -200
  95. package/dist/packages/cloud/src/types.d.ts.map +0 -1
  96. package/dist/packages/cloud/src/types.js +0 -12
  97. package/dist/packages/cloud/src/types.js.map +0 -1
  98. package/dist/packages/cloud/src/workflows.d.ts +0 -65
  99. package/dist/packages/cloud/src/workflows.d.ts.map +0 -1
  100. package/dist/packages/cloud/src/workflows.js +0 -892
  101. package/dist/packages/cloud/src/workflows.js.map +0 -1
  102. package/dist/packages/cloud/src/workspaces.d.ts +0 -11
  103. package/dist/packages/cloud/src/workspaces.d.ts.map +0 -1
  104. package/dist/packages/cloud/src/workspaces.js +0 -146
  105. package/dist/packages/cloud/src/workspaces.js.map +0 -1
  106. package/dist/packages/sdk/src/provisioner/local-jwks.d.ts +0 -25
  107. package/dist/packages/sdk/src/provisioner/local-jwks.d.ts.map +0 -1
  108. package/dist/packages/sdk/src/provisioner/local-jwks.js +0 -70
  109. package/dist/packages/sdk/src/provisioner/local-jwks.js.map +0 -1
  110. package/dist/packages/sdk/src/provisioner/seeder.d.ts +0 -17
  111. package/dist/packages/sdk/src/provisioner/seeder.d.ts.map +0 -1
  112. package/dist/packages/sdk/src/provisioner/seeder.js +0 -419
  113. package/dist/packages/sdk/src/provisioner/seeder.js.map +0 -1
  114. package/dist/packages/sdk/src/provisioner/token.d.ts +0 -41
  115. package/dist/packages/sdk/src/provisioner/token.d.ts.map +0 -1
  116. package/dist/packages/sdk/src/provisioner/token.js +0 -77
  117. package/dist/packages/sdk/src/provisioner/token.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -18571,7 +18571,7 @@ function createWorkflowRenderer() {
18571
18571
  });
18572
18572
  workflowDone.catch(() => {
18573
18573
  });
18574
- let setHeader = () => {
18574
+ let setHeader2 = () => {
18575
18575
  };
18576
18576
  let listr = null;
18577
18577
  const pendingAdds = [];
@@ -18583,7 +18583,7 @@ function createWorkflowRenderer() {
18583
18583
  {
18584
18584
  title: import_chalk3.default.dim("Workflow starting..."),
18585
18585
  task: async (_ctx, task) => {
18586
- setHeader = (text) => {
18586
+ setHeader2 = (text) => {
18587
18587
  task.title = text;
18588
18588
  };
18589
18589
  await workflowDone;
@@ -18611,7 +18611,7 @@ function createWorkflowRenderer() {
18611
18611
  const onEvent = (event) => {
18612
18612
  switch (event.type) {
18613
18613
  case "run:started": {
18614
- setHeader(import_chalk3.default.dim(`[workflow] run ${event.runId.slice(0, 8)}...`));
18614
+ setHeader2(import_chalk3.default.dim(`[workflow] run ${event.runId.slice(0, 8)}...`));
18615
18615
  break;
18616
18616
  }
18617
18617
  case "step:started": {
@@ -18709,17 +18709,17 @@ function createWorkflowRenderer() {
18709
18709
  break;
18710
18710
  }
18711
18711
  case "run:completed": {
18712
- setHeader(import_chalk3.default.green("Workflow completed"));
18712
+ setHeader2(import_chalk3.default.green("Workflow completed"));
18713
18713
  resolveWorkflow();
18714
18714
  break;
18715
18715
  }
18716
18716
  case "run:failed": {
18717
- setHeader(import_chalk3.default.red(`Workflow failed: ${event.error ?? "unknown error"}`));
18717
+ setHeader2(import_chalk3.default.red(`Workflow failed: ${event.error ?? "unknown error"}`));
18718
18718
  rejectWorkflow(new Error(event.error ?? "Workflow failed"));
18719
18719
  break;
18720
18720
  }
18721
18721
  case "run:cancelled": {
18722
- setHeader(import_chalk3.default.yellow("Workflow cancelled"));
18722
+ setHeader2(import_chalk3.default.yellow("Workflow cancelled"));
18723
18723
  resolveWorkflow();
18724
18724
  break;
18725
18725
  }
@@ -19866,7 +19866,7 @@ async function parseJsonResponse(response) {
19866
19866
  {
19867
19867
  status: response.status,
19868
19868
  responseBody: text,
19869
- responseHeaders: headersToRecord(response.headers)
19869
+ responseHeaders: headersToRecord2(response.headers)
19870
19870
  }
19871
19871
  );
19872
19872
  }
@@ -19881,7 +19881,7 @@ async function parseJsonResponse(response) {
19881
19881
  {
19882
19882
  status: response.status,
19883
19883
  responseBody: text,
19884
- responseHeaders: headersToRecord(response.headers),
19884
+ responseHeaders: headersToRecord2(response.headers),
19885
19885
  cause: error51
19886
19886
  }
19887
19887
  );
@@ -19898,7 +19898,7 @@ function joinUrl(baseUrl, path28) {
19898
19898
  function stripLeadingSlash(value) {
19899
19899
  return value.replace(/^\/+/, "");
19900
19900
  }
19901
- function headersToRecord(headers) {
19901
+ function headersToRecord2(headers) {
19902
19902
  const record2 = {};
19903
19903
  headers.forEach((value, key) => {
19904
19904
  record2[key] = value;
@@ -34027,7 +34027,7 @@ var require_axios = __commonJS({
34027
34027
  }
34028
34028
  set(header, valueOrRewrite, rewrite) {
34029
34029
  const self2 = this;
34030
- function setHeader(_value, _header, _rewrite) {
34030
+ function setHeader2(_value, _header, _rewrite) {
34031
34031
  const lHeader = normalizeHeader(_header);
34032
34032
  if (!lHeader) {
34033
34033
  throw new Error("header name must be a non-empty string");
@@ -34037,7 +34037,7 @@ var require_axios = __commonJS({
34037
34037
  self2[key || _header] = normalizeValue(_value);
34038
34038
  }
34039
34039
  }
34040
- const setHeaders = (headers, _rewrite) => utils$1.forEach(headers, (_value, _header) => setHeader(_value, _header, _rewrite));
34040
+ const setHeaders = (headers, _rewrite) => utils$1.forEach(headers, (_value, _header) => setHeader2(_value, _header, _rewrite));
34041
34041
  if (utils$1.isPlainObject(header) || header instanceof this.constructor) {
34042
34042
  setHeaders(header, valueOrRewrite);
34043
34043
  } else if (utils$1.isString(header) && (header = header.trim()) && !isValidHeaderName(header)) {
@@ -34052,7 +34052,7 @@ var require_axios = __commonJS({
34052
34052
  }
34053
34053
  setHeaders(obj, valueOrRewrite);
34054
34054
  } else {
34055
- header != null && setHeader(valueOrRewrite, header, rewrite);
34055
+ header != null && setHeader2(valueOrRewrite, header, rewrite);
34056
34056
  }
34057
34057
  return this;
34058
34058
  }
@@ -43732,18 +43732,21 @@ var wrapper_default = import_websocket.default;
43732
43732
  var AgentRelayProtocolError = class extends Error {
43733
43733
  code;
43734
43734
  retryable;
43735
+ status;
43735
43736
  data;
43736
43737
  constructor(payload) {
43737
43738
  super(payload.message);
43738
43739
  this.name = "AgentRelayProtocolError";
43739
43740
  this.code = payload.code;
43740
43741
  this.retryable = payload.retryable ?? false;
43742
+ this.status = payload.status;
43741
43743
  this.data = payload.data;
43742
43744
  }
43743
43745
  };
43744
43746
  var BrokerTransport = class {
43745
43747
  baseUrl;
43746
43748
  apiKey;
43749
+ fetchFn;
43747
43750
  requestTimeoutMs;
43748
43751
  maxBufferSize;
43749
43752
  ws = null;
@@ -43756,6 +43759,7 @@ var BrokerTransport = class {
43756
43759
  constructor(options) {
43757
43760
  this.baseUrl = options.baseUrl.replace(/\/$/, "");
43758
43761
  this.apiKey = options.apiKey;
43762
+ this.fetchFn = options.fetch ?? fetch;
43759
43763
  this.requestTimeoutMs = options.requestTimeoutMs ?? 3e4;
43760
43764
  this.maxBufferSize = options.maxBufferSize ?? 1e3;
43761
43765
  }
@@ -43767,15 +43771,15 @@ var BrokerTransport = class {
43767
43771
  }
43768
43772
  // ── HTTP ─────────────────────────────────────────────────────────────
43769
43773
  async request(path28, init) {
43770
- const headers = new Headers(init?.headers);
43771
- if (!headers.has("Content-Type")) {
43772
- headers.set("Content-Type", "application/json");
43774
+ const headers = headersToRecord(init?.headers);
43775
+ if (init?.body !== void 0 && !hasHeader(headers, "Content-Type")) {
43776
+ headers["Content-Type"] = "application/json";
43773
43777
  }
43774
43778
  if (this.apiKey) {
43775
- headers.set("X-API-Key", this.apiKey);
43779
+ setHeader(headers, "X-API-Key", this.apiKey);
43776
43780
  }
43777
43781
  const signal = init?.signal ?? AbortSignal.timeout(this.requestTimeoutMs);
43778
- const res = await fetch(`${this.baseUrl}${path28}`, { ...init, headers, signal });
43782
+ const res = await this.fetchFn(`${this.baseUrl}${path28}`, { ...init, headers, signal });
43779
43783
  if (!res.ok) {
43780
43784
  let body;
43781
43785
  try {
@@ -43784,11 +43788,29 @@ var BrokerTransport = class {
43784
43788
  }
43785
43789
  throw new AgentRelayProtocolError({
43786
43790
  code: body?.code ?? `http_${res.status}`,
43787
- message: body?.message ?? body?.error ?? res.statusText,
43788
- retryable: res.status >= 500
43791
+ message: (body?.message ?? body?.error ?? res.statusText) || `HTTP ${res.status}`,
43792
+ retryable: res.status >= 500,
43793
+ status: res.status,
43794
+ data: body
43795
+ });
43796
+ }
43797
+ if (isEmptySuccessResponse(res)) {
43798
+ return void 0;
43799
+ }
43800
+ const bodyText = await res.text();
43801
+ if (bodyText.length === 0) {
43802
+ return void 0;
43803
+ }
43804
+ try {
43805
+ return JSON.parse(bodyText);
43806
+ } catch {
43807
+ throw new AgentRelayProtocolError({
43808
+ code: "invalid_response",
43809
+ message: "response was not JSON",
43810
+ retryable: false,
43811
+ status: res.status
43789
43812
  });
43790
43813
  }
43791
- return res.json();
43792
43814
  }
43793
43815
  // ── WebSocket events ─────────────────────────────────────────────────
43794
43816
  connect(sinceSeq) {
@@ -43890,6 +43912,46 @@ var BrokerTransport = class {
43890
43912
  return void 0;
43891
43913
  }
43892
43914
  };
43915
+ function headersToRecord(headersInit) {
43916
+ const headers = {};
43917
+ if (!headersInit)
43918
+ return headers;
43919
+ if (headersInit instanceof Headers) {
43920
+ headersInit.forEach((value, key) => {
43921
+ headers[key] = value;
43922
+ });
43923
+ return headers;
43924
+ }
43925
+ if (Array.isArray(headersInit)) {
43926
+ for (const [key, value] of headersInit) {
43927
+ headers[key] = value;
43928
+ }
43929
+ return headers;
43930
+ }
43931
+ for (const [key, value] of Object.entries(headersInit)) {
43932
+ headers[key] = value;
43933
+ }
43934
+ return headers;
43935
+ }
43936
+ function hasHeader(headers, name) {
43937
+ const lowerName = name.toLowerCase();
43938
+ return Object.keys(headers).some((key) => key.toLowerCase() === lowerName);
43939
+ }
43940
+ function setHeader(headers, name, value) {
43941
+ const lowerName = name.toLowerCase();
43942
+ for (const key of Object.keys(headers)) {
43943
+ if (key.toLowerCase() === lowerName && key !== name) {
43944
+ delete headers[key];
43945
+ }
43946
+ }
43947
+ headers[name] = value;
43948
+ }
43949
+ function isEmptySuccessResponse(res) {
43950
+ if (res.status === 204 || res.status === 205) {
43951
+ return true;
43952
+ }
43953
+ return res.headers.get("content-length")?.trim() === "0";
43954
+ }
43893
43955
 
43894
43956
  // packages/sdk/dist/client.js
43895
43957
  var import_node_child_process2 = require("node:child_process");
@@ -44153,6 +44215,7 @@ var AgentRelayClient = class _AgentRelayClient {
44153
44215
  this.transport = new BrokerTransport({
44154
44216
  baseUrl: options.baseUrl,
44155
44217
  apiKey: options.apiKey,
44218
+ fetch: options.fetch,
44156
44219
  requestTimeoutMs: options.requestTimeoutMs
44157
44220
  });
44158
44221
  }
@@ -44318,19 +44381,19 @@ var AgentRelayClient = class _AgentRelayClient {
44318
44381
  body: JSON.stringify({
44319
44382
  name: input.name,
44320
44383
  cli: input.cli,
44321
- model: input.model,
44384
+ ...input.model !== void 0 ? { model: input.model } : {},
44322
44385
  args: input.args ?? [],
44323
- task: input.task,
44386
+ ...input.task !== void 0 ? { task: input.task } : {},
44324
44387
  channels: input.channels ?? [],
44325
- cwd: input.cwd,
44326
- team: input.team,
44327
- agentToken: input.agentToken,
44328
- shadowOf: input.shadowOf,
44329
- shadowMode: input.shadowMode,
44330
- continueFrom: input.continueFrom,
44331
- idleThresholdSecs: input.idleThresholdSecs,
44332
- restartPolicy: input.restartPolicy,
44333
- skipRelayPrompt: input.skipRelayPrompt
44388
+ ...input.cwd !== void 0 ? { cwd: input.cwd } : {},
44389
+ ...input.team !== void 0 ? { team: input.team } : {},
44390
+ ...input.agentToken !== void 0 ? { agentToken: input.agentToken } : {},
44391
+ ...input.shadowOf !== void 0 ? { shadowOf: input.shadowOf } : {},
44392
+ ...input.shadowMode !== void 0 ? { shadowMode: input.shadowMode } : {},
44393
+ ...input.continueFrom !== void 0 ? { continueFrom: input.continueFrom } : {},
44394
+ ...input.idleThresholdSecs !== void 0 ? { idleThresholdSecs: input.idleThresholdSecs } : {},
44395
+ ...input.restartPolicy !== void 0 ? { restartPolicy: input.restartPolicy } : {},
44396
+ ...input.skipRelayPrompt !== void 0 ? { skipRelayPrompt: input.skipRelayPrompt } : {}
44334
44397
  })
44335
44398
  });
44336
44399
  }
@@ -44344,19 +44407,19 @@ var AgentRelayClient = class _AgentRelayClient {
44344
44407
  body: JSON.stringify({
44345
44408
  name: input.name,
44346
44409
  cli: input.provider,
44347
- model: input.model,
44410
+ ...input.model !== void 0 ? { model: input.model } : {},
44348
44411
  args: input.args ?? [],
44349
- task: input.task,
44412
+ ...input.task !== void 0 ? { task: input.task } : {},
44350
44413
  channels: input.channels ?? [],
44351
- cwd: input.cwd,
44352
- team: input.team,
44353
- agentToken: input.agentToken,
44354
- shadowOf: input.shadowOf,
44355
- shadowMode: input.shadowMode,
44356
- continueFrom: input.continueFrom,
44357
- idleThresholdSecs: input.idleThresholdSecs,
44358
- restartPolicy: input.restartPolicy,
44359
- skipRelayPrompt: input.skipRelayPrompt,
44414
+ ...input.cwd !== void 0 ? { cwd: input.cwd } : {},
44415
+ ...input.team !== void 0 ? { team: input.team } : {},
44416
+ ...input.agentToken !== void 0 ? { agentToken: input.agentToken } : {},
44417
+ ...input.shadowOf !== void 0 ? { shadowOf: input.shadowOf } : {},
44418
+ ...input.shadowMode !== void 0 ? { shadowMode: input.shadowMode } : {},
44419
+ ...input.continueFrom !== void 0 ? { continueFrom: input.continueFrom } : {},
44420
+ ...input.idleThresholdSecs !== void 0 ? { idleThresholdSecs: input.idleThresholdSecs } : {},
44421
+ ...input.restartPolicy !== void 0 ? { restartPolicy: input.restartPolicy } : {},
44422
+ ...input.skipRelayPrompt !== void 0 ? { skipRelayPrompt: input.skipRelayPrompt } : {},
44360
44423
  transport
44361
44424
  })
44362
44425
  });
@@ -44393,6 +44456,104 @@ var AgentRelayClient = class _AgentRelayClient {
44393
44456
  body: JSON.stringify({ rows, cols })
44394
44457
  });
44395
44458
  }
44459
+ async getInboundDeliveryMode(name) {
44460
+ const result = await this.transport.request(`/api/spawned/${encodeURIComponent(name)}/delivery-mode`);
44461
+ if (result.mode !== "auto_inject" && result.mode !== "manual_flush") {
44462
+ throw new AgentRelayProtocolError({
44463
+ code: "invalid_response",
44464
+ message: "inbound delivery mode response missing valid 'mode'"
44465
+ });
44466
+ }
44467
+ return result.mode;
44468
+ }
44469
+ async setInboundDeliveryMode(name, mode) {
44470
+ const result = await this.transport.request(`/api/spawned/${encodeURIComponent(name)}/delivery-mode`, {
44471
+ method: "PUT",
44472
+ body: JSON.stringify({ mode })
44473
+ });
44474
+ if (result.mode !== "auto_inject" && result.mode !== "manual_flush") {
44475
+ throw new AgentRelayProtocolError({
44476
+ code: "invalid_response",
44477
+ message: "set inbound delivery mode response missing valid 'mode'"
44478
+ });
44479
+ }
44480
+ return {
44481
+ mode: result.mode,
44482
+ flushed: typeof result.flushed === "number" ? result.flushed : 0
44483
+ };
44484
+ }
44485
+ async getPending(name) {
44486
+ const result = await this.transport.request(`/api/spawned/${encodeURIComponent(name)}/pending`);
44487
+ return Array.isArray(result.pending) ? result.pending : [];
44488
+ }
44489
+ async flushPending(name) {
44490
+ const result = await this.transport.request(`/api/spawned/${encodeURIComponent(name)}/flush`, { method: "POST" });
44491
+ return { flushed: typeof result.flushed === "number" ? result.flushed : 0 };
44492
+ }
44493
+ async snapshot(name, format2 = "plain") {
44494
+ return this.transport.request(`/api/spawned/${encodeURIComponent(name)}/snapshot?format=${encodeURIComponent(format2)}`);
44495
+ }
44496
+ subscribeWorkerStream(name, options = {}) {
44497
+ this.connectEvents(options.sinceSeq);
44498
+ return {
44499
+ [Symbol.asyncIterator]: () => {
44500
+ const queue = [];
44501
+ let pending;
44502
+ let done = false;
44503
+ const unsubscribe = this.onEvent((event) => {
44504
+ if (event.kind !== "worker_stream" || event.name !== name || options.stream !== void 0 && event.stream !== options.stream) {
44505
+ return;
44506
+ }
44507
+ if (pending) {
44508
+ const { resolve: resolve4 } = pending;
44509
+ pending = void 0;
44510
+ resolve4({ done: false, value: event.chunk });
44511
+ return;
44512
+ }
44513
+ queue.push(event.chunk);
44514
+ });
44515
+ const close = () => {
44516
+ done = true;
44517
+ unsubscribe();
44518
+ if (pending) {
44519
+ const { resolve: resolve4 } = pending;
44520
+ pending = void 0;
44521
+ resolve4({ done: true, value: void 0 });
44522
+ }
44523
+ return { done: true, value: void 0 };
44524
+ };
44525
+ return {
44526
+ next() {
44527
+ if (queue.length > 0) {
44528
+ return Promise.resolve({ done: false, value: queue.shift() });
44529
+ }
44530
+ if (done) {
44531
+ return Promise.resolve({ done: true, value: void 0 });
44532
+ }
44533
+ return new Promise((resolve4, reject) => {
44534
+ pending = { resolve: resolve4, reject };
44535
+ });
44536
+ },
44537
+ return() {
44538
+ return Promise.resolve(close());
44539
+ },
44540
+ throw(error51) {
44541
+ done = true;
44542
+ unsubscribe();
44543
+ if (pending) {
44544
+ const { reject } = pending;
44545
+ pending = void 0;
44546
+ reject(error51);
44547
+ }
44548
+ return Promise.reject(error51);
44549
+ },
44550
+ [Symbol.asyncIterator]() {
44551
+ return this;
44552
+ }
44553
+ };
44554
+ }
44555
+ };
44556
+ }
44396
44557
  // ── Messaging ──────────────────────────────────────────────────────
44397
44558
  async sendMessage(input) {
44398
44559
  try {
@@ -90242,12 +90403,22 @@ function ensureLocalSdkWorkflowRuntime(startDir, execRunner = import_node_child_
90242
90403
  const workflowsEntry = import_node_path36.default.join(workspace.sdkDir, "dist", "workflows", "index.js");
90243
90404
  if (import_node_fs24.default.existsSync(workflowsEntry))
90244
90405
  return;
90245
- console.log("[agent-relay] Detected local @agent-relay/sdk workspace without built workflows runtime; building packages/sdk...");
90246
- execRunner("npm", ["run", "build:sdk"], {
90247
- cwd: workspace.rootDir,
90248
- stdio: "inherit",
90249
- env: process.env
90250
- });
90406
+ console.log("[agent-relay] Detected local @agent-relay/sdk workspace without built workflows runtime; building SDK workflow dependencies...");
90407
+ const buildCommands = [
90408
+ ["run", "build:config"],
90409
+ ["--prefix", "packages/workflow-types", "run", "build"],
90410
+ ["--prefix", "packages/github-primitive", "run", "build"],
90411
+ ["--prefix", "packages/slack-primitive", "run", "build"],
90412
+ ["--prefix", "packages/cloud", "run", "build"],
90413
+ ["run", "build:sdk"]
90414
+ ];
90415
+ for (const args of buildCommands) {
90416
+ execRunner("npm", args, {
90417
+ cwd: workspace.rootDir,
90418
+ stdio: "inherit",
90419
+ env: process.env
90420
+ });
90421
+ }
90251
90422
  if (!import_node_fs24.default.existsSync(workflowsEntry)) {
90252
90423
  throw new Error(`Local SDK workflows runtime is still missing after build: ${workflowsEntry}`);
90253
90424
  }
@@ -90288,6 +90459,120 @@ function parseTsxStderr(stderr) {
90288
90459
  }
90289
90460
  return null;
90290
90461
  }
90462
+ function resolveLocalTypeScriptImport(fromFile, specifier) {
90463
+ if (!specifier.startsWith(".") && !specifier.startsWith("/")) {
90464
+ return null;
90465
+ }
90466
+ const basePath = specifier.startsWith("/") ? import_node_path36.default.resolve(specifier) : import_node_path36.default.resolve(import_node_path36.default.dirname(fromFile), specifier);
90467
+ const ext = import_node_path36.default.extname(basePath);
90468
+ const candidates = ext === ".js" || ext === ".mjs" || ext === ".cjs" ? [
90469
+ `${basePath.slice(0, -ext.length)}.ts`,
90470
+ `${basePath.slice(0, -ext.length)}.tsx`,
90471
+ `${basePath.slice(0, -ext.length)}.mts`,
90472
+ `${basePath.slice(0, -ext.length)}.cts`,
90473
+ basePath
90474
+ ] : ext ? [basePath] : [
90475
+ `${basePath}.ts`,
90476
+ `${basePath}.tsx`,
90477
+ `${basePath}.mts`,
90478
+ `${basePath}.cts`,
90479
+ import_node_path36.default.join(basePath, "index.ts"),
90480
+ import_node_path36.default.join(basePath, "index.tsx"),
90481
+ import_node_path36.default.join(basePath, "index.mts"),
90482
+ import_node_path36.default.join(basePath, "index.cts")
90483
+ ];
90484
+ for (const candidate of candidates) {
90485
+ if (/\.(?:ts|tsx|mts|cts)$/.test(candidate) && import_node_fs24.default.existsSync(candidate)) {
90486
+ return candidate;
90487
+ }
90488
+ }
90489
+ return null;
90490
+ }
90491
+ function findStaticLocalTypeScriptImports(filePath, source) {
90492
+ const imports = [];
90493
+ const staticImportPattern = /(?:^|[\n;])\s*(?:import\s+(?:type\s+)?(?:[^'"]*?\s+from\s+)?|export\s+(?:type\s+)?[^'"]*?\s+from\s+)['"]([^'"]+)['"]/g;
90494
+ for (const match of source.matchAll(staticImportPattern)) {
90495
+ const resolved = resolveLocalTypeScriptImport(filePath, match[1]);
90496
+ if (resolved) {
90497
+ imports.push(resolved);
90498
+ }
90499
+ }
90500
+ return imports;
90501
+ }
90502
+ function shouldSkipNodeStripTypesPreflight(filePath, seen = /* @__PURE__ */ new Set(), isEntry = true) {
90503
+ const resolvedPath = import_node_path36.default.resolve(filePath);
90504
+ if (seen.has(resolvedPath)) {
90505
+ return false;
90506
+ }
90507
+ seen.add(resolvedPath);
90508
+ let source;
90509
+ try {
90510
+ source = import_node_fs24.default.readFileSync(resolvedPath, "utf8");
90511
+ } catch {
90512
+ return !isEntry;
90513
+ }
90514
+ if (containsNodeStripTypesUnsupportedSyntax(source)) {
90515
+ return true;
90516
+ }
90517
+ return findStaticLocalTypeScriptImports(resolvedPath, source).some((importPath) => shouldSkipNodeStripTypesPreflight(importPath, seen, false));
90518
+ }
90519
+ function stripCommentsAndStringsForSyntaxScan(source) {
90520
+ let output = "";
90521
+ for (let index = 0; index < source.length; index += 1) {
90522
+ const char = source[index];
90523
+ const next = source[index + 1];
90524
+ if (char === "/" && next === "/") {
90525
+ output += " ";
90526
+ index += 1;
90527
+ while (index + 1 < source.length && source[index + 1] !== "\n") {
90528
+ output += " ";
90529
+ index += 1;
90530
+ }
90531
+ continue;
90532
+ }
90533
+ if (char === "/" && next === "*") {
90534
+ output += " ";
90535
+ index += 1;
90536
+ while (index + 1 < source.length) {
90537
+ index += 1;
90538
+ const current = source[index];
90539
+ output += current === "\n" ? "\n" : " ";
90540
+ if (current === "*" && source[index + 1] === "/") {
90541
+ output += " ";
90542
+ index += 1;
90543
+ break;
90544
+ }
90545
+ }
90546
+ continue;
90547
+ }
90548
+ if (char === '"' || char === "'" || char === "`") {
90549
+ const quote = char;
90550
+ output += " ";
90551
+ while (index + 1 < source.length) {
90552
+ index += 1;
90553
+ const current = source[index];
90554
+ output += current === "\n" ? "\n" : " ";
90555
+ if (current === "\\") {
90556
+ if (index + 1 < source.length) {
90557
+ index += 1;
90558
+ output += source[index] === "\n" ? "\n" : " ";
90559
+ }
90560
+ continue;
90561
+ }
90562
+ if (current === quote) {
90563
+ break;
90564
+ }
90565
+ }
90566
+ continue;
90567
+ }
90568
+ output += char;
90569
+ }
90570
+ return output;
90571
+ }
90572
+ function containsNodeStripTypesUnsupportedSyntax(source) {
90573
+ const scanSource = stripCommentsAndStringsForSyntaxScan(source);
90574
+ return /(?:^|[;\n{}])\s*(?:export\s+)?(?:const\s+)?enum\s+[A-Za-z_$][\w$]*/.test(scanSource) || /(?:^|[;\n{}])\s*(?:export\s+)?(?:declare\s+)?(?:namespace|module)\s+[A-Za-z_$][\w$]*/.test(scanSource) || /\bconstructor\s*\([^)]*\b(?:public|private|protected|readonly)\s+(?:readonly\s+)?[A-Za-z_$][\w$]*/.test(scanSource) || /(?:^|[;\n{}])\s*import\s+[A-Za-z_$][\w$]*\s*=\s*(?:require\s*\(|[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*)/.test(scanSource) || /(?:^|[;\n{}])\s*export\s*=\s*/.test(scanSource);
90575
+ }
90291
90576
  function formatWorkflowParseError(parsed) {
90292
90577
  const where = parsed.line !== void 0 ? `${parsed.file}:${parsed.line}${parsed.column !== void 0 ? `:${parsed.column}` : ""}` : parsed.file;
90293
90578
  const hints = [];
@@ -90408,6 +90693,10 @@ Run ID: ${runId}`;
90408
90693
  { label: "ts-node", bin: "ts-node", preArgs: [] }
90409
90694
  ];
90410
90695
  for (const { label, bin, preArgs } of runners) {
90696
+ if (bin === "node" && shouldSkipNodeStripTypesPreflight(resolved)) {
90697
+ diag(`runScriptWorkflow: ${label} cannot parse this TypeScript file \u2014 trying next`);
90698
+ continue;
90699
+ }
90411
90700
  diag(`runScriptWorkflow: trying runner ${label}`);
90412
90701
  const result = await spawnRunnerWithStderrCapture(bin, [...preArgs, resolved], childEnv);
90413
90702
  if (result.error) {
@@ -90419,7 +90708,7 @@ Run ID: ${runId}`;
90419
90708
  }
90420
90709
  if (result.status !== 0) {
90421
90710
  if (bin === "node" && result.status === 9) {
90422
- diag(`runScriptWorkflow: runner ${label} unsupported on this Node (exit 9) \u2014 trying next`);
90711
+ diag(`runScriptWorkflow: runner ${label} cannot handle this TypeScript file \u2014 trying next`);
90423
90712
  continue;
90424
90713
  }
90425
90714
  return augmentErrorWithRunId(wrapRunnerError(label, result));
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../src/cli/bootstrap.ts"],"names":[],"mappings":";AAOA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAyDpC,eAAO,MAAM,OAAO,QAAsB,CAAC;AAkB3C,eAAO,MAAM,WAAW,oBAAsB,CAAC;AAoL/C,wBAAgB,aAAa,CAAC,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAuBtE;AAaD,wBAAsB,MAAM,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CAiE5E"}
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../../src/cli/bootstrap.ts"],"names":[],"mappings":";AAOA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+DpC,eAAO,MAAM,OAAO,QAAsB,CAAC;AAkB3C,eAAO,MAAM,WAAW,oBAAsB,CAAC;AAoL/C,wBAAgB,aAAa,CAAC,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CA+BtE;AA8BD,wBAAsB,MAAM,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,OAAO,CAAC,CA+F5E"}
@@ -22,6 +22,12 @@ import { registerSwarmCommands } from './commands/swarm.js';
22
22
  import { registerConnectCommands } from './commands/connect.js';
23
23
  import { registerOnCommands } from './commands/on.js';
24
24
  import { registerDlqCommands } from './commands/dlq.js';
25
+ import { registerViewCommands } from './commands/view.js';
26
+ import { registerDriveCommands } from './commands/drive.js';
27
+ import { registerPassthroughCommands } from './commands/passthrough.js';
28
+ import { registerNewCommands } from './commands/new.js';
29
+ import { registerRmCommands } from './commands/rm.js';
30
+ import { parseVerblessAlias, runVerblessAliasDispatch } from './lib/spawn-and-attach.js';
25
31
  dotenvConfig({ quiet: true });
26
32
  const __filename = fileURLToPath(import.meta.url);
27
33
  const __dirname = path.dirname(__filename);
@@ -241,6 +247,14 @@ export function createProgram(options = {}) {
241
247
  registerOnCommands(program);
242
248
  registerConnectCommands(program);
243
249
  registerDlqCommands(program);
250
+ registerViewCommands(program);
251
+ registerDriveCommands(program);
252
+ registerPassthroughCommands(program);
253
+ // The `run` command (registered by `registerSetupCommands` above) is the
254
+ // workflow-file runner and is intentionally untouched. The spawn-and-attach
255
+ // composition lives on `new --attach` — see `src/cli/commands/new.ts`.
256
+ registerNewCommands(program);
257
+ registerRmCommands(program);
244
258
  return program;
245
259
  }
246
260
  function maybeRunUpdateCheck(version, argv) {
@@ -253,6 +267,22 @@ function shouldSkipTelemetryInit(argv) {
253
267
  const commandName = argv[2];
254
268
  return Boolean(commandName && TELEMETRY_MANAGEMENT_COMMANDS.has(commandName));
255
269
  }
270
+ /**
271
+ * Top-level verb names that the verbless `-n NAME CLI` silent alias
272
+ * must NOT swallow. Built once from the program's leaf+group command
273
+ * tree so we can't drift if a new verb is added without updating both
274
+ * places.
275
+ */
276
+ function collectTopLevelVerbs(program) {
277
+ const verbs = new Set();
278
+ for (const command of program.commands) {
279
+ verbs.add(command.name());
280
+ for (const alias of command.aliases()) {
281
+ verbs.add(alias);
282
+ }
283
+ }
284
+ return verbs;
285
+ }
256
286
  export async function runCli(argv = process.argv) {
257
287
  maybeRunUpdateCheck(VERSION, argv);
258
288
  propagateVersionsToChildren();
@@ -266,6 +296,38 @@ export async function runCli(argv = process.argv) {
266
296
  const program = createProgram({ name: resolveProgramName(argv) });
267
297
  installTelemetryHooks(program);
268
298
  installExitHooks();
299
+ // Bare `-n NAME CLI` shorthand. `agent-relay -n NAME CLI [args...]`
300
+ // dispatches to `runSpawnAndAttach` with mode='passthrough' and ephemeral=true,
301
+ // which is equivalent to `agent-relay new NAME CLI --attach --mode passthrough --ephemeral`.
302
+ // Detected here BEFORE commander parses so the shorthand routes
303
+ // identically to the verbose form. See `parseVerblessAlias` in
304
+ // `lib/spawn-and-attach.ts`.
305
+ const knownVerbs = collectTopLevelVerbs(program);
306
+ const aliasMatch = parseVerblessAlias(argv.slice(2), knownVerbs);
307
+ if (aliasMatch) {
308
+ try {
309
+ const code = await runVerblessAliasDispatch(aliasMatch);
310
+ try {
311
+ await shutdownTelemetry();
312
+ }
313
+ catch {
314
+ // Never let telemetry shutdown mask the real exit code.
315
+ }
316
+ if (code !== 0) {
317
+ process.exit(code);
318
+ }
319
+ return program;
320
+ }
321
+ catch (err) {
322
+ try {
323
+ await shutdownTelemetry();
324
+ }
325
+ catch {
326
+ // ignore
327
+ }
328
+ throw err;
329
+ }
330
+ }
269
331
  try {
270
332
  await program.parseAsync(argv);
271
333
  }