@tylerl0706/ahpx 0.2.10 → 0.2.12

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.
package/dist/bin.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  createLogger,
12
12
  ensureFileUri,
13
13
  setVerbose
14
- } from "./chunk-646D2XNX.js";
14
+ } from "./chunk-7ZLDLPTX.js";
15
15
 
16
16
  // src/bin.ts
17
17
  import { randomUUID as randomUUID3 } from "crypto";
@@ -2453,7 +2453,7 @@ session.command("active").description("Show all active sessions on the server (l
2453
2453
  console.log(pc6.bold(`Active sessions on ${serverInfo.name}`), pc6.dim(`(${result.items.length})`));
2454
2454
  console.log();
2455
2455
  for (const s of result.items) {
2456
- const status = s.status === "in-progress" ? pc6.yellow("\u25CF in-progress") : s.status === "error" ? pc6.red("\u25CF error") : pc6.green("\u25CF idle");
2456
+ const status = s.status === 2 /* Error */ ? pc6.red("\u25CF error") : s.status === 24 /* InputNeeded */ ? pc6.yellow("\u25CF input-needed") : s.status === 8 /* InProgress */ ? pc6.yellow("\u25CF in-progress") : pc6.green("\u25CF idle");
2457
2457
  console.log(` ${pc6.bold(pc6.cyan(s.resource))}`);
2458
2458
  console.log(` ${pc6.bold("Provider:")} ${s.provider}`);
2459
2459
  if (s.model) console.log(` ${pc6.bold("Model:")} ${s.model}`);
@@ -20,6 +20,7 @@ var ActionType = /* @__PURE__ */ ((ActionType2) => {
20
20
  ActionType2["SessionToolCallConfirmed"] = "session/toolCallConfirmed";
21
21
  ActionType2["SessionToolCallComplete"] = "session/toolCallComplete";
22
22
  ActionType2["SessionToolCallResultConfirmed"] = "session/toolCallResultConfirmed";
23
+ ActionType2["SessionToolCallContentChanged"] = "session/toolCallContentChanged";
23
24
  ActionType2["SessionTurnComplete"] = "session/turnComplete";
24
25
  ActionType2["SessionTurnCancelled"] = "session/turnCancelled";
25
26
  ActionType2["SessionError"] = "session/error";
@@ -33,9 +34,24 @@ var ActionType = /* @__PURE__ */ ((ActionType2) => {
33
34
  ActionType2["SessionPendingMessageSet"] = "session/pendingMessageSet";
34
35
  ActionType2["SessionPendingMessageRemoved"] = "session/pendingMessageRemoved";
35
36
  ActionType2["SessionQueuedMessagesReordered"] = "session/queuedMessagesReordered";
37
+ ActionType2["SessionInputRequested"] = "session/inputRequested";
38
+ ActionType2["SessionInputAnswerChanged"] = "session/inputAnswerChanged";
39
+ ActionType2["SessionInputCompleted"] = "session/inputCompleted";
36
40
  ActionType2["SessionCustomizationsChanged"] = "session/customizationsChanged";
37
41
  ActionType2["SessionCustomizationToggled"] = "session/customizationToggled";
38
42
  ActionType2["SessionTruncated"] = "session/truncated";
43
+ ActionType2["SessionIsReadChanged"] = "session/isReadChanged";
44
+ ActionType2["SessionIsDoneChanged"] = "session/isDoneChanged";
45
+ ActionType2["SessionDiffsChanged"] = "session/diffsChanged";
46
+ ActionType2["RootTerminalsChanged"] = "root/terminalsChanged";
47
+ ActionType2["TerminalData"] = "terminal/data";
48
+ ActionType2["TerminalInput"] = "terminal/input";
49
+ ActionType2["TerminalResized"] = "terminal/resized";
50
+ ActionType2["TerminalClaimed"] = "terminal/claimed";
51
+ ActionType2["TerminalTitleChanged"] = "terminal/titleChanged";
52
+ ActionType2["TerminalCwdChanged"] = "terminal/cwdChanged";
53
+ ActionType2["TerminalExited"] = "terminal/exited";
54
+ ActionType2["TerminalCleared"] = "terminal/cleared";
39
55
  return ActionType2;
40
56
  })(ActionType || {});
41
57
 
@@ -48,6 +64,7 @@ var AuthRequiredReason = /* @__PURE__ */ ((AuthRequiredReason2) => {
48
64
  var NotificationType = /* @__PURE__ */ ((NotificationType2) => {
49
65
  NotificationType2["SessionAdded"] = "notify/sessionAdded";
50
66
  NotificationType2["SessionRemoved"] = "notify/sessionRemoved";
67
+ NotificationType2["SessionSummaryChanged"] = "notify/sessionSummaryChanged";
51
68
  NotificationType2["AuthRequired"] = "notify/authRequired";
52
69
  return NotificationType2;
53
70
  })(NotificationType || {});
@@ -170,11 +187,41 @@ var SessionLifecycle = /* @__PURE__ */ ((SessionLifecycle2) => {
170
187
  return SessionLifecycle2;
171
188
  })(SessionLifecycle || {});
172
189
  var SessionStatus = /* @__PURE__ */ ((SessionStatus2) => {
173
- SessionStatus2["Idle"] = "idle";
174
- SessionStatus2["InProgress"] = "in-progress";
175
- SessionStatus2["Error"] = "error";
190
+ SessionStatus2[SessionStatus2["Idle"] = 1] = "Idle";
191
+ SessionStatus2[SessionStatus2["Error"] = 2] = "Error";
192
+ SessionStatus2[SessionStatus2["InProgress"] = 8] = "InProgress";
193
+ SessionStatus2[SessionStatus2["InputNeeded"] = 24] = "InputNeeded";
176
194
  return SessionStatus2;
177
195
  })(SessionStatus || {});
196
+ var SessionInputResponseKind = /* @__PURE__ */ ((SessionInputResponseKind2) => {
197
+ SessionInputResponseKind2["Accept"] = "accept";
198
+ SessionInputResponseKind2["Decline"] = "decline";
199
+ SessionInputResponseKind2["Cancel"] = "cancel";
200
+ return SessionInputResponseKind2;
201
+ })(SessionInputResponseKind || {});
202
+ var SessionInputQuestionKind = /* @__PURE__ */ ((SessionInputQuestionKind2) => {
203
+ SessionInputQuestionKind2["Text"] = "text";
204
+ SessionInputQuestionKind2["Number"] = "number";
205
+ SessionInputQuestionKind2["Integer"] = "integer";
206
+ SessionInputQuestionKind2["Boolean"] = "boolean";
207
+ SessionInputQuestionKind2["SingleSelect"] = "single-select";
208
+ SessionInputQuestionKind2["MultiSelect"] = "multi-select";
209
+ return SessionInputQuestionKind2;
210
+ })(SessionInputQuestionKind || {});
211
+ var SessionInputAnswerValueKind = /* @__PURE__ */ ((SessionInputAnswerValueKind2) => {
212
+ SessionInputAnswerValueKind2["Text"] = "text";
213
+ SessionInputAnswerValueKind2["Number"] = "number";
214
+ SessionInputAnswerValueKind2["Boolean"] = "boolean";
215
+ SessionInputAnswerValueKind2["Selected"] = "selected";
216
+ SessionInputAnswerValueKind2["SelectedMany"] = "selected-many";
217
+ return SessionInputAnswerValueKind2;
218
+ })(SessionInputAnswerValueKind || {});
219
+ var SessionInputAnswerState = /* @__PURE__ */ ((SessionInputAnswerState2) => {
220
+ SessionInputAnswerState2["Draft"] = "draft";
221
+ SessionInputAnswerState2["Submitted"] = "submitted";
222
+ SessionInputAnswerState2["Skipped"] = "skipped";
223
+ return SessionInputAnswerState2;
224
+ })(SessionInputAnswerState || {});
178
225
  var TurnState = /* @__PURE__ */ ((TurnState2) => {
179
226
  TurnState2["Complete"] = "complete";
180
227
  TurnState2["Cancelled"] = "cancelled";
@@ -220,15 +267,15 @@ var ToolResultContentType = /* @__PURE__ */ ((ToolResultContentType2) => {
220
267
  ToolResultContentType2["EmbeddedResource"] = "embeddedResource";
221
268
  ToolResultContentType2["Resource"] = "resource";
222
269
  ToolResultContentType2["FileEdit"] = "fileEdit";
270
+ ToolResultContentType2["Terminal"] = "terminal";
271
+ ToolResultContentType2["Subagent"] = "subagent";
223
272
  return ToolResultContentType2;
224
273
  })(ToolResultContentType || {});
225
- var CustomizationStatus = /* @__PURE__ */ ((CustomizationStatus2) => {
226
- CustomizationStatus2["Loading"] = "loading";
227
- CustomizationStatus2["Loaded"] = "loaded";
228
- CustomizationStatus2["Degraded"] = "degraded";
229
- CustomizationStatus2["Error"] = "error";
230
- return CustomizationStatus2;
231
- })(CustomizationStatus || {});
274
+ var TerminalClaimKind = /* @__PURE__ */ ((TerminalClaimKind2) => {
275
+ TerminalClaimKind2["Client"] = "client";
276
+ TerminalClaimKind2["Session"] = "session";
277
+ return TerminalClaimKind2;
278
+ })(TerminalClaimKind || {});
232
279
 
233
280
  // src/client/session-handle.ts
234
281
  import { randomUUID } from "crypto";
@@ -481,6 +528,7 @@ var SessionHandle = class extends EventEmitter2 {
481
528
  var IS_CLIENT_DISPATCHABLE = {
482
529
  ["root/agentsChanged" /* RootAgentsChanged */]: false,
483
530
  ["root/activeSessionsChanged" /* RootActiveSessionsChanged */]: false,
531
+ ["root/terminalsChanged" /* RootTerminalsChanged */]: false,
484
532
  ["session/ready" /* SessionReady */]: false,
485
533
  ["session/creationFailed" /* SessionCreationFailed */]: false,
486
534
  ["session/turnStarted" /* SessionTurnStarted */]: true,
@@ -492,6 +540,7 @@ var IS_CLIENT_DISPATCHABLE = {
492
540
  ["session/toolCallConfirmed" /* SessionToolCallConfirmed */]: true,
493
541
  ["session/toolCallComplete" /* SessionToolCallComplete */]: true,
494
542
  ["session/toolCallResultConfirmed" /* SessionToolCallResultConfirmed */]: true,
543
+ ["session/toolCallContentChanged" /* SessionToolCallContentChanged */]: false,
495
544
  ["session/turnComplete" /* SessionTurnComplete */]: false,
496
545
  ["session/turnCancelled" /* SessionTurnCancelled */]: true,
497
546
  ["session/error" /* SessionError */]: false,
@@ -505,9 +554,23 @@ var IS_CLIENT_DISPATCHABLE = {
505
554
  ["session/pendingMessageSet" /* SessionPendingMessageSet */]: true,
506
555
  ["session/pendingMessageRemoved" /* SessionPendingMessageRemoved */]: true,
507
556
  ["session/queuedMessagesReordered" /* SessionQueuedMessagesReordered */]: true,
557
+ ["session/inputRequested" /* SessionInputRequested */]: false,
558
+ ["session/inputAnswerChanged" /* SessionInputAnswerChanged */]: true,
559
+ ["session/inputCompleted" /* SessionInputCompleted */]: true,
508
560
  ["session/customizationsChanged" /* SessionCustomizationsChanged */]: false,
509
561
  ["session/customizationToggled" /* SessionCustomizationToggled */]: true,
510
- ["session/truncated" /* SessionTruncated */]: true
562
+ ["session/truncated" /* SessionTruncated */]: true,
563
+ ["session/isReadChanged" /* SessionIsReadChanged */]: true,
564
+ ["session/isDoneChanged" /* SessionIsDoneChanged */]: true,
565
+ ["session/diffsChanged" /* SessionDiffsChanged */]: false,
566
+ ["terminal/data" /* TerminalData */]: false,
567
+ ["terminal/input" /* TerminalInput */]: true,
568
+ ["terminal/resized" /* TerminalResized */]: true,
569
+ ["terminal/claimed" /* TerminalClaimed */]: true,
570
+ ["terminal/titleChanged" /* TerminalTitleChanged */]: true,
571
+ ["terminal/cwdChanged" /* TerminalCwdChanged */]: false,
572
+ ["terminal/exited" /* TerminalExited */]: false,
573
+ ["terminal/cleared" /* TerminalCleared */]: true
511
574
  };
512
575
 
513
576
  // src/protocol/reducers.ts
@@ -524,7 +587,34 @@ function tcBase(tc) {
524
587
  _meta: tc._meta
525
588
  };
526
589
  }
527
- function endTurn(state, turnId, turnState, summaryStatus, error) {
590
+ function hasPendingToolCallConfirmation(state) {
591
+ if (!state.activeTurn) {
592
+ return false;
593
+ }
594
+ return state.activeTurn.responseParts.some(
595
+ (part) => part.kind === "toolCall" /* ToolCall */ && (part.toolCall.status === "pending-confirmation" /* PendingConfirmation */ || part.toolCall.status === "pending-result-confirmation" /* PendingResultConfirmation */)
596
+ );
597
+ }
598
+ function summaryStatus(state, terminalStatus) {
599
+ if (terminalStatus) {
600
+ return terminalStatus;
601
+ }
602
+ if ((state.inputRequests?.length ?? 0) > 0 || hasPendingToolCallConfirmation(state)) {
603
+ return 24 /* InputNeeded */;
604
+ }
605
+ if (state.activeTurn) {
606
+ return 8 /* InProgress */;
607
+ }
608
+ return 1 /* Idle */;
609
+ }
610
+ function refreshSummaryStatus(state) {
611
+ const status = summaryStatus(state);
612
+ if (status === state.summary.status) {
613
+ return state;
614
+ }
615
+ return { ...state, summary: { ...state.summary, status } };
616
+ }
617
+ function endTurn(state, turnId, turnState, terminalStatus, error) {
528
618
  if (!state.activeTurn || state.activeTurn.id !== turnId) {
529
619
  return state;
530
620
  }
@@ -556,12 +646,30 @@ function endTurn(state, turnId, turnState, summaryStatus, error) {
556
646
  state: turnState,
557
647
  error
558
648
  };
559
- return {
649
+ const next = {
560
650
  ...state,
561
651
  turns: [...state.turns, turn],
562
652
  activeTurn: void 0,
563
- summary: { ...state.summary, status: summaryStatus, modifiedAt: Date.now() }
653
+ summary: { ...state.summary, modifiedAt: Date.now() }
564
654
  };
655
+ delete next.inputRequests;
656
+ return {
657
+ ...next,
658
+ summary: { ...next.summary, status: summaryStatus(next, terminalStatus) }
659
+ };
660
+ }
661
+ function upsertInputRequest(state, request) {
662
+ const existing = state.inputRequests ?? [];
663
+ const idx = existing.findIndex((r) => r.id === request.id);
664
+ const inputRequests = [...existing];
665
+ if (idx >= 0) {
666
+ const answers = request.answers ?? inputRequests[idx].answers;
667
+ inputRequests[idx] = { ...request, answers };
668
+ } else {
669
+ inputRequests.push(request);
670
+ }
671
+ const next = { ...state, inputRequests };
672
+ return { ...next, summary: { ...next.summary, status: summaryStatus(next), modifiedAt: Date.now(), isRead: false } };
565
673
  }
566
674
  function updateToolCallInParts(state, turnId, toolCallId, updater) {
567
675
  const activeTurn = state.activeTurn;
@@ -618,6 +726,8 @@ function rootReducer(state, action, log7) {
618
726
  return { ...state, agents: action.agents };
619
727
  case "root/activeSessionsChanged" /* RootActiveSessionsChanged */:
620
728
  return { ...state, activeSessions: action.activeSessions };
729
+ case "root/terminalsChanged" /* RootTerminalsChanged */:
730
+ return { ...state, terminals: action.terminals };
621
731
  default:
622
732
  softAssertNever(action, log7);
623
733
  return state;
@@ -630,7 +740,7 @@ function sessionReducer(state, action, log7) {
630
740
  return {
631
741
  ...state,
632
742
  lifecycle: "ready" /* Ready */,
633
- summary: { ...state.summary, status: "idle" /* Idle */ }
743
+ summary: { ...state.summary, status: 1 /* Idle */ }
634
744
  };
635
745
  case "session/creationFailed" /* SessionCreationFailed */:
636
746
  return {
@@ -642,7 +752,6 @@ function sessionReducer(state, action, log7) {
642
752
  case "session/turnStarted" /* SessionTurnStarted */: {
643
753
  let next = {
644
754
  ...state,
645
- summary: { ...state.summary, status: "in-progress" /* InProgress */, modifiedAt: Date.now() },
646
755
  activeTurn: {
647
756
  id: action.turnId,
648
757
  userMessage: action.userMessage,
@@ -650,6 +759,10 @@ function sessionReducer(state, action, log7) {
650
759
  usage: void 0
651
760
  }
652
761
  };
762
+ next = {
763
+ ...next,
764
+ summary: { ...next.summary, status: summaryStatus(next), modifiedAt: Date.now(), isRead: false }
765
+ };
653
766
  if (action.queuedMessageId) {
654
767
  if (next.steeringMessage?.id === action.queuedMessageId) {
655
768
  next = { ...next, steeringMessage: void 0 };
@@ -661,41 +774,17 @@ function sessionReducer(state, action, log7) {
661
774
  }
662
775
  return next;
663
776
  }
664
- case "session/delta" /* SessionDelta */: {
665
- const updated = updateResponsePart(state, action.turnId, action.partId, (part) => {
777
+ case "session/delta" /* SessionDelta */:
778
+ return updateResponsePart(state, action.turnId, action.partId, (part) => {
666
779
  if (part.kind === "markdown" /* Markdown */) {
667
780
  return { ...part, content: part.content + action.content };
668
781
  }
669
782
  return part;
670
783
  });
671
- if (updated === state && state.activeTurn && state.activeTurn.id === action.turnId) {
672
- return {
673
- ...state,
674
- activeTurn: {
675
- ...state.activeTurn,
676
- responseParts: [
677
- ...state.activeTurn.responseParts,
678
- { kind: "markdown" /* Markdown */, id: action.partId, content: action.content }
679
- ]
680
- }
681
- };
682
- }
683
- return updated;
684
- }
685
- case "session/responsePart" /* SessionResponsePart */: {
784
+ case "session/responsePart" /* SessionResponsePart */:
686
785
  if (!state.activeTurn || state.activeTurn.id !== action.turnId) {
687
786
  return state;
688
787
  }
689
- const newPartId = action.part.kind === "toolCall" /* ToolCall */ ? action.part.toolCall.toolCallId : "id" in action.part ? action.part.id : void 0;
690
- if (newPartId !== void 0) {
691
- const exists = state.activeTurn.responseParts.some((p) => {
692
- const id = p.kind === "toolCall" /* ToolCall */ ? p.toolCall.toolCallId : "id" in p ? p.id : void 0;
693
- return id === newPartId;
694
- });
695
- if (exists) {
696
- return state;
697
- }
698
- }
699
788
  return {
700
789
  ...state,
701
790
  activeTurn: {
@@ -703,13 +792,12 @@ function sessionReducer(state, action, log7) {
703
792
  responseParts: [...state.activeTurn.responseParts, action.part]
704
793
  }
705
794
  };
706
- }
707
795
  case "session/turnComplete" /* SessionTurnComplete */:
708
- return endTurn(state, action.turnId, "complete" /* Complete */, "idle" /* Idle */);
796
+ return endTurn(state, action.turnId, "complete" /* Complete */);
709
797
  case "session/turnCancelled" /* SessionTurnCancelled */:
710
- return endTurn(state, action.turnId, "cancelled" /* Cancelled */, "idle" /* Idle */);
798
+ return endTurn(state, action.turnId, "cancelled" /* Cancelled */);
711
799
  case "session/error" /* SessionError */:
712
- return endTurn(state, action.turnId, "error" /* Error */, "error" /* Error */, action.error);
800
+ return endTurn(state, action.turnId, "error" /* Error */, 2 /* Error */, action.error);
713
801
  // ── Tool Call State Machine ───────────────────────────────────────────
714
802
  case "session/toolCallStart" /* SessionToolCallStart */:
715
803
  if (!state.activeTurn || state.activeTurn.id !== action.turnId) {
@@ -747,7 +835,7 @@ function sessionReducer(state, action, log7) {
747
835
  };
748
836
  });
749
837
  case "session/toolCallReady" /* SessionToolCallReady */:
750
- return updateToolCallInParts(state, action.turnId, action.toolCallId, (tc) => {
838
+ return refreshSummaryStatus(updateToolCallInParts(state, action.turnId, action.toolCallId, (tc) => {
751
839
  if (tc.status !== "streaming" /* Streaming */ && tc.status !== "running" /* Running */) {
752
840
  return tc;
753
841
  }
@@ -768,9 +856,9 @@ function sessionReducer(state, action, log7) {
768
856
  toolInput: action.toolInput,
769
857
  confirmationTitle: action.confirmationTitle
770
858
  };
771
- });
859
+ }));
772
860
  case "session/toolCallConfirmed" /* SessionToolCallConfirmed */:
773
- return updateToolCallInParts(state, action.turnId, action.toolCallId, (tc) => {
861
+ return refreshSummaryStatus(updateToolCallInParts(state, action.turnId, action.toolCallId, (tc) => {
774
862
  if (tc.status !== "pending-confirmation" /* PendingConfirmation */) {
775
863
  return tc;
776
864
  }
@@ -793,9 +881,9 @@ function sessionReducer(state, action, log7) {
793
881
  reasonMessage: action.reasonMessage,
794
882
  userSuggestion: action.userSuggestion
795
883
  };
796
- });
884
+ }));
797
885
  case "session/toolCallComplete" /* SessionToolCallComplete */:
798
- return updateToolCallInParts(state, action.turnId, action.toolCallId, (tc) => {
886
+ return refreshSummaryStatus(updateToolCallInParts(state, action.turnId, action.toolCallId, (tc) => {
799
887
  if (tc.status !== "running" /* Running */ && tc.status !== "pending-confirmation" /* PendingConfirmation */) {
800
888
  return tc;
801
889
  }
@@ -819,9 +907,9 @@ function sessionReducer(state, action, log7) {
819
907
  confirmed,
820
908
  ...action.result
821
909
  };
822
- });
910
+ }));
823
911
  case "session/toolCallResultConfirmed" /* SessionToolCallResultConfirmed */:
824
- return updateToolCallInParts(state, action.turnId, action.toolCallId, (tc) => {
912
+ return refreshSummaryStatus(updateToolCallInParts(state, action.turnId, action.toolCallId, (tc) => {
825
913
  if (tc.status !== "pending-result-confirmation" /* PendingResultConfirmation */) {
826
914
  return tc;
827
915
  }
@@ -847,6 +935,16 @@ function sessionReducer(state, action, log7) {
847
935
  toolInput: tc.toolInput,
848
936
  reason: "result-denied" /* ResultDenied */
849
937
  };
938
+ }));
939
+ case "session/toolCallContentChanged" /* SessionToolCallContentChanged */:
940
+ return updateToolCallInParts(state, action.turnId, action.toolCallId, (tc) => {
941
+ if (tc.status !== "running" /* Running */) {
942
+ return tc;
943
+ }
944
+ return {
945
+ ...tc,
946
+ content: action.content
947
+ };
850
948
  });
851
949
  // ── Metadata ──────────────────────────────────────────────────────────
852
950
  case "session/titleChanged" /* SessionTitleChanged */:
@@ -874,6 +972,21 @@ function sessionReducer(state, action, log7) {
874
972
  ...state,
875
973
  summary: { ...state.summary, model: action.model, modifiedAt: Date.now() }
876
974
  };
975
+ case "session/isReadChanged" /* SessionIsReadChanged */:
976
+ return {
977
+ ...state,
978
+ summary: { ...state.summary, isRead: action.isRead }
979
+ };
980
+ case "session/isDoneChanged" /* SessionIsDoneChanged */:
981
+ return {
982
+ ...state,
983
+ summary: { ...state.summary, isDone: action.isDone }
984
+ };
985
+ case "session/diffsChanged" /* SessionDiffsChanged */:
986
+ return {
987
+ ...state,
988
+ summary: { ...state.summary, diffs: action.diffs }
989
+ };
877
990
  case "session/serverToolsChanged" /* SessionServerToolsChanged */:
878
991
  return { ...state, serverTools: action.tools };
879
992
  case "session/activeClientChanged" /* SessionActiveClientChanged */:
@@ -917,11 +1030,62 @@ function sessionReducer(state, action, log7) {
917
1030
  }
918
1031
  turns = state.turns.slice(0, idx + 1);
919
1032
  }
920
- return {
1033
+ const next = {
921
1034
  ...state,
922
1035
  turns,
923
1036
  activeTurn: void 0,
924
- summary: { ...state.summary, status: "idle" /* Idle */, modifiedAt: Date.now() }
1037
+ summary: { ...state.summary, modifiedAt: Date.now() }
1038
+ };
1039
+ delete next.inputRequests;
1040
+ return {
1041
+ ...next,
1042
+ summary: { ...next.summary, status: summaryStatus(next) }
1043
+ };
1044
+ }
1045
+ // ── Session Input Requests ─────────────────────────────────────────────
1046
+ case "session/inputRequested" /* SessionInputRequested */:
1047
+ return upsertInputRequest(state, action.request);
1048
+ case "session/inputAnswerChanged" /* SessionInputAnswerChanged */: {
1049
+ const existing = state.inputRequests;
1050
+ const idx = existing?.findIndex((request2) => request2.id === action.requestId) ?? -1;
1051
+ if (!existing || idx < 0) {
1052
+ return state;
1053
+ }
1054
+ const request = existing[idx];
1055
+ const answers = { ...request.answers ?? {} };
1056
+ if (action.answer === void 0) {
1057
+ delete answers[action.questionId];
1058
+ } else {
1059
+ answers[action.questionId] = action.answer;
1060
+ }
1061
+ const updated = [...existing];
1062
+ updated[idx] = {
1063
+ ...request,
1064
+ answers: Object.keys(answers).length > 0 ? answers : void 0
1065
+ };
1066
+ return {
1067
+ ...state,
1068
+ inputRequests: updated,
1069
+ summary: { ...state.summary, modifiedAt: Date.now() }
1070
+ };
1071
+ }
1072
+ case "session/inputCompleted" /* SessionInputCompleted */: {
1073
+ const existing = state.inputRequests;
1074
+ if (!existing?.some((request) => request.id === action.requestId)) {
1075
+ return state;
1076
+ }
1077
+ const inputRequests = existing.filter((request) => request.id !== action.requestId);
1078
+ const next = {
1079
+ ...state
1080
+ };
1081
+ if (inputRequests.length > 0) {
1082
+ next.inputRequests = inputRequests;
1083
+ } else {
1084
+ delete next.inputRequests;
1085
+ }
1086
+ return {
1087
+ ...next,
1088
+ summary: { ...next.summary, status: summaryStatus(next), modifiedAt: Date.now() }
925
1089
  };
926
1090
  }
927
1091
  // ── Pending Messages ──────────────────────────────────────────────────
@@ -979,12 +1143,41 @@ function sessionReducer(state, action, log7) {
979
1143
  return state;
980
1144
  }
981
1145
  }
1146
+ function terminalReducer(state, action, log7) {
1147
+ switch (action.type) {
1148
+ case "terminal/data" /* TerminalData */:
1149
+ return { ...state, content: state.content + action.data };
1150
+ case "terminal/input" /* TerminalInput */:
1151
+ return state;
1152
+ case "terminal/resized" /* TerminalResized */:
1153
+ return { ...state, cols: action.cols, rows: action.rows };
1154
+ case "terminal/claimed" /* TerminalClaimed */:
1155
+ return { ...state, claim: action.claim };
1156
+ case "terminal/titleChanged" /* TerminalTitleChanged */:
1157
+ return { ...state, title: action.title };
1158
+ case "terminal/cwdChanged" /* TerminalCwdChanged */:
1159
+ return { ...state, cwd: action.cwd };
1160
+ case "terminal/exited" /* TerminalExited */:
1161
+ return { ...state, exitCode: action.exitCode };
1162
+ case "terminal/cleared" /* TerminalCleared */:
1163
+ return { ...state, content: "" };
1164
+ default:
1165
+ softAssertNever(action, log7);
1166
+ return state;
1167
+ }
1168
+ }
982
1169
 
983
1170
  // src/client/state.ts
984
- var ROOT_ACTION_TYPES = /* @__PURE__ */ new Set(["root/agentsChanged" /* RootAgentsChanged */, "root/activeSessionsChanged" /* RootActiveSessionsChanged */]);
1171
+ var ROOT_ACTION_TYPES = /* @__PURE__ */ new Set([
1172
+ "root/agentsChanged" /* RootAgentsChanged */,
1173
+ "root/activeSessionsChanged" /* RootActiveSessionsChanged */,
1174
+ "root/terminalsChanged" /* RootTerminalsChanged */
1175
+ ]);
1176
+ var TERMINAL_ACTION_PREFIX = "terminal/";
985
1177
  var StateMirror = class {
986
1178
  rootState = { agents: [] };
987
1179
  sessions = /* @__PURE__ */ new Map();
1180
+ terminals = /* @__PURE__ */ new Map();
988
1181
  serverSeq = 0;
989
1182
  pendingActions = /* @__PURE__ */ new Map();
990
1183
  /** Current root state (agents, active session count). */
@@ -1003,6 +1196,19 @@ var StateMirror = class {
1003
1196
  get sessionUris() {
1004
1197
  return [...this.sessions.keys()];
1005
1198
  }
1199
+ /** Get a terminal state by URI. */
1200
+ getTerminal(uri) {
1201
+ return this.terminals.get(uri);
1202
+ }
1203
+ /** All tracked terminal URIs. */
1204
+ get terminalUris() {
1205
+ return [...this.terminals.keys()];
1206
+ }
1207
+ /** Remove a terminal from tracking. */
1208
+ removeTerminal(uri) {
1209
+ this.terminals.delete(uri);
1210
+ this.pendingActions.delete(uri);
1211
+ }
1006
1212
  /**
1007
1213
  * Load a snapshot (from initialize, reconnect, or subscribe).
1008
1214
  * After registering a session, replays any actions that arrived before the snapshot.
@@ -1031,6 +1237,24 @@ var StateMirror = class {
1031
1237
  }
1032
1238
  }
1033
1239
  }
1240
+ } else if ("claim" in snapshot.state) {
1241
+ const terminalState = snapshot.state;
1242
+ this.terminals.set(snapshot.resource, terminalState);
1243
+ const buffered = this.pendingActions.get(snapshot.resource);
1244
+ if (buffered) {
1245
+ this.pendingActions.delete(snapshot.resource);
1246
+ for (const env of buffered) {
1247
+ if (env.serverSeq > snapshot.fromSeq) {
1248
+ const current = this.terminals.get(snapshot.resource);
1249
+ if (current) {
1250
+ this.terminals.set(
1251
+ snapshot.resource,
1252
+ terminalReducer(current, env.action)
1253
+ );
1254
+ }
1255
+ }
1256
+ }
1257
+ }
1034
1258
  }
1035
1259
  }
1036
1260
  /**
@@ -1041,6 +1265,22 @@ var StateMirror = class {
1041
1265
  const action = envelope.action;
1042
1266
  if (ROOT_ACTION_TYPES.has(action.type)) {
1043
1267
  this.rootState = rootReducer(this.rootState, action);
1268
+ } else if (action.type.startsWith(TERMINAL_ACTION_PREFIX)) {
1269
+ const terminalAction = action;
1270
+ const terminalUri = terminalAction.terminal;
1271
+ if (terminalUri) {
1272
+ const current = this.terminals.get(terminalUri);
1273
+ if (current) {
1274
+ this.terminals.set(terminalUri, terminalReducer(current, terminalAction));
1275
+ } else {
1276
+ let buffer = this.pendingActions.get(terminalUri);
1277
+ if (!buffer) {
1278
+ buffer = [];
1279
+ this.pendingActions.set(terminalUri, buffer);
1280
+ }
1281
+ buffer.push(envelope);
1282
+ }
1283
+ }
1044
1284
  } else {
1045
1285
  const sessionAction = action;
1046
1286
  const sessionUri = sessionAction.session;
@@ -1334,6 +1574,7 @@ var ACTION_INTRODUCED_IN = {
1334
1574
  ["session/toolCallConfirmed" /* SessionToolCallConfirmed */]: 1,
1335
1575
  ["session/toolCallComplete" /* SessionToolCallComplete */]: 1,
1336
1576
  ["session/toolCallResultConfirmed" /* SessionToolCallResultConfirmed */]: 1,
1577
+ ["session/toolCallContentChanged" /* SessionToolCallContentChanged */]: 1,
1337
1578
  ["session/turnComplete" /* SessionTurnComplete */]: 1,
1338
1579
  ["session/turnCancelled" /* SessionTurnCancelled */]: 1,
1339
1580
  ["session/error" /* SessionError */]: 1,
@@ -1347,13 +1588,29 @@ var ACTION_INTRODUCED_IN = {
1347
1588
  ["session/pendingMessageSet" /* SessionPendingMessageSet */]: 1,
1348
1589
  ["session/pendingMessageRemoved" /* SessionPendingMessageRemoved */]: 1,
1349
1590
  ["session/queuedMessagesReordered" /* SessionQueuedMessagesReordered */]: 1,
1591
+ ["session/inputRequested" /* SessionInputRequested */]: 1,
1592
+ ["session/inputAnswerChanged" /* SessionInputAnswerChanged */]: 1,
1593
+ ["session/inputCompleted" /* SessionInputCompleted */]: 1,
1350
1594
  ["session/customizationsChanged" /* SessionCustomizationsChanged */]: 1,
1351
1595
  ["session/customizationToggled" /* SessionCustomizationToggled */]: 1,
1352
- ["session/truncated" /* SessionTruncated */]: 1
1596
+ ["session/truncated" /* SessionTruncated */]: 1,
1597
+ ["session/isReadChanged" /* SessionIsReadChanged */]: 1,
1598
+ ["session/isDoneChanged" /* SessionIsDoneChanged */]: 1,
1599
+ ["session/diffsChanged" /* SessionDiffsChanged */]: 1,
1600
+ ["root/terminalsChanged" /* RootTerminalsChanged */]: 1,
1601
+ ["terminal/data" /* TerminalData */]: 1,
1602
+ ["terminal/input" /* TerminalInput */]: 1,
1603
+ ["terminal/resized" /* TerminalResized */]: 1,
1604
+ ["terminal/claimed" /* TerminalClaimed */]: 1,
1605
+ ["terminal/titleChanged" /* TerminalTitleChanged */]: 1,
1606
+ ["terminal/cwdChanged" /* TerminalCwdChanged */]: 1,
1607
+ ["terminal/exited" /* TerminalExited */]: 1,
1608
+ ["terminal/cleared" /* TerminalCleared */]: 1
1353
1609
  };
1354
1610
  var NOTIFICATION_INTRODUCED_IN = {
1355
1611
  ["notify/sessionAdded" /* SessionAdded */]: 1,
1356
1612
  ["notify/sessionRemoved" /* SessionRemoved */]: 1,
1613
+ ["notify/sessionSummaryChanged" /* SessionSummaryChanged */]: 1,
1357
1614
  ["notify/authRequired" /* AuthRequired */]: 1
1358
1615
  };
1359
1616
 
@@ -1510,6 +1767,28 @@ var AhpClient = class extends EventEmitter4 {
1510
1767
  this._sessions.delete(sessionUri);
1511
1768
  return result;
1512
1769
  }
1770
+ /**
1771
+ * Create a new terminal on the server.
1772
+ */
1773
+ async createTerminal(terminalUri, claim, options) {
1774
+ this.ensureConnected();
1775
+ return this.protocol.request("createTerminal", {
1776
+ terminal: terminalUri,
1777
+ claim,
1778
+ ...options
1779
+ });
1780
+ }
1781
+ /**
1782
+ * Dispose a terminal and kill its process if still running.
1783
+ */
1784
+ async disposeTerminal(terminalUri) {
1785
+ this.ensureConnected();
1786
+ const result = await this.protocol.request("disposeTerminal", {
1787
+ terminal: terminalUri
1788
+ });
1789
+ this._state.removeTerminal(terminalUri);
1790
+ return result;
1791
+ }
1513
1792
  /**
1514
1793
  * List all sessions on the server.
1515
1794
  */
@@ -2470,6 +2749,10 @@ export {
2470
2749
  PendingMessageKind,
2471
2750
  SessionLifecycle,
2472
2751
  SessionStatus,
2752
+ SessionInputResponseKind,
2753
+ SessionInputQuestionKind,
2754
+ SessionInputAnswerValueKind,
2755
+ SessionInputAnswerState,
2473
2756
  TurnState,
2474
2757
  AttachmentType,
2475
2758
  ResponsePartKind,
@@ -2477,8 +2760,9 @@ export {
2477
2760
  ToolCallConfirmationReason,
2478
2761
  ToolCallCancellationReason,
2479
2762
  ToolResultContentType,
2480
- CustomizationStatus,
2763
+ TerminalClaimKind,
2481
2764
  SessionHandle,
2765
+ terminalReducer,
2482
2766
  StateMirror,
2483
2767
  Transport,
2484
2768
  ActiveClientManager,