@atlasharness/atlascode 0.1.51 → 0.1.52

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/cli.js +277 -42
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -27939,7 +27939,14 @@ This tool's schema was not sent to the API — it was not in the discovered-tool
27939
27939
  }
27940
27940
 
27941
27941
  // src/engine/pipeline/toolExecution.ts
27942
- function mergeHookPermission(hookBehavior, gate) {
27942
+ function mergeHookPermission(hookBehavior, gate, hookReason) {
27943
+ if (hookBehavior === "defer") {
27944
+ return {
27945
+ allowed: false,
27946
+ deferred: true,
27947
+ reason: hookReason ?? "deferred by hook"
27948
+ };
27949
+ }
27943
27950
  if (hookBehavior === "deny") {
27944
27951
  return { allowed: false, reason: "blocked by hook" };
27945
27952
  }
@@ -28022,7 +28029,10 @@ async function executeToolUse(tu, assistantMsg, deps) {
28022
28029
  toolUseId: tu.id,
28023
28030
  assistantMessage: assistantMsg
28024
28031
  }) : { allowed: true };
28025
- const verdict = mergeHookPermission(preOutcome?.hookBehavior, gateVerdict);
28032
+ const verdict = mergeHookPermission(preOutcome?.hookBehavior, gateVerdict, preOutcome?.hookPermissionDecisionReason);
28033
+ if (verdict.deferred) {
28034
+ return { deferred: true, deferReason: verdict.reason, isError: false };
28035
+ }
28026
28036
  if (!verdict.allowed) {
28027
28037
  const content = verdict.ask ? `<tool_use_error>permission confirmation required (prompt 面残留守): ${verdict.reason ?? tu.name}</tool_use_error>` : `<tool_use_error>permission denied: ${verdict.reason ?? tu.name}</tool_use_error>`;
28028
28038
  return {
@@ -28087,8 +28097,13 @@ async function runToolBatch(toolUses, assistantMsg, deps) {
28087
28097
  name: tu.name,
28088
28098
  block: r.block,
28089
28099
  isError: r.isError,
28090
- toolUseResult: r.toolUseResult
28100
+ toolUseResult: r.toolUseResult,
28101
+ deferred: r.deferred,
28102
+ deferReason: r.deferReason
28091
28103
  });
28104
+ if (r.deferred) {
28105
+ return outcomes;
28106
+ }
28092
28107
  }
28093
28108
  }
28094
28109
  return outcomes;
@@ -28371,6 +28386,14 @@ function interpretHookOutput(p) {
28371
28386
  };
28372
28387
  } else if (specific?.permissionDecision === "ask") {
28373
28388
  result.permissionBehavior = "ask";
28389
+ if (specific.permissionDecisionReason) {
28390
+ result.permissionDecisionReason = specific.permissionDecisionReason;
28391
+ }
28392
+ } else if (specific?.permissionDecision === "defer") {
28393
+ result.permissionBehavior = "defer";
28394
+ if (specific.permissionDecisionReason) {
28395
+ result.permissionDecisionReason = specific.permissionDecisionReason;
28396
+ }
28374
28397
  }
28375
28398
  if (specific?.additionalContext)
28376
28399
  result.additionalContext = specific.additionalContext;
@@ -28410,6 +28433,7 @@ ${r.additionalContext}` : r.additionalContext;
28410
28433
  if (r.permissionBehavior) {
28411
28434
  if (!acc.permissionBehavior || PERMISSION_RANK[r.permissionBehavior] > PERMISSION_RANK[acc.permissionBehavior]) {
28412
28435
  acc.permissionBehavior = r.permissionBehavior;
28436
+ acc.permissionDecisionReason = r.permissionDecisionReason;
28413
28437
  }
28414
28438
  }
28415
28439
  }
@@ -28483,6 +28507,7 @@ var init_runHooks = __esm(() => {
28483
28507
  init_shouldSkipHookDueToTrust();
28484
28508
  HOOK_EXECUTION_TIMEOUT_MS = 10 * 60 * 1000;
28485
28509
  PERMISSION_RANK = {
28510
+ defer: 4,
28486
28511
  deny: 3,
28487
28512
  ask: 2,
28488
28513
  allow: 1,
@@ -81436,6 +81461,19 @@ var init_reactiveCompactError = __esm(() => {
81436
81461
 
81437
81462
  // src/engine/query/loop.ts
81438
81463
  import { randomUUID as randomUUID18 } from "crypto";
81464
+ function makeDeferredToolUseMarker(payload) {
81465
+ return {
81466
+ type: "system",
81467
+ subtype: "deferred_tool_use",
81468
+ role: "system",
81469
+ tool_use_id: payload.toolUseId,
81470
+ tool_name: payload.toolName,
81471
+ defer_reason: payload.deferReason,
81472
+ isMeta: false,
81473
+ uuid: randomUUID18(),
81474
+ timestamp: new Date().toISOString()
81475
+ };
81476
+ }
81439
81477
  async function queryOneRound(deps, tools, messages) {
81440
81478
  const chatArgs = {
81441
81479
  messages,
@@ -81495,13 +81533,20 @@ async function queryOneRound(deps, tools, messages) {
81495
81533
  hooks: deps.hooks?.toolHooks,
81496
81534
  toolContext: deps.toolContext
81497
81535
  });
81498
- const toolResults = outcomes.map((o) => ({
81536
+ const deferredOutcome = outcomes.find((o) => o.deferred);
81537
+ const deferredPayload = deferredOutcome ? {
81538
+ toolUseId: deferredOutcome.toolUseId,
81539
+ toolName: deferredOutcome.name,
81540
+ deferReason: deferredOutcome.deferReason
81541
+ } : undefined;
81542
+ const marker = deferredPayload ? makeDeferredToolUseMarker(deferredPayload) : undefined;
81543
+ const toolResults = outcomes.filter((o) => !o.deferred).map((o) => ({
81499
81544
  toolUseId: o.toolUseId,
81500
81545
  name: o.name,
81501
81546
  block: o.block
81502
81547
  }));
81503
81548
  const now = new Date().toISOString();
81504
- const resultMessages = outcomes.map((o) => ({
81549
+ const resultMessages = outcomes.filter((o) => !o.deferred).map((o) => ({
81505
81550
  type: "user",
81506
81551
  role: "user",
81507
81552
  uuid: randomUUID18(),
@@ -81509,15 +81554,17 @@ async function queryOneRound(deps, tools, messages) {
81509
81554
  message: { role: "user", content: [o.block] },
81510
81555
  toolUseResult: o.toolUseResult
81511
81556
  }));
81557
+ const roundMessages = marker ? [...messages, assistantMsg, ...resultMessages, marker] : [...messages, assistantMsg, ...resultMessages];
81512
81558
  if (deps.transcript) {
81513
- deps.transcript.record([...messages, assistantMsg, ...resultMessages]);
81559
+ deps.transcript.record(roundMessages);
81514
81560
  }
81515
81561
  return {
81516
- messages: [...messages, assistantMsg, ...resultMessages],
81562
+ messages: roundMessages,
81517
81563
  toolResults,
81518
81564
  assistantContent,
81519
81565
  stopReason: resp.message.stop_reason,
81520
- empty
81566
+ empty,
81567
+ deferred: deferredPayload
81521
81568
  };
81522
81569
  }
81523
81570
  async function queryAgentLoop(deps, args) {
@@ -81532,6 +81579,7 @@ async function queryAgentLoop(deps, args) {
81532
81579
  let turns = 0;
81533
81580
  let terminated = false;
81534
81581
  let lastRound;
81582
+ let deferredToolUse;
81535
81583
  if (deps.transcript) {
81536
81584
  await deps.transcript.record(messages);
81537
81585
  }
@@ -81606,6 +81654,10 @@ async function queryAgentLoop(deps, args) {
81606
81654
  });
81607
81655
  break;
81608
81656
  }
81657
+ if (lastRound.deferred) {
81658
+ deferredToolUse = lastRound.deferred;
81659
+ break;
81660
+ }
81609
81661
  if (lastRound.toolResults.length === 0) {
81610
81662
  const stop = deps.hooks?.stopHooks;
81611
81663
  const preventStop = stop ? (await stop(deps.signal)).preventContinuation : false;
@@ -81625,7 +81677,8 @@ async function queryAgentLoop(deps, args) {
81625
81677
  terminated,
81626
81678
  tracking,
81627
81679
  lastRound,
81628
- emptyTerminated
81680
+ emptyTerminated,
81681
+ deferred: deferredToolUse
81629
81682
  };
81630
81683
  deps.emit?.({ type: "loop_end", result });
81631
81684
  return result;
@@ -81683,6 +81736,7 @@ function createToolHooks(opts = {}) {
81683
81736
  blockingError: r.blockingError?.blockingError,
81684
81737
  updatedInput: r.updatedInput,
81685
81738
  hookBehavior: r.permissionBehavior,
81739
+ hookPermissionDecisionReason: r.permissionDecisionReason,
81686
81740
  preventContinuation: r.preventContinuation,
81687
81741
  stopReason: r.stopReason
81688
81742
  };
@@ -85526,6 +85580,98 @@ function extractFinalAssistantText(loopResult) {
85526
85580
  }
85527
85581
  return "";
85528
85582
  }
85583
+ function findDeferredToolUseState(conversation) {
85584
+ let markerIdx = -1;
85585
+ let marker;
85586
+ for (let i = conversation.length - 1;i >= 0; i--) {
85587
+ const m = conversation[i];
85588
+ if (m.type === "system" && m.subtype === "deferred_tool_use") {
85589
+ markerIdx = i;
85590
+ marker = m;
85591
+ break;
85592
+ }
85593
+ }
85594
+ if (!marker)
85595
+ return;
85596
+ const toolUseId = marker.tool_use_id;
85597
+ const toolName = marker.tool_name;
85598
+ if (typeof toolUseId !== "string" || typeof toolName !== "string") {
85599
+ return;
85600
+ }
85601
+ const deferReason = typeof marker.defer_reason === "string" ? marker.defer_reason : undefined;
85602
+ const resolved = conversation.slice(markerIdx + 1).some((m) => {
85603
+ const content = m.message?.content;
85604
+ return Array.isArray(content) && content.some((b) => b?.type === "tool_result" && b?.tool_use_id === toolUseId);
85605
+ });
85606
+ if (resolved)
85607
+ return;
85608
+ return { toolUseId, toolName, deferReason };
85609
+ }
85610
+ async function reEvaluateDeferredToolCalls(params) {
85611
+ const { conversation, toolUseId, tools, toolHooks, checkPermission } = params;
85612
+ let tu;
85613
+ let assistantMsg;
85614
+ for (let i = conversation.length - 1;i >= 0; i--) {
85615
+ const m = conversation[i];
85616
+ if (m.role !== "assistant")
85617
+ continue;
85618
+ const content = m.message?.content;
85619
+ if (!Array.isArray(content))
85620
+ continue;
85621
+ const block = content.find((b) => b?.type === "tool_use" && b?.id === toolUseId);
85622
+ if (block) {
85623
+ tu = block;
85624
+ assistantMsg = m;
85625
+ break;
85626
+ }
85627
+ }
85628
+ if (!tu) {
85629
+ const marker = conversation.find((m) => m.type === "system" && m.subtype === "deferred_tool_use" && m.tool_use_id === toolUseId);
85630
+ tu = {
85631
+ type: "tool_use",
85632
+ id: toolUseId,
85633
+ name: typeof marker?.tool_name === "string" ? marker?.tool_name : "unknown",
85634
+ input: {}
85635
+ };
85636
+ }
85637
+ if (!assistantMsg) {
85638
+ assistantMsg = {
85639
+ type: "assistant",
85640
+ role: "assistant",
85641
+ uuid: randomUUID21(),
85642
+ timestamp: new Date().toISOString(),
85643
+ message: { role: "assistant", content: [tu] }
85644
+ };
85645
+ }
85646
+ const outcome = await executeToolUse(tu, assistantMsg, {
85647
+ tools,
85648
+ hooks: toolHooks,
85649
+ checkPermission
85650
+ });
85651
+ if (outcome.deferred) {
85652
+ const payload = {
85653
+ toolUseId,
85654
+ toolName: tu.name,
85655
+ deferReason: outcome.deferReason
85656
+ };
85657
+ const marker = makeDeferredToolUseMarker(payload);
85658
+ return {
85659
+ suspended: true,
85660
+ deferred: payload,
85661
+ messages: [...conversation, marker]
85662
+ };
85663
+ }
85664
+ const now = new Date().toISOString();
85665
+ const resultMsg = {
85666
+ type: "user",
85667
+ role: "user",
85668
+ uuid: randomUUID21(),
85669
+ timestamp: now,
85670
+ message: { role: "user", content: [outcome.block] },
85671
+ toolUseResult: outcome.toolUseResult
85672
+ };
85673
+ return { suspended: false, messages: [...conversation, resultMsg] };
85674
+ }
85529
85675
  function resolveHeadlessTpc(tpc) {
85530
85676
  if (tpc)
85531
85677
  return tpc;
@@ -85751,6 +85897,34 @@ async function runHeadless(inputPrompt, options) {
85751
85897
  await writeMessage(resultMessage);
85752
85898
  return resultMessage;
85753
85899
  };
85900
+ const writeDeferredSuspendResult = async (p, numTurns, conversationMessages) => {
85901
+ await drainToOutput();
85902
+ for (const m of conversationMessages) {
85903
+ if (m.role !== "assistant")
85904
+ continue;
85905
+ const content = m.message?.content;
85906
+ if (!content || content.length === 0)
85907
+ continue;
85908
+ await writeMessage({
85909
+ type: "assistant",
85910
+ session_id: sessionId,
85911
+ message: { role: "assistant", content },
85912
+ uuid: randomUUID21()
85913
+ });
85914
+ }
85915
+ await drainToOutput();
85916
+ const resultMessage = {
85917
+ type: "result",
85918
+ subtype: "deferred",
85919
+ session_id: sessionId,
85920
+ is_error: false,
85921
+ num_turns: numTurns,
85922
+ result: `Deferred tool call ${p.toolName} (${p.toolUseId}) by PreToolUse hook` + (p.deferReason ? `: ${p.deferReason}` : "") + `. Session suspended — resume with: atlas -p --resume ${sessionId}`,
85923
+ uuid: randomUUID21()
85924
+ };
85925
+ await writeMessage(resultMessage);
85926
+ return resultMessage;
85927
+ };
85754
85928
  const queuedUserTurns = [];
85755
85929
  let stdinClosed = false;
85756
85930
  const drainPump = (async () => {
@@ -85783,38 +85957,90 @@ async function runHeadless(inputPrompt, options) {
85783
85957
  });
85784
85958
  cronScheduler.start();
85785
85959
  try {
85786
- let loopResult = await runTurn(conversation);
85787
- conversation = loopResult.messages;
85788
- const firstResult = await writeTurnOutputs(loopResult);
85789
- switch (options.outputFormat) {
85790
- case "json": {
85791
- if (options.verbose) {
85792
- process.stdout.write(JSON.stringify(conversation) + `
85793
- `);
85794
- } else {
85795
- process.stdout.write(JSON.stringify(firstResult) + `
85796
- `);
85797
- }
85798
- break;
85960
+ const deferredState = findDeferredToolUseState(conversation);
85961
+ let reSuspended = false;
85962
+ if (deferredState) {
85963
+ const re = await reEvaluateDeferredToolCalls({
85964
+ conversation,
85965
+ toolUseId: deferredState.toolUseId,
85966
+ tools,
85967
+ toolHooks: loopDeps.hooks?.toolHooks,
85968
+ checkPermission
85969
+ });
85970
+ conversation = re.messages;
85971
+ if (loopDeps.transcript) {
85972
+ loopDeps.transcript.record(conversation);
85799
85973
  }
85800
- case "stream-json":
85801
- break;
85802
- default: {
85803
- const result = firstResult;
85804
- switch (result.subtype) {
85805
- case "success":
85806
- process.stdout.write(result.result?.endsWith(`
85807
- `) ? result.result : (result.result ?? "") + `
85974
+ if (re.suspended && re.deferred) {
85975
+ await writeDeferredSuspendResult(re.deferred, 0, conversation);
85976
+ reSuspended = true;
85977
+ }
85978
+ }
85979
+ let loopResult;
85980
+ if (reSuspended) {
85981
+ queuedUserTurns.length = 0;
85982
+ stdinClosed = true;
85983
+ cronScheduler.stop();
85984
+ await drainToOutput();
85985
+ } else {
85986
+ loopResult = await runTurn(conversation);
85987
+ conversation = loopResult.messages;
85988
+ if (loopResult.deferred) {
85989
+ const firstResult = await writeDeferredSuspendResult(loopResult.deferred, loopResult.turns, conversation);
85990
+ switch (options.outputFormat) {
85991
+ case "json": {
85992
+ if (options.verbose) {
85993
+ process.stdout.write(JSON.stringify(conversation) + `
85808
85994
  `);
85995
+ } else {
85996
+ process.stdout.write(JSON.stringify(firstResult) + `
85997
+ `);
85998
+ }
85809
85999
  break;
85810
- case "error_during_execution":
85811
- process.stdout.write(`Execution error`);
86000
+ }
86001
+ case "stream-json":
85812
86002
  break;
85813
- case "error_max_turns":
85814
- process.stdout.write(`Error: Reached max turns (${String(options.maxTurns)})`);
86003
+ default: {
86004
+ process.stdout.write(String(firstResult.result ?? "") + `
86005
+ `);
85815
86006
  break;
85816
- default:
86007
+ }
86008
+ }
86009
+ queuedUserTurns.length = 0;
86010
+ stdinClosed = true;
86011
+ } else {
86012
+ const firstResult = await writeTurnOutputs(loopResult);
86013
+ switch (options.outputFormat) {
86014
+ case "json": {
86015
+ if (options.verbose) {
86016
+ process.stdout.write(JSON.stringify(conversation) + `
86017
+ `);
86018
+ } else {
86019
+ process.stdout.write(JSON.stringify(firstResult) + `
86020
+ `);
86021
+ }
86022
+ break;
86023
+ }
86024
+ case "stream-json":
85817
86025
  break;
86026
+ default: {
86027
+ const result = firstResult;
86028
+ switch (result.subtype) {
86029
+ case "success":
86030
+ process.stdout.write(result.result?.endsWith(`
86031
+ `) ? result.result : (result.result ?? "") + `
86032
+ `);
86033
+ break;
86034
+ case "error_during_execution":
86035
+ process.stdout.write(`Execution error`);
86036
+ break;
86037
+ case "error_max_turns":
86038
+ process.stdout.write(`Error: Reached max turns (${String(options.maxTurns)})`);
86039
+ break;
86040
+ default:
86041
+ break;
86042
+ }
86043
+ }
85818
86044
  }
85819
86045
  }
85820
86046
  }
@@ -165199,7 +165425,7 @@ var init_addDirPluginSettings = __esm(() => {
165199
165425
  });
165200
165426
 
165201
165427
  // src/tui/entrypoints/sdk/coreSchemas.ts
165202
- var ModelUsageSchema, OutputFormatTypeSchema, BaseOutputFormatSchema, JsonSchemaOutputFormatSchema, OutputFormatSchema, ApiKeySourceSchema, ConfigScopeSchema2, SdkBetaSchema, ThinkingAdaptiveSchema, ThinkingEnabledSchema, ThinkingDisabledSchema, ThinkingConfigSchema, McpStdioServerConfigSchema2, McpSSEServerConfigSchema2, McpHttpServerConfigSchema, McpSdkServerConfigSchema, McpServerConfigForProcessTransportSchema, McpClaudeAIProxyServerConfigSchema, McpServerStatusConfigSchema, McpServerStatusSchema, McpSetServersResultSchema, PermissionUpdateDestinationSchema, PermissionBehaviorSchema, PermissionRuleValueSchema, PermissionUpdateSchema, PermissionDecisionClassificationSchema, PermissionResultSchema, PermissionModeSchema2, HOOK_EVENTS2, HookEventSchema, BaseHookInputSchema, PreToolUseHookInputSchema, PermissionRequestHookInputSchema, PostToolUseHookInputSchema, PostToolUseFailureHookInputSchema, PermissionDeniedHookInputSchema, NotificationHookInputSchema, UserPromptSubmitHookInputSchema, SessionStartHookInputSchema, SetupHookInputSchema, StopHookInputSchema, StopFailureHookInputSchema, SubagentStartHookInputSchema, SubagentStopHookInputSchema, PreCompactHookInputSchema, PostCompactHookInputSchema, TeammateIdleHookInputSchema, TaskCreatedHookInputSchema, TaskCompletedHookInputSchema, ElicitationHookInputSchema, ElicitationResultHookInputSchema, CONFIG_CHANGE_SOURCES, ConfigChangeHookInputSchema, INSTRUCTIONS_LOAD_REASONS, INSTRUCTIONS_MEMORY_TYPES, InstructionsLoadedHookInputSchema, WorktreeCreateHookInputSchema, WorktreeRemoveHookInputSchema, CwdChangedHookInputSchema, FileChangedHookInputSchema, EXIT_REASONS, ExitReasonSchema, SessionEndHookInputSchema, HookInputSchema, AsyncHookJSONOutputSchema, PreToolUseHookSpecificOutputSchema, UserPromptSubmitHookSpecificOutputSchema, SessionStartHookSpecificOutputSchema, SetupHookSpecificOutputSchema, SubagentStartHookSpecificOutputSchema, PostToolUseHookSpecificOutputSchema, PostToolUseFailureHookSpecificOutputSchema, PermissionDeniedHookSpecificOutputSchema, NotificationHookSpecificOutputSchema, PermissionRequestHookSpecificOutputSchema, CwdChangedHookSpecificOutputSchema, FileChangedHookSpecificOutputSchema, SyncHookJSONOutputSchema, ElicitationHookSpecificOutputSchema, ElicitationResultHookSpecificOutputSchema, WorktreeCreateHookSpecificOutputSchema, HookJSONOutputSchema, PromptRequestOptionSchema, PromptRequestSchema, PromptResponseSchema, SlashCommandSchema, AgentInfoSchema, ModelInfoSchema, AccountInfoSchema, AgentMcpServerSpecSchema, AgentDefinitionSchema, SettingSourceSchema, SdkPluginConfigSchema, RewindFilesResultSchema, APIUserMessagePlaceholder, APIAssistantMessagePlaceholder, RawMessageStreamEventPlaceholder, UUIDPlaceholder, NonNullableUsagePlaceholder, SDKAssistantMessageErrorSchema, SDKStatusSchema, SDKUserMessageContentSchema, SDKUserMessageSchema, SDKUserMessageReplaySchema, SDKRateLimitInfoSchema, SDKAssistantMessageSchema, SDKRateLimitEventSchema, SDKStreamlinedTextMessageSchema, SDKStreamlinedToolUseSummaryMessageSchema, SDKPermissionDenialSchema, SDKResultSuccessSchema, SDKResultErrorSchema, SDKResultMessageSchema, SDKSystemMessageSchema, SDKPartialAssistantMessageSchema, SDKCompactBoundaryMessageSchema, SDKStatusMessageSchema, SDKPostTurnSummaryMessageSchema, SDKAPIRetryMessageSchema, SDKLocalCommandOutputMessageSchema, SDKHookStartedMessageSchema, SDKHookProgressMessageSchema, SDKHookResponseMessageSchema, SDKToolProgressMessageSchema, SDKAuthStatusMessageSchema, SDKFilesPersistedEventSchema, SDKTaskNotificationMessageSchema, SDKTaskStartedMessageSchema, SDKSessionStateChangedMessageSchema, SDKTaskProgressMessageSchema, SDKToolUseSummaryMessageSchema, SDKElicitationCompleteMessageSchema, SDKPromptSuggestionMessageSchema, SDKSessionInfoSchema, SDKMessageSchema, FastModeStateSchema;
165428
+ var ModelUsageSchema, OutputFormatTypeSchema, BaseOutputFormatSchema, JsonSchemaOutputFormatSchema, OutputFormatSchema, ApiKeySourceSchema, ConfigScopeSchema2, SdkBetaSchema, ThinkingAdaptiveSchema, ThinkingEnabledSchema, ThinkingDisabledSchema, ThinkingConfigSchema, McpStdioServerConfigSchema2, McpSSEServerConfigSchema2, McpHttpServerConfigSchema, McpSdkServerConfigSchema, McpServerConfigForProcessTransportSchema, McpClaudeAIProxyServerConfigSchema, McpServerStatusConfigSchema, McpServerStatusSchema, McpSetServersResultSchema, PermissionUpdateDestinationSchema, PermissionBehaviorSchema, PreToolUsePermissionDecisionSchema, PermissionRuleValueSchema, PermissionUpdateSchema, PermissionDecisionClassificationSchema, PermissionResultSchema, PermissionModeSchema2, HOOK_EVENTS2, HookEventSchema, BaseHookInputSchema, PreToolUseHookInputSchema, PermissionRequestHookInputSchema, PostToolUseHookInputSchema, PostToolUseFailureHookInputSchema, PermissionDeniedHookInputSchema, NotificationHookInputSchema, UserPromptSubmitHookInputSchema, SessionStartHookInputSchema, SetupHookInputSchema, StopHookInputSchema, StopFailureHookInputSchema, SubagentStartHookInputSchema, SubagentStopHookInputSchema, PreCompactHookInputSchema, PostCompactHookInputSchema, TeammateIdleHookInputSchema, TaskCreatedHookInputSchema, TaskCompletedHookInputSchema, ElicitationHookInputSchema, ElicitationResultHookInputSchema, CONFIG_CHANGE_SOURCES, ConfigChangeHookInputSchema, INSTRUCTIONS_LOAD_REASONS, INSTRUCTIONS_MEMORY_TYPES, InstructionsLoadedHookInputSchema, WorktreeCreateHookInputSchema, WorktreeRemoveHookInputSchema, CwdChangedHookInputSchema, FileChangedHookInputSchema, EXIT_REASONS, ExitReasonSchema, SessionEndHookInputSchema, HookInputSchema, AsyncHookJSONOutputSchema, PreToolUseHookSpecificOutputSchema, UserPromptSubmitHookSpecificOutputSchema, SessionStartHookSpecificOutputSchema, SetupHookSpecificOutputSchema, SubagentStartHookSpecificOutputSchema, PostToolUseHookSpecificOutputSchema, PostToolUseFailureHookSpecificOutputSchema, PermissionDeniedHookSpecificOutputSchema, NotificationHookSpecificOutputSchema, PermissionRequestHookSpecificOutputSchema, CwdChangedHookSpecificOutputSchema, FileChangedHookSpecificOutputSchema, SyncHookJSONOutputSchema, ElicitationHookSpecificOutputSchema, ElicitationResultHookSpecificOutputSchema, WorktreeCreateHookSpecificOutputSchema, HookJSONOutputSchema, PromptRequestOptionSchema, PromptRequestSchema, PromptResponseSchema, SlashCommandSchema, AgentInfoSchema, ModelInfoSchema, AccountInfoSchema, AgentMcpServerSpecSchema, AgentDefinitionSchema, SettingSourceSchema, SdkPluginConfigSchema, RewindFilesResultSchema, APIUserMessagePlaceholder, APIAssistantMessagePlaceholder, RawMessageStreamEventPlaceholder, UUIDPlaceholder, NonNullableUsagePlaceholder, SDKAssistantMessageErrorSchema, SDKStatusSchema, SDKUserMessageContentSchema, SDKUserMessageSchema, SDKUserMessageReplaySchema, SDKRateLimitInfoSchema, SDKAssistantMessageSchema, SDKRateLimitEventSchema, SDKStreamlinedTextMessageSchema, SDKStreamlinedToolUseSummaryMessageSchema, SDKPermissionDenialSchema, SDKResultSuccessSchema, SDKResultErrorSchema, SDKResultMessageSchema, SDKSystemMessageSchema, SDKPartialAssistantMessageSchema, SDKCompactBoundaryMessageSchema, SDKStatusMessageSchema, SDKPostTurnSummaryMessageSchema, SDKAPIRetryMessageSchema, SDKLocalCommandOutputMessageSchema, SDKHookStartedMessageSchema, SDKHookProgressMessageSchema, SDKHookResponseMessageSchema, SDKToolProgressMessageSchema, SDKAuthStatusMessageSchema, SDKFilesPersistedEventSchema, SDKTaskNotificationMessageSchema, SDKTaskStartedMessageSchema, SDKSessionStateChangedMessageSchema, SDKTaskProgressMessageSchema, SDKToolUseSummaryMessageSchema, SDKElicitationCompleteMessageSchema, SDKPromptSuggestionMessageSchema, SDKSessionInfoSchema, SDKMessageSchema, FastModeStateSchema;
165203
165429
  var init_coreSchemas = __esm(() => {
165204
165430
  init_v4();
165205
165431
  ModelUsageSchema = lazySchema2(() => object({
@@ -165309,6 +165535,7 @@ var init_coreSchemas = __esm(() => {
165309
165535
  "cliArg"
165310
165536
  ]));
165311
165537
  PermissionBehaviorSchema = lazySchema2(() => _enum(["allow", "deny", "ask"]));
165538
+ PreToolUsePermissionDecisionSchema = lazySchema2(() => _enum(["allow", "deny", "ask", "defer"]));
165312
165539
  PermissionRuleValueSchema = lazySchema2(() => object({
165313
165540
  toolName: string2(),
165314
165541
  ruleContent: string2().optional()
@@ -165630,7 +165857,7 @@ var init_coreSchemas = __esm(() => {
165630
165857
  }));
165631
165858
  PreToolUseHookSpecificOutputSchema = lazySchema2(() => object({
165632
165859
  hookEventName: literal("PreToolUse"),
165633
- permissionDecision: PermissionBehaviorSchema().optional(),
165860
+ permissionDecision: PreToolUsePermissionDecisionSchema().optional(),
165634
165861
  permissionDecisionReason: string2().optional(),
165635
165862
  updatedInput: record(string2(), unknown()).optional(),
165636
165863
  additionalContext: string2().optional()
@@ -179440,6 +179667,7 @@ __export(exports_engineCompat, {
179440
179667
  lock: () => lock,
179441
179668
  lockSync: () => lockSync,
179442
179669
  looksLikePrompt: () => looksLikePrompt,
179670
+ makeDeferredToolUseMarker: () => makeDeferredToolUseMarker,
179443
179671
  markAgentsNotified: () => markAgentsNotified,
179444
179672
  markCronTasksFired: () => markCronTasksFired,
179445
179673
  markExtractionCompleted: () => markExtractionCompleted,
@@ -301156,10 +301384,11 @@ var init_InProcessTeammateTask = __esm(() => {
301156
301384
  });
301157
301385
 
301158
301386
  // src/tui/utils/permissions/PermissionRule.ts
301159
- var permissionBehaviorSchema2, permissionRuleValueSchema2;
301387
+ var permissionBehaviorSchema2, preToolUsePermissionDecisionSchema, permissionRuleValueSchema2;
301160
301388
  var init_PermissionRule2 = __esm(() => {
301161
301389
  init_v4();
301162
301390
  permissionBehaviorSchema2 = lazySchema2(() => _enum(["allow", "deny", "ask"]));
301391
+ preToolUsePermissionDecisionSchema = lazySchema2(() => _enum(["allow", "deny", "ask", "defer"]));
301163
301392
  permissionRuleValueSchema2 = lazySchema2(() => object({
301164
301393
  toolName: string2(),
301165
301394
  ruleContent: string2().optional()
@@ -425482,7 +425711,7 @@ var init_hooks6 = __esm(() => {
425482
425711
  hookSpecificOutput: union([
425483
425712
  object({
425484
425713
  hookEventName: literal("PreToolUse"),
425485
- permissionDecision: permissionBehaviorSchema2().optional(),
425714
+ permissionDecision: preToolUsePermissionDecisionSchema().optional(),
425486
425715
  permissionDecisionReason: string2().optional(),
425487
425716
  updatedInput: record(string2(), unknown()).optional(),
425488
425717
  additionalContext: string2().optional()
@@ -426396,11 +426625,11 @@ ${jsonStringify5({
426396
426625
  decision: '"approve" | "block" (optional)',
426397
426626
  reason: "string (optional)",
426398
426627
  systemMessage: "string (optional)",
426399
- permissionDecision: '"allow" | "deny" | "ask" (optional)',
426628
+ permissionDecision: '"allow" | "deny" | "ask" | "defer" (optional; defer = 挂起重评, TUI 车道确认等价)',
426400
426629
  hookSpecificOutput: {
426401
426630
  "for PreToolUse": {
426402
426631
  hookEventName: '"PreToolUse"',
426403
- permissionDecision: '"allow" | "deny" | "ask" (optional)',
426632
+ permissionDecision: '"allow" | "deny" | "ask" | "defer" (optional; defer = 挂起重评, TUI 车道确认等价)',
426404
426633
  permissionDecisionReason: "string (optional)",
426405
426634
  updatedInput: "object (optional) - Modified tool input to use"
426406
426635
  },
@@ -426502,8 +426731,11 @@ function processHookJSONOutput({
426502
426731
  case "ask":
426503
426732
  result.permissionBehavior = "ask";
426504
426733
  break;
426734
+ case "defer":
426735
+ result.permissionBehavior = "ask";
426736
+ break;
426505
426737
  default:
426506
- throw new Error(`Unknown hook permissionDecision type: ${json.hookSpecificOutput.permissionDecision}. Valid types are: allow, deny, ask`);
426738
+ throw new Error(`Unknown hook permissionDecision type: ${json.hookSpecificOutput.permissionDecision}. Valid types are: allow, deny, ask, defer`);
426507
426739
  }
426508
426740
  }
426509
426741
  if (result.permissionBehavior !== undefined && json.reason !== undefined) {
@@ -426530,6 +426762,9 @@ function processHookJSONOutput({
426530
426762
  case "ask":
426531
426763
  result.permissionBehavior = "ask";
426532
426764
  break;
426765
+ case "defer":
426766
+ result.permissionBehavior = "ask";
426767
+ break;
426533
426768
  }
426534
426769
  }
426535
426770
  result.hookPermissionDecisionReason = json.hookSpecificOutput.permissionDecisionReason;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlasharness/atlascode",
3
- "version": "0.1.51",
3
+ "version": "0.1.52",
4
4
  "description": "AtlasCode \u2014 Coding Agent for the domestic computing ecosystem (Ascend NPU + domestic LLM backends)",
5
5
  "bin": {
6
6
  "atlas": "dist/cli.js",