@dexto/tui 1.13.5 → 1.14.0

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 (72) hide show
  1. package/dist/agent-backend.cjs +2 -0
  2. package/dist/agent-backend.d.ts +2 -0
  3. package/dist/agent-backend.d.ts.map +1 -1
  4. package/dist/agent-backend.js +2 -0
  5. package/dist/components/ApprovalPrompt.cjs +19 -17
  6. package/dist/components/ApprovalPrompt.d.ts +2 -1
  7. package/dist/components/ApprovalPrompt.d.ts.map +1 -1
  8. package/dist/components/ApprovalPrompt.js +19 -17
  9. package/dist/components/ApprovalPrompt.test.cjs +119 -0
  10. package/dist/components/ApprovalPrompt.test.d.ts +2 -0
  11. package/dist/components/ApprovalPrompt.test.d.ts.map +1 -0
  12. package/dist/components/ApprovalPrompt.test.js +120 -0
  13. package/dist/components/Footer.cjs +5 -1
  14. package/dist/components/Footer.d.ts.map +1 -1
  15. package/dist/components/Footer.js +5 -1
  16. package/dist/components/Footer.test.cjs +47 -0
  17. package/dist/components/Footer.test.d.ts +2 -0
  18. package/dist/components/Footer.test.d.ts.map +1 -0
  19. package/dist/components/Footer.test.js +46 -0
  20. package/dist/components/modes/AlternateBufferCLI.cjs +3 -1
  21. package/dist/components/modes/AlternateBufferCLI.d.ts.map +1 -1
  22. package/dist/components/modes/AlternateBufferCLI.js +3 -1
  23. package/dist/components/modes/StaticCLI.cjs +3 -1
  24. package/dist/components/modes/StaticCLI.d.ts.map +1 -1
  25. package/dist/components/modes/StaticCLI.js +3 -1
  26. package/dist/components/overlays/PermissionsSelector.cjs +139 -0
  27. package/dist/components/overlays/PermissionsSelector.d.ts +16 -0
  28. package/dist/components/overlays/PermissionsSelector.d.ts.map +1 -0
  29. package/dist/components/overlays/PermissionsSelector.js +115 -0
  30. package/dist/components/overlays/PermissionsSelector.test.cjs +105 -0
  31. package/dist/components/overlays/PermissionsSelector.test.d.ts +2 -0
  32. package/dist/components/overlays/PermissionsSelector.test.d.ts.map +1 -0
  33. package/dist/components/overlays/PermissionsSelector.test.js +104 -0
  34. package/dist/containers/InputContainer.cjs +108 -28
  35. package/dist/containers/InputContainer.d.ts +1 -0
  36. package/dist/containers/InputContainer.d.ts.map +1 -1
  37. package/dist/containers/InputContainer.js +108 -28
  38. package/dist/containers/OverlayContainer.cjs +15 -0
  39. package/dist/containers/OverlayContainer.d.ts.map +1 -1
  40. package/dist/containers/OverlayContainer.js +17 -0
  41. package/dist/hooks/useAgentEvents.cjs +6 -3
  42. package/dist/hooks/useAgentEvents.d.ts.map +1 -1
  43. package/dist/hooks/useAgentEvents.js +6 -3
  44. package/dist/hooks/useCLIState.cjs +28 -8
  45. package/dist/hooks/useCLIState.d.ts +1 -0
  46. package/dist/hooks/useCLIState.d.ts.map +1 -1
  47. package/dist/hooks/useCLIState.js +28 -8
  48. package/dist/hooks/useCLIState.test.cjs +583 -0
  49. package/dist/hooks/useCLIState.test.d.ts +2 -0
  50. package/dist/hooks/useCLIState.test.d.ts.map +1 -0
  51. package/dist/hooks/useCLIState.test.js +582 -0
  52. package/dist/index.d.cts +2 -0
  53. package/dist/interactive-commands/commands.test.cjs +6 -0
  54. package/dist/interactive-commands/commands.test.js +6 -0
  55. package/dist/interactive-commands/tool-commands.cjs +7 -0
  56. package/dist/interactive-commands/tool-commands.d.ts.map +1 -1
  57. package/dist/interactive-commands/tool-commands.js +7 -0
  58. package/dist/services/processStream.cjs +4 -2
  59. package/dist/services/processStream.d.ts.map +1 -1
  60. package/dist/services/processStream.js +4 -2
  61. package/dist/services/processStream.test.cjs +63 -0
  62. package/dist/services/processStream.test.js +63 -0
  63. package/dist/state/types.d.ts +1 -1
  64. package/dist/state/types.d.ts.map +1 -1
  65. package/dist/utils/approvalScope.cjs +35 -0
  66. package/dist/utils/approvalScope.d.ts +3 -0
  67. package/dist/utils/approvalScope.d.ts.map +1 -0
  68. package/dist/utils/approvalScope.js +11 -0
  69. package/dist/utils/commandOverlays.cjs +1 -0
  70. package/dist/utils/commandOverlays.d.ts.map +1 -1
  71. package/dist/utils/commandOverlays.js +1 -0
  72. package/package.json +5 -5
@@ -50,6 +50,7 @@ const InputContainer = (0, import_react.forwardRef)(
50
50
  ui,
51
51
  session,
52
52
  initialPrompt,
53
+ isHydratingHistory,
53
54
  approval,
54
55
  steerMessages,
55
56
  queuedMessages,
@@ -74,6 +75,14 @@ const InputContainer = (0, import_react.forwardRef)(
74
75
  const queuedEditPendingRef = (0, import_react.useRef)(false);
75
76
  const [isQueuedEditPending, setIsQueuedEditPending] = import_react.default.useState(false);
76
77
  const didAutoSubmitInitialPromptRef = (0, import_react.useRef)(false);
78
+ const initialPromptSessionIdRef = (0, import_react.useRef)(session.id);
79
+ const [isSubmittingInitialPrompt, setIsSubmittingInitialPrompt] = import_react.default.useState(
80
+ Boolean(initialPrompt)
81
+ );
82
+ const [deferredSubmissions, setDeferredSubmissions] = import_react.default.useState(
83
+ []
84
+ );
85
+ const isSubmittingDeferredRef = (0, import_react.useRef)(false);
77
86
  const soundService = (0, import_contexts.useSoundService)();
78
87
  const autoApproveEditsRef = (0, import_react.useRef)(ui.autoApproveEdits);
79
88
  (0, import_react.useEffect)(() => {
@@ -397,38 +406,70 @@ const InputContainer = (0, import_react.forwardRef)(
397
406
  return result;
398
407
  }, []);
399
408
  const handleSubmit = (0, import_react.useCallback)(
400
- async (value, bypassOverlayCheck = false, queueAsFollowUp = false) => {
401
- const expandedValue = expandPasteBlocks(value, input.pastedBlocks);
409
+ async (value, bypassOverlayCheck = false, queueAsFollowUp = false, submittedInput) => {
410
+ if (!submittedInput && (isHydratingHistory || deferredSubmissions.length > 0)) {
411
+ if (!value.trim()) return;
412
+ if (!bypassOverlayCheck && ui.activeOverlay !== "none" && ui.activeOverlay !== "approval")
413
+ return;
414
+ const completion = new Promise((resolve, reject) => {
415
+ setDeferredSubmissions((previous) => [
416
+ ...previous,
417
+ {
418
+ value,
419
+ input,
420
+ sessionId: session.id,
421
+ queueAsFollowUp,
422
+ resolve,
423
+ reject
424
+ }
425
+ ]);
426
+ });
427
+ buffer.setText("");
428
+ setInput((previous) => ({
429
+ ...previous,
430
+ value: "",
431
+ images: [],
432
+ pastedBlocks: [],
433
+ historyIndex: -1,
434
+ draftBeforeHistory: "",
435
+ editingQueuedFollowUp: false
436
+ }));
437
+ return completion;
438
+ }
439
+ const composer = submittedInput ?? input;
440
+ const expandedValue = expandPasteBlocks(value, composer.pastedBlocks);
402
441
  const trimmed = expandedValue.trim();
403
442
  if (!trimmed) return;
404
443
  if (ui.isProcessing && session.id) {
405
444
  const content = [{ type: "text", text: trimmed }];
406
- for (const img of input.images) {
445
+ for (const img of composer.images) {
407
446
  content.push({
408
447
  type: "image",
409
448
  image: img.data,
410
449
  mimeType: img.mimeType
411
450
  });
412
451
  }
413
- const submitAsFollowUp = queueAsFollowUp || input.editingQueuedFollowUp;
452
+ const submitAsFollowUp = queueAsFollowUp || composer.editingQueuedFollowUp;
414
453
  try {
415
454
  if (submitAsFollowUp) {
416
455
  await agent.followUp(session.id, { content });
417
456
  } else {
418
457
  await agent.steer(session.id, { content });
419
458
  }
420
- buffer.setText("");
459
+ if (!submittedInput) buffer.setText("");
421
460
  setInput((prev) => {
422
461
  const newHistory = prev.history.length > 0 && prev.history[prev.history.length - 1] === trimmed ? prev.history : [...prev.history, trimmed].slice(-100);
423
462
  return {
424
463
  ...prev,
425
- value: "",
464
+ ...submittedInput ? {} : {
465
+ value: "",
466
+ images: [],
467
+ pastedBlocks: [],
468
+ editingQueuedFollowUp: false,
469
+ draftBeforeHistory: ""
470
+ },
426
471
  history: newHistory,
427
- historyIndex: -1,
428
- draftBeforeHistory: "",
429
- editingQueuedFollowUp: false,
430
- images: [],
431
- pastedBlocks: []
472
+ historyIndex: -1
432
473
  };
433
474
  });
434
475
  } catch (error) {
@@ -447,24 +488,23 @@ const InputContainer = (0, import_react.forwardRef)(
447
488
  if (!bypassOverlayCheck && ui.activeOverlay !== "none" && ui.activeOverlay !== "approval") {
448
489
  return;
449
490
  }
450
- const pendingImages = [...input.images];
491
+ const pendingImages = [...composer.images];
451
492
  const userMessage = (0, import_messageFormatting.createUserMessage)(trimmed);
452
493
  setMessages((prev) => [...prev, userMessage]);
453
- buffer.setText("");
494
+ if (!submittedInput) buffer.setText("");
454
495
  setInput((prev) => {
455
496
  const newHistory = prev.history.length > 0 && prev.history[prev.history.length - 1] === trimmed ? prev.history : [...prev.history, trimmed].slice(-100);
456
497
  return {
457
- value: "",
498
+ ...prev,
499
+ ...submittedInput ? {} : {
500
+ value: "",
501
+ images: [],
502
+ pastedBlocks: [],
503
+ editingQueuedFollowUp: false,
504
+ draftBeforeHistory: ""
505
+ },
458
506
  history: newHistory,
459
- historyIndex: -1,
460
- draftBeforeHistory: "",
461
- editingQueuedFollowUp: false,
462
- images: [],
463
- // Clear images on submit
464
- pastedBlocks: [],
465
- // Clear paste blocks on submit
466
- pasteCounter: prev.pasteCounter
467
- // Keep counter for next session
507
+ historyIndex: -1
468
508
  };
469
509
  });
470
510
  setUi((prev) => ({
@@ -719,8 +759,9 @@ ${trimmed}`;
719
759
  },
720
760
  [
721
761
  buffer,
722
- input.images,
723
- input.pastedBlocks,
762
+ isHydratingHistory,
763
+ deferredSubmissions.length,
764
+ input,
724
765
  expandPasteBlocks,
725
766
  setInput,
726
767
  setUi,
@@ -742,11 +783,19 @@ ${trimmed}`;
742
783
  ]
743
784
  );
744
785
  (0, import_react.useEffect)(() => {
745
- if (!initialPrompt || didAutoSubmitInitialPromptRef.current) {
786
+ if (!initialPrompt || didAutoSubmitInitialPromptRef.current) return;
787
+ if (initialPromptSessionIdRef.current !== null && session.id !== initialPromptSessionIdRef.current) {
788
+ didAutoSubmitInitialPromptRef.current = true;
789
+ setIsSubmittingInitialPrompt(false);
746
790
  return;
747
791
  }
792
+ if (isHydratingHistory) return;
748
793
  didAutoSubmitInitialPromptRef.current = true;
749
- handleSubmit(initialPrompt, true).catch((error) => {
794
+ handleSubmit(initialPrompt, true, false, {
795
+ images: [],
796
+ pastedBlocks: [],
797
+ editingQueuedFollowUp: false
798
+ }).catch((error) => {
750
799
  agent.logger.error("InputContainer initial prompt submission failed", {
751
800
  error,
752
801
  initialPrompt
@@ -760,8 +809,39 @@ ${trimmed}`;
760
809
  timestamp: /* @__PURE__ */ new Date()
761
810
  }
762
811
  ]);
812
+ }).finally(() => setIsSubmittingInitialPrompt(false));
813
+ }, [
814
+ agent.logger,
815
+ handleSubmit,
816
+ initialPrompt,
817
+ setMessages,
818
+ isHydratingHistory,
819
+ session.id
820
+ ]);
821
+ (0, import_react.useEffect)(() => {
822
+ const submission = deferredSubmissions[0];
823
+ if (isHydratingHistory || isSubmittingInitialPrompt || !submission || isSubmittingDeferredRef.current)
824
+ return;
825
+ isSubmittingDeferredRef.current = true;
826
+ const result = submission.sessionId === session.id ? handleSubmit(
827
+ submission.value,
828
+ true,
829
+ submission.queueAsFollowUp,
830
+ submission.input
831
+ ) : Promise.resolve();
832
+ result.then(submission.resolve, submission.reject).finally(() => {
833
+ isSubmittingDeferredRef.current = false;
834
+ setDeferredSubmissions(
835
+ (previous) => previous.filter((item) => item !== submission)
836
+ );
763
837
  });
764
- }, [agent.logger, handleSubmit, initialPrompt, setMessages]);
838
+ }, [
839
+ deferredSubmissions,
840
+ handleSubmit,
841
+ isHydratingHistory,
842
+ isSubmittingInitialPrompt,
843
+ session.id
844
+ ]);
765
845
  const mainInputAllowedOverlays = ["none", "slash-autocomplete", "resource-autocomplete"];
766
846
  const mainInputAllowed = mainInputAllowedOverlays.includes(ui.activeOverlay);
767
847
  const isHistorySearchActive = ui.historySearch.isActive;
@@ -25,6 +25,7 @@ interface InputContainerProps {
25
25
  session: SessionState;
26
26
  /** If provided, auto-submits once when the UI is ready */
27
27
  initialPrompt?: string | undefined;
28
+ isHydratingHistory: boolean;
28
29
  approval: ApprovalRequest | null;
29
30
  /** Active-turn input waiting for the next executor boundary */
30
31
  steerMessages: QueuedMessage[];
@@ -1 +1 @@
1
- {"version":3,"file":"InputContainer.d.ts","sourceRoot":"","sources":["../../src/containers/InputContainer.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"InputContainer.d.ts","sourceRoot":"","sources":["../../src/containers/InputContainer.tsx"],"names":[],"mappings":"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"}
@@ -21,6 +21,7 @@ const InputContainer = forwardRef(
21
21
  ui,
22
22
  session,
23
23
  initialPrompt,
24
+ isHydratingHistory,
24
25
  approval,
25
26
  steerMessages,
26
27
  queuedMessages,
@@ -45,6 +46,14 @@ const InputContainer = forwardRef(
45
46
  const queuedEditPendingRef = useRef(false);
46
47
  const [isQueuedEditPending, setIsQueuedEditPending] = React.useState(false);
47
48
  const didAutoSubmitInitialPromptRef = useRef(false);
49
+ const initialPromptSessionIdRef = useRef(session.id);
50
+ const [isSubmittingInitialPrompt, setIsSubmittingInitialPrompt] = React.useState(
51
+ Boolean(initialPrompt)
52
+ );
53
+ const [deferredSubmissions, setDeferredSubmissions] = React.useState(
54
+ []
55
+ );
56
+ const isSubmittingDeferredRef = useRef(false);
48
57
  const soundService = useSoundService();
49
58
  const autoApproveEditsRef = useRef(ui.autoApproveEdits);
50
59
  useEffect(() => {
@@ -368,38 +377,70 @@ const InputContainer = forwardRef(
368
377
  return result;
369
378
  }, []);
370
379
  const handleSubmit = useCallback(
371
- async (value, bypassOverlayCheck = false, queueAsFollowUp = false) => {
372
- const expandedValue = expandPasteBlocks(value, input.pastedBlocks);
380
+ async (value, bypassOverlayCheck = false, queueAsFollowUp = false, submittedInput) => {
381
+ if (!submittedInput && (isHydratingHistory || deferredSubmissions.length > 0)) {
382
+ if (!value.trim()) return;
383
+ if (!bypassOverlayCheck && ui.activeOverlay !== "none" && ui.activeOverlay !== "approval")
384
+ return;
385
+ const completion = new Promise((resolve, reject) => {
386
+ setDeferredSubmissions((previous) => [
387
+ ...previous,
388
+ {
389
+ value,
390
+ input,
391
+ sessionId: session.id,
392
+ queueAsFollowUp,
393
+ resolve,
394
+ reject
395
+ }
396
+ ]);
397
+ });
398
+ buffer.setText("");
399
+ setInput((previous) => ({
400
+ ...previous,
401
+ value: "",
402
+ images: [],
403
+ pastedBlocks: [],
404
+ historyIndex: -1,
405
+ draftBeforeHistory: "",
406
+ editingQueuedFollowUp: false
407
+ }));
408
+ return completion;
409
+ }
410
+ const composer = submittedInput ?? input;
411
+ const expandedValue = expandPasteBlocks(value, composer.pastedBlocks);
373
412
  const trimmed = expandedValue.trim();
374
413
  if (!trimmed) return;
375
414
  if (ui.isProcessing && session.id) {
376
415
  const content = [{ type: "text", text: trimmed }];
377
- for (const img of input.images) {
416
+ for (const img of composer.images) {
378
417
  content.push({
379
418
  type: "image",
380
419
  image: img.data,
381
420
  mimeType: img.mimeType
382
421
  });
383
422
  }
384
- const submitAsFollowUp = queueAsFollowUp || input.editingQueuedFollowUp;
423
+ const submitAsFollowUp = queueAsFollowUp || composer.editingQueuedFollowUp;
385
424
  try {
386
425
  if (submitAsFollowUp) {
387
426
  await agent.followUp(session.id, { content });
388
427
  } else {
389
428
  await agent.steer(session.id, { content });
390
429
  }
391
- buffer.setText("");
430
+ if (!submittedInput) buffer.setText("");
392
431
  setInput((prev) => {
393
432
  const newHistory = prev.history.length > 0 && prev.history[prev.history.length - 1] === trimmed ? prev.history : [...prev.history, trimmed].slice(-100);
394
433
  return {
395
434
  ...prev,
396
- value: "",
435
+ ...submittedInput ? {} : {
436
+ value: "",
437
+ images: [],
438
+ pastedBlocks: [],
439
+ editingQueuedFollowUp: false,
440
+ draftBeforeHistory: ""
441
+ },
397
442
  history: newHistory,
398
- historyIndex: -1,
399
- draftBeforeHistory: "",
400
- editingQueuedFollowUp: false,
401
- images: [],
402
- pastedBlocks: []
443
+ historyIndex: -1
403
444
  };
404
445
  });
405
446
  } catch (error) {
@@ -418,24 +459,23 @@ const InputContainer = forwardRef(
418
459
  if (!bypassOverlayCheck && ui.activeOverlay !== "none" && ui.activeOverlay !== "approval") {
419
460
  return;
420
461
  }
421
- const pendingImages = [...input.images];
462
+ const pendingImages = [...composer.images];
422
463
  const userMessage = createUserMessage(trimmed);
423
464
  setMessages((prev) => [...prev, userMessage]);
424
- buffer.setText("");
465
+ if (!submittedInput) buffer.setText("");
425
466
  setInput((prev) => {
426
467
  const newHistory = prev.history.length > 0 && prev.history[prev.history.length - 1] === trimmed ? prev.history : [...prev.history, trimmed].slice(-100);
427
468
  return {
428
- value: "",
469
+ ...prev,
470
+ ...submittedInput ? {} : {
471
+ value: "",
472
+ images: [],
473
+ pastedBlocks: [],
474
+ editingQueuedFollowUp: false,
475
+ draftBeforeHistory: ""
476
+ },
429
477
  history: newHistory,
430
- historyIndex: -1,
431
- draftBeforeHistory: "",
432
- editingQueuedFollowUp: false,
433
- images: [],
434
- // Clear images on submit
435
- pastedBlocks: [],
436
- // Clear paste blocks on submit
437
- pasteCounter: prev.pasteCounter
438
- // Keep counter for next session
478
+ historyIndex: -1
439
479
  };
440
480
  });
441
481
  setUi((prev) => ({
@@ -690,8 +730,9 @@ ${trimmed}`;
690
730
  },
691
731
  [
692
732
  buffer,
693
- input.images,
694
- input.pastedBlocks,
733
+ isHydratingHistory,
734
+ deferredSubmissions.length,
735
+ input,
695
736
  expandPasteBlocks,
696
737
  setInput,
697
738
  setUi,
@@ -713,11 +754,19 @@ ${trimmed}`;
713
754
  ]
714
755
  );
715
756
  useEffect(() => {
716
- if (!initialPrompt || didAutoSubmitInitialPromptRef.current) {
757
+ if (!initialPrompt || didAutoSubmitInitialPromptRef.current) return;
758
+ if (initialPromptSessionIdRef.current !== null && session.id !== initialPromptSessionIdRef.current) {
759
+ didAutoSubmitInitialPromptRef.current = true;
760
+ setIsSubmittingInitialPrompt(false);
717
761
  return;
718
762
  }
763
+ if (isHydratingHistory) return;
719
764
  didAutoSubmitInitialPromptRef.current = true;
720
- handleSubmit(initialPrompt, true).catch((error) => {
765
+ handleSubmit(initialPrompt, true, false, {
766
+ images: [],
767
+ pastedBlocks: [],
768
+ editingQueuedFollowUp: false
769
+ }).catch((error) => {
721
770
  agent.logger.error("InputContainer initial prompt submission failed", {
722
771
  error,
723
772
  initialPrompt
@@ -731,8 +780,39 @@ ${trimmed}`;
731
780
  timestamp: /* @__PURE__ */ new Date()
732
781
  }
733
782
  ]);
783
+ }).finally(() => setIsSubmittingInitialPrompt(false));
784
+ }, [
785
+ agent.logger,
786
+ handleSubmit,
787
+ initialPrompt,
788
+ setMessages,
789
+ isHydratingHistory,
790
+ session.id
791
+ ]);
792
+ useEffect(() => {
793
+ const submission = deferredSubmissions[0];
794
+ if (isHydratingHistory || isSubmittingInitialPrompt || !submission || isSubmittingDeferredRef.current)
795
+ return;
796
+ isSubmittingDeferredRef.current = true;
797
+ const result = submission.sessionId === session.id ? handleSubmit(
798
+ submission.value,
799
+ true,
800
+ submission.queueAsFollowUp,
801
+ submission.input
802
+ ) : Promise.resolve();
803
+ result.then(submission.resolve, submission.reject).finally(() => {
804
+ isSubmittingDeferredRef.current = false;
805
+ setDeferredSubmissions(
806
+ (previous) => previous.filter((item) => item !== submission)
807
+ );
734
808
  });
735
- }, [agent.logger, handleSubmit, initialPrompt, setMessages]);
809
+ }, [
810
+ deferredSubmissions,
811
+ handleSubmit,
812
+ isHydratingHistory,
813
+ isSubmittingInitialPrompt,
814
+ session.id
815
+ ]);
736
816
  const mainInputAllowedOverlays = ["none", "slash-autocomplete", "resource-autocomplete"];
737
817
  const mainInputAllowed = mainInputAllowedOverlays.includes(ui.activeOverlay);
738
818
  const isHistorySearchActive = ui.historySearch.isActive;
@@ -45,6 +45,7 @@ var import_SessionSelectorRefactored = __toESM(require("../components/overlays/S
45
45
  var import_LogLevelSelector = __toESM(require("../components/overlays/LogLevelSelector.js"), 1);
46
46
  var import_StreamSelector = __toESM(require("../components/overlays/StreamSelector.js"), 1);
47
47
  var import_SoundsSelector = __toESM(require("../components/overlays/SoundsSelector.js"), 1);
48
+ var import_PermissionsSelector = require("../components/overlays/PermissionsSelector.js");
48
49
  var import_ToolBrowser = __toESM(require("../components/overlays/ToolBrowser.js"), 1);
49
50
  var import_CommandOutputOverlay = require("../components/overlays/CommandOutputOverlay.js");
50
51
  var import_McpServerList = __toESM(require("../components/overlays/McpServerList.js"), 1);
@@ -135,6 +136,7 @@ const OverlayContainer = (0, import_react.forwardRef)(
135
136
  const logLevelSelectorRef = (0, import_react.useRef)(null);
136
137
  const streamSelectorRef = (0, import_react.useRef)(null);
137
138
  const soundsSelectorRef = (0, import_react.useRef)(null);
139
+ const permissionsRef = (0, import_react.useRef)(null);
138
140
  const toolBrowserRef = (0, import_react.useRef)(null);
139
141
  const commandOutputRef = (0, import_react.useRef)(null);
140
142
  const mcpServerListRef = (0, import_react.useRef)(null);
@@ -207,6 +209,8 @@ const OverlayContainer = (0, import_react.forwardRef)(
207
209
  return streamSelectorRef.current?.handleInput(inputStr, key) ?? false;
208
210
  case "sounds-selector":
209
211
  return soundsSelectorRef.current?.handleInput(inputStr, key) ?? false;
212
+ case "permissions":
213
+ return permissionsRef.current?.handleInput(inputStr, key) ?? false;
210
214
  case "tool-browser":
211
215
  return toolBrowserRef.current?.handleInput(inputStr, key) ?? false;
212
216
  case "command-output":
@@ -2309,6 +2313,17 @@ Use /${data.name} to run it.`,
2309
2313
  onClose: handleClose
2310
2314
  }
2311
2315
  ) }),
2316
+ ui.activeOverlay === "permissions" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2317
+ import_PermissionsSelector.PermissionsSelector,
2318
+ {
2319
+ ref: permissionsRef,
2320
+ agent,
2321
+ sessionId: session.id,
2322
+ ui,
2323
+ setUi,
2324
+ onClose: handleClose
2325
+ }
2326
+ ) }),
2312
2327
  ui.activeOverlay === "tool-browser" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_ink.Box, { marginTop: 1, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
2313
2328
  import_ToolBrowser.default,
2314
2329
  {
@@ -1 +1 @@
1
- {"version":3,"file":"OverlayContainer.d.ts","sourceRoot":"","sources":["../../src/containers/OverlayContainer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAyE,MAAM,OAAO,CAAC;AAI9F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AAE5D,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAGH,KAAK,eAAe,EACvB,MAAM,iCAAiC,CAAC;AAmGzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAuC3D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAuC3D,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED,UAAU,qBAAqB;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC1E,KAAK,EAAE,eAAe,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,mDAAmD;IACnD,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,4EAA4E;IAC5E,qBAAqB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,sGA6+F5B,CAAC"}
1
+ {"version":3,"file":"OverlayContainer.d.ts","sourceRoot":"","sources":["../../src/containers/OverlayContainer.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAyE,MAAM,OAAO,CAAC;AAI9F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,kCAAkC,CAAC;AAE5D,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,EAGH,KAAK,eAAe,EACvB,MAAM,iCAAiC,CAAC;AAuGzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAuC3D,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAuC3D,MAAM,WAAW,sBAAsB;IACnC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC;CACrD;AAED,UAAU,qBAAqB;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,QAAQ,EAAE,eAAe,GAAG,IAAI,CAAC;IACjC,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC1E,KAAK,EAAE,eAAe,CAAC;IACvB,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,mDAAmD;IACnD,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,4EAA4E;IAC5E,qBAAqB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClE;AAED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,sGA6/F5B,CAAC"}
@@ -18,6 +18,9 @@ import SessionSelectorRefactored from "../components/overlays/SessionSelectorRef
18
18
  import LogLevelSelector from "../components/overlays/LogLevelSelector.js";
19
19
  import StreamSelector from "../components/overlays/StreamSelector.js";
20
20
  import SoundsSelector from "../components/overlays/SoundsSelector.js";
21
+ import {
22
+ PermissionsSelector
23
+ } from "../components/overlays/PermissionsSelector.js";
21
24
  import ToolBrowser from "../components/overlays/ToolBrowser.js";
22
25
  import {
23
26
  CommandOutputOverlay
@@ -115,6 +118,7 @@ const OverlayContainer = forwardRef(
115
118
  const logLevelSelectorRef = useRef(null);
116
119
  const streamSelectorRef = useRef(null);
117
120
  const soundsSelectorRef = useRef(null);
121
+ const permissionsRef = useRef(null);
118
122
  const toolBrowserRef = useRef(null);
119
123
  const commandOutputRef = useRef(null);
120
124
  const mcpServerListRef = useRef(null);
@@ -187,6 +191,8 @@ const OverlayContainer = forwardRef(
187
191
  return streamSelectorRef.current?.handleInput(inputStr, key) ?? false;
188
192
  case "sounds-selector":
189
193
  return soundsSelectorRef.current?.handleInput(inputStr, key) ?? false;
194
+ case "permissions":
195
+ return permissionsRef.current?.handleInput(inputStr, key) ?? false;
190
196
  case "tool-browser":
191
197
  return toolBrowserRef.current?.handleInput(inputStr, key) ?? false;
192
198
  case "command-output":
@@ -2289,6 +2295,17 @@ Use /${data.name} to run it.`,
2289
2295
  onClose: handleClose
2290
2296
  }
2291
2297
  ) }),
2298
+ ui.activeOverlay === "permissions" && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(
2299
+ PermissionsSelector,
2300
+ {
2301
+ ref: permissionsRef,
2302
+ agent,
2303
+ sessionId: session.id,
2304
+ ui,
2305
+ setUi,
2306
+ onClose: handleClose
2307
+ }
2308
+ ) }),
2292
2309
  ui.activeOverlay === "tool-browser" && /* @__PURE__ */ jsx(Box, { marginTop: 1, children: /* @__PURE__ */ jsx(
2293
2310
  ToolBrowser,
2294
2311
  {
@@ -43,6 +43,7 @@ function useAgentEvents({
43
43
  currentSessionId,
44
44
  buffer
45
45
  }) {
46
+ const { setText } = buffer;
46
47
  const externalTriggerRef = (0, import_react.useRef)({ active: false, sessionId: null, messageId: null });
47
48
  (0, import_react.useEffect)(() => {
48
49
  const controller = new AbortController();
@@ -51,6 +52,7 @@ function useAgentEvents({
51
52
  const syncQueue = (sessionId, queue) => {
52
53
  const getMessages = queue === "steer" ? agent.getSteerMessages(sessionId) : agent.getFollowUpMessages(sessionId);
53
54
  void getMessages.then((messages) => {
55
+ if (signal.aborted) return;
54
56
  if (queue === "steer") {
55
57
  setSteerMessages(messages);
56
58
  } else {
@@ -200,7 +202,7 @@ function useAgentEvents({
200
202
  setApprovalQueue([]);
201
203
  setSteerMessages([]);
202
204
  setQueuedMessages([]);
203
- buffer.setText("");
205
+ setText("");
204
206
  setInput((prev) => ({
205
207
  ...prev,
206
208
  value: "",
@@ -288,7 +290,7 @@ function useAgentEvents({
288
290
  agent.on(
289
291
  "message:queued",
290
292
  (payload) => {
291
- if (!payload.sessionId) return;
293
+ if (!payload.sessionId || payload.sessionId !== currentSessionId) return;
292
294
  syncQueue(payload.sessionId, payload.queue);
293
295
  },
294
296
  { signal }
@@ -304,6 +306,7 @@ function useAgentEvents({
304
306
  }
305
307
  return;
306
308
  }
309
+ if (payload.sessionId !== currentSessionId) return;
307
310
  syncQueue(payload.sessionId, payload.queue);
308
311
  },
309
312
  { signal }
@@ -430,7 +433,7 @@ function useAgentEvents({
430
433
  setSteerMessages,
431
434
  setQueuedMessages,
432
435
  currentSessionId,
433
- buffer
436
+ setText
434
437
  ]);
435
438
  }
436
439
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"file":"useAgentEvents.d.ts","sourceRoot":"","sources":["../../src/hooks/useAgentEvents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAqB,KAAK,aAAa,EAAoB,MAAM,aAAa,CAAC;AAEtF,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,UAAU,mBAAmB;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/D,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC1E,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACxE,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACzE,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iFAAiF;IACjF,MAAM,EAAE,UAAU,CAAC;CACtB;AAYD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAC3B,KAAK,EACL,WAAW,EACX,kBAAkB,EAClB,KAAK,EACL,UAAU,EACV,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,MAAM,GACT,EAAE,mBAAmB,GAAG,IAAI,CAgiB5B"}
1
+ {"version":3,"file":"useAgentEvents.d.ts","sourceRoot":"","sources":["../../src/hooks/useAgentEvents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,EAAqB,KAAK,aAAa,EAAoB,MAAM,aAAa,CAAC;AAEtF,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAEvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qCAAqC,CAAC;AACtE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,UAAU,mBAAmB;IACzB,KAAK,EAAE,eAAe,CAAC;IACvB,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,kBAAkB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACpE,KAAK,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;IACrD,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/D,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3D,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1E,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;IAC1E,gBAAgB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACxE,iBAAiB,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IACzE,8CAA8C;IAC9C,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iFAAiF;IACjF,MAAM,EAAE,UAAU,CAAC;CACtB;AAYD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,EAC3B,KAAK,EACL,WAAW,EACX,kBAAkB,EAClB,KAAK,EACL,UAAU,EACV,QAAQ,EACR,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,MAAM,GACT,EAAE,mBAAmB,GAAG,IAAI,CAsiB5B"}
@@ -20,6 +20,7 @@ function useAgentEvents({
20
20
  currentSessionId,
21
21
  buffer
22
22
  }) {
23
+ const { setText } = buffer;
23
24
  const externalTriggerRef = useRef({ active: false, sessionId: null, messageId: null });
24
25
  useEffect(() => {
25
26
  const controller = new AbortController();
@@ -28,6 +29,7 @@ function useAgentEvents({
28
29
  const syncQueue = (sessionId, queue) => {
29
30
  const getMessages = queue === "steer" ? agent.getSteerMessages(sessionId) : agent.getFollowUpMessages(sessionId);
30
31
  void getMessages.then((messages) => {
32
+ if (signal.aborted) return;
31
33
  if (queue === "steer") {
32
34
  setSteerMessages(messages);
33
35
  } else {
@@ -177,7 +179,7 @@ function useAgentEvents({
177
179
  setApprovalQueue([]);
178
180
  setSteerMessages([]);
179
181
  setQueuedMessages([]);
180
- buffer.setText("");
182
+ setText("");
181
183
  setInput((prev) => ({
182
184
  ...prev,
183
185
  value: "",
@@ -265,7 +267,7 @@ function useAgentEvents({
265
267
  agent.on(
266
268
  "message:queued",
267
269
  (payload) => {
268
- if (!payload.sessionId) return;
270
+ if (!payload.sessionId || payload.sessionId !== currentSessionId) return;
269
271
  syncQueue(payload.sessionId, payload.queue);
270
272
  },
271
273
  { signal }
@@ -281,6 +283,7 @@ function useAgentEvents({
281
283
  }
282
284
  return;
283
285
  }
286
+ if (payload.sessionId !== currentSessionId) return;
284
287
  syncQueue(payload.sessionId, payload.queue);
285
288
  },
286
289
  { signal }
@@ -407,7 +410,7 @@ function useAgentEvents({
407
410
  setSteerMessages,
408
411
  setQueuedMessages,
409
412
  currentSessionId,
410
- buffer
413
+ setText
411
414
  ]);
412
415
  }
413
416
  export {