@try-works/dsh-recursive-mode 0.1.10 → 0.1.12
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/lib/client/board.d.ts +0 -26
- package/lib/client/contract.d.ts +29 -0
- package/lib/client/index.d.ts +2 -2
- package/lib/client/inspector.d.ts +0 -14
- package/lib/client/slots.d.ts +3 -2
- package/lib/client/styles.d.ts +15 -0
- package/lib/client.js +506 -283
- package/package.json +1 -1
- package/src/client/board.tsx +53 -95
- package/src/client/contract.ts +48 -0
- package/src/client/index.ts +2 -2
- package/src/client/inspector.tsx +40 -49
- package/src/client/slots.ts +17 -9
- package/src/client/styles.ts +397 -0
package/lib/client.js
CHANGED
|
@@ -20,6 +20,31 @@ window.__ModuleLoader__.load({
|
|
|
20
20
|
function currentSessionCwd(state) {
|
|
21
21
|
return state.current === void 0 ? "" : state.byId[state.current]?.cwd ?? "";
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the CURRENT workspace path for a workspace-scoped board (run 14):
|
|
25
|
+
* the WORKSPACE owns the .recursive/ run-layer, not the session. Resolution:
|
|
26
|
+
* 1) recentWorkspaceId's item path (the workspace the user is viewing), else
|
|
27
|
+
* 2) the workspace whose sessionIds contains sessionList.current, else
|
|
28
|
+
* 3) the workspace whose path === currentSessionCwd(sessionList), else
|
|
29
|
+
* 4) '' (empty -> the route returns null root -> board renders nothing).
|
|
30
|
+
*/
|
|
31
|
+
function currentWorkspacePath(list, sessionList) {
|
|
32
|
+
if (list.recentWorkspaceId !== void 0) {
|
|
33
|
+
const recent = list.items.find((w) => w.workspaceId === list.recentWorkspaceId);
|
|
34
|
+
if (recent !== void 0) return recent.path;
|
|
35
|
+
}
|
|
36
|
+
const current = sessionList.current;
|
|
37
|
+
if (current !== void 0) {
|
|
38
|
+
const bySession = list.items.find((w) => w.sessionIds.includes(current));
|
|
39
|
+
if (bySession !== void 0) return bySession.path;
|
|
40
|
+
}
|
|
41
|
+
const cwd = currentSessionCwd(sessionList);
|
|
42
|
+
if (cwd !== "") {
|
|
43
|
+
const byCwd = list.items.find((w) => w.path === cwd);
|
|
44
|
+
if (byCwd !== void 0) return byCwd.path;
|
|
45
|
+
}
|
|
46
|
+
return "";
|
|
47
|
+
}
|
|
23
48
|
//#endregion
|
|
24
49
|
//#region src/client/derive.ts
|
|
25
50
|
const KANBAN_LANES = [
|
|
@@ -219,102 +244,14 @@ window.__ModuleLoader__.load({
|
|
|
219
244
|
//#endregion
|
|
220
245
|
//#region src/client/board.tsx
|
|
221
246
|
/**
|
|
222
|
-
* Board overlay (SP2 R1 + run 08 R3 + run
|
|
247
|
+
* Board overlay (SP2 R1 + run 08 R3 + run 15): the kanban view over the live
|
|
223
248
|
* host-route projection. Pure read-only renderer — no filesystem, no run-file
|
|
224
|
-
* scraping. Cards are grouped by worktree root
|
|
225
|
-
*
|
|
226
|
-
* when the snapshot is null (no recursive root / not loaded) or the current
|
|
227
|
-
* session is not on the recursive preset (the gate lives in slots.ts — here an
|
|
228
|
-
* empty projection with a null root is a no-op, not an "empty board").
|
|
249
|
+
* scraping. Cards are grouped by worktree root and mapped to their current-phase
|
|
250
|
+
* lane via derive.columnForRun.
|
|
229
251
|
*
|
|
230
|
-
* Run
|
|
231
|
-
*
|
|
232
|
-
* callback only selects a run for display; no mutation.
|
|
233
|
-
*
|
|
234
|
-
* Run 12 (LIVE BUG): shell.overlay is a click-through, unstyled frame layer —
|
|
235
|
-
* without inline styles the mounted board was INVISIBLE (no position/size/z)
|
|
236
|
-
* and CLICK-THROUGH (no pointer-events opt-in). Everything is styled inline
|
|
237
|
-
* (no CSS pipeline in the CJS client bundle): full-cover fixed overlay, opaque
|
|
238
|
-
* backdrop, pointerEvents auto, and a visible close button.
|
|
252
|
+
* Run 15 (task-board redesign): class-based structure + theme-token stylesheet
|
|
253
|
+
* injected once via styles.ts (no inline styles — unlocks hover/grid/theme).
|
|
239
254
|
*/
|
|
240
|
-
/** Full-cover overlay style — the shell.overlay seat is click-through + unstyled by default (run 12). */
|
|
241
|
-
const overlayStyle = {
|
|
242
|
-
position: "fixed",
|
|
243
|
-
inset: 0,
|
|
244
|
-
background: "rgba(15, 17, 21, 0.92)",
|
|
245
|
-
color: "#e6e6e6",
|
|
246
|
-
zIndex: 9999,
|
|
247
|
-
overflowY: "auto",
|
|
248
|
-
padding: "24px 32px",
|
|
249
|
-
pointerEvents: "auto",
|
|
250
|
-
fontFamily: "system-ui, sans-serif"
|
|
251
|
-
};
|
|
252
|
-
const laneStyle = { marginBottom: 24 };
|
|
253
|
-
const laneTitleStyle = {
|
|
254
|
-
fontSize: 14,
|
|
255
|
-
textTransform: "uppercase",
|
|
256
|
-
letterSpacing: "0.08em",
|
|
257
|
-
marginBottom: 8,
|
|
258
|
-
color: "#aaa"
|
|
259
|
-
};
|
|
260
|
-
const cardStyle = {
|
|
261
|
-
display: "inline-block",
|
|
262
|
-
width: 280,
|
|
263
|
-
margin: "0 12px 12px 0",
|
|
264
|
-
padding: 12,
|
|
265
|
-
background: "#1f2329",
|
|
266
|
-
borderRadius: 8,
|
|
267
|
-
border: "1px solid #333",
|
|
268
|
-
cursor: "pointer",
|
|
269
|
-
verticalAlign: "top"
|
|
270
|
-
};
|
|
271
|
-
const cardHeadStyle = {
|
|
272
|
-
display: "flex",
|
|
273
|
-
justifyContent: "space-between",
|
|
274
|
-
marginBottom: 8
|
|
275
|
-
};
|
|
276
|
-
const badgeStyle$1 = {
|
|
277
|
-
fontSize: 11,
|
|
278
|
-
padding: "2px 6px",
|
|
279
|
-
borderRadius: 4,
|
|
280
|
-
background: "#333"
|
|
281
|
-
};
|
|
282
|
-
const badgeTamperStyle = { background: "#7a1f1f" };
|
|
283
|
-
const progressStyle = {
|
|
284
|
-
height: 6,
|
|
285
|
-
background: "#333",
|
|
286
|
-
borderRadius: 3,
|
|
287
|
-
overflow: "hidden"
|
|
288
|
-
};
|
|
289
|
-
const progressFillStyle = {
|
|
290
|
-
background: "#4c9aff",
|
|
291
|
-
height: "100%"
|
|
292
|
-
};
|
|
293
|
-
const metaStyle = {
|
|
294
|
-
marginTop: 8,
|
|
295
|
-
fontSize: 12,
|
|
296
|
-
color: "#aaa",
|
|
297
|
-
display: "flex",
|
|
298
|
-
justifyContent: "space-between"
|
|
299
|
-
};
|
|
300
|
-
const emptyStyle = {
|
|
301
|
-
padding: 40,
|
|
302
|
-
textAlign: "center",
|
|
303
|
-
color: "#888"
|
|
304
|
-
};
|
|
305
|
-
const closeStyle$1 = {
|
|
306
|
-
position: "absolute",
|
|
307
|
-
top: 12,
|
|
308
|
-
right: 16,
|
|
309
|
-
background: "#1f2329",
|
|
310
|
-
color: "#e6e6e6",
|
|
311
|
-
border: "1px solid #444",
|
|
312
|
-
borderRadius: 6,
|
|
313
|
-
padding: "4px 12px",
|
|
314
|
-
cursor: "pointer",
|
|
315
|
-
fontSize: 16,
|
|
316
|
-
zIndex: 1
|
|
317
|
-
};
|
|
318
255
|
/** Flatten the worktree-grouped projection into a stable run list. */
|
|
319
256
|
function listRuns(projection) {
|
|
320
257
|
if (projection === void 0) return [];
|
|
@@ -322,220 +259,105 @@ window.__ModuleLoader__.load({
|
|
|
322
259
|
for (const worktreeRoot of Object.keys(projection)) for (const runId of Object.keys(projection[worktreeRoot])) runs.push(projection[worktreeRoot][runId]);
|
|
323
260
|
return runs;
|
|
324
261
|
}
|
|
262
|
+
function closeButton$1(onClose) {
|
|
263
|
+
if (onClose === void 0) return null;
|
|
264
|
+
return (0, react.createElement)("button", {
|
|
265
|
+
type: "button",
|
|
266
|
+
className: "rec-close",
|
|
267
|
+
onClick: onClose,
|
|
268
|
+
title: "Close",
|
|
269
|
+
"aria-label": "Close"
|
|
270
|
+
}, "×");
|
|
271
|
+
}
|
|
325
272
|
function Board({ snapshot, onOpenInspector, onClose }) {
|
|
326
273
|
if (snapshot === null || snapshot.root === null) return null;
|
|
327
274
|
const runs = listRuns(snapshot.projection);
|
|
328
|
-
const close = onClose !== void 0 ? (0, react.createElement)("button", {
|
|
329
|
-
className: "rec-close",
|
|
330
|
-
style: closeStyle$1,
|
|
331
|
-
onClick: onClose,
|
|
332
|
-
title: "Close"
|
|
333
|
-
}, "×") : null;
|
|
334
|
-
if (runs.length === 0) return (0, react.createElement)("div", {
|
|
335
|
-
className: "rec-board",
|
|
336
|
-
"data-empty": true,
|
|
337
|
-
style: overlayStyle
|
|
338
|
-
}, close, (0, react.createElement)("p", {
|
|
339
|
-
className: "rec-board-empty",
|
|
340
|
-
style: emptyStyle
|
|
341
|
-
}, "No recursive runs in this workspace yet."));
|
|
342
275
|
const open = (run) => () => onOpenInspector?.({
|
|
343
276
|
worktreeRoot: run.worktreeRoot,
|
|
344
277
|
runId: run.runId
|
|
345
278
|
});
|
|
346
|
-
return (0, react.createElement)("div", {
|
|
279
|
+
if (runs.length === 0) return (0, react.createElement)("div", {
|
|
347
280
|
className: "rec-board",
|
|
348
|
-
|
|
349
|
-
},
|
|
281
|
+
"data-empty": true
|
|
282
|
+
}, (0, react.createElement)("header", { className: "rec-board-header" }, (0, react.createElement)("h2", { className: "rec-board-title" }, "Recursive runs"), closeButton$1(onClose)), (0, react.createElement)("p", { className: "rec-board-empty" }, "No recursive runs in this workspace yet."));
|
|
283
|
+
return (0, react.createElement)("div", { className: "rec-board" }, (0, react.createElement)("header", { className: "rec-board-header" }, (0, react.createElement)("h2", { className: "rec-board-title" }, "Recursive runs"), (0, react.createElement)("span", { className: "rec-board-count" }, String(runs.length)), closeButton$1(onClose)), (0, react.createElement)("div", { className: "rec-columns" }, KANBAN_LANES.map((lane) => {
|
|
350
284
|
const laneRuns = runs.filter((r) => columnForRun(r) === lane.id);
|
|
351
285
|
return (0, react.createElement)("section", {
|
|
352
286
|
key: lane.id,
|
|
353
|
-
className: "rec-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
}, lane.label), laneRuns.map((run) => {
|
|
287
|
+
className: "rec-column"
|
|
288
|
+
}, (0, react.createElement)("header", { className: "rec-column-header" }, (0, react.createElement)("span", {
|
|
289
|
+
className: "rec-status-dot",
|
|
290
|
+
"data-status": laneRuns.length > 0 ? laneRuns[laneRuns.length - 1].state : "new",
|
|
291
|
+
"aria-hidden": true
|
|
292
|
+
}), (0, react.createElement)("h3", { className: "rec-column-title" }, lane.label), (0, react.createElement)("span", { className: "rec-column-count" }, String(laneRuns.length))), (0, react.createElement)("div", { className: "rec-cards" }, laneRuns.map((run) => {
|
|
359
293
|
const facts = cardFacts(run);
|
|
360
294
|
return (0, react.createElement)("article", {
|
|
361
295
|
key: run.worktreeRoot + "\0" + run.runId,
|
|
362
296
|
className: "rec-card",
|
|
363
|
-
|
|
297
|
+
"data-state": run.state,
|
|
364
298
|
onClick: open(run)
|
|
365
|
-
}, (0, react.createElement)("div", {
|
|
366
|
-
className: "rec-card-
|
|
367
|
-
style:
|
|
368
|
-
}, (0, react.createElement)("
|
|
299
|
+
}, (0, react.createElement)("div", { className: "rec-card-title" }, run.runId), (0, react.createElement)("div", { className: "rec-card-progress" }, (0, react.createElement)("div", {
|
|
300
|
+
className: "rec-card-progress-fill",
|
|
301
|
+
style: { width: Math.round(facts.progress * 100) + "%" }
|
|
302
|
+
})), (0, react.createElement)("div", { className: "rec-card-meta" }, (0, react.createElement)("span", { className: "rec-card-phase" }, facts.currentPhase ?? "no phases"), facts.tampered && (0, react.createElement)("span", {
|
|
369
303
|
className: "rec-badge rec-badge-tamper",
|
|
370
|
-
|
|
371
|
-
...badgeStyle$1,
|
|
372
|
-
...badgeTamperStyle
|
|
373
|
-
},
|
|
304
|
+
"data-status": run.state,
|
|
374
305
|
title: "tampered"
|
|
375
|
-
}, "!")
|
|
376
|
-
className: "rec-card-progress",
|
|
377
|
-
style: progressStyle
|
|
378
|
-
}, (0, react.createElement)("div", {
|
|
379
|
-
className: "rec-card-progress-fill",
|
|
380
|
-
style: {
|
|
381
|
-
...progressFillStyle,
|
|
382
|
-
width: Math.round(facts.progress * 100) + "%"
|
|
383
|
-
}
|
|
384
|
-
})), (0, react.createElement)("div", {
|
|
385
|
-
className: "rec-card-meta",
|
|
386
|
-
style: metaStyle
|
|
387
|
-
}, (0, react.createElement)("span", {}, facts.currentPhase ?? "no phases"), (0, react.createElement)("span", {
|
|
306
|
+
}, "!"), (0, react.createElement)("span", {
|
|
388
307
|
className: "rec-badge",
|
|
389
|
-
|
|
390
|
-
},
|
|
391
|
-
}));
|
|
392
|
-
}));
|
|
308
|
+
"data-status": run.state
|
|
309
|
+
}, run.state)));
|
|
310
|
+
}), laneRuns.length === 0 && (0, react.createElement)("div", { className: "rec-column-empty" }, "—")));
|
|
311
|
+
})));
|
|
393
312
|
}
|
|
394
313
|
//#endregion
|
|
395
314
|
//#region src/client/inspector.tsx
|
|
396
315
|
/**
|
|
397
|
-
* Drill-down inspector (SP2 R1 + run
|
|
398
|
-
*
|
|
399
|
-
*
|
|
400
|
-
* disk.
|
|
401
|
-
*
|
|
402
|
-
* Run 12 (LIVE BUG): same as the board — shell.overlay is click-through and
|
|
403
|
-
* unstyled, so the inspector mounts INVISIBLE + CLICK-THROUGH without inline
|
|
404
|
-
* styles. Full-cover fixed overlay + pointerEvents auto + a back button and a
|
|
405
|
-
* close button.
|
|
316
|
+
* Drill-down inspector (SP2 R1 + run 15): centered modal-style detail panel
|
|
317
|
+
* (task-board .detail shape) rendering one run's phase chain, lock badges, and
|
|
318
|
+
* tamper/gate facts — all from the live host-route snapshot, never disk.
|
|
406
319
|
*/
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
marginBottom: 16,
|
|
412
|
-
borderBottom: "1px solid #333",
|
|
413
|
-
paddingBottom: 12
|
|
414
|
-
};
|
|
415
|
-
const backStyle = {
|
|
416
|
-
background: "#1f2329",
|
|
417
|
-
color: "#e6e6e6",
|
|
418
|
-
border: "1px solid #444",
|
|
419
|
-
borderRadius: 6,
|
|
420
|
-
padding: "6px 12px",
|
|
421
|
-
cursor: "pointer"
|
|
422
|
-
};
|
|
423
|
-
const closeStyle = {
|
|
424
|
-
background: "#1f2329",
|
|
425
|
-
color: "#e6e6e6",
|
|
426
|
-
border: "1px solid #444",
|
|
427
|
-
borderRadius: 6,
|
|
428
|
-
padding: "6px 12px",
|
|
429
|
-
cursor: "pointer",
|
|
430
|
-
marginLeft: "auto"
|
|
431
|
-
};
|
|
432
|
-
const sectionStyle = { marginBottom: 16 };
|
|
433
|
-
const rowStyle = {
|
|
434
|
-
display: "flex",
|
|
435
|
-
gap: 12,
|
|
436
|
-
alignItems: "center",
|
|
437
|
-
padding: "6px 0",
|
|
438
|
-
borderBottom: "1px solid #222",
|
|
439
|
-
fontSize: 13
|
|
440
|
-
};
|
|
441
|
-
const phaseIdStyle = {
|
|
442
|
-
minWidth: 220,
|
|
443
|
-
fontFamily: "monospace",
|
|
444
|
-
color: "#4c9aff"
|
|
445
|
-
};
|
|
446
|
-
const phaseNameStyle = {
|
|
447
|
-
flex: 1,
|
|
448
|
-
color: "#ccc"
|
|
449
|
-
};
|
|
450
|
-
const badgeStyle = {
|
|
451
|
-
fontSize: 11,
|
|
452
|
-
padding: "2px 6px",
|
|
453
|
-
borderRadius: 4,
|
|
454
|
-
background: "#333"
|
|
455
|
-
};
|
|
456
|
-
const lockhashStyle = {
|
|
457
|
-
fontFamily: "monospace",
|
|
458
|
-
fontSize: 11,
|
|
459
|
-
color: "#888"
|
|
460
|
-
};
|
|
461
|
-
function Inspector({ runId, worktreeRoot, snapshot, onBackToToolDetails, onClose }) {
|
|
462
|
-
const close = onClose !== void 0 ? (0, react.createElement)("button", {
|
|
320
|
+
function closeButton(onClose) {
|
|
321
|
+
if (onClose === void 0) return null;
|
|
322
|
+
return (0, react.createElement)("button", {
|
|
323
|
+
type: "button",
|
|
463
324
|
className: "rec-close",
|
|
464
|
-
style: closeStyle,
|
|
465
325
|
onClick: onClose,
|
|
466
|
-
title: "Close"
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
className: "rec-inspector-head",
|
|
474
|
-
style: headStyle
|
|
475
|
-
}, (0, react.createElement)("button", {
|
|
476
|
-
onClick: onBackToToolDetails,
|
|
326
|
+
title: "Close",
|
|
327
|
+
"aria-label": "Close"
|
|
328
|
+
}, "×");
|
|
329
|
+
}
|
|
330
|
+
function detailShell(runId, onBackToToolDetails, onClose, headerExtra, body) {
|
|
331
|
+
return (0, react.createElement)("div", { className: "rec-inspector" }, (0, react.createElement)("div", { className: "rec-detail" }, (0, react.createElement)("div", { className: "rec-detail-header" }, (0, react.createElement)("button", {
|
|
332
|
+
type: "button",
|
|
477
333
|
className: "rec-back",
|
|
478
|
-
|
|
479
|
-
}, "←
|
|
334
|
+
onClick: onBackToToolDetails
|
|
335
|
+
}, "← Back"), (0, react.createElement)("h2", { className: "rec-detail-title" }, runId), headerExtra, closeButton(onClose)), (0, react.createElement)("div", { className: "rec-detail-body" }, body)));
|
|
336
|
+
}
|
|
337
|
+
function Inspector({ runId, worktreeRoot, snapshot, onBackToToolDetails, onClose }) {
|
|
338
|
+
const card = snapshot?.projection?.[worktreeRoot]?.[runId];
|
|
339
|
+
if (card === void 0) return detailShell(runId, onBackToToolDetails, onClose, null, (0, react.createElement)("p", { className: "rec-detail-text" }, "Run not found: " + runId));
|
|
480
340
|
const facts = cardFacts(card);
|
|
481
341
|
const rows = expandPhaseRows(card);
|
|
482
|
-
|
|
483
|
-
className: "rec-inspector",
|
|
484
|
-
style: overlayStyle
|
|
485
|
-
}, (0, react.createElement)("div", {
|
|
486
|
-
className: "rec-inspector-head",
|
|
487
|
-
style: headStyle
|
|
488
|
-
}, (0, react.createElement)("button", {
|
|
489
|
-
onClick: onBackToToolDetails,
|
|
490
|
-
className: "rec-back",
|
|
491
|
-
style: backStyle
|
|
492
|
-
}, "← back to tool details"), (0, react.createElement)("h2", { style: {
|
|
493
|
-
margin: 0,
|
|
494
|
-
fontSize: 18
|
|
495
|
-
} }, runId), (0, react.createElement)("span", {
|
|
342
|
+
const badge = (0, react.createElement)("span", {
|
|
496
343
|
className: "rec-badge",
|
|
497
|
-
|
|
498
|
-
}, facts.state)
|
|
344
|
+
"data-status": card.state
|
|
345
|
+
}, facts.state);
|
|
346
|
+
const tamper = facts.tampered ? (0, react.createElement)("span", {
|
|
499
347
|
className: "rec-badge rec-badge-tamper",
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
}, (0, react.createElement)("h3", { style: {
|
|
508
|
-
fontSize: 13,
|
|
509
|
-
textTransform: "uppercase",
|
|
510
|
-
letterSpacing: "0.08em",
|
|
511
|
-
color: "#aaa",
|
|
512
|
-
marginBottom: 8
|
|
513
|
-
} }, "Phases"), rows.map((row) => (0, react.createElement)("div", {
|
|
348
|
+
"data-status": card.state
|
|
349
|
+
}, "tampered") : null;
|
|
350
|
+
return detailShell(runId, onBackToToolDetails, onClose, (0, react.createElement)("span", { style: {
|
|
351
|
+
display: "flex",
|
|
352
|
+
alignItems: "center",
|
|
353
|
+
gap: 6
|
|
354
|
+
} }, badge, tamper), (0, react.createElement)("section", { className: "rec-detail-section" }, (0, react.createElement)("h3", {}, "Phases"), rows.map((row) => (0, react.createElement)("div", {
|
|
514
355
|
key: row.phase,
|
|
515
|
-
className: "rec-phase-row"
|
|
516
|
-
|
|
517
|
-
}, (0, react.createElement)("span", {
|
|
518
|
-
className: "rec-phase-id",
|
|
519
|
-
style: phaseIdStyle
|
|
520
|
-
}, row.phase), (0, react.createElement)("span", {
|
|
521
|
-
className: "rec-phase-name",
|
|
522
|
-
style: phaseNameStyle
|
|
523
|
-
}, row.fileName ?? "—"), (0, react.createElement)("span", {
|
|
356
|
+
className: "rec-phase-row"
|
|
357
|
+
}, (0, react.createElement)("span", { className: "rec-phase-id" }, row.phase), (0, react.createElement)("span", { className: "rec-phase-name" }, row.fileName ?? "—"), (0, react.createElement)("span", {
|
|
524
358
|
className: "rec-badge",
|
|
525
|
-
|
|
526
|
-
}, row.status), row.lockHash !== void 0 && (0, react.createElement)("code", {
|
|
527
|
-
className: "rec-lockhash",
|
|
528
|
-
style: lockhashStyle
|
|
529
|
-
}, "#" + row.lockHash.slice(0, 8))))), facts.gateBlocked && (0, react.createElement)("section", {
|
|
530
|
-
className: "rec-inspector-section",
|
|
531
|
-
style: sectionStyle
|
|
532
|
-
}, (0, react.createElement)("h3", { style: {
|
|
533
|
-
fontSize: 13,
|
|
534
|
-
textTransform: "uppercase",
|
|
535
|
-
letterSpacing: "0.08em",
|
|
536
|
-
color: "#aaa",
|
|
537
|
-
marginBottom: 8
|
|
538
|
-
} }, "Gate"), (0, react.createElement)("p", {}, "Blocked (" + (facts.gateKind ?? "") + ")")));
|
|
359
|
+
"data-status": row.status === "LOCKED" ? "complete" : "active"
|
|
360
|
+
}, row.status), row.lockHash !== void 0 && (0, react.createElement)("code", { className: "rec-lockhash" }, "#" + row.lockHash.slice(0, 8)))), facts.gateBlocked && (0, react.createElement)("div", { className: "rec-detail-section" }, (0, react.createElement)("h3", {}, "Gate"), (0, react.createElement)("p", { className: "rec-detail-text" }, "Blocked (" + (facts.gateKind ?? "") + ")"))));
|
|
539
361
|
}
|
|
540
362
|
//#endregion
|
|
541
363
|
//#region src/client/strip.tsx
|
|
@@ -741,6 +563,402 @@ window.__ModuleLoader__.load({
|
|
|
741
563
|
return (0, react.useSyncExternalStore)(store.subscribe, store.get, store.get);
|
|
742
564
|
}
|
|
743
565
|
//#endregion
|
|
566
|
+
//#region src/client/styles.ts
|
|
567
|
+
/**
|
|
568
|
+
* One-shot board/inspector stylesheet injection (run 15). The client bundle is a
|
|
569
|
+
* plain CJS closure with NO CSS pipeline (tsdown has no CSS handling), so we
|
|
570
|
+
* inject a single <style data-dsh-recursive> element into document.head and
|
|
571
|
+
* style via class names + the shell's --dsw-* theme tokens. That unlocks hover,
|
|
572
|
+
* grid layout, and light/dark/skin theme following — impossible with inline
|
|
573
|
+
* styles. Idempotent: guarded by document.querySelector, so every registration
|
|
574
|
+
* reuses the one element; the returned disposer removes it.
|
|
575
|
+
*/
|
|
576
|
+
const BOARD_CSS = `
|
|
577
|
+
/* dsh-recursive board + inspector (theme-token driven, .rec-* scoped) */
|
|
578
|
+
.rec-board {
|
|
579
|
+
position: fixed;
|
|
580
|
+
inset: 0;
|
|
581
|
+
z-index: 9999;
|
|
582
|
+
background: var(--dsw-alias-bg-base);
|
|
583
|
+
color: var(--dsw-alias-label-primary);
|
|
584
|
+
font-family: var(--dsw-font-family);
|
|
585
|
+
display: flex;
|
|
586
|
+
flex-direction: column;
|
|
587
|
+
box-sizing: border-box;
|
|
588
|
+
padding: 14px 16px 16px;
|
|
589
|
+
gap: 12px;
|
|
590
|
+
pointer-events: auto;
|
|
591
|
+
overflow: hidden;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
.rec-board-header {
|
|
595
|
+
display: flex;
|
|
596
|
+
align-items: center;
|
|
597
|
+
gap: 10px;
|
|
598
|
+
flex: none;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
.rec-board-title {
|
|
602
|
+
margin: 0;
|
|
603
|
+
font-size: 16px;
|
|
604
|
+
font-weight: 700;
|
|
605
|
+
color: var(--dsw-alias-label-primary);
|
|
606
|
+
white-space: nowrap;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
.rec-board-count {
|
|
610
|
+
flex: none;
|
|
611
|
+
font-size: 12px;
|
|
612
|
+
color: var(--dsw-alias-label-tertiary);
|
|
613
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
614
|
+
border-radius: 999px;
|
|
615
|
+
padding: 1px 8px;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
.rec-board-empty {
|
|
619
|
+
margin: 0;
|
|
620
|
+
padding: 40px;
|
|
621
|
+
text-align: center;
|
|
622
|
+
color: var(--dsw-alias-label-tertiary);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
.rec-close {
|
|
626
|
+
position: absolute;
|
|
627
|
+
top: 14px;
|
|
628
|
+
right: 16px;
|
|
629
|
+
z-index: 1;
|
|
630
|
+
display: inline-flex;
|
|
631
|
+
align-items: center;
|
|
632
|
+
justify-content: center;
|
|
633
|
+
width: 26px;
|
|
634
|
+
height: 26px;
|
|
635
|
+
padding: 0;
|
|
636
|
+
background: transparent;
|
|
637
|
+
border: 1px solid var(--dsw-alias-border-l2);
|
|
638
|
+
border-radius: 6px;
|
|
639
|
+
color: var(--dsw-alias-label-secondary);
|
|
640
|
+
cursor: pointer;
|
|
641
|
+
font-size: 15px;
|
|
642
|
+
line-height: 1;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
.rec-close:hover {
|
|
646
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
647
|
+
color: var(--dsw-alias-label-primary);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
.rec-columns {
|
|
651
|
+
display: grid;
|
|
652
|
+
grid-auto-flow: column;
|
|
653
|
+
grid-auto-columns: minmax(240px, 1fr);
|
|
654
|
+
gap: 12px;
|
|
655
|
+
flex: 1;
|
|
656
|
+
min-height: 0;
|
|
657
|
+
overflow-x: auto;
|
|
658
|
+
overflow-y: hidden;
|
|
659
|
+
overscroll-behavior-inline: contain;
|
|
660
|
+
padding-bottom: 6px;
|
|
661
|
+
scrollbar-color: var(--dsw-alias-border-l3) var(--dsw-alias-interactive-bg-hover);
|
|
662
|
+
scrollbar-width: thin;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
.rec-columns::-webkit-scrollbar { height: 10px; }
|
|
666
|
+
.rec-columns::-webkit-scrollbar-track { background: var(--dsw-alias-interactive-bg-hover); border-radius: 999px; }
|
|
667
|
+
.rec-columns::-webkit-scrollbar-thumb { background: var(--dsw-alias-border-l3); background-clip: content-box; border: 2px solid transparent; border-radius: 999px; }
|
|
668
|
+
.rec-columns::-webkit-scrollbar-thumb:hover { background: var(--dsw-alias-border-l3); background-clip: content-box; }
|
|
669
|
+
|
|
670
|
+
.rec-column {
|
|
671
|
+
display: flex;
|
|
672
|
+
flex-direction: column;
|
|
673
|
+
min-height: 0;
|
|
674
|
+
background: var(--dsw-alias-bg-layer-2);
|
|
675
|
+
border: 1px solid var(--dsw-alias-border-l1);
|
|
676
|
+
border-radius: 12px;
|
|
677
|
+
overflow: hidden;
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
.rec-column-header {
|
|
681
|
+
display: flex;
|
|
682
|
+
align-items: center;
|
|
683
|
+
gap: 6px;
|
|
684
|
+
padding: 10px 12px;
|
|
685
|
+
flex: none;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
.rec-column-title {
|
|
689
|
+
margin: 0;
|
|
690
|
+
flex: 1;
|
|
691
|
+
font-size: 13px;
|
|
692
|
+
font-weight: 700;
|
|
693
|
+
color: var(--dsw-alias-label-primary);
|
|
694
|
+
overflow: hidden;
|
|
695
|
+
text-overflow: ellipsis;
|
|
696
|
+
white-space: nowrap;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
.rec-column-count {
|
|
700
|
+
flex: none;
|
|
701
|
+
font-size: 12px;
|
|
702
|
+
color: var(--dsw-alias-label-tertiary);
|
|
703
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
704
|
+
border-radius: 999px;
|
|
705
|
+
padding: 1px 8px;
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
.rec-status-dot {
|
|
709
|
+
width: 8px;
|
|
710
|
+
height: 8px;
|
|
711
|
+
border-radius: 50%;
|
|
712
|
+
flex: none;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
.rec-status-dot[data-status='new'] { background: var(--dsw-alias-label-tertiary); }
|
|
716
|
+
.rec-status-dot[data-status='active'] { background: var(--dsw-alias-state-business-primary); }
|
|
717
|
+
.rec-status-dot[data-status='paused'] { background: var(--dsw-alias-state-warn-primary); }
|
|
718
|
+
.rec-status-dot[data-status='blocked'] { background: var(--dsw-alias-state-error-primary); }
|
|
719
|
+
.rec-status-dot[data-status='complete'] { background: var(--dsw-alias-state-success-primary); }
|
|
720
|
+
|
|
721
|
+
.rec-cards {
|
|
722
|
+
display: flex;
|
|
723
|
+
flex-direction: column;
|
|
724
|
+
gap: 8px;
|
|
725
|
+
padding: 2px 8px 10px;
|
|
726
|
+
overflow-y: auto;
|
|
727
|
+
flex: 1;
|
|
728
|
+
min-height: 0;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
.rec-column-empty {
|
|
732
|
+
padding: 24px 8px;
|
|
733
|
+
text-align: center;
|
|
734
|
+
font-size: 12px;
|
|
735
|
+
color: var(--dsw-alias-label-tertiary);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
.rec-card {
|
|
739
|
+
display: flex;
|
|
740
|
+
flex-direction: column;
|
|
741
|
+
gap: 6px;
|
|
742
|
+
padding: 10px 12px;
|
|
743
|
+
text-align: left;
|
|
744
|
+
background: var(--dsw-alias-bg-base);
|
|
745
|
+
border: 1px solid var(--dsw-alias-border-l2);
|
|
746
|
+
border-radius: 10px;
|
|
747
|
+
cursor: pointer;
|
|
748
|
+
color: var(--dsw-alias-label-primary);
|
|
749
|
+
font-family: inherit;
|
|
750
|
+
transition: box-shadow 120ms ease, border-color 120ms ease, transform 120ms ease;
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
.rec-card:hover {
|
|
754
|
+
box-shadow: var(--dsw-shadow-lv2);
|
|
755
|
+
border-color: var(--dsw-alias-border-l3);
|
|
756
|
+
transform: translateY(-1px);
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
.rec-card:active {
|
|
760
|
+
box-shadow: var(--dsw-shadow-lv1);
|
|
761
|
+
transform: translateY(0);
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
.rec-card[data-state='active'] { border-color: var(--dsw-alias-state-business-primary); }
|
|
765
|
+
.rec-card[data-state='paused'] { border-color: var(--dsw-alias-state-warn-primary); }
|
|
766
|
+
.rec-card[data-state='blocked'] { border-color: var(--dsw-alias-state-error-primary); }
|
|
767
|
+
.rec-card[data-state='complete'] { border-color: var(--dsw-alias-state-success-primary); }
|
|
768
|
+
|
|
769
|
+
.rec-card-title {
|
|
770
|
+
font-size: 13px;
|
|
771
|
+
font-weight: 600;
|
|
772
|
+
line-height: 1.35;
|
|
773
|
+
overflow: hidden;
|
|
774
|
+
display: -webkit-box;
|
|
775
|
+
-webkit-line-clamp: 2;
|
|
776
|
+
-webkit-box-orient: vertical;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
.rec-card-progress {
|
|
780
|
+
height: 6px;
|
|
781
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
782
|
+
border-radius: 3px;
|
|
783
|
+
overflow: hidden;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
.rec-card-progress-fill {
|
|
787
|
+
height: 100%;
|
|
788
|
+
background: var(--dsw-alias-state-business-primary);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
.rec-card-meta {
|
|
792
|
+
display: flex;
|
|
793
|
+
align-items: center;
|
|
794
|
+
gap: 8px;
|
|
795
|
+
font-size: 11px;
|
|
796
|
+
color: var(--dsw-alias-label-tertiary);
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
.rec-card-phase {
|
|
800
|
+
flex: 1;
|
|
801
|
+
overflow: hidden;
|
|
802
|
+
text-overflow: ellipsis;
|
|
803
|
+
white-space: nowrap;
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
.rec-badge {
|
|
807
|
+
flex: none;
|
|
808
|
+
padding: 2px 10px;
|
|
809
|
+
font-size: 12px;
|
|
810
|
+
border-radius: 999px;
|
|
811
|
+
border: 1px solid var(--dsw-alias-border-l2);
|
|
812
|
+
color: var(--dsw-alias-label-secondary);
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
.rec-badge[data-status='active'] { color: var(--dsw-alias-state-business-primary); border-color: var(--dsw-alias-state-business-primary); }
|
|
816
|
+
.rec-badge[data-status='paused'] { color: var(--dsw-alias-state-warn-primary); border-color: var(--dsw-alias-state-warn-primary); }
|
|
817
|
+
.rec-badge[data-status='blocked'] { color: var(--dsw-alias-state-error-primary); border-color: var(--dsw-alias-state-error-primary); }
|
|
818
|
+
.rec-badge[data-status='complete'] { color: var(--dsw-alias-state-success-primary); border-color: var(--dsw-alias-state-success-primary); }
|
|
819
|
+
.rec-badge[data-status='new'] { color: var(--dsw-alias-label-tertiary); }
|
|
820
|
+
|
|
821
|
+
.rec-badge-tamper {
|
|
822
|
+
color: var(--dsw-alias-state-error-primary);
|
|
823
|
+
border-color: var(--dsw-alias-state-error-primary);
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
/* inspector: centered modal-style detail */
|
|
827
|
+
.rec-inspector {
|
|
828
|
+
position: fixed;
|
|
829
|
+
inset: 0;
|
|
830
|
+
z-index: 9999;
|
|
831
|
+
display: flex;
|
|
832
|
+
align-items: center;
|
|
833
|
+
justify-content: center;
|
|
834
|
+
background: var(--dsw-alias-bg-mask-1);
|
|
835
|
+
pointer-events: auto;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
.rec-detail {
|
|
839
|
+
display: flex;
|
|
840
|
+
flex-direction: column;
|
|
841
|
+
width: min(640px, calc(100vw - 48px));
|
|
842
|
+
max-height: calc(100vh - 80px);
|
|
843
|
+
background: var(--dsw-alias-bg-base);
|
|
844
|
+
border: 1px solid var(--dsw-alias-border-l2);
|
|
845
|
+
border-radius: 14px;
|
|
846
|
+
box-shadow: var(--dsw-shadow-lv3);
|
|
847
|
+
color: var(--dsw-alias-label-primary);
|
|
848
|
+
overflow: hidden;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
.rec-detail-header {
|
|
852
|
+
display: flex;
|
|
853
|
+
align-items: center;
|
|
854
|
+
gap: 10px;
|
|
855
|
+
padding: 14px 18px;
|
|
856
|
+
border-bottom: 1px solid var(--dsw-alias-separator-primary);
|
|
857
|
+
flex: none;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
.rec-detail-title {
|
|
861
|
+
margin: 0;
|
|
862
|
+
flex: 1;
|
|
863
|
+
font-size: 15px;
|
|
864
|
+
font-weight: 700;
|
|
865
|
+
overflow-wrap: anywhere;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
.rec-back {
|
|
869
|
+
display: inline-flex;
|
|
870
|
+
align-items: center;
|
|
871
|
+
gap: 4px;
|
|
872
|
+
padding: 5px 12px;
|
|
873
|
+
font-size: 12px;
|
|
874
|
+
color: var(--dsw-alias-label-primary);
|
|
875
|
+
background: transparent;
|
|
876
|
+
border: 1px solid var(--dsw-alias-border-l2);
|
|
877
|
+
border-radius: 8px;
|
|
878
|
+
cursor: pointer;
|
|
879
|
+
white-space: nowrap;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
.rec-back:hover {
|
|
883
|
+
background: var(--dsw-alias-interactive-bg-hover);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
.rec-detail-body {
|
|
887
|
+
padding: 14px 18px;
|
|
888
|
+
overflow-y: auto;
|
|
889
|
+
display: flex;
|
|
890
|
+
flex-direction: column;
|
|
891
|
+
gap: 16px;
|
|
892
|
+
flex: 1;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
.rec-detail-section {
|
|
896
|
+
display: flex;
|
|
897
|
+
flex-direction: column;
|
|
898
|
+
gap: 6px;
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
.rec-detail-section h3 {
|
|
902
|
+
margin: 0;
|
|
903
|
+
font-size: 12px;
|
|
904
|
+
font-weight: 700;
|
|
905
|
+
color: var(--dsw-alias-label-tertiary);
|
|
906
|
+
}
|
|
907
|
+
|
|
908
|
+
.rec-phase-row {
|
|
909
|
+
display: flex;
|
|
910
|
+
align-items: center;
|
|
911
|
+
gap: 10px;
|
|
912
|
+
padding: 8px 10px;
|
|
913
|
+
border: 1px solid var(--dsw-alias-border-l1);
|
|
914
|
+
border-radius: 8px;
|
|
915
|
+
font-size: 13px;
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
.rec-phase-id {
|
|
919
|
+
min-width: 48px;
|
|
920
|
+
font-family: var(--dsw-font-markdown-code-block-small);
|
|
921
|
+
color: var(--dsw-alias-state-business-primary);
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
.rec-phase-name {
|
|
925
|
+
flex: 1;
|
|
926
|
+
color: var(--dsw-alias-label-primary);
|
|
927
|
+
overflow: hidden;
|
|
928
|
+
text-overflow: ellipsis;
|
|
929
|
+
white-space: nowrap;
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
.rec-lockhash {
|
|
933
|
+
font-family: var(--dsw-font-markdown-code-block-small);
|
|
934
|
+
font-size: 11px;
|
|
935
|
+
color: var(--dsw-alias-label-tertiary);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
@media (prefers-reduced-motion: reduce) {
|
|
939
|
+
.rec-card, .rec-back, .rec-close { transition: none; }
|
|
940
|
+
}
|
|
941
|
+
`;
|
|
942
|
+
/**
|
|
943
|
+
* Inject the board/inspector stylesheet once. Idempotent: if a <style
|
|
944
|
+
* data-dsh-recursive> already exists, returns a disposer that does nothing
|
|
945
|
+
* (the first injector owns the element). Returns a disposer that removes it.
|
|
946
|
+
*/
|
|
947
|
+
function injectBoardStyles() {
|
|
948
|
+
if (typeof document === "undefined") return () => {};
|
|
949
|
+
if (document.querySelector("style[data-dsh-recursive]") !== null) return () => {};
|
|
950
|
+
const style = document.createElement("style");
|
|
951
|
+
style.setAttribute("data-dsh-recursive", "");
|
|
952
|
+
style.textContent = BOARD_CSS;
|
|
953
|
+
document.head.appendChild(style);
|
|
954
|
+
let disposed = false;
|
|
955
|
+
return () => {
|
|
956
|
+
if (disposed) return;
|
|
957
|
+
disposed = true;
|
|
958
|
+
style.remove();
|
|
959
|
+
};
|
|
960
|
+
}
|
|
961
|
+
//#endregion
|
|
744
962
|
//#region src/client/slots.ts
|
|
745
963
|
/**
|
|
746
964
|
* Slot registrations (SP2 R1 + run 08 R1/R3/R4): the sidebar launcher, the
|
|
@@ -792,6 +1010,7 @@ window.__ModuleLoader__.load({
|
|
|
792
1010
|
}
|
|
793
1011
|
function registerSlots(ctx) {
|
|
794
1012
|
const disposers = [];
|
|
1013
|
+
disposers.push(injectBoardStyles());
|
|
795
1014
|
disposers.push(ctx.slots.inject("sidebar.footer.action", () => ctx.slots.register({
|
|
796
1015
|
name: "sidebar.footer.action",
|
|
797
1016
|
id: "recursive",
|
|
@@ -809,7 +1028,10 @@ window.__ModuleLoader__.load({
|
|
|
809
1028
|
}, (props) => {
|
|
810
1029
|
const useSessions = props?.useSessions;
|
|
811
1030
|
if (useSessions === void 0) return null;
|
|
812
|
-
return (0, react.createElement)(RecursiveBoardOverlay, {
|
|
1031
|
+
return (0, react.createElement)(RecursiveBoardOverlay, {
|
|
1032
|
+
useSessions,
|
|
1033
|
+
useWorkspaces: props?.useWorkspaces
|
|
1034
|
+
});
|
|
813
1035
|
})));
|
|
814
1036
|
disposers.push(ctx.slots.inject("conversation.input.dock", () => ctx.slots.register({
|
|
815
1037
|
name: "conversation.input.dock",
|
|
@@ -840,15 +1062,15 @@ window.__ModuleLoader__.load({
|
|
|
840
1062
|
* Run 10: consumes the full SessionListStateLike through the identity selector
|
|
841
1063
|
* (useSessions((s) => s)); no fake {list:{getSnapshot}} wrapper.
|
|
842
1064
|
*/
|
|
843
|
-
function RecursiveBoardOverlay({ useSessions }) {
|
|
1065
|
+
function RecursiveBoardOverlay({ useSessions, useWorkspaces }) {
|
|
844
1066
|
const board = useBoardState();
|
|
845
|
-
const
|
|
846
|
-
const
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
});
|
|
1067
|
+
const sessions = useRecursiveSessions(useSessions);
|
|
1068
|
+
const workspaces = useWorkspaces !== void 0 ? useWorkspaces((s) => s) : {
|
|
1069
|
+
items: [],
|
|
1070
|
+
recentWorkspaceId: void 0
|
|
1071
|
+
};
|
|
1072
|
+
const content = overlayContent(board, sessions);
|
|
1073
|
+
const snapshot = useLiveProjection({ cwd: currentWorkspacePath(workspaces, sessions) });
|
|
852
1074
|
if (content === "hidden") return null;
|
|
853
1075
|
if (content === "inspector" && board.selection !== null) return (0, react.createElement)(Inspector, {
|
|
854
1076
|
runId: board.selection.runId,
|
|
@@ -910,6 +1132,7 @@ window.__ModuleLoader__.load({
|
|
|
910
1132
|
exports.StatusStrip = StatusStrip;
|
|
911
1133
|
exports.apply = apply;
|
|
912
1134
|
exports.currentSessionCwd = currentSessionCwd;
|
|
1135
|
+
exports.currentWorkspacePath = currentWorkspacePath;
|
|
913
1136
|
exports.fetchLiveState = fetchLiveState;
|
|
914
1137
|
exports.inject = inject;
|
|
915
1138
|
exports.isRecursivePreset = isRecursivePreset;
|