@hachej/boring-workspace 0.1.62 → 0.1.64

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/workspace.js CHANGED
@@ -1,27 +1,27 @@
1
1
  var X = Object.defineProperty;
2
2
  var Q = (e, t, a) => t in e ? X(e, t, { enumerable: !0, configurable: !0, writable: !0, value: a }) : e[t] = a;
3
3
  var T = (e, t, a) => Q(e, typeof t != "symbol" ? t + "" : t, a);
4
- import { u as D, p as Y, a as Z, b as ee, D as te } from "./WorkspaceProvider-kf-pjz6V.js";
5
- import { A as qe, C as Je, c as Ve, d as Ge, e as Xe, f as Qe, F as Ye, g as Ze, M as et, h as tt, P as at, i as rt, j as nt, k as st, l as ot, R as it, S as lt, m as ct, n as dt, T as ut, U as pt, W as mt, o as ft, q as ht, r as gt, s as bt, t as yt, v as kt, w as St, x as vt, y as Pt, z as xt, B as wt, E as Ct, G as Et, H as Nt, I as Rt, J as Tt, K as Ot, L as It, N as Wt, O as Ft, Q as Lt, V as Bt, X as Mt, Y as Kt, Z as _t, _ as Dt, $ as At, a0 as $t, a1 as jt, a2 as zt, a3 as Ht, a4 as Ut, a5 as qt, a6 as Jt, a7 as Vt, a8 as Gt, a9 as Xt, aa as Qt, ab as Yt, ac as Zt, ad as ea, ae as ta, af as aa, ag as ra, ah as na, ai as sa, aj as oa, ak as ia, al as la, am as ca, an as da, ao as ua, ap as pa, aq as ma, ar as fa, as as ha, at as ga, au as ba, av as ya, aw as ka, ax as Sa, ay as va, az as Pa, aA as xa, aB as wa, aC as Ca, aD as Ea, aE as Na, aF as Ra, aG as Ta, aH as Oa, aI as Ia, aJ as Wa, aK as Fa, aL as La } from "./WorkspaceProvider-kf-pjz6V.js";
4
+ import { u as D, p as Y, a as Z, b as ee, D as te } from "./WorkspaceProvider-CEZUOy1M.js";
5
+ import { A as qe, C as Je, c as Ve, d as Ge, e as Xe, f as Qe, F as Ye, g as Ze, M as et, h as tt, P as at, i as rt, j as nt, k as st, l as ot, R as it, S as lt, m as ct, n as dt, T as ut, U as pt, W as mt, o as ft, q as ht, r as gt, s as yt, t as bt, v as kt, w as St, x as vt, y as Pt, z as xt, B as wt, E as Ct, G as Et, H as Nt, I as Rt, J as Tt, K as Ot, L as It, N as Wt, O as Ft, Q as Lt, V as Mt, X as Bt, Y as Kt, Z as _t, _ as Dt, $ as At, a0 as $t, a1 as jt, a2 as zt, a3 as Ht, a4 as Ut, a5 as qt, a6 as Jt, a7 as Vt, a8 as Gt, a9 as Xt, aa as Qt, ab as Yt, ac as Zt, ad as ea, ae as ta, af as aa, ag as ra, ah as na, ai as sa, aj as oa, ak as ia, al as la, am as ca, an as da, ao as ua, ap as pa, aq as ma, ar as fa, as as ha, at as ga, au as ya, av as ba, aw as ka, ax as Sa, ay as va, az as Pa, aA as xa, aB as wa, aC as Ca, aD as Ea, aE as Na, aF as Ra, aG as Ta, aH as Oa, aI as Ia, aJ as Wa, aK as Fa, aL as La, aM as Ma } from "./WorkspaceProvider-CEZUOy1M.js";
6
6
  import { c as C } from "./utils-B6yFEsav.js";
7
- import { C as Ma, T as Ka, W as _a, b as Da } from "./WorkspaceLoadingState-Dfnk7JjR.js";
7
+ import { C as Ka, T as _a, W as Da, b as Aa } from "./WorkspaceLoadingState-D4SB2awA.js";
8
8
  import { jsx as r, jsxs as g, Fragment as ae } from "react/jsx-runtime";
9
9
  import { Button as x, Sheet as re, SheetContent as ne, SheetHeader as se, SheetTitle as oe, SheetDescription as ie, EmptyState as le, Kbd as O, ErrorState as ce, IconButton as I } from "@hachej/boring-ui-kit";
10
- import { Toaster as $a, dismissToast as ja, toast as za } from "@hachej/boring-ui-kit";
11
- import { useSyncExternalStore as A, useState as E, useEffect as v, useRef as w, useCallback as b, useMemo as P, Suspense as de, Component as ue } from "react";
12
- import { FileTree as Ua } from "./FileTree-zGmxifl_.js";
13
- import { MarkdownEditor as Ja } from "./MarkdownEditor-BykEKKxv.js";
14
- import { MenuIcon as pe, PanelLeftIcon as B, PinIcon as me, CheckIcon as fe, CopyIcon as he } from "lucide-react";
15
- function Be() {
10
+ import { Toaster as ja, dismissToast as za, toast as Ha } from "@hachej/boring-ui-kit";
11
+ import { useSyncExternalStore as A, useState as E, useEffect as v, useRef as w, useCallback as y, useMemo as P, Suspense as de, Component as ue } from "react";
12
+ import { FileTree as qa } from "./FileTree-DjhAzlg3.js";
13
+ import { MarkdownEditor as Va } from "./MarkdownEditor-CeN7n6mw.js";
14
+ import { MenuIcon as pe, PanelLeftIcon as M, PinIcon as me, CheckIcon as fe, CopyIcon as he } from "lucide-react";
15
+ function Me() {
16
16
  const e = D();
17
17
  return A(e.subscribe, e.getSnapshot);
18
18
  }
19
19
  function $(e) {
20
20
  switch (e.kind) {
21
21
  case "openFile":
22
- return { kind: "openFile", params: { path: e.path, ...e.mode ? { mode: e.mode } : {} } };
22
+ return { kind: "openFile", params: { path: e.path, ...e.mode ? { mode: e.mode } : {}, ...e.filesystem ? { filesystem: e.filesystem } : {} } };
23
23
  case "openSurface":
24
- return { kind: "openSurface", params: { kind: e.surfaceKind, target: e.target, ...e.meta ? { meta: e.meta } : {} } };
24
+ return { kind: "openSurface", params: { kind: e.surfaceKind, target: e.target, ...e.filesystem ? { filesystem: e.filesystem } : {}, ...e.meta ? { meta: e.meta } : {} } };
25
25
  case "openPanel":
26
26
  return {
27
27
  kind: "openPanel",
@@ -39,10 +39,10 @@ function $(e) {
39
39
  function ge(e) {
40
40
  return `boring-workspace-command:${encodeURIComponent(JSON.stringify($(e)))}`;
41
41
  }
42
- function be(e) {
42
+ function ye(e) {
43
43
  return e.button === 0 && !e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey;
44
44
  }
45
- function Me({ to: e, children: t, className: a, title: n, href: o, onClick: i }) {
45
+ function Be({ to: e, children: t, className: a, title: n, href: o, onClick: i }) {
46
46
  return /* @__PURE__ */ r(
47
47
  "a",
48
48
  {
@@ -50,13 +50,13 @@ function Me({ to: e, children: t, className: a, title: n, href: o, onClick: i })
50
50
  className: a,
51
51
  title: n,
52
52
  onClick: (u) => {
53
- i == null || i(u), !(u.defaultPrevented || !be(u)) && (u.preventDefault(), Y($(e)));
53
+ i == null || i(u), !(u.defaultPrevented || !ye(u)) && (u.preventDefault(), Y($(e)));
54
54
  },
55
55
  children: t
56
56
  }
57
57
  );
58
58
  }
59
- function ye(e, t) {
59
+ function be(e, t) {
60
60
  return e ? `${e.replace(/\/$/, "")}${t}` : t;
61
61
  }
62
62
  function ke() {
@@ -74,7 +74,7 @@ async function Ke(e) {
74
74
  e.recordSet && t.set("recordSet", e.recordSet), e.offset !== void 0 && t.set("offset", String(e.offset)), e.limit !== void 0 && t.set("limit", String(e.limit)), e.q && t.set("q", e.q);
75
75
  const a = { ...e.headers ?? {} }, n = e.workspaceId ?? ke();
76
76
  n && !Object.keys(a).some((i) => i.toLowerCase() === "x-boring-workspace-id") && (a["x-boring-workspace-id"] = n);
77
- const o = await fetch(ye(e.apiBaseUrl, `/api/v1/files/records?${t}`), {
77
+ const o = await fetch(be(e.apiBaseUrl, `/api/v1/files/records?${t}`), {
78
78
  method: "GET",
79
79
  headers: a,
80
80
  signal: e.signal
@@ -83,14 +83,14 @@ async function Ke(e) {
83
83
  throw new Error(`readFileRecords failed: HTTP ${o.status}`);
84
84
  return await o.json();
85
85
  }
86
- function M(e) {
86
+ function B(e) {
87
87
  return typeof window > "u" ? !1 : window.innerWidth < e;
88
88
  }
89
89
  function K(e = 1024) {
90
- const [t, a] = E(() => M(e));
90
+ const [t, a] = E(() => B(e));
91
91
  return v(() => {
92
92
  const n = () => {
93
- a(M(e));
93
+ a(B(e));
94
94
  };
95
95
  return n(), window.addEventListener("resize", n), () => {
96
96
  window.removeEventListener("resize", n);
@@ -112,7 +112,7 @@ function Se({
112
112
  return;
113
113
  }
114
114
  l && o.current && (o.current = !1, a(!1));
115
- }, [e, a]), b(() => {
115
+ }, [e, a]), y(() => {
116
116
  o.current = !1;
117
117
  }, []);
118
118
  }
@@ -127,9 +127,9 @@ function _e(e) {
127
127
  try {
128
128
  const p = e.toJSON(), f = [];
129
129
  if (p && typeof p == "object" && "panels" in p) {
130
- const y = p;
131
- if (y.panels)
132
- for (const [, m] of Object.entries(y.panels))
130
+ const b = p;
131
+ if (b.panels)
132
+ for (const [, m] of Object.entries(b.panels))
133
133
  m.id && f.push({
134
134
  id: m.id,
135
135
  component: m.contentComponent ?? m.id,
@@ -137,9 +137,9 @@ function _e(e) {
137
137
  });
138
138
  }
139
139
  const s = n.current;
140
- (s.length !== f.length || s.some((y, m) => {
140
+ (s.length !== f.length || s.some((b, m) => {
141
141
  var k;
142
- return y.id !== ((k = f[m]) == null ? void 0 : k.id);
142
+ return b.id !== ((k = f[m]) == null ? void 0 : k.id);
143
143
  })) && a(f);
144
144
  } catch {
145
145
  }
@@ -148,7 +148,7 @@ function _e(e) {
148
148
  const c = setInterval(l, 500);
149
149
  return () => clearInterval(c);
150
150
  }, [e]);
151
- const o = b(
151
+ const o = y(
152
152
  (l) => {
153
153
  e == null || e.addPanel("artifacts", {
154
154
  id: l.id,
@@ -157,28 +157,28 @@ function _e(e) {
157
157
  });
158
158
  },
159
159
  [e]
160
- ), i = b(
160
+ ), i = y(
161
161
  (l) => {
162
162
  e == null || e.removePanel(l);
163
163
  },
164
164
  [e]
165
- ), u = b(
165
+ ), u = y(
166
166
  (l) => {
167
167
  e == null || e.activatePanel(l);
168
168
  },
169
169
  [e]
170
- ), d = b(
170
+ ), d = y(
171
171
  (l) => n.current.some((c) => c.id === l),
172
172
  []
173
173
  );
174
174
  return { panels: t, open: o, close: i, activate: u, isOpen: d };
175
175
  }
176
176
  function De(e, t = {}) {
177
- const a = t.toolPanelMap ?? {}, n = b(
177
+ const a = t.toolPanelMap ?? {}, n = y(
178
178
  (i) => a[i],
179
179
  [a]
180
180
  );
181
- return { openForTool: b(
181
+ return { openForTool: y(
182
182
  (i, u) => {
183
183
  const d = a[i];
184
184
  if (!d) return;
@@ -211,7 +211,7 @@ function we({
211
211
  v(() => {
212
212
  (!p || !i && !d) && h(!1);
213
213
  }, [p, i, d]);
214
- const y = p && (i || d && n.collapsed), m = p && !i && (!d || !n.collapsed), k = P(
214
+ const b = p && (i || d && n.collapsed), m = p && !i && (!d || !n.collapsed), k = P(
215
215
  () => m ? e : xe(e),
216
216
  [m, e]
217
217
  ), j = P(() => {
@@ -229,13 +229,13 @@ function we({
229
229
  a.subscribe,
230
230
  a.getSnapshot,
231
231
  a.getSnapshot
232
- ), H = P(() => a.getComponents(), [a, z]), W = c ? H[c] : null, U = c ? ((F = a.get(c)) == null ? void 0 : F.title) ?? "Sidebar" : "Sidebar", q = b(() => {
232
+ ), H = P(() => a.getComponents(), [a, z]), W = c ? H[c] : null, U = c ? ((F = a.get(c)) == null ? void 0 : F.title) ?? "Sidebar" : "Sidebar", q = y(() => {
233
233
  h(!0);
234
- }, []), J = b(() => {
234
+ }, []), J = y(() => {
235
235
  f(), o({ collapsed: !1 }), h(!1);
236
- }, [f, o]), V = b(() => {
236
+ }, [f, o]), V = y(() => {
237
237
  f(), o({ collapsed: !0 }), h(!1);
238
- }, [f, o]), G = b(
238
+ }, [f, o]), G = y(
239
239
  (S) => {
240
240
  S.target.closest("[role='treeitem']") && h(!1);
241
241
  },
@@ -249,7 +249,7 @@ function we({
249
249
  "aria-hidden": "true"
250
250
  }
251
251
  ),
252
- y && /* @__PURE__ */ r(
252
+ b && /* @__PURE__ */ r(
253
253
  "div",
254
254
  {
255
255
  className: C(
@@ -264,7 +264,7 @@ function we({
264
264
  size: "icon-sm",
265
265
  onClick: q,
266
266
  "aria-label": i ? "Open sidebar menu" : "Open collapsed sidebar",
267
- children: i ? /* @__PURE__ */ r(pe, { className: "h-4 w-4" }) : /* @__PURE__ */ r(B, { className: "h-4 w-4" })
267
+ children: i ? /* @__PURE__ */ r(pe, { className: "h-4 w-4" }) : /* @__PURE__ */ r(M, { className: "h-4 w-4" })
268
268
  }
269
269
  )
270
270
  }
@@ -277,7 +277,7 @@ function we({
277
277
  size: "icon-sm",
278
278
  onClick: V,
279
279
  "aria-label": "Collapse sidebar",
280
- children: /* @__PURE__ */ r(B, { className: "h-4 w-4" })
280
+ children: /* @__PURE__ */ r(M, { className: "h-4 w-4" })
281
281
  }
282
282
  ) }),
283
283
  /* @__PURE__ */ r(
@@ -291,7 +291,7 @@ function we({
291
291
  },
292
292
  j
293
293
  ),
294
- y && /* @__PURE__ */ r(re, { open: s, onOpenChange: h, children: /* @__PURE__ */ g(
294
+ b && /* @__PURE__ */ r(re, { open: s, onOpenChange: h, children: /* @__PURE__ */ g(
295
295
  ne,
296
296
  {
297
297
  side: "left",
@@ -443,23 +443,23 @@ function ze({
443
443
  }
444
444
  d((s) => s && c.includes(s) ? s : t && c.includes(t) ? t : c[0] ?? null);
445
445
  }, [c, t]);
446
- const p = b((s) => {
446
+ const p = y((s) => {
447
447
  var h;
448
448
  d(s), (h = l.current[s]) == null || h.focus();
449
- }, []), f = b(
449
+ }, []), f = y(
450
450
  (s, h) => {
451
451
  if (s.target !== s.currentTarget) return;
452
452
  if (s.key === "Enter" || s.key === " ") {
453
453
  s.preventDefault(), a == null || a(h);
454
454
  return;
455
455
  }
456
- const y = c.indexOf(h);
457
- if (y < 0) return;
458
- let m = y;
456
+ const b = c.indexOf(h);
457
+ if (b < 0) return;
458
+ let m = b;
459
459
  if (s.key === "ArrowDown")
460
- m = Math.min(y + 1, c.length - 1);
460
+ m = Math.min(b + 1, c.length - 1);
461
461
  else if (s.key === "ArrowUp")
462
- m = Math.max(y - 1, 0);
462
+ m = Math.max(b - 1, 0);
463
463
  else if (s.key === "Home")
464
464
  m = 0;
465
465
  else if (s.key === "End")
@@ -547,7 +547,7 @@ function Ne({
547
547
  onKeyDown: u,
548
548
  rowRef: d
549
549
  }) {
550
- const [l, c] = E(!1), p = b((f) => {
550
+ const [l, c] = E(!1), p = y((f) => {
551
551
  f.stopPropagation(), Ee(e.id).then((s) => {
552
552
  s && (c(!0), window.setTimeout(() => c(!1), 1200));
553
553
  });
@@ -627,19 +627,19 @@ function Ne({
627
627
  export {
628
628
  qe as ArtifactSurfacePane,
629
629
  Je as CatalogRegistry,
630
- Ma as ChatLayout,
630
+ Ka as ChatLayout,
631
631
  Ve as CodeEditor,
632
632
  Ge as CodeEditorPane,
633
633
  Xe as CommandPalette,
634
634
  Qe as CommandRegistry,
635
635
  te as DockviewShell,
636
636
  $e as EmptyPane,
637
- Ua as FileTree,
637
+ qa as FileTree,
638
638
  Ye as FileTreePane,
639
639
  Ze as FileTreeView,
640
640
  Ae as IdeLayout,
641
641
  et as MAX_PANELS,
642
- Ja as MarkdownEditor,
642
+ Va as MarkdownEditor,
643
643
  tt as MarkdownEditorPane,
644
644
  at as PanelChrome,
645
645
  je as PanelErrorBoundary,
@@ -654,25 +654,25 @@ export {
654
654
  ct as SurfaceResolverRegistry,
655
655
  dt as SurfaceShell,
656
656
  ut as ThemeProvider,
657
- $a as Toaster,
658
- Ka as TopBar,
657
+ ja as Toaster,
658
+ _a as TopBar,
659
659
  pt as UI_COMMAND_EVENT,
660
660
  mt as WORKSPACE_ATTENTION_ACTION_EVENT,
661
661
  ft as WORKSPACE_COMPOSER_STOP_EVENT,
662
662
  ht as WORKSPACE_COMPOSER_STOP_REASONS,
663
663
  gt as WORKSPACE_OPEN_PATH_SURFACE_KIND,
664
- bt as WORKSPACE_SURFACE_OPEN_SKIPPED_EVENT,
665
- yt as WorkbenchLeftPane,
664
+ yt as WORKSPACE_SURFACE_OPEN_SKIPPED_EVENT,
665
+ bt as WorkbenchLeftPane,
666
666
  kt as WorkspaceFilesProvider,
667
- Me as WorkspaceLink,
668
- _a as WorkspaceLoadingState,
667
+ Be as WorkspaceLink,
668
+ Da as WorkspaceLoadingState,
669
669
  St as WorkspacePluginClientProvider,
670
670
  vt as WorkspaceProvider,
671
671
  Pt as WorkspaceSourceRegistry,
672
672
  xt as agentMeta,
673
673
  wt as bindStore,
674
674
  Ct as bootstrap,
675
- Da as buildChatLayout,
675
+ Aa as buildChatLayout,
676
676
  Et as buildFullPagePanelHref,
677
677
  Ce as buildIdeLayout,
678
678
  Nt as closePanelSchema,
@@ -683,10 +683,10 @@ export {
683
683
  It as createWorkspacePluginClient,
684
684
  Wt as createWorkspaceStore,
685
685
  Ft as definePanel,
686
- ja as dismissToast,
686
+ za as dismissToast,
687
687
  Lt as emitAgentData,
688
- Bt as emitFilesystemAgentFileChange,
689
- Mt as emitWorkspaceAttentionAction,
688
+ Mt as emitFilesystemAgentFileChange,
689
+ Bt as emitWorkspaceAttentionAction,
690
690
  Kt as emitWorkspaceComposerStop,
691
691
  _t as events,
692
692
  Dt as expandToFileSchema,
@@ -703,10 +703,10 @@ export {
703
703
  Xt as openPanelSchema,
704
704
  Y as postUiCommand,
705
705
  Ke as readFileRecords,
706
- za as toast,
706
+ Ha as toast,
707
707
  Qt as useActiveFile,
708
708
  Yt as useActivePanel,
709
- Be as useActivePanels,
709
+ Me as useActivePanels,
710
710
  Zt as useApiBaseUrl,
711
711
  _e as useArtifactPanels,
712
712
  De as useArtifactRouting,
@@ -727,9 +727,9 @@ export {
727
727
  fa as useKeyboardShortcuts,
728
728
  ha as useOpenPanels,
729
729
  ga as usePanelRenderMode,
730
- ba as usePluginErrors,
730
+ ya as usePluginErrors,
731
731
  D as useRegistry,
732
- ya as useResetLayout,
732
+ ba as useResetLayout,
733
733
  Se as useResponsiveSidebarCollapse,
734
734
  ee as useSetSidebar,
735
735
  Z as useSidebarState,
@@ -742,14 +742,15 @@ export {
742
742
  wa as useWorkspaceChatPanel,
743
743
  Ca as useWorkspaceContext,
744
744
  Ea as useWorkspaceContextOptional,
745
- Na as useWorkspacePluginClient,
746
- Ra as useWorkspaceRequestId,
747
- Ta as useWorkspaceSourceRegistry,
748
- Oa as userMeta,
749
- Ia as workspaceAttentionSessionBadgeForBlocker,
750
- Wa as workspaceComposerStopAppliesToSession,
751
- Fa as workspaceComposerStopTargetSessionId,
752
- La as workspaceEvents,
745
+ Na as useWorkspaceLeftPaneActions,
746
+ Ra as useWorkspacePluginClient,
747
+ Ta as useWorkspaceRequestId,
748
+ Oa as useWorkspaceSourceRegistry,
749
+ Ia as userMeta,
750
+ Wa as workspaceAttentionSessionBadgeForBlocker,
751
+ Fa as workspaceComposerStopAppliesToSession,
752
+ La as workspaceComposerStopTargetSessionId,
753
+ Ma as workspaceEvents,
753
754
  $ as workspaceLinkCommand,
754
755
  ge as workspaceLinkHref
755
756
  };
package/docs/README.md CHANGED
@@ -34,6 +34,7 @@ the doc that matches your task.
34
34
  | Abstraction | Where | What it is |
35
35
  | --- | --- | --- |
36
36
  | `WorkspaceProvider` | `src/front/provider` | Root provider; boots plugins, layout, bridge. |
37
+ | `useWorkspaceLeftPaneActions()` | `@hachej/boring-workspace` | Public hook for host apps that want to render workspace left-pane category buttons inside their own explorer/sidebar without mounting `WorkbenchLeftPane`. |
37
38
  | `definePlugin()` | `@hachej/boring-workspace/plugin` | Declarative front plugin: panels, commands, catalogs, bindings, providers, surfaceResolvers. |
38
39
  | `defineServerPlugin()` | `@hachej/boring-workspace/server` | Trusted boot-time server plugin: routes, agent tools, system prompt, Pi packages, provisioning. |
39
40
  | `PaneProps<T>` | `src/shared/types/panel.ts` | Props every panel/page component receives (`params`, `api`, `containerApi`). |
@@ -66,6 +67,34 @@ the doc that matches your task.
66
67
  reset; agent consumes them under `[data-boring-agent]`. See
67
68
  [`docs/TAILWIND-V4-STYLE-ISOLATION.md`](../../../docs/TAILWIND-V4-STYLE-ISOLATION.md).
68
69
 
70
+ ## Host explorer composition
71
+
72
+ Standalone workspaces can keep using `WorkbenchLeftPane`. Apps that already own a
73
+ left explorer/sidebar can instead render the category actions themselves:
74
+
75
+ ```tsx
76
+ import { useWorkspaceLeftPaneActions } from "@hachej/boring-workspace"
77
+
78
+ function HostExplorer({ onOpenPanel, activePanelId }) {
79
+ const actions = useWorkspaceLeftPaneActions({ onOpenPanel, activePanelId })
80
+
81
+ return actions.map((action) => (
82
+ <button key={action.id} aria-pressed={action.active} onClick={action.select}>
83
+ {action.icon}
84
+ {action.title}
85
+ </button>
86
+ ))
87
+ }
88
+ ```
89
+
90
+ Pass `activePanelId` when the host also renders `workspace-page` panels and wants
91
+ those launcher actions to show the focused page as active.
92
+
93
+ Use this public hook rather than deep-importing chrome internals. Search UI,
94
+ workspace-source content hosting, and plugin chrome action portals remain owned
95
+ by the default `WorkbenchLeftPane` unless a host explicitly renders that full
96
+ component.
97
+
69
98
  ## Docs
70
99
 
71
100
  Authoring:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hachej/boring-workspace",
3
- "version": "0.1.62",
3
+ "version": "0.1.64",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Workspace UI, plugin, and bridge package for composing chat, files, catalogs, editors, and app-specific panes.",
@@ -139,9 +139,9 @@
139
139
  "tailwind-merge": "^2.0.0",
140
140
  "zod": "^3.23.0",
141
141
  "zustand": "^5.0.0",
142
- "@hachej/boring-agent": "0.1.62",
143
- "@hachej/boring-ui-kit": "0.1.62",
144
- "@hachej/boring-ui-plugin-cli": "0.1.62"
142
+ "@hachej/boring-agent": "0.1.64",
143
+ "@hachej/boring-ui-plugin-cli": "0.1.64",
144
+ "@hachej/boring-ui-kit": "0.1.64"
145
145
  },
146
146
  "devDependencies": {
147
147
  "@tailwindcss/postcss": "^4.0.0",