@autohq/cli 0.1.308 → 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.308",
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: [
@@ -40016,13 +40047,25 @@ var ClaudeCodeProjector = class {
40016
40047
  activeParts = /* @__PURE__ */ new Map();
40017
40048
  activeToolInputs = /* @__PURE__ */ new Map();
40018
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;
40019
40056
  project(message) {
40057
+ if (isClaudeCodeInterruptMarker(message)) {
40058
+ this.interruptMarkerSeen = true;
40059
+ }
40020
40060
  if (message.type === "stream_event") {
40021
40061
  return this.projectStreamEvent(message);
40022
40062
  }
40023
40063
  const parsed = parseClaudeCodeStreamRecord(message);
40024
40064
  const snapshotMessageId = assistantSnapshotMessageId(message);
40025
40065
  const suppressStreamed = snapshotMessageId !== null && this.streamedMessageIds.has(snapshotMessageId);
40066
+ if (message.type === "assistant" && !suppressStreamed) {
40067
+ this.interruptMarkerSeen = false;
40068
+ }
40026
40069
  const outputs = !suppressStreamed && message.type === "assistant" ? projectAssistantSnapshot(parsed.projections) : parsed.projections.flatMap((entry) => {
40027
40070
  if (suppressStreamed && (entry.kind === "message" || entry.kind === "tool_call")) {
40028
40071
  return [];
@@ -40033,10 +40076,24 @@ var ClaudeCodeProjector = class {
40033
40076
  outputs.push(...this.endActiveParts(), ...this.finishActiveToolInputs());
40034
40077
  this.currentMessageId = null;
40035
40078
  this.activeResponseMessageId = null;
40036
- outputs.push(projectClaudeCodeResult(parsed.result));
40079
+ outputs.push(
40080
+ projectClaudeCodeResult(parsed.result, {
40081
+ interrupted: this.isInterruptCancellation(parsed.result)
40082
+ })
40083
+ );
40084
+ this.interruptMarkerSeen = false;
40037
40085
  }
40038
40086
  return outputs;
40039
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
+ }
40040
40097
  flushPendingAssistantMessages() {
40041
40098
  const outputs = [
40042
40099
  ...this.endActiveParts(),
@@ -40044,6 +40101,7 @@ var ClaudeCodeProjector = class {
40044
40101
  ];
40045
40102
  this.currentMessageId = null;
40046
40103
  this.activeResponseMessageId = null;
40104
+ this.interruptMarkerSeen = false;
40047
40105
  return outputs;
40048
40106
  }
40049
40107
  projectStreamEvent(message) {
@@ -40052,6 +40110,7 @@ var ClaudeCodeProjector = class {
40052
40110
  this.streamedMessageIds.add(this.currentMessageId);
40053
40111
  this.activeParts.clear();
40054
40112
  this.activeToolInputs.clear();
40113
+ this.interruptMarkerSeen = false;
40055
40114
  return this.ensureResponseStarted(this.currentMessageId);
40056
40115
  }
40057
40116
  if (message.event.type === "message_stop") {
@@ -40142,7 +40201,17 @@ var ClaudeCodeProjector = class {
40142
40201
  );
40143
40202
  }
40144
40203
  };
40145
- 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
+ }
40146
40215
  return {
40147
40216
  type: "ui_message_chunk",
40148
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.308",
25613
+ version: "0.1.309",
25583
25614
  license: "SEE LICENSE IN README.md",
25584
25615
  publishConfig: {
25585
25616
  access: "public"
@@ -37114,13 +37145,25 @@ var ClaudeCodeProjector = class {
37114
37145
  activeParts = /* @__PURE__ */ new Map();
37115
37146
  activeToolInputs = /* @__PURE__ */ new Map();
37116
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;
37117
37154
  project(message) {
37155
+ if (isClaudeCodeInterruptMarker(message)) {
37156
+ this.interruptMarkerSeen = true;
37157
+ }
37118
37158
  if (message.type === "stream_event") {
37119
37159
  return this.projectStreamEvent(message);
37120
37160
  }
37121
37161
  const parsed = parseClaudeCodeStreamRecord(message);
37122
37162
  const snapshotMessageId = assistantSnapshotMessageId(message);
37123
37163
  const suppressStreamed = snapshotMessageId !== null && this.streamedMessageIds.has(snapshotMessageId);
37164
+ if (message.type === "assistant" && !suppressStreamed) {
37165
+ this.interruptMarkerSeen = false;
37166
+ }
37124
37167
  const outputs = !suppressStreamed && message.type === "assistant" ? projectAssistantSnapshot(parsed.projections) : parsed.projections.flatMap((entry) => {
37125
37168
  if (suppressStreamed && (entry.kind === "message" || entry.kind === "tool_call")) {
37126
37169
  return [];
@@ -37131,10 +37174,24 @@ var ClaudeCodeProjector = class {
37131
37174
  outputs.push(...this.endActiveParts(), ...this.finishActiveToolInputs());
37132
37175
  this.currentMessageId = null;
37133
37176
  this.activeResponseMessageId = null;
37134
- outputs.push(projectClaudeCodeResult(parsed.result));
37177
+ outputs.push(
37178
+ projectClaudeCodeResult(parsed.result, {
37179
+ interrupted: this.isInterruptCancellation(parsed.result)
37180
+ })
37181
+ );
37182
+ this.interruptMarkerSeen = false;
37135
37183
  }
37136
37184
  return outputs;
37137
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
+ }
37138
37195
  flushPendingAssistantMessages() {
37139
37196
  const outputs = [
37140
37197
  ...this.endActiveParts(),
@@ -37142,6 +37199,7 @@ var ClaudeCodeProjector = class {
37142
37199
  ];
37143
37200
  this.currentMessageId = null;
37144
37201
  this.activeResponseMessageId = null;
37202
+ this.interruptMarkerSeen = false;
37145
37203
  return outputs;
37146
37204
  }
37147
37205
  projectStreamEvent(message) {
@@ -37150,6 +37208,7 @@ var ClaudeCodeProjector = class {
37150
37208
  this.streamedMessageIds.add(this.currentMessageId);
37151
37209
  this.activeParts.clear();
37152
37210
  this.activeToolInputs.clear();
37211
+ this.interruptMarkerSeen = false;
37153
37212
  return this.ensureResponseStarted(this.currentMessageId);
37154
37213
  }
37155
37214
  if (message.event.type === "message_stop") {
@@ -37240,7 +37299,17 @@ var ClaudeCodeProjector = class {
37240
37299
  );
37241
37300
  }
37242
37301
  };
37243
- 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
+ }
37244
37313
  return {
37245
37314
  type: "ui_message_chunk",
37246
37315
  chunk: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.308",
3
+ "version": "0.1.309",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"