@astralyn/pi 1.4.9 → 1.4.10

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 (204) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/bundle/chunks/{chunk-3PKXUKTB.js → chunk-6GTUUUCJ.js} +123 -123
  3. package/dist/bundle/chunks/{chunk-BAGHIP5J.js → chunk-MF3T3ETJ.js} +3 -3
  4. package/dist/bundle/chunks/{chunk-F66AY3WR.js → chunk-UCH27AVQ.js} +1 -1
  5. package/dist/bundle/chunks/{execute-P22VMM2H.js → execute-FQKRO4XJ.js} +1 -1
  6. package/dist/bundle/chunks/{virtual-modules-VKMBQTR2.js → virtual-modules-6IJ6V2CG.js} +1 -1
  7. package/dist/bundle/cli.js +1 -1
  8. package/dist/bundle/index.js +1 -1
  9. package/dist/bundle/rpc-entry.js +1 -1
  10. package/dist/core/agent-session.d.ts +34 -0
  11. package/dist/core/agent-session.d.ts.map +1 -1
  12. package/dist/core/agent-session.js +99 -2
  13. package/dist/core/agent-session.js.map +1 -1
  14. package/dist/core/isolated-session.d.ts +7 -2
  15. package/dist/core/isolated-session.d.ts.map +1 -1
  16. package/dist/core/isolated-session.js +7 -3
  17. package/dist/core/isolated-session.js.map +1 -1
  18. package/dist/core/session-manager.d.ts +17 -1
  19. package/dist/core/session-manager.d.ts.map +1 -1
  20. package/dist/core/session-manager.js +29 -0
  21. package/dist/core/session-manager.js.map +1 -1
  22. package/dist/core/tasks/delivery.d.ts +42 -7
  23. package/dist/core/tasks/delivery.d.ts.map +1 -1
  24. package/dist/core/tasks/delivery.js +129 -15
  25. package/dist/core/tasks/delivery.js.map +1 -1
  26. package/dist/core/tasks/execution.d.ts +27 -14
  27. package/dist/core/tasks/execution.d.ts.map +1 -1
  28. package/dist/core/tasks/execution.js +90 -86
  29. package/dist/core/tasks/execution.js.map +1 -1
  30. package/dist/core/tasks/limits.d.ts +13 -1
  31. package/dist/core/tasks/limits.d.ts.map +1 -1
  32. package/dist/core/tasks/limits.js +14 -1
  33. package/dist/core/tasks/limits.js.map +1 -1
  34. package/dist/core/tasks/output.d.ts +9 -1
  35. package/dist/core/tasks/output.d.ts.map +1 -1
  36. package/dist/core/tasks/output.js +23 -10
  37. package/dist/core/tasks/output.js.map +1 -1
  38. package/dist/core/tasks/presentation.d.ts +1 -1
  39. package/dist/core/tasks/presentation.d.ts.map +1 -1
  40. package/dist/core/tasks/presentation.js +6 -4
  41. package/dist/core/tasks/presentation.js.map +1 -1
  42. package/dist/core/tasks/record.d.ts +41 -29
  43. package/dist/core/tasks/record.d.ts.map +1 -1
  44. package/dist/core/tasks/record.js +82 -37
  45. package/dist/core/tasks/record.js.map +1 -1
  46. package/dist/core/tasks/reminder.js +2 -2
  47. package/dist/core/tasks/reminder.js.map +1 -1
  48. package/dist/core/tasks/runtime.d.ts +17 -14
  49. package/dist/core/tasks/runtime.d.ts.map +1 -1
  50. package/dist/core/tasks/runtime.js +68 -116
  51. package/dist/core/tasks/runtime.js.map +1 -1
  52. package/dist/core/tasks/scheduler.d.ts +3 -1
  53. package/dist/core/tasks/scheduler.d.ts.map +1 -1
  54. package/dist/core/tasks/scheduler.js +16 -12
  55. package/dist/core/tasks/scheduler.js.map +1 -1
  56. package/dist/core/tasks/session.d.ts +24 -3
  57. package/dist/core/tasks/session.d.ts.map +1 -1
  58. package/dist/core/tasks/session.js +73 -9
  59. package/dist/core/tasks/session.js.map +1 -1
  60. package/dist/core/tasks/store.d.ts +17 -4
  61. package/dist/core/tasks/store.d.ts.map +1 -1
  62. package/dist/core/tasks/store.js +45 -48
  63. package/dist/core/tasks/store.js.map +1 -1
  64. package/dist/core/tasks/types.d.ts +72 -29
  65. package/dist/core/tasks/types.d.ts.map +1 -1
  66. package/dist/core/tasks/types.js +7 -0
  67. package/dist/core/tasks/types.js.map +1 -1
  68. package/dist/core/tasks/wait.d.ts +19 -0
  69. package/dist/core/tasks/wait.d.ts.map +1 -0
  70. package/dist/core/tasks/wait.js +45 -0
  71. package/dist/core/tasks/wait.js.map +1 -0
  72. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  73. package/dist/core/tools/shell-execution.js +2 -1
  74. package/dist/core/tools/shell-execution.js.map +1 -1
  75. package/dist/core/tools/shell-tool.d.ts.map +1 -1
  76. package/dist/core/tools/shell-tool.js +20 -13
  77. package/dist/core/tools/shell-tool.js.map +1 -1
  78. package/dist/extensions/agent/activity-lines.d.ts +10 -0
  79. package/dist/extensions/agent/activity-lines.d.ts.map +1 -0
  80. package/dist/extensions/agent/activity-lines.js +76 -0
  81. package/dist/extensions/agent/activity-lines.js.map +1 -0
  82. package/dist/extensions/agent/activity.d.ts +25 -4
  83. package/dist/extensions/agent/activity.d.ts.map +1 -1
  84. package/dist/extensions/agent/activity.js +76 -21
  85. package/dist/extensions/agent/activity.js.map +1 -1
  86. package/dist/extensions/agent/artifacts.d.ts +15 -0
  87. package/dist/extensions/agent/artifacts.d.ts.map +1 -0
  88. package/dist/extensions/agent/artifacts.js +44 -0
  89. package/dist/extensions/agent/artifacts.js.map +1 -0
  90. package/dist/extensions/agent/progress.d.ts +30 -4
  91. package/dist/extensions/agent/progress.d.ts.map +1 -1
  92. package/dist/extensions/agent/progress.js +84 -11
  93. package/dist/extensions/agent/progress.js.map +1 -1
  94. package/dist/extensions/agent/render.d.ts.map +1 -1
  95. package/dist/extensions/agent/render.js +8 -24
  96. package/dist/extensions/agent/render.js.map +1 -1
  97. package/dist/extensions/agent/report.d.ts +11 -3
  98. package/dist/extensions/agent/report.d.ts.map +1 -1
  99. package/dist/extensions/agent/report.js +32 -7
  100. package/dist/extensions/agent/report.js.map +1 -1
  101. package/dist/extensions/agent/tool.d.ts.map +1 -1
  102. package/dist/extensions/agent/tool.js +20 -5
  103. package/dist/extensions/agent/tool.js.map +1 -1
  104. package/dist/extensions/agent/types.d.ts +2 -0
  105. package/dist/extensions/agent/types.d.ts.map +1 -1
  106. package/dist/extensions/agent/types.js.map +1 -1
  107. package/dist/extensions/agent/worker.d.ts +7 -0
  108. package/dist/extensions/agent/worker.d.ts.map +1 -1
  109. package/dist/extensions/agent/worker.js +9 -3
  110. package/dist/extensions/agent/worker.js.map +1 -1
  111. package/dist/extensions/search/index.d.ts.map +1 -1
  112. package/dist/extensions/search/index.js +6 -7
  113. package/dist/extensions/search/index.js.map +1 -1
  114. package/dist/extensions/tasks/tool/actions.d.ts.map +1 -1
  115. package/dist/extensions/tasks/tool/actions.js +15 -11
  116. package/dist/extensions/tasks/tool/actions.js.map +1 -1
  117. package/dist/extensions/tasks/tool/schema.d.ts +1 -1
  118. package/dist/extensions/tasks/tool/schema.d.ts.map +1 -1
  119. package/dist/extensions/tasks/tool/schema.js +5 -5
  120. package/dist/extensions/tasks/tool/schema.js.map +1 -1
  121. package/dist/extensions/tasks/tool/types.d.ts +2 -0
  122. package/dist/extensions/tasks/tool/types.d.ts.map +1 -1
  123. package/dist/extensions/tasks/tool/types.js.map +1 -1
  124. package/dist/extensions/tasks/tool.d.ts.map +1 -1
  125. package/dist/extensions/tasks/tool.js +3 -2
  126. package/dist/extensions/tasks/tool.js.map +1 -1
  127. package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -1
  128. package/dist/extensions/tasks/ui/completion-render.js +2 -2
  129. package/dist/extensions/tasks/ui/completion-render.js.map +1 -1
  130. package/dist/extensions/tasks/ui/footer.d.ts +37 -0
  131. package/dist/extensions/tasks/ui/footer.d.ts.map +1 -0
  132. package/dist/extensions/tasks/ui/footer.js +129 -0
  133. package/dist/extensions/tasks/ui/footer.js.map +1 -0
  134. package/dist/extensions/tasks/ui/frame.d.ts +36 -0
  135. package/dist/extensions/tasks/ui/frame.d.ts.map +1 -0
  136. package/dist/extensions/tasks/ui/frame.js +33 -0
  137. package/dist/extensions/tasks/ui/frame.js.map +1 -0
  138. package/dist/extensions/tasks/ui/help.d.ts +6 -0
  139. package/dist/extensions/tasks/ui/help.d.ts.map +1 -0
  140. package/dist/extensions/tasks/ui/help.js +53 -0
  141. package/dist/extensions/tasks/ui/help.js.map +1 -0
  142. package/dist/extensions/tasks/ui/inspector.d.ts +4 -3
  143. package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -1
  144. package/dist/extensions/tasks/ui/inspector.js +25 -6
  145. package/dist/extensions/tasks/ui/inspector.js.map +1 -1
  146. package/dist/extensions/tasks/ui/layout.d.ts +15 -18
  147. package/dist/extensions/tasks/ui/layout.d.ts.map +1 -1
  148. package/dist/extensions/tasks/ui/layout.js +162 -255
  149. package/dist/extensions/tasks/ui/layout.js.map +1 -1
  150. package/dist/extensions/tasks/ui/list.d.ts +3 -1
  151. package/dist/extensions/tasks/ui/list.d.ts.map +1 -1
  152. package/dist/extensions/tasks/ui/list.js +19 -14
  153. package/dist/extensions/tasks/ui/list.js.map +1 -1
  154. package/dist/extensions/tasks/ui/manager.d.ts +17 -5
  155. package/dist/extensions/tasks/ui/manager.d.ts.map +1 -1
  156. package/dist/extensions/tasks/ui/manager.js +147 -90
  157. package/dist/extensions/tasks/ui/manager.js.map +1 -1
  158. package/dist/extensions/tasks/ui/model.d.ts +32 -5
  159. package/dist/extensions/tasks/ui/model.d.ts.map +1 -1
  160. package/dist/extensions/tasks/ui/model.js +7 -7
  161. package/dist/extensions/tasks/ui/model.js.map +1 -1
  162. package/dist/extensions/tasks/ui/panes.d.ts +40 -0
  163. package/dist/extensions/tasks/ui/panes.d.ts.map +1 -0
  164. package/dist/extensions/tasks/ui/panes.js +144 -0
  165. package/dist/extensions/tasks/ui/panes.js.map +1 -0
  166. package/dist/extensions/tasks/ui/render.d.ts.map +1 -1
  167. package/dist/extensions/tasks/ui/render.js +11 -7
  168. package/dist/extensions/tasks/ui/render.js.map +1 -1
  169. package/dist/extensions/tasks/ui/viewport.d.ts +12 -4
  170. package/dist/extensions/tasks/ui/viewport.d.ts.map +1 -1
  171. package/dist/extensions/tasks/ui/viewport.js +23 -7
  172. package/dist/extensions/tasks/ui/viewport.js.map +1 -1
  173. package/dist/extensions/tasks/ui/views.d.ts +12 -6
  174. package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
  175. package/dist/extensions/tasks/ui/views.js +39 -32
  176. package/dist/extensions/tasks/ui/views.js.map +1 -1
  177. package/dist/modes/interactive/components/session-selector.d.ts +11 -1
  178. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  179. package/dist/modes/interactive/components/session-selector.js +43 -17
  180. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  181. package/dist/modes/print-mode.d.ts.map +1 -1
  182. package/dist/modes/print-mode.js +37 -2
  183. package/dist/modes/print-mode.js.map +1 -1
  184. package/dist/modes/rpc/rpc-client.d.ts +11 -0
  185. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  186. package/dist/modes/rpc/rpc-client.js +48 -0
  187. package/dist/modes/rpc/rpc-client.js.map +1 -1
  188. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  189. package/dist/modes/rpc/rpc-mode.js +1 -0
  190. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  191. package/dist/modes/rpc/rpc-types.d.ts +2 -0
  192. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  193. package/dist/modes/rpc/rpc-types.js.map +1 -1
  194. package/docs/bundled/extensions/agent.md +39 -7
  195. package/docs/bundled/tasks.md +25 -21
  196. package/docs/extensions.md +14 -10
  197. package/docs/json.md +3 -0
  198. package/docs/rpc.md +14 -0
  199. package/docs/sdk.md +11 -1
  200. package/docs/session-format.md +10 -4
  201. package/docs/sessions.md +1 -1
  202. package/docs/usage.md +2 -0
  203. package/npm-shrinkwrap.json +2 -2
  204. package/package.json +1 -1
@@ -6,10 +6,13 @@ import { STATUS_SPINNER_INTERVAL_MS } from "../../../modes/interactive/component
6
6
  import { TaskInspector } from "./inspector.js";
7
7
  import { renderTasksLayout } from "./layout.js";
8
8
  import { TaskList } from "./list.js";
9
- import { isStoppable, TaskSelection } from "./model.js";
9
+ import { TaskSelection } from "./model.js";
10
10
  import { cleanTaskText } from "./text.js";
11
11
  import { TaskViewport } from "./viewport.js";
12
12
  const BROWSE = { kind: "browse" };
13
+ /** Feedback outlives a glance but not the next thing the user does. */
14
+ const FEEDBACK_MS = 4000;
15
+ const QUERY_LIMIT = 512;
13
16
  const actions = [
14
17
  "app.tasks.search",
15
18
  "app.tasks.kill",
@@ -23,6 +26,14 @@ const actions = [
23
26
  "app.tasks.previousFocus",
24
27
  "app.tasks.help",
25
28
  ];
29
+ /** Why a stop or background request cannot apply to this task, for the states the footer does not offer. */
30
+ function unavailableReason(task) {
31
+ if (isTaskTerminal(task.status))
32
+ return "Task already finished.";
33
+ if (task.status === "stopping")
34
+ return "Task is already stopping.";
35
+ return undefined;
36
+ }
26
37
  export class TasksMenu {
27
38
  constructor(options) {
28
39
  this.focused = false;
@@ -41,7 +52,6 @@ export class TasksMenu {
41
52
  theme: options.theme,
42
53
  requestRender: () => options.tui.requestRender(),
43
54
  });
44
- this.search = new Input({ prompt: "Find task: ", placeholder: "title, command, kind or ID" });
45
55
  this.sync();
46
56
  this.selection.selectStartedSinceClose();
47
57
  this.inspector.select(this.selection.selected);
@@ -59,17 +69,21 @@ export class TasksMenu {
59
69
  this.pollTimer.unref?.();
60
70
  this.queueTick(true);
61
71
  }
72
+ /** The search text, owned by the search mode: browsing always sees every retained task. */
73
+ get query() {
74
+ return this.mode.kind === "search" ? this.mode.input.getValue().slice(0, QUERY_LIMIT) : "";
75
+ }
76
+ select(id) {
77
+ this.selection.select(id, this.query);
78
+ }
62
79
  sync() {
63
80
  if (this.disposed || !this.dirty)
64
81
  return;
65
82
  this.dirty = false;
66
- const previous = this.selection.selected;
67
- this.selection.sync(this.options.host.list());
83
+ this.selection.sync(this.options.host.list(), this.query);
68
84
  this.inspector.select(this.selection.selected);
69
85
  this.inspector.prune(new Set(this.selection.all.map((task) => task.id)));
70
86
  const selected = this.selection.selected;
71
- if (selected && isTaskTerminal(selected.status) && previous && !isTaskTerminal(previous.status))
72
- this.feedback = undefined;
73
87
  if (this.mode.kind === "confirmStop" && (this.mode.taskId !== selected?.id || isTaskTerminal(selected.status)))
74
88
  this.setMode(BROWSE);
75
89
  const animates = this.selection.all.some((task) => task.status === "running");
@@ -107,13 +121,31 @@ export class TasksMenu {
107
121
  invalidate() {
108
122
  this.inspector.invalidate();
109
123
  }
110
- /** The one place the mode changes; the search input is focused exactly while searching. */
111
124
  setMode(next) {
112
125
  this.mode = next;
113
- this.search.focused = next.kind === "search";
114
126
  }
115
- /** Unwinds exactly one transient layer; from plain browsing it closes the panel. */
116
- cancel() {
127
+ /** Reports an action that did not do what was asked; it clears on the next input or after a few seconds. */
128
+ notify(tone, text) {
129
+ this.clearFeedback();
130
+ this.feedback = { tone, text };
131
+ this.feedbackTimer = setTimeout(() => {
132
+ this.feedbackTimer = undefined;
133
+ this.feedback = undefined;
134
+ if (!this.disposed)
135
+ this.options.tui.requestRender();
136
+ }, FEEDBACK_MS);
137
+ this.feedbackTimer.unref?.();
138
+ }
139
+ clearFeedback() {
140
+ clearTimeout(this.feedbackTimer);
141
+ this.feedbackTimer = undefined;
142
+ this.feedback = undefined;
143
+ }
144
+ /**
145
+ * Unwinds exactly one layer: search, help or a confirmation; then the inspector back to the
146
+ * list when the list is hidden; from plain browsing it closes the panel.
147
+ */
148
+ escape() {
117
149
  switch (this.mode.kind) {
118
150
  case "search":
119
151
  this.finishSearch(true);
@@ -123,7 +155,10 @@ export class TasksMenu {
123
155
  this.setMode(BROWSE);
124
156
  break;
125
157
  case "browse":
126
- this.close();
158
+ if (this.layout && !this.layout.tooSmall && !this.layout.split && this.focus === "inspector")
159
+ this.focus = "list";
160
+ else
161
+ this.close();
127
162
  break;
128
163
  }
129
164
  }
@@ -140,7 +175,12 @@ export class TasksMenu {
140
175
  }
141
176
  requestStop() {
142
177
  const task = this.selection.selected;
143
- if (task && isStoppable(task))
178
+ if (!task)
179
+ return;
180
+ const reason = unavailableReason(task);
181
+ if (reason)
182
+ this.notify("warning", reason);
183
+ else
144
184
  this.setMode({ kind: "confirmStop", taskId: task.id });
145
185
  }
146
186
  confirmStop() {
@@ -151,14 +191,33 @@ export class TasksMenu {
151
191
  const task = this.selection.selected;
152
192
  if (mode.taskId !== task?.id || isTaskTerminal(task.status))
153
193
  return;
154
- this.feedback = this.options.host.kill(mode.taskId)
155
- ? "Cancellation requested; waiting for cleanup."
156
- : "No new cancellation requested.";
194
+ // A granted request shows as Stopping on the row and header; only a refusal needs saying.
195
+ if (!this.options.host.kill(mode.taskId))
196
+ this.notify("warning", "No new cancellation requested.");
197
+ }
198
+ detachSelected() {
199
+ const task = this.selection.selected;
200
+ if (!task)
201
+ return;
202
+ const reason = unavailableReason(task) ?? (task.mode === "background" ? "Task is already in the background." : "");
203
+ if (reason) {
204
+ this.notify("warning", reason);
205
+ return;
206
+ }
207
+ try {
208
+ // The core decides; a full background lane throws its own explanation.
209
+ if (!this.options.host.detach(task.id))
210
+ this.notify("warning", "This task cannot move to background.");
211
+ }
212
+ catch (error) {
213
+ this.notify("warning", cleanTaskText(error instanceof Error ? error.message : String(error)));
214
+ }
157
215
  }
158
216
  startSearch() {
159
- this.setMode({ kind: "search", restore: { id: this.selection.state.selectedId, focus: this.focus } });
217
+ const input = new Input({ prompt: "Find task: ", placeholder: "title, command, kind or ID" });
218
+ input.focused = true;
219
+ this.setMode({ kind: "search", restore: { id: this.selection.state.selectedId, focus: this.focus }, input });
160
220
  this.focus = "list";
161
- this.search.setValue("");
162
221
  }
163
222
  finishSearch(cancel) {
164
223
  const mode = this.mode;
@@ -169,10 +228,13 @@ export class TasksMenu {
169
228
  return;
170
229
  this.focus = cancel ? mode.restore.focus : "list";
171
230
  this.setMode(BROWSE);
172
- this.selection.query = "";
173
- this.selection.select(id);
231
+ this.select(id);
174
232
  this.selectedChanged();
175
233
  }
234
+ open() {
235
+ if (this.focus === "list" && this.selection.selected)
236
+ this.focus = "inspector";
237
+ }
176
238
  action(key) {
177
239
  switch (key) {
178
240
  case "app.tasks.search":
@@ -189,18 +251,18 @@ export class TasksMenu {
189
251
  break;
190
252
  case "app.tasks.follow":
191
253
  if (this.focus === "inspector" && this.selection.state.tab === "output") {
192
- this.inspector.position.output.jump(true, true);
254
+ this.inspector.position.output.jump(true);
193
255
  this.queueTick(true);
194
256
  }
195
257
  break;
196
258
  case "app.tasks.top":
197
259
  case "app.tasks.bottom":
198
260
  if (this.focus === "list") {
199
- this.selection.select(key === "app.tasks.top" ? this.selection.rows[0]?.id : this.selection.rows.at(-1)?.id);
261
+ this.select(key === "app.tasks.top" ? this.selection.rows[0]?.id : this.selection.rows.at(-1)?.id);
200
262
  this.selectedChanged();
201
263
  }
202
264
  else
203
- this.inspector.position[this.selection.state.tab].jump(key === "app.tasks.bottom", this.selection.state.tab === "output");
265
+ this.inspector.position[this.selection.state.tab].jump(key === "app.tasks.bottom");
204
266
  break;
205
267
  case "app.tasks.kill":
206
268
  this.requestStop();
@@ -208,24 +270,44 @@ export class TasksMenu {
208
270
  case "app.tasks.confirmStop":
209
271
  this.confirmStop();
210
272
  break;
211
- case "app.tasks.detachSelected": {
212
- const task = this.selection.selected;
213
- // The core decides; a full background lane throws its own explanation, shown as feedback.
214
- if (task?.mode === "foreground" && isStoppable(task)) {
215
- this.feedback = this.options.host.detach(task.id)
216
- ? "Selected task moved to background; execution continues."
217
- : "This task cannot move to background.";
218
- }
273
+ case "app.tasks.detachSelected":
274
+ this.detachSelected();
219
275
  break;
220
- }
221
276
  case "app.tasks.help":
222
277
  this.setMode({ kind: "help", viewport: new TaskViewport() });
223
278
  break;
224
279
  }
225
280
  }
281
+ /** Performs what a click on a rendered target asks for. */
282
+ perform(action) {
283
+ switch (action.kind) {
284
+ case "select":
285
+ this.select(action.taskId);
286
+ this.selectedChanged();
287
+ this.focus = "list";
288
+ if (this.mode.kind === "search")
289
+ this.finishSearch(false);
290
+ break;
291
+ case "tab":
292
+ this.focus = "inspector";
293
+ this.selection.state.tab = action.tab;
294
+ break;
295
+ case "key":
296
+ if (action.key === "app.tasks.follow")
297
+ this.focus = "inspector";
298
+ this.action(action.key);
299
+ break;
300
+ case "open":
301
+ this.open();
302
+ break;
303
+ case "back":
304
+ this.escape();
305
+ break;
306
+ }
307
+ }
226
308
  move(direction, page = false) {
227
309
  if (this.mode.kind === "help") {
228
- this.mode.viewport.move(direction, page, false);
310
+ this.mode.viewport.move(direction, page);
229
311
  return;
230
312
  }
231
313
  if (this.focus === "list") {
@@ -236,23 +318,23 @@ export class TasksMenu {
236
318
  const next = page
237
319
  ? Math.max(0, Math.min(rows.length - 1, index + direction * (this.layout?.listPageSize ?? 1)))
238
320
  : (index + direction + rows.length) % rows.length;
239
- this.selection.select(rows[next]?.id);
321
+ this.select(rows[next]?.id);
240
322
  this.selectedChanged();
241
323
  }
242
324
  else
243
- this.inspector.position[this.selection.state.tab].move(direction, page, this.selection.state.tab === "output");
325
+ this.inspector.position[this.selection.state.tab].move(direction, page);
244
326
  }
245
327
  handleInput(data) {
246
328
  if (this.disposed)
247
329
  return;
248
330
  this.sync();
249
331
  this.render(this.width);
250
- this.feedback = undefined;
332
+ this.clearFeedback();
251
333
  try {
252
334
  if (this.layout?.tooSmall) {
253
335
  // The resize notice owns the screen; keys must not act on the hidden panel.
254
336
  if (this.options.keybindings.matches(data, "tui.select.cancel"))
255
- this.cancel();
337
+ this.escape();
256
338
  }
257
339
  else {
258
340
  switch (this.mode.kind) {
@@ -260,7 +342,7 @@ export class TasksMenu {
260
342
  this.helpInput(this.mode.viewport, data);
261
343
  break;
262
344
  case "search":
263
- this.searchInput(data);
345
+ this.searchInput(this.mode.input, data);
264
346
  break;
265
347
  case "confirmStop":
266
348
  this.confirmInput(data);
@@ -272,7 +354,7 @@ export class TasksMenu {
272
354
  }
273
355
  }
274
356
  catch (error) {
275
- this.feedback = cleanTaskText(error instanceof Error ? error.message : String(error));
357
+ this.notify("error", cleanTaskText(error instanceof Error ? error.message : String(error)));
276
358
  }
277
359
  if (this.disposed)
278
360
  return;
@@ -284,16 +366,16 @@ export class TasksMenu {
284
366
  if (kb.matches(data, "tui.select.cancel") || kb.matches(data, "app.tasks.help"))
285
367
  this.setMode(BROWSE);
286
368
  else if (kb.matches(data, "app.tasks.top") || kb.matches(data, "app.tasks.bottom"))
287
- viewport.jump(kb.matches(data, "app.tasks.bottom"), false);
369
+ viewport.jump(kb.matches(data, "app.tasks.bottom"));
288
370
  else if (kb.matches(data, "tui.select.up") || kb.matches(data, "tui.editor.pageUp"))
289
- viewport.move(-1, kb.matches(data, "tui.editor.pageUp"), false);
371
+ viewport.move(-1, kb.matches(data, "tui.editor.pageUp"));
290
372
  else if (kb.matches(data, "tui.select.down") || kb.matches(data, "tui.editor.pageDown"))
291
- viewport.move(1, kb.matches(data, "tui.editor.pageDown"), false);
373
+ viewport.move(1, kb.matches(data, "tui.editor.pageDown"));
292
374
  }
293
- searchInput(data) {
375
+ searchInput(input, data) {
294
376
  const kb = this.options.keybindings;
295
377
  if (kb.matches(data, "tui.select.cancel"))
296
- this.cancel();
378
+ this.escape();
297
379
  else if (kb.matches(data, "tui.select.confirm"))
298
380
  this.finishSearch(false);
299
381
  else if (kb.matches(data, "tui.select.up") || kb.matches(data, "tui.select.pageUp"))
@@ -301,9 +383,8 @@ export class TasksMenu {
301
383
  else if (kb.matches(data, "tui.select.down") || kb.matches(data, "tui.select.pageDown"))
302
384
  this.move(1, kb.matches(data, "tui.select.pageDown"));
303
385
  else {
304
- this.search.handleInput(data);
305
- this.selection.query = this.search.getValue().slice(0, 512);
306
- this.selection.refresh();
386
+ input.handleInput(data);
387
+ this.selection.refresh(this.query);
307
388
  this.selectedChanged();
308
389
  }
309
390
  }
@@ -312,12 +393,12 @@ export class TasksMenu {
312
393
  if (kb.matches(data, "app.tasks.confirmStop"))
313
394
  this.confirmStop();
314
395
  else if (kb.matches(data, "tui.select.cancel"))
315
- this.cancel();
396
+ this.escape();
316
397
  }
317
398
  browseInput(data) {
318
399
  const kb = this.options.keybindings;
319
400
  if (kb.matches(data, "tui.select.cancel")) {
320
- this.cancel();
401
+ this.escape();
321
402
  return;
322
403
  }
323
404
  const pageUp = kb.matches(data, this.focus === "list" ? "tui.select.pageUp" : "tui.editor.pageUp");
@@ -326,10 +407,8 @@ export class TasksMenu {
326
407
  this.move(-1, pageUp);
327
408
  else if (pageDown || kb.matches(data, "tui.select.down"))
328
409
  this.move(1, pageDown);
329
- else if (kb.matches(data, "tui.select.confirm")) {
330
- if (this.focus === "list" && this.selection.selected)
331
- this.focus = "inspector";
332
- }
410
+ else if (kb.matches(data, "tui.select.confirm"))
411
+ this.open();
333
412
  else {
334
413
  const key = actions.find((key) => kb.matches(data, key));
335
414
  if (key)
@@ -340,55 +419,33 @@ export class TasksMenu {
340
419
  if (this.disposed || event.ctrl || event.alt || event.shift)
341
420
  return;
342
421
  // Feedback is transient: a click retracts it and acts, exactly like a keypress does.
343
- this.feedback = undefined;
422
+ this.clearFeedback();
344
423
  this.render(event.width);
345
424
  const layout = this.layout;
346
- const mode = this.mode;
425
+ const region = layout.regions.find((r) => event.y >= r.y && event.y < r.y + r.height && event.x >= r.x && event.x < r.x + r.width);
347
426
  if (event.type === "wheel" && event.wheelDelta) {
348
- if (mode.kind !== "confirmStop" &&
349
- !layout.tooSmall &&
350
- event.y >= 2 &&
351
- event.y < this.options.tui.terminal.rows - 3) {
427
+ if (region) {
352
428
  const delta = Math.sign(event.wheelDelta) * Math.min(20, Math.abs(event.wheelDelta));
353
- const region = this.width >= 100 ? (event.x < layout.listWidth ? "list" : "inspector") : this.focus;
354
- if (mode.kind === "help")
355
- mode.viewport.move(delta, false, false);
356
- else if (region === "list")
429
+ if (region.pane === "help") {
430
+ if (this.mode.kind === "help")
431
+ this.mode.viewport.move(delta, false);
432
+ }
433
+ else if (region.pane === "list")
357
434
  this.list.scroll(delta);
358
- else if (mode.kind !== "search")
359
- this.inspector.position[this.selection.state.tab].move(delta, false, this.selection.state.tab === "output");
435
+ else
436
+ this.inspector.position[this.selection.state.tab].move(delta, false);
360
437
  }
361
438
  }
362
439
  else if (event.type === "click" && event.button === "left") {
363
440
  const hit = layout.hits.find((hit) => hit.y === event.y && event.x >= hit.x && event.x < hit.x + hit.width);
364
441
  try {
365
- if (hit?.cancel)
366
- this.cancel();
367
- else if (hit?.taskId) {
368
- this.selection.select(hit.taskId);
369
- this.selectedChanged();
370
- this.focus = "list";
371
- if (mode.kind === "search")
372
- this.finishSearch(false);
373
- }
374
- else if (hit?.tab) {
375
- this.focus = "inspector";
376
- this.selection.state.tab = hit.tab;
377
- }
378
- else if (hit?.key) {
379
- if (hit.key === "app.tasks.follow")
380
- this.focus = "inspector";
381
- this.action(hit.key);
382
- }
383
- else if (mode.kind === "browse" &&
384
- !layout.tooSmall &&
385
- event.y >= 1 &&
386
- event.y < this.options.tui.terminal.rows - 2 &&
387
- this.width >= 100)
388
- this.focus = event.x < layout.listWidth ? "list" : "inspector";
442
+ if (hit)
443
+ this.perform(hit.action);
444
+ else if (region && region.pane !== "help")
445
+ this.focus = region.pane;
389
446
  }
390
447
  catch (error) {
391
- this.feedback = cleanTaskText(error instanceof Error ? error.message : String(error));
448
+ this.notify("error", cleanTaskText(error instanceof Error ? error.message : String(error)));
392
449
  }
393
450
  }
394
451
  else
@@ -410,7 +467,6 @@ export class TasksMenu {
410
467
  list: this.list,
411
468
  focus: this.focus,
412
469
  mode: this.mode,
413
- searchLine: (width) => this.search.render(width).join(""),
414
470
  feedback: this.feedback,
415
471
  canDetach: (id) => this.canDetach(id),
416
472
  });
@@ -432,6 +488,7 @@ export class TasksMenu {
432
488
  this.selection.state.closedAt = Date.now();
433
489
  clearInterval(this.pollTimer);
434
490
  clearInterval(this.animationTimer);
491
+ this.clearFeedback();
435
492
  this.unsubscribe();
436
493
  this.inspector.dispose();
437
494
  }
@@ -1 +1 @@
1
- {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/manager.ts"],"names":[],"mappings":"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","sourcesContent":["/** Panel lifecycle and input routing; selection, output ownership and layout have separate owners. */\nimport \"../keybindings.ts\";\nimport {\n\ttype Component,\n\ttype Focusable,\n\tInput,\n\ttype TuiMouseEvent,\n\ttype TuiMouseEventResult,\n} from \"@earendil-works/pi-tui\";\nimport type { AppKeybinding, KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { isTaskTerminal, type TasksContext } from \"../../../core/tasks/types.ts\";\nimport { STATUS_SPINNER_INTERVAL_MS } from \"../../../modes/interactive/components/status-marker.ts\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport { TaskInspector } from \"./inspector.ts\";\nimport { renderTasksLayout, type TasksLayout } from \"./layout.ts\";\nimport { TaskList } from \"./list.ts\";\nimport { isStoppable, type PanelFocus, type PanelMode, TaskSelection, type TasksPanelState } from \"./model.ts\";\nimport { cleanTaskText } from \"./text.ts\";\nimport { TaskViewport } from \"./viewport.ts\";\n\nexport type TasksManagerHost = Pick<\n\tTasksContext,\n\t\"list\" | \"read\" | \"kill\" | \"subscribe\" | \"retain\" | \"canDetach\" | \"detach\"\n>;\nexport interface TasksMenuOptions {\n\ttui: { requestRender(): void; terminal: { rows: number; columns: number } };\n\ttheme: Theme;\n\tkeybindings: Pick<KeybindingsManager, \"matches\" | \"getKeys\">;\n\thost: TasksManagerHost;\n\tstate?: TasksPanelState;\n\tonClose(): void;\n\tpollIntervalMs?: number;\n}\n\nconst BROWSE: PanelMode = { kind: \"browse\" };\nconst actions: AppKeybinding[] = [\n\t\"app.tasks.search\",\n\t\"app.tasks.kill\",\n\t\"app.tasks.detachSelected\",\n\t\"app.tasks.previousTab\",\n\t\"app.tasks.nextTab\",\n\t\"app.tasks.follow\",\n\t\"app.tasks.top\",\n\t\"app.tasks.bottom\",\n\t\"app.tasks.nextFocus\",\n\t\"app.tasks.previousFocus\",\n\t\"app.tasks.help\",\n];\n\nexport class TasksMenu implements Component, Focusable {\n\tfocused = false;\n\tprivate readonly options: TasksMenuOptions;\n\tprivate readonly selection: TaskSelection;\n\tprivate readonly inspector: TaskInspector;\n\tprivate readonly list = new TaskList();\n\tprivate readonly search: Input;\n\tprivate readonly unsubscribe: () => void;\n\tprivate readonly pollTimer: ReturnType<typeof setInterval>;\n\tprivate animationTimer?: ReturnType<typeof setInterval>;\n\tprivate mode: PanelMode = BROWSE;\n\tprivate feedback?: string;\n\tprivate focus: PanelFocus = \"list\";\n\tprivate dirty = true;\n\tprivate tickQueued = false;\n\tprivate refreshQueued = false;\n\tprivate disposed = false;\n\tprivate width: number;\n\tprivate layout?: TasksLayout;\n\tconstructor(options: TasksMenuOptions) {\n\t\tthis.options = options;\n\t\tthis.width = options.tui.terminal.columns;\n\t\tthis.selection = new TaskSelection(options.state ?? { tab: \"output\" });\n\t\tthis.inspector = new TaskInspector({\n\t\t\thost: options.host,\n\t\t\ttheme: options.theme,\n\t\t\trequestRender: () => options.tui.requestRender(),\n\t\t});\n\t\tthis.search = new Input({ prompt: \"Find task: \", placeholder: \"title, command, kind or ID\" });\n\t\tthis.sync();\n\t\tthis.selection.selectStartedSinceClose();\n\t\tthis.inspector.select(this.selection.selected);\n\t\tthis.list.showSelection();\n\t\tthis.unsubscribe = options.host.subscribe(() => {\n\t\t\tthis.dirty = true;\n\t\t\tthis.queueTick();\n\t\t\toptions.tui.requestRender();\n\t\t});\n\t\tthis.pollTimer = setInterval(() => {\n\t\t\tthis.queueTick(true);\n\t\t\tif (this.selection.activeCount) options.tui.requestRender();\n\t\t}, options.pollIntervalMs ?? 1000);\n\t\tthis.pollTimer.unref?.();\n\t\tthis.queueTick(true);\n\t}\n\tprivate sync(): void {\n\t\tif (this.disposed || !this.dirty) return;\n\t\tthis.dirty = false;\n\t\tconst previous = this.selection.selected;\n\t\tthis.selection.sync(this.options.host.list());\n\t\tthis.inspector.select(this.selection.selected);\n\t\tthis.inspector.prune(new Set(this.selection.all.map((task) => task.id)));\n\t\tconst selected = this.selection.selected;\n\t\tif (selected && isTaskTerminal(selected.status) && previous && !isTaskTerminal(previous.status))\n\t\t\tthis.feedback = undefined;\n\t\tif (this.mode.kind === \"confirmStop\" && (this.mode.taskId !== selected?.id || isTaskTerminal(selected.status)))\n\t\t\tthis.setMode(BROWSE);\n\t\tconst animates = this.selection.all.some((task) => task.status === \"running\");\n\t\tif (animates && !this.animationTimer) {\n\t\t\tthis.animationTimer = setInterval(() => this.options.tui.requestRender(), STATUS_SPINNER_INTERVAL_MS);\n\t\t\tthis.animationTimer.unref?.();\n\t\t} else if (!animates) {\n\t\t\tclearInterval(this.animationTimer);\n\t\t\tthis.animationTimer = undefined;\n\t\t}\n\t}\n\tprivate queueTick(refresh = false): void {\n\t\tif (this.disposed) return;\n\t\tthis.refreshQueued ||= refresh;\n\t\tif (this.tickQueued) return;\n\t\tthis.tickQueued = true;\n\t\tvoid Promise.resolve()\n\t\t\t.then(async () => {\n\t\t\t\tthis.tickQueued = false;\n\t\t\t\tif (this.disposed) return;\n\t\t\t\tconst refresh = this.refreshQueued;\n\t\t\t\tthis.refreshQueued = false;\n\t\t\t\tthis.sync();\n\t\t\t\tif (refresh || (this.inspector.task && isTaskTerminal(this.inspector.task.status)))\n\t\t\t\t\tawait this.inspector.refresh();\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\t/* Task observers cannot reject execution. */\n\t\t\t});\n\t}\n\tinvalidate(): void {\n\t\tthis.inspector.invalidate();\n\t}\n\t/** The one place the mode changes; the search input is focused exactly while searching. */\n\tprivate setMode(next: PanelMode): void {\n\t\tthis.mode = next;\n\t\tthis.search.focused = next.kind === \"search\";\n\t}\n\t/** Unwinds exactly one transient layer; from plain browsing it closes the panel. */\n\tprivate cancel(): void {\n\t\tswitch (this.mode.kind) {\n\t\t\tcase \"search\":\n\t\t\t\tthis.finishSearch(true);\n\t\t\t\tbreak;\n\t\t\tcase \"help\":\n\t\t\tcase \"confirmStop\":\n\t\t\t\tthis.setMode(BROWSE);\n\t\t\t\tbreak;\n\t\t\tcase \"browse\":\n\t\t\t\tthis.close();\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tprivate close(): void {\n\t\tthis.dispose();\n\t\tthis.options.onClose();\n\t}\n\tprivate selectedChanged(): void {\n\t\tif (this.mode.kind === \"confirmStop\") this.setMode(BROWSE);\n\t\tthis.list.showSelection();\n\t\tthis.inspector.select(this.selection.selected);\n\t\tthis.queueTick(true);\n\t}\n\tprivate requestStop(): void {\n\t\tconst task = this.selection.selected;\n\t\tif (task && isStoppable(task)) this.setMode({ kind: \"confirmStop\", taskId: task.id });\n\t}\n\tprivate confirmStop(): void {\n\t\tconst mode = this.mode;\n\t\tif (mode.kind !== \"confirmStop\") return;\n\t\tthis.setMode(BROWSE);\n\t\tconst task = this.selection.selected;\n\t\tif (mode.taskId !== task?.id || isTaskTerminal(task.status)) return;\n\t\tthis.feedback = this.options.host.kill(mode.taskId)\n\t\t\t? \"Cancellation requested; waiting for cleanup.\"\n\t\t\t: \"No new cancellation requested.\";\n\t}\n\tprivate startSearch(): void {\n\t\tthis.setMode({ kind: \"search\", restore: { id: this.selection.state.selectedId, focus: this.focus } });\n\t\tthis.focus = \"list\";\n\t\tthis.search.setValue(\"\");\n\t}\n\tprivate finishSearch(cancel: boolean): void {\n\t\tconst mode = this.mode;\n\t\tif (mode.kind !== \"search\") return;\n\t\tconst id = cancel ? mode.restore.id : this.selection.state.selectedId;\n\t\tif (!cancel && !id) return;\n\t\tthis.focus = cancel ? mode.restore.focus : \"list\";\n\t\tthis.setMode(BROWSE);\n\t\tthis.selection.query = \"\";\n\t\tthis.selection.select(id);\n\t\tthis.selectedChanged();\n\t}\n\tprivate action(key: AppKeybinding): void {\n\t\tswitch (key) {\n\t\t\tcase \"app.tasks.search\":\n\t\t\t\tthis.startSearch();\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.previousTab\":\n\t\t\tcase \"app.tasks.nextTab\":\n\t\t\t\tif (this.focus === \"inspector\")\n\t\t\t\t\tthis.selection.state.tab = key === \"app.tasks.previousTab\" ? \"output\" : \"info\";\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.nextFocus\":\n\t\t\tcase \"app.tasks.previousFocus\":\n\t\t\t\tthis.focus = this.focus === \"list\" ? \"inspector\" : \"list\";\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.follow\":\n\t\t\t\tif (this.focus === \"inspector\" && this.selection.state.tab === \"output\") {\n\t\t\t\t\tthis.inspector.position.output.jump(true, true);\n\t\t\t\t\tthis.queueTick(true);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.top\":\n\t\t\tcase \"app.tasks.bottom\":\n\t\t\t\tif (this.focus === \"list\") {\n\t\t\t\t\tthis.selection.select(\n\t\t\t\t\t\tkey === \"app.tasks.top\" ? this.selection.rows[0]?.id : this.selection.rows.at(-1)?.id,\n\t\t\t\t\t);\n\t\t\t\t\tthis.selectedChanged();\n\t\t\t\t} else\n\t\t\t\t\tthis.inspector.position[this.selection.state.tab].jump(\n\t\t\t\t\t\tkey === \"app.tasks.bottom\",\n\t\t\t\t\t\tthis.selection.state.tab === \"output\",\n\t\t\t\t\t);\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.kill\":\n\t\t\t\tthis.requestStop();\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.confirmStop\":\n\t\t\t\tthis.confirmStop();\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.detachSelected\": {\n\t\t\t\tconst task = this.selection.selected;\n\t\t\t\t// The core decides; a full background lane throws its own explanation, shown as feedback.\n\t\t\t\tif (task?.mode === \"foreground\" && isStoppable(task)) {\n\t\t\t\t\tthis.feedback = this.options.host.detach(task.id)\n\t\t\t\t\t\t? \"Selected task moved to background; execution continues.\"\n\t\t\t\t\t\t: \"This task cannot move to background.\";\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase \"app.tasks.help\":\n\t\t\t\tthis.setMode({ kind: \"help\", viewport: new TaskViewport() });\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tprivate move(direction: number, page = false): void {\n\t\tif (this.mode.kind === \"help\") {\n\t\t\tthis.mode.viewport.move(direction, page, false);\n\t\t\treturn;\n\t\t}\n\t\tif (this.focus === \"list\") {\n\t\t\tconst rows = this.selection.rows;\n\t\t\tif (!rows.length) return;\n\t\t\tconst index = rows.findIndex((task) => task.id === this.selection.state.selectedId);\n\t\t\tconst next = page\n\t\t\t\t? Math.max(0, Math.min(rows.length - 1, index + direction * (this.layout?.listPageSize ?? 1)))\n\t\t\t\t: (index + direction + rows.length) % rows.length;\n\t\t\tthis.selection.select(rows[next]?.id);\n\t\t\tthis.selectedChanged();\n\t\t} else\n\t\t\tthis.inspector.position[this.selection.state.tab].move(direction, page, this.selection.state.tab === \"output\");\n\t}\n\thandleInput(data: string): void {\n\t\tif (this.disposed) return;\n\t\tthis.sync();\n\t\tthis.render(this.width);\n\t\tthis.feedback = undefined;\n\t\ttry {\n\t\t\tif (this.layout?.tooSmall) {\n\t\t\t\t// The resize notice owns the screen; keys must not act on the hidden panel.\n\t\t\t\tif (this.options.keybindings.matches(data, \"tui.select.cancel\")) this.cancel();\n\t\t\t} else {\n\t\t\t\tswitch (this.mode.kind) {\n\t\t\t\t\tcase \"help\":\n\t\t\t\t\t\tthis.helpInput(this.mode.viewport, data);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"search\":\n\t\t\t\t\t\tthis.searchInput(data);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"confirmStop\":\n\t\t\t\t\t\tthis.confirmInput(data);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"browse\":\n\t\t\t\t\t\tthis.browseInput(data);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.feedback = cleanTaskText(error instanceof Error ? error.message : String(error));\n\t\t}\n\t\tif (this.disposed) return;\n\t\tthis.queueTick(true);\n\t\tthis.options.tui.requestRender();\n\t}\n\tprivate helpInput(viewport: TaskViewport, data: string): void {\n\t\tconst kb = this.options.keybindings;\n\t\tif (kb.matches(data, \"tui.select.cancel\") || kb.matches(data, \"app.tasks.help\")) this.setMode(BROWSE);\n\t\telse if (kb.matches(data, \"app.tasks.top\") || kb.matches(data, \"app.tasks.bottom\"))\n\t\t\tviewport.jump(kb.matches(data, \"app.tasks.bottom\"), false);\n\t\telse if (kb.matches(data, \"tui.select.up\") || kb.matches(data, \"tui.editor.pageUp\"))\n\t\t\tviewport.move(-1, kb.matches(data, \"tui.editor.pageUp\"), false);\n\t\telse if (kb.matches(data, \"tui.select.down\") || kb.matches(data, \"tui.editor.pageDown\"))\n\t\t\tviewport.move(1, kb.matches(data, \"tui.editor.pageDown\"), false);\n\t}\n\tprivate searchInput(data: string): void {\n\t\tconst kb = this.options.keybindings;\n\t\tif (kb.matches(data, \"tui.select.cancel\")) this.cancel();\n\t\telse if (kb.matches(data, \"tui.select.confirm\")) this.finishSearch(false);\n\t\telse if (kb.matches(data, \"tui.select.up\") || kb.matches(data, \"tui.select.pageUp\"))\n\t\t\tthis.move(-1, kb.matches(data, \"tui.select.pageUp\"));\n\t\telse if (kb.matches(data, \"tui.select.down\") || kb.matches(data, \"tui.select.pageDown\"))\n\t\t\tthis.move(1, kb.matches(data, \"tui.select.pageDown\"));\n\t\telse {\n\t\t\tthis.search.handleInput(data);\n\t\t\tthis.selection.query = this.search.getValue().slice(0, 512);\n\t\t\tthis.selection.refresh();\n\t\t\tthis.selectedChanged();\n\t\t}\n\t}\n\tprivate confirmInput(data: string): void {\n\t\tconst kb = this.options.keybindings;\n\t\tif (kb.matches(data, \"app.tasks.confirmStop\")) this.confirmStop();\n\t\telse if (kb.matches(data, \"tui.select.cancel\")) this.cancel();\n\t}\n\tprivate browseInput(data: string): void {\n\t\tconst kb = this.options.keybindings;\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.cancel();\n\t\t\treturn;\n\t\t}\n\t\tconst pageUp = kb.matches(data, this.focus === \"list\" ? \"tui.select.pageUp\" : \"tui.editor.pageUp\");\n\t\tconst pageDown = kb.matches(data, this.focus === \"list\" ? \"tui.select.pageDown\" : \"tui.editor.pageDown\");\n\t\tif (pageUp || kb.matches(data, \"tui.select.up\")) this.move(-1, pageUp);\n\t\telse if (pageDown || kb.matches(data, \"tui.select.down\")) this.move(1, pageDown);\n\t\telse if (kb.matches(data, \"tui.select.confirm\")) {\n\t\t\tif (this.focus === \"list\" && this.selection.selected) this.focus = \"inspector\";\n\t\t} else {\n\t\t\tconst key = actions.find((key) => kb.matches(data, key));\n\t\t\tif (key) this.action(key);\n\t\t}\n\t}\n\thandleMouse(event: TuiMouseEvent): TuiMouseEventResult | undefined {\n\t\tif (this.disposed || event.ctrl || event.alt || event.shift) return;\n\t\t// Feedback is transient: a click retracts it and acts, exactly like a keypress does.\n\t\tthis.feedback = undefined;\n\t\tthis.render(event.width);\n\t\tconst layout = this.layout!;\n\t\tconst mode = this.mode;\n\t\tif (event.type === \"wheel\" && event.wheelDelta) {\n\t\t\tif (\n\t\t\t\tmode.kind !== \"confirmStop\" &&\n\t\t\t\t!layout.tooSmall &&\n\t\t\t\tevent.y >= 2 &&\n\t\t\t\tevent.y < this.options.tui.terminal.rows - 3\n\t\t\t) {\n\t\t\t\tconst delta = Math.sign(event.wheelDelta) * Math.min(20, Math.abs(event.wheelDelta));\n\t\t\t\tconst region = this.width >= 100 ? (event.x < layout.listWidth ? \"list\" : \"inspector\") : this.focus;\n\t\t\t\tif (mode.kind === \"help\") mode.viewport.move(delta, false, false);\n\t\t\t\telse if (region === \"list\") this.list.scroll(delta);\n\t\t\t\telse if (mode.kind !== \"search\")\n\t\t\t\t\tthis.inspector.position[this.selection.state.tab].move(\n\t\t\t\t\t\tdelta,\n\t\t\t\t\t\tfalse,\n\t\t\t\t\t\tthis.selection.state.tab === \"output\",\n\t\t\t\t\t);\n\t\t\t}\n\t\t} else if (event.type === \"click\" && event.button === \"left\") {\n\t\t\tconst hit = layout.hits.find((hit) => hit.y === event.y && event.x >= hit.x && event.x < hit.x + hit.width);\n\t\t\ttry {\n\t\t\t\tif (hit?.cancel) this.cancel();\n\t\t\t\telse if (hit?.taskId) {\n\t\t\t\t\tthis.selection.select(hit.taskId);\n\t\t\t\t\tthis.selectedChanged();\n\t\t\t\t\tthis.focus = \"list\";\n\t\t\t\t\tif (mode.kind === \"search\") this.finishSearch(false);\n\t\t\t\t} else if (hit?.tab) {\n\t\t\t\t\tthis.focus = \"inspector\";\n\t\t\t\t\tthis.selection.state.tab = hit.tab;\n\t\t\t\t} else if (hit?.key) {\n\t\t\t\t\tif (hit.key === \"app.tasks.follow\") this.focus = \"inspector\";\n\t\t\t\t\tthis.action(hit.key);\n\t\t\t\t} else if (\n\t\t\t\t\tmode.kind === \"browse\" &&\n\t\t\t\t\t!layout.tooSmall &&\n\t\t\t\t\tevent.y >= 1 &&\n\t\t\t\t\tevent.y < this.options.tui.terminal.rows - 2 &&\n\t\t\t\t\tthis.width >= 100\n\t\t\t\t)\n\t\t\t\t\tthis.focus = event.x < layout.listWidth ? \"list\" : \"inspector\";\n\t\t\t} catch (error) {\n\t\t\t\tthis.feedback = cleanTaskText(error instanceof Error ? error.message : String(error));\n\t\t\t}\n\t\t} else return;\n\t\tthis.queueTick(true);\n\t\tthis.options.tui.requestRender();\n\t\treturn { handled: true, focus: event.type === \"click\" };\n\t}\n\trender(width: number): string[] {\n\t\tthis.width = width;\n\t\tthis.sync();\n\t\tthis.layout = renderTasksLayout({\n\t\t\twidth,\n\t\t\theight: this.options.tui.terminal.rows,\n\t\t\ttheme: this.options.theme,\n\t\t\tkeybindings: this.options.keybindings,\n\t\t\tselection: this.selection,\n\t\t\tinspector: this.inspector,\n\t\t\tlist: this.list,\n\t\t\tfocus: this.focus,\n\t\t\tmode: this.mode,\n\t\t\tsearchLine: (width) => this.search.render(width).join(\"\"),\n\t\t\tfeedback: this.feedback,\n\t\t\tcanDetach: (id) => this.canDetach(id),\n\t\t});\n\t\treturn this.layout.lines;\n\t}\n\t/** The panel's selection can lag the runtime by a notification; a task that is gone cannot move. */\n\tprivate canDetach(id: string): boolean {\n\t\ttry {\n\t\t\treturn this.options.host.canDetach(id);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\tdispose(): void {\n\t\tif (this.disposed) return;\n\t\tthis.disposed = true;\n\t\tthis.selection.state.closedAt = Date.now();\n\t\tclearInterval(this.pollTimer);\n\t\tclearInterval(this.animationTimer);\n\t\tthis.unsubscribe();\n\t\tthis.inspector.dispose();\n\t}\n}\n"]}
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../../src/extensions/tasks/ui/manager.ts"],"names":[],"mappings":"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","sourcesContent":["/** Panel lifecycle and input routing; selection, output ownership and layout have separate owners. */\nimport \"../keybindings.ts\";\nimport {\n\ttype Component,\n\ttype Focusable,\n\tInput,\n\ttype TuiMouseEvent,\n\ttype TuiMouseEventResult,\n} from \"@earendil-works/pi-tui\";\nimport type { AppKeybinding, KeybindingsManager } from \"../../../core/keybindings.ts\";\nimport { isTaskTerminal, type TaskSnapshot, type TasksContext } from \"../../../core/tasks/types.ts\";\nimport { STATUS_SPINNER_INTERVAL_MS } from \"../../../modes/interactive/components/status-marker.ts\";\nimport type { Theme } from \"../../../modes/interactive/theme/theme.ts\";\nimport type { Feedback } from \"./footer.ts\";\nimport { TaskInspector } from \"./inspector.ts\";\nimport { renderTasksLayout, type TasksLayout } from \"./layout.ts\";\nimport { TaskList } from \"./list.ts\";\nimport { type PanelFocus, type PanelMode, type TaskAction, TaskSelection, type TasksPanelState } from \"./model.ts\";\nimport { cleanTaskText } from \"./text.ts\";\nimport { TaskViewport } from \"./viewport.ts\";\n\nexport type TasksManagerHost = Pick<\n\tTasksContext,\n\t\"list\" | \"read\" | \"kill\" | \"subscribe\" | \"retain\" | \"canDetach\" | \"detach\" | \"presentOutput\"\n>;\nexport interface TasksMenuOptions {\n\ttui: { requestRender(): void; terminal: { rows: number; columns: number } };\n\ttheme: Theme;\n\tkeybindings: Pick<KeybindingsManager, \"matches\" | \"getKeys\">;\n\thost: TasksManagerHost;\n\tstate?: TasksPanelState;\n\tonClose(): void;\n\tpollIntervalMs?: number;\n}\n\nconst BROWSE: PanelMode = { kind: \"browse\" };\n/** Feedback outlives a glance but not the next thing the user does. */\nconst FEEDBACK_MS = 4000;\nconst QUERY_LIMIT = 512;\nconst actions: AppKeybinding[] = [\n\t\"app.tasks.search\",\n\t\"app.tasks.kill\",\n\t\"app.tasks.detachSelected\",\n\t\"app.tasks.previousTab\",\n\t\"app.tasks.nextTab\",\n\t\"app.tasks.follow\",\n\t\"app.tasks.top\",\n\t\"app.tasks.bottom\",\n\t\"app.tasks.nextFocus\",\n\t\"app.tasks.previousFocus\",\n\t\"app.tasks.help\",\n];\n\n/** Why a stop or background request cannot apply to this task, for the states the footer does not offer. */\nfunction unavailableReason(task: TaskSnapshot): string | undefined {\n\tif (isTaskTerminal(task.status)) return \"Task already finished.\";\n\tif (task.status === \"stopping\") return \"Task is already stopping.\";\n\treturn undefined;\n}\n\nexport class TasksMenu implements Component, Focusable {\n\tfocused = false;\n\tprivate readonly options: TasksMenuOptions;\n\tprivate readonly selection: TaskSelection;\n\tprivate readonly inspector: TaskInspector;\n\tprivate readonly list = new TaskList();\n\tprivate readonly unsubscribe: () => void;\n\tprivate readonly pollTimer: ReturnType<typeof setInterval>;\n\tprivate animationTimer?: ReturnType<typeof setInterval>;\n\tprivate feedbackTimer?: ReturnType<typeof setTimeout>;\n\tprivate mode: PanelMode = BROWSE;\n\tprivate feedback?: Feedback;\n\tprivate focus: PanelFocus = \"list\";\n\tprivate dirty = true;\n\tprivate tickQueued = false;\n\tprivate refreshQueued = false;\n\tprivate disposed = false;\n\tprivate width: number;\n\tprivate layout?: TasksLayout;\n\tconstructor(options: TasksMenuOptions) {\n\t\tthis.options = options;\n\t\tthis.width = options.tui.terminal.columns;\n\t\tthis.selection = new TaskSelection(options.state ?? { tab: \"output\" });\n\t\tthis.inspector = new TaskInspector({\n\t\t\thost: options.host,\n\t\t\ttheme: options.theme,\n\t\t\trequestRender: () => options.tui.requestRender(),\n\t\t});\n\t\tthis.sync();\n\t\tthis.selection.selectStartedSinceClose();\n\t\tthis.inspector.select(this.selection.selected);\n\t\tthis.list.showSelection();\n\t\tthis.unsubscribe = options.host.subscribe(() => {\n\t\t\tthis.dirty = true;\n\t\t\tthis.queueTick();\n\t\t\toptions.tui.requestRender();\n\t\t});\n\t\tthis.pollTimer = setInterval(() => {\n\t\t\tthis.queueTick(true);\n\t\t\tif (this.selection.activeCount) options.tui.requestRender();\n\t\t}, options.pollIntervalMs ?? 1000);\n\t\tthis.pollTimer.unref?.();\n\t\tthis.queueTick(true);\n\t}\n\t/** The search text, owned by the search mode: browsing always sees every retained task. */\n\tprivate get query(): string {\n\t\treturn this.mode.kind === \"search\" ? this.mode.input.getValue().slice(0, QUERY_LIMIT) : \"\";\n\t}\n\tprivate select(id: string | undefined): void {\n\t\tthis.selection.select(id, this.query);\n\t}\n\tprivate sync(): void {\n\t\tif (this.disposed || !this.dirty) return;\n\t\tthis.dirty = false;\n\t\tthis.selection.sync(this.options.host.list(), this.query);\n\t\tthis.inspector.select(this.selection.selected);\n\t\tthis.inspector.prune(new Set(this.selection.all.map((task) => task.id)));\n\t\tconst selected = this.selection.selected;\n\t\tif (this.mode.kind === \"confirmStop\" && (this.mode.taskId !== selected?.id || isTaskTerminal(selected.status)))\n\t\t\tthis.setMode(BROWSE);\n\t\tconst animates = this.selection.all.some((task) => task.status === \"running\");\n\t\tif (animates && !this.animationTimer) {\n\t\t\tthis.animationTimer = setInterval(() => this.options.tui.requestRender(), STATUS_SPINNER_INTERVAL_MS);\n\t\t\tthis.animationTimer.unref?.();\n\t\t} else if (!animates) {\n\t\t\tclearInterval(this.animationTimer);\n\t\t\tthis.animationTimer = undefined;\n\t\t}\n\t}\n\tprivate queueTick(refresh = false): void {\n\t\tif (this.disposed) return;\n\t\tthis.refreshQueued ||= refresh;\n\t\tif (this.tickQueued) return;\n\t\tthis.tickQueued = true;\n\t\tvoid Promise.resolve()\n\t\t\t.then(async () => {\n\t\t\t\tthis.tickQueued = false;\n\t\t\t\tif (this.disposed) return;\n\t\t\t\tconst refresh = this.refreshQueued;\n\t\t\t\tthis.refreshQueued = false;\n\t\t\t\tthis.sync();\n\t\t\t\tif (refresh || (this.inspector.task && isTaskTerminal(this.inspector.task.status)))\n\t\t\t\t\tawait this.inspector.refresh();\n\t\t\t})\n\t\t\t.catch(() => {\n\t\t\t\t/* Task observers cannot reject execution. */\n\t\t\t});\n\t}\n\tinvalidate(): void {\n\t\tthis.inspector.invalidate();\n\t}\n\tprivate setMode(next: PanelMode): void {\n\t\tthis.mode = next;\n\t}\n\t/** Reports an action that did not do what was asked; it clears on the next input or after a few seconds. */\n\tprivate notify(tone: Feedback[\"tone\"], text: string): void {\n\t\tthis.clearFeedback();\n\t\tthis.feedback = { tone, text };\n\t\tthis.feedbackTimer = setTimeout(() => {\n\t\t\tthis.feedbackTimer = undefined;\n\t\t\tthis.feedback = undefined;\n\t\t\tif (!this.disposed) this.options.tui.requestRender();\n\t\t}, FEEDBACK_MS);\n\t\tthis.feedbackTimer.unref?.();\n\t}\n\tprivate clearFeedback(): void {\n\t\tclearTimeout(this.feedbackTimer);\n\t\tthis.feedbackTimer = undefined;\n\t\tthis.feedback = undefined;\n\t}\n\t/**\n\t * Unwinds exactly one layer: search, help or a confirmation; then the inspector back to the\n\t * list when the list is hidden; from plain browsing it closes the panel.\n\t */\n\tprivate escape(): void {\n\t\tswitch (this.mode.kind) {\n\t\t\tcase \"search\":\n\t\t\t\tthis.finishSearch(true);\n\t\t\t\tbreak;\n\t\t\tcase \"help\":\n\t\t\tcase \"confirmStop\":\n\t\t\t\tthis.setMode(BROWSE);\n\t\t\t\tbreak;\n\t\t\tcase \"browse\":\n\t\t\t\tif (this.layout && !this.layout.tooSmall && !this.layout.split && this.focus === \"inspector\")\n\t\t\t\t\tthis.focus = \"list\";\n\t\t\t\telse this.close();\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tprivate close(): void {\n\t\tthis.dispose();\n\t\tthis.options.onClose();\n\t}\n\tprivate selectedChanged(): void {\n\t\tif (this.mode.kind === \"confirmStop\") this.setMode(BROWSE);\n\t\tthis.list.showSelection();\n\t\tthis.inspector.select(this.selection.selected);\n\t\tthis.queueTick(true);\n\t}\n\tprivate requestStop(): void {\n\t\tconst task = this.selection.selected;\n\t\tif (!task) return;\n\t\tconst reason = unavailableReason(task);\n\t\tif (reason) this.notify(\"warning\", reason);\n\t\telse this.setMode({ kind: \"confirmStop\", taskId: task.id });\n\t}\n\tprivate confirmStop(): void {\n\t\tconst mode = this.mode;\n\t\tif (mode.kind !== \"confirmStop\") return;\n\t\tthis.setMode(BROWSE);\n\t\tconst task = this.selection.selected;\n\t\tif (mode.taskId !== task?.id || isTaskTerminal(task.status)) return;\n\t\t// A granted request shows as Stopping on the row and header; only a refusal needs saying.\n\t\tif (!this.options.host.kill(mode.taskId)) this.notify(\"warning\", \"No new cancellation requested.\");\n\t}\n\tprivate detachSelected(): void {\n\t\tconst task = this.selection.selected;\n\t\tif (!task) return;\n\t\tconst reason =\n\t\t\tunavailableReason(task) ?? (task.mode === \"background\" ? \"Task is already in the background.\" : \"\");\n\t\tif (reason) {\n\t\t\tthis.notify(\"warning\", reason);\n\t\t\treturn;\n\t\t}\n\t\ttry {\n\t\t\t// The core decides; a full background lane throws its own explanation.\n\t\t\tif (!this.options.host.detach(task.id)) this.notify(\"warning\", \"This task cannot move to background.\");\n\t\t} catch (error) {\n\t\t\tthis.notify(\"warning\", cleanTaskText(error instanceof Error ? error.message : String(error)));\n\t\t}\n\t}\n\tprivate startSearch(): void {\n\t\tconst input = new Input({ prompt: \"Find task: \", placeholder: \"title, command, kind or ID\" });\n\t\tinput.focused = true;\n\t\tthis.setMode({ kind: \"search\", restore: { id: this.selection.state.selectedId, focus: this.focus }, input });\n\t\tthis.focus = \"list\";\n\t}\n\tprivate finishSearch(cancel: boolean): void {\n\t\tconst mode = this.mode;\n\t\tif (mode.kind !== \"search\") return;\n\t\tconst id = cancel ? mode.restore.id : this.selection.state.selectedId;\n\t\tif (!cancel && !id) return;\n\t\tthis.focus = cancel ? mode.restore.focus : \"list\";\n\t\tthis.setMode(BROWSE);\n\t\tthis.select(id);\n\t\tthis.selectedChanged();\n\t}\n\tprivate open(): void {\n\t\tif (this.focus === \"list\" && this.selection.selected) this.focus = \"inspector\";\n\t}\n\tprivate action(key: AppKeybinding): void {\n\t\tswitch (key) {\n\t\t\tcase \"app.tasks.search\":\n\t\t\t\tthis.startSearch();\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.previousTab\":\n\t\t\tcase \"app.tasks.nextTab\":\n\t\t\t\tif (this.focus === \"inspector\")\n\t\t\t\t\tthis.selection.state.tab = key === \"app.tasks.previousTab\" ? \"output\" : \"info\";\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.nextFocus\":\n\t\t\tcase \"app.tasks.previousFocus\":\n\t\t\t\tthis.focus = this.focus === \"list\" ? \"inspector\" : \"list\";\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.follow\":\n\t\t\t\tif (this.focus === \"inspector\" && this.selection.state.tab === \"output\") {\n\t\t\t\t\tthis.inspector.position.output.jump(true);\n\t\t\t\t\tthis.queueTick(true);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.top\":\n\t\t\tcase \"app.tasks.bottom\":\n\t\t\t\tif (this.focus === \"list\") {\n\t\t\t\t\tthis.select(key === \"app.tasks.top\" ? this.selection.rows[0]?.id : this.selection.rows.at(-1)?.id);\n\t\t\t\t\tthis.selectedChanged();\n\t\t\t\t} else this.inspector.position[this.selection.state.tab].jump(key === \"app.tasks.bottom\");\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.kill\":\n\t\t\t\tthis.requestStop();\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.confirmStop\":\n\t\t\t\tthis.confirmStop();\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.detachSelected\":\n\t\t\t\tthis.detachSelected();\n\t\t\t\tbreak;\n\t\t\tcase \"app.tasks.help\":\n\t\t\t\tthis.setMode({ kind: \"help\", viewport: new TaskViewport() });\n\t\t\t\tbreak;\n\t\t}\n\t}\n\t/** Performs what a click on a rendered target asks for. */\n\tprivate perform(action: TaskAction): void {\n\t\tswitch (action.kind) {\n\t\t\tcase \"select\":\n\t\t\t\tthis.select(action.taskId);\n\t\t\t\tthis.selectedChanged();\n\t\t\t\tthis.focus = \"list\";\n\t\t\t\tif (this.mode.kind === \"search\") this.finishSearch(false);\n\t\t\t\tbreak;\n\t\t\tcase \"tab\":\n\t\t\t\tthis.focus = \"inspector\";\n\t\t\t\tthis.selection.state.tab = action.tab;\n\t\t\t\tbreak;\n\t\t\tcase \"key\":\n\t\t\t\tif (action.key === \"app.tasks.follow\") this.focus = \"inspector\";\n\t\t\t\tthis.action(action.key);\n\t\t\t\tbreak;\n\t\t\tcase \"open\":\n\t\t\t\tthis.open();\n\t\t\t\tbreak;\n\t\t\tcase \"back\":\n\t\t\t\tthis.escape();\n\t\t\t\tbreak;\n\t\t}\n\t}\n\tprivate move(direction: number, page = false): void {\n\t\tif (this.mode.kind === \"help\") {\n\t\t\tthis.mode.viewport.move(direction, page);\n\t\t\treturn;\n\t\t}\n\t\tif (this.focus === \"list\") {\n\t\t\tconst rows = this.selection.rows;\n\t\t\tif (!rows.length) return;\n\t\t\tconst index = rows.findIndex((task) => task.id === this.selection.state.selectedId);\n\t\t\tconst next = page\n\t\t\t\t? Math.max(0, Math.min(rows.length - 1, index + direction * (this.layout?.listPageSize ?? 1)))\n\t\t\t\t: (index + direction + rows.length) % rows.length;\n\t\t\tthis.select(rows[next]?.id);\n\t\t\tthis.selectedChanged();\n\t\t} else this.inspector.position[this.selection.state.tab].move(direction, page);\n\t}\n\thandleInput(data: string): void {\n\t\tif (this.disposed) return;\n\t\tthis.sync();\n\t\tthis.render(this.width);\n\t\tthis.clearFeedback();\n\t\ttry {\n\t\t\tif (this.layout?.tooSmall) {\n\t\t\t\t// The resize notice owns the screen; keys must not act on the hidden panel.\n\t\t\t\tif (this.options.keybindings.matches(data, \"tui.select.cancel\")) this.escape();\n\t\t\t} else {\n\t\t\t\tswitch (this.mode.kind) {\n\t\t\t\t\tcase \"help\":\n\t\t\t\t\t\tthis.helpInput(this.mode.viewport, data);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"search\":\n\t\t\t\t\t\tthis.searchInput(this.mode.input, data);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"confirmStop\":\n\t\t\t\t\t\tthis.confirmInput(data);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"browse\":\n\t\t\t\t\t\tthis.browseInput(data);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tthis.notify(\"error\", cleanTaskText(error instanceof Error ? error.message : String(error)));\n\t\t}\n\t\tif (this.disposed) return;\n\t\tthis.queueTick(true);\n\t\tthis.options.tui.requestRender();\n\t}\n\tprivate helpInput(viewport: TaskViewport, data: string): void {\n\t\tconst kb = this.options.keybindings;\n\t\tif (kb.matches(data, \"tui.select.cancel\") || kb.matches(data, \"app.tasks.help\")) this.setMode(BROWSE);\n\t\telse if (kb.matches(data, \"app.tasks.top\") || kb.matches(data, \"app.tasks.bottom\"))\n\t\t\tviewport.jump(kb.matches(data, \"app.tasks.bottom\"));\n\t\telse if (kb.matches(data, \"tui.select.up\") || kb.matches(data, \"tui.editor.pageUp\"))\n\t\t\tviewport.move(-1, kb.matches(data, \"tui.editor.pageUp\"));\n\t\telse if (kb.matches(data, \"tui.select.down\") || kb.matches(data, \"tui.editor.pageDown\"))\n\t\t\tviewport.move(1, kb.matches(data, \"tui.editor.pageDown\"));\n\t}\n\tprivate searchInput(input: Input, data: string): void {\n\t\tconst kb = this.options.keybindings;\n\t\tif (kb.matches(data, \"tui.select.cancel\")) this.escape();\n\t\telse if (kb.matches(data, \"tui.select.confirm\")) this.finishSearch(false);\n\t\telse if (kb.matches(data, \"tui.select.up\") || kb.matches(data, \"tui.select.pageUp\"))\n\t\t\tthis.move(-1, kb.matches(data, \"tui.select.pageUp\"));\n\t\telse if (kb.matches(data, \"tui.select.down\") || kb.matches(data, \"tui.select.pageDown\"))\n\t\t\tthis.move(1, kb.matches(data, \"tui.select.pageDown\"));\n\t\telse {\n\t\t\tinput.handleInput(data);\n\t\t\tthis.selection.refresh(this.query);\n\t\t\tthis.selectedChanged();\n\t\t}\n\t}\n\tprivate confirmInput(data: string): void {\n\t\tconst kb = this.options.keybindings;\n\t\tif (kb.matches(data, \"app.tasks.confirmStop\")) this.confirmStop();\n\t\telse if (kb.matches(data, \"tui.select.cancel\")) this.escape();\n\t}\n\tprivate browseInput(data: string): void {\n\t\tconst kb = this.options.keybindings;\n\t\tif (kb.matches(data, \"tui.select.cancel\")) {\n\t\t\tthis.escape();\n\t\t\treturn;\n\t\t}\n\t\tconst pageUp = kb.matches(data, this.focus === \"list\" ? \"tui.select.pageUp\" : \"tui.editor.pageUp\");\n\t\tconst pageDown = kb.matches(data, this.focus === \"list\" ? \"tui.select.pageDown\" : \"tui.editor.pageDown\");\n\t\tif (pageUp || kb.matches(data, \"tui.select.up\")) this.move(-1, pageUp);\n\t\telse if (pageDown || kb.matches(data, \"tui.select.down\")) this.move(1, pageDown);\n\t\telse if (kb.matches(data, \"tui.select.confirm\")) this.open();\n\t\telse {\n\t\t\tconst key = actions.find((key) => kb.matches(data, key));\n\t\t\tif (key) this.action(key);\n\t\t}\n\t}\n\thandleMouse(event: TuiMouseEvent): TuiMouseEventResult | undefined {\n\t\tif (this.disposed || event.ctrl || event.alt || event.shift) return;\n\t\t// Feedback is transient: a click retracts it and acts, exactly like a keypress does.\n\t\tthis.clearFeedback();\n\t\tthis.render(event.width);\n\t\tconst layout = this.layout!;\n\t\tconst region = layout.regions.find(\n\t\t\t(r) => event.y >= r.y && event.y < r.y + r.height && event.x >= r.x && event.x < r.x + r.width,\n\t\t);\n\t\tif (event.type === \"wheel\" && event.wheelDelta) {\n\t\t\tif (region) {\n\t\t\t\tconst delta = Math.sign(event.wheelDelta) * Math.min(20, Math.abs(event.wheelDelta));\n\t\t\t\tif (region.pane === \"help\") {\n\t\t\t\t\tif (this.mode.kind === \"help\") this.mode.viewport.move(delta, false);\n\t\t\t\t} else if (region.pane === \"list\") this.list.scroll(delta);\n\t\t\t\telse this.inspector.position[this.selection.state.tab].move(delta, false);\n\t\t\t}\n\t\t} else if (event.type === \"click\" && event.button === \"left\") {\n\t\t\tconst hit = layout.hits.find((hit) => hit.y === event.y && event.x >= hit.x && event.x < hit.x + hit.width);\n\t\t\ttry {\n\t\t\t\tif (hit) this.perform(hit.action);\n\t\t\t\telse if (region && region.pane !== \"help\") this.focus = region.pane;\n\t\t\t} catch (error) {\n\t\t\t\tthis.notify(\"error\", cleanTaskText(error instanceof Error ? error.message : String(error)));\n\t\t\t}\n\t\t} else return;\n\t\tthis.queueTick(true);\n\t\tthis.options.tui.requestRender();\n\t\treturn { handled: true, focus: event.type === \"click\" };\n\t}\n\trender(width: number): string[] {\n\t\tthis.width = width;\n\t\tthis.sync();\n\t\tthis.layout = renderTasksLayout({\n\t\t\twidth,\n\t\t\theight: this.options.tui.terminal.rows,\n\t\t\ttheme: this.options.theme,\n\t\t\tkeybindings: this.options.keybindings,\n\t\t\tselection: this.selection,\n\t\t\tinspector: this.inspector,\n\t\t\tlist: this.list,\n\t\t\tfocus: this.focus,\n\t\t\tmode: this.mode,\n\t\t\tfeedback: this.feedback,\n\t\t\tcanDetach: (id) => this.canDetach(id),\n\t\t});\n\t\treturn this.layout.lines;\n\t}\n\t/** The panel's selection can lag the runtime by a notification; a task that is gone cannot move. */\n\tprivate canDetach(id: string): boolean {\n\t\ttry {\n\t\t\treturn this.options.host.canDetach(id);\n\t\t} catch {\n\t\t\treturn false;\n\t\t}\n\t}\n\tdispose(): void {\n\t\tif (this.disposed) return;\n\t\tthis.disposed = true;\n\t\tthis.selection.state.closedAt = Date.now();\n\t\tclearInterval(this.pollTimer);\n\t\tclearInterval(this.animationTimer);\n\t\tthis.clearFeedback();\n\t\tthis.unsubscribe();\n\t\tthis.inspector.dispose();\n\t}\n}\n"]}