@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/wizard.js
CHANGED
|
@@ -13,6 +13,7 @@ import { useTerminalDimensions } from "@opentui/solid";
|
|
|
13
13
|
import { createEffect, createMemo, createSignal, For, onCleanup, Show } from "solid-js";
|
|
14
14
|
|
|
15
15
|
// src/sessions.ts
|
|
16
|
+
import { existsSync, readFileSync } from "fs";
|
|
16
17
|
var CALL_TIMEOUT_MS = 5000;
|
|
17
18
|
var BUILTIN_AGENTS = new Set(["build", "plan"]);
|
|
18
19
|
function withTimeout(fn, ms = CALL_TIMEOUT_MS) {
|
|
@@ -54,16 +55,17 @@ function normalizeSession(raw) {
|
|
|
54
55
|
updated: toMillis(time.updated ?? record.time_updated)
|
|
55
56
|
};
|
|
56
57
|
}
|
|
58
|
+
var SESSION_LIST_LIMIT = 5000;
|
|
57
59
|
async function fetchSessions(client, directory) {
|
|
58
60
|
const namespace = client?.session;
|
|
59
61
|
if (!namespace?.list)
|
|
60
62
|
return;
|
|
61
63
|
const calls = [
|
|
62
|
-
() => namespace.list({ directory }),
|
|
63
|
-
() => namespace.list({ query: { directory } })
|
|
64
|
+
() => namespace.list({ directory, limit: SESSION_LIST_LIMIT }),
|
|
65
|
+
() => namespace.list({ query: { directory, limit: SESSION_LIST_LIMIT } })
|
|
64
66
|
];
|
|
65
67
|
for (const call of calls) {
|
|
66
|
-
const result = unwrap(await withTimeout(call));
|
|
68
|
+
const result = unwrap(await withTimeout(call, 8000));
|
|
67
69
|
if (Array.isArray(result))
|
|
68
70
|
return result.map(normalizeSession).filter((s) => !!s);
|
|
69
71
|
}
|
|
@@ -74,23 +76,20 @@ async function fetchActiveSessionIDs(client) {
|
|
|
74
76
|
if (!namespace)
|
|
75
77
|
return;
|
|
76
78
|
if (typeof namespace.active === "function") {
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (value)
|
|
82
|
-
ids.add(id);
|
|
83
|
-
}
|
|
84
|
-
return ids;
|
|
79
|
+
const result = await withTimeout(() => namespace.active());
|
|
80
|
+
const data = result && typeof result === "object" ? result.data : undefined;
|
|
81
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
82
|
+
return new Set(Object.keys(data));
|
|
85
83
|
}
|
|
86
84
|
}
|
|
87
85
|
if (typeof namespace.status === "function") {
|
|
88
|
-
const
|
|
89
|
-
|
|
86
|
+
const result = await withTimeout(() => namespace.status());
|
|
87
|
+
const data = result && typeof result === "object" ? result.data : undefined;
|
|
88
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
90
89
|
const ids = new Set;
|
|
91
|
-
for (const [id, value] of Object.entries(
|
|
92
|
-
const
|
|
93
|
-
if (
|
|
90
|
+
for (const [id, value] of Object.entries(data)) {
|
|
91
|
+
const type = value && typeof value === "object" ? value.type ?? value.status : value;
|
|
92
|
+
if (type === undefined || type === "busy" || type === "retry")
|
|
94
93
|
ids.add(id);
|
|
95
94
|
}
|
|
96
95
|
return ids;
|
|
@@ -98,6 +97,88 @@ async function fetchActiveSessionIDs(client) {
|
|
|
98
97
|
}
|
|
99
98
|
return;
|
|
100
99
|
}
|
|
100
|
+
function loadAvSidecar(globalConfigDir) {
|
|
101
|
+
const parents = new Map;
|
|
102
|
+
if (!globalConfigDir)
|
|
103
|
+
return { parents };
|
|
104
|
+
try {
|
|
105
|
+
const path = `${globalConfigDir.replace(/[\\/]+$/, "")}/agent-variants.jsonc`;
|
|
106
|
+
if (!existsSync(path))
|
|
107
|
+
return { parents };
|
|
108
|
+
const raw = readFileSync(path, "utf8");
|
|
109
|
+
const json = JSON.parse(stripJsoncComments(raw));
|
|
110
|
+
for (const [parent, entry] of Object.entries(json.agents ?? {})) {
|
|
111
|
+
if (!entry || typeof entry !== "object")
|
|
112
|
+
continue;
|
|
113
|
+
parents.set(parent, { disableBase: entry.disable_base === true && entry.disable !== true });
|
|
114
|
+
}
|
|
115
|
+
} catch {}
|
|
116
|
+
return { parents };
|
|
117
|
+
}
|
|
118
|
+
function stripJsoncComments(text) {
|
|
119
|
+
return text.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:"'\\])\/\/.*$/gm, "$1").replace(/,(\s*[}\]])/g, "$1");
|
|
120
|
+
}
|
|
121
|
+
var ATTRIBUTION_PAGE_SIZE = 100;
|
|
122
|
+
var ATTRIBUTION_PAGES = 5;
|
|
123
|
+
async function fetchVariantAttribution(client, parentSessionID, directory, avParents) {
|
|
124
|
+
const map = new Map;
|
|
125
|
+
if (avParents.size === 0 || !parentSessionID)
|
|
126
|
+
return map;
|
|
127
|
+
const namespace = client?.session;
|
|
128
|
+
if (!namespace || typeof namespace.messages !== "function")
|
|
129
|
+
return map;
|
|
130
|
+
const fetchPage = (before) => {
|
|
131
|
+
const query = { directory, limit: ATTRIBUTION_PAGE_SIZE };
|
|
132
|
+
if (before)
|
|
133
|
+
query.before = before;
|
|
134
|
+
const flat = namespace.messages({ sessionID: parentSessionID, ...query });
|
|
135
|
+
return flat instanceof Promise ? flat : namespace.messages({ path: { id: parentSessionID }, query });
|
|
136
|
+
};
|
|
137
|
+
const asList = (value) => {
|
|
138
|
+
if (Array.isArray(value))
|
|
139
|
+
return value;
|
|
140
|
+
if (value && typeof value === "object") {
|
|
141
|
+
const unwrapped = value.data;
|
|
142
|
+
if (Array.isArray(unwrapped))
|
|
143
|
+
return unwrapped;
|
|
144
|
+
}
|
|
145
|
+
return;
|
|
146
|
+
};
|
|
147
|
+
let before;
|
|
148
|
+
const seenCursors = new Set;
|
|
149
|
+
for (let page = 0;page < ATTRIBUTION_PAGES; page++) {
|
|
150
|
+
const messages = await withTimeout(() => fetchPage(before), 8000);
|
|
151
|
+
const list = asList(messages);
|
|
152
|
+
if (!list || list.length === 0)
|
|
153
|
+
break;
|
|
154
|
+
for (const message of list) {
|
|
155
|
+
for (const part of message.parts ?? []) {
|
|
156
|
+
if (part?.type !== "tool" || part.tool !== "task")
|
|
157
|
+
continue;
|
|
158
|
+
const metadata = part.state?.metadata;
|
|
159
|
+
const child = metadata?.sessionId;
|
|
160
|
+
const variantMeta = metadata?.agentVariants;
|
|
161
|
+
const alias = variantMeta?.alias;
|
|
162
|
+
const routedAgent = variantMeta?.routedAgent;
|
|
163
|
+
if (typeof child === "string" && typeof alias === "string" && !map.has(child)) {
|
|
164
|
+
map.set(child, {
|
|
165
|
+
alias,
|
|
166
|
+
parent: typeof routedAgent === "string" ? routedAgent : alias.replace(/-[a-z0-9-]+$/, "")
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (list.length < ATTRIBUTION_PAGE_SIZE)
|
|
172
|
+
break;
|
|
173
|
+
const last = list[list.length - 1];
|
|
174
|
+
const next = last?.info?.id ?? last?.id;
|
|
175
|
+
if (!next || seenCursors.has(next))
|
|
176
|
+
break;
|
|
177
|
+
seenCursors.add(next);
|
|
178
|
+
before = next;
|
|
179
|
+
}
|
|
180
|
+
return map;
|
|
181
|
+
}
|
|
101
182
|
function buildSessionTree(sessions, rootID) {
|
|
102
183
|
const byParent = new Map;
|
|
103
184
|
for (const session of sessions) {
|
|
@@ -170,10 +251,18 @@ function isHiddenAgent(agent, hidden, configAgents) {
|
|
|
170
251
|
return true;
|
|
171
252
|
return !configAgents.has(agent) && !BUILTIN_AGENTS.has(agent) && !agent.startsWith("av:");
|
|
172
253
|
}
|
|
254
|
+
function rowHidden(variant, agent, avParents, hidden, configAgents) {
|
|
255
|
+
if (variant)
|
|
256
|
+
return false;
|
|
257
|
+
if (agent && avParents.has(agent))
|
|
258
|
+
return false;
|
|
259
|
+
return isHiddenAgent(agent, hidden, configAgents);
|
|
260
|
+
}
|
|
173
261
|
async function deleteSession(client, sessionID) {
|
|
174
262
|
const namespace = client?.session;
|
|
175
263
|
if (!namespace)
|
|
176
264
|
return false;
|
|
265
|
+
const isErrorEnvelope = (value) => !!value && typeof value === "object" && ("error" in value) && !("data" in value);
|
|
177
266
|
const shapes = [];
|
|
178
267
|
if (typeof namespace.delete === "function") {
|
|
179
268
|
shapes.push(() => namespace.delete({ sessionID }), () => namespace.delete({ path: { sessionID } }), () => namespace.delete({ path: { id: sessionID } }), () => namespace.delete({ id: sessionID }));
|
|
@@ -183,8 +272,11 @@ async function deleteSession(client, sessionID) {
|
|
|
183
272
|
}
|
|
184
273
|
for (const call of shapes) {
|
|
185
274
|
const result = await withTimeout(call);
|
|
186
|
-
if (result
|
|
187
|
-
|
|
275
|
+
if (result === undefined)
|
|
276
|
+
continue;
|
|
277
|
+
if (isErrorEnvelope(result))
|
|
278
|
+
continue;
|
|
279
|
+
return true;
|
|
188
280
|
}
|
|
189
281
|
return false;
|
|
190
282
|
}
|
|
@@ -260,28 +352,42 @@ function parentCandidates(sessions) {
|
|
|
260
352
|
}
|
|
261
353
|
|
|
262
354
|
// src/wizard.tsx
|
|
263
|
-
|
|
355
|
+
function globalConfigDirOf(api) {
|
|
356
|
+
const config = api.state.path?.config;
|
|
357
|
+
if (!config)
|
|
358
|
+
return;
|
|
359
|
+
const index = Math.max(config.lastIndexOf("/"), config.lastIndexOf("\\"));
|
|
360
|
+
return index > 0 ? config.slice(0, index) : undefined;
|
|
361
|
+
}
|
|
362
|
+
async function loadExplorerData(api, directory, rootOverride) {
|
|
264
363
|
const sessions = await fetchSessions(api.client, directory);
|
|
265
364
|
if (!sessions)
|
|
266
365
|
return;
|
|
267
|
-
const activeIDs = await fetchActiveSessionIDs(api.client);
|
|
366
|
+
const [activeIDs, avSidecar] = await Promise.all([fetchActiveSessionIDs(api.client), Promise.resolve(loadAvSidecar(globalConfigDirOf(api)))]);
|
|
367
|
+
const rootID = rootOverride ?? currentSessionID(api.currentSessionID?.(), sessions);
|
|
368
|
+
const variantOf = await fetchVariantAttribution(api.client, rootID, directory, new Set(avSidecar.parents.keys()));
|
|
268
369
|
return {
|
|
269
370
|
sessions,
|
|
270
371
|
activeIDs,
|
|
271
372
|
activeKnown: activeIDs !== undefined,
|
|
272
373
|
hidden: hiddenAgentIDs(api.state.config),
|
|
273
|
-
configAgents: configAgentIDs(api.state.config)
|
|
374
|
+
configAgents: configAgentIDs(api.state.config),
|
|
375
|
+
variantOf,
|
|
376
|
+
avParents: avSidecar.parents
|
|
274
377
|
};
|
|
275
378
|
}
|
|
276
379
|
function explorerRows(tree, data) {
|
|
277
380
|
const rows = [];
|
|
278
381
|
const walk = (nodes, depth) => {
|
|
279
382
|
for (const node of nodes) {
|
|
383
|
+
const variant = data.variantOf.get(node.session.id);
|
|
384
|
+
const agent = node.session.agent;
|
|
280
385
|
rows.push({
|
|
281
386
|
session: node.session,
|
|
282
387
|
depth,
|
|
283
388
|
running: data.activeIDs?.has(node.session.id) ?? false,
|
|
284
|
-
hidden:
|
|
389
|
+
hidden: rowHidden(variant, agent, data.avParents, data.hidden, data.configAgents),
|
|
390
|
+
variant
|
|
285
391
|
});
|
|
286
392
|
walk(node.children, depth + 1);
|
|
287
393
|
}
|
|
@@ -289,6 +395,9 @@ function explorerRows(tree, data) {
|
|
|
289
395
|
walk(tree, 0);
|
|
290
396
|
return rows;
|
|
291
397
|
}
|
|
398
|
+
function agentLabelOf(row) {
|
|
399
|
+
return row.variant?.alias ?? row.session.agent ?? "unknown";
|
|
400
|
+
}
|
|
292
401
|
function themeOf(api) {
|
|
293
402
|
return api.theme.current;
|
|
294
403
|
}
|
|
@@ -661,7 +770,7 @@ function SubagentTreeDialog(props) {
|
|
|
661
770
|
_$setProp(_el$30, "flexShrink", 0);
|
|
662
771
|
_$setProp(_el$30, "wrapMode", "none");
|
|
663
772
|
_$setProp(_el$30, "overflow", "hidden");
|
|
664
|
-
_$insert(_el$31, () => truncate(row
|
|
773
|
+
_$insert(_el$31, () => truncate(agentLabelOf(row), agentWidth));
|
|
665
774
|
_$insert(_el$28, _$createComponent(Show, {
|
|
666
775
|
get when() {
|
|
667
776
|
return row.hidden;
|
|
@@ -986,7 +1095,7 @@ function showConfirm(api, props) {
|
|
|
986
1095
|
async function deleteOne(api, row) {
|
|
987
1096
|
const label = `${rowTitle(row)}${row.hidden ? " [hidden agent]" : ""}`;
|
|
988
1097
|
const summary = `${label}
|
|
989
|
-
agent: ${row.session.agent ?? "unknown"}
|
|
1098
|
+
${row.variant ? `variant: ${row.variant.alias} (of ${row.variant.parent})` : `agent: ${row.session.agent ?? "unknown"}`}
|
|
990
1099
|
last activity: ${formatAge(row.session.updated ?? row.session.created)}
|
|
991
1100
|
|
|
992
1101
|
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.`;
|
|
@@ -1010,7 +1119,50 @@ Deleting a session permanently removes it, its messages, and its history. The pa
|
|
|
1010
1119
|
});
|
|
1011
1120
|
return ok;
|
|
1012
1121
|
}
|
|
1013
|
-
|
|
1122
|
+
function CleanupProgressDialog(props) {
|
|
1123
|
+
const theme = () => themeOf(props.api);
|
|
1124
|
+
const popMode = props.api.mode.push("subagent-explorer.cleanup");
|
|
1125
|
+
onCleanup(() => popMode());
|
|
1126
|
+
const done = props.done;
|
|
1127
|
+
const total = props.total;
|
|
1128
|
+
return (() => {
|
|
1129
|
+
var _el$56 = _$createElement("box"), _el$57 = _$createElement("text"), _el$58 = _$createElement("b"), _el$60 = _$createElement("text"), _el$61 = _$createElement("text");
|
|
1130
|
+
_$insertNode(_el$56, _el$57);
|
|
1131
|
+
_$insertNode(_el$56, _el$60);
|
|
1132
|
+
_$insertNode(_el$56, _el$61);
|
|
1133
|
+
_$setProp(_el$56, "flexDirection", "column");
|
|
1134
|
+
_$setProp(_el$56, "width", "100%");
|
|
1135
|
+
_$setProp(_el$56, "paddingLeft", 2);
|
|
1136
|
+
_$setProp(_el$56, "paddingRight", 2);
|
|
1137
|
+
_$setProp(_el$56, "paddingTop", 2);
|
|
1138
|
+
_$setProp(_el$56, "paddingBottom", 2);
|
|
1139
|
+
_$setProp(_el$56, "gap", 1);
|
|
1140
|
+
_$insertNode(_el$57, _el$58);
|
|
1141
|
+
_$insertNode(_el$58, _$createTextNode(`Cleaning up idle subagent sessions\u2026`));
|
|
1142
|
+
_$insert(_el$60, () => `${done()} / ${total} deleted`);
|
|
1143
|
+
_$insertNode(_el$61, _$createTextNode(`This dialog closes when the batch finishes.`));
|
|
1144
|
+
_$effect((_p$) => {
|
|
1145
|
+
var _v$24 = theme().text, _v$25 = theme().textMuted, _v$26 = theme().textMuted;
|
|
1146
|
+
_v$24 !== _p$.e && (_p$.e = _$setProp(_el$57, "fg", _v$24, _p$.e));
|
|
1147
|
+
_v$25 !== _p$.t && (_p$.t = _$setProp(_el$60, "fg", _v$25, _p$.t));
|
|
1148
|
+
_v$26 !== _p$.a && (_p$.a = _$setProp(_el$61, "fg", _v$26, _p$.a));
|
|
1149
|
+
return _p$;
|
|
1150
|
+
}, {
|
|
1151
|
+
e: undefined,
|
|
1152
|
+
t: undefined,
|
|
1153
|
+
a: undefined
|
|
1154
|
+
});
|
|
1155
|
+
return _el$56;
|
|
1156
|
+
})();
|
|
1157
|
+
}
|
|
1158
|
+
function showCleanupProgress(api, done, total) {
|
|
1159
|
+
api.ui.dialog.replace(() => _$createComponent(CleanupProgressDialog, {
|
|
1160
|
+
api,
|
|
1161
|
+
done,
|
|
1162
|
+
total
|
|
1163
|
+
}), () => {});
|
|
1164
|
+
}
|
|
1165
|
+
async function runCleanup(api, plan, rootTitle, directory, rootID) {
|
|
1014
1166
|
if (plan.deletable.length === 0) {
|
|
1015
1167
|
await showInfo(api, {
|
|
1016
1168
|
title: "Nothing to clean up",
|
|
@@ -1029,18 +1181,40 @@ ${plan.sparedActive.length} running session(s) will be spared.` : "";
|
|
|
1029
1181
|
if (!confirmed)
|
|
1030
1182
|
return 0;
|
|
1031
1183
|
let deleted = 0;
|
|
1184
|
+
const [progressDone, setProgressDone] = createSignal(0);
|
|
1185
|
+
showCleanupProgress(api, progressDone, plan.deletable.length);
|
|
1032
1186
|
for (const session of plan.deletable) {
|
|
1033
|
-
if (await deleteSession(api.client, session.id))
|
|
1187
|
+
if (await deleteSession(api.client, session.id)) {
|
|
1034
1188
|
deleted += 1;
|
|
1189
|
+
setProgressDone(deleted);
|
|
1190
|
+
}
|
|
1035
1191
|
}
|
|
1192
|
+
const remainingIdle = await remainingIdleCount(api, directory, rootID);
|
|
1193
|
+
api.ui.dialog.clear();
|
|
1036
1194
|
const failed = plan.deletable.length - deleted;
|
|
1037
1195
|
api.ui.toast({
|
|
1038
|
-
variant: failed > 0 ? "warning" : "default",
|
|
1196
|
+
variant: failed > 0 || remainingIdle > 0 ? "warning" : "default",
|
|
1039
1197
|
title: "Cleanup finished",
|
|
1040
|
-
message: failed > 0 ? `Deleted ${deleted}, failed ${failed}.` : `Deleted ${deleted} session(s).`
|
|
1198
|
+
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).`
|
|
1041
1199
|
});
|
|
1042
1200
|
return deleted;
|
|
1043
1201
|
}
|
|
1202
|
+
async function remainingIdleCount(api, directory, rootID) {
|
|
1203
|
+
const sessions = await fetchSessions(api.client, directory);
|
|
1204
|
+
if (!sessions)
|
|
1205
|
+
return 0;
|
|
1206
|
+
const active = await fetchActiveSessionIDs(api.client);
|
|
1207
|
+
const rows = explorerRows(buildSessionTree(sessions, rootID), {
|
|
1208
|
+
sessions,
|
|
1209
|
+
activeIDs: active,
|
|
1210
|
+
activeKnown: active !== undefined,
|
|
1211
|
+
hidden: new Set,
|
|
1212
|
+
configAgents: new Set,
|
|
1213
|
+
variantOf: new Map,
|
|
1214
|
+
avParents: new Map
|
|
1215
|
+
});
|
|
1216
|
+
return rows.filter((row) => !row.running).length;
|
|
1217
|
+
}
|
|
1044
1218
|
function showRootPicker(api, sessions, currentRoot) {
|
|
1045
1219
|
return new Promise((resolve) => {
|
|
1046
1220
|
let settled = false;
|
|
@@ -1065,9 +1239,19 @@ function showRootPicker(api, sessions, currentRoot) {
|
|
|
1065
1239
|
}), () => done(undefined));
|
|
1066
1240
|
});
|
|
1067
1241
|
}
|
|
1068
|
-
async function showDetails(api, row) {
|
|
1242
|
+
async function showDetails(api, row, data) {
|
|
1069
1243
|
const details = await fetchSessionDetails(api.client, row.session.id);
|
|
1070
|
-
const
|
|
1244
|
+
const parentAgent = row.session.agent ?? "unknown";
|
|
1245
|
+
const lines = [`title: ${rowTitle(row)}`, row.variant ? `variant: ${row.variant.alias} (of ${row.variant.parent})` : `agent: ${parentAgent}${row.hidden ? " (hidden/background)" : ""}`];
|
|
1246
|
+
if (row.variant) {
|
|
1247
|
+
const parentEntry = data.avParents.get(row.variant.parent);
|
|
1248
|
+
if (parentEntry) {
|
|
1249
|
+
lines.push(`base ${row.variant.parent}: ${parentEntry.disableBase ? "disabled (variants only)" : "enabled"}`);
|
|
1250
|
+
}
|
|
1251
|
+
} else if (data.avParents.has(parentAgent)) {
|
|
1252
|
+
lines.push(`base ${parentAgent}: ${data.avParents.get(parentAgent)?.disableBase ? "disabled (variants only)" : "enabled"}`);
|
|
1253
|
+
}
|
|
1254
|
+
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)}`);
|
|
1071
1255
|
if (details) {
|
|
1072
1256
|
lines.push(`messages: ${details.messageCount}`);
|
|
1073
1257
|
if (details.model)
|
|
@@ -1347,140 +1531,140 @@ function SizeSliderDialog(props) {
|
|
|
1347
1531
|
popMode();
|
|
1348
1532
|
});
|
|
1349
1533
|
return (() => {
|
|
1350
|
-
var _el$
|
|
1351
|
-
_$insertNode(_el$56, _el$57);
|
|
1352
|
-
_$insertNode(_el$56, _el$63);
|
|
1353
|
-
_$insertNode(_el$56, _el$74);
|
|
1354
|
-
_$insertNode(_el$56, _el$82);
|
|
1355
|
-
_$insertNode(_el$56, _el$93);
|
|
1356
|
-
_$setProp(_el$56, "flexDirection", "column");
|
|
1357
|
-
_$setProp(_el$56, "width", "100%");
|
|
1358
|
-
_$setProp(_el$56, "paddingLeft", 2);
|
|
1359
|
-
_$setProp(_el$56, "paddingRight", 2);
|
|
1360
|
-
_$setProp(_el$56, "paddingTop", 1);
|
|
1361
|
-
_$setProp(_el$56, "paddingBottom", 1);
|
|
1362
|
-
_$insertNode(_el$57, _el$58);
|
|
1363
|
-
_$insertNode(_el$57, _el$61);
|
|
1364
|
-
_$setProp(_el$57, "flexDirection", "row");
|
|
1365
|
-
_$setProp(_el$57, "justifyContent", "space-between");
|
|
1366
|
-
_$setProp(_el$57, "width", "100%");
|
|
1367
|
-
_$setProp(_el$57, "marginBottom", 1);
|
|
1368
|
-
_$insertNode(_el$58, _el$59);
|
|
1369
|
-
_$insertNode(_el$59, _$createTextNode(`Dialog size`));
|
|
1370
|
-
_$insertNode(_el$61, _$createTextNode(`esc`));
|
|
1371
|
-
_$setProp(_el$61, "onMouseUp", () => props.onDone(undefined));
|
|
1534
|
+
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");
|
|
1372
1535
|
_$insertNode(_el$63, _el$64);
|
|
1373
|
-
_$insertNode(_el$63, _el$
|
|
1374
|
-
_$insertNode(_el$63, _el$
|
|
1375
|
-
_$insertNode(_el$63, _el$
|
|
1376
|
-
_$
|
|
1377
|
-
_$setProp(_el$63, "
|
|
1536
|
+
_$insertNode(_el$63, _el$70);
|
|
1537
|
+
_$insertNode(_el$63, _el$81);
|
|
1538
|
+
_$insertNode(_el$63, _el$89);
|
|
1539
|
+
_$insertNode(_el$63, _el$100);
|
|
1540
|
+
_$setProp(_el$63, "flexDirection", "column");
|
|
1378
1541
|
_$setProp(_el$63, "width", "100%");
|
|
1379
|
-
_$setProp(_el$63, "
|
|
1380
|
-
_$
|
|
1381
|
-
_$
|
|
1382
|
-
_$
|
|
1383
|
-
_$insertNode(_el$
|
|
1384
|
-
_$insertNode(_el$
|
|
1385
|
-
_$
|
|
1386
|
-
_$
|
|
1387
|
-
_$
|
|
1388
|
-
_$
|
|
1389
|
-
_$insertNode(_el$
|
|
1390
|
-
_$insertNode(_el$
|
|
1391
|
-
_$
|
|
1392
|
-
_$setProp(_el$
|
|
1393
|
-
_$
|
|
1542
|
+
_$setProp(_el$63, "paddingLeft", 2);
|
|
1543
|
+
_$setProp(_el$63, "paddingRight", 2);
|
|
1544
|
+
_$setProp(_el$63, "paddingTop", 1);
|
|
1545
|
+
_$setProp(_el$63, "paddingBottom", 1);
|
|
1546
|
+
_$insertNode(_el$64, _el$65);
|
|
1547
|
+
_$insertNode(_el$64, _el$68);
|
|
1548
|
+
_$setProp(_el$64, "flexDirection", "row");
|
|
1549
|
+
_$setProp(_el$64, "justifyContent", "space-between");
|
|
1550
|
+
_$setProp(_el$64, "width", "100%");
|
|
1551
|
+
_$setProp(_el$64, "marginBottom", 1);
|
|
1552
|
+
_$insertNode(_el$65, _el$66);
|
|
1553
|
+
_$insertNode(_el$66, _$createTextNode(`Dialog size`));
|
|
1554
|
+
_$insertNode(_el$68, _$createTextNode(`esc`));
|
|
1555
|
+
_$setProp(_el$68, "onMouseUp", () => props.onDone(undefined));
|
|
1556
|
+
_$insertNode(_el$70, _el$71);
|
|
1557
|
+
_$insertNode(_el$70, _el$73);
|
|
1558
|
+
_$insertNode(_el$70, _el$75);
|
|
1559
|
+
_$insertNode(_el$70, _el$78);
|
|
1560
|
+
_$setProp(_el$70, "flexDirection", "row");
|
|
1561
|
+
_$setProp(_el$70, "gap", 0);
|
|
1562
|
+
_$setProp(_el$70, "width", "100%");
|
|
1563
|
+
_$setProp(_el$70, "marginBottom", 1);
|
|
1564
|
+
_$insertNode(_el$71, _$createTextNode(`Width: `));
|
|
1565
|
+
_$insertNode(_el$73, _el$74);
|
|
1566
|
+
_$insert(_el$74, () => dialogSizeOf(props.api));
|
|
1394
1567
|
_$insertNode(_el$75, _el$76);
|
|
1395
|
-
_$
|
|
1568
|
+
_$insertNode(_el$75, _el$77);
|
|
1569
|
+
_$insert(_el$75, () => DIALOG_WIDTH_COLUMNS[dialogSizeOf(props.api)], _el$77);
|
|
1570
|
+
_$insertNode(_el$78, _el$79);
|
|
1571
|
+
_$insertNode(_el$79, _el$80);
|
|
1572
|
+
_$insert(_el$79, height, _el$80);
|
|
1573
|
+
_$insertNode(_el$81, _el$82);
|
|
1574
|
+
_$insertNode(_el$81, _el$85);
|
|
1575
|
+
_$setProp(_el$81, "flexDirection", "row");
|
|
1576
|
+
_$setProp(_el$81, "width", "100%");
|
|
1577
|
+
_$setProp(_el$81, "marginBottom", 1);
|
|
1578
|
+
_$insertNode(_el$82, _el$83);
|
|
1579
|
+
_$insert(_el$81, _$createComponent(For, {
|
|
1396
1580
|
get each() {
|
|
1397
1581
|
return sliderCells();
|
|
1398
1582
|
},
|
|
1399
1583
|
children: (cell) => (() => {
|
|
1400
|
-
var _el$
|
|
1401
|
-
_$insert(_el$
|
|
1402
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1403
|
-
return _el$
|
|
1584
|
+
var _el$107 = _$createElement("text");
|
|
1585
|
+
_$insert(_el$107, () => cell.char);
|
|
1586
|
+
_$effect((_$p) => _$setProp(_el$107, "fg", cell.color, _$p));
|
|
1587
|
+
return _el$107;
|
|
1404
1588
|
})()
|
|
1405
|
-
}), _el$
|
|
1406
|
-
_$insertNode(_el$
|
|
1407
|
-
_$insertNode(_el$
|
|
1408
|
-
_$insertNode(_el$
|
|
1409
|
-
_$setProp(_el$
|
|
1410
|
-
_$setProp(_el$
|
|
1411
|
-
_$setProp(_el$
|
|
1412
|
-
_$insertNode(_el$
|
|
1413
|
-
_$insertNode(_el$
|
|
1414
|
-
_$insertNode(_el$
|
|
1415
|
-
_$insertNode(_el$
|
|
1416
|
-
_$setProp(_el$
|
|
1417
|
-
_$setProp(_el$
|
|
1418
|
-
_$insert(_el$
|
|
1589
|
+
}), _el$85);
|
|
1590
|
+
_$insertNode(_el$85, _el$86);
|
|
1591
|
+
_$insertNode(_el$89, _el$90);
|
|
1592
|
+
_$insertNode(_el$89, _el$99);
|
|
1593
|
+
_$setProp(_el$89, "flexDirection", "row");
|
|
1594
|
+
_$setProp(_el$89, "gap", 2);
|
|
1595
|
+
_$setProp(_el$89, "marginBottom", 1);
|
|
1596
|
+
_$insertNode(_el$90, _el$91);
|
|
1597
|
+
_$insertNode(_el$90, _el$93);
|
|
1598
|
+
_$insertNode(_el$90, _el$95);
|
|
1599
|
+
_$insertNode(_el$90, _el$97);
|
|
1600
|
+
_$setProp(_el$90, "flexDirection", "column");
|
|
1601
|
+
_$setProp(_el$90, "gap", 0);
|
|
1602
|
+
_$insert(_el$90, _$createComponent(For, {
|
|
1419
1603
|
each: HEIGHT_PRESETS,
|
|
1420
1604
|
children: (preset) => (() => {
|
|
1421
|
-
var _el$
|
|
1422
|
-
_$insertNode(_el$
|
|
1423
|
-
_$insertNode(_el$
|
|
1424
|
-
_$insertNode(_el$
|
|
1425
|
-
_$insert(_el$
|
|
1426
|
-
_$insert(_el$
|
|
1427
|
-
_$insert(_el$
|
|
1428
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1429
|
-
return _el$
|
|
1605
|
+
var _el$108 = _$createElement("text"), _el$109 = _$createTextNode(` `), _el$110 = _$createTextNode(`: `), _el$111 = _$createTextNode(`%`);
|
|
1606
|
+
_$insertNode(_el$108, _el$109);
|
|
1607
|
+
_$insertNode(_el$108, _el$110);
|
|
1608
|
+
_$insertNode(_el$108, _el$111);
|
|
1609
|
+
_$insert(_el$108, () => preset.key, _el$109);
|
|
1610
|
+
_$insert(_el$108, () => preset.label, _el$110);
|
|
1611
|
+
_$insert(_el$108, () => preset.value, _el$111);
|
|
1612
|
+
_$effect((_$p) => _$setProp(_el$108, "fg", height() === preset.value ? theme().primary : theme().textMuted, _$p));
|
|
1613
|
+
return _el$108;
|
|
1430
1614
|
})()
|
|
1431
|
-
}), _el$
|
|
1432
|
-
_$insertNode(_el$
|
|
1433
|
-
_$insertNode(_el$
|
|
1434
|
-
_$insertNode(_el$
|
|
1435
|
-
_$insertNode(_el$
|
|
1436
|
-
_$setProp(_el$
|
|
1437
|
-
_$setProp(_el$
|
|
1438
|
-
_$insert(_el$
|
|
1615
|
+
}), _el$91);
|
|
1616
|
+
_$insertNode(_el$91, _$createTextNode(` `));
|
|
1617
|
+
_$insertNode(_el$93, _$createTextNode(`left/right 1%`));
|
|
1618
|
+
_$insertNode(_el$95, _$createTextNode(`up/down 5%`));
|
|
1619
|
+
_$insertNode(_el$97, _$createTextNode(`c custom`));
|
|
1620
|
+
_$setProp(_el$99, "flexDirection", "column");
|
|
1621
|
+
_$setProp(_el$99, "gap", 0);
|
|
1622
|
+
_$insert(_el$99, _$createComponent(For, {
|
|
1439
1623
|
get each() {
|
|
1440
1624
|
return preview();
|
|
1441
1625
|
},
|
|
1442
1626
|
children: (line) => (() => {
|
|
1443
|
-
var _el$
|
|
1444
|
-
_$insert(_el$
|
|
1445
|
-
_$effect((_$p) => _$setProp(_el$
|
|
1446
|
-
return _el$
|
|
1627
|
+
var _el$112 = _$createElement("text");
|
|
1628
|
+
_$insert(_el$112, line);
|
|
1629
|
+
_$effect((_$p) => _$setProp(_el$112, "fg", theme().textMuted, _$p));
|
|
1630
|
+
return _el$112;
|
|
1447
1631
|
})()
|
|
1448
1632
|
}));
|
|
1449
|
-
_$insertNode(_el$
|
|
1450
|
-
_$insertNode(_el$
|
|
1451
|
-
_$setProp(_el$
|
|
1452
|
-
_$setProp(_el$
|
|
1453
|
-
_$setProp(_el$
|
|
1454
|
-
_$insertNode(_el$
|
|
1455
|
-
_$insertNode(_el$
|
|
1456
|
-
_$setProp(_el$
|
|
1457
|
-
_$setProp(_el$
|
|
1458
|
-
_$setProp(_el$
|
|
1633
|
+
_$insertNode(_el$100, _el$101);
|
|
1634
|
+
_$insertNode(_el$100, _el$103);
|
|
1635
|
+
_$setProp(_el$100, "flexDirection", "row");
|
|
1636
|
+
_$setProp(_el$100, "justifyContent", "space-between");
|
|
1637
|
+
_$setProp(_el$100, "width", "100%");
|
|
1638
|
+
_$insertNode(_el$101, _$createTextNode(`enter save`));
|
|
1639
|
+
_$insertNode(_el$103, _el$104);
|
|
1640
|
+
_$setProp(_el$103, "paddingLeft", 3);
|
|
1641
|
+
_$setProp(_el$103, "paddingRight", 3);
|
|
1642
|
+
_$setProp(_el$103, "onMouseUp", () => {
|
|
1459
1643
|
setDialogHeightPercent(props.api, height());
|
|
1460
1644
|
props.onDone({
|
|
1461
1645
|
action: "save",
|
|
1462
1646
|
height: height()
|
|
1463
1647
|
});
|
|
1464
1648
|
});
|
|
1465
|
-
_$insertNode(_el$
|
|
1466
|
-
_$insertNode(_el$
|
|
1649
|
+
_$insertNode(_el$104, _el$105);
|
|
1650
|
+
_$insertNode(_el$105, _$createTextNode(`save`));
|
|
1467
1651
|
_$effect((_p$) => {
|
|
1468
|
-
var _v$
|
|
1469
|
-
_v$
|
|
1470
|
-
_v$
|
|
1471
|
-
_v$
|
|
1472
|
-
_v$
|
|
1473
|
-
_v$
|
|
1474
|
-
_v$
|
|
1475
|
-
_v$
|
|
1476
|
-
_v$
|
|
1477
|
-
_v$
|
|
1478
|
-
_v$
|
|
1479
|
-
_v$
|
|
1480
|
-
_v$
|
|
1481
|
-
_v$
|
|
1482
|
-
_v$
|
|
1483
|
-
_v$
|
|
1652
|
+
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;
|
|
1653
|
+
_v$27 !== _p$.e && (_p$.e = _$setProp(_el$65, "fg", _v$27, _p$.e));
|
|
1654
|
+
_v$28 !== _p$.t && (_p$.t = _$setProp(_el$68, "fg", _v$28, _p$.t));
|
|
1655
|
+
_v$29 !== _p$.a && (_p$.a = _$setProp(_el$71, "fg", _v$29, _p$.a));
|
|
1656
|
+
_v$30 !== _p$.o && (_p$.o = _$setProp(_el$73, "fg", _v$30, _p$.o));
|
|
1657
|
+
_v$31 !== _p$.i && (_p$.i = _$setProp(_el$75, "fg", _v$31, _p$.i));
|
|
1658
|
+
_v$32 !== _p$.n && (_p$.n = _$setProp(_el$78, "fg", _v$32, _p$.n));
|
|
1659
|
+
_v$33 !== _p$.s && (_p$.s = _$setProp(_el$82, "fg", _v$33, _p$.s));
|
|
1660
|
+
_v$34 !== _p$.h && (_p$.h = _$setProp(_el$85, "fg", _v$34, _p$.h));
|
|
1661
|
+
_v$35 !== _p$.r && (_p$.r = _$setProp(_el$91, "fg", _v$35, _p$.r));
|
|
1662
|
+
_v$36 !== _p$.d && (_p$.d = _$setProp(_el$93, "fg", _v$36, _p$.d));
|
|
1663
|
+
_v$37 !== _p$.l && (_p$.l = _$setProp(_el$95, "fg", _v$37, _p$.l));
|
|
1664
|
+
_v$38 !== _p$.u && (_p$.u = _$setProp(_el$97, "fg", _v$38, _p$.u));
|
|
1665
|
+
_v$39 !== _p$.c && (_p$.c = _$setProp(_el$101, "fg", _v$39, _p$.c));
|
|
1666
|
+
_v$40 !== _p$.w && (_p$.w = _$setProp(_el$103, "backgroundColor", _v$40, _p$.w));
|
|
1667
|
+
_v$41 !== _p$.m && (_p$.m = _$setProp(_el$104, "fg", _v$41, _p$.m));
|
|
1484
1668
|
return _p$;
|
|
1485
1669
|
}, {
|
|
1486
1670
|
e: undefined,
|
|
@@ -1499,7 +1683,7 @@ function SizeSliderDialog(props) {
|
|
|
1499
1683
|
w: undefined,
|
|
1500
1684
|
m: undefined
|
|
1501
1685
|
});
|
|
1502
|
-
return _el$
|
|
1686
|
+
return _el$63;
|
|
1503
1687
|
})();
|
|
1504
1688
|
}
|
|
1505
1689
|
async function mainMenu(api) {
|
|
@@ -1513,7 +1697,7 @@ async function mainMenu(api) {
|
|
|
1513
1697
|
}
|
|
1514
1698
|
let rootOverride;
|
|
1515
1699
|
while (true) {
|
|
1516
|
-
const data = await loadExplorerData(api, directory);
|
|
1700
|
+
const data = await loadExplorerData(api, directory, rootOverride);
|
|
1517
1701
|
if (!data) {
|
|
1518
1702
|
await showInfo(api, {
|
|
1519
1703
|
title: "Subagent Explorer",
|
|
@@ -1561,20 +1745,21 @@ The host client does not expose session.list for this directory.`
|
|
|
1561
1745
|
continue;
|
|
1562
1746
|
}
|
|
1563
1747
|
if (action.type === "details") {
|
|
1564
|
-
await showDetails(api, action.row);
|
|
1748
|
+
await showDetails(api, action.row, data);
|
|
1565
1749
|
continue;
|
|
1566
1750
|
}
|
|
1567
1751
|
if (action.type === "cleanup") {
|
|
1568
|
-
await runCleanup(api, cleanupTargets(tree, data.activeIDs), rootSession?.title ?? rootID);
|
|
1752
|
+
await runCleanup(api, cleanupTargets(tree, data.activeIDs), rootSession?.title ?? rootID, directory, rootID);
|
|
1569
1753
|
continue;
|
|
1570
1754
|
}
|
|
1571
1755
|
}
|
|
1572
1756
|
}
|
|
1573
1757
|
export {
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
loadExplorerData,
|
|
1577
|
-
explorerRows,
|
|
1758
|
+
SubagentTreeDialog,
|
|
1759
|
+
agentLabelOf,
|
|
1578
1760
|
computeDialogRows,
|
|
1579
|
-
|
|
1761
|
+
explorerRows,
|
|
1762
|
+
loadExplorerData,
|
|
1763
|
+
mainMenu,
|
|
1764
|
+
rowTitle
|
|
1580
1765
|
};
|