@nathapp/nax 0.85.0 → 0.85.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 (2) hide show
  1. package/dist/nax.js +236 -79
  2. package/package.json +3 -3
package/dist/nax.js CHANGED
@@ -143,14 +143,48 @@ var init_infra = __esm(() => {
143
143
  init_nax_error();
144
144
  });
145
145
 
146
+ // ../nax-agent/src/internal/redact-structured.ts
147
+ function redactStructured(text) {
148
+ let out = text;
149
+ for (const { re } of STRUCTURED_PATTERNS) {
150
+ re.lastIndex = 0;
151
+ out = out.replace(re, (_match, keep) => `${keep}${REDACTED}`);
152
+ }
153
+ return out;
154
+ }
155
+ var REDACTED = "[REDACTED]", KEYWORD, KEY, DQ_BODY, ESCAPED_BODY, SQ_BODY, NOT_A_REFERENCE, NOT_A_TOKEN_COUNT, AUTH_SCHEME, STRUCTURED_PATTERNS;
156
+ var init_redact_structured = __esm(() => {
157
+ KEYWORD = String.raw`(?:SECRET|TOKEN(?!s\b)|API[_-]?KEY|PASSWORD|PRIVATE[_-]?KEY|ACCESS[_-]?KEY|WEBHOOK|AUTHORIZATION|COOKIE|CREDENTIAL|PASSWD|(?<=[\w.-])_(?:URI|DSN)|CONNECTION_?STRING)`;
158
+ KEY = String.raw`[\w.-]{0,64}?${KEYWORD}[\w.-]{0,64}`;
159
+ DQ_BODY = String.raw`(?:[^"\\\r\n]|\\.)+`;
160
+ ESCAPED_BODY = String.raw`(?:[^"\\\r\n]|\\(?!\\*"))+`;
161
+ SQ_BODY = String.raw`[^'\r\n]+`;
162
+ NOT_A_REFERENCE = String.raw`(?!["'$<{(\[]|process\.|import\.meta|os\.|env\.|await\b|new\b|[\w.]+\(|(?:string|number|boolean|str|int|any|unknown|undefined|null|true|false|none)(?![\w-]))`;
163
+ NOT_A_TOKEN_COUNT = String.raw`(?![\w.-]{0,64}?TOKEN(?!s\b)[\w.-]{0,64}[ \t]{0,8}[=:][ \t]{0,8}\d+(?![\w.-]))`;
164
+ AUTH_SCHEME = String.raw`(?:(?:Bearer|Basic|Digest|Token)[ \t]+)?`;
165
+ STRUCTURED_PATTERNS = [
166
+ { re: new RegExp(String.raw`("${KEY}"\s{0,256}:\s{0,256}")(${DQ_BODY})`, "gi") },
167
+ { re: new RegExp(String.raw`('${KEY}'\s{0,256}:\s{0,256}')(${SQ_BODY})`, "gi") },
168
+ { re: new RegExp(String.raw`('${KEY}'\s{0,256}:\s{0,256}")(${DQ_BODY})`, "gi") },
169
+ { re: new RegExp(String.raw`(\\{1,3}"${KEY}\\{1,3}"\s{0,256}:\s{0,256}\\{1,3}")(${ESCAPED_BODY})`, "gi") },
170
+ { re: new RegExp(String.raw`(?<![\w.-])(${KEY}[ \t]{0,8}[=:][ \t]{0,8}")(${DQ_BODY})`, "gi") },
171
+ { re: new RegExp(String.raw`(?<![\w.-])(${KEY}[ \t]{0,8}[=:][ \t]{0,8}')(${SQ_BODY})`, "gi") },
172
+ {
173
+ re: new RegExp(String.raw`(?<![\w.-])${NOT_A_TOKEN_COUNT}(${KEY}[ \t]{0,8}[=:][ \t]{0,8})${NOT_A_REFERENCE}(${AUTH_SCHEME}[^\s"',]+)`, "gi")
174
+ }
175
+ ];
176
+ });
177
+
146
178
  // ../nax-agent/src/internal/redact.ts
147
179
  function redactString(value) {
148
180
  let out = value;
149
- for (const { re } of SECRET_VALUE_PATTERNS) {
181
+ for (const { kind, re } of SECRET_VALUE_PATTERNS) {
182
+ if (STRUCTURED_KINDS.has(kind))
183
+ continue;
150
184
  re.lastIndex = 0;
151
- out = out.replace(re, REDACTED);
185
+ out = out.replace(re, REDACTED2);
152
186
  }
153
- return out;
187
+ return redactStructured(out);
154
188
  }
155
189
  function redactSecrets(input) {
156
190
  return redactValue(input);
@@ -204,15 +238,16 @@ function redactValue(input, seen = new WeakSet, depth = 0) {
204
238
  return input.map((item) => redactValue(item, seen, depth + 1));
205
239
  const out = {};
206
240
  for (const [key, value] of Object.entries(input)) {
207
- out[key] = SECRET_KEY_PATTERN.test(key) ? REDACTED : redactValue(value, seen, depth + 1);
241
+ out[key] = SECRET_KEY_PATTERN.test(key) ? REDACTED2 : redactValue(value, seen, depth + 1);
208
242
  }
209
243
  return out;
210
244
  } finally {
211
245
  seen.delete(input);
212
246
  }
213
247
  }
214
- var SECRET_KEY_PATTERN, SECRET_VALUE_PATTERNS, REDACTED = "[REDACTED]", MAX_REDACT_DEPTH = 100, CIRCULAR_REF_MARKER = "[Circular]";
248
+ var SECRET_KEY_PATTERN, SECRET_VALUE_PATTERNS, REDACTED2 = "[REDACTED]", STRUCTURED_KINDS, MAX_REDACT_DEPTH = 100, CIRCULAR_REF_MARKER = "[Circular]";
215
249
  var init_redact = __esm(() => {
250
+ init_redact_structured();
216
251
  SECRET_KEY_PATTERN = /(SECRET|TOKEN(?!s\b)|API_?KEY|PASSWORD|PRIVATE_?KEY|ACCESS_?KEY|WEBHOOK|AUTHORIZATION|COOKIE|CREDENTIAL|PASSWD|(?:\w+)?_URL|\w+_URI|\w+_DSN|CONNECTION\s*STRING)/i;
217
252
  SECRET_VALUE_PATTERNS = [
218
253
  { kind: "openai", re: /sk-[A-Za-z0-9_-]{16,}/g },
@@ -238,6 +273,7 @@ var init_redact = __esm(() => {
238
273
  { kind: "cookie", re: /\b(?:Set-)?Cookie\s*:\s*[^\r\n]+/gi },
239
274
  { kind: "url-credentials", re: /\b[a-z][a-z0-9+.-]*:\/\/(?:[^/\s@]*:[^/\s@]+)@/gi }
240
275
  ];
276
+ STRUCTURED_KINDS = new Set(["assignment", "api-key-header"]);
241
277
  });
242
278
 
243
279
  // ../nax-agent/src/permissions/secret-spans.ts
@@ -26699,6 +26735,23 @@ var init_interaction_handler = __esm(() => {
26699
26735
  NO_OP_INTERACTION_HANDLER2 = NO_OP_INTERACTION_HANDLER;
26700
26736
  });
26701
26737
 
26738
+ // ../nax-agent/src/native/session/compaction-settings.ts
26739
+ function resolveCompaction(input) {
26740
+ return compactionSettingsSchema.parse(input);
26741
+ }
26742
+ var DEFAULT_COMPACTION, compactionSettingsSchema;
26743
+ var init_compaction_settings = __esm(() => {
26744
+ init_zod();
26745
+ DEFAULT_COMPACTION = { enabled: true, compactAtPercent: 90, keepRecentPercent: 30 };
26746
+ compactionSettingsSchema = exports_external.object({
26747
+ enabled: exports_external.boolean().default(DEFAULT_COMPACTION.enabled),
26748
+ compactAtPercent: exports_external.number().int().min(50).max(99).default(DEFAULT_COMPACTION.compactAtPercent),
26749
+ keepRecentPercent: exports_external.number().int().min(5).max(79).default(DEFAULT_COMPACTION.keepRecentPercent)
26750
+ }).refine((c) => c.keepRecentPercent <= c.compactAtPercent - 20, {
26751
+ message: "keepRecentPercent must be at least 20 points below compactAtPercent"
26752
+ }).default({ ...DEFAULT_COMPACTION });
26753
+ });
26754
+
26702
26755
  // ../nax-agent/src/session/native-backend-options.ts
26703
26756
  function isRecord2(value) {
26704
26757
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -26710,6 +26763,7 @@ var isStringArray = (value) => Array.isArray(value) && value.every((item) => typ
26710
26763
  var init_native_backend_options = __esm(() => {
26711
26764
  init_zod();
26712
26765
  init_models();
26766
+ init_compaction_settings();
26713
26767
  init_instruction_file_name();
26714
26768
  init_agent_session_errors();
26715
26769
  OptionsSchema2 = exports_external.strictObject({
@@ -26724,7 +26778,8 @@ var init_native_backend_options = __esm(() => {
26724
26778
  }).optional(),
26725
26779
  bashApproval: exports_external.enum(["raw", "gated", "escalate"]).optional(),
26726
26780
  allowUnsandboxed: exports_external.boolean().optional(),
26727
- carryHistoryAcrossModels: exports_external.boolean().optional()
26781
+ carryHistoryAcrossModels: exports_external.boolean().optional(),
26782
+ compaction: compactionSettingsSchema.optional()
26728
26783
  });
26729
26784
  });
26730
26785
 
@@ -27051,6 +27106,7 @@ var init_session_tool_support = __esm(() => {
27051
27106
  var init_native_backend = __esm(() => {
27052
27107
  init_spin_breaker();
27053
27108
  init_models();
27109
+ init_compaction_settings();
27054
27110
  init_transcript_identity();
27055
27111
  init_session_adapter();
27056
27112
  init_agent_session_errors();
@@ -29661,6 +29717,7 @@ __export(exports_internal, {
29661
29717
  COMPACTION_SUMMARY_SUFFIX: () => COMPACTION_SUMMARY_SUFFIX,
29662
29718
  DEFAULT_BASH_APPROVAL_MODE: () => DEFAULT_BASH_APPROVAL_MODE,
29663
29719
  DEFAULT_BASH_SHELL: () => DEFAULT_BASH_SHELL,
29720
+ DEFAULT_COMPACTION: () => DEFAULT_COMPACTION,
29664
29721
  DEFAULT_INSTRUCTION_FILE_NAME: () => DEFAULT_INSTRUCTION_FILE_NAME,
29665
29722
  DEFAULT_LOG_FORMAT: () => DEFAULT_LOG_FORMAT,
29666
29723
  DEFAULT_LOG_MAX_COUNT: () => DEFAULT_LOG_MAX_COUNT,
@@ -29786,6 +29843,7 @@ __export(exports_internal, {
29786
29843
  codingToolSupportModule: () => exports_coding_tool_support,
29787
29844
  codingToolsToDefinitions: () => codingToolsToDefinitions,
29788
29845
  commandSpecIncludes: () => commandSpecIncludes,
29846
+ compactionSettingsSchema: () => compactionSettingsSchema,
29789
29847
  compactionThreshold: () => compactionThreshold,
29790
29848
  compileToolPolicy: () => compileToolPolicy,
29791
29849
  completeWithRecovery: () => completeWithRecovery,
@@ -29940,6 +29998,7 @@ __export(exports_internal, {
29940
29998
  resetSandboxBackend: () => resetSandboxBackend,
29941
29999
  resolveBashApproval: () => resolveBashApproval,
29942
30000
  resolveBashSupport: () => resolveBashSupport,
30001
+ resolveCompaction: () => resolveCompaction,
29943
30002
  resolveContextWindow: () => resolveContextWindow,
29944
30003
  resolveGitLayout: () => resolveGitLayout,
29945
30004
  resolveNativeId: () => resolveNativeId,
@@ -30016,6 +30075,7 @@ var init_internal = __esm(() => {
30016
30075
  init_core();
30017
30076
  init_infra();
30018
30077
  init_git_exec();
30078
+ init_compaction_settings();
30019
30079
  init_instruction_file_name();
30020
30080
  init_repository_instructions();
30021
30081
  init_session();
@@ -33192,13 +33252,7 @@ var init_schemas_execution = __esm(() => {
33192
33252
  rectification: RectificationConfigSchema,
33193
33253
  regressionGate: RegressionGateConfigSchema,
33194
33254
  contextProviderTokenBudget: exports_external.number().int().positive({ message: "contextProviderTokenBudget must be > 0" }).default(2000),
33195
- compaction: exports_external.object({
33196
- enabled: exports_external.boolean().default(true),
33197
- compactAtPercent: exports_external.number().int().min(50).max(99).default(90),
33198
- keepRecentPercent: exports_external.number().int().min(5).max(79).default(30)
33199
- }).refine((c) => c.keepRecentPercent <= c.compactAtPercent - 20, {
33200
- message: "keepRecentPercent must be at least 20 points below compactAtPercent"
33201
- }).default({ enabled: true, compactAtPercent: 90, keepRecentPercent: 30 }),
33255
+ compaction: compactionSettingsSchema,
33202
33256
  lintCommand: exports_external.string().nullable().optional(),
33203
33257
  typecheckCommand: exports_external.string().nullable().optional(),
33204
33258
  permissionProfile: exports_external.enum(["unrestricted", "safe", "scoped"]).default("unrestricted"),
@@ -38893,7 +38947,7 @@ var package_default;
38893
38947
  var init_package = __esm(() => {
38894
38948
  package_default = {
38895
38949
  name: "@nathapp/nax",
38896
- version: "0.85.0",
38950
+ version: "0.85.1",
38897
38951
  description: "AI Coding Agent Orchestrator \u2014 loops until done",
38898
38952
  type: "module",
38899
38953
  bin: {
@@ -38979,8 +39033,8 @@ var init_package = __esm(() => {
38979
39033
  dependencies: {
38980
39034
  "@agentclientprotocol/sdk": "~1.7.0",
38981
39035
  "@anthropic-ai/sandbox-runtime": "0.0.77",
38982
- "@modelcontextprotocol/sdk": "^1.30.0",
38983
- "@nathapp/nax-ai": "0.85.0",
39036
+ "@modelcontextprotocol/sdk": "^1.32.1",
39037
+ "@nathapp/nax-ai": "0.85.1",
38984
39038
  chalk: "^5.6.2",
38985
39039
  commander: "^13.1.0",
38986
39040
  ink: "^6.7.0",
@@ -57399,8 +57453,8 @@ var init_version = __esm(() => {
57399
57453
  NAX_AI_VERSION = CATALOG_VERSION;
57400
57454
  NAX_COMMIT = (() => {
57401
57455
  try {
57402
- if (/^[0-9a-f]{6,10}$/.test("dafafae"))
57403
- return "dafafae";
57456
+ if (/^[0-9a-f]{6,10}$/.test("9611b61"))
57457
+ return "9611b61";
57404
57458
  } catch {}
57405
57459
  try {
57406
57460
  const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
@@ -59249,7 +59303,7 @@ var init_v4_mini = __esm(() => {
59249
59303
  init_external2();
59250
59304
  });
59251
59305
 
59252
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
59306
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js
59253
59307
  function isZ4Schema(s) {
59254
59308
  const schema = s;
59255
59309
  return !!schema._zod;
@@ -59326,7 +59380,7 @@ var init_v4 = __esm(() => {
59326
59380
  init_classic();
59327
59381
  });
59328
59382
 
59329
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
59383
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
59330
59384
  var LATEST_PROTOCOL_VERSION = "2025-11-25", DEFAULT_NEGOTIATED_PROTOCOL_VERSION = "2025-03-26", SUPPORTED_PROTOCOL_VERSIONS, RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task", JSONRPC_VERSION = "2.0", AssertObjectSchema, ProgressTokenSchema, CursorSchema, TaskCreationParamsSchema, TaskMetadataSchema, RelatedTaskMetadataSchema, RequestMetaSchema, BaseRequestParamsSchema, TaskAugmentedRequestParamsSchema, isTaskAugmentedRequestParams = (value) => TaskAugmentedRequestParamsSchema.safeParse(value).success, RequestSchema, NotificationsParamsSchema, NotificationSchema, ResultSchema, RequestIdSchema, JSONRPCRequestSchema, isJSONRPCRequest = (value) => JSONRPCRequestSchema.safeParse(value).success, JSONRPCNotificationSchema, isJSONRPCNotification = (value) => JSONRPCNotificationSchema.safeParse(value).success, JSONRPCResultResponseSchema, isJSONRPCResultResponse = (value) => JSONRPCResultResponseSchema.safeParse(value).success, ErrorCode, JSONRPCErrorResponseSchema, isJSONRPCErrorResponse = (value) => JSONRPCErrorResponseSchema.safeParse(value).success, JSONRPCMessageSchema, JSONRPCResponseSchema, EmptyResultSchema, CancelledNotificationParamsSchema, CancelledNotificationSchema, IconSchema, IconsSchema, BaseMetadataSchema, ImplementationSchema, FormElicitationCapabilitySchema, ElicitationCapabilitySchema, ClientTasksCapabilitySchema, ServerTasksCapabilitySchema, ClientCapabilitiesSchema, InitializeRequestParamsSchema, InitializeRequestSchema, isInitializeRequest = (value) => InitializeRequestSchema.safeParse(value).success, ServerCapabilitiesSchema, InitializeResultSchema, InitializedNotificationSchema, PingRequestSchema, ProgressSchema, ProgressNotificationParamsSchema, ProgressNotificationSchema, PaginatedRequestParamsSchema, PaginatedRequestSchema, PaginatedResultSchema, TaskStatusSchema, TaskSchema, CreateTaskResultSchema, TaskStatusNotificationParamsSchema, TaskStatusNotificationSchema, GetTaskRequestSchema, GetTaskResultSchema, GetTaskPayloadRequestSchema, GetTaskPayloadResultSchema, ListTasksRequestSchema, ListTasksResultSchema, CancelTaskRequestSchema, CancelTaskResultSchema, ResourceContentsSchema, TextResourceContentsSchema, Base64Schema, BlobResourceContentsSchema, RoleSchema, AnnotationsSchema, ResourceSchema, ResourceTemplateSchema, ListResourcesRequestSchema, ListResourcesResultSchema, ListResourceTemplatesRequestSchema, ListResourceTemplatesResultSchema, ResourceRequestParamsSchema, ReadResourceRequestParamsSchema, ReadResourceRequestSchema, ReadResourceResultSchema, ResourceListChangedNotificationSchema, SubscribeRequestParamsSchema, SubscribeRequestSchema, UnsubscribeRequestParamsSchema, UnsubscribeRequestSchema, ResourceUpdatedNotificationParamsSchema, ResourceUpdatedNotificationSchema, PromptArgumentSchema, PromptSchema, ListPromptsRequestSchema, ListPromptsResultSchema, GetPromptRequestParamsSchema, GetPromptRequestSchema, TextContentSchema, ImageContentSchema, AudioContentSchema, ToolUseContentSchema, EmbeddedResourceSchema, ResourceLinkSchema, ContentBlockSchema, PromptMessageSchema, GetPromptResultSchema, PromptListChangedNotificationSchema, ToolAnnotationsSchema, ToolExecutionSchema, ToolSchema, ListToolsRequestSchema, ListToolsResultSchema, CallToolResultSchema, CompatibilityCallToolResultSchema, CallToolRequestParamsSchema, CallToolRequestSchema, ToolListChangedNotificationSchema, ListChangedOptionsBaseSchema, LoggingLevelSchema, SetLevelRequestParamsSchema, SetLevelRequestSchema, LoggingMessageNotificationParamsSchema, LoggingMessageNotificationSchema, ModelHintSchema, ModelPreferencesSchema, ToolChoiceSchema, ToolResultContentSchema, SamplingContentSchema, SamplingMessageContentBlockSchema, SamplingMessageSchema, CreateMessageRequestParamsSchema, CreateMessageRequestSchema, CreateMessageResultSchema, CreateMessageResultWithToolsSchema, BooleanSchemaSchema, StringSchemaSchema, NumberSchemaSchema, UntitledSingleSelectEnumSchemaSchema, TitledSingleSelectEnumSchemaSchema, LegacyTitledEnumSchemaSchema, SingleSelectEnumSchemaSchema, UntitledMultiSelectEnumSchemaSchema, TitledMultiSelectEnumSchemaSchema, MultiSelectEnumSchemaSchema, EnumSchemaSchema, PrimitiveSchemaDefinitionSchema, ElicitRequestFormParamsSchema, ElicitRequestURLParamsSchema, ElicitRequestParamsSchema, ElicitRequestSchema, ElicitationCompleteNotificationParamsSchema, ElicitationCompleteNotificationSchema, ElicitResultSchema, ResourceTemplateReferenceSchema, PromptReferenceSchema, CompleteRequestParamsSchema, CompleteRequestSchema, CompleteResultSchema, RootSchema, ListRootsRequestSchema, ListRootsResultSchema, RootsListChangedNotificationSchema, ClientRequestSchema, ClientNotificationSchema, ClientResultSchema, ServerRequestSchema, ServerNotificationSchema, ServerResultSchema, McpError, UrlElicitationRequiredError;
59331
59385
  var init_types7 = __esm(() => {
59332
59386
  init_v4();
@@ -60154,7 +60208,7 @@ var init_types7 = __esm(() => {
60154
60208
  };
60155
60209
  });
60156
60210
 
60157
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
60211
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js
60158
60212
  function isTerminal(status) {
60159
60213
  return status === "completed" || status === "failed" || status === "cancelled";
60160
60214
  }
@@ -60372,7 +60426,7 @@ var init_esm = __esm(() => {
60372
60426
  init_zodToJsonSchema();
60373
60427
  });
60374
60428
 
60375
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
60429
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js
60376
60430
  function getMethodLiteral(schema) {
60377
60431
  const shape = getObjectShape(schema);
60378
60432
  const methodSchema = shape?.method;
@@ -60397,7 +60451,7 @@ var init_zod_json_schema_compat = __esm(() => {
60397
60451
  init_esm();
60398
60452
  });
60399
60453
 
60400
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
60454
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js
60401
60455
  class Protocol {
60402
60456
  constructor(_options) {
60403
60457
  this._options = _options;
@@ -60433,6 +60487,9 @@ class Protocol {
60433
60487
  this.setRequestHandler(GetTaskPayloadRequestSchema, async (request, extra) => {
60434
60488
  const handleTaskResult = async () => {
60435
60489
  const taskId = request.params.taskId;
60490
+ if (!await this._taskStore.getTask(taskId, extra.sessionId)) {
60491
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
60492
+ }
60436
60493
  if (this._taskMessageQueue) {
60437
60494
  let queuedMessage;
60438
60495
  while (queuedMessage = await this._taskMessageQueue.dequeue(taskId, extra.sessionId)) {
@@ -60463,12 +60520,12 @@ class Protocol {
60463
60520
  throw new McpError(ErrorCode.InvalidParams, `Task not found: ${taskId}`);
60464
60521
  }
60465
60522
  if (!isTerminal(task.status)) {
60466
- await this._waitForTaskUpdate(taskId, extra.signal);
60523
+ await this._waitForTaskUpdate(taskId, extra.signal, extra.sessionId);
60467
60524
  return await handleTaskResult();
60468
60525
  }
60469
60526
  if (isTerminal(task.status)) {
60470
60527
  const result = await this._taskStore.getTaskResult(taskId, extra.sessionId);
60471
- this._clearTaskQueue(taskId);
60528
+ this._clearTaskQueue(taskId, extra.sessionId);
60472
60529
  return {
60473
60530
  ...result,
60474
60531
  _meta: {
@@ -60505,7 +60562,7 @@ class Protocol {
60505
60562
  throw new McpError(ErrorCode.InvalidParams, `Cannot cancel task in terminal status: ${task.status}`);
60506
60563
  }
60507
60564
  await this._taskStore.updateTaskStatus(request.params.taskId, "cancelled", "Client cancelled task execution.", extra.sessionId);
60508
- this._clearTaskQueue(request.params.taskId);
60565
+ this._clearTaskQueue(request.params.taskId, extra.sessionId);
60509
60566
  const cancelledTask = await this._taskStore.getTask(request.params.taskId, extra.sessionId);
60510
60567
  if (!cancelledTask) {
60511
60568
  throw new McpError(ErrorCode.InvalidParams, `Task not found after cancellation: ${request.params.taskId}`);
@@ -60628,6 +60685,19 @@ class Protocol {
60628
60685
  const handler = this._requestHandlers.get(request.method) ?? this.fallbackRequestHandler;
60629
60686
  const capturedTransport = this._transport;
60630
60687
  const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY]?.taskId;
60688
+ const sessionId = capturedTransport?.sessionId;
60689
+ const store = this._taskStore;
60690
+ let relatedTaskFound = true;
60691
+ let relatedTaskLookup;
60692
+ if (relatedTaskId && store && this._taskMessageQueue && sessionId !== undefined) {
60693
+ relatedTaskFound = false;
60694
+ relatedTaskLookup = (async () => {
60695
+ if (!await store.getTask(relatedTaskId, sessionId)) {
60696
+ throw new McpError(ErrorCode.InvalidParams, `Task not found: ${relatedTaskId}`);
60697
+ }
60698
+ relatedTaskFound = true;
60699
+ })();
60700
+ }
60631
60701
  if (handler === undefined) {
60632
60702
  const errorResponse = {
60633
60703
  jsonrpc: "2.0",
@@ -60637,7 +60707,10 @@ class Protocol {
60637
60707
  message: "Method not found"
60638
60708
  }
60639
60709
  };
60640
- if (relatedTaskId && this._taskMessageQueue) {
60710
+ if (relatedTaskId && relatedTaskLookup) {
60711
+ const queuedError = { type: "error", message: errorResponse, timestamp: Date.now() };
60712
+ relatedTaskLookup.then(() => this._enqueueTaskMessage(relatedTaskId, queuedError, sessionId), () => capturedTransport?.send(errorResponse)).catch((error48) => this._onerror(new Error(`Failed to send an error response: ${error48}`)));
60713
+ } else if (relatedTaskId && this._taskMessageQueue) {
60641
60714
  this._enqueueTaskMessage(relatedTaskId, {
60642
60715
  type: "error",
60643
60716
  message: errorResponse,
@@ -60688,7 +60761,10 @@ class Protocol {
60688
60761
  closeSSEStream: extra?.closeSSEStream,
60689
60762
  closeStandaloneSSEStream: extra?.closeStandaloneSSEStream
60690
60763
  };
60691
- Promise.resolve().then(() => {
60764
+ (relatedTaskLookup ?? Promise.resolve()).then(() => {
60765
+ if (relatedTaskLookup && abortController.signal.aborted) {
60766
+ throw new McpError(ErrorCode.ConnectionClosed, "Request was cancelled");
60767
+ }
60692
60768
  if (taskCreationParams) {
60693
60769
  this.assertTaskHandlerCapability(request.method);
60694
60770
  }
@@ -60723,7 +60799,7 @@ class Protocol {
60723
60799
  ...error48["data"] !== undefined && { data: error48["data"] }
60724
60800
  }
60725
60801
  };
60726
- if (relatedTaskId && this._taskMessageQueue) {
60802
+ if (relatedTaskId && this._taskMessageQueue && relatedTaskFound) {
60727
60803
  await this._enqueueTaskMessage(relatedTaskId, {
60728
60804
  type: "error",
60729
60805
  message: errorResponse,
@@ -61111,7 +61187,7 @@ class Protocol {
61111
61187
  throw new Error("Cannot enqueue task message: taskStore and taskMessageQueue are not configured");
61112
61188
  }
61113
61189
  const maxQueueSize = this._options?.maxTaskQueueSize;
61114
- await this._taskMessageQueue.enqueue(taskId, message, sessionId, maxQueueSize);
61190
+ await this._taskMessageQueue.enqueue(taskId, message, sessionId ?? this._transport?.sessionId, maxQueueSize);
61115
61191
  }
61116
61192
  async _clearTaskQueue(taskId, sessionId) {
61117
61193
  if (this._taskMessageQueue) {
@@ -61130,10 +61206,10 @@ class Protocol {
61130
61206
  }
61131
61207
  }
61132
61208
  }
61133
- async _waitForTaskUpdate(taskId, signal) {
61209
+ async _waitForTaskUpdate(taskId, signal, sessionId) {
61134
61210
  let interval = this._options?.defaultTaskPollInterval ?? 1000;
61135
61211
  try {
61136
- const task = await this._taskStore?.getTask(taskId);
61212
+ const task = await this._taskStore?.getTask(taskId, sessionId);
61137
61213
  if (task?.pollInterval) {
61138
61214
  interval = task.pollInterval;
61139
61215
  }
@@ -64244,7 +64320,7 @@ var require_data = __commonJS(function(exports, module) {
64244
64320
  };
64245
64321
  });
64246
64322
 
64247
- // ../../node_modules/.bun/fast-uri@3.1.7/node_modules/fast-uri/lib/utils.js
64323
+ // ../../node_modules/.bun/fast-uri@3.1.8/node_modules/fast-uri/lib/utils.js
64248
64324
  var require_utils = __commonJS(function(exports, module) {
64249
64325
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
64250
64326
  var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
@@ -64761,7 +64837,7 @@ var require_utils = __commonJS(function(exports, module) {
64761
64837
  };
64762
64838
  });
64763
64839
 
64764
- // ../../node_modules/.bun/fast-uri@3.1.7/node_modules/fast-uri/lib/schemes.js
64840
+ // ../../node_modules/.bun/fast-uri@3.1.8/node_modules/fast-uri/lib/schemes.js
64765
64841
  var require_schemes = __commonJS(function(exports, module) {
64766
64842
  var { isUUID } = require_utils();
64767
64843
  var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
@@ -64936,7 +65012,7 @@ var require_schemes = __commonJS(function(exports, module) {
64936
65012
  };
64937
65013
  });
64938
65014
 
64939
- // ../../node_modules/.bun/fast-uri@3.1.7/node_modules/fast-uri/index.js
65015
+ // ../../node_modules/.bun/fast-uri@3.1.8/node_modules/fast-uri/index.js
64940
65016
  var require_fast_uri = __commonJS(function(exports, module) {
64941
65017
  var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
64942
65018
  var { SCHEMES, getSchemeHandler } = require_schemes();
@@ -65266,13 +65342,14 @@ var require_fast_uri = __commonJS(function(exports, module) {
65266
65342
  if (!malformedIPLiteral) {
65267
65343
  malformedHost = canonicalizeHost(parsed, options, schemeHandler, isIP);
65268
65344
  }
65269
- if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
65270
- if (uri.indexOf("%") !== -1) {
65271
- if (parsed.host !== undefined && !malformedIPLiteral) {
65272
- const host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
65273
- parsed.host = reescapeHostDelimiters(host, isIP);
65274
- }
65345
+ if (uri.indexOf("%") !== -1 && parsed.host !== undefined && !malformedIPLiteral) {
65346
+ let host = isIP ? parsed.host : normalizePercentEncoding(parsed.host, true);
65347
+ if (!isIP) {
65348
+ host = normalizePercentEncoding(host.toLowerCase());
65275
65349
  }
65350
+ parsed.host = reescapeHostDelimiters(host, isIP);
65351
+ }
65352
+ if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
65276
65353
  if (parsed.path) {
65277
65354
  parsed.path = normalizePathEncoding(parsed.path);
65278
65355
  }
@@ -68128,7 +68205,7 @@ var require_dist = __commonJS(function(exports, module) {
68128
68205
  exports.default = formatsPlugin;
68129
68206
  });
68130
68207
 
68131
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
68208
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js
68132
68209
  function createDefaultAjvInstance() {
68133
68210
  const ajv = new import_ajv.default({
68134
68211
  strict: false,
@@ -68171,7 +68248,7 @@ var init_ajv_provider = __esm(() => {
68171
68248
  import_ajv_formats = __toESM(require_dist(), 1);
68172
68249
  });
68173
68250
 
68174
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/client.js
68251
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/client.js
68175
68252
  class ExperimentalClientTasks {
68176
68253
  constructor(_client) {
68177
68254
  this._client = _client;
@@ -68240,7 +68317,7 @@ var init_client2 = __esm(() => {
68240
68317
  init_types7();
68241
68318
  });
68242
68319
 
68243
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
68320
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js
68244
68321
  function assertToolsCallTaskCapability(requests, method, entityName) {
68245
68322
  if (!requests) {
68246
68323
  throw new Error(`${entityName} does not support task creation (required for ${method})`);
@@ -68275,7 +68352,7 @@ function assertClientRequestTaskCapability(requests, method, entityName) {
68275
68352
  }
68276
68353
  }
68277
68354
 
68278
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.js
68355
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/client/index.js
68279
68356
  function applyElicitationDefaults(schema, data) {
68280
68357
  if (!schema || data === null || typeof data !== "object")
68281
68358
  return;
@@ -69196,7 +69273,7 @@ var require_cross_spawn = __commonJS(function(exports, module) {
69196
69273
  module.exports._enoent = enoent;
69197
69274
  });
69198
69275
 
69199
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
69276
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js
69200
69277
  class ReadBuffer {
69201
69278
  constructor(options) {
69202
69279
  this._maxBufferSize = options?.maxBufferSize ?? STDIO_DEFAULT_MAX_BUFFER_SIZE;
@@ -69239,7 +69316,7 @@ var init_stdio = __esm(() => {
69239
69316
  STDIO_DEFAULT_MAX_BUFFER_SIZE = 10 * 1024 * 1024;
69240
69317
  });
69241
69318
 
69242
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.js
69319
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/client/stdio.js
69243
69320
  import process4 from "process";
69244
69321
  import { PassThrough } from "stream";
69245
69322
  function getDefaultEnvironment() {
@@ -89641,7 +89718,7 @@ var init_tool_calls = __esm(() => {
89641
89718
  TOO_MANY_TEXT = `Too many concurrent tool calls: at most ${MAX_CONCURRENT_TOOL_CALLS} run at once.`;
89642
89719
  });
89643
89720
 
89644
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
89721
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js
89645
89722
  class ExperimentalServerTasks {
89646
89723
  constructor(_server) {
89647
89724
  this._server = _server;
@@ -89722,7 +89799,7 @@ var init_server = __esm(() => {
89722
89799
  init_types7();
89723
89800
  });
89724
89801
 
89725
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
89802
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js
89726
89803
  var Server;
89727
89804
  var init_server2 = __esm(() => {
89728
89805
  init_protocol();
@@ -91455,7 +91532,7 @@ var require_content_type = __commonJS(function(exports) {
91455
91532
  }
91456
91533
  });
91457
91534
 
91458
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.js
91535
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.js
91459
91536
  function mediaTypeEssence(header) {
91460
91537
  if (!header) {
91461
91538
  return;
@@ -91481,7 +91558,53 @@ var init_mediaType = __esm(() => {
91481
91558
  import_content_type = __toESM(require_content_type(), 1);
91482
91559
  });
91483
91560
 
91484
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.js
91561
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/server/requestBody.js
91562
+ function requestBodyTooLargeMessage(maxBytes) {
91563
+ return `Payload Too Large: Request body must not exceed ${maxBytes} bytes`;
91564
+ }
91565
+ function resolveMaxRequestBodySize(value) {
91566
+ if (value === undefined) {
91567
+ return DEFAULT_MAX_REQUEST_BODY_SIZE;
91568
+ }
91569
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) {
91570
+ throw new RangeError(`maxRequestBodySize must be a positive number of bytes, got ${String(value)}`);
91571
+ }
91572
+ return value;
91573
+ }
91574
+ async function readRequestBody(request, maxBytes = DEFAULT_MAX_REQUEST_BODY_SIZE) {
91575
+ if (Number(request.headers.get("content-length")) > maxBytes) {
91576
+ return { tooLarge: true };
91577
+ }
91578
+ if (request.body === null) {
91579
+ return { tooLarge: false, text: "" };
91580
+ }
91581
+ const reader = request.body.getReader();
91582
+ const decoder = new TextDecoder;
91583
+ let received = 0;
91584
+ let text = "";
91585
+ try {
91586
+ for (;; ) {
91587
+ const { done, value } = await reader.read();
91588
+ if (done) {
91589
+ break;
91590
+ }
91591
+ received += value.byteLength;
91592
+ if (received > maxBytes) {
91593
+ return { tooLarge: true };
91594
+ }
91595
+ text += decoder.decode(value, { stream: true });
91596
+ }
91597
+ } finally {
91598
+ reader.releaseLock();
91599
+ }
91600
+ return { tooLarge: false, text: text + decoder.decode() };
91601
+ }
91602
+ var DEFAULT_MAX_REQUEST_BODY_SIZE, MAX_BATCH_SIZE = 100;
91603
+ var init_requestBody = __esm(() => {
91604
+ DEFAULT_MAX_REQUEST_BODY_SIZE = 4 * 1024 * 1024;
91605
+ });
91606
+
91607
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.js
91485
91608
  function armSseKeepAlive(intervalMs, onTick) {
91486
91609
  if (!Number.isFinite(intervalMs) || intervalMs < 1) {
91487
91610
  return;
@@ -91495,7 +91618,7 @@ var init_sseKeepAlive = __esm(() => {
91495
91618
  MAX_TIMER_DELAY_MS = 2 ** 31 - 1;
91496
91619
  });
91497
91620
 
91498
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.js
91621
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.js
91499
91622
  class WebStandardStreamableHTTPServerTransport {
91500
91623
  constructor(options = {}) {
91501
91624
  this._started = false;
@@ -91518,6 +91641,7 @@ class WebStandardStreamableHTTPServerTransport {
91518
91641
  this._enableDnsRebindingProtection = options.enableDnsRebindingProtection ?? false;
91519
91642
  this._retryInterval = options.retryInterval;
91520
91643
  this._keepAliveMs = options.keepAliveMs ?? DEFAULT_SSE_KEEP_ALIVE_MS;
91644
+ this._maxRequestBodySize = resolveMaxRequestBodySize(options.maxRequestBodySize);
91521
91645
  }
91522
91646
  startKeepAlive(controller, encoder) {
91523
91647
  if (this._closed)
@@ -91834,12 +91958,22 @@ data:
91834
91958
  rawMessage = options.parsedBody;
91835
91959
  } else {
91836
91960
  try {
91837
- rawMessage = await req.json();
91961
+ const body = await readRequestBody(req, this._maxRequestBodySize);
91962
+ if (body.tooLarge) {
91963
+ const message = requestBodyTooLargeMessage(this._maxRequestBodySize);
91964
+ this.onerror?.(new Error(message));
91965
+ return this.createJsonErrorResponse(413, -32000, message);
91966
+ }
91967
+ rawMessage = JSON.parse(body.text);
91838
91968
  } catch {
91839
91969
  this.onerror?.(new Error("Parse error: Invalid JSON"));
91840
91970
  return this.createJsonErrorResponse(400, -32700, "Parse error: Invalid JSON");
91841
91971
  }
91842
91972
  }
91973
+ if (Array.isArray(rawMessage) && rawMessage.length > MAX_BATCH_SIZE) {
91974
+ this.onerror?.(new Error(`Invalid Request: Batch must not exceed ${MAX_BATCH_SIZE} messages`));
91975
+ return this.createJsonErrorResponse(400, -32600, `Invalid Request: Batch must not exceed ${MAX_BATCH_SIZE} messages`);
91976
+ }
91843
91977
  let messages;
91844
91978
  try {
91845
91979
  if (Array.isArray(rawMessage)) {
@@ -92153,11 +92287,12 @@ data:
92153
92287
  }
92154
92288
  var init_webStandardStreamableHttp = __esm(() => {
92155
92289
  init_mediaType();
92290
+ init_requestBody();
92156
92291
  init_sseKeepAlive();
92157
92292
  init_types7();
92158
92293
  });
92159
92294
 
92160
- // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.30.0/node_modules/@modelcontextprotocol/sdk/dist/esm/server/streamableHttp.js
92295
+ // ../../node_modules/.bun/@modelcontextprotocol+sdk@1.32.1/node_modules/@modelcontextprotocol/sdk/dist/esm/server/streamableHttp.js
92161
92296
  class StreamableHTTPServerTransport {
92162
92297
  constructor(options = {}) {
92163
92298
  this._requestContext = new WeakMap;
@@ -104254,7 +104389,8 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs, overrides)
104254
104389
  success: cycleResult.exitReason === "resolved",
104255
104390
  iterationCount: priorRectifyIterations + cycleResult.iterations.length,
104256
104391
  exitReason: reportedExitReason,
104257
- finalFindingsCount: cycleResult.finalFindings.length
104392
+ finalFindingsCount: cycleResult.finalFindings.length,
104393
+ ...provisionalMarker(cycleResult.exitReason, cycleResult.finalFindings.length)
104258
104394
  };
104259
104395
  const rectLogger = getSafeLogger2();
104260
104396
  const rectSummary = {
@@ -104301,6 +104437,9 @@ async function runRectification(ctx, state, phaseCosts, phaseOutputs, overrides)
104301
104437
  }
104302
104438
  return repoScoped;
104303
104439
  }
104440
+ function provisionalMarker(exitReason, finalFindingsCount) {
104441
+ return exitReason === "validate-short-circuit" && finalFindingsCount === 0 ? { provisional: true } : {};
104442
+ }
104304
104443
  var init_rectification = __esm(() => {
104305
104444
  init_findings();
104306
104445
  init_logger2();
@@ -104500,7 +104639,7 @@ async function runPostRectificationResume(plan, tracking, preRectGateFailureKeys
104500
104639
  phase: name,
104501
104640
  source: "post-rectification-resume"
104502
104641
  });
104503
- break;
104642
+ return false;
104504
104643
  }
104505
104644
  if (phasePassed(name, phaseOutputs[name], ctx.storyId))
104506
104645
  continue;
@@ -104511,8 +104650,19 @@ async function runPostRectificationResume(plan, tracking, preRectGateFailureKeys
104511
104650
  source: "post-rectification-resume",
104512
104651
  secondRectifyUsed: resumeRectifyUsed
104513
104652
  });
104514
- break;
104653
+ return false;
104515
104654
  }
104655
+ return true;
104656
+ }
104657
+ function settleProvisionalRectification(phaseOutputs, storyId) {
104658
+ const rect = phaseOutputs.rectification;
104659
+ if (rect?.provisional !== true)
104660
+ return;
104661
+ const othersPassed = Object.entries(phaseOutputs).every(([name, output]) => name === "rectification" || phasePassed(name, output, storyId));
104662
+ if (!othersPassed)
104663
+ return;
104664
+ const { provisional: _settled, ...rest } = rect;
104665
+ phaseOutputs.rectification = { ...rest, success: true, settledBy: "resume" };
104516
104666
  }
104517
104667
  async function runMechanicalOnlyResume(plan, tracking, rectResult) {
104518
104668
  const mechanicalOnly = !!rectResult.unfixedFindings?.length && rectResult.unfixedFindings.every((f) => f.source === "lint" || f.source === "typecheck");
@@ -104704,6 +104854,7 @@ function buildStoryOrchestratorResult(plan, tracking, inputs) {
104704
104854
  });
104705
104855
  const totalCostUsd = Object.values(phaseCosts).reduce((sum, cost) => sum + cost, 0);
104706
104856
  const durationMs = Date.now() - startedAt;
104857
+ const failedPhases = collectFailedPhases(ctx, phaseOutputs, { gateName, verifierPassedSsot, failedPhaseEntries });
104707
104858
  logStoryOrchestratorVerdict(ctx, {
104708
104859
  success: success2,
104709
104860
  phaseOutputs,
@@ -104713,9 +104864,7 @@ function buildStoryOrchestratorResult(plan, tracking, inputs) {
104713
104864
  missingRequiredReviewPhases,
104714
104865
  upstreamShortCircuited,
104715
104866
  shortCircuitPhase,
104716
- failedPhaseEntries,
104717
- gateName,
104718
- verifierPassedSsot
104867
+ failedPhases
104719
104868
  });
104720
104869
  return {
104721
104870
  success: success2,
@@ -104725,9 +104874,20 @@ function buildStoryOrchestratorResult(plan, tracking, inputs) {
104725
104874
  phaseOutputs,
104726
104875
  ...rectResult,
104727
104876
  gateRegressedDuringRect,
104728
- missingRequiredReviewPhases: missingRequiredReviewPhases.length > 0 ? missingRequiredReviewPhases : undefined
104877
+ missingRequiredReviewPhases: missingRequiredReviewPhases.length > 0 ? missingRequiredReviewPhases : undefined,
104878
+ ...failedPhases.length > 0 && { failedPhases }
104729
104879
  };
104730
104880
  }
104881
+ function collectFailedPhases(ctx, phaseOutputs, opts) {
104882
+ return [
104883
+ ...Object.entries(phaseOutputs).filter(([name, output]) => {
104884
+ if (opts.verifierPassedSsot && name === opts.gateName)
104885
+ return false;
104886
+ return !phasePassed(name, output, ctx.storyId);
104887
+ }).map(([name]) => name),
104888
+ ...opts.failedPhaseEntries.map((name) => `${name} (never ran)`)
104889
+ ];
104890
+ }
104731
104891
  function logStoryOrchestratorVerdict(ctx, inputs) {
104732
104892
  const {
104733
104893
  success: success2,
@@ -104738,19 +104898,9 @@ function logStoryOrchestratorVerdict(ctx, inputs) {
104738
104898
  missingRequiredReviewPhases,
104739
104899
  upstreamShortCircuited,
104740
104900
  shortCircuitPhase,
104741
- failedPhaseEntries,
104742
- gateName,
104743
- verifierPassedSsot
104901
+ failedPhases
104744
104902
  } = inputs;
104745
104903
  const logger = getSafeLogger2();
104746
- const failedPhases = [
104747
- ...Object.entries(phaseOutputs).filter(([name, output]) => {
104748
- if (verifierPassedSsot && name === gateName)
104749
- return false;
104750
- return !phasePassed(name, output, ctx.storyId);
104751
- }).map(([name]) => name),
104752
- ...failedPhaseEntries.map((name) => `${name} (never ran)`)
104753
- ];
104754
104904
  const summary = {
104755
104905
  storyId: ctx.storyId,
104756
104906
  success: success2,
@@ -104821,13 +104971,13 @@ class ExecutionPlan {
104821
104971
  isThreeSession: this.isThreeSession
104822
104972
  });
104823
104973
  const resumeLoopEligible = !!this.state.rectification && !rectResult.terminalReviewRequired && (!rectResult.rectificationExhausted || !!rectResult.liteScopeIncomplete);
104824
- if (resumeLoopEligible) {
104825
- await runPostRectificationResume(plan, tracking, preRectGateFailureKeys);
104826
- }
104974
+ const resumeCompleted = resumeLoopEligible && await runPostRectificationResume(plan, tracking, preRectGateFailureKeys);
104827
104975
  if (this.state.rectification && rectResult.rectificationExhausted) {
104828
104976
  await runMechanicalOnlyResume(plan, tracking, rectResult);
104829
104977
  }
104830
104978
  await maybeRunNonBlockingFix(plan, tracking, rectResult, { gateName, preRectGateFailureKeys });
104979
+ if (resumeCompleted)
104980
+ settleProvisionalRectification(tracking.phaseOutputs, this.ctx.storyId);
104831
104981
  return buildStoryOrchestratorResult(plan, tracking, {
104832
104982
  gateName,
104833
104983
  preRectGateFailureKeys,
@@ -109574,7 +109724,7 @@ function routeTddFailure(failureCategory, isLiteMode, ctx, reviewReason, failure
109574
109724
  };
109575
109725
  const pauseFallback = {
109576
109726
  action: "pause",
109577
- reason: reviewReason || "Three-session TDD requires review"
109727
+ reason: reviewReason || TDD_REVIEW_PAUSE_REASON
109578
109728
  };
109579
109729
  if (failureCategory === undefined) {
109580
109730
  return pauseFallback;
@@ -109606,6 +109756,7 @@ function routeTddFailure(failureCategory, isLiteMode, ctx, reviewReason, failure
109606
109756
  return pauseFallback;
109607
109757
  }
109608
109758
  }
109759
+ var TDD_REVIEW_PAUSE_REASON = "Three-session TDD requires review";
109609
109760
  var init_execution_helpers = __esm(() => {
109610
109761
  init_errors4();
109611
109762
  });
@@ -121946,7 +122097,13 @@ Category: ${failureCategory ?? "unknown"}`,
121946
122097
  });
121947
122098
  return { action: "pause", reason: `Human review needed: ${failureCategory ?? "unknown"}` };
121948
122099
  }
121949
- return routeTddFailure(failureCategory, isLiteMode, ctx);
122100
+ return routeTddFailure(failureCategory, isLiteMode, ctx, uncategorisedPauseReason(frame));
122101
+ }
122102
+ function uncategorisedPauseReason(frame) {
122103
+ const failed3 = frame.planResult.failedPhases;
122104
+ if (frame.inspection.failureCategory !== undefined || !failed3?.length)
122105
+ return;
122106
+ return `${TDD_REVIEW_PAUSE_REASON} (failed phases: ${failed3.join(", ")})`;
121950
122107
  }
121951
122108
  async function failOnMergeConflict(frame) {
121952
122109
  const { ctx, inspection, deps } = frame;
@@ -121965,7 +122122,7 @@ async function failOnMergeConflict(frame) {
121965
122122
  }
121966
122123
  return null;
121967
122124
  }
121968
- function collectFailedPhases(planResult) {
122125
+ function collectFailedPhases2(planResult) {
121969
122126
  const failedPhases = {};
121970
122127
  for (const [name, output] of Object.entries(planResult.phaseOutputs)) {
121971
122128
  if (!output || typeof output !== "object")
@@ -121997,7 +122154,7 @@ async function escalateFailedSession(frame) {
121997
122154
  const { ctx, planResult, inspection, deps } = frame;
121998
122155
  const logger = getLogger2();
121999
122156
  const { agentResult, failureCategory } = inspection;
122000
- const failedPhases = collectFailedPhases(planResult);
122157
+ const failedPhases = collectFailedPhases2(planResult);
122001
122158
  const stderrTail = (agentResult.stderr ?? "").slice(-500);
122002
122159
  const outputTail = (agentResult.output ?? "").slice(-500);
122003
122160
  logger.error("execution", "Agent session failed", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nathapp/nax",
3
- "version": "0.85.0",
3
+ "version": "0.85.1",
4
4
  "description": "AI Coding Agent Orchestrator — loops until done",
5
5
  "type": "module",
6
6
  "bin": {
@@ -86,8 +86,8 @@
86
86
  "dependencies": {
87
87
  "@agentclientprotocol/sdk": "~1.7.0",
88
88
  "@anthropic-ai/sandbox-runtime": "0.0.77",
89
- "@modelcontextprotocol/sdk": "^1.30.0",
90
- "@nathapp/nax-ai": "0.85.0",
89
+ "@modelcontextprotocol/sdk": "^1.32.1",
90
+ "@nathapp/nax-ai": "0.85.1",
91
91
  "chalk": "^5.6.2",
92
92
  "commander": "^13.1.0",
93
93
  "ink": "^6.7.0",