@mirrowel/opencode-subagent-explorer 0.2.0-dev.1 → 0.2.0-dev.3

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/wizard.js CHANGED
@@ -55,16 +55,17 @@ function normalizeSession(raw) {
55
55
  updated: toMillis(time.updated ?? record.time_updated)
56
56
  };
57
57
  }
58
+ var SESSION_LIST_LIMIT = 5000;
58
59
  async function fetchSessions(client, directory) {
59
60
  const namespace = client?.session;
60
61
  if (!namespace?.list)
61
62
  return;
62
63
  const calls = [
63
- () => namespace.list({ directory }),
64
- () => namespace.list({ query: { directory } })
64
+ () => namespace.list({ directory, limit: SESSION_LIST_LIMIT }),
65
+ () => namespace.list({ query: { directory, limit: SESSION_LIST_LIMIT } })
65
66
  ];
66
67
  for (const call of calls) {
67
- const result = unwrap(await withTimeout(call));
68
+ const result = unwrap(await withTimeout(call, 8000));
68
69
  if (Array.isArray(result))
69
70
  return result.map(normalizeSession).filter((s) => !!s);
70
71
  }
@@ -117,6 +118,8 @@ function loadAvSidecar(globalConfigDir) {
117
118
  function stripJsoncComments(text) {
118
119
  return text.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:"'\\])\/\/.*$/gm, "$1").replace(/,(\s*[}\]])/g, "$1");
119
120
  }
121
+ var ATTRIBUTION_PAGE_SIZE = 100;
122
+ var ATTRIBUTION_PAGES = 5;
120
123
  async function fetchVariantAttribution(client, parentSessionID, directory, avParents) {
121
124
  const map = new Map;
122
125
  if (avParents.size === 0 || !parentSessionID)
@@ -124,29 +127,57 @@ async function fetchVariantAttribution(client, parentSessionID, directory, avPar
124
127
  const namespace = client?.session;
125
128
  if (!namespace || typeof namespace.messages !== "function")
126
129
  return map;
127
- const messages = await withTimeout(() => {
128
- const flat = namespace.messages({ sessionID: parentSessionID, directory, limit: 50 });
129
- return flat instanceof Promise ? flat : namespace.messages({ path: { id: parentSessionID }, query: { directory, limit: 50 } });
130
- });
131
- const list = Array.isArray(messages) ? messages : messages && typeof messages === "object" ? messages.data ?? messages : undefined;
132
- if (!Array.isArray(list))
133
- return map;
134
- for (const message of list) {
135
- for (const part of message.parts ?? []) {
136
- if (part?.type !== "tool" || part.tool !== "task")
137
- continue;
138
- const metadata = part.state?.metadata;
139
- const child = metadata?.sessionId;
140
- const variantMeta = metadata?.agentVariants;
141
- const alias = variantMeta?.alias;
142
- const routedAgent = variantMeta?.routedAgent;
143
- if (typeof child === "string" && typeof alias === "string" && !map.has(child)) {
144
- map.set(child, {
145
- alias,
146
- parent: typeof routedAgent === "string" ? routedAgent : alias.replace(/-[a-z0-9-]+$/, "")
147
- });
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 description = part.state?.input?.description;
162
+ const descriptionMatch = typeof description === "string" ? description.match(/\s+\(@(\S+) variant\)$/) : undefined;
163
+ const alias = (typeof variantMeta?.alias === "string" ? variantMeta.alias : undefined) ?? descriptionMatch?.[1];
164
+ const routedAgent = variantMeta?.routedAgent;
165
+ if (typeof child === "string" && typeof alias === "string" && !map.has(child)) {
166
+ map.set(child, {
167
+ alias,
168
+ parent: typeof routedAgent === "string" ? routedAgent : alias.replace(/-[a-z0-9-]+$/, "")
169
+ });
170
+ }
148
171
  }
149
172
  }
173
+ if (list.length < ATTRIBUTION_PAGE_SIZE)
174
+ break;
175
+ const last = list[list.length - 1];
176
+ const next = last?.info?.id ?? last?.id;
177
+ if (!next || seenCursors.has(next))
178
+ break;
179
+ seenCursors.add(next);
180
+ before = next;
150
181
  }
151
182
  return map;
152
183
  }
@@ -222,10 +253,18 @@ function isHiddenAgent(agent, hidden, configAgents) {
222
253
  return true;
223
254
  return !configAgents.has(agent) && !BUILTIN_AGENTS.has(agent) && !agent.startsWith("av:");
224
255
  }
256
+ function rowHidden(variant, agent, avParents, hidden, configAgents) {
257
+ if (variant)
258
+ return false;
259
+ if (agent && avParents.has(agent))
260
+ return false;
261
+ return isHiddenAgent(agent, hidden, configAgents);
262
+ }
225
263
  async function deleteSession(client, sessionID) {
226
264
  const namespace = client?.session;
227
265
  if (!namespace)
228
266
  return false;
267
+ const isErrorEnvelope = (value) => !!value && typeof value === "object" && ("error" in value) && !("data" in value);
229
268
  const shapes = [];
230
269
  if (typeof namespace.delete === "function") {
231
270
  shapes.push(() => namespace.delete({ sessionID }), () => namespace.delete({ path: { sessionID } }), () => namespace.delete({ path: { id: sessionID } }), () => namespace.delete({ id: sessionID }));
@@ -235,8 +274,11 @@ async function deleteSession(client, sessionID) {
235
274
  }
236
275
  for (const call of shapes) {
237
276
  const result = await withTimeout(call);
238
- if (result !== undefined)
239
- return true;
277
+ if (result === undefined)
278
+ continue;
279
+ if (isErrorEnvelope(result))
280
+ continue;
281
+ return true;
240
282
  }
241
283
  return false;
242
284
  }
@@ -341,11 +383,12 @@ function explorerRows(tree, data) {
341
383
  const walk = (nodes, depth) => {
342
384
  for (const node of nodes) {
343
385
  const variant = data.variantOf.get(node.session.id);
386
+ const agent = node.session.agent;
344
387
  rows.push({
345
388
  session: node.session,
346
389
  depth,
347
390
  running: data.activeIDs?.has(node.session.id) ?? false,
348
- hidden: variant ? false : isHiddenAgent(node.session.agent, data.hidden, data.configAgents),
391
+ hidden: rowHidden(variant, agent, data.avParents, data.hidden, data.configAgents),
349
392
  variant
350
393
  });
351
394
  walk(node.children, depth + 1);
@@ -1078,7 +1121,50 @@ Deleting a session permanently removes it, its messages, and its history. The pa
1078
1121
  });
1079
1122
  return ok;
1080
1123
  }
1081
- async function runCleanup(api, plan, rootTitle) {
1124
+ function CleanupProgressDialog(props) {
1125
+ const theme = () => themeOf(props.api);
1126
+ const popMode = props.api.mode.push("subagent-explorer.cleanup");
1127
+ onCleanup(() => popMode());
1128
+ const done = props.done;
1129
+ const total = props.total;
1130
+ return (() => {
1131
+ var _el$56 = _$createElement("box"), _el$57 = _$createElement("text"), _el$58 = _$createElement("b"), _el$60 = _$createElement("text"), _el$61 = _$createElement("text");
1132
+ _$insertNode(_el$56, _el$57);
1133
+ _$insertNode(_el$56, _el$60);
1134
+ _$insertNode(_el$56, _el$61);
1135
+ _$setProp(_el$56, "flexDirection", "column");
1136
+ _$setProp(_el$56, "width", "100%");
1137
+ _$setProp(_el$56, "paddingLeft", 2);
1138
+ _$setProp(_el$56, "paddingRight", 2);
1139
+ _$setProp(_el$56, "paddingTop", 2);
1140
+ _$setProp(_el$56, "paddingBottom", 2);
1141
+ _$setProp(_el$56, "gap", 1);
1142
+ _$insertNode(_el$57, _el$58);
1143
+ _$insertNode(_el$58, _$createTextNode(`Cleaning up idle subagent sessions\u2026`));
1144
+ _$insert(_el$60, () => `${done()} / ${total} deleted`);
1145
+ _$insertNode(_el$61, _$createTextNode(`This dialog closes when the batch finishes.`));
1146
+ _$effect((_p$) => {
1147
+ var _v$24 = theme().text, _v$25 = theme().textMuted, _v$26 = theme().textMuted;
1148
+ _v$24 !== _p$.e && (_p$.e = _$setProp(_el$57, "fg", _v$24, _p$.e));
1149
+ _v$25 !== _p$.t && (_p$.t = _$setProp(_el$60, "fg", _v$25, _p$.t));
1150
+ _v$26 !== _p$.a && (_p$.a = _$setProp(_el$61, "fg", _v$26, _p$.a));
1151
+ return _p$;
1152
+ }, {
1153
+ e: undefined,
1154
+ t: undefined,
1155
+ a: undefined
1156
+ });
1157
+ return _el$56;
1158
+ })();
1159
+ }
1160
+ function showCleanupProgress(api, done, total) {
1161
+ api.ui.dialog.replace(() => _$createComponent(CleanupProgressDialog, {
1162
+ api,
1163
+ done,
1164
+ total
1165
+ }), () => {});
1166
+ }
1167
+ async function runCleanup(api, plan, rootTitle, directory, rootID) {
1082
1168
  if (plan.deletable.length === 0) {
1083
1169
  await showInfo(api, {
1084
1170
  title: "Nothing to clean up",
@@ -1097,18 +1183,40 @@ ${plan.sparedActive.length} running session(s) will be spared.` : "";
1097
1183
  if (!confirmed)
1098
1184
  return 0;
1099
1185
  let deleted = 0;
1186
+ const [progressDone, setProgressDone] = createSignal(0);
1187
+ showCleanupProgress(api, progressDone, plan.deletable.length);
1100
1188
  for (const session of plan.deletable) {
1101
- if (await deleteSession(api.client, session.id))
1189
+ if (await deleteSession(api.client, session.id)) {
1102
1190
  deleted += 1;
1191
+ setProgressDone(deleted);
1192
+ }
1103
1193
  }
1194
+ const remainingIdle = await remainingIdleCount(api, directory, rootID);
1195
+ api.ui.dialog.clear();
1104
1196
  const failed = plan.deletable.length - deleted;
1105
1197
  api.ui.toast({
1106
- variant: failed > 0 ? "warning" : "default",
1198
+ variant: failed > 0 || remainingIdle > 0 ? "warning" : "default",
1107
1199
  title: "Cleanup finished",
1108
- message: failed > 0 ? `Deleted ${deleted}, failed ${failed}.` : `Deleted ${deleted} session(s).`
1200
+ 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).`
1109
1201
  });
1110
1202
  return deleted;
1111
1203
  }
1204
+ async function remainingIdleCount(api, directory, rootID) {
1205
+ const sessions = await fetchSessions(api.client, directory);
1206
+ if (!sessions)
1207
+ return 0;
1208
+ const active = await fetchActiveSessionIDs(api.client);
1209
+ const rows = explorerRows(buildSessionTree(sessions, rootID), {
1210
+ sessions,
1211
+ activeIDs: active,
1212
+ activeKnown: active !== undefined,
1213
+ hidden: new Set,
1214
+ configAgents: new Set,
1215
+ variantOf: new Map,
1216
+ avParents: new Map
1217
+ });
1218
+ return rows.filter((row) => !row.running).length;
1219
+ }
1112
1220
  function showRootPicker(api, sessions, currentRoot) {
1113
1221
  return new Promise((resolve) => {
1114
1222
  let settled = false;
@@ -1425,140 +1533,140 @@ function SizeSliderDialog(props) {
1425
1533
  popMode();
1426
1534
  });
1427
1535
  return (() => {
1428
- var _el$56 = _$createElement("box"), _el$57 = _$createElement("box"), _el$58 = _$createElement("text"), _el$59 = _$createElement("b"), _el$61 = _$createElement("text"), _el$63 = _$createElement("box"), _el$64 = _$createElement("text"), _el$66 = _$createElement("text"), _el$67 = _$createElement("b"), _el$68 = _$createElement("text"), _el$69 = _$createTextNode(` (`), _el$70 = _$createTextNode(` cols, w to cycle) Height: `), _el$71 = _$createElement("text"), _el$72 = _$createElement("b"), _el$73 = _$createTextNode(`%`), _el$74 = _$createElement("box"), _el$75 = _$createElement("text"), _el$76 = _$createTextNode(`25% `), _el$78 = _$createElement("text"), _el$79 = _$createTextNode(` 100%`), _el$82 = _$createElement("box"), _el$83 = _$createElement("box"), _el$84 = _$createElement("text"), _el$86 = _$createElement("text"), _el$88 = _$createElement("text"), _el$90 = _$createElement("text"), _el$92 = _$createElement("box"), _el$93 = _$createElement("box"), _el$94 = _$createElement("text"), _el$96 = _$createElement("box"), _el$97 = _$createElement("text"), _el$98 = _$createElement("b");
1429
- _$insertNode(_el$56, _el$57);
1430
- _$insertNode(_el$56, _el$63);
1431
- _$insertNode(_el$56, _el$74);
1432
- _$insertNode(_el$56, _el$82);
1433
- _$insertNode(_el$56, _el$93);
1434
- _$setProp(_el$56, "flexDirection", "column");
1435
- _$setProp(_el$56, "width", "100%");
1436
- _$setProp(_el$56, "paddingLeft", 2);
1437
- _$setProp(_el$56, "paddingRight", 2);
1438
- _$setProp(_el$56, "paddingTop", 1);
1439
- _$setProp(_el$56, "paddingBottom", 1);
1440
- _$insertNode(_el$57, _el$58);
1441
- _$insertNode(_el$57, _el$61);
1442
- _$setProp(_el$57, "flexDirection", "row");
1443
- _$setProp(_el$57, "justifyContent", "space-between");
1444
- _$setProp(_el$57, "width", "100%");
1445
- _$setProp(_el$57, "marginBottom", 1);
1446
- _$insertNode(_el$58, _el$59);
1447
- _$insertNode(_el$59, _$createTextNode(`Dialog size`));
1448
- _$insertNode(_el$61, _$createTextNode(`esc`));
1449
- _$setProp(_el$61, "onMouseUp", () => props.onDone(undefined));
1536
+ 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");
1450
1537
  _$insertNode(_el$63, _el$64);
1451
- _$insertNode(_el$63, _el$66);
1452
- _$insertNode(_el$63, _el$68);
1453
- _$insertNode(_el$63, _el$71);
1454
- _$setProp(_el$63, "flexDirection", "row");
1455
- _$setProp(_el$63, "gap", 0);
1538
+ _$insertNode(_el$63, _el$70);
1539
+ _$insertNode(_el$63, _el$81);
1540
+ _$insertNode(_el$63, _el$89);
1541
+ _$insertNode(_el$63, _el$100);
1542
+ _$setProp(_el$63, "flexDirection", "column");
1456
1543
  _$setProp(_el$63, "width", "100%");
1457
- _$setProp(_el$63, "marginBottom", 1);
1458
- _$insertNode(_el$64, _$createTextNode(`Width: `));
1459
- _$insertNode(_el$66, _el$67);
1460
- _$insert(_el$67, () => dialogSizeOf(props.api));
1461
- _$insertNode(_el$68, _el$69);
1462
- _$insertNode(_el$68, _el$70);
1463
- _$insert(_el$68, () => DIALOG_WIDTH_COLUMNS[dialogSizeOf(props.api)], _el$70);
1464
- _$insertNode(_el$71, _el$72);
1465
- _$insertNode(_el$72, _el$73);
1466
- _$insert(_el$72, height, _el$73);
1467
- _$insertNode(_el$74, _el$75);
1468
- _$insertNode(_el$74, _el$78);
1469
- _$setProp(_el$74, "flexDirection", "row");
1470
- _$setProp(_el$74, "width", "100%");
1471
- _$setProp(_el$74, "marginBottom", 1);
1544
+ _$setProp(_el$63, "paddingLeft", 2);
1545
+ _$setProp(_el$63, "paddingRight", 2);
1546
+ _$setProp(_el$63, "paddingTop", 1);
1547
+ _$setProp(_el$63, "paddingBottom", 1);
1548
+ _$insertNode(_el$64, _el$65);
1549
+ _$insertNode(_el$64, _el$68);
1550
+ _$setProp(_el$64, "flexDirection", "row");
1551
+ _$setProp(_el$64, "justifyContent", "space-between");
1552
+ _$setProp(_el$64, "width", "100%");
1553
+ _$setProp(_el$64, "marginBottom", 1);
1554
+ _$insertNode(_el$65, _el$66);
1555
+ _$insertNode(_el$66, _$createTextNode(`Dialog size`));
1556
+ _$insertNode(_el$68, _$createTextNode(`esc`));
1557
+ _$setProp(_el$68, "onMouseUp", () => props.onDone(undefined));
1558
+ _$insertNode(_el$70, _el$71);
1559
+ _$insertNode(_el$70, _el$73);
1560
+ _$insertNode(_el$70, _el$75);
1561
+ _$insertNode(_el$70, _el$78);
1562
+ _$setProp(_el$70, "flexDirection", "row");
1563
+ _$setProp(_el$70, "gap", 0);
1564
+ _$setProp(_el$70, "width", "100%");
1565
+ _$setProp(_el$70, "marginBottom", 1);
1566
+ _$insertNode(_el$71, _$createTextNode(`Width: `));
1567
+ _$insertNode(_el$73, _el$74);
1568
+ _$insert(_el$74, () => dialogSizeOf(props.api));
1472
1569
  _$insertNode(_el$75, _el$76);
1473
- _$insert(_el$74, _$createComponent(For, {
1570
+ _$insertNode(_el$75, _el$77);
1571
+ _$insert(_el$75, () => DIALOG_WIDTH_COLUMNS[dialogSizeOf(props.api)], _el$77);
1572
+ _$insertNode(_el$78, _el$79);
1573
+ _$insertNode(_el$79, _el$80);
1574
+ _$insert(_el$79, height, _el$80);
1575
+ _$insertNode(_el$81, _el$82);
1576
+ _$insertNode(_el$81, _el$85);
1577
+ _$setProp(_el$81, "flexDirection", "row");
1578
+ _$setProp(_el$81, "width", "100%");
1579
+ _$setProp(_el$81, "marginBottom", 1);
1580
+ _$insertNode(_el$82, _el$83);
1581
+ _$insert(_el$81, _$createComponent(For, {
1474
1582
  get each() {
1475
1583
  return sliderCells();
1476
1584
  },
1477
1585
  children: (cell) => (() => {
1478
- var _el$100 = _$createElement("text");
1479
- _$insert(_el$100, () => cell.char);
1480
- _$effect((_$p) => _$setProp(_el$100, "fg", cell.color, _$p));
1481
- return _el$100;
1586
+ var _el$107 = _$createElement("text");
1587
+ _$insert(_el$107, () => cell.char);
1588
+ _$effect((_$p) => _$setProp(_el$107, "fg", cell.color, _$p));
1589
+ return _el$107;
1482
1590
  })()
1483
- }), _el$78);
1484
- _$insertNode(_el$78, _el$79);
1485
- _$insertNode(_el$82, _el$83);
1486
- _$insertNode(_el$82, _el$92);
1487
- _$setProp(_el$82, "flexDirection", "row");
1488
- _$setProp(_el$82, "gap", 2);
1489
- _$setProp(_el$82, "marginBottom", 1);
1490
- _$insertNode(_el$83, _el$84);
1491
- _$insertNode(_el$83, _el$86);
1492
- _$insertNode(_el$83, _el$88);
1493
- _$insertNode(_el$83, _el$90);
1494
- _$setProp(_el$83, "flexDirection", "column");
1495
- _$setProp(_el$83, "gap", 0);
1496
- _$insert(_el$83, _$createComponent(For, {
1591
+ }), _el$85);
1592
+ _$insertNode(_el$85, _el$86);
1593
+ _$insertNode(_el$89, _el$90);
1594
+ _$insertNode(_el$89, _el$99);
1595
+ _$setProp(_el$89, "flexDirection", "row");
1596
+ _$setProp(_el$89, "gap", 2);
1597
+ _$setProp(_el$89, "marginBottom", 1);
1598
+ _$insertNode(_el$90, _el$91);
1599
+ _$insertNode(_el$90, _el$93);
1600
+ _$insertNode(_el$90, _el$95);
1601
+ _$insertNode(_el$90, _el$97);
1602
+ _$setProp(_el$90, "flexDirection", "column");
1603
+ _$setProp(_el$90, "gap", 0);
1604
+ _$insert(_el$90, _$createComponent(For, {
1497
1605
  each: HEIGHT_PRESETS,
1498
1606
  children: (preset) => (() => {
1499
- var _el$101 = _$createElement("text"), _el$102 = _$createTextNode(` `), _el$103 = _$createTextNode(`: `), _el$104 = _$createTextNode(`%`);
1500
- _$insertNode(_el$101, _el$102);
1501
- _$insertNode(_el$101, _el$103);
1502
- _$insertNode(_el$101, _el$104);
1503
- _$insert(_el$101, () => preset.key, _el$102);
1504
- _$insert(_el$101, () => preset.label, _el$103);
1505
- _$insert(_el$101, () => preset.value, _el$104);
1506
- _$effect((_$p) => _$setProp(_el$101, "fg", height() === preset.value ? theme().primary : theme().textMuted, _$p));
1507
- return _el$101;
1607
+ var _el$108 = _$createElement("text"), _el$109 = _$createTextNode(` `), _el$110 = _$createTextNode(`: `), _el$111 = _$createTextNode(`%`);
1608
+ _$insertNode(_el$108, _el$109);
1609
+ _$insertNode(_el$108, _el$110);
1610
+ _$insertNode(_el$108, _el$111);
1611
+ _$insert(_el$108, () => preset.key, _el$109);
1612
+ _$insert(_el$108, () => preset.label, _el$110);
1613
+ _$insert(_el$108, () => preset.value, _el$111);
1614
+ _$effect((_$p) => _$setProp(_el$108, "fg", height() === preset.value ? theme().primary : theme().textMuted, _$p));
1615
+ return _el$108;
1508
1616
  })()
1509
- }), _el$84);
1510
- _$insertNode(_el$84, _$createTextNode(` `));
1511
- _$insertNode(_el$86, _$createTextNode(`left/right 1%`));
1512
- _$insertNode(_el$88, _$createTextNode(`up/down 5%`));
1513
- _$insertNode(_el$90, _$createTextNode(`c custom`));
1514
- _$setProp(_el$92, "flexDirection", "column");
1515
- _$setProp(_el$92, "gap", 0);
1516
- _$insert(_el$92, _$createComponent(For, {
1617
+ }), _el$91);
1618
+ _$insertNode(_el$91, _$createTextNode(` `));
1619
+ _$insertNode(_el$93, _$createTextNode(`left/right 1%`));
1620
+ _$insertNode(_el$95, _$createTextNode(`up/down 5%`));
1621
+ _$insertNode(_el$97, _$createTextNode(`c custom`));
1622
+ _$setProp(_el$99, "flexDirection", "column");
1623
+ _$setProp(_el$99, "gap", 0);
1624
+ _$insert(_el$99, _$createComponent(For, {
1517
1625
  get each() {
1518
1626
  return preview();
1519
1627
  },
1520
1628
  children: (line) => (() => {
1521
- var _el$105 = _$createElement("text");
1522
- _$insert(_el$105, line);
1523
- _$effect((_$p) => _$setProp(_el$105, "fg", theme().textMuted, _$p));
1524
- return _el$105;
1629
+ var _el$112 = _$createElement("text");
1630
+ _$insert(_el$112, line);
1631
+ _$effect((_$p) => _$setProp(_el$112, "fg", theme().textMuted, _$p));
1632
+ return _el$112;
1525
1633
  })()
1526
1634
  }));
1527
- _$insertNode(_el$93, _el$94);
1528
- _$insertNode(_el$93, _el$96);
1529
- _$setProp(_el$93, "flexDirection", "row");
1530
- _$setProp(_el$93, "justifyContent", "space-between");
1531
- _$setProp(_el$93, "width", "100%");
1532
- _$insertNode(_el$94, _$createTextNode(`enter save`));
1533
- _$insertNode(_el$96, _el$97);
1534
- _$setProp(_el$96, "paddingLeft", 3);
1535
- _$setProp(_el$96, "paddingRight", 3);
1536
- _$setProp(_el$96, "onMouseUp", () => {
1635
+ _$insertNode(_el$100, _el$101);
1636
+ _$insertNode(_el$100, _el$103);
1637
+ _$setProp(_el$100, "flexDirection", "row");
1638
+ _$setProp(_el$100, "justifyContent", "space-between");
1639
+ _$setProp(_el$100, "width", "100%");
1640
+ _$insertNode(_el$101, _$createTextNode(`enter save`));
1641
+ _$insertNode(_el$103, _el$104);
1642
+ _$setProp(_el$103, "paddingLeft", 3);
1643
+ _$setProp(_el$103, "paddingRight", 3);
1644
+ _$setProp(_el$103, "onMouseUp", () => {
1537
1645
  setDialogHeightPercent(props.api, height());
1538
1646
  props.onDone({
1539
1647
  action: "save",
1540
1648
  height: height()
1541
1649
  });
1542
1650
  });
1543
- _$insertNode(_el$97, _el$98);
1544
- _$insertNode(_el$98, _$createTextNode(`save`));
1651
+ _$insertNode(_el$104, _el$105);
1652
+ _$insertNode(_el$105, _$createTextNode(`save`));
1545
1653
  _$effect((_p$) => {
1546
- var _v$24 = theme().accent, _v$25 = theme().textMuted, _v$26 = theme().textMuted, _v$27 = theme().primary, _v$28 = theme().textMuted, _v$29 = theme().primary, _v$30 = theme().textMuted, _v$31 = theme().textMuted, _v$32 = theme().textMuted, _v$33 = theme().textMuted, _v$34 = theme().textMuted, _v$35 = theme().textMuted, _v$36 = theme().textMuted, _v$37 = theme().primary, _v$38 = theme().background;
1547
- _v$24 !== _p$.e && (_p$.e = _$setProp(_el$58, "fg", _v$24, _p$.e));
1548
- _v$25 !== _p$.t && (_p$.t = _$setProp(_el$61, "fg", _v$25, _p$.t));
1549
- _v$26 !== _p$.a && (_p$.a = _$setProp(_el$64, "fg", _v$26, _p$.a));
1550
- _v$27 !== _p$.o && (_p$.o = _$setProp(_el$66, "fg", _v$27, _p$.o));
1551
- _v$28 !== _p$.i && (_p$.i = _$setProp(_el$68, "fg", _v$28, _p$.i));
1552
- _v$29 !== _p$.n && (_p$.n = _$setProp(_el$71, "fg", _v$29, _p$.n));
1553
- _v$30 !== _p$.s && (_p$.s = _$setProp(_el$75, "fg", _v$30, _p$.s));
1554
- _v$31 !== _p$.h && (_p$.h = _$setProp(_el$78, "fg", _v$31, _p$.h));
1555
- _v$32 !== _p$.r && (_p$.r = _$setProp(_el$84, "fg", _v$32, _p$.r));
1556
- _v$33 !== _p$.d && (_p$.d = _$setProp(_el$86, "fg", _v$33, _p$.d));
1557
- _v$34 !== _p$.l && (_p$.l = _$setProp(_el$88, "fg", _v$34, _p$.l));
1558
- _v$35 !== _p$.u && (_p$.u = _$setProp(_el$90, "fg", _v$35, _p$.u));
1559
- _v$36 !== _p$.c && (_p$.c = _$setProp(_el$94, "fg", _v$36, _p$.c));
1560
- _v$37 !== _p$.w && (_p$.w = _$setProp(_el$96, "backgroundColor", _v$37, _p$.w));
1561
- _v$38 !== _p$.m && (_p$.m = _$setProp(_el$97, "fg", _v$38, _p$.m));
1654
+ 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;
1655
+ _v$27 !== _p$.e && (_p$.e = _$setProp(_el$65, "fg", _v$27, _p$.e));
1656
+ _v$28 !== _p$.t && (_p$.t = _$setProp(_el$68, "fg", _v$28, _p$.t));
1657
+ _v$29 !== _p$.a && (_p$.a = _$setProp(_el$71, "fg", _v$29, _p$.a));
1658
+ _v$30 !== _p$.o && (_p$.o = _$setProp(_el$73, "fg", _v$30, _p$.o));
1659
+ _v$31 !== _p$.i && (_p$.i = _$setProp(_el$75, "fg", _v$31, _p$.i));
1660
+ _v$32 !== _p$.n && (_p$.n = _$setProp(_el$78, "fg", _v$32, _p$.n));
1661
+ _v$33 !== _p$.s && (_p$.s = _$setProp(_el$82, "fg", _v$33, _p$.s));
1662
+ _v$34 !== _p$.h && (_p$.h = _$setProp(_el$85, "fg", _v$34, _p$.h));
1663
+ _v$35 !== _p$.r && (_p$.r = _$setProp(_el$91, "fg", _v$35, _p$.r));
1664
+ _v$36 !== _p$.d && (_p$.d = _$setProp(_el$93, "fg", _v$36, _p$.d));
1665
+ _v$37 !== _p$.l && (_p$.l = _$setProp(_el$95, "fg", _v$37, _p$.l));
1666
+ _v$38 !== _p$.u && (_p$.u = _$setProp(_el$97, "fg", _v$38, _p$.u));
1667
+ _v$39 !== _p$.c && (_p$.c = _$setProp(_el$101, "fg", _v$39, _p$.c));
1668
+ _v$40 !== _p$.w && (_p$.w = _$setProp(_el$103, "backgroundColor", _v$40, _p$.w));
1669
+ _v$41 !== _p$.m && (_p$.m = _$setProp(_el$104, "fg", _v$41, _p$.m));
1562
1670
  return _p$;
1563
1671
  }, {
1564
1672
  e: undefined,
@@ -1577,7 +1685,7 @@ function SizeSliderDialog(props) {
1577
1685
  w: undefined,
1578
1686
  m: undefined
1579
1687
  });
1580
- return _el$56;
1688
+ return _el$63;
1581
1689
  })();
1582
1690
  }
1583
1691
  async function mainMenu(api) {
@@ -1643,7 +1751,7 @@ The host client does not expose session.list for this directory.`
1643
1751
  continue;
1644
1752
  }
1645
1753
  if (action.type === "cleanup") {
1646
- await runCleanup(api, cleanupTargets(tree, data.activeIDs), rootSession?.title ?? rootID);
1754
+ await runCleanup(api, cleanupTargets(tree, data.activeIDs), rootSession?.title ?? rootID, directory, rootID);
1647
1755
  continue;
1648
1756
  }
1649
1757
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mirrowel/opencode-subagent-explorer",
3
- "version": "0.2.0-dev.1",
3
+ "version": "0.2.0-dev.3",
4
4
  "type": "module",
5
5
  "description": "OpenCode plugin for exploring and cleaning up subagent sessions of the current session",
6
6
  "license": "MIT",