@astralyn/pi 1.4.8 → 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.
- package/CHANGELOG.md +68 -0
- package/dist/bundle/chunks/{chunk-I2COK45I.js → chunk-6GTUUUCJ.js} +128 -128
- package/dist/bundle/chunks/{chunk-PU2IWWXV.js → chunk-DLVLAQEG.js} +1 -1
- package/dist/bundle/chunks/{chunk-MG5XDTXV.js → chunk-LPF7HQ3S.js} +1 -1
- package/dist/bundle/chunks/{chunk-FODCTZXW.js → chunk-MF3T3ETJ.js} +4 -4
- package/dist/bundle/chunks/{chunk-RO2VH6UZ.js → chunk-R267VV5T.js} +1 -1
- package/dist/bundle/chunks/{chunk-RLNMABLM.js → chunk-RVKT7OUB.js} +1 -1
- package/dist/bundle/chunks/{chunk-5VIOGR76.js → chunk-UCH27AVQ.js} +1 -1
- package/dist/bundle/chunks/{cli-MEL7SGJD.js → cli-MBFCFGI2.js} +1 -1
- package/dist/bundle/chunks/{execute-4CWRNHPO.js → execute-FQKRO4XJ.js} +1 -1
- package/dist/bundle/chunks/{runtime-R3X67XMR.js → runtime-3RPOJS5T.js} +1 -1
- package/dist/bundle/chunks/{virtual-modules-BBLD7YLS.js → virtual-modules-6IJ6V2CG.js} +1 -1
- package/dist/bundle/cli.js +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/core/agent-session.d.ts +34 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +99 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/isolated-session.d.ts +7 -2
- package/dist/core/isolated-session.d.ts.map +1 -1
- package/dist/core/isolated-session.js +7 -3
- package/dist/core/isolated-session.js.map +1 -1
- package/dist/core/session-manager.d.ts +17 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +29 -0
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/tasks/delivery.d.ts +42 -7
- package/dist/core/tasks/delivery.d.ts.map +1 -1
- package/dist/core/tasks/delivery.js +129 -15
- package/dist/core/tasks/delivery.js.map +1 -1
- package/dist/core/tasks/execution.d.ts +27 -14
- package/dist/core/tasks/execution.d.ts.map +1 -1
- package/dist/core/tasks/execution.js +90 -86
- package/dist/core/tasks/execution.js.map +1 -1
- package/dist/core/tasks/limits.d.ts +13 -1
- package/dist/core/tasks/limits.d.ts.map +1 -1
- package/dist/core/tasks/limits.js +14 -1
- package/dist/core/tasks/limits.js.map +1 -1
- package/dist/core/tasks/output.d.ts +9 -1
- package/dist/core/tasks/output.d.ts.map +1 -1
- package/dist/core/tasks/output.js +23 -10
- package/dist/core/tasks/output.js.map +1 -1
- package/dist/core/tasks/presentation.d.ts +1 -1
- package/dist/core/tasks/presentation.d.ts.map +1 -1
- package/dist/core/tasks/presentation.js +6 -4
- package/dist/core/tasks/presentation.js.map +1 -1
- package/dist/core/tasks/record.d.ts +41 -29
- package/dist/core/tasks/record.d.ts.map +1 -1
- package/dist/core/tasks/record.js +82 -37
- package/dist/core/tasks/record.js.map +1 -1
- package/dist/core/tasks/reminder.js +2 -2
- package/dist/core/tasks/reminder.js.map +1 -1
- package/dist/core/tasks/runtime.d.ts +17 -14
- package/dist/core/tasks/runtime.d.ts.map +1 -1
- package/dist/core/tasks/runtime.js +68 -116
- package/dist/core/tasks/runtime.js.map +1 -1
- package/dist/core/tasks/scheduler.d.ts +3 -1
- package/dist/core/tasks/scheduler.d.ts.map +1 -1
- package/dist/core/tasks/scheduler.js +16 -12
- package/dist/core/tasks/scheduler.js.map +1 -1
- package/dist/core/tasks/session.d.ts +24 -3
- package/dist/core/tasks/session.d.ts.map +1 -1
- package/dist/core/tasks/session.js +73 -9
- package/dist/core/tasks/session.js.map +1 -1
- package/dist/core/tasks/store.d.ts +17 -4
- package/dist/core/tasks/store.d.ts.map +1 -1
- package/dist/core/tasks/store.js +45 -48
- package/dist/core/tasks/store.js.map +1 -1
- package/dist/core/tasks/types.d.ts +72 -29
- package/dist/core/tasks/types.d.ts.map +1 -1
- package/dist/core/tasks/types.js +7 -0
- package/dist/core/tasks/types.js.map +1 -1
- package/dist/core/tasks/wait.d.ts +19 -0
- package/dist/core/tasks/wait.d.ts.map +1 -0
- package/dist/core/tasks/wait.js +45 -0
- package/dist/core/tasks/wait.js.map +1 -0
- package/dist/core/tools/shell-execution.d.ts.map +1 -1
- package/dist/core/tools/shell-execution.js +2 -1
- package/dist/core/tools/shell-execution.js.map +1 -1
- package/dist/core/tools/shell-tool.d.ts.map +1 -1
- package/dist/core/tools/shell-tool.js +20 -13
- package/dist/core/tools/shell-tool.js.map +1 -1
- package/dist/extensions/agent/activity-lines.d.ts +10 -0
- package/dist/extensions/agent/activity-lines.d.ts.map +1 -0
- package/dist/extensions/agent/activity-lines.js +76 -0
- package/dist/extensions/agent/activity-lines.js.map +1 -0
- package/dist/extensions/agent/activity.d.ts +25 -4
- package/dist/extensions/agent/activity.d.ts.map +1 -1
- package/dist/extensions/agent/activity.js +76 -21
- package/dist/extensions/agent/activity.js.map +1 -1
- package/dist/extensions/agent/artifacts.d.ts +15 -0
- package/dist/extensions/agent/artifacts.d.ts.map +1 -0
- package/dist/extensions/agent/artifacts.js +44 -0
- package/dist/extensions/agent/artifacts.js.map +1 -0
- package/dist/extensions/agent/progress.d.ts +30 -4
- package/dist/extensions/agent/progress.d.ts.map +1 -1
- package/dist/extensions/agent/progress.js +84 -11
- package/dist/extensions/agent/progress.js.map +1 -1
- package/dist/extensions/agent/render.d.ts.map +1 -1
- package/dist/extensions/agent/render.js +8 -24
- package/dist/extensions/agent/render.js.map +1 -1
- package/dist/extensions/agent/report.d.ts +11 -3
- package/dist/extensions/agent/report.d.ts.map +1 -1
- package/dist/extensions/agent/report.js +32 -7
- package/dist/extensions/agent/report.js.map +1 -1
- package/dist/extensions/agent/tool.d.ts.map +1 -1
- package/dist/extensions/agent/tool.js +20 -5
- package/dist/extensions/agent/tool.js.map +1 -1
- package/dist/extensions/agent/types.d.ts +2 -0
- package/dist/extensions/agent/types.d.ts.map +1 -1
- package/dist/extensions/agent/types.js.map +1 -1
- package/dist/extensions/agent/worker.d.ts +7 -0
- package/dist/extensions/agent/worker.d.ts.map +1 -1
- package/dist/extensions/agent/worker.js +9 -3
- package/dist/extensions/agent/worker.js.map +1 -1
- package/dist/extensions/index.d.ts.map +1 -1
- package/dist/extensions/index.js +2 -0
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/search/index.d.ts.map +1 -1
- package/dist/extensions/search/index.js +6 -7
- package/dist/extensions/search/index.js.map +1 -1
- package/dist/extensions/shell-paths/index.d.ts +8 -0
- package/dist/extensions/shell-paths/index.d.ts.map +1 -0
- package/dist/extensions/shell-paths/index.js +74 -0
- package/dist/extensions/shell-paths/index.js.map +1 -0
- package/dist/extensions/tasks/tool/actions.d.ts.map +1 -1
- package/dist/extensions/tasks/tool/actions.js +15 -11
- package/dist/extensions/tasks/tool/actions.js.map +1 -1
- package/dist/extensions/tasks/tool/schema.d.ts +1 -1
- package/dist/extensions/tasks/tool/schema.d.ts.map +1 -1
- package/dist/extensions/tasks/tool/schema.js +5 -5
- package/dist/extensions/tasks/tool/schema.js.map +1 -1
- package/dist/extensions/tasks/tool/types.d.ts +2 -0
- package/dist/extensions/tasks/tool/types.d.ts.map +1 -1
- package/dist/extensions/tasks/tool/types.js.map +1 -1
- package/dist/extensions/tasks/tool.d.ts.map +1 -1
- package/dist/extensions/tasks/tool.js +3 -2
- package/dist/extensions/tasks/tool.js.map +1 -1
- package/dist/extensions/tasks/ui/completion-render.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/completion-render.js +2 -2
- package/dist/extensions/tasks/ui/completion-render.js.map +1 -1
- package/dist/extensions/tasks/ui/footer.d.ts +37 -0
- package/dist/extensions/tasks/ui/footer.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/footer.js +129 -0
- package/dist/extensions/tasks/ui/footer.js.map +1 -0
- package/dist/extensions/tasks/ui/frame.d.ts +36 -0
- package/dist/extensions/tasks/ui/frame.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/frame.js +33 -0
- package/dist/extensions/tasks/ui/frame.js.map +1 -0
- package/dist/extensions/tasks/ui/help.d.ts +6 -0
- package/dist/extensions/tasks/ui/help.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/help.js +53 -0
- package/dist/extensions/tasks/ui/help.js.map +1 -0
- package/dist/extensions/tasks/ui/inspector.d.ts +4 -3
- package/dist/extensions/tasks/ui/inspector.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/inspector.js +25 -6
- package/dist/extensions/tasks/ui/inspector.js.map +1 -1
- package/dist/extensions/tasks/ui/layout.d.ts +15 -18
- package/dist/extensions/tasks/ui/layout.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/layout.js +162 -255
- package/dist/extensions/tasks/ui/layout.js.map +1 -1
- package/dist/extensions/tasks/ui/list.d.ts +3 -1
- package/dist/extensions/tasks/ui/list.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/list.js +19 -14
- package/dist/extensions/tasks/ui/list.js.map +1 -1
- package/dist/extensions/tasks/ui/manager.d.ts +17 -5
- package/dist/extensions/tasks/ui/manager.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/manager.js +147 -90
- package/dist/extensions/tasks/ui/manager.js.map +1 -1
- package/dist/extensions/tasks/ui/model.d.ts +32 -5
- package/dist/extensions/tasks/ui/model.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/model.js +7 -7
- package/dist/extensions/tasks/ui/model.js.map +1 -1
- package/dist/extensions/tasks/ui/panes.d.ts +40 -0
- package/dist/extensions/tasks/ui/panes.d.ts.map +1 -0
- package/dist/extensions/tasks/ui/panes.js +144 -0
- package/dist/extensions/tasks/ui/panes.js.map +1 -0
- package/dist/extensions/tasks/ui/render.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/render.js +11 -7
- package/dist/extensions/tasks/ui/render.js.map +1 -1
- package/dist/extensions/tasks/ui/viewport.d.ts +12 -4
- package/dist/extensions/tasks/ui/viewport.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/viewport.js +23 -7
- package/dist/extensions/tasks/ui/viewport.js.map +1 -1
- package/dist/extensions/tasks/ui/views.d.ts +12 -6
- package/dist/extensions/tasks/ui/views.d.ts.map +1 -1
- package/dist/extensions/tasks/ui/views.js +39 -32
- package/dist/extensions/tasks/ui/views.js.map +1 -1
- package/dist/modes/interactive/chat-viewport.d.ts +5 -2
- package/dist/modes/interactive/chat-viewport.d.ts.map +1 -1
- package/dist/modes/interactive/chat-viewport.js +72 -12
- package/dist/modes/interactive/chat-viewport.js.map +1 -1
- package/dist/modes/interactive/components/session-selector.d.ts +11 -1
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector.js +43 -17
- package/dist/modes/interactive/components/session-selector.js.map +1 -1
- package/dist/modes/interactive/components/sticky-user-message.d.ts +23 -0
- package/dist/modes/interactive/components/sticky-user-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/sticky-user-message.js +58 -0
- package/dist/modes/interactive/components/sticky-user-message.js.map +1 -0
- package/dist/modes/interactive/components/user-message.d.ts +9 -0
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/user-message.js +51 -10
- package/dist/modes/interactive/components/user-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +4 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/tool-view/chat.d.ts +3 -2
- package/dist/modes/interactive/tool-view/chat.d.ts.map +1 -1
- package/dist/modes/interactive/tool-view/chat.js +3 -3
- package/dist/modes/interactive/tool-view/chat.js.map +1 -1
- package/dist/modes/interactive/transcript-layout.d.ts +23 -0
- package/dist/modes/interactive/transcript-layout.d.ts.map +1 -0
- package/dist/modes/interactive/transcript-layout.js +29 -0
- package/dist/modes/interactive/transcript-layout.js.map +1 -0
- package/dist/modes/print-mode.d.ts.map +1 -1
- package/dist/modes/print-mode.js +37 -2
- package/dist/modes/print-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +11 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +48 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +1 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +2 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/docs/bundled/README.md +1 -0
- package/docs/bundled/extensions/agent.md +39 -7
- package/docs/bundled/extensions/shell-paths.md +17 -0
- package/docs/bundled/tasks.md +25 -21
- package/docs/docs.json +4 -0
- package/docs/extensions.md +14 -10
- package/docs/json.md +3 -0
- package/docs/rpc.md +14 -0
- package/docs/sdk.md +11 -1
- package/docs/session-format.md +10 -4
- package/docs/sessions.md +1 -1
- package/docs/usage.md +3 -1
- package/npm-shrinkwrap.json +2 -2
- 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 {
|
|
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
|
-
|
|
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
|
-
/**
|
|
116
|
-
|
|
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.
|
|
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
|
|
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
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
|
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.
|
|
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"
|
|
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
|
-
|
|
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
|
|
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.
|
|
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
|
|
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.
|
|
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.
|
|
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.
|
|
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")
|
|
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")
|
|
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")
|
|
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.
|
|
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
|
-
|
|
305
|
-
this.selection.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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.
|
|
422
|
+
this.clearFeedback();
|
|
344
423
|
this.render(event.width);
|
|
345
424
|
const layout = this.layout;
|
|
346
|
-
const
|
|
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 (
|
|
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
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
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
|
|
359
|
-
this.inspector.position[this.selection.state.tab].move(delta, false
|
|
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
|
|
366
|
-
this.
|
|
367
|
-
else if (
|
|
368
|
-
this.
|
|
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.
|
|
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"]}
|