@sagmans/dsh-tui 0.5.2 → 0.7.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 (285) hide show
  1. package/.agents/skills/dsh-tui-dogfood/SKILL.md +83 -0
  2. package/.agents/skills/dsh-tui-dogfood/references/home-state.md +78 -0
  3. package/.agents/skills/dsh-tui-dogfood/scripts/clone-links.mjs +133 -0
  4. package/.agents/skills/dsh-tui-dogfood/scripts/run-plugin-from-worktree.sh +417 -0
  5. package/.agents/skills/dsh-tui-update-models/SKILL.md +121 -0
  6. package/.agents/skills/dsh-tui-update-models/references/model-wiring.md +162 -0
  7. package/.agents/skills/dsh-tui-update-models/scripts/dump-model-catalog.mjs +178 -0
  8. package/README.md +131 -17
  9. package/lib/agent/host.d.ts +11 -0
  10. package/lib/agent/host.d.ts.map +1 -1
  11. package/lib/agent/host.js +16 -2
  12. package/lib/agent/host.js.map +1 -1
  13. package/lib/agent/present.d.ts.map +1 -1
  14. package/lib/agent/present.js +2 -1
  15. package/lib/agent/present.js.map +1 -1
  16. package/lib/agent/undo.d.ts +52 -0
  17. package/lib/agent/undo.d.ts.map +1 -0
  18. package/lib/agent/undo.js +106 -0
  19. package/lib/agent/undo.js.map +1 -0
  20. package/lib/cards/composition.d.ts +68 -0
  21. package/lib/cards/composition.d.ts.map +1 -0
  22. package/lib/cards/composition.js +117 -0
  23. package/lib/cards/composition.js.map +1 -0
  24. package/lib/cards/presenter.d.ts +23 -0
  25. package/lib/cards/presenter.d.ts.map +1 -0
  26. package/lib/cards/presenter.js +394 -0
  27. package/lib/cards/presenter.js.map +1 -0
  28. package/lib/cards/preview.d.ts +42 -0
  29. package/lib/cards/preview.d.ts.map +1 -0
  30. package/lib/cards/preview.js +51 -0
  31. package/lib/cards/preview.js.map +1 -0
  32. package/lib/cards.d.ts +42 -95
  33. package/lib/cards.d.ts.map +1 -1
  34. package/lib/cards.js +4 -526
  35. package/lib/cards.js.map +1 -1
  36. package/lib/compat/section.d.ts +29 -0
  37. package/lib/compat/section.d.ts.map +1 -0
  38. package/lib/compat/section.js +82 -0
  39. package/lib/compat/section.js.map +1 -0
  40. package/lib/config.d.ts +27 -2
  41. package/lib/config.d.ts.map +1 -1
  42. package/lib/config.js +61 -1
  43. package/lib/config.js.map +1 -1
  44. package/lib/contracts.d.ts +28 -0
  45. package/lib/contracts.d.ts.map +1 -1
  46. package/lib/fold-cursor.d.ts +8 -0
  47. package/lib/fold-cursor.d.ts.map +1 -1
  48. package/lib/fold-cursor.js +18 -0
  49. package/lib/fold-cursor.js.map +1 -1
  50. package/lib/gates/question-card.d.ts +77 -0
  51. package/lib/gates/question-card.d.ts.map +1 -0
  52. package/lib/gates/question-card.js +113 -0
  53. package/lib/gates/question-card.js.map +1 -0
  54. package/lib/gates/questions.d.ts +127 -0
  55. package/lib/gates/questions.d.ts.map +1 -0
  56. package/lib/gates/questions.js +418 -0
  57. package/lib/gates/questions.js.map +1 -0
  58. package/lib/gates.d.ts +1 -113
  59. package/lib/gates.d.ts.map +1 -1
  60. package/lib/gates.js +1 -484
  61. package/lib/gates.js.map +1 -1
  62. package/lib/herdr/reporter.d.ts +9 -4
  63. package/lib/herdr/reporter.d.ts.map +1 -1
  64. package/lib/herdr/reporter.js +5 -9
  65. package/lib/herdr/reporter.js.map +1 -1
  66. package/lib/herdr/state.d.ts +35 -4
  67. package/lib/herdr/state.d.ts.map +1 -1
  68. package/lib/herdr/state.js +37 -4
  69. package/lib/herdr/state.js.map +1 -1
  70. package/lib/index.d.ts +1 -0
  71. package/lib/index.d.ts.map +1 -1
  72. package/lib/index.js +343 -2267
  73. package/lib/index.js.map +1 -1
  74. package/lib/input/action-catalog.d.ts +74 -0
  75. package/lib/input/action-catalog.d.ts.map +1 -0
  76. package/lib/input/action-catalog.js +137 -0
  77. package/lib/input/action-catalog.js.map +1 -0
  78. package/lib/input/actions.d.ts +5 -81
  79. package/lib/input/actions.d.ts.map +1 -1
  80. package/lib/input/actions.js +4 -621
  81. package/lib/input/actions.js.map +1 -1
  82. package/lib/input/completion.d.ts +11 -1
  83. package/lib/input/completion.d.ts.map +1 -1
  84. package/lib/input/completion.js +17 -1
  85. package/lib/input/completion.js.map +1 -1
  86. package/lib/input/file-index.d.ts +40 -0
  87. package/lib/input/file-index.d.ts.map +1 -0
  88. package/lib/input/file-index.js +141 -0
  89. package/lib/input/file-index.js.map +1 -0
  90. package/lib/input/file-search.d.ts +1 -38
  91. package/lib/input/file-search.d.ts.map +1 -1
  92. package/lib/input/file-search.js +1 -487
  93. package/lib/input/file-search.js.map +1 -1
  94. package/lib/input/key-press.d.ts +57 -0
  95. package/lib/input/key-press.d.ts.map +1 -0
  96. package/lib/input/key-press.js +218 -0
  97. package/lib/input/key-press.js.map +1 -0
  98. package/lib/input/keymap-conflicts.d.ts +59 -0
  99. package/lib/input/keymap-conflicts.d.ts.map +1 -0
  100. package/lib/input/keymap-conflicts.js +292 -0
  101. package/lib/input/keymap-conflicts.js.map +1 -0
  102. package/lib/input/keymap-settings.js +1 -1
  103. package/lib/input/keymap-settings.js.map +1 -1
  104. package/lib/input/keymap.d.ts.map +1 -1
  105. package/lib/input/keymap.js +5 -1
  106. package/lib/input/keymap.js.map +1 -1
  107. package/lib/input/submission.d.ts +11 -1
  108. package/lib/input/submission.d.ts.map +1 -1
  109. package/lib/input/submission.js +10 -1
  110. package/lib/input/submission.js.map +1 -1
  111. package/lib/input/workspace-files.d.ts +10 -0
  112. package/lib/input/workspace-files.d.ts.map +1 -0
  113. package/lib/input/workspace-files.js +359 -0
  114. package/lib/input/workspace-files.js.map +1 -0
  115. package/lib/install-skills.d.ts +20 -0
  116. package/lib/install-skills.d.ts.map +1 -0
  117. package/lib/install-skills.js +198 -0
  118. package/lib/install-skills.js.map +1 -0
  119. package/lib/keys-command.d.ts +2 -1
  120. package/lib/keys-command.d.ts.map +1 -1
  121. package/lib/keys-command.js +2 -1
  122. package/lib/keys-command.js.map +1 -1
  123. package/lib/model-list.d.ts +37 -0
  124. package/lib/model-list.d.ts.map +1 -0
  125. package/lib/model-list.js +60 -0
  126. package/lib/model-list.js.map +1 -0
  127. package/lib/startup.d.ts +8 -0
  128. package/lib/startup.d.ts.map +1 -1
  129. package/lib/startup.js +120 -24
  130. package/lib/startup.js.map +1 -1
  131. package/lib/subagents.d.ts +7 -3
  132. package/lib/subagents.d.ts.map +1 -1
  133. package/lib/subagents.js +28 -4
  134. package/lib/subagents.js.map +1 -1
  135. package/lib/surface/appearance-preferences.d.ts +26 -0
  136. package/lib/surface/appearance-preferences.d.ts.map +1 -0
  137. package/lib/surface/appearance-preferences.js +139 -0
  138. package/lib/surface/appearance-preferences.js.map +1 -0
  139. package/lib/surface/appearance.d.ts +87 -0
  140. package/lib/surface/appearance.d.ts.map +1 -0
  141. package/lib/surface/appearance.js +353 -0
  142. package/lib/surface/appearance.js.map +1 -0
  143. package/lib/surface/background-work.d.ts +49 -0
  144. package/lib/surface/background-work.d.ts.map +1 -0
  145. package/lib/surface/background-work.js +146 -0
  146. package/lib/surface/background-work.js.map +1 -0
  147. package/lib/surface/commands.d.ts +80 -0
  148. package/lib/surface/commands.d.ts.map +1 -0
  149. package/lib/surface/commands.js +364 -0
  150. package/lib/surface/commands.js.map +1 -0
  151. package/lib/surface/modal-input.d.ts +58 -0
  152. package/lib/surface/modal-input.d.ts.map +1 -0
  153. package/lib/surface/modal-input.js +237 -0
  154. package/lib/surface/modal-input.js.map +1 -0
  155. package/lib/surface/model-choice.d.ts +54 -0
  156. package/lib/surface/model-choice.d.ts.map +1 -0
  157. package/lib/surface/model-choice.js +325 -0
  158. package/lib/surface/model-choice.js.map +1 -0
  159. package/lib/surface/preset-choice.d.ts +78 -0
  160. package/lib/surface/preset-choice.d.ts.map +1 -0
  161. package/lib/surface/preset-choice.js +163 -0
  162. package/lib/surface/preset-choice.js.map +1 -0
  163. package/lib/surface/prompt-input.d.ts +97 -0
  164. package/lib/surface/prompt-input.d.ts.map +1 -0
  165. package/lib/surface/prompt-input.js +215 -0
  166. package/lib/surface/prompt-input.js.map +1 -0
  167. package/lib/surface/prompt-memory.d.ts +76 -0
  168. package/lib/surface/prompt-memory.d.ts.map +1 -0
  169. package/lib/surface/prompt-memory.js +167 -0
  170. package/lib/surface/prompt-memory.js.map +1 -0
  171. package/lib/surface/session-lifecycle.d.ts +120 -0
  172. package/lib/surface/session-lifecycle.d.ts.map +1 -0
  173. package/lib/surface/session-lifecycle.js +321 -0
  174. package/lib/surface/session-lifecycle.js.map +1 -0
  175. package/lib/surface/session-picker.d.ts +39 -0
  176. package/lib/surface/session-picker.d.ts.map +1 -0
  177. package/lib/surface/session-picker.js +107 -0
  178. package/lib/surface/session-picker.js.map +1 -0
  179. package/lib/surface/session-view.d.ts +86 -0
  180. package/lib/surface/session-view.d.ts.map +1 -0
  181. package/lib/surface/session-view.js +215 -0
  182. package/lib/surface/session-view.js.map +1 -0
  183. package/lib/surface/staged-turns.d.ts +81 -0
  184. package/lib/surface/staged-turns.d.ts.map +1 -0
  185. package/lib/surface/staged-turns.js +206 -0
  186. package/lib/surface/staged-turns.js.map +1 -0
  187. package/lib/surface/terminal-lifecycle.d.ts +76 -0
  188. package/lib/surface/terminal-lifecycle.d.ts.map +1 -0
  189. package/lib/surface/terminal-lifecycle.js +222 -0
  190. package/lib/surface/terminal-lifecycle.js.map +1 -0
  191. package/lib/terminal/warning-screen.d.ts +8 -1
  192. package/lib/terminal/warning-screen.d.ts.map +1 -1
  193. package/lib/terminal/warning-screen.js +9 -0
  194. package/lib/terminal/warning-screen.js.map +1 -1
  195. package/lib/terminal-text/scan.d.ts +44 -0
  196. package/lib/terminal-text/scan.d.ts.map +1 -0
  197. package/lib/terminal-text/scan.js +195 -0
  198. package/lib/terminal-text/scan.js.map +1 -0
  199. package/lib/terminal-text/sgr.d.ts +32 -0
  200. package/lib/terminal-text/sgr.d.ts.map +1 -0
  201. package/lib/terminal-text/sgr.js +203 -0
  202. package/lib/terminal-text/sgr.js.map +1 -0
  203. package/lib/terminal-text.d.ts +1 -1
  204. package/lib/terminal-text.d.ts.map +1 -1
  205. package/lib/terminal-text.js +2 -379
  206. package/lib/terminal-text.js.map +1 -1
  207. package/lib/theme-command.js +2 -1
  208. package/lib/theme-command.js.map +1 -1
  209. package/lib/theme-defaults.d.ts +64 -0
  210. package/lib/theme-defaults.d.ts.map +1 -0
  211. package/lib/theme-defaults.js +248 -0
  212. package/lib/theme-defaults.js.map +1 -0
  213. package/lib/theme-resolver.d.ts +36 -0
  214. package/lib/theme-resolver.d.ts.map +1 -0
  215. package/lib/theme-resolver.js +112 -0
  216. package/lib/theme-resolver.js.map +1 -0
  217. package/lib/theme-schema.d.ts +6 -6
  218. package/lib/theme-schema.d.ts.map +1 -1
  219. package/lib/theme-schema.js +3 -2
  220. package/lib/theme-schema.js.map +1 -1
  221. package/lib/theme-settings.d.ts +13 -15
  222. package/lib/theme-settings.d.ts.map +1 -1
  223. package/lib/theme-settings.js +27 -19
  224. package/lib/theme-settings.js.map +1 -1
  225. package/lib/theme-tokens.d.ts +1 -90
  226. package/lib/theme-tokens.d.ts.map +1 -1
  227. package/lib/theme-tokens.js +11 -341
  228. package/lib/theme-tokens.js.map +1 -1
  229. package/lib/theme.d.ts +1 -1
  230. package/lib/theme.d.ts.map +1 -1
  231. package/lib/theme.js +2 -1
  232. package/lib/theme.js.map +1 -1
  233. package/lib/tool-display.d.ts.map +1 -1
  234. package/lib/tool-display.js +2 -1
  235. package/lib/tool-display.js.map +1 -1
  236. package/lib/transcript/message-content.d.ts +21 -0
  237. package/lib/transcript/message-content.d.ts.map +1 -0
  238. package/lib/transcript/message-content.js +61 -0
  239. package/lib/transcript/message-content.js.map +1 -0
  240. package/lib/transcript/tool-calls.d.ts +106 -0
  241. package/lib/transcript/tool-calls.d.ts.map +1 -0
  242. package/lib/transcript/tool-calls.js +254 -0
  243. package/lib/transcript/tool-calls.js.map +1 -0
  244. package/lib/transcript.d.ts +38 -43
  245. package/lib/transcript.d.ts.map +1 -1
  246. package/lib/transcript.js +58 -245
  247. package/lib/transcript.js.map +1 -1
  248. package/lib/ui/copy.d.ts +17 -0
  249. package/lib/ui/copy.d.ts.map +1 -0
  250. package/lib/ui/copy.js +104 -0
  251. package/lib/ui/copy.js.map +1 -0
  252. package/lib/ui/dock.d.ts +35 -3
  253. package/lib/ui/dock.d.ts.map +1 -1
  254. package/lib/ui/dock.js +124 -23
  255. package/lib/ui/dock.js.map +1 -1
  256. package/lib/ui/editor.d.ts.map +1 -1
  257. package/lib/ui/editor.js +2 -1
  258. package/lib/ui/editor.js.map +1 -1
  259. package/lib/ui/frame.d.ts +31 -0
  260. package/lib/ui/frame.d.ts.map +1 -1
  261. package/lib/ui/frame.js +27 -4
  262. package/lib/ui/frame.js.map +1 -1
  263. package/lib/ui/keymap-picker.d.ts +2 -1
  264. package/lib/ui/keymap-picker.d.ts.map +1 -1
  265. package/lib/ui/keymap-picker.js +1 -0
  266. package/lib/ui/keymap-picker.js.map +1 -1
  267. package/lib/ui/view/gate-card.d.ts +21 -0
  268. package/lib/ui/view/gate-card.d.ts.map +1 -0
  269. package/lib/ui/view/gate-card.js +104 -0
  270. package/lib/ui/view/gate-card.js.map +1 -0
  271. package/lib/ui/view/tool-card.d.ts +138 -0
  272. package/lib/ui/view/tool-card.d.ts.map +1 -0
  273. package/lib/ui/view/tool-card.js +413 -0
  274. package/lib/ui/view/tool-card.js.map +1 -0
  275. package/lib/ui/view/transcript-message.d.ts +62 -0
  276. package/lib/ui/view/transcript-message.d.ts.map +1 -0
  277. package/lib/ui/view/transcript-message.js +158 -0
  278. package/lib/ui/view/transcript-message.js.map +1 -0
  279. package/lib/ui/view.d.ts +87 -156
  280. package/lib/ui/view.d.ts.map +1 -1
  281. package/lib/ui/view.js +122 -556
  282. package/lib/ui/view.js.map +1 -1
  283. package/package.json +3 -1
  284. package/themes/deepseek-blue.yaml +9 -0
  285. package/themes/violet-orbit.yaml +7 -0
@@ -0,0 +1,321 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { SessionId } from '@deepseek-ai/dsh-session';
3
+ import { forkPoint } from "../agent/fork.js";
4
+ import { startAgent } from "../agent/host.js";
5
+ import { driverReportFor, sessionStartReason } from "../herdr/state.js";
6
+ import { pendingPrompts } from "../queue.js";
7
+ import { BELL, shouldRingBell } from "../terminal/bell.js";
8
+ import { windowTitle } from "../terminal/title.js";
9
+ /**
10
+ * The agent this terminal drives: its identity, its activity, and every
11
+ * transition that replaces it. One owner, because a replacement is one thing:
12
+ * the handle, the turn it ran, the scope its cards read through, the transcript
13
+ * folded from it, and its roster all move together.
14
+ */
15
+ /** How often the running-state clock repaints while a turn is open. */
16
+ const STATUS_TICK_MS = 1000;
17
+ export function createSessionLifecycle(ctx, ports) {
18
+ /** The session this surface drives: commands, approvals, and the bell belong to it. */
19
+ let activeSession = ports.initialSession;
20
+ /** The agent in service, or undefined while a transition creates the next one. */
21
+ let agent;
22
+ /** Whether a turn is open, which is what the clock repaints for. */
23
+ let turnOpen = false;
24
+ /** When the open turn started, which the status facts time it from. */
25
+ let turnStartedAt;
26
+ /** Whether a session was really opened, which is what an exit hint can name. */
27
+ let sessionOpened = false;
28
+ // The queue is read from the agent this terminal drives rather than from the
29
+ // session on screen, because it sits on the editor that submits to that agent.
30
+ const queuedPrompts = () => pendingPrompts(ctx, ports.liveSession(activeSession));
31
+ // Only a running turn has anything to say over time, so the clock stops with it.
32
+ const statusTicker = setInterval(() => {
33
+ if (turnOpen)
34
+ ports.render();
35
+ }, STATUS_TICK_MS);
36
+ ports.disposers.push(() => clearInterval(statusTicker));
37
+ const stopClock = () => clearInterval(statusTicker);
38
+ /**
39
+ * Let go of the agent in service and everything projected from it, handing the
40
+ * handle back to be stopped.
41
+ *
42
+ * `clearScope` is the path's, not this helper's: a replacement drops the
43
+ * outgoing scope before stopping its agent, and an open that folds history of
44
+ * its own relies on the scope it installs.
45
+ */
46
+ const letGoOfOutgoing = (clearScope) => {
47
+ const previous = agent;
48
+ agent = undefined;
49
+ turnOpen = false;
50
+ // The outgoing turn's clock dies with its agent; leaving it set would time
51
+ // the session being joined by work it never ran.
52
+ turnStartedAt = undefined;
53
+ if (clearScope)
54
+ ports.clearPresentScope();
55
+ ports.resetTranscript();
56
+ ports.resetRoster();
57
+ return previous;
58
+ };
59
+ const disposeOutgoing = async () => {
60
+ const previous = letGoOfOutgoing(true);
61
+ if (previous !== undefined)
62
+ await previous.dispose();
63
+ };
64
+ const openAgent = async (id, resume, fork) => {
65
+ // Settled before the transcript is touched, so a refusal leaves neither a
66
+ // half-replayed session nor a half-composed agent behind.
67
+ const preset = await ports.presetFor(id, resume, fork);
68
+ const handle = await startAgent(ctx, {
69
+ sessionId: id,
70
+ resume,
71
+ model: ports.model,
72
+ provider: ports.provider,
73
+ cwd: process.cwd(),
74
+ preset,
75
+ setup: async (agentCtx) => {
76
+ ports.installModelChoice(agentCtx);
77
+ if (preset !== undefined)
78
+ await ports.mountPreset(agentCtx, preset);
79
+ },
80
+ ...(fork === undefined ? {} : { fork }),
81
+ });
82
+ sessionOpened = true;
83
+ activeSession = id;
84
+ ports.setViewed(id);
85
+ agent = handle;
86
+ // A cursor counts the turns of one log; the session just opened has its own.
87
+ ports.stagedSessionOpened(id);
88
+ ports.promptMemorySessionOpened();
89
+ // agent/status is emitted on transitions only, so a driver that was
90
+ // already running when this surface attached — a resume that wakes
91
+ // straight away — would otherwise stay unreported until it stops. The
92
+ // status is read once here and settled before the session identity, so the
93
+ // report that carries the new session id states the driver's real phase
94
+ // rather than the one the previous session left behind.
95
+ ports.herdr.driver(handle.agent.status);
96
+ // The agent's own id is reported rather than the requested one: a resume can
97
+ // be answered by the session the log actually holds.
98
+ ports.herdr.session({
99
+ id: String(handle.sessionId),
100
+ cwd: process.cwd(),
101
+ reason: sessionStartReason({ forked: fork !== undefined, resumed: resume }),
102
+ });
103
+ // A session with no history to fold still has to present its first live
104
+ // card through the right scope, so the scope is set before any event can.
105
+ ports.setPresentScope(handle.agent);
106
+ // Replayed only once the agent exists, because the fold reads every card
107
+ // through the scope the preset mounted; a fold before that scope existed
108
+ // degraded each replayed card to a bare generic row. The agent's loop is
109
+ // live by now, so the fold and the stream race over the same events; the
110
+ // durable sequence number is what keeps one event from landing twice.
111
+ if (resume)
112
+ await ports.replay(id);
113
+ // A branch inherits the conversation the reader was already reading, so it
114
+ // opens on that history rather than on an empty screen.
115
+ if (fork !== undefined)
116
+ await ports.fold(id);
117
+ ports.disposers.push(() => {
118
+ void handle.dispose();
119
+ });
120
+ ports.installCompletion();
121
+ ports.notice(`session ${handle.sessionId}${resume ? ' (resumed)' : ''}`);
122
+ ports.render();
123
+ // Returned so a caller that replaced the handle can send through the new
124
+ // one without a fresh read of state TypeScript can no longer widen.
125
+ return handle;
126
+ };
127
+ const switchSession = async (id) => {
128
+ await disposeOutgoing();
129
+ await openAgent(id, true);
130
+ };
131
+ const runNewCommand = (title) => {
132
+ if (agent === undefined) {
133
+ ports.notice('the agent is still starting; try again in a moment');
134
+ ports.render();
135
+ return;
136
+ }
137
+ void (async () => {
138
+ const previous = letGoOfOutgoing(false);
139
+ if (previous !== undefined)
140
+ await previous.dispose();
141
+ await openAgent(SessionId(`tui-session-${randomUUID()}`), false);
142
+ if (title !== '')
143
+ runRenameCommand(title);
144
+ ports.notice('started a new session');
145
+ ports.render();
146
+ })().catch((error) => {
147
+ ports.notice(`could not start a session: ${error instanceof Error ? error.message : String(error)}`);
148
+ ports.render();
149
+ });
150
+ };
151
+ /**
152
+ * Compose this session's agent again without leaving the conversation: a
153
+ * preset's standing mount only re-reads its composition file for an agent that
154
+ * joins after the file changed, and the durable log is replayed afterwards, so
155
+ * the reader keeps the conversation they were reading.
156
+ */
157
+ const runReloadCommand = () => {
158
+ // A failed reload leaves no agent behind, so the command has to be usable
159
+ // again: the retry is what makes a broken composition file recoverable,
160
+ // while a surface that has opened no session yet is still starting.
161
+ if (agent === undefined && !sessionOpened) {
162
+ ports.notice('the agent is still starting; try again in a moment');
163
+ ports.render();
164
+ return;
165
+ }
166
+ const queued = queuedPrompts();
167
+ // Work the reader would lose is a decision, and the interrupt key already
168
+ // owns that decision: it stops the turn and hands queued words back to the
169
+ // bar. Reopening the session drops the inbox, so a reload that would take
170
+ // those words asks for the key instead of asking a question of its own.
171
+ if (turnOpen || queued.length > 0) {
172
+ ports.notice(queued.length > 0
173
+ ? `${queued.length} queued ${queued.length === 1 ? 'prompt' : 'prompts'} would be dropped — ctrl+c hands them back to the bar, then /reload`
174
+ : 'a turn is running — ctrl+c interrupts it first (delivered text is kept), then /reload');
175
+ ports.render();
176
+ return;
177
+ }
178
+ const id = activeSession;
179
+ void (async () => {
180
+ // The same transition a session switch takes, aimed at the session
181
+ // already open: dispose, then join its preset generation anew.
182
+ await switchSession(id);
183
+ ports.notice("reloaded this session's composition; the transcript was replayed");
184
+ ports.render();
185
+ })().catch((error) => {
186
+ const reason = error instanceof Error ? error.message : String(error);
187
+ ports.notice(`could not reload: ${reason} — fix the composition and /reload again`);
188
+ ports.render();
189
+ });
190
+ };
191
+ const runForkCommand = (title) => {
192
+ if (agent === undefined) {
193
+ ports.notice('the agent is still starting; try again in a moment');
194
+ ports.render();
195
+ return;
196
+ }
197
+ void (async () => {
198
+ const source = activeSession;
199
+ const events = await ports.sessionEvents(source);
200
+ const point = forkPoint(events);
201
+ if (point === undefined) {
202
+ ports.notice('nothing to fork yet: this session has no completed turn');
203
+ ports.render();
204
+ return;
205
+ }
206
+ const childId = SessionId(`tui-session-${randomUUID()}`);
207
+ const previous = letGoOfOutgoing(false);
208
+ if (previous !== undefined)
209
+ await previous.dispose();
210
+ await openAgent(childId, false, { from: source, events: events.slice(0, point.inheritedEvents) });
211
+ if (title !== '')
212
+ runRenameCommand(title);
213
+ ports.notice(`forked from ${source} at event ${point.boundarySeq} — ${point.inheritedEvents} inherited`);
214
+ ports.render();
215
+ })().catch((error) => {
216
+ ports.notice(`could not fork: ${error instanceof Error ? error.message : String(error)}`);
217
+ ports.render();
218
+ });
219
+ };
220
+ /**
221
+ * Give this session a title: it is what the resume picker shows, so a reader
222
+ * who has several sessions can name the one they are in.
223
+ */
224
+ const runRenameCommand = (title) => {
225
+ if (title === '') {
226
+ ports.notice('use /rename <title>; the title is what the resume picker shows');
227
+ ports.render();
228
+ return;
229
+ }
230
+ const session = ctx.get('sessions')?.get?.(activeSession);
231
+ const titles = ctx.get('sessionTitle');
232
+ if (session === undefined || typeof titles?.rename !== 'function') {
233
+ ports.notice('this profile has no session-title service, so this session cannot be renamed');
234
+ ports.render();
235
+ return;
236
+ }
237
+ try {
238
+ const accepted = titles.rename(session, title);
239
+ ports.notice(`session renamed to "${typeof accepted?.title === 'string' ? accepted.title : title}"`);
240
+ }
241
+ catch (error) {
242
+ ports.notice(`could not rename: ${error instanceof Error ? error.message : String(error)}`);
243
+ }
244
+ ports.render();
245
+ };
246
+ /**
247
+ * The driven half of one durable event.
248
+ *
249
+ * The surface state — activity, timer, title, bell, job board — belongs to the
250
+ * agent this terminal drives, even while a child is on screen.
251
+ */
252
+ const observe = (session, event) => {
253
+ if (session.id !== activeSession)
254
+ return;
255
+ // The parent's catalog names the child; lifecycle events carry only its id.
256
+ if (event.type === 'subagent/catalog') {
257
+ ports.acceptCatalog(event.data);
258
+ ports.render();
259
+ }
260
+ if (event.type === 'turn/start') {
261
+ turnOpen = true;
262
+ turnStartedAt = Date.now();
263
+ ports.writeTerminal(windowTitle(process.cwd(), 'working'));
264
+ }
265
+ if (event.type === 'turn/end') {
266
+ const ranFor = turnStartedAt === undefined ? 0 : Date.now() - turnStartedAt;
267
+ turnOpen = false;
268
+ turnStartedAt = undefined;
269
+ // An undo may be parked waiting for exactly this boundary.
270
+ ports.turnSettled();
271
+ ports.writeTerminal(windowTitle(process.cwd(), 'ready'));
272
+ if (shouldRingBell({ bell: ports.bell, ranForMs: ranFor, exiting: ports.exiting() }))
273
+ ports.writeTerminal(BELL);
274
+ // A job the turn started may have settled while the reader was watching
275
+ // something else, and nothing else refreshes a live board.
276
+ ports.refreshJobs();
277
+ }
278
+ // A claim or a discard changes what is queued, and that belongs to this
279
+ // session even while the transcript shows a child's conversation.
280
+ if (event.type === 'agent/inbox/spliced')
281
+ ports.render();
282
+ };
283
+ /** The name is cast so a rename in the harness cannot break this compilation. */
284
+ const listenFor = (name, handler) => ctx.on(name, handler);
285
+ /**
286
+ * The listeners that follow the driver rather than each turn: a run chaining
287
+ * turns through a pending inbox is one stretch of work, and a turn boundary
288
+ * inside it would read as done while the agent is still working; the turn
289
+ * events keep the title and the bell, the reader's own conversation.
290
+ */
291
+ const driverListeners = () => [
292
+ listenFor('agent/status', payload => {
293
+ // Read against the driven session at delivery time: the reader can switch
294
+ // sessions between two transitions, and the row must follow the one this
295
+ // terminal now drives.
296
+ const status = driverReportFor(payload, activeSession);
297
+ if (status === undefined)
298
+ return;
299
+ ports.herdr.driver(status);
300
+ }),
301
+ ];
302
+ return {
303
+ activeSession: () => activeSession,
304
+ drivingAgent: () => agent,
305
+ turnRunning: () => turnOpen,
306
+ activity: () => ({ running: turnOpen, startedAt: turnStartedAt }),
307
+ sessionOpened: () => sessionOpened,
308
+ queuedPrompts,
309
+ stopClock,
310
+ disposeOutgoing,
311
+ openAgent,
312
+ switchSession,
313
+ runNewCommand,
314
+ runReloadCommand,
315
+ runForkCommand,
316
+ runRenameCommand,
317
+ observe,
318
+ driverListeners,
319
+ };
320
+ }
321
+ //# sourceMappingURL=session-lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-lifecycle.js","sourceRoot":"","sources":["../../src/surface/session-lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import { SessionId } from '@deepseek-ai/dsh-session';
3
+ import type { Keymap } from '../input/actions.ts';
4
+ import { SessionPicker } from '../ui/picker.ts';
5
+ /**
6
+ * What the stored-session owner needs from the surface that composes it.
7
+ *
8
+ * The keys are read at call time, because a settings edit while the list is
9
+ * open moves the chords its hints name; the picker operation is a port rather
10
+ * than an import, because the keyboard's lifetime belongs to the surface.
11
+ */
12
+ export interface SessionPickerPorts {
13
+ readonly keymap: () => Keymap;
14
+ readonly notice: (text: string) => void;
15
+ readonly render: () => void;
16
+ /**
17
+ * Reject when this run cannot open that session under the mode it named.
18
+ *
19
+ * The composing surface owns what a mode is and which one this run named, so
20
+ * it decides when there is a disagreement to look for at all.
21
+ */
22
+ readonly validateStoredPreset: (id: string) => Promise<void>;
23
+ /** Take the keyboard for the list and answer with the id it settled on. */
24
+ readonly openPicker: (picker: SessionPicker, vet?: (id: string) => Promise<string | undefined>) => Promise<string | undefined>;
25
+ }
26
+ /** The one read the composing surface routes to this owner. */
27
+ export interface SessionPickerChoice {
28
+ /** Which stored session to open, or undefined when the reader asked for none. */
29
+ readonly chooseSession: () => Promise<SessionId | undefined>;
30
+ }
31
+ /**
32
+ * The stored sessions a bare `--resume` asks the reader to choose between.
33
+ *
34
+ * The list is drawn by id before any log is opened: reading every title first
35
+ * would make the picker as slow as the slowest session, and a session whose
36
+ * log this build cannot read is still one the reader may want back.
37
+ */
38
+ export declare function createSessionPicker(ctx: Context, ports: SessionPickerPorts): SessionPickerChoice;
39
+ //# sourceMappingURL=session-picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-picker.d.ts","sourceRoot":"","sources":["../../src/surface/session-picker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAA;AAQpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAY/C;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,MAAM,CAAA;IAC7B,QAAQ,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAA;IAC3B;;;;;OAKG;IACH,QAAQ,CAAC,oBAAoB,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5D,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,CACnB,MAAM,EAAE,aAAa,EACrB,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,KAC9C,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAA;CACjC;AAED,+DAA+D;AAC/D,MAAM,WAAW,mBAAmB;IAClC,iFAAiF;IACjF,QAAQ,CAAC,aAAa,EAAE,MAAM,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAA;CAC7D;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,kBAAkB,GAAG,mBAAmB,CA0FhG"}
@@ -0,0 +1,107 @@
1
+ import { SessionId } from '@deepseek-ai/dsh-session';
2
+ import { PICKER_LIMIT, createSessionHistory, readSessionTitle, } from "../agent/history.js";
3
+ import { SessionPicker } from "../ui/picker.js";
4
+ /**
5
+ * Titles read at once.
6
+ *
7
+ * Every title costs a log read, and the list is already on screen without them,
8
+ * so they are pipelined to keep the wait near the slowest log rather than the
9
+ * sum of them — bounded, because a hundred parallel reads is a disk storm the
10
+ * reader would feel elsewhere.
11
+ */
12
+ const TITLE_CONCURRENCY = 4;
13
+ /**
14
+ * The stored sessions a bare `--resume` asks the reader to choose between.
15
+ *
16
+ * The list is drawn by id before any log is opened: reading every title first
17
+ * would make the picker as slow as the slowest session, and a session whose
18
+ * log this build cannot read is still one the reader may want back.
19
+ */
20
+ export function createSessionPicker(ctx, ports) {
21
+ /** Title the listed sessions without making the reader wait for the slowest log. */
22
+ const loadTitles = async (history, sessions, titles) => {
23
+ const queue = [...sessions];
24
+ const worker = async () => {
25
+ for (;;) {
26
+ const next = queue.shift();
27
+ if (next === undefined)
28
+ return;
29
+ try {
30
+ const title = await readSessionTitle(history, next);
31
+ if (title === undefined)
32
+ continue;
33
+ titles.set(next.id, title);
34
+ ports.render();
35
+ }
36
+ catch {
37
+ // A log this build cannot read stays listed by id; the picker is not
38
+ // the place to explain storage, and one bad session is not the list.
39
+ }
40
+ }
41
+ };
42
+ await Promise.all(Array.from({ length: TITLE_CONCURRENCY }, worker));
43
+ };
44
+ /**
45
+ * The stored list, or undefined after telling the reader why there is none.
46
+ *
47
+ * No storage, an empty history, and a listing that throws all end the same way
48
+ * — there is nothing to pick from — and none of them is worth ending the run
49
+ * over, so each is a notice rather than a failure.
50
+ */
51
+ const storedSessions = async () => {
52
+ const history = createSessionHistory(ctx);
53
+ if (history === undefined) {
54
+ ports.notice('this profile has no session storage, so there is nothing to resume');
55
+ ports.render();
56
+ return undefined;
57
+ }
58
+ try {
59
+ const sessions = await history.list(PICKER_LIMIT);
60
+ if (sessions.length === 0) {
61
+ ports.notice('no stored sessions to resume');
62
+ ports.render();
63
+ return undefined;
64
+ }
65
+ return { history, sessions };
66
+ }
67
+ catch (error) {
68
+ ports.notice(`could not list stored sessions: ${error instanceof Error ? error.message : String(error)}`);
69
+ ports.render();
70
+ return undefined;
71
+ }
72
+ };
73
+ /**
74
+ * Why this run cannot open a stored session, or undefined when it can.
75
+ *
76
+ * A session runs the mode its own log recorded, so a `--preset` that
77
+ * disagrees with it can only be refused: the picker asks first so the refusal
78
+ * lands in the list rather than after the terminal has been handed back.
79
+ */
80
+ const refuseReason = async (id) => {
81
+ try {
82
+ await ports.validateStoredPreset(id);
83
+ return undefined;
84
+ }
85
+ catch (error) {
86
+ return error instanceof Error ? error.message : String(error);
87
+ }
88
+ };
89
+ /**
90
+ * Take the keyboard for a picker.
91
+ *
92
+ * The list is already in hand, so the picker is interactive immediately while
93
+ * the titles that make its rows recognizable stream in behind it.
94
+ */
95
+ const askForSession = async (history, sessions) => {
96
+ const titles = new Map();
97
+ void loadTitles(history, sessions, titles);
98
+ const picked = await ports.openPicker(new SessionPicker(sessions, () => titles, undefined, ports.keymap), refuseReason);
99
+ return picked === undefined ? undefined : SessionId(picked);
100
+ };
101
+ const chooseSession = async () => {
102
+ const listed = await storedSessions();
103
+ return listed === undefined ? undefined : askForSession(listed.history, listed.sessions);
104
+ };
105
+ return { chooseSession };
106
+ }
107
+ //# sourceMappingURL=session-picker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-picker.js","sourceRoot":"","sources":["../../src/surface/session-picker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ import type { Context } from '@deepseek-ai/cordis';
2
+ import type { Agent } from '@deepseek-ai/dsh-agent';
3
+ import type { SessionId } from '@deepseek-ai/dsh-session';
4
+ import type { ForkEvent } from '../agent/fork.ts';
5
+ import { type Keymap } from '../input/actions.ts';
6
+ import { TranscriptModel } from '../transcript.ts';
7
+ import { type WorkState } from '../work.ts';
8
+ /** What the reader presses to leave a view they did not open. */
9
+ export declare const backHint: (map: Keymap) => string;
10
+ /**
11
+ * What the transcript owner needs from the surface that composes it.
12
+ *
13
+ * The identity, the cutoff and the scope are read at call time: all three can
14
+ * change between two folds, and a captured copy would fold — or degrade a card
15
+ * through — the session this terminal drove before the reader moved.
16
+ */
17
+ export interface SessionViewPorts {
18
+ /** The session the transcript opens on, named by the run that launched this surface. */
19
+ readonly initialSession: SessionId;
20
+ /** The session this terminal drives: commands, approvals, and the bell belong to it. */
21
+ readonly drivenSession: () => SessionId;
22
+ /** Event index the transcript must not fold past while turns are hidden. */
23
+ readonly stagedCutoff: () => number | undefined;
24
+ /** The world a folded card reads its tool through; a stored session has none. */
25
+ readonly agentScope: (id: SessionId) => Agent | undefined;
26
+ /** A live session's own events, or undefined when this process does not run it. */
27
+ readonly liveEvents: (id: SessionId) => readonly ForkEvent[] | undefined;
28
+ readonly render: () => void;
29
+ }
30
+ /** The transcript on screen, and every read and operation the composing surface takes from it. */
31
+ export interface SessionView {
32
+ /** The session the transcript is showing, which can be one of its children. */
33
+ readonly viewed: () => SessionId;
34
+ readonly viewingChild: () => boolean;
35
+ readonly notice: (message: string) => void;
36
+ readonly marker: (text: string) => void;
37
+ readonly reportError: (error: unknown) => void;
38
+ /** The model the transcript is drawn from, and what an export writes out. */
39
+ readonly model: TranscriptModel;
40
+ /** What the transcript folded: todos, the goal, and plan mode. */
41
+ readonly workState: () => WorkState;
42
+ /** Every event of a session, from memory when this process runs it. */
43
+ readonly sessionEvents: (id: SessionId) => Promise<readonly ForkEvent[]>;
44
+ /** The scope a folded card reads through. */
45
+ readonly setPresentScope: (scope: Agent | undefined) => void;
46
+ /**
47
+ * Drop that scope. Also the teardown disposer the composition root pushes.
48
+ *
49
+ * The presenter closure outlives the composition's own teardown, so it must
50
+ * not keep an agent alive after its world unwinds.
51
+ */
52
+ readonly clearPresentScope: () => void;
53
+ /** Start a fresh transcript: every reset revokes reads started for the previous view. */
54
+ readonly reset: () => () => boolean;
55
+ /** Show a session without folding it; the caller owns the fold that follows. */
56
+ readonly setViewed: (id: SessionId) => void;
57
+ /** Fold one session's history, or the driven one's through a staged cutoff. */
58
+ readonly fold: (id: SessionId, through?: number, current?: () => boolean) => Promise<number>;
59
+ /** Fold a stored log as a replay, which reports its own failure in a notice. */
60
+ readonly replay: (id: SessionId) => Promise<void>;
61
+ /** Show another session in the transcript without leaving the one this terminal drives. */
62
+ readonly show: (id: SessionId) => Promise<void>;
63
+ /** Come back to the transcript of the session this terminal drives. */
64
+ readonly showDriven: () => Promise<void>;
65
+ /** The viewed half of one durable event: the fold and the repaint it earns. */
66
+ readonly observe: (id: SessionId, event: ForkEvent) => void;
67
+ /**
68
+ * Register the two listeners that follow the viewed agent's own stream.
69
+ *
70
+ * They are returned rather than pushed here so the composition root keeps one
71
+ * ordered list of teardowns, which is unwound in reverse registration order.
72
+ */
73
+ readonly agentListeners: () => readonly (() => void)[];
74
+ }
75
+ /**
76
+ * The transcript on screen: what is drawn, and never which agent is driven.
77
+ *
78
+ * The model, the work fold and the identity they are folded for are one owner
79
+ * because the reader's view is one thing: a durable event reaches both folds,
80
+ * and a switch of identity resets both. What this owner drives — the agent, its
81
+ * staged cutoff, and the terminal it paints — stays with the surface that
82
+ * composes it, so a reader can watch a child's conversation without moving the
83
+ * commands, the approvals, or the bell.
84
+ */
85
+ export declare function createSessionView(ctx: Context, ports: SessionViewPorts): SessionView;
86
+ //# sourceMappingURL=session-view.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-view.d.ts","sourceRoot":"","sources":["../../src/surface/session-view.ts"],"names":[],"mappings":"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"}