opencode-subagents-sidebar-plugin 0.1.3 → 0.1.5
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/README.md +11 -5
- package/dist/popover.d.ts +23 -0
- package/dist/popover.d.ts.map +1 -0
- package/dist/popover.js +57 -0
- package/dist/popover.js.map +1 -0
- package/dist/tasks.d.ts +2 -0
- package/dist/tasks.d.ts.map +1 -1
- package/dist/tasks.js +11 -0
- package/dist/tasks.js.map +1 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +443 -251
- package/dist/tui.js.map +1 -1
- package/package.json +1 -1
package/dist/tui.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { use as _$use } from "@opentui/solid";
|
|
1
2
|
import { createComponent as _$createComponent } from "@opentui/solid";
|
|
2
3
|
import { effect as _$effect } from "@opentui/solid";
|
|
3
4
|
import { memo as _$memo } from "@opentui/solid";
|
|
@@ -8,9 +9,16 @@ import { setProp as _$setProp } from "@opentui/solid";
|
|
|
8
9
|
import { createElement as _$createElement } from "@opentui/solid";
|
|
9
10
|
/** @jsxImportSource @opentui/solid */
|
|
10
11
|
|
|
12
|
+
import { Portal, useTerminalDimensions } from "@opentui/solid";
|
|
11
13
|
import { elapsedLabel } from "./activity.js";
|
|
12
|
-
import {
|
|
14
|
+
import { placePopover } from "./popover.js";
|
|
15
|
+
import { canOpenTaskSession, isTaskPart, isVisibleTask, latestAssistantText, resolveTaskModel, taskAgent, taskDescription, taskModeLabel, taskModelLabel, taskSessionID, taskStatusLabel, taskVariantLabel } from "./tasks.js";
|
|
13
16
|
import { createEffect, createMemo, createSignal, For, on, onCleanup, onMount, Show } from "solid-js";
|
|
17
|
+
const POPOVER_SIZE = {
|
|
18
|
+
width: 52,
|
|
19
|
+
height: 14
|
|
20
|
+
};
|
|
21
|
+
const POPOVER_Z_INDEX = 100;
|
|
14
22
|
function resolvedModel(api, part, session, sessionID) {
|
|
15
23
|
return resolveTaskModel(part, session, sessionID ? api.state.session.messages(sessionID) : []);
|
|
16
24
|
}
|
|
@@ -18,9 +26,16 @@ function modelName(api, model) {
|
|
|
18
26
|
const name = model ? api.state.provider.find(provider => provider.id === model.providerID)?.models[model.modelID]?.name : undefined;
|
|
19
27
|
return taskModelLabel(model, name);
|
|
20
28
|
}
|
|
21
|
-
function
|
|
29
|
+
function TaskPopover(props) {
|
|
30
|
+
const viewport = useTerminalDimensions();
|
|
31
|
+
const [hydratedChildMessages, setHydratedChildMessages] = createSignal();
|
|
32
|
+
const placement = createMemo(() => placePopover(props.ownership().anchor, viewport(), POPOVER_SIZE));
|
|
33
|
+
const callID = () => props.ownership().callID;
|
|
34
|
+
let portalWrapper;
|
|
35
|
+
let hydrationRequest = 0;
|
|
36
|
+
let requestedHydration;
|
|
22
37
|
const fallback = () => {
|
|
23
|
-
const known = props.fallbackFor(
|
|
38
|
+
const known = props.fallbackFor(callID());
|
|
24
39
|
if (known) return known;
|
|
25
40
|
const sessionID = taskSessionID(props.fallbackPart);
|
|
26
41
|
return {
|
|
@@ -32,7 +47,7 @@ function TaskDetails(props) {
|
|
|
32
47
|
};
|
|
33
48
|
const part = createMemo(() => {
|
|
34
49
|
props.revision();
|
|
35
|
-
return props.tasksByCallID().get(
|
|
50
|
+
return props.tasksByCallID().get(callID()) ?? fallback().part;
|
|
36
51
|
});
|
|
37
52
|
const childSessionID = () => taskSessionID(part() ?? fallback().part) ?? fallback().sessionID;
|
|
38
53
|
const childSession = () => {
|
|
@@ -45,6 +60,80 @@ function TaskDetails(props) {
|
|
|
45
60
|
return resolvedModel(props.api, part() ?? fallback().part, childSession(), childSessionID());
|
|
46
61
|
});
|
|
47
62
|
const canOpen = () => canOpenTaskSession(childSessionID(), props.currentSessionID);
|
|
63
|
+
const liveChildMessages = createMemo(() => {
|
|
64
|
+
props.revision();
|
|
65
|
+
const sessionID = childSessionID();
|
|
66
|
+
if (!sessionID) return undefined;
|
|
67
|
+
const messages = props.api.state.session.messages(sessionID);
|
|
68
|
+
const parts = new Map();
|
|
69
|
+
let hasParts = false;
|
|
70
|
+
for (const message of messages) {
|
|
71
|
+
const messageParts = props.api.state.part(message.id);
|
|
72
|
+
parts.set(message.id, messageParts);
|
|
73
|
+
if (messageParts.length) hasParts = true;
|
|
74
|
+
}
|
|
75
|
+
return {
|
|
76
|
+
sessionID,
|
|
77
|
+
messages,
|
|
78
|
+
parts,
|
|
79
|
+
hasParts
|
|
80
|
+
};
|
|
81
|
+
});
|
|
82
|
+
const ownsHydration = (token, sessionID, request) => {
|
|
83
|
+
if (props.api.lifecycle.signal.aborted || request !== hydrationRequest) return false;
|
|
84
|
+
return props.ownership().token === token && childSessionID() === sessionID;
|
|
85
|
+
};
|
|
86
|
+
const hydrateChildMessages = async (token, sessionID, request) => {
|
|
87
|
+
try {
|
|
88
|
+
const result = await props.api.client.session.messages({
|
|
89
|
+
sessionID,
|
|
90
|
+
directory: props.api.state.path.directory
|
|
91
|
+
}, {
|
|
92
|
+
throwOnError: true
|
|
93
|
+
});
|
|
94
|
+
if (!ownsHydration(token, sessionID, request)) return;
|
|
95
|
+
if (liveChildMessages()?.hasParts) return;
|
|
96
|
+
setHydratedChildMessages({
|
|
97
|
+
token,
|
|
98
|
+
sessionID,
|
|
99
|
+
messages: result.data
|
|
100
|
+
});
|
|
101
|
+
} catch {
|
|
102
|
+
if (ownsHydration(token, sessionID, request)) requestedHydration = undefined;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
createEffect(() => {
|
|
106
|
+
const ownership = props.ownership();
|
|
107
|
+
const sessionID = childSessionID();
|
|
108
|
+
const live = liveChildMessages();
|
|
109
|
+
if (!sessionID || live?.hasParts) {
|
|
110
|
+
if (requestedHydration) {
|
|
111
|
+
requestedHydration = undefined;
|
|
112
|
+
hydrationRequest += 1;
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (requestedHydration?.token === ownership.token && requestedHydration.sessionID === sessionID) return;
|
|
117
|
+
const request = ++hydrationRequest;
|
|
118
|
+
requestedHydration = {
|
|
119
|
+
token: ownership.token,
|
|
120
|
+
sessionID
|
|
121
|
+
};
|
|
122
|
+
setHydratedChildMessages(undefined);
|
|
123
|
+
void hydrateChildMessages(ownership.token, sessionID, request);
|
|
124
|
+
});
|
|
125
|
+
const latestResponse = createMemo(() => {
|
|
126
|
+
const ownership = props.ownership();
|
|
127
|
+
const sessionID = childSessionID();
|
|
128
|
+
if (!sessionID) return undefined;
|
|
129
|
+
const live = liveChildMessages();
|
|
130
|
+
if (live?.hasParts) return latestAssistantText(live.messages, messageID => live.parts.get(messageID) ?? []);
|
|
131
|
+
const hydrated = hydratedChildMessages();
|
|
132
|
+
if (!hydrated || hydrated.token !== ownership.token || hydrated.sessionID !== sessionID) return undefined;
|
|
133
|
+
const parts = new Map(hydrated.messages.map(message => [message.info.id, message.parts]));
|
|
134
|
+
return latestAssistantText(hydrated.messages.map(message => message.info), messageID => parts.get(messageID) ?? []);
|
|
135
|
+
});
|
|
136
|
+
const responseLabel = () => latestResponse() ?? (childSessionID() ? "Waiting for assistant response" : "Waiting for child session");
|
|
48
137
|
const openSession = () => {
|
|
49
138
|
const sessionID = childSessionID();
|
|
50
139
|
if (!canOpen() || !sessionID) return;
|
|
@@ -53,122 +142,166 @@ function TaskDetails(props) {
|
|
|
53
142
|
});
|
|
54
143
|
props.close();
|
|
55
144
|
};
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
_el$
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
145
|
+
const applyPortalPlacement = (next = placement()) => {
|
|
146
|
+
const wrapper = portalWrapper;
|
|
147
|
+
if (!wrapper || wrapper.isDestroyed) return;
|
|
148
|
+
wrapper.position = "absolute";
|
|
149
|
+
wrapper.left = next.left;
|
|
150
|
+
wrapper.top = next.top;
|
|
151
|
+
wrapper.width = next.width;
|
|
152
|
+
wrapper.height = next.height;
|
|
153
|
+
wrapper.zIndex = POPOVER_Z_INDEX;
|
|
154
|
+
wrapper.focusable = false;
|
|
155
|
+
};
|
|
156
|
+
createEffect(() => applyPortalPlacement(placement()));
|
|
157
|
+
onCleanup(() => {
|
|
158
|
+
hydrationRequest += 1;
|
|
159
|
+
requestedHydration = undefined;
|
|
160
|
+
portalWrapper = undefined;
|
|
161
|
+
});
|
|
162
|
+
return _$createComponent(Portal, {
|
|
163
|
+
get mount() {
|
|
164
|
+
return props.api.renderer.root;
|
|
165
|
+
},
|
|
166
|
+
ref: element => {
|
|
167
|
+
portalWrapper = element;
|
|
168
|
+
applyPortalPlacement();
|
|
169
|
+
},
|
|
170
|
+
get children() {
|
|
171
|
+
var _el$ = _$createElement("box"),
|
|
172
|
+
_el$2 = _$createElement("text"),
|
|
173
|
+
_el$3 = _$createElement("b"),
|
|
174
|
+
_el$5 = _$createElement("text"),
|
|
175
|
+
_el$6 = _$createTextNode(`Agent: `),
|
|
176
|
+
_el$7 = _$createElement("text"),
|
|
177
|
+
_el$8 = _$createTextNode(`Assigned: `),
|
|
178
|
+
_el$9 = _$createElement("text"),
|
|
179
|
+
_el$0 = _$createTextNode(`Latest: `),
|
|
180
|
+
_el$1 = _$createElement("text"),
|
|
181
|
+
_el$10 = _$createTextNode(`Status: `),
|
|
182
|
+
_el$11 = _$createElement("text"),
|
|
183
|
+
_el$12 = _$createTextNode(`Model: `),
|
|
184
|
+
_el$13 = _$createTextNode(` · `),
|
|
185
|
+
_el$14 = _$createElement("text"),
|
|
186
|
+
_el$15 = _$createTextNode(` · `),
|
|
187
|
+
_el$16 = _$createElement("text"),
|
|
188
|
+
_el$17 = _$createTextNode(`Child: `),
|
|
189
|
+
_el$18 = _$createElement("box"),
|
|
190
|
+
_el$19 = _$createElement("box"),
|
|
191
|
+
_el$20 = _$createElement("text"),
|
|
192
|
+
_el$21 = _$createElement("b"),
|
|
193
|
+
_el$23 = _$createElement("box"),
|
|
194
|
+
_el$24 = _$createElement("text"),
|
|
195
|
+
_el$25 = _$createElement("b");
|
|
196
|
+
_$insertNode(_el$, _el$2);
|
|
197
|
+
_$insertNode(_el$, _el$5);
|
|
198
|
+
_$insertNode(_el$, _el$7);
|
|
199
|
+
_$insertNode(_el$, _el$9);
|
|
200
|
+
_$insertNode(_el$, _el$1);
|
|
201
|
+
_$insertNode(_el$, _el$11);
|
|
202
|
+
_$insertNode(_el$, _el$14);
|
|
203
|
+
_$insertNode(_el$, _el$16);
|
|
204
|
+
_$insertNode(_el$, _el$18);
|
|
205
|
+
_$setProp(_el$, "width", "100%");
|
|
206
|
+
_$setProp(_el$, "height", "100%");
|
|
207
|
+
_$setProp(_el$, "focusable", false);
|
|
208
|
+
_$setProp(_el$, "live", true);
|
|
209
|
+
_$setProp(_el$, "border", true);
|
|
210
|
+
_$setProp(_el$, "padding", 1);
|
|
211
|
+
_$setProp(_el$, "flexDirection", "column");
|
|
212
|
+
_$setProp(_el$, "overflow", "hidden");
|
|
213
|
+
_$insertNode(_el$2, _el$3);
|
|
214
|
+
_$setProp(_el$2, "wrapMode", "none");
|
|
215
|
+
_$setProp(_el$2, "truncate", true);
|
|
216
|
+
_$insertNode(_el$3, _$createTextNode(`Subagent details`));
|
|
217
|
+
_$insertNode(_el$5, _el$6);
|
|
218
|
+
_$setProp(_el$5, "wrapMode", "none");
|
|
219
|
+
_$setProp(_el$5, "truncate", true);
|
|
220
|
+
_$insert(_el$5, () => taskAgent(part() ?? fallback().part), null);
|
|
221
|
+
_$insertNode(_el$7, _el$8);
|
|
222
|
+
_$setProp(_el$7, "wrapMode", "none");
|
|
223
|
+
_$setProp(_el$7, "truncate", true);
|
|
224
|
+
_$insert(_el$7, () => taskDescription(part() ?? fallback().part), null);
|
|
225
|
+
_$insertNode(_el$9, _el$0);
|
|
226
|
+
_$setProp(_el$9, "wrapMode", "none");
|
|
227
|
+
_$setProp(_el$9, "truncate", true);
|
|
228
|
+
_$insert(_el$9, responseLabel, null);
|
|
229
|
+
_$insertNode(_el$1, _el$10);
|
|
230
|
+
_$setProp(_el$1, "wrapMode", "none");
|
|
231
|
+
_$setProp(_el$1, "truncate", true);
|
|
232
|
+
_$insert(_el$1, () => taskStatusLabel(part() ?? fallback().part, childSessionID() ? props.api.state.session.status(childSessionID()) : undefined), null);
|
|
233
|
+
_$insertNode(_el$11, _el$12);
|
|
234
|
+
_$insertNode(_el$11, _el$13);
|
|
235
|
+
_$setProp(_el$11, "wrapMode", "none");
|
|
236
|
+
_$setProp(_el$11, "truncate", true);
|
|
237
|
+
_$insert(_el$11, () => modelName(props.api, model()), _el$13);
|
|
238
|
+
_$insert(_el$11, () => taskVariantLabel(model()) ?? "pending", null);
|
|
239
|
+
_$insertNode(_el$14, _el$15);
|
|
240
|
+
_$setProp(_el$14, "wrapMode", "none");
|
|
241
|
+
_$setProp(_el$14, "truncate", true);
|
|
242
|
+
_$insert(_el$14, () => taskModeLabel(part() ?? fallback().part), _el$15);
|
|
243
|
+
_$insert(_el$14, () => elapsedLabel(props.now() - props.startedAt(part() ?? fallback().part)), null);
|
|
244
|
+
_$insertNode(_el$16, _el$17);
|
|
245
|
+
_$setProp(_el$16, "wrapMode", "none");
|
|
246
|
+
_$setProp(_el$16, "truncate", true);
|
|
247
|
+
_$insert(_el$16, () => childSessionID() ?? "Waiting for child session", null);
|
|
248
|
+
_$insertNode(_el$18, _el$19);
|
|
249
|
+
_$insertNode(_el$18, _el$23);
|
|
250
|
+
_$setProp(_el$18, "flexDirection", "row");
|
|
251
|
+
_$setProp(_el$18, "gap", 2);
|
|
252
|
+
_$insertNode(_el$19, _el$20);
|
|
253
|
+
_$setProp(_el$19, "onMouseUp", openSession);
|
|
254
|
+
_$insertNode(_el$20, _el$21);
|
|
255
|
+
_$insertNode(_el$21, _$createTextNode(`Open Session`));
|
|
256
|
+
_$insertNode(_el$23, _el$24);
|
|
257
|
+
_$insertNode(_el$24, _el$25);
|
|
258
|
+
_$insertNode(_el$25, _$createTextNode(`Close`));
|
|
259
|
+
_$effect(_p$ => {
|
|
260
|
+
var _v$ = props.api.theme.current.borderActive,
|
|
261
|
+
_v$2 = props.api.theme.current.backgroundPanel,
|
|
262
|
+
_v$3 = props.api.theme.current.text,
|
|
263
|
+
_v$4 = props.api.theme.current.text,
|
|
264
|
+
_v$5 = props.api.theme.current.textMuted,
|
|
265
|
+
_v$6 = props.api.theme.current.textMuted,
|
|
266
|
+
_v$7 = props.api.theme.current.textMuted,
|
|
267
|
+
_v$8 = props.api.theme.current.textMuted,
|
|
268
|
+
_v$9 = props.api.theme.current.textMuted,
|
|
269
|
+
_v$0 = props.api.theme.current.textMuted,
|
|
270
|
+
_v$1 = canOpen() ? props.api.theme.current.primary : props.api.theme.current.textMuted,
|
|
271
|
+
_v$10 = props.close,
|
|
272
|
+
_v$11 = props.api.theme.current.primary;
|
|
273
|
+
_v$ !== _p$.e && (_p$.e = _$setProp(_el$, "borderColor", _v$, _p$.e));
|
|
274
|
+
_v$2 !== _p$.t && (_p$.t = _$setProp(_el$, "backgroundColor", _v$2, _p$.t));
|
|
275
|
+
_v$3 !== _p$.a && (_p$.a = _$setProp(_el$2, "fg", _v$3, _p$.a));
|
|
276
|
+
_v$4 !== _p$.o && (_p$.o = _$setProp(_el$5, "fg", _v$4, _p$.o));
|
|
277
|
+
_v$5 !== _p$.i && (_p$.i = _$setProp(_el$7, "fg", _v$5, _p$.i));
|
|
278
|
+
_v$6 !== _p$.n && (_p$.n = _$setProp(_el$9, "fg", _v$6, _p$.n));
|
|
279
|
+
_v$7 !== _p$.s && (_p$.s = _$setProp(_el$1, "fg", _v$7, _p$.s));
|
|
280
|
+
_v$8 !== _p$.h && (_p$.h = _$setProp(_el$11, "fg", _v$8, _p$.h));
|
|
281
|
+
_v$9 !== _p$.r && (_p$.r = _$setProp(_el$14, "fg", _v$9, _p$.r));
|
|
282
|
+
_v$0 !== _p$.d && (_p$.d = _$setProp(_el$16, "fg", _v$0, _p$.d));
|
|
283
|
+
_v$1 !== _p$.l && (_p$.l = _$setProp(_el$20, "fg", _v$1, _p$.l));
|
|
284
|
+
_v$10 !== _p$.u && (_p$.u = _$setProp(_el$23, "onMouseUp", _v$10, _p$.u));
|
|
285
|
+
_v$11 !== _p$.c && (_p$.c = _$setProp(_el$24, "fg", _v$11, _p$.c));
|
|
286
|
+
return _p$;
|
|
287
|
+
}, {
|
|
288
|
+
e: undefined,
|
|
289
|
+
t: undefined,
|
|
290
|
+
a: undefined,
|
|
291
|
+
o: undefined,
|
|
292
|
+
i: undefined,
|
|
293
|
+
n: undefined,
|
|
294
|
+
s: undefined,
|
|
295
|
+
h: undefined,
|
|
296
|
+
r: undefined,
|
|
297
|
+
d: undefined,
|
|
298
|
+
l: undefined,
|
|
299
|
+
u: undefined,
|
|
300
|
+
c: undefined
|
|
301
|
+
});
|
|
302
|
+
return _el$;
|
|
303
|
+
}
|
|
304
|
+
});
|
|
172
305
|
}
|
|
173
306
|
function TaskCard(props) {
|
|
174
307
|
// The call ID is stable, while the actual ToolPart is re-read after each event.
|
|
@@ -191,59 +324,89 @@ function TaskCard(props) {
|
|
|
191
324
|
const current = part();
|
|
192
325
|
return current ? elapsedLabel(props.now() - props.startedAt(current)) : "";
|
|
193
326
|
};
|
|
327
|
+
let card;
|
|
328
|
+
let lastAnchor;
|
|
329
|
+
const anchor = () => card && {
|
|
330
|
+
x: card.screenX,
|
|
331
|
+
y: card.screenY,
|
|
332
|
+
width: card.width,
|
|
333
|
+
height: card.height
|
|
334
|
+
};
|
|
335
|
+
const updateAnchor = () => {
|
|
336
|
+
const current = anchor();
|
|
337
|
+
if (!current || lastAnchor && lastAnchor.x === current.x && lastAnchor.y === current.y && lastAnchor.width === current.width && lastAnchor.height === current.height) {
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
lastAnchor = current;
|
|
341
|
+
props.updatePopupAnchor(props.callID, current);
|
|
342
|
+
};
|
|
343
|
+
onCleanup(() => {
|
|
344
|
+
// The popover owns its last reported rect, so losing this card must not
|
|
345
|
+
// reset its placement before the user explicitly closes it.
|
|
346
|
+
card = undefined;
|
|
347
|
+
lastAnchor = undefined;
|
|
348
|
+
});
|
|
194
349
|
const openDetails = () => {
|
|
195
350
|
if (props.api.renderer.getSelection()?.getSelectedText()) return;
|
|
196
351
|
const part = livePart();
|
|
197
|
-
|
|
352
|
+
const currentAnchor = anchor();
|
|
353
|
+
if (!part || !currentAnchor) return;
|
|
198
354
|
props.remember(part);
|
|
199
|
-
props.openPopup(props.callID,
|
|
355
|
+
props.openPopup(props.callID, currentAnchor);
|
|
200
356
|
};
|
|
201
357
|
return (() => {
|
|
202
|
-
var _el$
|
|
203
|
-
_el$
|
|
204
|
-
_el$
|
|
205
|
-
_el$
|
|
358
|
+
var _el$27 = _$createElement("box"),
|
|
359
|
+
_el$28 = _$createElement("box"),
|
|
360
|
+
_el$29 = _$createElement("text"),
|
|
361
|
+
_el$30 = _$createElement("b"),
|
|
362
|
+
_el$31 = _$createElement("box"),
|
|
363
|
+
_el$32 = _$createElement("text"),
|
|
206
364
|
_el$33 = _$createElement("box"),
|
|
207
365
|
_el$34 = _$createElement("text"),
|
|
208
366
|
_el$35 = _$createElement("box"),
|
|
209
|
-
_el$36 = _$createElement("text")
|
|
210
|
-
|
|
211
|
-
|
|
367
|
+
_el$36 = _$createElement("text");
|
|
368
|
+
_$insertNode(_el$27, _el$28);
|
|
369
|
+
_$insertNode(_el$27, _el$33);
|
|
370
|
+
_$use(element => {
|
|
371
|
+
card = element;
|
|
372
|
+
updateAnchor();
|
|
373
|
+
}, _el$27);
|
|
374
|
+
_$setProp(_el$27, "onSizeChange", updateAnchor);
|
|
375
|
+
_$setProp(_el$27, "renderBefore", updateAnchor);
|
|
376
|
+
_$setProp(_el$27, "width", "100%");
|
|
377
|
+
_$setProp(_el$27, "height", 2);
|
|
378
|
+
_$setProp(_el$27, "flexDirection", "column");
|
|
379
|
+
_$setProp(_el$27, "overflow", "hidden");
|
|
380
|
+
_$setProp(_el$27, "onMouseUp", openDetails);
|
|
381
|
+
_$insertNode(_el$28, _el$29);
|
|
382
|
+
_$insertNode(_el$28, _el$31);
|
|
383
|
+
_$setProp(_el$28, "width", "100%");
|
|
384
|
+
_$setProp(_el$28, "height", 1);
|
|
385
|
+
_$setProp(_el$28, "flexDirection", "row");
|
|
386
|
+
_$setProp(_el$28, "overflow", "hidden");
|
|
212
387
|
_$insertNode(_el$29, _el$30);
|
|
213
|
-
_$
|
|
214
|
-
_$setProp(_el$29, "
|
|
215
|
-
_$setProp(_el$29, "
|
|
216
|
-
_$setProp(_el$29, "
|
|
217
|
-
_$setProp(_el$29, "
|
|
218
|
-
_$
|
|
219
|
-
_$insertNode(_el$30, _el$33);
|
|
220
|
-
_$setProp(_el$30, "width", "100%");
|
|
221
|
-
_$setProp(_el$30, "height", 1);
|
|
222
|
-
_$setProp(_el$30, "flexDirection", "row");
|
|
223
|
-
_$setProp(_el$30, "overflow", "hidden");
|
|
224
|
-
_$insertNode(_el$31, _el$32);
|
|
225
|
-
_$setProp(_el$31, "flexGrow", 1);
|
|
226
|
-
_$setProp(_el$31, "flexShrink", 1);
|
|
227
|
-
_$setProp(_el$31, "minWidth", 0);
|
|
228
|
-
_$setProp(_el$31, "wrapMode", "none");
|
|
229
|
-
_$setProp(_el$31, "truncate", true);
|
|
230
|
-
_$insert(_el$32, (() => {
|
|
388
|
+
_$setProp(_el$29, "flexGrow", 1);
|
|
389
|
+
_$setProp(_el$29, "flexShrink", 1);
|
|
390
|
+
_$setProp(_el$29, "minWidth", 0);
|
|
391
|
+
_$setProp(_el$29, "wrapMode", "none");
|
|
392
|
+
_$setProp(_el$29, "truncate", true);
|
|
393
|
+
_$insert(_el$30, (() => {
|
|
231
394
|
var _c$ = _$memo(() => !!part());
|
|
232
395
|
return () => _c$() ? taskAgent(part()) : "subagent";
|
|
233
396
|
})());
|
|
234
|
-
_$insertNode(_el$
|
|
235
|
-
_$setProp(_el$
|
|
236
|
-
_$setProp(_el$
|
|
237
|
-
_$setProp(_el$
|
|
238
|
-
_$setProp(_el$
|
|
239
|
-
_$setProp(_el$
|
|
240
|
-
_$setProp(_el$
|
|
241
|
-
_$setProp(_el$
|
|
242
|
-
_$setProp(_el$
|
|
243
|
-
_$setProp(_el$
|
|
244
|
-
_$setProp(_el$
|
|
245
|
-
_$insert(_el$
|
|
246
|
-
_$insert(_el$
|
|
397
|
+
_$insertNode(_el$31, _el$32);
|
|
398
|
+
_$setProp(_el$31, "flexShrink", 1);
|
|
399
|
+
_$setProp(_el$31, "minWidth", 0);
|
|
400
|
+
_$setProp(_el$31, "maxWidth", 28);
|
|
401
|
+
_$setProp(_el$31, "marginLeft", 1);
|
|
402
|
+
_$setProp(_el$31, "flexDirection", "row");
|
|
403
|
+
_$setProp(_el$32, "flexGrow", 1);
|
|
404
|
+
_$setProp(_el$32, "flexShrink", 1);
|
|
405
|
+
_$setProp(_el$32, "minWidth", 0);
|
|
406
|
+
_$setProp(_el$32, "wrapMode", "none");
|
|
407
|
+
_$setProp(_el$32, "truncate", true);
|
|
408
|
+
_$insert(_el$32, () => modelName(props.api, model()));
|
|
409
|
+
_$insert(_el$31, _$createComponent(Show, {
|
|
247
410
|
get when() {
|
|
248
411
|
return taskVariantLabel(model());
|
|
249
412
|
},
|
|
@@ -253,61 +416,62 @@ function TaskCard(props) {
|
|
|
253
416
|
return model();
|
|
254
417
|
},
|
|
255
418
|
get children() {
|
|
256
|
-
var _el$
|
|
257
|
-
_$insertNode(_el$
|
|
258
|
-
_$setProp(_el$
|
|
259
|
-
_$setProp(_el$
|
|
260
|
-
_$setProp(_el$
|
|
261
|
-
_$setProp(_el$
|
|
262
|
-
_$effect(_$p => _$setProp(_el$
|
|
263
|
-
return _el$
|
|
419
|
+
var _el$37 = _$createElement("text");
|
|
420
|
+
_$insertNode(_el$37, _$createTextNode(`· pending`));
|
|
421
|
+
_$setProp(_el$37, "flexShrink", 0);
|
|
422
|
+
_$setProp(_el$37, "marginLeft", 1);
|
|
423
|
+
_$setProp(_el$37, "wrapMode", "none");
|
|
424
|
+
_$setProp(_el$37, "truncate", true);
|
|
425
|
+
_$effect(_$p => _$setProp(_el$37, "fg", props.api.theme.current.textMuted, _$p));
|
|
426
|
+
return _el$37;
|
|
264
427
|
}
|
|
265
428
|
});
|
|
266
429
|
},
|
|
267
430
|
children: variant => (() => {
|
|
268
|
-
var _el$
|
|
269
|
-
_el$
|
|
270
|
-
_$insertNode(_el$
|
|
271
|
-
_$setProp(_el$
|
|
272
|
-
_$setProp(_el$
|
|
273
|
-
_$setProp(_el$
|
|
274
|
-
_$setProp(_el$
|
|
275
|
-
_$insert(_el$
|
|
276
|
-
_$effect(_$p => _$setProp(_el$
|
|
277
|
-
return _el$
|
|
431
|
+
var _el$39 = _$createElement("text"),
|
|
432
|
+
_el$40 = _$createTextNode(`· `);
|
|
433
|
+
_$insertNode(_el$39, _el$40);
|
|
434
|
+
_$setProp(_el$39, "flexShrink", 0);
|
|
435
|
+
_$setProp(_el$39, "marginLeft", 1);
|
|
436
|
+
_$setProp(_el$39, "wrapMode", "none");
|
|
437
|
+
_$setProp(_el$39, "truncate", true);
|
|
438
|
+
_$insert(_el$39, variant, null);
|
|
439
|
+
_$effect(_$p => _$setProp(_el$39, "fg", props.api.theme.current.textMuted, _$p));
|
|
440
|
+
return _el$39;
|
|
278
441
|
})()
|
|
279
442
|
}), null);
|
|
443
|
+
_$insertNode(_el$33, _el$34);
|
|
444
|
+
_$insertNode(_el$33, _el$35);
|
|
445
|
+
_$setProp(_el$33, "width", "100%");
|
|
446
|
+
_$setProp(_el$33, "height", 1);
|
|
447
|
+
_$setProp(_el$33, "flexDirection", "row");
|
|
448
|
+
_$setProp(_el$33, "overflow", "hidden");
|
|
449
|
+
_$setProp(_el$34, "flexGrow", 1);
|
|
450
|
+
_$setProp(_el$34, "flexShrink", 1);
|
|
451
|
+
_$setProp(_el$34, "minWidth", 0);
|
|
452
|
+
_$setProp(_el$34, "wrapMode", "none");
|
|
453
|
+
_$setProp(_el$34, "truncate", true);
|
|
454
|
+
_$insert(_el$34, (() => {
|
|
455
|
+
var _c$2 = _$memo(() => !!part());
|
|
456
|
+
return () => _c$2() ? taskDescription(part()) : "Working";
|
|
457
|
+
})());
|
|
280
458
|
_$insertNode(_el$35, _el$36);
|
|
281
|
-
_$
|
|
282
|
-
_$setProp(_el$35, "
|
|
283
|
-
_$setProp(_el$35, "height", 1);
|
|
459
|
+
_$setProp(_el$35, "width", 8);
|
|
460
|
+
_$setProp(_el$35, "flexShrink", 0);
|
|
284
461
|
_$setProp(_el$35, "flexDirection", "row");
|
|
285
|
-
_$setProp(_el$35, "
|
|
286
|
-
_$setProp(_el$36, "flexGrow", 1);
|
|
287
|
-
_$setProp(_el$36, "flexShrink", 1);
|
|
288
|
-
_$setProp(_el$36, "minWidth", 0);
|
|
462
|
+
_$setProp(_el$35, "justifyContent", "flex-end");
|
|
289
463
|
_$setProp(_el$36, "wrapMode", "none");
|
|
290
464
|
_$setProp(_el$36, "truncate", true);
|
|
291
|
-
_$insert(_el$36,
|
|
292
|
-
var _c$2 = _$memo(() => !!part());
|
|
293
|
-
return () => _c$2() ? taskDescription(part()) : "Working";
|
|
294
|
-
})());
|
|
295
|
-
_$insertNode(_el$37, _el$38);
|
|
296
|
-
_$setProp(_el$37, "width", 8);
|
|
297
|
-
_$setProp(_el$37, "flexShrink", 0);
|
|
298
|
-
_$setProp(_el$37, "justifyContent", "flex-end");
|
|
299
|
-
_$setProp(_el$38, "wrapMode", "none");
|
|
300
|
-
_$setProp(_el$38, "truncate", true);
|
|
301
|
-
_$insert(_el$38, elapsed);
|
|
465
|
+
_$insert(_el$36, elapsed);
|
|
302
466
|
_$effect(_p$ => {
|
|
303
|
-
var _v$
|
|
304
|
-
_v$12 = props.api.theme.current.textMuted,
|
|
467
|
+
var _v$12 = props.api.theme.current.text,
|
|
305
468
|
_v$13 = props.api.theme.current.textMuted,
|
|
306
|
-
_v$14 = props.api.theme.current.textMuted
|
|
307
|
-
|
|
308
|
-
_v$12 !== _p$.
|
|
309
|
-
_v$13 !== _p$.
|
|
310
|
-
_v$14 !== _p$.
|
|
469
|
+
_v$14 = props.api.theme.current.textMuted,
|
|
470
|
+
_v$15 = props.api.theme.current.textMuted;
|
|
471
|
+
_v$12 !== _p$.e && (_p$.e = _$setProp(_el$29, "fg", _v$12, _p$.e));
|
|
472
|
+
_v$13 !== _p$.t && (_p$.t = _$setProp(_el$32, "fg", _v$13, _p$.t));
|
|
473
|
+
_v$14 !== _p$.a && (_p$.a = _$setProp(_el$34, "fg", _v$14, _p$.a));
|
|
474
|
+
_v$15 !== _p$.o && (_p$.o = _$setProp(_el$36, "fg", _v$15, _p$.o));
|
|
311
475
|
return _p$;
|
|
312
476
|
}, {
|
|
313
477
|
e: undefined,
|
|
@@ -315,7 +479,7 @@ function TaskCard(props) {
|
|
|
315
479
|
a: undefined,
|
|
316
480
|
o: undefined
|
|
317
481
|
});
|
|
318
|
-
return _el$
|
|
482
|
+
return _el$27;
|
|
319
483
|
})();
|
|
320
484
|
}
|
|
321
485
|
function RunningSubagents(props) {
|
|
@@ -369,7 +533,10 @@ function RunningSubagents(props) {
|
|
|
369
533
|
setRevision(value => value + 1);
|
|
370
534
|
void loadMessages(parentSessionID, currentRequest);
|
|
371
535
|
};
|
|
372
|
-
createEffect(on(() => props.sessionID, sessionID =>
|
|
536
|
+
createEffect(on(() => props.sessionID, (sessionID, previousSessionID) => {
|
|
537
|
+
if (previousSessionID !== undefined && sessionID !== previousSessionID) setOpenPopup(undefined);
|
|
538
|
+
void selectSession(sessionID);
|
|
539
|
+
}));
|
|
373
540
|
const allTaskParts = createMemo(() => {
|
|
374
541
|
revision();
|
|
375
542
|
const sessionID = scopeSessionID();
|
|
@@ -420,37 +587,36 @@ function RunningSubagents(props) {
|
|
|
420
587
|
firstSeen.set(part.callID, value);
|
|
421
588
|
return value;
|
|
422
589
|
};
|
|
423
|
-
const releasePopup = ownership => {
|
|
424
|
-
if (openPopup()?.token === ownership.token) setOpenPopup(undefined);
|
|
425
|
-
};
|
|
426
590
|
const closePopup = ownership => {
|
|
427
591
|
if (openPopup()?.token !== ownership.token) return;
|
|
428
592
|
setOpenPopup(undefined);
|
|
429
|
-
props.api.ui.dialog.clear();
|
|
430
593
|
};
|
|
431
|
-
const showPopup = (callID,
|
|
594
|
+
const showPopup = (callID, anchor) => {
|
|
432
595
|
const ownership = {
|
|
433
596
|
callID,
|
|
434
|
-
token: Symbol(callID)
|
|
597
|
+
token: Symbol(callID),
|
|
598
|
+
anchor
|
|
435
599
|
};
|
|
436
600
|
setOpenPopup(ownership);
|
|
437
|
-
props.api.ui.dialog.replace(() => _$createComponent(TaskDetails, {
|
|
438
|
-
get api() {
|
|
439
|
-
return props.api;
|
|
440
|
-
},
|
|
441
|
-
callID: callID,
|
|
442
|
-
get currentSessionID() {
|
|
443
|
-
return props.sessionID;
|
|
444
|
-
},
|
|
445
|
-
fallbackPart: part,
|
|
446
|
-
tasksByCallID: tasksByCallID,
|
|
447
|
-
fallbackFor: id => fallbacks.get(id),
|
|
448
|
-
revision: revision,
|
|
449
|
-
now: now,
|
|
450
|
-
startedAt: startedAt,
|
|
451
|
-
close: () => closePopup(ownership)
|
|
452
|
-
}), () => releasePopup(ownership));
|
|
453
601
|
};
|
|
602
|
+
const updatePopupAnchor = (callID, anchor) => {
|
|
603
|
+
const ownership = openPopup();
|
|
604
|
+
if (!ownership || ownership.callID !== callID) return;
|
|
605
|
+
if (ownership.anchor.x === anchor.x && ownership.anchor.y === anchor.y && ownership.anchor.width === anchor.width && ownership.anchor.height === anchor.height) {
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
setOpenPopup({
|
|
609
|
+
...ownership,
|
|
610
|
+
anchor
|
|
611
|
+
});
|
|
612
|
+
};
|
|
613
|
+
const dismissForHostDialog = () => {
|
|
614
|
+
if (openPopup() && props.api.ui.dialog.open) setOpenPopup(undefined);
|
|
615
|
+
};
|
|
616
|
+
const dismissForHostDialogFrame = async () => {
|
|
617
|
+
dismissForHostDialog();
|
|
618
|
+
};
|
|
619
|
+
createEffect(dismissForHostDialog);
|
|
454
620
|
const unregister = [];
|
|
455
621
|
let timer;
|
|
456
622
|
onMount(() => {
|
|
@@ -465,40 +631,42 @@ function RunningSubagents(props) {
|
|
|
465
631
|
setRevision(value => value + 1);
|
|
466
632
|
}
|
|
467
633
|
};
|
|
468
|
-
unregister.push(
|
|
634
|
+
unregister.push(() => {
|
|
635
|
+
props.api.renderer.removeFrameCallback(dismissForHostDialogFrame);
|
|
636
|
+
}, props.api.event.on("session.created", event => syncCurrentSession(event.properties.info)), props.api.event.on("session.updated", event => syncCurrentSession(event.properties.info)), props.api.event.on("message.updated", event => refreshSession(event.properties.sessionID)), props.api.event.on("message.part.updated", event => refreshSession(event.properties.sessionID)), props.api.event.on("message.part.removed", event => refreshSession(event.properties.sessionID)));
|
|
637
|
+
props.api.renderer.setFrameCallback(dismissForHostDialogFrame);
|
|
469
638
|
timer = setInterval(() => setNow(Date.now()), 1_000);
|
|
470
639
|
});
|
|
471
640
|
onCleanup(() => {
|
|
472
641
|
sessionRequest += 1;
|
|
473
642
|
if (timer) clearInterval(timer);
|
|
474
643
|
for (const dispose of unregister) dispose();
|
|
475
|
-
|
|
476
|
-
if (ownership) closePopup(ownership);
|
|
644
|
+
setOpenPopup(undefined);
|
|
477
645
|
});
|
|
478
646
|
return (() => {
|
|
479
|
-
var _el$
|
|
480
|
-
_el$
|
|
481
|
-
_el$
|
|
482
|
-
_el$
|
|
483
|
-
_$insertNode(_el$
|
|
484
|
-
_$setProp(_el$
|
|
485
|
-
_$insertNode(_el$
|
|
486
|
-
_$insertNode(_el$
|
|
487
|
-
_$insertNode(_el$
|
|
488
|
-
_$insert(_el$
|
|
647
|
+
var _el$41 = _$createElement("box"),
|
|
648
|
+
_el$42 = _$createElement("text"),
|
|
649
|
+
_el$43 = _$createElement("b"),
|
|
650
|
+
_el$45 = _$createElement("span");
|
|
651
|
+
_$insertNode(_el$41, _el$42);
|
|
652
|
+
_$setProp(_el$41, "overflow", "hidden");
|
|
653
|
+
_$insertNode(_el$42, _el$43);
|
|
654
|
+
_$insertNode(_el$42, _el$45);
|
|
655
|
+
_$insertNode(_el$43, _$createTextNode(`Subagents`));
|
|
656
|
+
_$insert(_el$45, (() => {
|
|
489
657
|
var _c$3 = _$memo(() => !!visibleTaskParts().length);
|
|
490
658
|
return () => _c$3() ? ` (${visibleTaskParts().length} running)` : "";
|
|
491
659
|
})());
|
|
492
|
-
_$insert(_el$
|
|
660
|
+
_$insert(_el$41, _$createComponent(Show, {
|
|
493
661
|
get when() {
|
|
494
662
|
return taskCallIDs().length > 0;
|
|
495
663
|
},
|
|
496
664
|
get fallback() {
|
|
497
665
|
return (() => {
|
|
498
|
-
var _el$
|
|
499
|
-
_$insertNode(_el$
|
|
500
|
-
_$effect(_$p => _$setProp(_el$
|
|
501
|
-
return _el$
|
|
666
|
+
var _el$46 = _$createElement("text");
|
|
667
|
+
_$insertNode(_el$46, _$createTextNode(`No subagent running`));
|
|
668
|
+
_$effect(_$p => _$setProp(_el$46, "fg", props.api.theme.current.textMuted, _$p));
|
|
669
|
+
return _el$46;
|
|
502
670
|
})();
|
|
503
671
|
},
|
|
504
672
|
get children() {
|
|
@@ -517,24 +685,48 @@ function RunningSubagents(props) {
|
|
|
517
685
|
revision: revision,
|
|
518
686
|
now: now,
|
|
519
687
|
startedAt: startedAt,
|
|
520
|
-
openPopup: showPopup
|
|
688
|
+
openPopup: showPopup,
|
|
689
|
+
updatePopupAnchor: updatePopupAnchor
|
|
521
690
|
})
|
|
522
691
|
});
|
|
523
692
|
}
|
|
524
693
|
}), null);
|
|
694
|
+
_$insert(_el$41, _$createComponent(Show, {
|
|
695
|
+
get when() {
|
|
696
|
+
return openPopup();
|
|
697
|
+
},
|
|
698
|
+
children: ownership => _$createComponent(TaskPopover, {
|
|
699
|
+
get api() {
|
|
700
|
+
return props.api;
|
|
701
|
+
},
|
|
702
|
+
ownership: ownership,
|
|
703
|
+
get currentSessionID() {
|
|
704
|
+
return props.sessionID;
|
|
705
|
+
},
|
|
706
|
+
get fallbackPart() {
|
|
707
|
+
return fallbacks.get(ownership().callID).part;
|
|
708
|
+
},
|
|
709
|
+
tasksByCallID: tasksByCallID,
|
|
710
|
+
fallbackFor: id => fallbacks.get(id),
|
|
711
|
+
revision: revision,
|
|
712
|
+
now: now,
|
|
713
|
+
startedAt: startedAt,
|
|
714
|
+
close: () => closePopup(ownership())
|
|
715
|
+
})
|
|
716
|
+
}), null);
|
|
525
717
|
_$effect(_p$ => {
|
|
526
|
-
var _v$
|
|
527
|
-
_v$
|
|
718
|
+
var _v$16 = props.api.theme.current.text,
|
|
719
|
+
_v$17 = {
|
|
528
720
|
fg: props.api.theme.current.textMuted
|
|
529
721
|
};
|
|
530
|
-
_v$
|
|
531
|
-
_v$
|
|
722
|
+
_v$16 !== _p$.e && (_p$.e = _$setProp(_el$42, "fg", _v$16, _p$.e));
|
|
723
|
+
_v$17 !== _p$.t && (_p$.t = _$setProp(_el$45, "style", _v$17, _p$.t));
|
|
532
724
|
return _p$;
|
|
533
725
|
}, {
|
|
534
726
|
e: undefined,
|
|
535
727
|
t: undefined
|
|
536
728
|
});
|
|
537
|
-
return _el$
|
|
729
|
+
return _el$41;
|
|
538
730
|
})();
|
|
539
731
|
}
|
|
540
732
|
const tui = async api => {
|