@mirrowel/opencode-subagent-explorer 0.2.0-dev.1 → 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/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,55 @@ 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 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
+ }
201
222
  }
202
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;
203
232
  }
204
233
  return map;
205
234
  }
@@ -275,10 +304,18 @@ function isHiddenAgent(agent, hidden, configAgents) {
275
304
  return true;
276
305
  return !configAgents.has(agent) && !BUILTIN_AGENTS.has(agent) && !agent.startsWith("av:");
277
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
+ }
278
314
  async function deleteSession(client, sessionID) {
279
315
  const namespace = client?.session;
280
316
  if (!namespace)
281
317
  return false;
318
+ const isErrorEnvelope = (value) => !!value && typeof value === "object" && ("error" in value) && !("data" in value);
282
319
  const shapes = [];
283
320
  if (typeof namespace.delete === "function") {
284
321
  shapes.push(() => namespace.delete({ sessionID }), () => namespace.delete({ path: { sessionID } }), () => namespace.delete({ path: { id: sessionID } }), () => namespace.delete({ id: sessionID }));
@@ -288,8 +325,11 @@ async function deleteSession(client, sessionID) {
288
325
  }
289
326
  for (const call of shapes) {
290
327
  const result = await withTimeout(call);
291
- if (result !== undefined)
292
- return true;
328
+ if (result === undefined)
329
+ continue;
330
+ if (isErrorEnvelope(result))
331
+ continue;
332
+ return true;
293
333
  }
294
334
  return false;
295
335
  }
@@ -394,11 +434,12 @@ function explorerRows(tree, data) {
394
434
  const walk = (nodes, depth) => {
395
435
  for (const node of nodes) {
396
436
  const variant = data.variantOf.get(node.session.id);
437
+ const agent = node.session.agent;
397
438
  rows.push({
398
439
  session: node.session,
399
440
  depth,
400
441
  running: data.activeIDs?.has(node.session.id) ?? false,
401
- hidden: variant ? false : isHiddenAgent(node.session.agent, data.hidden, data.configAgents),
442
+ hidden: rowHidden(variant, agent, data.avParents, data.hidden, data.configAgents),
402
443
  variant
403
444
  });
404
445
  walk(node.children, depth + 1);
@@ -1131,7 +1172,50 @@ Deleting a session permanently removes it, its messages, and its history. The pa
1131
1172
  });
1132
1173
  return ok;
1133
1174
  }
1134
- async function runCleanup(api, plan, rootTitle) {
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) {
1135
1219
  if (plan.deletable.length === 0) {
1136
1220
  await showInfo(api, {
1137
1221
  title: "Nothing to clean up",
@@ -1150,18 +1234,40 @@ ${plan.sparedActive.length} running session(s) will be spared.` : "";
1150
1234
  if (!confirmed)
1151
1235
  return 0;
1152
1236
  let deleted = 0;
1237
+ const [progressDone, setProgressDone] = createSignal(0);
1238
+ showCleanupProgress(api, progressDone, plan.deletable.length);
1153
1239
  for (const session of plan.deletable) {
1154
- if (await deleteSession(api.client, session.id))
1240
+ if (await deleteSession(api.client, session.id)) {
1155
1241
  deleted += 1;
1242
+ setProgressDone(deleted);
1243
+ }
1156
1244
  }
1245
+ const remainingIdle = await remainingIdleCount(api, directory, rootID);
1246
+ api.ui.dialog.clear();
1157
1247
  const failed = plan.deletable.length - deleted;
1158
1248
  api.ui.toast({
1159
- variant: failed > 0 ? "warning" : "default",
1249
+ variant: failed > 0 || remainingIdle > 0 ? "warning" : "default",
1160
1250
  title: "Cleanup finished",
1161
- 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).`
1162
1252
  });
1163
1253
  return deleted;
1164
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
+ }
1165
1271
  function showRootPicker(api, sessions, currentRoot) {
1166
1272
  return new Promise((resolve) => {
1167
1273
  let settled = false;
@@ -1478,140 +1584,140 @@ function SizeSliderDialog(props) {
1478
1584
  popMode();
1479
1585
  });
1480
1586
  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));
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");
1503
1588
  _$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);
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");
1509
1594
  _$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);
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));
1525
1620
  _$insertNode(_el$75, _el$76);
1526
- _$insert(_el$74, _$createComponent(For, {
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, {
1527
1633
  get each() {
1528
1634
  return sliderCells();
1529
1635
  },
1530
1636
  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;
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;
1535
1641
  })()
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, {
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, {
1550
1656
  each: HEIGHT_PRESETS,
1551
1657
  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;
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;
1561
1667
  })()
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, {
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, {
1570
1676
  get each() {
1571
1677
  return preview();
1572
1678
  },
1573
1679
  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;
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;
1578
1684
  })()
1579
1685
  }));
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", () => {
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", () => {
1590
1696
  setDialogHeightPercent(props.api, height());
1591
1697
  props.onDone({
1592
1698
  action: "save",
1593
1699
  height: height()
1594
1700
  });
1595
1701
  });
1596
- _$insertNode(_el$97, _el$98);
1597
- _$insertNode(_el$98, _$createTextNode(`save`));
1702
+ _$insertNode(_el$104, _el$105);
1703
+ _$insertNode(_el$105, _$createTextNode(`save`));
1598
1704
  _$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));
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));
1615
1721
  return _p$;
1616
1722
  }, {
1617
1723
  e: undefined,
@@ -1630,7 +1736,7 @@ function SizeSliderDialog(props) {
1630
1736
  w: undefined,
1631
1737
  m: undefined
1632
1738
  });
1633
- return _el$56;
1739
+ return _el$63;
1634
1740
  })();
1635
1741
  }
1636
1742
  async function mainMenu(api) {
@@ -1696,7 +1802,7 @@ The host client does not expose session.list for this directory.`
1696
1802
  continue;
1697
1803
  }
1698
1804
  if (action.type === "cleanup") {
1699
- await runCleanup(api, cleanupTargets(tree, data.activeIDs), rootSession?.title ?? rootID);
1805
+ await runCleanup(api, cleanupTargets(tree, data.activeIDs), rootSession?.title ?? rootID, directory, rootID);
1700
1806
  continue;
1701
1807
  }
1702
1808
  }