@namzu/cli 33.0.0 → 33.1.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 (90) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/commands/archive.d.ts.map +1 -1
  3. package/dist/commands/archive.js +4 -1
  4. package/dist/commands/archive.js.map +1 -1
  5. package/dist/commands/drain.js +3 -3
  6. package/dist/commands/drain.js.map +1 -1
  7. package/dist/commands/exec.js +1 -1
  8. package/dist/commands/exec.js.map +1 -1
  9. package/dist/commands/schedule.d.ts.map +1 -1
  10. package/dist/commands/schedule.js +5 -2
  11. package/dist/commands/schedule.js.map +1 -1
  12. package/dist/commands/worktree.d.ts.map +1 -1
  13. package/dist/commands/worktree.js +2 -1
  14. package/dist/commands/worktree.js.map +1 -1
  15. package/dist/integrations/sessions/display-title.d.ts +3 -0
  16. package/dist/integrations/sessions/display-title.d.ts.map +1 -0
  17. package/dist/integrations/sessions/display-title.js +5 -0
  18. package/dist/integrations/sessions/display-title.js.map +1 -0
  19. package/dist/schedule/build.d.ts +2 -0
  20. package/dist/schedule/build.d.ts.map +1 -1
  21. package/dist/schedule/build.js +11 -2
  22. package/dist/schedule/build.js.map +1 -1
  23. package/dist/schedule/commands/add.d.ts +1 -1
  24. package/dist/schedule/commands/add.d.ts.map +1 -1
  25. package/dist/schedule/commands/add.js +12 -2
  26. package/dist/schedule/commands/add.js.map +1 -1
  27. package/dist/schedule/commands/list.d.ts.map +1 -1
  28. package/dist/schedule/commands/list.js +10 -1
  29. package/dist/schedule/commands/list.js.map +1 -1
  30. package/dist/schedule/daemon/daemon.js +1 -1
  31. package/dist/schedule/daemon/daemon.js.map +1 -1
  32. package/dist/schedule/fire/fire.d.ts.map +1 -1
  33. package/dist/schedule/fire/fire.js +1 -1
  34. package/dist/schedule/fire/fire.js.map +1 -1
  35. package/dist/schedule/script-check.d.ts.map +1 -1
  36. package/dist/schedule/script-check.js +2 -1
  37. package/dist/schedule/script-check.js.map +1 -1
  38. package/dist/tui/App.d.ts.map +1 -1
  39. package/dist/tui/App.js +116 -53
  40. package/dist/tui/App.js.map +1 -1
  41. package/dist/tui/BrandHeader.js +1 -1
  42. package/dist/tui/BrandHeader.js.map +1 -1
  43. package/dist/tui/Composer.d.ts.map +1 -1
  44. package/dist/tui/Composer.js +6 -11
  45. package/dist/tui/Composer.js.map +1 -1
  46. package/dist/tui/ComposerFrame.d.ts +6 -8
  47. package/dist/tui/ComposerFrame.d.ts.map +1 -1
  48. package/dist/tui/ComposerFrame.js +55 -12
  49. package/dist/tui/ComposerFrame.js.map +1 -1
  50. package/dist/tui/ResumePicker.d.ts.map +1 -1
  51. package/dist/tui/ResumePicker.js +2 -1
  52. package/dist/tui/ResumePicker.js.map +1 -1
  53. package/dist/tui/SaveSkillOverlay.js +1 -1
  54. package/dist/tui/SaveSkillOverlay.js.map +1 -1
  55. package/dist/tui/ScheduleReviewOverlay.d.ts +27 -0
  56. package/dist/tui/ScheduleReviewOverlay.d.ts.map +1 -0
  57. package/dist/tui/ScheduleReviewOverlay.js +166 -0
  58. package/dist/tui/ScheduleReviewOverlay.js.map +1 -0
  59. package/dist/tui/Transcript.js +2 -2
  60. package/dist/tui/Transcript.js.map +1 -1
  61. package/dist/tui/agent.d.ts +1 -1
  62. package/dist/tui/agent.d.ts.map +1 -1
  63. package/dist/tui/agent.js +1 -1
  64. package/dist/tui/agent.js.map +1 -1
  65. package/dist/tui/hypermode.d.ts +1 -1
  66. package/dist/tui/hypermode.d.ts.map +1 -1
  67. package/dist/tui/hypermode.js +1 -1
  68. package/dist/tui/hypermode.js.map +1 -1
  69. package/dist/tui/schedule/host-commands.d.ts +3 -0
  70. package/dist/tui/schedule/host-commands.d.ts.map +1 -1
  71. package/dist/tui/schedule/host-commands.js +72 -15
  72. package/dist/tui/schedule/host-commands.js.map +1 -1
  73. package/dist/tui/schedule/integration.d.ts +2 -0
  74. package/dist/tui/schedule/integration.d.ts.map +1 -1
  75. package/dist/tui/schedule/integration.js +3 -0
  76. package/dist/tui/schedule/integration.js.map +1 -1
  77. package/dist/tui/schedule/resume.js +2 -2
  78. package/dist/tui/schedule/resume.js.map +1 -1
  79. package/dist/tui/schedule/tool-host.d.ts +3 -0
  80. package/dist/tui/schedule/tool-host.d.ts.map +1 -1
  81. package/dist/tui/schedule/tool-host.js +34 -9
  82. package/dist/tui/schedule/tool-host.js.map +1 -1
  83. package/dist/tui/slashCommands.js +1 -1
  84. package/dist/tui/slashCommands.js.map +1 -1
  85. package/dist/tui/theme.d.ts +5 -6
  86. package/dist/tui/theme.d.ts.map +1 -1
  87. package/dist/tui/theme.js +3 -4
  88. package/dist/tui/theme.js.map +1 -1
  89. package/package.json +4 -4
  90. package/skills/schedule-task/SKILL.md +41 -15
@@ -133,9 +133,10 @@ export function verifyScheduledScript(body, shell, policy) {
133
133
  commandDialect: shell,
134
134
  });
135
135
  if (result.decision === 'deny') {
136
+ const blanketBashDeny = result.reason.includes('denied by name (bash)');
136
137
  return {
137
138
  ok: false,
138
- reason: `the command ${shown(command.text)} is denied: ${result.reason}`,
139
+ reason: `the command ${shown(command.text)} is denied: ${result.reason}${blanketBashDeny ? '; a bash deny rule blocks every script command, so changing the script text cannot fix it' : ''}`,
139
140
  };
140
141
  }
141
142
  }
@@ -1 +1 @@
1
- {"version":3,"file":"script-check.js","sourceRoot":"","sources":["../../src/schedule/script-check.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"script-check.js","sourceRoot":"","sources":["../../src/schedule/script-check.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAON,KAAK,OAAO,EAmBZ,MAAM,YAAY,CAAA;AA8NnB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AA+DvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAa/D,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAA;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAA;IAC1D,0EAA0E;IAC1E,QAAQ,CAAC,cAAc,CAAC,EAAE,qBAAqB,CAAA;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAA;KAAE,CAAA;CAC3D;AASD,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAC5B,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;AAuSrB,6EAA6E;AAC7E,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,MAAM,EAAE,CAM7F;AAED,sEAAsE;AACtE,wBAAgB,mBAAmB,CAClC,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,MAAM,EAAE,MAAM,MAAM,EACpB,iBAAiB,GAAE,SAAS,MAAM,EAAO,GACvC,SAAS,iBAAiB,EAAE,CAqE9B;AA2HD,wBAAgB,GAAG,CAAC,EACnB,GAAG,EAAE,UAAU,EACf,aAAa,EACb,cAAsC,EACtC,eAAe,GACf,EAAE,QAAQ,2CAosRV"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/tui/App.tsx"],"names":[],"mappings":"AAmBA,OAAO,EAON,KAAK,OAAO,EAmBZ,MAAM,YAAY,CAAA;AAoOnB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AA+DvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAa/D,MAAM,WAAW,QAAQ;IACxB,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAA;IACxB,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAA;IAC1D,0EAA0E;IAC1E,QAAQ,CAAC,cAAc,CAAC,EAAE,qBAAqB,CAAA;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE;QAAE,OAAO,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAA;KAAE,CAAA;CAC3D;AASD,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,EAAE;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAA;CAC5B,KAAK,OAAO,CAAC,MAAM,CAAC,CAAA;AAuSrB,6EAA6E;AAC7E,wBAAgB,6BAA6B,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,SAAS,MAAM,EAAE,CAM7F;AAED,sEAAsE;AACtE,wBAAgB,mBAAmB,CAClC,QAAQ,EAAE,SAAS,OAAO,EAAE,EAC5B,MAAM,EAAE,MAAM,MAAM,EACpB,iBAAiB,GAAE,SAAS,MAAM,EAAO,GACvC,SAAS,iBAAiB,EAAE,CAqE9B;AA2HD,wBAAgB,GAAG,CAAC,EACnB,GAAG,EAAE,UAAU,EACf,aAAa,EACb,cAAsC,EACtC,eAAe,GACf,EAAE,QAAQ,2CAqxRV"}
package/dist/tui/App.js CHANGED
@@ -19,7 +19,7 @@ import { ToolOutputViewer } from './ToolOutputViewer.js';
19
19
  import { join, relative } from 'node:path';
20
20
  import { DEFAULT_MAX_GOAL_ROUNDS, DiskMessageFeedbackStore, GoalRoundLimitError, HostCommandRegistry, SessionGoalActivation, StaleGoalError, TurnCancelled, asSessionId, createAssistantMessage, createUserMessage, generateSessionId, generateTurnId, isCompactionMessage, kernelHostCommands, SKILL_TOOL_NAME, } from '@namzu/sdk';
21
21
  import { Box, Text, useApp, useInput, useStdout, useWindowSize } from 'ink';
22
- import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
22
+ import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
23
23
  import { pinTrustedProjectPath, resolveTrustedProjectContext, } from '../config/trusted-project-context.js';
24
24
  import { visibleProjectInstructionPath } from '../context/project-path.js';
25
25
  import { runtimeContextLabel } from '../context/runtime-message.js';
@@ -28,6 +28,7 @@ import { terminalNotificationEnabled, writeTerminalNotification, } from '../inte
28
28
  import { beginCodexDeviceLogin, beginSubscriptionLogin, clearAllStoredCredentials, clearStoredCodexCredential, clearStoredGeminiApiKey as clearStoredGoogleApiKey, clearStoredSubscriptionCredential, credentialsPath, googleApiKeyPath, parsePastedInput, primaryProvider, readStoredCodexCredential, readStoredGeminiApiKey as readStoredGoogleApiKey, readStoredSubscriptionCredential, signedInSubscriptionProviders, writePreferences, writeStoredGeminiApiKey as writeStoredGoogleApiKey, } from '../integrations/providers/index.js';
29
29
  import { ConversationIndexRefreshError, activeConversationTurn, archiveConversation, forkConversation, forkConversationBeforeUser, listArchived, listRecent, loadConversation, loadResumableConversation, openSessions, requireWritableConversation, setTitle, startConversation, titleOf, unarchiveConversation, } from '../integrations/sessions/store.js';
30
30
  import { conversationMarkdown, writeConversationExport, } from '../integrations/sessions/transcript-export.js';
31
+ import { displayConversationTitle } from '../integrations/sessions/display-title.js';
31
32
  import { openManagedWorktrees, worktreeOpenHint } from '../integrations/worktrees/managed.js';
32
33
  import { NARRATION_TOOL_NAME } from '../integrations/subagents/runtime.js';
33
34
  import { agentsSlashCommand } from '../integrations/subagents/slash.js';
@@ -62,6 +63,7 @@ import { Picker } from './Picker.js';
62
63
  import { ResumePicker } from './ResumePicker.js';
63
64
  import { resolveNamzuHome } from '../integrations/state/home.js';
64
65
  import { createScheduleIntegration } from './schedule/integration.js';
66
+ import { ScheduleReviewOverlay, } from './ScheduleReviewOverlay.js';
65
67
  import { SaveSkillOverlay } from './SaveSkillOverlay.js';
66
68
  import { SKILL_CREATOR_SKILL, buildSaveSkillTool, learnSkillPrompt, newSkillPrompt, } from '../skills/save.js';
67
69
  import { SUGGESTIONS_STOPPED_NOTICE, createTurnActivity, judgeSkillSuggestion, observeTurnEvent, skillSuggestionNotice, } from './skills/learning.js';
@@ -426,6 +428,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
426
428
  // per-session like reasoningEffort above; no preferences file involved.
427
429
  const [hypermode, setHypermodeState] = useState(false);
428
430
  const hypermodeRef = useRef(false);
431
+ const [hypermodeActivation, setHypermodeActivation] = useState(0);
429
432
  const setHypermode = useCallback((next) => {
430
433
  hypermodeRef.current = next;
431
434
  setHypermodeState(next);
@@ -490,7 +493,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
490
493
  ...(job.signal ? { signal: job.signal } : {}),
491
494
  });
492
495
  idleJobNoticesRef.current.push(text);
493
- pushMessage('system', text, false, '⚙');
496
+ pushMessage('system', text, false, 'J');
494
497
  });
495
498
  }, [session]);
496
499
  const [usage, setUsage] = useState(null);
@@ -624,7 +627,9 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
624
627
  choicePickerCommittedRef.current = null;
625
628
  setChoicePickerState(next);
626
629
  }, []);
627
- useEffect(() => {
630
+ // A painted menu must already accept its first key. A passive effect can
631
+ // run after Ink flushes that frame, leaving the ownership fence closed.
632
+ useLayoutEffect(() => {
628
633
  choicePickerCommittedRef.current = choicePicker;
629
634
  }, [choicePicker]);
630
635
  /** Host-owned text decision; its value never enters model prompt history. */
@@ -990,6 +995,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
990
995
  isIdle: () => stateRef.current === 'idle' && abortRef.current === null,
991
996
  say: (text) => scheduleLiveRef.current?.say(text),
992
997
  ask: (question, signal) => scheduleLiveRef.current?.ask(question, signal) ?? Promise.resolve({ kind: 'skip' }),
998
+ review: (request, signal) => scheduleLiveRef.current?.review(request, signal) ?? Promise.resolve('cancel'),
993
999
  askPermission: (request) => scheduleLiveRef.current?.askPermission(request) ??
994
1000
  Promise.resolve({ kind: 'reject', feedback: 'Nobody can answer yet.' }),
995
1001
  submit: (text, createdBy) => scheduleLiveRef.current?.submit(text, createdBy),
@@ -1006,6 +1012,13 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
1006
1012
  saveSkillPromptRef.current = next;
1007
1013
  setSaveSkillPromptState(next);
1008
1014
  }, []);
1015
+ const [scheduleReviewPrompt, setScheduleReviewPromptState] = useState(null);
1016
+ const scheduleReviewTokenRef = useRef(0);
1017
+ const scheduleReviewPromptRef = useRef(null);
1018
+ const setScheduleReviewPrompt = useCallback((next) => {
1019
+ scheduleReviewPromptRef.current = next;
1020
+ setScheduleReviewPromptState(next);
1021
+ }, []);
1009
1022
  const saveSkillNotifyRef = useRef(null);
1010
1023
  const saveSkillToolRef = useRef(null);
1011
1024
  if (saveSkillToolRef.current === null) {
@@ -1039,7 +1052,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
1039
1052
  setSaveSkillPrompt(entry);
1040
1053
  saveSkillNotifyRef.current?.();
1041
1054
  }),
1042
- saved: ({ name, path }) => scheduleLiveRef.current?.say(`✎ Saved skill ${name} to ${path}. The model is offered it from the next turn; /skills ${name} activates it now.`),
1055
+ saved: ({ name, path }) => scheduleLiveRef.current?.say(`Saved skill ${name} to ${path}. The model is offered it from the next turn; /skills ${name} activates it now.`),
1043
1056
  });
1044
1057
  }
1045
1058
  /**
@@ -1702,7 +1715,10 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
1702
1715
  pushMessage('system', 'Hypermode is off.');
1703
1716
  return;
1704
1717
  }
1718
+ const newlyEnabled = enabled && !hypermodeRef.current;
1705
1719
  setHypermode(enabled);
1720
+ if (newlyEnabled)
1721
+ setHypermodeActivation((activation) => activation + 1);
1706
1722
  if (!enabled) {
1707
1723
  const pin = hypermodePinRef.current;
1708
1724
  hypermodePinRef.current = null;
@@ -3090,9 +3106,11 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
3090
3106
  // settling in the background prints through the child screen. Returning
3091
3107
  // advances the floor once and emits those finalized rows exactly once.
3092
3108
  const nextSettled = settledBeforeStreaming(messages, window.settled, settledRef.current);
3093
- if (agentSurface === null && outputViewer === null)
3109
+ if (agentSurface === null && outputViewer === null && scheduleReviewPrompt === null)
3094
3110
  settledRef.current = nextSettled;
3095
- const renderedSettled = agentSurface === null && outputViewer === null ? nextSettled : settledRef.current;
3111
+ const renderedSettled = agentSurface === null && outputViewer === null && scheduleReviewPrompt === null
3112
+ ? nextSettled
3113
+ : settledRef.current;
3096
3114
  // One merged vocabulary for the session: this host's own commands plus
3097
3115
  // whatever the kernel's registry reports. Built here so `/help`, the
3098
3116
  // autocomplete and the dispatcher all answer from the same list — three
@@ -3269,7 +3287,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
3269
3287
  }
3270
3288
  // Said once the turn really continues: a scheduled park can still
3271
3289
  // be left waiting or abandoned above.
3272
- pushMessage('system', PAUSED_TURN_LINES.resuming, false, '▶');
3290
+ pushMessage('system', PAUSED_TURN_LINES.resuming);
3273
3291
  for await (const event of session.resumePaused({
3274
3292
  turnId: active.turnId,
3275
3293
  signal: ac.signal,
@@ -3621,7 +3639,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
3621
3639
  // would have nothing to find.
3622
3640
  void hydrateSavedChildren();
3623
3641
  conversationMaterializedRef.current = true;
3624
- pushMessage('system', `Resumed: ${conv.title}`);
3642
+ pushMessage('system', `Resumed: ${displayConversationTitle(conv.title)}`);
3625
3643
  if (discardedQueued > 0) {
3626
3644
  pushMessage('system', `Discarded ${discardedQueued} queued prompt${discardedQueued === 1 ? '' : 's'} from the conversation you left.`);
3627
3645
  }
@@ -3674,7 +3692,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
3674
3692
  : `Could not restore: ${err instanceof Error ? err.message : String(err)}`);
3675
3693
  return;
3676
3694
  }
3677
- pushMessage('system', `Restored: ${conv.title}`);
3695
+ pushMessage('system', `Restored: ${displayConversationTitle(conv.title)}`);
3678
3696
  try {
3679
3697
  await resumeConversation(conv);
3680
3698
  }
@@ -3916,7 +3934,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
3916
3934
  session?.resetTaskStore?.();
3917
3935
  goalActivation.clear();
3918
3936
  wakeGoalDriver();
3919
- pushMessage('system', `Forked into "${forked.title}" — ${forked.copied} message(s) copied. This screen continues in the copy; ${original} is unchanged and still in /resume.`);
3937
+ pushMessage('system', `Forked into "${displayConversationTitle(forked.title)}" — ${forked.copied} message(s) copied. This screen continues in the copy; ${original} is unchanged and still in /resume.`);
3920
3938
  }
3921
3939
  catch (err) {
3922
3940
  pushMessage('system', `Could not fork: ${err instanceof Error ? err.message : String(err)}`);
@@ -4043,7 +4061,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
4043
4061
  });
4044
4062
  setEditList([]);
4045
4063
  setPhase('ready');
4046
- pushMessage('system', `Forked into "${forked.title}" before the selected prompt. Edit it below; ${source} is unchanged and remains in /resume.`);
4064
+ pushMessage('system', `Forked into "${displayConversationTitle(forked.title)}" before the selected prompt. Edit it below; ${source} is unchanged and remains in /resume.`);
4047
4065
  }
4048
4066
  catch (err) {
4049
4067
  setPhase('ready');
@@ -4155,6 +4173,39 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
4155
4173
  setChoicePicker(picker);
4156
4174
  sendTerminalNotification({ kind: 'approval-required' });
4157
4175
  }), [closeLiveReply, sendTerminalNotification, setChoicePicker, setSelectedChoice, resolveQuestion]);
4176
+ const reviewSchedule = useCallback((request, signal) => new Promise((resolve) => {
4177
+ if (signal?.aborted) {
4178
+ resolve('cancel');
4179
+ return;
4180
+ }
4181
+ closeLiveReply();
4182
+ // A second tool call must not replace an open review and leave its
4183
+ // Promise waiting forever. Each decision still belongs to its own
4184
+ // captured proposal.
4185
+ scheduleReviewPromptRef.current?.resolve('cancel');
4186
+ let settled = false;
4187
+ const entry = {
4188
+ token: ++scheduleReviewTokenRef.current,
4189
+ request,
4190
+ resolve: (answer) => {
4191
+ if (settled)
4192
+ return;
4193
+ settled = true;
4194
+ signal?.removeEventListener('abort', onAbort);
4195
+ // Let the overlay's key dispatch finish before App regains its
4196
+ // keyboard handler, so Esc cannot interrupt this same turn.
4197
+ queueMicrotask(() => {
4198
+ if (scheduleReviewPromptRef.current === entry)
4199
+ setScheduleReviewPrompt(null);
4200
+ });
4201
+ resolve(answer);
4202
+ },
4203
+ };
4204
+ const onAbort = () => entry.resolve('cancel');
4205
+ signal?.addEventListener('abort', onAbort, { once: true });
4206
+ setScheduleReviewPrompt(entry);
4207
+ sendTerminalNotification({ kind: 'approval-required' });
4208
+ }), [closeLiveReply, sendTerminalNotification, setScheduleReviewPrompt]);
4158
4209
  /**
4159
4210
  * Grow this turn's open task block, or open one. The whole plan rides along
4160
4211
  * so the block shows the checklist as it stood after the operation; a
@@ -4546,7 +4597,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
4546
4597
  case 'job':
4547
4598
  // The kernel saw it end during a turn; the model reads the notice
4548
4599
  // on its next tool result, the operator reads this row.
4549
- pushMessage('system', describeJobExit(event), false, '⚙');
4600
+ pushMessage('system', describeJobExit(event), false, 'J');
4550
4601
  break;
4551
4602
  case 'context':
4552
4603
  // Into the TRANSCRIPT, not a status line. A status indicator is
@@ -6153,7 +6204,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
6153
6204
  throw new Error('Conversation history is unavailable in this folder.');
6154
6205
  await persistenceTailRef.current;
6155
6206
  const forked = await manager.fork(scope.sessionId, label);
6156
- notice(`Forked ${forked.copied} messages into ${forked.title}. Open the new checkout in a new terminal: ${worktreeOpenHint(forked.path, forked.conversationId)}${forked.sourceDirty ? '\nUncommitted files stayed in this checkout.' : ''}`);
6207
+ notice(`Forked ${forked.copied} messages into ${displayConversationTitle(forked.title)}. Open the new checkout in a new terminal: ${worktreeOpenHint(forked.path, forked.conversationId)}${forked.sourceDirty ? '\nUncommitted files stayed in this checkout.' : ''}`);
6157
6208
  }
6158
6209
  else if (label) {
6159
6210
  const target = await manager.resume(label);
@@ -6705,6 +6756,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
6705
6756
  pushMessage('system', text);
6706
6757
  },
6707
6758
  ask: askQuestion,
6759
+ review: reviewSchedule,
6708
6760
  askPermission: onPermission,
6709
6761
  submit: (text, createdBy) => handleSubmit(text, undefined, 'submit', {
6710
6762
  source: createdBy === 'operator' ? 'operator-loop' : 'model-loop',
@@ -6943,7 +6995,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
6943
6995
  if (ups.length === 0)
6944
6996
  return;
6945
6997
  const lines = ups.map((u) => ` • ${u.name} ${u.current} → ${u.latest} (${u.how})`);
6946
- pushMessage('system', `⬆ Update available:\n${lines.join('\n')}`);
6998
+ pushMessage('system', `Update available:\n${lines.join('\n')}`);
6947
6999
  });
6948
7000
  }, [phase, ctx.version, pushMessage]);
6949
7001
  const hydrateFromPicker = useCallback(async (prefs, detectedNow, signal, options = {}) => {
@@ -7064,7 +7116,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
7064
7116
  // The save-skill screen owns its keys, Esc and Ctrl+C included: neither
7065
7117
  // may interrupt the turn that is waiting on its answer. A permission
7066
7118
  // request (an agent's, say) takes the screen over it and gets the keys.
7067
- if (saveSkillPromptRef.current && permission === null)
7119
+ if ((saveSkillPromptRef.current || scheduleReviewPromptRef.current) && permission === null)
7068
7120
  return;
7069
7121
  // Startup has refused admission, so there is no draft or active turn to
7070
7122
  // protect with the ready screen's two-press exit ladder.
@@ -7655,6 +7707,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
7655
7707
  ? subagents.find((agent) => agent.viewId === agentSurface.selectedId)
7656
7708
  : undefined;
7657
7709
  const lifecycleOwnsViewport = outputViewer !== null ||
7710
+ scheduleReviewPrompt !== null ||
7658
7711
  phase === 'trust' ||
7659
7712
  phase === 'resume' ||
7660
7713
  phase === 'unarchive' ||
@@ -7669,6 +7722,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
7669
7722
  textPrompt === null &&
7670
7723
  choicePicker === null &&
7671
7724
  copyPicker === null &&
7725
+ scheduleReviewPrompt === null &&
7672
7726
  agentSurface === null
7673
7727
  ? goalStatusLabel(goalStatus, goalStatus ? goalActivation.isArmed(goalStatus.sessionId, goalStatus) : false)
7674
7728
  : null;
@@ -7687,33 +7741,35 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
7687
7741
  ? 'starting a fresh conversation — input is paused'
7688
7742
  : compacting
7689
7743
  ? 'compacting conversation — input is paused'
7690
- : saveSkillPrompt
7691
- ? 'save skill — ←/→ choose · enter apply · esc cancel'
7692
- : permission
7693
- ? hintForPhase(phase, state, session?.hasProvider === true)
7694
- : agentSurface?.kind === 'cockpit'
7695
- ? agentSurface.focus === 'workflows'
7696
- ? 'workflows — enter select · esc return'
7697
- : agentSurface.focus === 'phases'
7698
- ? 'agent phases — enter agents · esc return'
7699
- : 'agents — enter inspect · left phases · esc return'
7700
- : agentSurface?.kind === 'transcript'
7701
- ? 'observing agent — esc agents · q parent'
7702
- : textPrompt
7703
- ? 'editor open · enter apply · esc cancel'
7704
- : choicePicker
7705
- ? choicePickerSearchable(choicePicker)
7706
- ? 'type to filter · ↑↓ select · enter apply · esc back'
7707
- : effortSlider
7708
- ? '←/→ adjust · 1–9 select · enter apply · esc back'
7709
- : '↑↓ / 1–9 select · enter apply · esc back'
7710
- : copyPicker
7711
- ? 'copy target open — ↑↓ / 1–9 select · esc cancel'
7712
- : handoffPark && phase === 'ready' && state === 'idle' && !composerHasDraft
7713
- ? 'enter continue · esc stop'
7714
- : goalStatus && phase === 'ready' && state === 'idle'
7715
- ? undefined
7716
- : hintForPhase(phase, state, session?.hasProvider === true, composerHasDraft);
7744
+ : permission
7745
+ ? hintForPhase(phase, state, session?.hasProvider === true)
7746
+ : scheduleReviewPrompt
7747
+ ? 'review schedule — ↑/↓ scroll · ←/→ choose · enter apply · esc cancel'
7748
+ : saveSkillPrompt
7749
+ ? 'save skill — ←/→ choose · enter apply · esc cancel'
7750
+ : agentSurface?.kind === 'cockpit'
7751
+ ? agentSurface.focus === 'workflows'
7752
+ ? 'workflows — enter select · esc return'
7753
+ : agentSurface.focus === 'phases'
7754
+ ? 'agent phases — enter agents · esc return'
7755
+ : 'agents — enter inspect · left phases · esc return'
7756
+ : agentSurface?.kind === 'transcript'
7757
+ ? 'observing agent — esc agents · q parent'
7758
+ : textPrompt
7759
+ ? 'editor open · enter apply · esc cancel'
7760
+ : choicePicker
7761
+ ? choicePickerSearchable(choicePicker)
7762
+ ? 'type to filter · ↑↓ select · enter apply · esc back'
7763
+ : effortSlider
7764
+ ? '←/→ adjust · 1–9 select · enter apply · esc back'
7765
+ : '↑↓ / 1–9 select · enter apply · esc back'
7766
+ : copyPicker
7767
+ ? 'copy target open — ↑↓ / 1–9 select · esc cancel'
7768
+ : handoffPark && phase === 'ready' && state === 'idle' && !composerHasDraft
7769
+ ? 'enter continue · esc stop'
7770
+ : goalStatus && phase === 'ready' && state === 'idle'
7771
+ ? undefined
7772
+ : hintForPhase(phase, state, session?.hasProvider === true, composerHasDraft);
7717
7773
  const permissionSource = reviewSource(permission, scopeRef.current?.sessionId);
7718
7774
  const permissionOwner = permissionSource
7719
7775
  ? subagents.find((agent) => agent.sessionId === permissionSource)
@@ -7770,19 +7826,21 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
7770
7826
  // where it is decided rather than guessed on the screen: with no
7771
7827
  // session behind the picker, esc exits namzu and the footer says
7772
7828
  // so instead of offering a cancel nobody will see.
7773
- cancelExits: !session?.hasProvider })) : (_jsxs(_Fragment, { children: [agentSurface === null && outputViewer === null ? (_jsx(LiveActivity, { compact: compactWork, activeTools: visibleActiveTools, working: state === 'thinking' || state === 'tool', interruptible: abortRef.current !== null, animate: stdout.isTTY === true &&
7829
+ cancelExits: !session?.hasProvider })) : (_jsxs(_Fragment, { children: [agentSurface === null && outputViewer === null && scheduleReviewPrompt === null ? (_jsx(LiveActivity, { compact: compactWork, activeTools: visibleActiveTools, working: state === 'thinking' || state === 'tool', interruptible: abortRef.current !== null, animate: stdout.isTTY === true &&
7774
7830
  permission === null &&
7775
7831
  textPrompt === null &&
7776
- saveSkillPrompt === null, thinking: thinking, tokens: turnTokens, waitingForYou: choicePicker !== null ||
7832
+ saveSkillPrompt === null &&
7833
+ scheduleReviewPrompt === null, thinking: thinking, tokens: turnTokens, waitingForYou: choicePicker !== null ||
7777
7834
  permission !== null ||
7778
7835
  textPrompt !== null ||
7779
- saveSkillPrompt !== null })) : null, agentSurface === null && outputViewer === null && permission === null ? (_jsx(TaskList, { tasks: liveTasks })) : null, permission ? (_jsx(PermissionOverlay, { toolCalls: permission.toolCalls, review: permission.review, summary: permission.summary, detailsOpen: permissionDetailsOpen, reviewOffset: permissionReviewOffset, choice: permissionChoice, queuedCount: queuedPermissionCount, sourceLabel: permissionSourceLabel, columns: terminal.columns, rows: terminal.rows, batchOnly: permission.batchOnly === true, siteNotes: permission.siteNotes, ...(permission.screenConsent === true
7836
+ saveSkillPrompt !== null ||
7837
+ scheduleReviewPrompt !== null })) : null, agentSurface === null && outputViewer === null && permission === null && scheduleReviewPrompt === null ? (_jsx(TaskList, { tasks: liveTasks })) : null, permission ? (_jsx(PermissionOverlay, { toolCalls: permission.toolCalls, review: permission.review, summary: permission.summary, detailsOpen: permissionDetailsOpen, reviewOffset: permissionReviewOffset, choice: permissionChoice, queuedCount: queuedPermissionCount, sourceLabel: permissionSourceLabel, columns: terminal.columns, rows: terminal.rows, batchOnly: permission.batchOnly === true, siteNotes: permission.siteNotes, ...(permission.screenConsent === true
7780
7838
  ? { screenConsent: { provider: session?.providerSummary ?? null } }
7781
- : {}) })) : null, saveSkillPrompt && permission === null ? (_jsx(SaveSkillOverlay, { request: saveSkillPrompt.request, cwd: ctx.cwd, columns: Math.max(1, (terminal.columns ?? 80) - 2), rows: terminal.rows, onAnswer: saveSkillPrompt.resolve }, saveSkillPrompt.request.markdown)) : null, textPrompt ? (_jsx(TextPrompt, { columns: Math.max(1, (terminal.columns ?? 80) - 2), title: textPrompt.title, placeholder: textPrompt.placeholder, initialValue: textPrompt.initialValue, emptyNotice: textPrompt.emptyNotice, hidden: permission !== null || (agentSurface !== null || outputViewer !== null), onSubmit: submitTextPrompt, onCancel: cancelTextPrompt }, textPrompt.token)) : permission === null &&
7839
+ : {}) })) : null, saveSkillPrompt && permission === null && scheduleReviewPrompt === null ? (_jsx(SaveSkillOverlay, { request: saveSkillPrompt.request, cwd: ctx.cwd, columns: Math.max(1, (terminal.columns ?? 80) - 2), rows: terminal.rows, onAnswer: saveSkillPrompt.resolve }, saveSkillPrompt.request.markdown)) : null, scheduleReviewPrompt && permission === null ? (_jsx(ScheduleReviewOverlay, { request: scheduleReviewPrompt.request, columns: Math.max(1, (terminal.columns ?? 80) - 2), rows: Math.max(1, (terminal.rows ?? 24) - 2), onAnswer: scheduleReviewPrompt.resolve }, scheduleReviewPrompt.token)) : null, textPrompt ? (_jsx(TextPrompt, { columns: Math.max(1, (terminal.columns ?? 80) - 2), title: textPrompt.title, placeholder: textPrompt.placeholder, initialValue: textPrompt.initialValue, emptyNotice: textPrompt.emptyNotice, hidden: permission !== null || scheduleReviewPrompt !== null || (agentSurface !== null || outputViewer !== null), onSubmit: submitTextPrompt, onCancel: cancelTextPrompt }, textPrompt.token)) : permission === null && scheduleReviewPrompt === null &&
7782
7840
  agentSurface === null &&
7783
7841
  outputViewer === null &&
7784
7842
  choicePicker?.kind === 'reasoning-effort' &&
7785
- effortSlider ? (_jsx(EffortSlider, { title: choicePicker.title, notice: choicePicker.notice, options: choicePicker.options, selected: selectedChoice, layout: effortSlider, columns: Math.max(1, (terminal.columns ?? 80) - 2) })) : permission === null && agentSurface === null && outputViewer === null && choicePicker ? (_jsx(ChoicePicker, { busy: 'busy' in choicePicker && choicePicker.busy === true, columns: Math.max(1, (terminal.columns ?? 80) - 2), title: choicePicker.title, notice: choicePicker.notice, options: filterChoiceOptions(choicePicker.options, choiceQuery), query: choicePickerSearchable(choicePicker) ? choiceQuery : undefined, selected: selectedChoice, windowSize: choicePicker.kind === 'command' ? choicePicker.windowSize : undefined })) : permission === null && agentSurface === null && outputViewer === null && copyPicker ? (_jsx(CopyPicker, { targets: copyPicker.targets, selected: selectedCopy })) : null, _jsxs(ComposerFrame, { working: state === 'thinking' || state === 'tool' || visibleActiveTools.length > 0, ...(hypermode ? { mode: HYPERMODE } : {}), focus: phase === 'ready' &&
7843
+ effortSlider ? (_jsx(EffortSlider, { title: choicePicker.title, notice: choicePicker.notice, options: choicePicker.options, selected: selectedChoice, layout: effortSlider, columns: Math.max(1, (terminal.columns ?? 80) - 2) })) : permission === null && scheduleReviewPrompt === null && agentSurface === null && outputViewer === null && choicePicker ? (_jsx(ChoicePicker, { busy: 'busy' in choicePicker && choicePicker.busy === true, columns: Math.max(1, (terminal.columns ?? 80) - 2), title: choicePicker.title, notice: choicePicker.notice, options: filterChoiceOptions(choicePicker.options, choiceQuery), query: choicePickerSearchable(choicePicker) ? choiceQuery : undefined, selected: selectedChoice, windowSize: choicePicker.kind === 'command' ? choicePicker.windowSize : undefined })) : permission === null && scheduleReviewPrompt === null && agentSurface === null && outputViewer === null && copyPicker ? (_jsx(CopyPicker, { targets: copyPicker.targets, selected: selectedCopy })) : null, _jsxs(ComposerFrame, { working: state === 'thinking' || state === 'tool' || visibleActiveTools.length > 0, ...(hypermode ? { mode: HYPERMODE } : {}), activation: hypermodeActivation, animate: externalEditorRequest === null, focus: phase === 'ready' &&
7786
7844
  state !== 'awaiting-permission' &&
7787
7845
  !compacting &&
7788
7846
  externalEditorRequest === null &&
@@ -7791,8 +7849,10 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
7791
7849
  choicePicker === null &&
7792
7850
  copyPicker === null &&
7793
7851
  saveSkillPrompt === null &&
7852
+ scheduleReviewPrompt === null &&
7794
7853
  agentSurface === null && outputViewer === null, hidden: permission !== null ||
7795
7854
  saveSkillPrompt !== null ||
7855
+ scheduleReviewPrompt !== null ||
7796
7856
  textPrompt !== null ||
7797
7857
  choicePicker !== null ||
7798
7858
  copyPicker !== null ||
@@ -7818,6 +7878,7 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
7818
7878
  externalEditorRequest !== null ||
7819
7879
  (agentSurface !== null || outputViewer !== null), hidden: permission !== null ||
7820
7880
  saveSkillPrompt !== null ||
7881
+ scheduleReviewPrompt !== null ||
7821
7882
  textPrompt !== null ||
7822
7883
  choicePicker !== null ||
7823
7884
  copyPicker !== null ||
@@ -7834,17 +7895,19 @@ export function App({ ctx: initialCtx, onExitSummary, externalEditor = defaultEx
7834
7895
  })), mentionCandidates: mentionCandidates, history: history, ...(composerTriggers ? { triggers: composerTriggers } : {}), turnActive: !compacting && (state === 'thinking' || state === 'tool') })] })] })), _jsx(StatusBar, { cwd: ctx.cwd, provider: session?.providerSummary ?? null, model: session?.modelSummary ?? null, effort: reasoningEffort, hypermode: hypermode, goal: statusGoal, state: state, hint: statusHint, permissionMode: displayedPermissionMode, canCycleMode: true }), showComposerSurface &&
7835
7896
  permission === null &&
7836
7897
  agentSurface === null &&
7837
- outputViewer === null ? (_jsx(AgentNarrationBand, { lines: narration })) : null, showComposerSurface &&
7898
+ outputViewer === null &&
7899
+ scheduleReviewPrompt === null ? (_jsx(AgentNarrationBand, { lines: narration })) : null, showComposerSurface &&
7838
7900
  agentSurface === null &&
7839
7901
  outputViewer === null &&
7902
+ scheduleReviewPrompt === null &&
7840
7903
  liveSubagents.length > 0 ? (
7841
- // Still drawn while a review is open, reduced to its header line:
7842
- // the work already approved keeps moving, and the operator
7843
- // deciding the next launch should be able to see that it does.
7844
- _jsx(AgentTaskPanel, { agents: liveSubagents, terminalRows: terminal.rows, terminalColumns: terminal.columns, compact: permission !== null })) : showComposerSurface && permission === null && agentSurface?.kind === 'cockpit' ? (_jsx(AgentCockpit, { agents: subagents, selectedPhaseId: agentSurface.selectedPhaseId, selectedId: agentSurface.selectedId, focus: agentSurface.focus, terminalRows: terminal.rows, terminalColumns: terminal.columns })) : showComposerSurface &&
7904
+ // The active agents remain in memory while the schedule review
7905
+ // owns the available rows; the panel returns after the decision.
7906
+ _jsx(AgentTaskPanel, { agents: liveSubagents, terminalRows: terminal.rows, terminalColumns: terminal.columns, compact: permission !== null })) : showComposerSurface && permission === null && scheduleReviewPrompt === null && agentSurface?.kind === 'cockpit' ? (_jsx(AgentCockpit, { agents: subagents, selectedPhaseId: agentSurface.selectedPhaseId, selectedId: agentSurface.selectedId, focus: agentSurface.focus, terminalRows: terminal.rows, terminalColumns: terminal.columns })) : showComposerSurface &&
7845
7907
  permission === null &&
7908
+ scheduleReviewPrompt === null &&
7846
7909
  agentSurface?.kind === 'transcript' &&
7847
- selectedSubagent ? (_jsx(AgentTranscript, { agent: selectedSubagent, tailOffset: agentSurface.tailOffset, terminalRows: terminal.rows, terminalColumns: terminal.columns })) : null, outputViewer && permission === null ? (_jsx(ToolOutputViewer, { onPrevious: () => {
7910
+ selectedSubagent ? (_jsx(AgentTranscript, { agent: selectedSubagent, tailOffset: agentSurface.tailOffset, terminalRows: terminal.rows, terminalColumns: terminal.columns })) : null, outputViewer && permission === null && scheduleReviewPrompt === null ? (_jsx(ToolOutputViewer, { onPrevious: () => {
7848
7911
  if (outputIndex > 0)
7849
7912
  setOutputViewer(outputBlocks[outputIndex - 1]);
7850
7913
  }, onNext: () => {