@autohq/cli 0.1.287 → 0.1.288

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.
@@ -23384,7 +23384,7 @@ Object.assign(lookup, {
23384
23384
  // package.json
23385
23385
  var package_default = {
23386
23386
  name: "@autohq/cli",
23387
- version: "0.1.287",
23387
+ version: "0.1.288",
23388
23388
  license: "SEE LICENSE IN README.md",
23389
23389
  publishConfig: {
23390
23390
  access: "public"
@@ -28362,6 +28362,9 @@ var ProjectTemplateSubscriptionSchema = external_exports.object({
28362
28362
  });
28363
28363
 
28364
28364
  // ../../packages/schemas/src/temporal.ts
28365
+ var SessionCheckTimeoutWorkflowInputSchema = external_exports.object({
28366
+ checkId: external_exports.string().trim().min(1)
28367
+ });
28365
28368
  var ResourceReconciliationScopeSchema = external_exports.object({
28366
28369
  organizationId: external_exports.string().trim().min(1),
28367
28370
  projectId: external_exports.string().trim().min(1).nullable()
@@ -57340,6 +57343,12 @@ var claudeAgentBridgeRuntime = {
57340
57343
  var claudeAgentSdkRuntime = {
57341
57344
  startup: (input) => aj$(input)
57342
57345
  };
57346
+ var ClaudeMcpRegistryEmptyError = class extends Error {
57347
+ constructor(detail) {
57348
+ super(`MCP tool registry came up empty at session start: ${detail}`);
57349
+ this.name = "ClaudeMcpRegistryEmptyError";
57350
+ }
57351
+ };
57343
57352
  var ClaudeAgentBridgeSessionImpl = class {
57344
57353
  input;
57345
57354
  inputQueue;
@@ -57729,17 +57738,20 @@ var ClaudeAgentBridgeSessionImpl = class {
57729
57738
  }
57730
57739
  // Why this gate is correct without a provider-backed test (it relies on real
57731
57740
  // SDK mcpServerStatus() timing that fakes cannot prove):
57732
- // - Safe-degrade: pollMcpRegistration never rejects — on timeout, a
57733
- // status-read failure, or a closed session it resolves, so the worst case
57734
- // is today's immediate injection. The gate can never regress below the
57735
- // status-quo race; it can only close it.
57741
+ // - Safe-degrade on uncertainty: pollMcpRegistration never rejects — on
57742
+ // timeout, a status-read failure, or a closed session it resolves, so an
57743
+ // *unconfirmed* registry still degrades to today's immediate injection.
57744
+ // The one fail-closed exit is the confirmed-empty registry: every
57745
+ // configured server settled and none is serving tools, which is exactly
57746
+ // the state that produced silent toolless runs in production (FRA-3458).
57736
57747
  // - Provider-path validation is deferred deliberately: the failure is the
57737
57748
  // intermittent live-prod race on the chief-of-staff singleton (a real
57738
57749
  // runtime restart dispatching turn-1 while real mcp__* servers reconnect),
57739
57750
  // which cannot be reproduced deterministically without live credentials
57740
57751
  // and a forced restart racing reconnect.
57741
57752
  // - Live confirmation comes from the agent_bridge_claude_mcp_gate_started/
57742
- // _ready/_timeout diagnostics on the next real restart, not a CI fake.
57753
+ // _ready/_timeout/_empty diagnostics on the next real restart, not a CI
57754
+ // fake.
57743
57755
  //
57744
57756
  // Block until the freshly-warmed query's MCP servers have left `pending`, so
57745
57757
  // the first turn's prompt is built with the mcp__* tools registered. Memoized
@@ -57763,15 +57775,22 @@ var ClaudeAgentBridgeSessionImpl = class {
57763
57775
  promise: this.pollMcpRegistration(query)
57764
57776
  };
57765
57777
  }
57766
- await this.mcpRegistrationGate.promise;
57778
+ const result = await this.mcpRegistrationGate.promise;
57779
+ if (result.outcome !== "empty") {
57780
+ return;
57781
+ }
57782
+ this.close();
57783
+ throw new ClaudeMcpRegistryEmptyError(result.detail);
57767
57784
  }
57768
57785
  // Poll the live query's MCP server status until no configured server is still
57769
57786
  // `pending`, bounded by CLAUDE_MCP_REGISTRATION_TIMEOUT_MS. Terminal states
57770
57787
  // (connected/failed/needs-auth/disabled) all count as settled, so a server
57771
57788
  // that cannot connect in this runtime (e.g. an interactively-authed server in
57772
- // a headless sandbox) never holds the gate to the timeout. Never rejects:
57789
+ // a headless sandbox) never holds the gate to the timeout. A settled state
57790
+ // where no configured server is serving tools resolves "empty" — the caller
57791
+ // fails the send rather than injecting a toolless turn. Never rejects:
57773
57792
  // status-read failure, timeout, or a closed session all resolve so the caller
57774
- // degrades to immediate injection.
57793
+ // degrades to immediate injection when the registry state is uncertain.
57775
57794
  async pollMcpRegistration(query) {
57776
57795
  const configuredNames = Object.keys(this.options.mcpServers ?? {});
57777
57796
  const startedAt = Date.now();
@@ -57781,7 +57800,7 @@ var ClaudeAgentBridgeSessionImpl = class {
57781
57800
  );
57782
57801
  while (true) {
57783
57802
  if (this.state.kind === "closed") {
57784
- return;
57803
+ return { outcome: "closed" };
57785
57804
  }
57786
57805
  let statuses;
57787
57806
  try {
@@ -57790,19 +57809,26 @@ var ClaudeAgentBridgeSessionImpl = class {
57790
57809
  this.input.writeOutput?.(
57791
57810
  `agent_bridge_claude_mcp_gate_status_failed duration_ms=${Date.now() - startedAt} error=${error51 instanceof Error ? error51.message : String(error51)}`
57792
57811
  );
57793
- return;
57812
+ return { outcome: "status_failed" };
57794
57813
  }
57795
57814
  if (mcpServersSettled(statuses, configuredNames)) {
57815
+ if (!mcpRegistryHasTools(statuses, configuredNames)) {
57816
+ const detail = mcpStatusDetailList(statuses);
57817
+ this.input.writeOutput?.(
57818
+ `agent_bridge_claude_mcp_gate_empty duration_ms=${Date.now() - startedAt} servers=${detail}`
57819
+ );
57820
+ return { outcome: "empty", detail };
57821
+ }
57796
57822
  this.input.writeOutput?.(
57797
57823
  `agent_bridge_claude_mcp_gate_ready duration_ms=${Date.now() - startedAt} servers=${mcpStatusList(statuses)}`
57798
57824
  );
57799
- return;
57825
+ return { outcome: "ready" };
57800
57826
  }
57801
57827
  if (Date.now() >= deadline) {
57802
57828
  this.input.writeOutput?.(
57803
57829
  `agent_bridge_claude_mcp_gate_timeout duration_ms=${Date.now() - startedAt} servers=${mcpStatusList(statuses)}`
57804
57830
  );
57805
- return;
57831
+ return { outcome: "timeout" };
57806
57832
  }
57807
57833
  await delay(CLAUDE_MCP_REGISTRATION_POLL_INTERVAL_MS);
57808
57834
  }
@@ -57945,9 +57971,20 @@ function mcpServersSettled(statuses, configuredNames) {
57945
57971
  return status !== void 0 && status !== "pending";
57946
57972
  });
57947
57973
  }
57974
+ function mcpRegistryHasTools(statuses, configuredNames) {
57975
+ const configured = new Set(configuredNames);
57976
+ return statuses.some(
57977
+ (server) => configured.has(server.name) && server.status === "connected" && (server.tools === void 0 || server.tools.length > 0)
57978
+ );
57979
+ }
57948
57980
  function mcpStatusList(statuses) {
57949
57981
  return statuses.map((server) => `${server.name}:${server.status}`).join(",");
57950
57982
  }
57983
+ function mcpStatusDetailList(statuses) {
57984
+ return statuses.map(
57985
+ (server) => server.error ? `${server.name}:${server.status}(${server.error})` : `${server.name}:${server.status}`
57986
+ ).join(",");
57987
+ }
57951
57988
  function delay(ms) {
57952
57989
  return new Promise((resolve2) => {
57953
57990
  const timer = setTimeout(resolve2, ms);
@@ -58055,6 +58092,13 @@ var ClaudeCodeCommandHandler = class {
58055
58092
  agentSession = null;
58056
58093
  persistedAgentId = null;
58057
58094
  injectedCommands = /* @__PURE__ */ new Set();
58095
+ // Message commands whose injection has started but not settled. A fresh SDK
58096
+ // warm inside sendMessage can outlast the bridge's command-ack window, so a
58097
+ // redelivery may arrive while the first attempt is still in flight; acking it
58098
+ // "duplicate" then would let the worker accept a command whose injection
58099
+ // later fails, silently stalling the turn (FRA-3458). The duplicate branch
58100
+ // awaits the in-flight outcome here and relays it instead.
58101
+ inFlightMessageCommands = /* @__PURE__ */ new Map();
58058
58102
  pendingQuestions = /* @__PURE__ */ new Map();
58059
58103
  outputBuffer;
58060
58104
  projector = new ClaudeCodeProjector();
@@ -58102,13 +58146,25 @@ var ClaudeCodeCommandHandler = class {
58102
58146
  });
58103
58147
  }
58104
58148
  if (this.injectedCommands.has(delivery.commandId)) {
58149
+ const inFlight = this.inFlightMessageCommands.get(delivery.commandId);
58150
+ const outcome2 = inFlight ? await inFlight : { status: "injected" };
58105
58151
  this.input.runtimeLogger?.info(
58106
58152
  "agent_bridge_claude_command_duplicate",
58107
58153
  commandLogContext(delivery, {
58108
58154
  socket_id: socketId,
58109
- duration_ms: Date.now() - startedAt
58155
+ duration_ms: Date.now() - startedAt,
58156
+ awaited_in_flight: Boolean(inFlight),
58157
+ in_flight_status: outcome2.status
58110
58158
  })
58111
58159
  );
58160
+ if (outcome2.status === "failed") {
58161
+ return commandAck({
58162
+ delivery,
58163
+ socketId,
58164
+ status: "failed",
58165
+ error: outcome2.error
58166
+ });
58167
+ }
58112
58168
  return commandAck({
58113
58169
  delivery,
58114
58170
  socketId,
@@ -58159,6 +58215,53 @@ var ClaudeCodeCommandHandler = class {
58159
58215
  });
58160
58216
  }
58161
58217
  this.injectedCommands.add(delivery.commandId);
58218
+ const injection = this.injectMessageCommand(
58219
+ activeContext,
58220
+ delivery,
58221
+ message,
58222
+ socketId
58223
+ );
58224
+ this.inFlightMessageCommands.set(delivery.commandId, injection);
58225
+ let outcome;
58226
+ try {
58227
+ outcome = await injection;
58228
+ } finally {
58229
+ this.inFlightMessageCommands.delete(delivery.commandId);
58230
+ }
58231
+ if (outcome.status === "failed") {
58232
+ this.injectedCommands.delete(delivery.commandId);
58233
+ this.input.runtimeLogger?.warn(
58234
+ "agent_bridge_claude_command_failed",
58235
+ commandLogContext(delivery, {
58236
+ socket_id: socketId,
58237
+ duration_ms: Date.now() - startedAt,
58238
+ error: outcome.error
58239
+ })
58240
+ );
58241
+ return commandAck({
58242
+ delivery,
58243
+ socketId,
58244
+ status: "failed",
58245
+ error: outcome.error
58246
+ });
58247
+ }
58248
+ this.input.runtimeLogger?.info(
58249
+ "agent_bridge_claude_command_injected",
58250
+ commandLogContext(delivery, {
58251
+ socket_id: socketId,
58252
+ duration_ms: Date.now() - startedAt
58253
+ })
58254
+ );
58255
+ return commandAck({
58256
+ delivery,
58257
+ socketId,
58258
+ status: "injected"
58259
+ });
58260
+ }
58261
+ // Runs one message command's injection to a terminal outcome. Never rejects:
58262
+ // the returned promise is stored in the in-flight map and awaited by both the
58263
+ // original delivery and any redeliveries, so failures travel as values.
58264
+ async injectMessageCommand(activeContext, delivery, message, socketId) {
58162
58265
  try {
58163
58266
  const emitStartedAt = Date.now();
58164
58267
  this.input.runtimeLogger?.info(
@@ -58204,35 +58307,13 @@ var ClaudeCodeCommandHandler = class {
58204
58307
  duration_ms: Date.now() - sendStartedAt
58205
58308
  })
58206
58309
  );
58310
+ return { status: "injected" };
58207
58311
  } catch (error51) {
58208
- this.injectedCommands.delete(delivery.commandId);
58209
- this.input.runtimeLogger?.warn(
58210
- "agent_bridge_claude_command_failed",
58211
- commandLogContext(delivery, {
58212
- socket_id: socketId,
58213
- duration_ms: Date.now() - startedAt,
58214
- error: error51 instanceof Error ? error51.message : String(error51)
58215
- })
58216
- );
58217
- return commandAck({
58218
- delivery,
58219
- socketId,
58312
+ return {
58220
58313
  status: "failed",
58221
58314
  error: error51 instanceof Error ? error51.message : String(error51)
58222
- });
58315
+ };
58223
58316
  }
58224
- this.input.runtimeLogger?.info(
58225
- "agent_bridge_claude_command_injected",
58226
- commandLogContext(delivery, {
58227
- socket_id: socketId,
58228
- duration_ms: Date.now() - startedAt
58229
- })
58230
- );
58231
- return commandAck({
58232
- delivery,
58233
- socketId,
58234
- status: "injected"
58235
- });
58236
58317
  }
58237
58318
  // -----------------------------------------------------------------------------
58238
58319
  // Question answering
package/dist/index.js CHANGED
@@ -20265,11 +20265,14 @@ var init_templates = __esm({
20265
20265
  });
20266
20266
 
20267
20267
  // ../../packages/schemas/src/temporal.ts
20268
- var ResourceReconciliationScopeSchema;
20268
+ var SessionCheckTimeoutWorkflowInputSchema, ResourceReconciliationScopeSchema;
20269
20269
  var init_temporal = __esm({
20270
20270
  "../../packages/schemas/src/temporal.ts"() {
20271
20271
  "use strict";
20272
20272
  init_zod();
20273
+ SessionCheckTimeoutWorkflowInputSchema = external_exports.object({
20274
+ checkId: external_exports.string().trim().min(1)
20275
+ });
20273
20276
  ResourceReconciliationScopeSchema = external_exports.object({
20274
20277
  organizationId: external_exports.string().trim().min(1),
20275
20278
  projectId: external_exports.string().trim().min(1).nullable()
@@ -23170,7 +23173,7 @@ var init_package = __esm({
23170
23173
  "package.json"() {
23171
23174
  package_default = {
23172
23175
  name: "@autohq/cli",
23173
- version: "0.1.287",
23176
+ version: "0.1.288",
23174
23177
  license: "SEE LICENSE IN README.md",
23175
23178
  publishConfig: {
23176
23179
  access: "public"
@@ -34786,6 +34789,12 @@ var claudeAgentBridgeRuntime = {
34786
34789
  var claudeAgentSdkRuntime = {
34787
34790
  startup: (input) => startupClaudeAgent(input)
34788
34791
  };
34792
+ var ClaudeMcpRegistryEmptyError = class extends Error {
34793
+ constructor(detail) {
34794
+ super(`MCP tool registry came up empty at session start: ${detail}`);
34795
+ this.name = "ClaudeMcpRegistryEmptyError";
34796
+ }
34797
+ };
34789
34798
  var ClaudeAgentBridgeSessionImpl = class {
34790
34799
  input;
34791
34800
  inputQueue;
@@ -35175,17 +35184,20 @@ var ClaudeAgentBridgeSessionImpl = class {
35175
35184
  }
35176
35185
  // Why this gate is correct without a provider-backed test (it relies on real
35177
35186
  // SDK mcpServerStatus() timing that fakes cannot prove):
35178
- // - Safe-degrade: pollMcpRegistration never rejects — on timeout, a
35179
- // status-read failure, or a closed session it resolves, so the worst case
35180
- // is today's immediate injection. The gate can never regress below the
35181
- // status-quo race; it can only close it.
35187
+ // - Safe-degrade on uncertainty: pollMcpRegistration never rejects — on
35188
+ // timeout, a status-read failure, or a closed session it resolves, so an
35189
+ // *unconfirmed* registry still degrades to today's immediate injection.
35190
+ // The one fail-closed exit is the confirmed-empty registry: every
35191
+ // configured server settled and none is serving tools, which is exactly
35192
+ // the state that produced silent toolless runs in production (FRA-3458).
35182
35193
  // - Provider-path validation is deferred deliberately: the failure is the
35183
35194
  // intermittent live-prod race on the chief-of-staff singleton (a real
35184
35195
  // runtime restart dispatching turn-1 while real mcp__* servers reconnect),
35185
35196
  // which cannot be reproduced deterministically without live credentials
35186
35197
  // and a forced restart racing reconnect.
35187
35198
  // - Live confirmation comes from the agent_bridge_claude_mcp_gate_started/
35188
- // _ready/_timeout diagnostics on the next real restart, not a CI fake.
35199
+ // _ready/_timeout/_empty diagnostics on the next real restart, not a CI
35200
+ // fake.
35189
35201
  //
35190
35202
  // Block until the freshly-warmed query's MCP servers have left `pending`, so
35191
35203
  // the first turn's prompt is built with the mcp__* tools registered. Memoized
@@ -35209,15 +35221,22 @@ var ClaudeAgentBridgeSessionImpl = class {
35209
35221
  promise: this.pollMcpRegistration(query)
35210
35222
  };
35211
35223
  }
35212
- await this.mcpRegistrationGate.promise;
35224
+ const result = await this.mcpRegistrationGate.promise;
35225
+ if (result.outcome !== "empty") {
35226
+ return;
35227
+ }
35228
+ this.close();
35229
+ throw new ClaudeMcpRegistryEmptyError(result.detail);
35213
35230
  }
35214
35231
  // Poll the live query's MCP server status until no configured server is still
35215
35232
  // `pending`, bounded by CLAUDE_MCP_REGISTRATION_TIMEOUT_MS. Terminal states
35216
35233
  // (connected/failed/needs-auth/disabled) all count as settled, so a server
35217
35234
  // that cannot connect in this runtime (e.g. an interactively-authed server in
35218
- // a headless sandbox) never holds the gate to the timeout. Never rejects:
35235
+ // a headless sandbox) never holds the gate to the timeout. A settled state
35236
+ // where no configured server is serving tools resolves "empty" — the caller
35237
+ // fails the send rather than injecting a toolless turn. Never rejects:
35219
35238
  // status-read failure, timeout, or a closed session all resolve so the caller
35220
- // degrades to immediate injection.
35239
+ // degrades to immediate injection when the registry state is uncertain.
35221
35240
  async pollMcpRegistration(query) {
35222
35241
  const configuredNames = Object.keys(this.options.mcpServers ?? {});
35223
35242
  const startedAt = Date.now();
@@ -35227,7 +35246,7 @@ var ClaudeAgentBridgeSessionImpl = class {
35227
35246
  );
35228
35247
  while (true) {
35229
35248
  if (this.state.kind === "closed") {
35230
- return;
35249
+ return { outcome: "closed" };
35231
35250
  }
35232
35251
  let statuses;
35233
35252
  try {
@@ -35236,19 +35255,26 @@ var ClaudeAgentBridgeSessionImpl = class {
35236
35255
  this.input.writeOutput?.(
35237
35256
  `agent_bridge_claude_mcp_gate_status_failed duration_ms=${Date.now() - startedAt} error=${error51 instanceof Error ? error51.message : String(error51)}`
35238
35257
  );
35239
- return;
35258
+ return { outcome: "status_failed" };
35240
35259
  }
35241
35260
  if (mcpServersSettled(statuses, configuredNames)) {
35261
+ if (!mcpRegistryHasTools(statuses, configuredNames)) {
35262
+ const detail = mcpStatusDetailList(statuses);
35263
+ this.input.writeOutput?.(
35264
+ `agent_bridge_claude_mcp_gate_empty duration_ms=${Date.now() - startedAt} servers=${detail}`
35265
+ );
35266
+ return { outcome: "empty", detail };
35267
+ }
35242
35268
  this.input.writeOutput?.(
35243
35269
  `agent_bridge_claude_mcp_gate_ready duration_ms=${Date.now() - startedAt} servers=${mcpStatusList(statuses)}`
35244
35270
  );
35245
- return;
35271
+ return { outcome: "ready" };
35246
35272
  }
35247
35273
  if (Date.now() >= deadline) {
35248
35274
  this.input.writeOutput?.(
35249
35275
  `agent_bridge_claude_mcp_gate_timeout duration_ms=${Date.now() - startedAt} servers=${mcpStatusList(statuses)}`
35250
35276
  );
35251
- return;
35277
+ return { outcome: "timeout" };
35252
35278
  }
35253
35279
  await delay(CLAUDE_MCP_REGISTRATION_POLL_INTERVAL_MS);
35254
35280
  }
@@ -35391,9 +35417,20 @@ function mcpServersSettled(statuses, configuredNames) {
35391
35417
  return status !== void 0 && status !== "pending";
35392
35418
  });
35393
35419
  }
35420
+ function mcpRegistryHasTools(statuses, configuredNames) {
35421
+ const configured = new Set(configuredNames);
35422
+ return statuses.some(
35423
+ (server) => configured.has(server.name) && server.status === "connected" && (server.tools === void 0 || server.tools.length > 0)
35424
+ );
35425
+ }
35394
35426
  function mcpStatusList(statuses) {
35395
35427
  return statuses.map((server) => `${server.name}:${server.status}`).join(",");
35396
35428
  }
35429
+ function mcpStatusDetailList(statuses) {
35430
+ return statuses.map(
35431
+ (server) => server.error ? `${server.name}:${server.status}(${server.error})` : `${server.name}:${server.status}`
35432
+ ).join(",");
35433
+ }
35397
35434
  function delay(ms) {
35398
35435
  return new Promise((resolve4) => {
35399
35436
  const timer = setTimeout(resolve4, ms);
@@ -35501,6 +35538,13 @@ var ClaudeCodeCommandHandler = class {
35501
35538
  agentSession = null;
35502
35539
  persistedAgentId = null;
35503
35540
  injectedCommands = /* @__PURE__ */ new Set();
35541
+ // Message commands whose injection has started but not settled. A fresh SDK
35542
+ // warm inside sendMessage can outlast the bridge's command-ack window, so a
35543
+ // redelivery may arrive while the first attempt is still in flight; acking it
35544
+ // "duplicate" then would let the worker accept a command whose injection
35545
+ // later fails, silently stalling the turn (FRA-3458). The duplicate branch
35546
+ // awaits the in-flight outcome here and relays it instead.
35547
+ inFlightMessageCommands = /* @__PURE__ */ new Map();
35504
35548
  pendingQuestions = /* @__PURE__ */ new Map();
35505
35549
  outputBuffer;
35506
35550
  projector = new ClaudeCodeProjector();
@@ -35548,13 +35592,25 @@ var ClaudeCodeCommandHandler = class {
35548
35592
  });
35549
35593
  }
35550
35594
  if (this.injectedCommands.has(delivery.commandId)) {
35595
+ const inFlight = this.inFlightMessageCommands.get(delivery.commandId);
35596
+ const outcome2 = inFlight ? await inFlight : { status: "injected" };
35551
35597
  this.input.runtimeLogger?.info(
35552
35598
  "agent_bridge_claude_command_duplicate",
35553
35599
  commandLogContext(delivery, {
35554
35600
  socket_id: socketId,
35555
- duration_ms: Date.now() - startedAt
35601
+ duration_ms: Date.now() - startedAt,
35602
+ awaited_in_flight: Boolean(inFlight),
35603
+ in_flight_status: outcome2.status
35556
35604
  })
35557
35605
  );
35606
+ if (outcome2.status === "failed") {
35607
+ return commandAck({
35608
+ delivery,
35609
+ socketId,
35610
+ status: "failed",
35611
+ error: outcome2.error
35612
+ });
35613
+ }
35558
35614
  return commandAck({
35559
35615
  delivery,
35560
35616
  socketId,
@@ -35605,6 +35661,53 @@ var ClaudeCodeCommandHandler = class {
35605
35661
  });
35606
35662
  }
35607
35663
  this.injectedCommands.add(delivery.commandId);
35664
+ const injection = this.injectMessageCommand(
35665
+ activeContext,
35666
+ delivery,
35667
+ message,
35668
+ socketId
35669
+ );
35670
+ this.inFlightMessageCommands.set(delivery.commandId, injection);
35671
+ let outcome;
35672
+ try {
35673
+ outcome = await injection;
35674
+ } finally {
35675
+ this.inFlightMessageCommands.delete(delivery.commandId);
35676
+ }
35677
+ if (outcome.status === "failed") {
35678
+ this.injectedCommands.delete(delivery.commandId);
35679
+ this.input.runtimeLogger?.warn(
35680
+ "agent_bridge_claude_command_failed",
35681
+ commandLogContext(delivery, {
35682
+ socket_id: socketId,
35683
+ duration_ms: Date.now() - startedAt,
35684
+ error: outcome.error
35685
+ })
35686
+ );
35687
+ return commandAck({
35688
+ delivery,
35689
+ socketId,
35690
+ status: "failed",
35691
+ error: outcome.error
35692
+ });
35693
+ }
35694
+ this.input.runtimeLogger?.info(
35695
+ "agent_bridge_claude_command_injected",
35696
+ commandLogContext(delivery, {
35697
+ socket_id: socketId,
35698
+ duration_ms: Date.now() - startedAt
35699
+ })
35700
+ );
35701
+ return commandAck({
35702
+ delivery,
35703
+ socketId,
35704
+ status: "injected"
35705
+ });
35706
+ }
35707
+ // Runs one message command's injection to a terminal outcome. Never rejects:
35708
+ // the returned promise is stored in the in-flight map and awaited by both the
35709
+ // original delivery and any redeliveries, so failures travel as values.
35710
+ async injectMessageCommand(activeContext, delivery, message, socketId) {
35608
35711
  try {
35609
35712
  const emitStartedAt = Date.now();
35610
35713
  this.input.runtimeLogger?.info(
@@ -35650,35 +35753,13 @@ var ClaudeCodeCommandHandler = class {
35650
35753
  duration_ms: Date.now() - sendStartedAt
35651
35754
  })
35652
35755
  );
35756
+ return { status: "injected" };
35653
35757
  } catch (error51) {
35654
- this.injectedCommands.delete(delivery.commandId);
35655
- this.input.runtimeLogger?.warn(
35656
- "agent_bridge_claude_command_failed",
35657
- commandLogContext(delivery, {
35658
- socket_id: socketId,
35659
- duration_ms: Date.now() - startedAt,
35660
- error: error51 instanceof Error ? error51.message : String(error51)
35661
- })
35662
- );
35663
- return commandAck({
35664
- delivery,
35665
- socketId,
35758
+ return {
35666
35759
  status: "failed",
35667
35760
  error: error51 instanceof Error ? error51.message : String(error51)
35668
- });
35761
+ };
35669
35762
  }
35670
- this.input.runtimeLogger?.info(
35671
- "agent_bridge_claude_command_injected",
35672
- commandLogContext(delivery, {
35673
- socket_id: socketId,
35674
- duration_ms: Date.now() - startedAt
35675
- })
35676
- );
35677
- return commandAck({
35678
- delivery,
35679
- socketId,
35680
- status: "injected"
35681
- });
35682
35763
  }
35683
35764
  // -----------------------------------------------------------------------------
35684
35765
  // Question answering
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.287",
3
+ "version": "0.1.288",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"