@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/tui.js CHANGED
@@ -108,16 +108,17 @@ function normalizeSession(raw) {
108
108
  updated: toMillis(time.updated ?? record.time_updated)
109
109
  };
110
110
  }
111
+ var SESSION_LIST_LIMIT = 5000;
111
112
  async function fetchSessions(client, directory) {
112
113
  const namespace = client?.session;
113
114
  if (!namespace?.list)
114
115
  return;
115
116
  const calls = [
116
- () => namespace.list({ directory }),
117
- () => namespace.list({ query: { directory } })
117
+ () => namespace.list({ directory, limit: SESSION_LIST_LIMIT }),
118
+ () => namespace.list({ query: { directory, limit: SESSION_LIST_LIMIT } })
118
119
  ];
119
120
  for (const call of calls) {
120
- const result = unwrap(await withTimeout(call));
121
+ const result = unwrap(await withTimeout(call, 8000));
121
122
  if (Array.isArray(result))
122
123
  return result.map(normalizeSession).filter((s) => !!s);
123
124
  }
@@ -170,6 +171,8 @@ function loadAvSidecar(globalConfigDir) {
170
171
  function stripJsoncComments(text) {
171
172
  return text.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:"'\\])\/\/.*$/gm, "$1").replace(/,(\s*[}\]])/g, "$1");
172
173
  }
174
+ var ATTRIBUTION_PAGE_SIZE = 100;
175
+ var ATTRIBUTION_PAGES = 5;
173
176
  async function fetchVariantAttribution(client, parentSessionID, directory, avParents) {
174
177
  const map = new Map;
175
178
  if (avParents.size === 0 || !parentSessionID)
@@ -177,29 +180,57 @@ async function fetchVariantAttribution(client, parentSessionID, directory, avPar
177
180
  const namespace = client?.session;
178
181
  if (!namespace || typeof namespace.messages !== "function")
179
182
  return map;
180
- const messages = await withTimeout(() => {
181
- const flat = namespace.messages({ sessionID: parentSessionID, directory, limit: 50 });
182
- return flat instanceof Promise ? flat : namespace.messages({ path: { id: parentSessionID }, query: { directory, limit: 50 } });
183
- });
184
- const list = Array.isArray(messages) ? messages : messages && typeof messages === "object" ? messages.data ?? messages : undefined;
185
- if (!Array.isArray(list))
186
- return map;
187
- for (const message of list) {
188
- for (const part of message.parts ?? []) {
189
- if (part?.type !== "tool" || part.tool !== "task")
190
- continue;
191
- const metadata = part.state?.metadata;
192
- const child = metadata?.sessionId;
193
- const variantMeta = metadata?.agentVariants;
194
- const alias = variantMeta?.alias;
195
- const routedAgent = variantMeta?.routedAgent;
196
- if (typeof child === "string" && typeof alias === "string" && !map.has(child)) {
197
- map.set(child, {
198
- alias,
199
- parent: typeof routedAgent === "string" ? routedAgent : alias.replace(/-[a-z0-9-]+$/, "")
200
- });
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 description = part.state?.input?.description;
215
+ const descriptionMatch = typeof description === "string" ? description.match(/\s+\(@(\S+) variant\)$/) : undefined;
216
+ const alias = (typeof variantMeta?.alias === "string" ? variantMeta.alias : undefined) ?? descriptionMatch?.[1];
217
+ const routedAgent = variantMeta?.routedAgent;
218
+ if (typeof child === "string" && typeof alias === "string" && !map.has(child)) {
219
+ map.set(child, {
220
+ alias,
221
+ parent: typeof routedAgent === "string" ? routedAgent : alias.replace(/-[a-z0-9-]+$/, "")
222
+ });
223
+ }
201
224
  }
202
225
  }
226
+ if (list.length < ATTRIBUTION_PAGE_SIZE)
227
+ break;
228
+ const last = list[list.length - 1];
229
+ const next = last?.info?.id ?? last?.id;
230
+ if (!next || seenCursors.has(next))
231
+ break;
232
+ seenCursors.add(next);
233
+ before = next;
203
234
  }
204
235
  return map;
205
236
  }
@@ -275,10 +306,18 @@ function isHiddenAgent(agent, hidden, configAgents) {
275
306
  return true;
276
307
  return !configAgents.has(agent) && !BUILTIN_AGENTS.has(agent) && !agent.startsWith("av:");
277
308
  }
309
+ function rowHidden(variant, agent, avParents, hidden, configAgents) {
310
+ if (variant)
311
+ return false;
312
+ if (agent && avParents.has(agent))
313
+ return false;
314
+ return isHiddenAgent(agent, hidden, configAgents);
315
+ }
278
316
  async function deleteSession(client, sessionID) {
279
317
  const namespace = client?.session;
280
318
  if (!namespace)
281
319
  return false;
320
+ const isErrorEnvelope = (value) => !!value && typeof value === "object" && ("error" in value) && !("data" in value);
282
321
  const shapes = [];
283
322
  if (typeof namespace.delete === "function") {
284
323
  shapes.push(() => namespace.delete({ sessionID }), () => namespace.delete({ path: { sessionID } }), () => namespace.delete({ path: { id: sessionID } }), () => namespace.delete({ id: sessionID }));
@@ -288,8 +327,11 @@ async function deleteSession(client, sessionID) {
288
327
  }
289
328
  for (const call of shapes) {
290
329
  const result = await withTimeout(call);
291
- if (result !== undefined)
292
- return true;
330
+ if (result === undefined)
331
+ continue;
332
+ if (isErrorEnvelope(result))
333
+ continue;
334
+ return true;
293
335
  }
294
336
  return false;
295
337
  }
@@ -394,11 +436,12 @@ function explorerRows(tree, data) {
394
436
  const walk = (nodes, depth) => {
395
437
  for (const node of nodes) {
396
438
  const variant = data.variantOf.get(node.session.id);
439
+ const agent = node.session.agent;
397
440
  rows.push({
398
441
  session: node.session,
399
442
  depth,
400
443
  running: data.activeIDs?.has(node.session.id) ?? false,
401
- hidden: variant ? false : isHiddenAgent(node.session.agent, data.hidden, data.configAgents),
444
+ hidden: rowHidden(variant, agent, data.avParents, data.hidden, data.configAgents),
402
445
  variant
403
446
  });
404
447
  walk(node.children, depth + 1);
@@ -1131,7 +1174,50 @@ Deleting a session permanently removes it, its messages, and its history. The pa
1131
1174
  });
1132
1175
  return ok;
1133
1176
  }
1134
- async function runCleanup(api, plan, rootTitle) {
1177
+ function CleanupProgressDialog(props) {
1178
+ const theme = () => themeOf(props.api);
1179
+ const popMode = props.api.mode.push("subagent-explorer.cleanup");
1180
+ onCleanup(() => popMode());
1181
+ const done = props.done;
1182
+ const total = props.total;
1183
+ return (() => {
1184
+ var _el$56 = _$createElement("box"), _el$57 = _$createElement("text"), _el$58 = _$createElement("b"), _el$60 = _$createElement("text"), _el$61 = _$createElement("text");
1185
+ _$insertNode(_el$56, _el$57);
1186
+ _$insertNode(_el$56, _el$60);
1187
+ _$insertNode(_el$56, _el$61);
1188
+ _$setProp(_el$56, "flexDirection", "column");
1189
+ _$setProp(_el$56, "width", "100%");
1190
+ _$setProp(_el$56, "paddingLeft", 2);
1191
+ _$setProp(_el$56, "paddingRight", 2);
1192
+ _$setProp(_el$56, "paddingTop", 2);
1193
+ _$setProp(_el$56, "paddingBottom", 2);
1194
+ _$setProp(_el$56, "gap", 1);
1195
+ _$insertNode(_el$57, _el$58);
1196
+ _$insertNode(_el$58, _$createTextNode(`Cleaning up idle subagent sessions\u2026`));
1197
+ _$insert(_el$60, () => `${done()} / ${total} deleted`);
1198
+ _$insertNode(_el$61, _$createTextNode(`This dialog closes when the batch finishes.`));
1199
+ _$effect((_p$) => {
1200
+ var _v$24 = theme().text, _v$25 = theme().textMuted, _v$26 = theme().textMuted;
1201
+ _v$24 !== _p$.e && (_p$.e = _$setProp(_el$57, "fg", _v$24, _p$.e));
1202
+ _v$25 !== _p$.t && (_p$.t = _$setProp(_el$60, "fg", _v$25, _p$.t));
1203
+ _v$26 !== _p$.a && (_p$.a = _$setProp(_el$61, "fg", _v$26, _p$.a));
1204
+ return _p$;
1205
+ }, {
1206
+ e: undefined,
1207
+ t: undefined,
1208
+ a: undefined
1209
+ });
1210
+ return _el$56;
1211
+ })();
1212
+ }
1213
+ function showCleanupProgress(api, done, total) {
1214
+ api.ui.dialog.replace(() => _$createComponent(CleanupProgressDialog, {
1215
+ api,
1216
+ done,
1217
+ total
1218
+ }), () => {});
1219
+ }
1220
+ async function runCleanup(api, plan, rootTitle, directory, rootID) {
1135
1221
  if (plan.deletable.length === 0) {
1136
1222
  await showInfo(api, {
1137
1223
  title: "Nothing to clean up",
@@ -1150,18 +1236,40 @@ ${plan.sparedActive.length} running session(s) will be spared.` : "";
1150
1236
  if (!confirmed)
1151
1237
  return 0;
1152
1238
  let deleted = 0;
1239
+ const [progressDone, setProgressDone] = createSignal(0);
1240
+ showCleanupProgress(api, progressDone, plan.deletable.length);
1153
1241
  for (const session of plan.deletable) {
1154
- if (await deleteSession(api.client, session.id))
1242
+ if (await deleteSession(api.client, session.id)) {
1155
1243
  deleted += 1;
1244
+ setProgressDone(deleted);
1245
+ }
1156
1246
  }
1247
+ const remainingIdle = await remainingIdleCount(api, directory, rootID);
1248
+ api.ui.dialog.clear();
1157
1249
  const failed = plan.deletable.length - deleted;
1158
1250
  api.ui.toast({
1159
- variant: failed > 0 ? "warning" : "default",
1251
+ variant: failed > 0 || remainingIdle > 0 ? "warning" : "default",
1160
1252
  title: "Cleanup finished",
1161
- message: failed > 0 ? `Deleted ${deleted}, failed ${failed}.` : `Deleted ${deleted} session(s).`
1253
+ 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).`
1162
1254
  });
1163
1255
  return deleted;
1164
1256
  }
1257
+ async function remainingIdleCount(api, directory, rootID) {
1258
+ const sessions = await fetchSessions(api.client, directory);
1259
+ if (!sessions)
1260
+ return 0;
1261
+ const active = await fetchActiveSessionIDs(api.client);
1262
+ const rows = explorerRows(buildSessionTree(sessions, rootID), {
1263
+ sessions,
1264
+ activeIDs: active,
1265
+ activeKnown: active !== undefined,
1266
+ hidden: new Set,
1267
+ configAgents: new Set,
1268
+ variantOf: new Map,
1269
+ avParents: new Map
1270
+ });
1271
+ return rows.filter((row) => !row.running).length;
1272
+ }
1165
1273
  function showRootPicker(api, sessions, currentRoot) {
1166
1274
  return new Promise((resolve) => {
1167
1275
  let settled = false;
@@ -1478,140 +1586,140 @@ function SizeSliderDialog(props) {
1478
1586
  popMode();
1479
1587
  });
1480
1588
  return (() => {
1481
- 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");
1482
- _$insertNode(_el$56, _el$57);
1483
- _$insertNode(_el$56, _el$63);
1484
- _$insertNode(_el$56, _el$74);
1485
- _$insertNode(_el$56, _el$82);
1486
- _$insertNode(_el$56, _el$93);
1487
- _$setProp(_el$56, "flexDirection", "column");
1488
- _$setProp(_el$56, "width", "100%");
1489
- _$setProp(_el$56, "paddingLeft", 2);
1490
- _$setProp(_el$56, "paddingRight", 2);
1491
- _$setProp(_el$56, "paddingTop", 1);
1492
- _$setProp(_el$56, "paddingBottom", 1);
1493
- _$insertNode(_el$57, _el$58);
1494
- _$insertNode(_el$57, _el$61);
1495
- _$setProp(_el$57, "flexDirection", "row");
1496
- _$setProp(_el$57, "justifyContent", "space-between");
1497
- _$setProp(_el$57, "width", "100%");
1498
- _$setProp(_el$57, "marginBottom", 1);
1499
- _$insertNode(_el$58, _el$59);
1500
- _$insertNode(_el$59, _$createTextNode(`Dialog size`));
1501
- _$insertNode(_el$61, _$createTextNode(`esc`));
1502
- _$setProp(_el$61, "onMouseUp", () => props.onDone(undefined));
1589
+ 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");
1503
1590
  _$insertNode(_el$63, _el$64);
1504
- _$insertNode(_el$63, _el$66);
1505
- _$insertNode(_el$63, _el$68);
1506
- _$insertNode(_el$63, _el$71);
1507
- _$setProp(_el$63, "flexDirection", "row");
1508
- _$setProp(_el$63, "gap", 0);
1591
+ _$insertNode(_el$63, _el$70);
1592
+ _$insertNode(_el$63, _el$81);
1593
+ _$insertNode(_el$63, _el$89);
1594
+ _$insertNode(_el$63, _el$100);
1595
+ _$setProp(_el$63, "flexDirection", "column");
1509
1596
  _$setProp(_el$63, "width", "100%");
1510
- _$setProp(_el$63, "marginBottom", 1);
1511
- _$insertNode(_el$64, _$createTextNode(`Width: `));
1512
- _$insertNode(_el$66, _el$67);
1513
- _$insert(_el$67, () => dialogSizeOf(props.api));
1514
- _$insertNode(_el$68, _el$69);
1515
- _$insertNode(_el$68, _el$70);
1516
- _$insert(_el$68, () => DIALOG_WIDTH_COLUMNS[dialogSizeOf(props.api)], _el$70);
1517
- _$insertNode(_el$71, _el$72);
1518
- _$insertNode(_el$72, _el$73);
1519
- _$insert(_el$72, height, _el$73);
1520
- _$insertNode(_el$74, _el$75);
1521
- _$insertNode(_el$74, _el$78);
1522
- _$setProp(_el$74, "flexDirection", "row");
1523
- _$setProp(_el$74, "width", "100%");
1524
- _$setProp(_el$74, "marginBottom", 1);
1597
+ _$setProp(_el$63, "paddingLeft", 2);
1598
+ _$setProp(_el$63, "paddingRight", 2);
1599
+ _$setProp(_el$63, "paddingTop", 1);
1600
+ _$setProp(_el$63, "paddingBottom", 1);
1601
+ _$insertNode(_el$64, _el$65);
1602
+ _$insertNode(_el$64, _el$68);
1603
+ _$setProp(_el$64, "flexDirection", "row");
1604
+ _$setProp(_el$64, "justifyContent", "space-between");
1605
+ _$setProp(_el$64, "width", "100%");
1606
+ _$setProp(_el$64, "marginBottom", 1);
1607
+ _$insertNode(_el$65, _el$66);
1608
+ _$insertNode(_el$66, _$createTextNode(`Dialog size`));
1609
+ _$insertNode(_el$68, _$createTextNode(`esc`));
1610
+ _$setProp(_el$68, "onMouseUp", () => props.onDone(undefined));
1611
+ _$insertNode(_el$70, _el$71);
1612
+ _$insertNode(_el$70, _el$73);
1613
+ _$insertNode(_el$70, _el$75);
1614
+ _$insertNode(_el$70, _el$78);
1615
+ _$setProp(_el$70, "flexDirection", "row");
1616
+ _$setProp(_el$70, "gap", 0);
1617
+ _$setProp(_el$70, "width", "100%");
1618
+ _$setProp(_el$70, "marginBottom", 1);
1619
+ _$insertNode(_el$71, _$createTextNode(`Width: `));
1620
+ _$insertNode(_el$73, _el$74);
1621
+ _$insert(_el$74, () => dialogSizeOf(props.api));
1525
1622
  _$insertNode(_el$75, _el$76);
1526
- _$insert(_el$74, _$createComponent(For, {
1623
+ _$insertNode(_el$75, _el$77);
1624
+ _$insert(_el$75, () => DIALOG_WIDTH_COLUMNS[dialogSizeOf(props.api)], _el$77);
1625
+ _$insertNode(_el$78, _el$79);
1626
+ _$insertNode(_el$79, _el$80);
1627
+ _$insert(_el$79, height, _el$80);
1628
+ _$insertNode(_el$81, _el$82);
1629
+ _$insertNode(_el$81, _el$85);
1630
+ _$setProp(_el$81, "flexDirection", "row");
1631
+ _$setProp(_el$81, "width", "100%");
1632
+ _$setProp(_el$81, "marginBottom", 1);
1633
+ _$insertNode(_el$82, _el$83);
1634
+ _$insert(_el$81, _$createComponent(For, {
1527
1635
  get each() {
1528
1636
  return sliderCells();
1529
1637
  },
1530
1638
  children: (cell) => (() => {
1531
- var _el$100 = _$createElement("text");
1532
- _$insert(_el$100, () => cell.char);
1533
- _$effect((_$p) => _$setProp(_el$100, "fg", cell.color, _$p));
1534
- return _el$100;
1639
+ var _el$107 = _$createElement("text");
1640
+ _$insert(_el$107, () => cell.char);
1641
+ _$effect((_$p) => _$setProp(_el$107, "fg", cell.color, _$p));
1642
+ return _el$107;
1535
1643
  })()
1536
- }), _el$78);
1537
- _$insertNode(_el$78, _el$79);
1538
- _$insertNode(_el$82, _el$83);
1539
- _$insertNode(_el$82, _el$92);
1540
- _$setProp(_el$82, "flexDirection", "row");
1541
- _$setProp(_el$82, "gap", 2);
1542
- _$setProp(_el$82, "marginBottom", 1);
1543
- _$insertNode(_el$83, _el$84);
1544
- _$insertNode(_el$83, _el$86);
1545
- _$insertNode(_el$83, _el$88);
1546
- _$insertNode(_el$83, _el$90);
1547
- _$setProp(_el$83, "flexDirection", "column");
1548
- _$setProp(_el$83, "gap", 0);
1549
- _$insert(_el$83, _$createComponent(For, {
1644
+ }), _el$85);
1645
+ _$insertNode(_el$85, _el$86);
1646
+ _$insertNode(_el$89, _el$90);
1647
+ _$insertNode(_el$89, _el$99);
1648
+ _$setProp(_el$89, "flexDirection", "row");
1649
+ _$setProp(_el$89, "gap", 2);
1650
+ _$setProp(_el$89, "marginBottom", 1);
1651
+ _$insertNode(_el$90, _el$91);
1652
+ _$insertNode(_el$90, _el$93);
1653
+ _$insertNode(_el$90, _el$95);
1654
+ _$insertNode(_el$90, _el$97);
1655
+ _$setProp(_el$90, "flexDirection", "column");
1656
+ _$setProp(_el$90, "gap", 0);
1657
+ _$insert(_el$90, _$createComponent(For, {
1550
1658
  each: HEIGHT_PRESETS,
1551
1659
  children: (preset) => (() => {
1552
- var _el$101 = _$createElement("text"), _el$102 = _$createTextNode(` `), _el$103 = _$createTextNode(`: `), _el$104 = _$createTextNode(`%`);
1553
- _$insertNode(_el$101, _el$102);
1554
- _$insertNode(_el$101, _el$103);
1555
- _$insertNode(_el$101, _el$104);
1556
- _$insert(_el$101, () => preset.key, _el$102);
1557
- _$insert(_el$101, () => preset.label, _el$103);
1558
- _$insert(_el$101, () => preset.value, _el$104);
1559
- _$effect((_$p) => _$setProp(_el$101, "fg", height() === preset.value ? theme().primary : theme().textMuted, _$p));
1560
- return _el$101;
1660
+ var _el$108 = _$createElement("text"), _el$109 = _$createTextNode(` `), _el$110 = _$createTextNode(`: `), _el$111 = _$createTextNode(`%`);
1661
+ _$insertNode(_el$108, _el$109);
1662
+ _$insertNode(_el$108, _el$110);
1663
+ _$insertNode(_el$108, _el$111);
1664
+ _$insert(_el$108, () => preset.key, _el$109);
1665
+ _$insert(_el$108, () => preset.label, _el$110);
1666
+ _$insert(_el$108, () => preset.value, _el$111);
1667
+ _$effect((_$p) => _$setProp(_el$108, "fg", height() === preset.value ? theme().primary : theme().textMuted, _$p));
1668
+ return _el$108;
1561
1669
  })()
1562
- }), _el$84);
1563
- _$insertNode(_el$84, _$createTextNode(` `));
1564
- _$insertNode(_el$86, _$createTextNode(`left/right 1%`));
1565
- _$insertNode(_el$88, _$createTextNode(`up/down 5%`));
1566
- _$insertNode(_el$90, _$createTextNode(`c custom`));
1567
- _$setProp(_el$92, "flexDirection", "column");
1568
- _$setProp(_el$92, "gap", 0);
1569
- _$insert(_el$92, _$createComponent(For, {
1670
+ }), _el$91);
1671
+ _$insertNode(_el$91, _$createTextNode(` `));
1672
+ _$insertNode(_el$93, _$createTextNode(`left/right 1%`));
1673
+ _$insertNode(_el$95, _$createTextNode(`up/down 5%`));
1674
+ _$insertNode(_el$97, _$createTextNode(`c custom`));
1675
+ _$setProp(_el$99, "flexDirection", "column");
1676
+ _$setProp(_el$99, "gap", 0);
1677
+ _$insert(_el$99, _$createComponent(For, {
1570
1678
  get each() {
1571
1679
  return preview();
1572
1680
  },
1573
1681
  children: (line) => (() => {
1574
- var _el$105 = _$createElement("text");
1575
- _$insert(_el$105, line);
1576
- _$effect((_$p) => _$setProp(_el$105, "fg", theme().textMuted, _$p));
1577
- return _el$105;
1682
+ var _el$112 = _$createElement("text");
1683
+ _$insert(_el$112, line);
1684
+ _$effect((_$p) => _$setProp(_el$112, "fg", theme().textMuted, _$p));
1685
+ return _el$112;
1578
1686
  })()
1579
1687
  }));
1580
- _$insertNode(_el$93, _el$94);
1581
- _$insertNode(_el$93, _el$96);
1582
- _$setProp(_el$93, "flexDirection", "row");
1583
- _$setProp(_el$93, "justifyContent", "space-between");
1584
- _$setProp(_el$93, "width", "100%");
1585
- _$insertNode(_el$94, _$createTextNode(`enter save`));
1586
- _$insertNode(_el$96, _el$97);
1587
- _$setProp(_el$96, "paddingLeft", 3);
1588
- _$setProp(_el$96, "paddingRight", 3);
1589
- _$setProp(_el$96, "onMouseUp", () => {
1688
+ _$insertNode(_el$100, _el$101);
1689
+ _$insertNode(_el$100, _el$103);
1690
+ _$setProp(_el$100, "flexDirection", "row");
1691
+ _$setProp(_el$100, "justifyContent", "space-between");
1692
+ _$setProp(_el$100, "width", "100%");
1693
+ _$insertNode(_el$101, _$createTextNode(`enter save`));
1694
+ _$insertNode(_el$103, _el$104);
1695
+ _$setProp(_el$103, "paddingLeft", 3);
1696
+ _$setProp(_el$103, "paddingRight", 3);
1697
+ _$setProp(_el$103, "onMouseUp", () => {
1590
1698
  setDialogHeightPercent(props.api, height());
1591
1699
  props.onDone({
1592
1700
  action: "save",
1593
1701
  height: height()
1594
1702
  });
1595
1703
  });
1596
- _$insertNode(_el$97, _el$98);
1597
- _$insertNode(_el$98, _$createTextNode(`save`));
1704
+ _$insertNode(_el$104, _el$105);
1705
+ _$insertNode(_el$105, _$createTextNode(`save`));
1598
1706
  _$effect((_p$) => {
1599
- 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;
1600
- _v$24 !== _p$.e && (_p$.e = _$setProp(_el$58, "fg", _v$24, _p$.e));
1601
- _v$25 !== _p$.t && (_p$.t = _$setProp(_el$61, "fg", _v$25, _p$.t));
1602
- _v$26 !== _p$.a && (_p$.a = _$setProp(_el$64, "fg", _v$26, _p$.a));
1603
- _v$27 !== _p$.o && (_p$.o = _$setProp(_el$66, "fg", _v$27, _p$.o));
1604
- _v$28 !== _p$.i && (_p$.i = _$setProp(_el$68, "fg", _v$28, _p$.i));
1605
- _v$29 !== _p$.n && (_p$.n = _$setProp(_el$71, "fg", _v$29, _p$.n));
1606
- _v$30 !== _p$.s && (_p$.s = _$setProp(_el$75, "fg", _v$30, _p$.s));
1607
- _v$31 !== _p$.h && (_p$.h = _$setProp(_el$78, "fg", _v$31, _p$.h));
1608
- _v$32 !== _p$.r && (_p$.r = _$setProp(_el$84, "fg", _v$32, _p$.r));
1609
- _v$33 !== _p$.d && (_p$.d = _$setProp(_el$86, "fg", _v$33, _p$.d));
1610
- _v$34 !== _p$.l && (_p$.l = _$setProp(_el$88, "fg", _v$34, _p$.l));
1611
- _v$35 !== _p$.u && (_p$.u = _$setProp(_el$90, "fg", _v$35, _p$.u));
1612
- _v$36 !== _p$.c && (_p$.c = _$setProp(_el$94, "fg", _v$36, _p$.c));
1613
- _v$37 !== _p$.w && (_p$.w = _$setProp(_el$96, "backgroundColor", _v$37, _p$.w));
1614
- _v$38 !== _p$.m && (_p$.m = _$setProp(_el$97, "fg", _v$38, _p$.m));
1707
+ 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;
1708
+ _v$27 !== _p$.e && (_p$.e = _$setProp(_el$65, "fg", _v$27, _p$.e));
1709
+ _v$28 !== _p$.t && (_p$.t = _$setProp(_el$68, "fg", _v$28, _p$.t));
1710
+ _v$29 !== _p$.a && (_p$.a = _$setProp(_el$71, "fg", _v$29, _p$.a));
1711
+ _v$30 !== _p$.o && (_p$.o = _$setProp(_el$73, "fg", _v$30, _p$.o));
1712
+ _v$31 !== _p$.i && (_p$.i = _$setProp(_el$75, "fg", _v$31, _p$.i));
1713
+ _v$32 !== _p$.n && (_p$.n = _$setProp(_el$78, "fg", _v$32, _p$.n));
1714
+ _v$33 !== _p$.s && (_p$.s = _$setProp(_el$82, "fg", _v$33, _p$.s));
1715
+ _v$34 !== _p$.h && (_p$.h = _$setProp(_el$85, "fg", _v$34, _p$.h));
1716
+ _v$35 !== _p$.r && (_p$.r = _$setProp(_el$91, "fg", _v$35, _p$.r));
1717
+ _v$36 !== _p$.d && (_p$.d = _$setProp(_el$93, "fg", _v$36, _p$.d));
1718
+ _v$37 !== _p$.l && (_p$.l = _$setProp(_el$95, "fg", _v$37, _p$.l));
1719
+ _v$38 !== _p$.u && (_p$.u = _$setProp(_el$97, "fg", _v$38, _p$.u));
1720
+ _v$39 !== _p$.c && (_p$.c = _$setProp(_el$101, "fg", _v$39, _p$.c));
1721
+ _v$40 !== _p$.w && (_p$.w = _$setProp(_el$103, "backgroundColor", _v$40, _p$.w));
1722
+ _v$41 !== _p$.m && (_p$.m = _$setProp(_el$104, "fg", _v$41, _p$.m));
1615
1723
  return _p$;
1616
1724
  }, {
1617
1725
  e: undefined,
@@ -1630,7 +1738,7 @@ function SizeSliderDialog(props) {
1630
1738
  w: undefined,
1631
1739
  m: undefined
1632
1740
  });
1633
- return _el$56;
1741
+ return _el$63;
1634
1742
  })();
1635
1743
  }
1636
1744
  async function mainMenu(api) {
@@ -1696,7 +1804,7 @@ The host client does not expose session.list for this directory.`
1696
1804
  continue;
1697
1805
  }
1698
1806
  if (action.type === "cleanup") {
1699
- await runCleanup(api, cleanupTargets(tree, data.activeIDs), rootSession?.title ?? rootID);
1807
+ await runCleanup(api, cleanupTargets(tree, data.activeIDs), rootSession?.title ?? rootID, directory, rootID);
1700
1808
  continue;
1701
1809
  }
1702
1810
  }