@atlasharness/atlascode 0.1.51 → 0.1.53

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 +283 -43
  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,100 @@ 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, signal, toolContext } = 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
+ signal,
85651
+ toolContext
85652
+ });
85653
+ if (outcome.deferred) {
85654
+ const payload = {
85655
+ toolUseId,
85656
+ toolName: tu.name,
85657
+ deferReason: outcome.deferReason
85658
+ };
85659
+ const marker = makeDeferredToolUseMarker(payload);
85660
+ return {
85661
+ suspended: true,
85662
+ deferred: payload,
85663
+ messages: [...conversation, marker]
85664
+ };
85665
+ }
85666
+ const now = new Date().toISOString();
85667
+ const resultMsg = {
85668
+ type: "user",
85669
+ role: "user",
85670
+ uuid: randomUUID21(),
85671
+ timestamp: now,
85672
+ message: { role: "user", content: [outcome.block] },
85673
+ toolUseResult: outcome.toolUseResult
85674
+ };
85675
+ return { suspended: false, messages: [...conversation, resultMsg] };
85676
+ }
85529
85677
  function resolveHeadlessTpc(tpc) {
85530
85678
  if (tpc)
85531
85679
  return tpc;
@@ -85682,7 +85830,8 @@ async function runHeadless(inputPrompt, options) {
85682
85830
  const loopDeps = {
85683
85831
  ...bundle.deps,
85684
85832
  signal: abortController.signal,
85685
- checkPermission
85833
+ checkPermission,
85834
+ toolContext: makeCtx()
85686
85835
  };
85687
85836
  const autoCompact = {
85688
85837
  contextWindow: (roleModel ? getProviderContextWindow(roleModel) : undefined) ?? 200000,
@@ -85751,6 +85900,34 @@ async function runHeadless(inputPrompt, options) {
85751
85900
  await writeMessage(resultMessage);
85752
85901
  return resultMessage;
85753
85902
  };
85903
+ const writeDeferredSuspendResult = async (p, numTurns, conversationMessages) => {
85904
+ await drainToOutput();
85905
+ for (const m of conversationMessages) {
85906
+ if (m.role !== "assistant")
85907
+ continue;
85908
+ const content = m.message?.content;
85909
+ if (!content || content.length === 0)
85910
+ continue;
85911
+ await writeMessage({
85912
+ type: "assistant",
85913
+ session_id: sessionId,
85914
+ message: { role: "assistant", content },
85915
+ uuid: randomUUID21()
85916
+ });
85917
+ }
85918
+ await drainToOutput();
85919
+ const resultMessage = {
85920
+ type: "result",
85921
+ subtype: "deferred",
85922
+ session_id: sessionId,
85923
+ is_error: false,
85924
+ num_turns: numTurns,
85925
+ result: `Deferred tool call ${p.toolName} (${p.toolUseId}) by PreToolUse hook` + (p.deferReason ? `: ${p.deferReason}` : "") + `. Session suspended — resume with: atlas -p --resume ${sessionId}`,
85926
+ uuid: randomUUID21()
85927
+ };
85928
+ await writeMessage(resultMessage);
85929
+ return resultMessage;
85930
+ };
85754
85931
  const queuedUserTurns = [];
85755
85932
  let stdinClosed = false;
85756
85933
  const drainPump = (async () => {
@@ -85783,38 +85960,92 @@ async function runHeadless(inputPrompt, options) {
85783
85960
  });
85784
85961
  cronScheduler.start();
85785
85962
  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;
85963
+ const deferredState = findDeferredToolUseState(conversation);
85964
+ let reSuspended = false;
85965
+ if (deferredState) {
85966
+ const re = await reEvaluateDeferredToolCalls({
85967
+ conversation,
85968
+ toolUseId: deferredState.toolUseId,
85969
+ tools,
85970
+ toolHooks: loopDeps.hooks?.toolHooks,
85971
+ checkPermission,
85972
+ signal: loopDeps.signal,
85973
+ toolContext: loopDeps.toolContext
85974
+ });
85975
+ conversation = re.messages;
85976
+ if (loopDeps.transcript) {
85977
+ loopDeps.transcript.record(conversation);
85799
85978
  }
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 ?? "") + `
85979
+ if (re.suspended && re.deferred) {
85980
+ await writeDeferredSuspendResult(re.deferred, 0, conversation);
85981
+ reSuspended = true;
85982
+ }
85983
+ }
85984
+ let loopResult;
85985
+ if (reSuspended) {
85986
+ queuedUserTurns.length = 0;
85987
+ stdinClosed = true;
85988
+ cronScheduler.stop();
85989
+ await drainToOutput();
85990
+ } else {
85991
+ loopResult = await runTurn(conversation);
85992
+ conversation = loopResult.messages;
85993
+ if (loopResult.deferred) {
85994
+ const firstResult = await writeDeferredSuspendResult(loopResult.deferred, loopResult.turns, conversation);
85995
+ switch (options.outputFormat) {
85996
+ case "json": {
85997
+ if (options.verbose) {
85998
+ process.stdout.write(JSON.stringify(conversation) + `
85808
85999
  `);
86000
+ } else {
86001
+ process.stdout.write(JSON.stringify(firstResult) + `
86002
+ `);
86003
+ }
85809
86004
  break;
85810
- case "error_during_execution":
85811
- process.stdout.write(`Execution error`);
86005
+ }
86006
+ case "stream-json":
85812
86007
  break;
85813
- case "error_max_turns":
85814
- process.stdout.write(`Error: Reached max turns (${String(options.maxTurns)})`);
86008
+ default: {
86009
+ process.stdout.write(String(firstResult.result ?? "") + `
86010
+ `);
85815
86011
  break;
85816
- default:
86012
+ }
86013
+ }
86014
+ queuedUserTurns.length = 0;
86015
+ stdinClosed = true;
86016
+ } else {
86017
+ const firstResult = await writeTurnOutputs(loopResult);
86018
+ switch (options.outputFormat) {
86019
+ case "json": {
86020
+ if (options.verbose) {
86021
+ process.stdout.write(JSON.stringify(conversation) + `
86022
+ `);
86023
+ } else {
86024
+ process.stdout.write(JSON.stringify(firstResult) + `
86025
+ `);
86026
+ }
86027
+ break;
86028
+ }
86029
+ case "stream-json":
85817
86030
  break;
86031
+ default: {
86032
+ const result = firstResult;
86033
+ switch (result.subtype) {
86034
+ case "success":
86035
+ process.stdout.write(result.result?.endsWith(`
86036
+ `) ? result.result : (result.result ?? "") + `
86037
+ `);
86038
+ break;
86039
+ case "error_during_execution":
86040
+ process.stdout.write(`Execution error`);
86041
+ break;
86042
+ case "error_max_turns":
86043
+ process.stdout.write(`Error: Reached max turns (${String(options.maxTurns)})`);
86044
+ break;
86045
+ default:
86046
+ break;
86047
+ }
86048
+ }
85818
86049
  }
85819
86050
  }
85820
86051
  }
@@ -165199,7 +165430,7 @@ var init_addDirPluginSettings = __esm(() => {
165199
165430
  });
165200
165431
 
165201
165432
  // 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;
165433
+ 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
165434
  var init_coreSchemas = __esm(() => {
165204
165435
  init_v4();
165205
165436
  ModelUsageSchema = lazySchema2(() => object({
@@ -165309,6 +165540,7 @@ var init_coreSchemas = __esm(() => {
165309
165540
  "cliArg"
165310
165541
  ]));
165311
165542
  PermissionBehaviorSchema = lazySchema2(() => _enum(["allow", "deny", "ask"]));
165543
+ PreToolUsePermissionDecisionSchema = lazySchema2(() => _enum(["allow", "deny", "ask", "defer"]));
165312
165544
  PermissionRuleValueSchema = lazySchema2(() => object({
165313
165545
  toolName: string2(),
165314
165546
  ruleContent: string2().optional()
@@ -165630,7 +165862,7 @@ var init_coreSchemas = __esm(() => {
165630
165862
  }));
165631
165863
  PreToolUseHookSpecificOutputSchema = lazySchema2(() => object({
165632
165864
  hookEventName: literal("PreToolUse"),
165633
- permissionDecision: PermissionBehaviorSchema().optional(),
165865
+ permissionDecision: PreToolUsePermissionDecisionSchema().optional(),
165634
165866
  permissionDecisionReason: string2().optional(),
165635
165867
  updatedInput: record(string2(), unknown()).optional(),
165636
165868
  additionalContext: string2().optional()
@@ -179440,6 +179672,7 @@ __export(exports_engineCompat, {
179440
179672
  lock: () => lock,
179441
179673
  lockSync: () => lockSync,
179442
179674
  looksLikePrompt: () => looksLikePrompt,
179675
+ makeDeferredToolUseMarker: () => makeDeferredToolUseMarker,
179443
179676
  markAgentsNotified: () => markAgentsNotified,
179444
179677
  markCronTasksFired: () => markCronTasksFired,
179445
179678
  markExtractionCompleted: () => markExtractionCompleted,
@@ -301156,10 +301389,11 @@ var init_InProcessTeammateTask = __esm(() => {
301156
301389
  });
301157
301390
 
301158
301391
  // src/tui/utils/permissions/PermissionRule.ts
301159
- var permissionBehaviorSchema2, permissionRuleValueSchema2;
301392
+ var permissionBehaviorSchema2, preToolUsePermissionDecisionSchema, permissionRuleValueSchema2;
301160
301393
  var init_PermissionRule2 = __esm(() => {
301161
301394
  init_v4();
301162
301395
  permissionBehaviorSchema2 = lazySchema2(() => _enum(["allow", "deny", "ask"]));
301396
+ preToolUsePermissionDecisionSchema = lazySchema2(() => _enum(["allow", "deny", "ask", "defer"]));
301163
301397
  permissionRuleValueSchema2 = lazySchema2(() => object({
301164
301398
  toolName: string2(),
301165
301399
  ruleContent: string2().optional()
@@ -425482,7 +425716,7 @@ var init_hooks6 = __esm(() => {
425482
425716
  hookSpecificOutput: union([
425483
425717
  object({
425484
425718
  hookEventName: literal("PreToolUse"),
425485
- permissionDecision: permissionBehaviorSchema2().optional(),
425719
+ permissionDecision: preToolUsePermissionDecisionSchema().optional(),
425486
425720
  permissionDecisionReason: string2().optional(),
425487
425721
  updatedInput: record(string2(), unknown()).optional(),
425488
425722
  additionalContext: string2().optional()
@@ -426396,11 +426630,11 @@ ${jsonStringify5({
426396
426630
  decision: '"approve" | "block" (optional)',
426397
426631
  reason: "string (optional)",
426398
426632
  systemMessage: "string (optional)",
426399
- permissionDecision: '"allow" | "deny" | "ask" (optional)',
426633
+ permissionDecision: '"allow" | "deny" | "ask" | "defer" (optional; defer = 挂起重评, TUI 车道确认等价)',
426400
426634
  hookSpecificOutput: {
426401
426635
  "for PreToolUse": {
426402
426636
  hookEventName: '"PreToolUse"',
426403
- permissionDecision: '"allow" | "deny" | "ask" (optional)',
426637
+ permissionDecision: '"allow" | "deny" | "ask" | "defer" (optional; defer = 挂起重评, TUI 车道确认等价)',
426404
426638
  permissionDecisionReason: "string (optional)",
426405
426639
  updatedInput: "object (optional) - Modified tool input to use"
426406
426640
  },
@@ -426502,8 +426736,11 @@ function processHookJSONOutput({
426502
426736
  case "ask":
426503
426737
  result.permissionBehavior = "ask";
426504
426738
  break;
426739
+ case "defer":
426740
+ result.permissionBehavior = "ask";
426741
+ break;
426505
426742
  default:
426506
- throw new Error(`Unknown hook permissionDecision type: ${json.hookSpecificOutput.permissionDecision}. Valid types are: allow, deny, ask`);
426743
+ throw new Error(`Unknown hook permissionDecision type: ${json.hookSpecificOutput.permissionDecision}. Valid types are: allow, deny, ask, defer`);
426507
426744
  }
426508
426745
  }
426509
426746
  if (result.permissionBehavior !== undefined && json.reason !== undefined) {
@@ -426530,6 +426767,9 @@ function processHookJSONOutput({
426530
426767
  case "ask":
426531
426768
  result.permissionBehavior = "ask";
426532
426769
  break;
426770
+ case "defer":
426771
+ result.permissionBehavior = "ask";
426772
+ break;
426533
426773
  }
426534
426774
  }
426535
426775
  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.53",
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",