@mirrowel/opencode-subagent-explorer 0.1.0 → 0.2.0-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sessions.d.ts +42 -10
- package/dist/sessions.js +147 -20
- package/dist/tui.js +328 -144
- package/dist/wizard.d.ts +13 -2
- package/dist/wizard.js +334 -149
- package/package.json +1 -1
- package/src/palette-category.ts +83 -83
- package/src/sessions.ts +164 -18
- package/src/wizard.tsx +110 -16
package/dist/tui.js
CHANGED
|
@@ -66,6 +66,7 @@ import { useTerminalDimensions } from "@opentui/solid";
|
|
|
66
66
|
import { createEffect, createMemo, createSignal, For, onCleanup, Show } from "solid-js";
|
|
67
67
|
|
|
68
68
|
// src/sessions.ts
|
|
69
|
+
import { existsSync, readFileSync } from "fs";
|
|
69
70
|
var CALL_TIMEOUT_MS = 5000;
|
|
70
71
|
var BUILTIN_AGENTS = new Set(["build", "plan"]);
|
|
71
72
|
function withTimeout(fn, ms = CALL_TIMEOUT_MS) {
|
|
@@ -107,16 +108,17 @@ function normalizeSession(raw) {
|
|
|
107
108
|
updated: toMillis(time.updated ?? record.time_updated)
|
|
108
109
|
};
|
|
109
110
|
}
|
|
111
|
+
var SESSION_LIST_LIMIT = 5000;
|
|
110
112
|
async function fetchSessions(client, directory) {
|
|
111
113
|
const namespace = client?.session;
|
|
112
114
|
if (!namespace?.list)
|
|
113
115
|
return;
|
|
114
116
|
const calls = [
|
|
115
|
-
() => namespace.list({ directory }),
|
|
116
|
-
() => namespace.list({ query: { directory } })
|
|
117
|
+
() => namespace.list({ directory, limit: SESSION_LIST_LIMIT }),
|
|
118
|
+
() => namespace.list({ query: { directory, limit: SESSION_LIST_LIMIT } })
|
|
117
119
|
];
|
|
118
120
|
for (const call of calls) {
|
|
119
|
-
const result = unwrap(await withTimeout(call));
|
|
121
|
+
const result = unwrap(await withTimeout(call, 8000));
|
|
120
122
|
if (Array.isArray(result))
|
|
121
123
|
return result.map(normalizeSession).filter((s) => !!s);
|
|
122
124
|
}
|
|
@@ -127,23 +129,20 @@ async function fetchActiveSessionIDs(client) {
|
|
|
127
129
|
if (!namespace)
|
|
128
130
|
return;
|
|
129
131
|
if (typeof namespace.active === "function") {
|
|
130
|
-
const
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
if (value)
|
|
135
|
-
ids.add(id);
|
|
136
|
-
}
|
|
137
|
-
return ids;
|
|
132
|
+
const result = await withTimeout(() => namespace.active());
|
|
133
|
+
const data = result && typeof result === "object" ? result.data : undefined;
|
|
134
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
135
|
+
return new Set(Object.keys(data));
|
|
138
136
|
}
|
|
139
137
|
}
|
|
140
138
|
if (typeof namespace.status === "function") {
|
|
141
|
-
const
|
|
142
|
-
|
|
139
|
+
const result = await withTimeout(() => namespace.status());
|
|
140
|
+
const data = result && typeof result === "object" ? result.data : undefined;
|
|
141
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
143
142
|
const ids = new Set;
|
|
144
|
-
for (const [id, value] of Object.entries(
|
|
145
|
-
const
|
|
146
|
-
if (
|
|
143
|
+
for (const [id, value] of Object.entries(data)) {
|
|
144
|
+
const type = value && typeof value === "object" ? value.type ?? value.status : value;
|
|
145
|
+
if (type === undefined || type === "busy" || type === "retry")
|
|
147
146
|
ids.add(id);
|
|
148
147
|
}
|
|
149
148
|
return ids;
|
|
@@ -151,6 +150,88 @@ async function fetchActiveSessionIDs(client) {
|
|
|
151
150
|
}
|
|
152
151
|
return;
|
|
153
152
|
}
|
|
153
|
+
function loadAvSidecar(globalConfigDir) {
|
|
154
|
+
const parents = new Map;
|
|
155
|
+
if (!globalConfigDir)
|
|
156
|
+
return { parents };
|
|
157
|
+
try {
|
|
158
|
+
const path = `${globalConfigDir.replace(/[\\/]+$/, "")}/agent-variants.jsonc`;
|
|
159
|
+
if (!existsSync(path))
|
|
160
|
+
return { parents };
|
|
161
|
+
const raw = readFileSync(path, "utf8");
|
|
162
|
+
const json = JSON.parse(stripJsoncComments(raw));
|
|
163
|
+
for (const [parent, entry] of Object.entries(json.agents ?? {})) {
|
|
164
|
+
if (!entry || typeof entry !== "object")
|
|
165
|
+
continue;
|
|
166
|
+
parents.set(parent, { disableBase: entry.disable_base === true && entry.disable !== true });
|
|
167
|
+
}
|
|
168
|
+
} catch {}
|
|
169
|
+
return { parents };
|
|
170
|
+
}
|
|
171
|
+
function stripJsoncComments(text) {
|
|
172
|
+
return text.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:"'\\])\/\/.*$/gm, "$1").replace(/,(\s*[}\]])/g, "$1");
|
|
173
|
+
}
|
|
174
|
+
var ATTRIBUTION_PAGE_SIZE = 100;
|
|
175
|
+
var ATTRIBUTION_PAGES = 5;
|
|
176
|
+
async function fetchVariantAttribution(client, parentSessionID, directory, avParents) {
|
|
177
|
+
const map = new Map;
|
|
178
|
+
if (avParents.size === 0 || !parentSessionID)
|
|
179
|
+
return map;
|
|
180
|
+
const namespace = client?.session;
|
|
181
|
+
if (!namespace || typeof namespace.messages !== "function")
|
|
182
|
+
return map;
|
|
183
|
+
const fetchPage = (before) => {
|
|
184
|
+
const query = { directory, limit: ATTRIBUTION_PAGE_SIZE };
|
|
185
|
+
if (before)
|
|
186
|
+
query.before = before;
|
|
187
|
+
const flat = namespace.messages({ sessionID: parentSessionID, ...query });
|
|
188
|
+
return flat instanceof Promise ? flat : namespace.messages({ path: { id: parentSessionID }, query });
|
|
189
|
+
};
|
|
190
|
+
const asList = (value) => {
|
|
191
|
+
if (Array.isArray(value))
|
|
192
|
+
return value;
|
|
193
|
+
if (value && typeof value === "object") {
|
|
194
|
+
const unwrapped = value.data;
|
|
195
|
+
if (Array.isArray(unwrapped))
|
|
196
|
+
return unwrapped;
|
|
197
|
+
}
|
|
198
|
+
return;
|
|
199
|
+
};
|
|
200
|
+
let before;
|
|
201
|
+
const seenCursors = new Set;
|
|
202
|
+
for (let page = 0;page < ATTRIBUTION_PAGES; page++) {
|
|
203
|
+
const messages = await withTimeout(() => fetchPage(before), 8000);
|
|
204
|
+
const list = asList(messages);
|
|
205
|
+
if (!list || list.length === 0)
|
|
206
|
+
break;
|
|
207
|
+
for (const message of list) {
|
|
208
|
+
for (const part of message.parts ?? []) {
|
|
209
|
+
if (part?.type !== "tool" || part.tool !== "task")
|
|
210
|
+
continue;
|
|
211
|
+
const metadata = part.state?.metadata;
|
|
212
|
+
const child = metadata?.sessionId;
|
|
213
|
+
const variantMeta = metadata?.agentVariants;
|
|
214
|
+
const alias = variantMeta?.alias;
|
|
215
|
+
const routedAgent = variantMeta?.routedAgent;
|
|
216
|
+
if (typeof child === "string" && typeof alias === "string" && !map.has(child)) {
|
|
217
|
+
map.set(child, {
|
|
218
|
+
alias,
|
|
219
|
+
parent: typeof routedAgent === "string" ? routedAgent : alias.replace(/-[a-z0-9-]+$/, "")
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (list.length < ATTRIBUTION_PAGE_SIZE)
|
|
225
|
+
break;
|
|
226
|
+
const last = list[list.length - 1];
|
|
227
|
+
const next = last?.info?.id ?? last?.id;
|
|
228
|
+
if (!next || seenCursors.has(next))
|
|
229
|
+
break;
|
|
230
|
+
seenCursors.add(next);
|
|
231
|
+
before = next;
|
|
232
|
+
}
|
|
233
|
+
return map;
|
|
234
|
+
}
|
|
154
235
|
function buildSessionTree(sessions, rootID) {
|
|
155
236
|
const byParent = new Map;
|
|
156
237
|
for (const session of sessions) {
|
|
@@ -223,10 +304,18 @@ function isHiddenAgent(agent, hidden, configAgents) {
|
|
|
223
304
|
return true;
|
|
224
305
|
return !configAgents.has(agent) && !BUILTIN_AGENTS.has(agent) && !agent.startsWith("av:");
|
|
225
306
|
}
|
|
307
|
+
function rowHidden(variant, agent, avParents, hidden, configAgents) {
|
|
308
|
+
if (variant)
|
|
309
|
+
return false;
|
|
310
|
+
if (agent && avParents.has(agent))
|
|
311
|
+
return false;
|
|
312
|
+
return isHiddenAgent(agent, hidden, configAgents);
|
|
313
|
+
}
|
|
226
314
|
async function deleteSession(client, sessionID) {
|
|
227
315
|
const namespace = client?.session;
|
|
228
316
|
if (!namespace)
|
|
229
317
|
return false;
|
|
318
|
+
const isErrorEnvelope = (value) => !!value && typeof value === "object" && ("error" in value) && !("data" in value);
|
|
230
319
|
const shapes = [];
|
|
231
320
|
if (typeof namespace.delete === "function") {
|
|
232
321
|
shapes.push(() => namespace.delete({ sessionID }), () => namespace.delete({ path: { sessionID } }), () => namespace.delete({ path: { id: sessionID } }), () => namespace.delete({ id: sessionID }));
|
|
@@ -236,8 +325,11 @@ async function deleteSession(client, sessionID) {
|
|
|
236
325
|
}
|
|
237
326
|
for (const call of shapes) {
|
|
238
327
|
const result = await withTimeout(call);
|
|
239
|
-
if (result
|
|
240
|
-
|
|
328
|
+
if (result === undefined)
|
|
329
|
+
continue;
|
|
330
|
+
if (isErrorEnvelope(result))
|
|
331
|
+
continue;
|
|
332
|
+
return true;
|
|
241
333
|
}
|
|
242
334
|
return false;
|
|
243
335
|
}
|
|
@@ -313,28 +405,42 @@ function parentCandidates(sessions) {
|
|
|
313
405
|
}
|
|
314
406
|
|
|
315
407
|
// src/wizard.tsx
|
|
316
|
-
|
|
408
|
+
function globalConfigDirOf(api) {
|
|
409
|
+
const config = api.state.path?.config;
|
|
410
|
+
if (!config)
|
|
411
|
+
return;
|
|
412
|
+
const index = Math.max(config.lastIndexOf("/"), config.lastIndexOf("\\"));
|
|
413
|
+
return index > 0 ? config.slice(0, index) : undefined;
|
|
414
|
+
}
|
|
415
|
+
async function loadExplorerData(api, directory, rootOverride) {
|
|
317
416
|
const sessions = await fetchSessions(api.client, directory);
|
|
318
417
|
if (!sessions)
|
|
319
418
|
return;
|
|
320
|
-
const activeIDs = await fetchActiveSessionIDs(api.client);
|
|
419
|
+
const [activeIDs, avSidecar] = await Promise.all([fetchActiveSessionIDs(api.client), Promise.resolve(loadAvSidecar(globalConfigDirOf(api)))]);
|
|
420
|
+
const rootID = rootOverride ?? currentSessionID(api.currentSessionID?.(), sessions);
|
|
421
|
+
const variantOf = await fetchVariantAttribution(api.client, rootID, directory, new Set(avSidecar.parents.keys()));
|
|
321
422
|
return {
|
|
322
423
|
sessions,
|
|
323
424
|
activeIDs,
|
|
324
425
|
activeKnown: activeIDs !== undefined,
|
|
325
426
|
hidden: hiddenAgentIDs(api.state.config),
|
|
326
|
-
configAgents: configAgentIDs(api.state.config)
|
|
427
|
+
configAgents: configAgentIDs(api.state.config),
|
|
428
|
+
variantOf,
|
|
429
|
+
avParents: avSidecar.parents
|
|
327
430
|
};
|
|
328
431
|
}
|
|
329
432
|
function explorerRows(tree, data) {
|
|
330
433
|
const rows = [];
|
|
331
434
|
const walk = (nodes, depth) => {
|
|
332
435
|
for (const node of nodes) {
|
|
436
|
+
const variant = data.variantOf.get(node.session.id);
|
|
437
|
+
const agent = node.session.agent;
|
|
333
438
|
rows.push({
|
|
334
439
|
session: node.session,
|
|
335
440
|
depth,
|
|
336
441
|
running: data.activeIDs?.has(node.session.id) ?? false,
|
|
337
|
-
hidden:
|
|
442
|
+
hidden: rowHidden(variant, agent, data.avParents, data.hidden, data.configAgents),
|
|
443
|
+
variant
|
|
338
444
|
});
|
|
339
445
|
walk(node.children, depth + 1);
|
|
340
446
|
}
|
|
@@ -342,6 +448,9 @@ function explorerRows(tree, data) {
|
|
|
342
448
|
walk(tree, 0);
|
|
343
449
|
return rows;
|
|
344
450
|
}
|
|
451
|
+
function agentLabelOf(row) {
|
|
452
|
+
return row.variant?.alias ?? row.session.agent ?? "unknown";
|
|
453
|
+
}
|
|
345
454
|
function themeOf(api) {
|
|
346
455
|
return api.theme.current;
|
|
347
456
|
}
|
|
@@ -714,7 +823,7 @@ function SubagentTreeDialog(props) {
|
|
|
714
823
|
_$setProp(_el$30, "flexShrink", 0);
|
|
715
824
|
_$setProp(_el$30, "wrapMode", "none");
|
|
716
825
|
_$setProp(_el$30, "overflow", "hidden");
|
|
717
|
-
_$insert(_el$31, () => truncate(row
|
|
826
|
+
_$insert(_el$31, () => truncate(agentLabelOf(row), agentWidth));
|
|
718
827
|
_$insert(_el$28, _$createComponent(Show, {
|
|
719
828
|
get when() {
|
|
720
829
|
return row.hidden;
|
|
@@ -1039,7 +1148,7 @@ function showConfirm(api, props) {
|
|
|
1039
1148
|
async function deleteOne(api, row) {
|
|
1040
1149
|
const label = `${rowTitle(row)}${row.hidden ? " [hidden agent]" : ""}`;
|
|
1041
1150
|
const summary = `${label}
|
|
1042
|
-
agent: ${row.session.agent ?? "unknown"}
|
|
1151
|
+
${row.variant ? `variant: ${row.variant.alias} (of ${row.variant.parent})` : `agent: ${row.session.agent ?? "unknown"}`}
|
|
1043
1152
|
last activity: ${formatAge(row.session.updated ?? row.session.created)}
|
|
1044
1153
|
|
|
1045
1154
|
Deleting a session permanently removes it, its messages, and its history. The parent session keeps the task result text; only the jump target is lost.`;
|
|
@@ -1063,7 +1172,50 @@ Deleting a session permanently removes it, its messages, and its history. The pa
|
|
|
1063
1172
|
});
|
|
1064
1173
|
return ok;
|
|
1065
1174
|
}
|
|
1066
|
-
|
|
1175
|
+
function CleanupProgressDialog(props) {
|
|
1176
|
+
const theme = () => themeOf(props.api);
|
|
1177
|
+
const popMode = props.api.mode.push("subagent-explorer.cleanup");
|
|
1178
|
+
onCleanup(() => popMode());
|
|
1179
|
+
const done = props.done;
|
|
1180
|
+
const total = props.total;
|
|
1181
|
+
return (() => {
|
|
1182
|
+
var _el$56 = _$createElement("box"), _el$57 = _$createElement("text"), _el$58 = _$createElement("b"), _el$60 = _$createElement("text"), _el$61 = _$createElement("text");
|
|
1183
|
+
_$insertNode(_el$56, _el$57);
|
|
1184
|
+
_$insertNode(_el$56, _el$60);
|
|
1185
|
+
_$insertNode(_el$56, _el$61);
|
|
1186
|
+
_$setProp(_el$56, "flexDirection", "column");
|
|
1187
|
+
_$setProp(_el$56, "width", "100%");
|
|
1188
|
+
_$setProp(_el$56, "paddingLeft", 2);
|
|
1189
|
+
_$setProp(_el$56, "paddingRight", 2);
|
|
1190
|
+
_$setProp(_el$56, "paddingTop", 2);
|
|
1191
|
+
_$setProp(_el$56, "paddingBottom", 2);
|
|
1192
|
+
_$setProp(_el$56, "gap", 1);
|
|
1193
|
+
_$insertNode(_el$57, _el$58);
|
|
1194
|
+
_$insertNode(_el$58, _$createTextNode(`Cleaning up idle subagent sessions\u2026`));
|
|
1195
|
+
_$insert(_el$60, () => `${done()} / ${total} deleted`);
|
|
1196
|
+
_$insertNode(_el$61, _$createTextNode(`This dialog closes when the batch finishes.`));
|
|
1197
|
+
_$effect((_p$) => {
|
|
1198
|
+
var _v$24 = theme().text, _v$25 = theme().textMuted, _v$26 = theme().textMuted;
|
|
1199
|
+
_v$24 !== _p$.e && (_p$.e = _$setProp(_el$57, "fg", _v$24, _p$.e));
|
|
1200
|
+
_v$25 !== _p$.t && (_p$.t = _$setProp(_el$60, "fg", _v$25, _p$.t));
|
|
1201
|
+
_v$26 !== _p$.a && (_p$.a = _$setProp(_el$61, "fg", _v$26, _p$.a));
|
|
1202
|
+
return _p$;
|
|
1203
|
+
}, {
|
|
1204
|
+
e: undefined,
|
|
1205
|
+
t: undefined,
|
|
1206
|
+
a: undefined
|
|
1207
|
+
});
|
|
1208
|
+
return _el$56;
|
|
1209
|
+
})();
|
|
1210
|
+
}
|
|
1211
|
+
function showCleanupProgress(api, done, total) {
|
|
1212
|
+
api.ui.dialog.replace(() => _$createComponent(CleanupProgressDialog, {
|
|
1213
|
+
api,
|
|
1214
|
+
done,
|
|
1215
|
+
total
|
|
1216
|
+
}), () => {});
|
|
1217
|
+
}
|
|
1218
|
+
async function runCleanup(api, plan, rootTitle, directory, rootID) {
|
|
1067
1219
|
if (plan.deletable.length === 0) {
|
|
1068
1220
|
await showInfo(api, {
|
|
1069
1221
|
title: "Nothing to clean up",
|
|
@@ -1082,18 +1234,40 @@ ${plan.sparedActive.length} running session(s) will be spared.` : "";
|
|
|
1082
1234
|
if (!confirmed)
|
|
1083
1235
|
return 0;
|
|
1084
1236
|
let deleted = 0;
|
|
1237
|
+
const [progressDone, setProgressDone] = createSignal(0);
|
|
1238
|
+
showCleanupProgress(api, progressDone, plan.deletable.length);
|
|
1085
1239
|
for (const session of plan.deletable) {
|
|
1086
|
-
if (await deleteSession(api.client, session.id))
|
|
1240
|
+
if (await deleteSession(api.client, session.id)) {
|
|
1087
1241
|
deleted += 1;
|
|
1242
|
+
setProgressDone(deleted);
|
|
1243
|
+
}
|
|
1088
1244
|
}
|
|
1245
|
+
const remainingIdle = await remainingIdleCount(api, directory, rootID);
|
|
1246
|
+
api.ui.dialog.clear();
|
|
1089
1247
|
const failed = plan.deletable.length - deleted;
|
|
1090
1248
|
api.ui.toast({
|
|
1091
|
-
variant: failed > 0 ? "warning" : "default",
|
|
1249
|
+
variant: failed > 0 || remainingIdle > 0 ? "warning" : "default",
|
|
1092
1250
|
title: "Cleanup finished",
|
|
1093
|
-
message: failed > 0 ? `Deleted ${deleted}, failed ${failed}.` : `Deleted ${deleted} session(s).`
|
|
1251
|
+
message: remainingIdle > 0 ? `Deleted ${deleted}. ${remainingIdle} idle session(s) still remain${failed > 0 ? ` (${failed} delete call(s) failed - re-run cleanup or delete rows individually)` : " - re-run cleanup for the newly-idle"}.` : failed > 0 ? `Deleted ${deleted}, failed ${failed}.` : `Deleted ${deleted} session(s).`
|
|
1094
1252
|
});
|
|
1095
1253
|
return deleted;
|
|
1096
1254
|
}
|
|
1255
|
+
async function remainingIdleCount(api, directory, rootID) {
|
|
1256
|
+
const sessions = await fetchSessions(api.client, directory);
|
|
1257
|
+
if (!sessions)
|
|
1258
|
+
return 0;
|
|
1259
|
+
const active = await fetchActiveSessionIDs(api.client);
|
|
1260
|
+
const rows = explorerRows(buildSessionTree(sessions, rootID), {
|
|
1261
|
+
sessions,
|
|
1262
|
+
activeIDs: active,
|
|
1263
|
+
activeKnown: active !== undefined,
|
|
1264
|
+
hidden: new Set,
|
|
1265
|
+
configAgents: new Set,
|
|
1266
|
+
variantOf: new Map,
|
|
1267
|
+
avParents: new Map
|
|
1268
|
+
});
|
|
1269
|
+
return rows.filter((row) => !row.running).length;
|
|
1270
|
+
}
|
|
1097
1271
|
function showRootPicker(api, sessions, currentRoot) {
|
|
1098
1272
|
return new Promise((resolve) => {
|
|
1099
1273
|
let settled = false;
|
|
@@ -1118,9 +1292,19 @@ function showRootPicker(api, sessions, currentRoot) {
|
|
|
1118
1292
|
}), () => done(undefined));
|
|
1119
1293
|
});
|
|
1120
1294
|
}
|
|
1121
|
-
async function showDetails(api, row) {
|
|
1295
|
+
async function showDetails(api, row, data) {
|
|
1122
1296
|
const details = await fetchSessionDetails(api.client, row.session.id);
|
|
1123
|
-
const
|
|
1297
|
+
const parentAgent = row.session.agent ?? "unknown";
|
|
1298
|
+
const lines = [`title: ${rowTitle(row)}`, row.variant ? `variant: ${row.variant.alias} (of ${row.variant.parent})` : `agent: ${parentAgent}${row.hidden ? " (hidden/background)" : ""}`];
|
|
1299
|
+
if (row.variant) {
|
|
1300
|
+
const parentEntry = data.avParents.get(row.variant.parent);
|
|
1301
|
+
if (parentEntry) {
|
|
1302
|
+
lines.push(`base ${row.variant.parent}: ${parentEntry.disableBase ? "disabled (variants only)" : "enabled"}`);
|
|
1303
|
+
}
|
|
1304
|
+
} else if (data.avParents.has(parentAgent)) {
|
|
1305
|
+
lines.push(`base ${parentAgent}: ${data.avParents.get(parentAgent)?.disableBase ? "disabled (variants only)" : "enabled"}`);
|
|
1306
|
+
}
|
|
1307
|
+
lines.push(`session: ${row.session.id}`, `status: ${row.running ? "running" : "idle"}`, `created: ${formatAge(row.session.created)}`, `last activity: ${formatAge(row.session.updated ?? row.session.created)}`);
|
|
1124
1308
|
if (details) {
|
|
1125
1309
|
lines.push(`messages: ${details.messageCount}`);
|
|
1126
1310
|
if (details.model)
|
|
@@ -1400,140 +1584,140 @@ function SizeSliderDialog(props) {
|
|
|
1400
1584
|
popMode();
|
|
1401
1585
|
});
|
|
1402
1586
|
return (() => {
|
|
1403
|
-
var _el$
|
|
1404
|
-
_$insertNode(_el$56, _el$57);
|
|
1405
|
-
_$insertNode(_el$56, _el$63);
|
|
1406
|
-
_$insertNode(_el$56, _el$74);
|
|
1407
|
-
_$insertNode(_el$56, _el$82);
|
|
1408
|
-
_$insertNode(_el$56, _el$93);
|
|
1409
|
-
_$setProp(_el$56, "flexDirection", "column");
|
|
1410
|
-
_$setProp(_el$56, "width", "100%");
|
|
1411
|
-
_$setProp(_el$56, "paddingLeft", 2);
|
|
1412
|
-
_$setProp(_el$56, "paddingRight", 2);
|
|
1413
|
-
_$setProp(_el$56, "paddingTop", 1);
|
|
1414
|
-
_$setProp(_el$56, "paddingBottom", 1);
|
|
1415
|
-
_$insertNode(_el$57, _el$58);
|
|
1416
|
-
_$insertNode(_el$57, _el$61);
|
|
1417
|
-
_$setProp(_el$57, "flexDirection", "row");
|
|
1418
|
-
_$setProp(_el$57, "justifyContent", "space-between");
|
|
1419
|
-
_$setProp(_el$57, "width", "100%");
|
|
1420
|
-
_$setProp(_el$57, "marginBottom", 1);
|
|
1421
|
-
_$insertNode(_el$58, _el$59);
|
|
1422
|
-
_$insertNode(_el$59, _$createTextNode(`Dialog size`));
|
|
1423
|
-
_$insertNode(_el$61, _$createTextNode(`esc`));
|
|
1424
|
-
_$setProp(_el$61, "onMouseUp", () => props.onDone(undefined));
|
|
1587
|
+
var _el$63 = _$createElement("box"), _el$64 = _$createElement("box"), _el$65 = _$createElement("text"), _el$66 = _$createElement("b"), _el$68 = _$createElement("text"), _el$70 = _$createElement("box"), _el$71 = _$createElement("text"), _el$73 = _$createElement("text"), _el$74 = _$createElement("b"), _el$75 = _$createElement("text"), _el$76 = _$createTextNode(` (`), _el$77 = _$createTextNode(` cols, w to cycle) Height: `), _el$78 = _$createElement("text"), _el$79 = _$createElement("b"), _el$80 = _$createTextNode(`%`), _el$81 = _$createElement("box"), _el$82 = _$createElement("text"), _el$83 = _$createTextNode(`25% `), _el$85 = _$createElement("text"), _el$86 = _$createTextNode(` 100%`), _el$89 = _$createElement("box"), _el$90 = _$createElement("box"), _el$91 = _$createElement("text"), _el$93 = _$createElement("text"), _el$95 = _$createElement("text"), _el$97 = _$createElement("text"), _el$99 = _$createElement("box"), _el$100 = _$createElement("box"), _el$101 = _$createElement("text"), _el$103 = _$createElement("box"), _el$104 = _$createElement("text"), _el$105 = _$createElement("b");
|
|
1425
1588
|
_$insertNode(_el$63, _el$64);
|
|
1426
|
-
_$insertNode(_el$63, _el$
|
|
1427
|
-
_$insertNode(_el$63, _el$
|
|
1428
|
-
_$insertNode(_el$63, _el$
|
|
1429
|
-
_$
|
|
1430
|
-
_$setProp(_el$63, "
|
|
1589
|
+
_$insertNode(_el$63, _el$70);
|
|
1590
|
+
_$insertNode(_el$63, _el$81);
|
|
1591
|
+
_$insertNode(_el$63, _el$89);
|
|
1592
|
+
_$insertNode(_el$63, _el$100);
|
|
1593
|
+
_$setProp(_el$63, "flexDirection", "column");
|
|
1431
1594
|
_$setProp(_el$63, "width", "100%");
|
|
1432
|
-
_$setProp(_el$63, "
|
|
1433
|
-
_$
|
|
1434
|
-
_$
|
|
1435
|
-
_$
|
|
1436
|
-
_$insertNode(_el$
|
|
1437
|
-
_$insertNode(_el$
|
|
1438
|
-
_$
|
|
1439
|
-
_$
|
|
1440
|
-
_$
|
|
1441
|
-
_$
|
|
1442
|
-
_$insertNode(_el$
|
|
1443
|
-
_$insertNode(_el$
|
|
1444
|
-
_$
|
|
1445
|
-
_$setProp(_el$
|
|
1446
|
-
_$
|
|
1595
|
+
_$setProp(_el$63, "paddingLeft", 2);
|
|
1596
|
+
_$setProp(_el$63, "paddingRight", 2);
|
|
1597
|
+
_$setProp(_el$63, "paddingTop", 1);
|
|
1598
|
+
_$setProp(_el$63, "paddingBottom", 1);
|
|
1599
|
+
_$insertNode(_el$64, _el$65);
|
|
1600
|
+
_$insertNode(_el$64, _el$68);
|
|
1601
|
+
_$setProp(_el$64, "flexDirection", "row");
|
|
1602
|
+
_$setProp(_el$64, "justifyContent", "space-between");
|
|
1603
|
+
_$setProp(_el$64, "width", "100%");
|
|
1604
|
+
_$setProp(_el$64, "marginBottom", 1);
|
|
1605
|
+
_$insertNode(_el$65, _el$66);
|
|
1606
|
+
_$insertNode(_el$66, _$createTextNode(`Dialog size`));
|
|
1607
|
+
_$insertNode(_el$68, _$createTextNode(`esc`));
|
|
1608
|
+
_$setProp(_el$68, "onMouseUp", () => props.onDone(undefined));
|
|
1609
|
+
_$insertNode(_el$70, _el$71);
|
|
1610
|
+
_$insertNode(_el$70, _el$73);
|
|
1611
|
+
_$insertNode(_el$70, _el$75);
|
|
1612
|
+
_$insertNode(_el$70, _el$78);
|
|
1613
|
+
_$setProp(_el$70, "flexDirection", "row");
|
|
1614
|
+
_$setProp(_el$70, "gap", 0);
|
|
1615
|
+
_$setProp(_el$70, "width", "100%");
|
|
1616
|
+
_$setProp(_el$70, "marginBottom", 1);
|
|
1617
|
+
_$insertNode(_el$71, _$createTextNode(`Width: `));
|
|
1618
|
+
_$insertNode(_el$73, _el$74);
|
|
1619
|
+
_$insert(_el$74, () => dialogSizeOf(props.api));
|
|
1447
1620
|
_$insertNode(_el$75, _el$76);
|
|
1448
|
-
_$
|
|
1621
|
+
_$insertNode(_el$75, _el$77);
|
|
1622
|
+
_$insert(_el$75, () => DIALOG_WIDTH_COLUMNS[dialogSizeOf(props.api)], _el$77);
|
|
1623
|
+
_$insertNode(_el$78, _el$79);
|
|
1624
|
+
_$insertNode(_el$79, _el$80);
|
|
1625
|
+
_$insert(_el$79, height, _el$80);
|
|
1626
|
+
_$insertNode(_el$81, _el$82);
|
|
1627
|
+
_$insertNode(_el$81, _el$85);
|
|
1628
|
+
_$setProp(_el$81, "flexDirection", "row");
|
|
1629
|
+
_$setProp(_el$81, "width", "100%");
|
|
1630
|
+
_$setProp(_el$81, "marginBottom", 1);
|
|
1631
|
+
_$insertNode(_el$82, _el$83);
|
|
1632
|
+
_$insert(_el$81, _$createComponent(For, {
|
|
1449
1633
|
get each() {
|
|
1450
1634
|
return sliderCells();
|
|
1451
1635
|
},
|
|
1452
1636
|
children: (cell) => (() => {
|
|
1453
|
-
var _el$
|
|
1454
|
-
_$insert(_el$
|
|
1455
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1456
|
-
return _el$
|
|
1637
|
+
var _el$107 = _$createElement("text");
|
|
1638
|
+
_$insert(_el$107, () => cell.char);
|
|
1639
|
+
_$effect((_$p) => _$setProp(_el$107, "fg", cell.color, _$p));
|
|
1640
|
+
return _el$107;
|
|
1457
1641
|
})()
|
|
1458
|
-
}), _el$
|
|
1459
|
-
_$insertNode(_el$
|
|
1460
|
-
_$insertNode(_el$
|
|
1461
|
-
_$insertNode(_el$
|
|
1462
|
-
_$setProp(_el$
|
|
1463
|
-
_$setProp(_el$
|
|
1464
|
-
_$setProp(_el$
|
|
1465
|
-
_$insertNode(_el$
|
|
1466
|
-
_$insertNode(_el$
|
|
1467
|
-
_$insertNode(_el$
|
|
1468
|
-
_$insertNode(_el$
|
|
1469
|
-
_$setProp(_el$
|
|
1470
|
-
_$setProp(_el$
|
|
1471
|
-
_$insert(_el$
|
|
1642
|
+
}), _el$85);
|
|
1643
|
+
_$insertNode(_el$85, _el$86);
|
|
1644
|
+
_$insertNode(_el$89, _el$90);
|
|
1645
|
+
_$insertNode(_el$89, _el$99);
|
|
1646
|
+
_$setProp(_el$89, "flexDirection", "row");
|
|
1647
|
+
_$setProp(_el$89, "gap", 2);
|
|
1648
|
+
_$setProp(_el$89, "marginBottom", 1);
|
|
1649
|
+
_$insertNode(_el$90, _el$91);
|
|
1650
|
+
_$insertNode(_el$90, _el$93);
|
|
1651
|
+
_$insertNode(_el$90, _el$95);
|
|
1652
|
+
_$insertNode(_el$90, _el$97);
|
|
1653
|
+
_$setProp(_el$90, "flexDirection", "column");
|
|
1654
|
+
_$setProp(_el$90, "gap", 0);
|
|
1655
|
+
_$insert(_el$90, _$createComponent(For, {
|
|
1472
1656
|
each: HEIGHT_PRESETS,
|
|
1473
1657
|
children: (preset) => (() => {
|
|
1474
|
-
var _el$
|
|
1475
|
-
_$insertNode(_el$
|
|
1476
|
-
_$insertNode(_el$
|
|
1477
|
-
_$insertNode(_el$
|
|
1478
|
-
_$insert(_el$
|
|
1479
|
-
_$insert(_el$
|
|
1480
|
-
_$insert(_el$
|
|
1481
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1482
|
-
return _el$
|
|
1658
|
+
var _el$108 = _$createElement("text"), _el$109 = _$createTextNode(` `), _el$110 = _$createTextNode(`: `), _el$111 = _$createTextNode(`%`);
|
|
1659
|
+
_$insertNode(_el$108, _el$109);
|
|
1660
|
+
_$insertNode(_el$108, _el$110);
|
|
1661
|
+
_$insertNode(_el$108, _el$111);
|
|
1662
|
+
_$insert(_el$108, () => preset.key, _el$109);
|
|
1663
|
+
_$insert(_el$108, () => preset.label, _el$110);
|
|
1664
|
+
_$insert(_el$108, () => preset.value, _el$111);
|
|
1665
|
+
_$effect((_$p) => _$setProp(_el$108, "fg", height() === preset.value ? theme().primary : theme().textMuted, _$p));
|
|
1666
|
+
return _el$108;
|
|
1483
1667
|
})()
|
|
1484
|
-
}), _el$
|
|
1485
|
-
_$insertNode(_el$
|
|
1486
|
-
_$insertNode(_el$
|
|
1487
|
-
_$insertNode(_el$
|
|
1488
|
-
_$insertNode(_el$
|
|
1489
|
-
_$setProp(_el$
|
|
1490
|
-
_$setProp(_el$
|
|
1491
|
-
_$insert(_el$
|
|
1668
|
+
}), _el$91);
|
|
1669
|
+
_$insertNode(_el$91, _$createTextNode(` `));
|
|
1670
|
+
_$insertNode(_el$93, _$createTextNode(`left/right 1%`));
|
|
1671
|
+
_$insertNode(_el$95, _$createTextNode(`up/down 5%`));
|
|
1672
|
+
_$insertNode(_el$97, _$createTextNode(`c custom`));
|
|
1673
|
+
_$setProp(_el$99, "flexDirection", "column");
|
|
1674
|
+
_$setProp(_el$99, "gap", 0);
|
|
1675
|
+
_$insert(_el$99, _$createComponent(For, {
|
|
1492
1676
|
get each() {
|
|
1493
1677
|
return preview();
|
|
1494
1678
|
},
|
|
1495
1679
|
children: (line) => (() => {
|
|
1496
|
-
var _el$
|
|
1497
|
-
_$insert(_el$
|
|
1498
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1499
|
-
return _el$
|
|
1680
|
+
var _el$112 = _$createElement("text");
|
|
1681
|
+
_$insert(_el$112, line);
|
|
1682
|
+
_$effect((_$p) => _$setProp(_el$112, "fg", theme().textMuted, _$p));
|
|
1683
|
+
return _el$112;
|
|
1500
1684
|
})()
|
|
1501
1685
|
}));
|
|
1502
|
-
_$insertNode(_el$
|
|
1503
|
-
_$insertNode(_el$
|
|
1504
|
-
_$setProp(_el$
|
|
1505
|
-
_$setProp(_el$
|
|
1506
|
-
_$setProp(_el$
|
|
1507
|
-
_$insertNode(_el$
|
|
1508
|
-
_$insertNode(_el$
|
|
1509
|
-
_$setProp(_el$
|
|
1510
|
-
_$setProp(_el$
|
|
1511
|
-
_$setProp(_el$
|
|
1686
|
+
_$insertNode(_el$100, _el$101);
|
|
1687
|
+
_$insertNode(_el$100, _el$103);
|
|
1688
|
+
_$setProp(_el$100, "flexDirection", "row");
|
|
1689
|
+
_$setProp(_el$100, "justifyContent", "space-between");
|
|
1690
|
+
_$setProp(_el$100, "width", "100%");
|
|
1691
|
+
_$insertNode(_el$101, _$createTextNode(`enter save`));
|
|
1692
|
+
_$insertNode(_el$103, _el$104);
|
|
1693
|
+
_$setProp(_el$103, "paddingLeft", 3);
|
|
1694
|
+
_$setProp(_el$103, "paddingRight", 3);
|
|
1695
|
+
_$setProp(_el$103, "onMouseUp", () => {
|
|
1512
1696
|
setDialogHeightPercent(props.api, height());
|
|
1513
1697
|
props.onDone({
|
|
1514
1698
|
action: "save",
|
|
1515
1699
|
height: height()
|
|
1516
1700
|
});
|
|
1517
1701
|
});
|
|
1518
|
-
_$insertNode(_el$
|
|
1519
|
-
_$insertNode(_el$
|
|
1702
|
+
_$insertNode(_el$104, _el$105);
|
|
1703
|
+
_$insertNode(_el$105, _$createTextNode(`save`));
|
|
1520
1704
|
_$effect((_p$) => {
|
|
1521
|
-
var _v$
|
|
1522
|
-
_v$
|
|
1523
|
-
_v$
|
|
1524
|
-
_v$
|
|
1525
|
-
_v$
|
|
1526
|
-
_v$
|
|
1527
|
-
_v$
|
|
1528
|
-
_v$
|
|
1529
|
-
_v$
|
|
1530
|
-
_v$
|
|
1531
|
-
_v$
|
|
1532
|
-
_v$
|
|
1533
|
-
_v$
|
|
1534
|
-
_v$
|
|
1535
|
-
_v$
|
|
1536
|
-
_v$
|
|
1705
|
+
var _v$27 = theme().accent, _v$28 = theme().textMuted, _v$29 = theme().textMuted, _v$30 = theme().primary, _v$31 = theme().textMuted, _v$32 = theme().primary, _v$33 = theme().textMuted, _v$34 = theme().textMuted, _v$35 = theme().textMuted, _v$36 = theme().textMuted, _v$37 = theme().textMuted, _v$38 = theme().textMuted, _v$39 = theme().textMuted, _v$40 = theme().primary, _v$41 = theme().background;
|
|
1706
|
+
_v$27 !== _p$.e && (_p$.e = _$setProp(_el$65, "fg", _v$27, _p$.e));
|
|
1707
|
+
_v$28 !== _p$.t && (_p$.t = _$setProp(_el$68, "fg", _v$28, _p$.t));
|
|
1708
|
+
_v$29 !== _p$.a && (_p$.a = _$setProp(_el$71, "fg", _v$29, _p$.a));
|
|
1709
|
+
_v$30 !== _p$.o && (_p$.o = _$setProp(_el$73, "fg", _v$30, _p$.o));
|
|
1710
|
+
_v$31 !== _p$.i && (_p$.i = _$setProp(_el$75, "fg", _v$31, _p$.i));
|
|
1711
|
+
_v$32 !== _p$.n && (_p$.n = _$setProp(_el$78, "fg", _v$32, _p$.n));
|
|
1712
|
+
_v$33 !== _p$.s && (_p$.s = _$setProp(_el$82, "fg", _v$33, _p$.s));
|
|
1713
|
+
_v$34 !== _p$.h && (_p$.h = _$setProp(_el$85, "fg", _v$34, _p$.h));
|
|
1714
|
+
_v$35 !== _p$.r && (_p$.r = _$setProp(_el$91, "fg", _v$35, _p$.r));
|
|
1715
|
+
_v$36 !== _p$.d && (_p$.d = _$setProp(_el$93, "fg", _v$36, _p$.d));
|
|
1716
|
+
_v$37 !== _p$.l && (_p$.l = _$setProp(_el$95, "fg", _v$37, _p$.l));
|
|
1717
|
+
_v$38 !== _p$.u && (_p$.u = _$setProp(_el$97, "fg", _v$38, _p$.u));
|
|
1718
|
+
_v$39 !== _p$.c && (_p$.c = _$setProp(_el$101, "fg", _v$39, _p$.c));
|
|
1719
|
+
_v$40 !== _p$.w && (_p$.w = _$setProp(_el$103, "backgroundColor", _v$40, _p$.w));
|
|
1720
|
+
_v$41 !== _p$.m && (_p$.m = _$setProp(_el$104, "fg", _v$41, _p$.m));
|
|
1537
1721
|
return _p$;
|
|
1538
1722
|
}, {
|
|
1539
1723
|
e: undefined,
|
|
@@ -1552,7 +1736,7 @@ function SizeSliderDialog(props) {
|
|
|
1552
1736
|
w: undefined,
|
|
1553
1737
|
m: undefined
|
|
1554
1738
|
});
|
|
1555
|
-
return _el$
|
|
1739
|
+
return _el$63;
|
|
1556
1740
|
})();
|
|
1557
1741
|
}
|
|
1558
1742
|
async function mainMenu(api) {
|
|
@@ -1566,7 +1750,7 @@ async function mainMenu(api) {
|
|
|
1566
1750
|
}
|
|
1567
1751
|
let rootOverride;
|
|
1568
1752
|
while (true) {
|
|
1569
|
-
const data = await loadExplorerData(api, directory);
|
|
1753
|
+
const data = await loadExplorerData(api, directory, rootOverride);
|
|
1570
1754
|
if (!data) {
|
|
1571
1755
|
await showInfo(api, {
|
|
1572
1756
|
title: "Subagent Explorer",
|
|
@@ -1614,11 +1798,11 @@ The host client does not expose session.list for this directory.`
|
|
|
1614
1798
|
continue;
|
|
1615
1799
|
}
|
|
1616
1800
|
if (action.type === "details") {
|
|
1617
|
-
await showDetails(api, action.row);
|
|
1801
|
+
await showDetails(api, action.row, data);
|
|
1618
1802
|
continue;
|
|
1619
1803
|
}
|
|
1620
1804
|
if (action.type === "cleanup") {
|
|
1621
|
-
await runCleanup(api, cleanupTargets(tree, data.activeIDs), rootSession?.title ?? rootID);
|
|
1805
|
+
await runCleanup(api, cleanupTargets(tree, data.activeIDs), rootSession?.title ?? rootID, directory, rootID);
|
|
1622
1806
|
continue;
|
|
1623
1807
|
}
|
|
1624
1808
|
}
|