@autohq/cli 0.1.307 → 0.1.309

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.
@@ -23399,7 +23399,7 @@ Object.assign(lookup, {
23399
23399
  // package.json
23400
23400
  var package_default = {
23401
23401
  name: "@autohq/cli",
23402
- version: "0.1.307",
23402
+ version: "0.1.309",
23403
23403
  license: "SEE LICENSE IN README.md",
23404
23404
  publishConfig: {
23405
23405
  access: "public"
@@ -24616,6 +24616,8 @@ var ConversationRealtimeEventSchema = external_exports.discriminatedUnion("type"
24616
24616
 
24617
24617
  // ../../packages/schemas/src/claude-code.ts
24618
24618
  var ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
24619
+ var CLAUDE_CODE_INTERRUPT_MARKER_PREFIX = "[Request interrupted by user";
24620
+ var CLAUDE_CODE_EDE_DIAGNOSTIC_PREFIX = "[ede_diagnostic]";
24619
24621
  var ClaudeCodeTextBlockSchema = external_exports.object({
24620
24622
  type: external_exports.literal("text"),
24621
24623
  text: external_exports.string()
@@ -24684,6 +24686,15 @@ var ClaudeCodeUserRecordSchema = external_exports.object({
24684
24686
  type: external_exports.literal("user"),
24685
24687
  message: ClaudeCodeUserMessageSchema
24686
24688
  }).passthrough();
24689
+ var ClaudeCodeInterruptMarkerRecordSchema = external_exports.object({
24690
+ type: external_exports.literal("user"),
24691
+ message: external_exports.object({
24692
+ content: external_exports.union([
24693
+ external_exports.string(),
24694
+ external_exports.array(OptionalClaudeCodeAssistantContentBlockSchema)
24695
+ ])
24696
+ }).passthrough()
24697
+ }).passthrough();
24687
24698
  var ClaudeCodeAggregateUsageSchema = external_exports.object({
24688
24699
  input_tokens: external_exports.number().optional(),
24689
24700
  output_tokens: external_exports.number().optional(),
@@ -24746,6 +24757,26 @@ function parseClaudeCodeStreamRecord(parsed) {
24746
24757
  }
24747
24758
  };
24748
24759
  }
24760
+ function isClaudeCodeInterruptMarker(record2) {
24761
+ const parsed = ClaudeCodeInterruptMarkerRecordSchema.safeParse(record2);
24762
+ if (!parsed.success) {
24763
+ return false;
24764
+ }
24765
+ const content = parsed.data.message.content;
24766
+ if (typeof content === "string") {
24767
+ return content.startsWith(CLAUDE_CODE_INTERRUPT_MARKER_PREFIX);
24768
+ }
24769
+ return content.some(
24770
+ (block) => block !== null && block.type === "text" && block.text.startsWith(CLAUDE_CODE_INTERRUPT_MARKER_PREFIX)
24771
+ );
24772
+ }
24773
+ function isClaudeCodeEdeDiagnosticOnlyError(errorMessage4) {
24774
+ if (!errorMessage4) {
24775
+ return false;
24776
+ }
24777
+ const lines = errorMessage4.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
24778
+ return lines.length > 0 && lines.every((line) => line.startsWith(CLAUDE_CODE_EDE_DIAGNOSTIC_PREFIX));
24779
+ }
24749
24780
  function textContent(text2) {
24750
24781
  return {
24751
24782
  parts: [
@@ -39832,7 +39863,7 @@ function legacyToolEntry(chunk) {
39832
39863
  {
39833
39864
  type: "tool_result",
39834
39865
  toolUseId: legacyToolCallId(chunk.toolCallId),
39835
- output: chunk.errorText,
39866
+ output: errorOutput(chunk.errorText),
39836
39867
  isError: true
39837
39868
  }
39838
39869
  ]
@@ -39860,6 +39891,13 @@ function legacyToolEntry(chunk) {
39860
39891
  function legacyToolCallId(toolCallId) {
39861
39892
  return toolCallId === UNKNOWN_MESSAGE_ID ? null : toolCallId;
39862
39893
  }
39894
+ function errorOutput(errorText) {
39895
+ try {
39896
+ return JSON.parse(errorText);
39897
+ } catch {
39898
+ return errorText;
39899
+ }
39900
+ }
39863
39901
  function terminalStatusText(projection) {
39864
39902
  if (projection.statusText) {
39865
39903
  return projection.statusText;
@@ -40009,13 +40047,25 @@ var ClaudeCodeProjector = class {
40009
40047
  activeParts = /* @__PURE__ */ new Map();
40010
40048
  activeToolInputs = /* @__PURE__ */ new Map();
40011
40049
  streamedMessageIds = /* @__PURE__ */ new Set();
40050
+ // The SDK's "[Request interrupted by user]" transcript marker was seen since
40051
+ // the last terminal result: the very next diagnostic-only
40052
+ // `error_during_execution` result is that interrupt's cancellation, not a
40053
+ // real turn failure (FRA-3548). Cleared on every result and on the next
40054
+ // message_start so a stale marker can never reclassify a later failure.
40055
+ interruptMarkerSeen = false;
40012
40056
  project(message) {
40057
+ if (isClaudeCodeInterruptMarker(message)) {
40058
+ this.interruptMarkerSeen = true;
40059
+ }
40013
40060
  if (message.type === "stream_event") {
40014
40061
  return this.projectStreamEvent(message);
40015
40062
  }
40016
40063
  const parsed = parseClaudeCodeStreamRecord(message);
40017
40064
  const snapshotMessageId = assistantSnapshotMessageId(message);
40018
40065
  const suppressStreamed = snapshotMessageId !== null && this.streamedMessageIds.has(snapshotMessageId);
40066
+ if (message.type === "assistant" && !suppressStreamed) {
40067
+ this.interruptMarkerSeen = false;
40068
+ }
40019
40069
  const outputs = !suppressStreamed && message.type === "assistant" ? projectAssistantSnapshot(parsed.projections) : parsed.projections.flatMap((entry) => {
40020
40070
  if (suppressStreamed && (entry.kind === "message" || entry.kind === "tool_call")) {
40021
40071
  return [];
@@ -40026,10 +40076,24 @@ var ClaudeCodeProjector = class {
40026
40076
  outputs.push(...this.endActiveParts(), ...this.finishActiveToolInputs());
40027
40077
  this.currentMessageId = null;
40028
40078
  this.activeResponseMessageId = null;
40029
- outputs.push(projectClaudeCodeResult(parsed.result));
40079
+ outputs.push(
40080
+ projectClaudeCodeResult(parsed.result, {
40081
+ interrupted: this.isInterruptCancellation(parsed.result)
40082
+ })
40083
+ );
40084
+ this.interruptMarkerSeen = false;
40030
40085
  }
40031
40086
  return outputs;
40032
40087
  }
40088
+ // An interrupt cancels the running turn cleanly at the transcript level, but
40089
+ // Claude Code has no cancelled result subtype: the turn's terminal result
40090
+ // surfaces as a diagnostic-only `error_during_execution`. Treating that as a
40091
+ // turn failure fed the FRA-3548 redelivery loop (the bridge redelivered a
40092
+ // message the SDK was actively answering), so a failed result bracketed by
40093
+ // the SDK's own interrupt marker is classified as a cancellation instead.
40094
+ isInterruptCancellation(result) {
40095
+ return result.isError && this.interruptMarkerSeen && isClaudeCodeEdeDiagnosticOnlyError(result.errorMessage);
40096
+ }
40033
40097
  flushPendingAssistantMessages() {
40034
40098
  const outputs = [
40035
40099
  ...this.endActiveParts(),
@@ -40037,6 +40101,7 @@ var ClaudeCodeProjector = class {
40037
40101
  ];
40038
40102
  this.currentMessageId = null;
40039
40103
  this.activeResponseMessageId = null;
40104
+ this.interruptMarkerSeen = false;
40040
40105
  return outputs;
40041
40106
  }
40042
40107
  projectStreamEvent(message) {
@@ -40045,6 +40110,7 @@ var ClaudeCodeProjector = class {
40045
40110
  this.streamedMessageIds.add(this.currentMessageId);
40046
40111
  this.activeParts.clear();
40047
40112
  this.activeToolInputs.clear();
40113
+ this.interruptMarkerSeen = false;
40048
40114
  return this.ensureResponseStarted(this.currentMessageId);
40049
40115
  }
40050
40116
  if (message.event.type === "message_stop") {
@@ -40135,7 +40201,17 @@ var ClaudeCodeProjector = class {
40135
40201
  );
40136
40202
  }
40137
40203
  };
40138
- function projectClaudeCodeResult(result) {
40204
+ function projectClaudeCodeResult(result, options = {}) {
40205
+ if (options.interrupted) {
40206
+ return {
40207
+ type: "ui_message_chunk",
40208
+ chunk: { type: "finish", finishReason: "stop" },
40209
+ // Neutral wording: the projector sees that an interrupt cancelled the
40210
+ // turn, not why the interrupt was sent.
40211
+ statusText: "claude-code turn interrupted",
40212
+ turnStatus: "completed"
40213
+ };
40214
+ }
40139
40215
  return {
40140
40216
  type: "ui_message_chunk",
40141
40217
  chunk: {
package/dist/index.js CHANGED
@@ -16004,6 +16004,26 @@ function parseClaudeCodeStreamRecord(parsed) {
16004
16004
  }
16005
16005
  };
16006
16006
  }
16007
+ function isClaudeCodeInterruptMarker(record2) {
16008
+ const parsed = ClaudeCodeInterruptMarkerRecordSchema.safeParse(record2);
16009
+ if (!parsed.success) {
16010
+ return false;
16011
+ }
16012
+ const content = parsed.data.message.content;
16013
+ if (typeof content === "string") {
16014
+ return content.startsWith(CLAUDE_CODE_INTERRUPT_MARKER_PREFIX);
16015
+ }
16016
+ return content.some(
16017
+ (block) => block !== null && block.type === "text" && block.text.startsWith(CLAUDE_CODE_INTERRUPT_MARKER_PREFIX)
16018
+ );
16019
+ }
16020
+ function isClaudeCodeEdeDiagnosticOnlyError(errorMessage6) {
16021
+ if (!errorMessage6) {
16022
+ return false;
16023
+ }
16024
+ const lines = errorMessage6.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
16025
+ return lines.length > 0 && lines.every((line) => line.startsWith(CLAUDE_CODE_EDE_DIAGNOSTIC_PREFIX));
16026
+ }
16007
16027
  function textContent(text) {
16008
16028
  return {
16009
16029
  parts: [
@@ -16185,7 +16205,7 @@ function usdAmount(value) {
16185
16205
  }
16186
16206
  return value;
16187
16207
  }
16188
- var ASK_USER_QUESTION_TOOL_NAME, ClaudeCodeTextBlockSchema, ClaudeCodeToolUseBlockSchema, ClaudeCodeThinkingBlockSchema, ClaudeCodeToolResultBlockSchema, ClaudeCodeAssistantContentBlockSchema, OptionalClaudeCodeAssistantContentBlockSchema, ClaudeCodeAssistantContentSchema, OptionalClaudeCodeToolResultBlockSchema, ClaudeCodeToolResultContentSchema, ClaudeCodeUserContentSchema, ClaudeCodeAssistantMessageSchema, ClaudeCodeUserMessageSchema, ClaudeCodeSystemRecordSchema, ClaudeCodeAssistantRecordSchema, ClaudeCodeUserRecordSchema, ClaudeCodeAggregateUsageSchema, ClaudeCodeModelUsageSchema, ClaudeCodeResultRecordSchema, ClaudeCodeSessionRecordSchema, ClaudeCodeStreamRecordSchema, AskUserQuestionInputSchema;
16208
+ var ASK_USER_QUESTION_TOOL_NAME, CLAUDE_CODE_INTERRUPT_MARKER_PREFIX, CLAUDE_CODE_EDE_DIAGNOSTIC_PREFIX, ClaudeCodeTextBlockSchema, ClaudeCodeToolUseBlockSchema, ClaudeCodeThinkingBlockSchema, ClaudeCodeToolResultBlockSchema, ClaudeCodeAssistantContentBlockSchema, OptionalClaudeCodeAssistantContentBlockSchema, ClaudeCodeAssistantContentSchema, OptionalClaudeCodeToolResultBlockSchema, ClaudeCodeToolResultContentSchema, ClaudeCodeUserContentSchema, ClaudeCodeAssistantMessageSchema, ClaudeCodeUserMessageSchema, ClaudeCodeSystemRecordSchema, ClaudeCodeAssistantRecordSchema, ClaudeCodeUserRecordSchema, ClaudeCodeInterruptMarkerRecordSchema, ClaudeCodeAggregateUsageSchema, ClaudeCodeModelUsageSchema, ClaudeCodeResultRecordSchema, ClaudeCodeSessionRecordSchema, ClaudeCodeStreamRecordSchema, AskUserQuestionInputSchema;
16189
16209
  var init_claude_code = __esm({
16190
16210
  "../../packages/schemas/src/claude-code.ts"() {
16191
16211
  "use strict";
@@ -16193,6 +16213,8 @@ var init_claude_code = __esm({
16193
16213
  init_conversation();
16194
16214
  init_primitives();
16195
16215
  ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion";
16216
+ CLAUDE_CODE_INTERRUPT_MARKER_PREFIX = "[Request interrupted by user";
16217
+ CLAUDE_CODE_EDE_DIAGNOSTIC_PREFIX = "[ede_diagnostic]";
16196
16218
  ClaudeCodeTextBlockSchema = external_exports.object({
16197
16219
  type: external_exports.literal("text"),
16198
16220
  text: external_exports.string()
@@ -16261,6 +16283,15 @@ var init_claude_code = __esm({
16261
16283
  type: external_exports.literal("user"),
16262
16284
  message: ClaudeCodeUserMessageSchema
16263
16285
  }).passthrough();
16286
+ ClaudeCodeInterruptMarkerRecordSchema = external_exports.object({
16287
+ type: external_exports.literal("user"),
16288
+ message: external_exports.object({
16289
+ content: external_exports.union([
16290
+ external_exports.string(),
16291
+ external_exports.array(OptionalClaudeCodeAssistantContentBlockSchema)
16292
+ ])
16293
+ }).passthrough()
16294
+ }).passthrough();
16264
16295
  ClaudeCodeAggregateUsageSchema = external_exports.object({
16265
16296
  input_tokens: external_exports.number().optional(),
16266
16297
  output_tokens: external_exports.number().optional(),
@@ -25579,7 +25610,7 @@ var init_package = __esm({
25579
25610
  "package.json"() {
25580
25611
  package_default = {
25581
25612
  name: "@autohq/cli",
25582
- version: "0.1.307",
25613
+ version: "0.1.309",
25583
25614
  license: "SEE LICENSE IN README.md",
25584
25615
  publishConfig: {
25585
25616
  access: "public"
@@ -36929,7 +36960,7 @@ function legacyToolEntry(chunk) {
36929
36960
  {
36930
36961
  type: "tool_result",
36931
36962
  toolUseId: legacyToolCallId(chunk.toolCallId),
36932
- output: chunk.errorText,
36963
+ output: errorOutput(chunk.errorText),
36933
36964
  isError: true
36934
36965
  }
36935
36966
  ]
@@ -36957,6 +36988,13 @@ function legacyToolEntry(chunk) {
36957
36988
  function legacyToolCallId(toolCallId) {
36958
36989
  return toolCallId === UNKNOWN_MESSAGE_ID ? null : toolCallId;
36959
36990
  }
36991
+ function errorOutput(errorText) {
36992
+ try {
36993
+ return JSON.parse(errorText);
36994
+ } catch {
36995
+ return errorText;
36996
+ }
36997
+ }
36960
36998
  function terminalStatusText(projection) {
36961
36999
  if (projection.statusText) {
36962
37000
  return projection.statusText;
@@ -37107,13 +37145,25 @@ var ClaudeCodeProjector = class {
37107
37145
  activeParts = /* @__PURE__ */ new Map();
37108
37146
  activeToolInputs = /* @__PURE__ */ new Map();
37109
37147
  streamedMessageIds = /* @__PURE__ */ new Set();
37148
+ // The SDK's "[Request interrupted by user]" transcript marker was seen since
37149
+ // the last terminal result: the very next diagnostic-only
37150
+ // `error_during_execution` result is that interrupt's cancellation, not a
37151
+ // real turn failure (FRA-3548). Cleared on every result and on the next
37152
+ // message_start so a stale marker can never reclassify a later failure.
37153
+ interruptMarkerSeen = false;
37110
37154
  project(message) {
37155
+ if (isClaudeCodeInterruptMarker(message)) {
37156
+ this.interruptMarkerSeen = true;
37157
+ }
37111
37158
  if (message.type === "stream_event") {
37112
37159
  return this.projectStreamEvent(message);
37113
37160
  }
37114
37161
  const parsed = parseClaudeCodeStreamRecord(message);
37115
37162
  const snapshotMessageId = assistantSnapshotMessageId(message);
37116
37163
  const suppressStreamed = snapshotMessageId !== null && this.streamedMessageIds.has(snapshotMessageId);
37164
+ if (message.type === "assistant" && !suppressStreamed) {
37165
+ this.interruptMarkerSeen = false;
37166
+ }
37117
37167
  const outputs = !suppressStreamed && message.type === "assistant" ? projectAssistantSnapshot(parsed.projections) : parsed.projections.flatMap((entry) => {
37118
37168
  if (suppressStreamed && (entry.kind === "message" || entry.kind === "tool_call")) {
37119
37169
  return [];
@@ -37124,10 +37174,24 @@ var ClaudeCodeProjector = class {
37124
37174
  outputs.push(...this.endActiveParts(), ...this.finishActiveToolInputs());
37125
37175
  this.currentMessageId = null;
37126
37176
  this.activeResponseMessageId = null;
37127
- outputs.push(projectClaudeCodeResult(parsed.result));
37177
+ outputs.push(
37178
+ projectClaudeCodeResult(parsed.result, {
37179
+ interrupted: this.isInterruptCancellation(parsed.result)
37180
+ })
37181
+ );
37182
+ this.interruptMarkerSeen = false;
37128
37183
  }
37129
37184
  return outputs;
37130
37185
  }
37186
+ // An interrupt cancels the running turn cleanly at the transcript level, but
37187
+ // Claude Code has no cancelled result subtype: the turn's terminal result
37188
+ // surfaces as a diagnostic-only `error_during_execution`. Treating that as a
37189
+ // turn failure fed the FRA-3548 redelivery loop (the bridge redelivered a
37190
+ // message the SDK was actively answering), so a failed result bracketed by
37191
+ // the SDK's own interrupt marker is classified as a cancellation instead.
37192
+ isInterruptCancellation(result) {
37193
+ return result.isError && this.interruptMarkerSeen && isClaudeCodeEdeDiagnosticOnlyError(result.errorMessage);
37194
+ }
37131
37195
  flushPendingAssistantMessages() {
37132
37196
  const outputs = [
37133
37197
  ...this.endActiveParts(),
@@ -37135,6 +37199,7 @@ var ClaudeCodeProjector = class {
37135
37199
  ];
37136
37200
  this.currentMessageId = null;
37137
37201
  this.activeResponseMessageId = null;
37202
+ this.interruptMarkerSeen = false;
37138
37203
  return outputs;
37139
37204
  }
37140
37205
  projectStreamEvent(message) {
@@ -37143,6 +37208,7 @@ var ClaudeCodeProjector = class {
37143
37208
  this.streamedMessageIds.add(this.currentMessageId);
37144
37209
  this.activeParts.clear();
37145
37210
  this.activeToolInputs.clear();
37211
+ this.interruptMarkerSeen = false;
37146
37212
  return this.ensureResponseStarted(this.currentMessageId);
37147
37213
  }
37148
37214
  if (message.event.type === "message_stop") {
@@ -37233,7 +37299,17 @@ var ClaudeCodeProjector = class {
37233
37299
  );
37234
37300
  }
37235
37301
  };
37236
- function projectClaudeCodeResult(result) {
37302
+ function projectClaudeCodeResult(result, options = {}) {
37303
+ if (options.interrupted) {
37304
+ return {
37305
+ type: "ui_message_chunk",
37306
+ chunk: { type: "finish", finishReason: "stop" },
37307
+ // Neutral wording: the projector sees that an interrupt cancelled the
37308
+ // turn, not why the interrupt was sent.
37309
+ statusText: "claude-code turn interrupted",
37310
+ turnStatus: "completed"
37311
+ };
37312
+ }
37237
37313
  return {
37238
37314
  type: "ui_message_chunk",
37239
37315
  chunk: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.307",
3
+ "version": "0.1.309",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"