@hachej/boring-workspace 0.1.13 → 0.1.14

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.
Files changed (34) hide show
  1. package/README.md +270 -42
  2. package/dist/CommandPalette-NOEOVkN2.js +5714 -0
  3. package/dist/{FileTree-BVfqs3rR.js → FileTree-Dl-qUAB0.js} +9 -9
  4. package/dist/MarkdownEditor-yc6mFsnI.js +533 -0
  5. package/dist/{WorkspaceLoadingState-BjZGQLS_.js → WorkspaceLoadingState-CSZfENWe.js} +145 -124
  6. package/dist/agent-tool-DEtfQPVB.d.ts +100 -0
  7. package/dist/app-front.d.ts +79 -67
  8. package/dist/app-front.js +253 -241
  9. package/dist/app-server.d.ts +17 -12
  10. package/dist/app-server.js +80 -10
  11. package/dist/{bootstrapServer-BRUqUpVW.d.ts → bootstrapServer-BreQ9QBc.d.ts} +8 -2
  12. package/dist/server.d.ts +10 -32
  13. package/dist/server.js +22 -127
  14. package/dist/shared.d.ts +1 -2
  15. package/dist/testing.d.ts +0 -63
  16. package/dist/testing.js +2248 -2401
  17. package/dist/workspace.css +1616 -974
  18. package/dist/workspace.d.ts +111 -450
  19. package/dist/workspace.js +417 -1635
  20. package/docs/INTERFACES.md +2 -2
  21. package/docs/PLUGIN_STRUCTURE.md +1 -1
  22. package/docs/plans/ASK_USER_QUESTIONS_PLUGIN_SPEC.md +131 -263
  23. package/docs/plans/GENERIC_EXPLORER_PLUGIN_PLAN.md +29 -27
  24. package/docs/plans/MACRO_PLUGIN_GENERIC_HELPERS_AUDIT.md +12 -12
  25. package/docs/plans/PANE_TO_AGENT_CHAT_ACTIONS_SPEC.md +366 -0
  26. package/docs/plans/README.md +2 -0
  27. package/docs/plans/archive/PLUGIN_MODEL.md +14 -14
  28. package/docs/plans/archive/SRC_FOLDER_REORG_PLAN.md +2 -3
  29. package/docs/plans/archive/WORKSPACE_V2_PLAN.md +1 -1
  30. package/package.json +3 -6
  31. package/dist/CommandPalette-Dme9em28.js +0 -5506
  32. package/dist/MarkdownEditor-CcCDF65H.js +0 -502
  33. package/dist/agent-tool-NvxKfist.d.ts +0 -28
  34. package/dist/explorer-DtLUnuah.d.ts +0 -129
@@ -1,10 +1,10 @@
1
- import { jsxs as d, jsx as a, Fragment as H } from "react/jsx-runtime";
2
- import { useCallback as p, useMemo as D, useEffect as S, useState as V, Suspense as U, useRef as q } from "react";
3
- import { LoadingState as Z, ResizeHandle as G, IconButton as $, Button as J, Kbd as Q } from "@hachej/boring-ui-kit";
1
+ import { jsxs as d, jsx as a, Fragment as V } from "react/jsx-runtime";
2
+ import { useCallback as b, useMemo as F, useEffect as I, useState as q, Suspense as Q, useRef as Y } from "react";
3
+ import { LoadingState as ee, ResizeHandle as te, IconButton as Z, Button as ne, Kbd as re } from "@hachej/boring-ui-kit";
4
4
  import { c as g } from "./utils-B6yFEsav.js";
5
- import { $ as Y, a6 as ee, E as te, am as ne, ak as re, u as ae } from "./CommandPalette-Dme9em28.js";
6
- import { Search as oe, Plus as ie } from "lucide-react";
7
- function pe(e, t, r = !0) {
5
+ import { a0 as ae, a7 as oe, B as ie, an as se, al as ce, u as de } from "./CommandPalette-NOEOVkN2.js";
6
+ import { Search as le, Plus as ue } from "lucide-react";
7
+ function ke(e, t, r = !0) {
8
8
  if (!r || typeof window > "u") return t;
9
9
  try {
10
10
  const n = window.localStorage.getItem(e);
@@ -14,14 +14,14 @@ function pe(e, t, r = !0) {
14
14
  }
15
15
  return t;
16
16
  }
17
- function we(e, t, r = !0) {
17
+ function _e(e, t, r = !0) {
18
18
  if (!(!r || typeof window > "u"))
19
19
  try {
20
20
  window.localStorage.setItem(e, t ? "1" : "0");
21
21
  } catch {
22
22
  }
23
23
  }
24
- function F(e, t, r = !0) {
24
+ function T(e, t, r = !0) {
25
25
  if (!r || typeof window > "u") return t;
26
26
  try {
27
27
  const n = window.localStorage.getItem(e);
@@ -32,14 +32,14 @@ function F(e, t, r = !0) {
32
32
  }
33
33
  return t;
34
34
  }
35
- function se(e, t, r = !0) {
35
+ function he(e, t, r = !0) {
36
36
  if (!(!r || typeof window > "u"))
37
37
  try {
38
38
  window.localStorage.setItem(e, String(Math.round(t)));
39
39
  } catch {
40
40
  }
41
41
  }
42
- function ve(e = {}) {
42
+ function Ce(e = {}) {
43
43
  const {
44
44
  nav: t = "session-list",
45
45
  navParams: r,
@@ -48,9 +48,9 @@ function ve(e = {}) {
48
48
  surface: c,
49
49
  surfaceParams: l,
50
50
  sidebar: s,
51
- sidebarParams: w
52
- } = e, b = [];
53
- return t && b.push({
51
+ sidebarParams: x
52
+ } = e, w = [];
53
+ return t && w.push({
54
54
  id: "nav",
55
55
  position: "left",
56
56
  panel: t,
@@ -58,22 +58,22 @@ function ve(e = {}) {
58
58
  locked: !0,
59
59
  hideHeader: !0,
60
60
  constraints: { minWidth: 60, maxWidth: 60 }
61
- }), b.push({
61
+ }), w.push({
62
62
  id: "center",
63
63
  position: "center",
64
64
  panel: n,
65
65
  params: i,
66
66
  hideHeader: !0
67
- }), s && b.push({
67
+ }), s && w.push({
68
68
  id: "sidebar",
69
69
  position: "left",
70
70
  panel: s,
71
- params: w,
71
+ params: x,
72
72
  hideHeader: !0,
73
73
  collapsible: !0,
74
74
  collapsedWidth: 40,
75
75
  constraints: { minWidth: 200, maxWidthViewportRatio: 0.5 }
76
- }), c && b.push({
76
+ }), c && w.push({
77
77
  id: "surface",
78
78
  position: "right",
79
79
  panel: c,
@@ -81,72 +81,87 @@ function ve(e = {}) {
81
81
  hideHeader: !0,
82
82
  dynamic: !0,
83
83
  placeholder: "empty"
84
- }), { version: "2.0", groups: b };
84
+ }), { version: "2.0", groups: w };
85
85
  }
86
- function xe(e) {
87
- const t = e.nav !== null, r = e.surface !== void 0, n = !!e.surface, i = e.nav || "session-list", c = e.center ?? "chat", l = e.surface || "artifact-surface", s = ce(), [w, b] = E(
86
+ function Se(e) {
87
+ const t = e.nav !== null, r = e.surface !== void 0, n = !!e.surface, i = e.nav || "session-list", c = e.center ?? "chat", l = e.surface || "artifact-surface", s = me(), [x, w] = $(
88
88
  e.storageKey ? `${e.storageKey}:drawerWidth` : void 0,
89
89
  260
90
- ), [T, X] = E(
90
+ ), [G, J] = $(
91
91
  e.storageKey ? `${e.storageKey}:surfaceWidth` : void 0,
92
92
  680
93
- ), f = Y(), W = C(w, 200, 360), M = Math.max(480, Math.floor(s * 0.72)), P = C(T, 480, M), z = N(e.centerParams, "getSurface"), I = N(e.centerParams, "isWorkbenchOpen"), O = N(e.centerParams, "openWorkbench"), u = R(e.navParams, "onClose"), h = R(e.surfaceParams, "onClose"), B = R(e.navParams, "onCreate"), v = t ? !!u : !!e.onOpenNav, x = n ? !!h : !!e.onOpenSurface, y = p(() => {
93
+ ), u = ae(), z = O(x, 200, 360), K = Math.max(480, Math.floor(s * 0.72)), L = O(G, 480, K), R = y(e.centerParams, "getSurface"), D = y(e.centerParams, "isWorkbenchOpen"), A = y(e.centerParams, "openWorkbench"), j = y(e.centerParams, "closeWorkbench"), h = B(e.navParams, "onClose"), m = B(e.surfaceParams, "onClose"), p = B(e.sidebarParams, "onClose"), M = B(e.navParams, "onCreate"), v = !!e.sidebar, k = t ? !!h : !!e.onOpenNav, _ = n ? !!m : !!e.onOpenSurface, C = v ? !!p : !!e.onOpenSidebar, S = b(() => {
94
94
  var o;
95
95
  if (t) {
96
- u == null || u();
96
+ h == null || h();
97
97
  return;
98
98
  }
99
99
  (o = e.onOpenNav) == null || o.call(e);
100
- }, [u, t, e.onOpenNav]), k = p(() => {
100
+ }, [h, t, e.onOpenNav]), N = b(() => {
101
101
  var o;
102
102
  if (n) {
103
- h == null || h();
103
+ m == null || m();
104
104
  return;
105
105
  }
106
106
  (o = e.onOpenSurface) == null || o.call(e);
107
- }, [h, e.onOpenSurface, n]), _ = p(() => {
108
- t && (u == null || u()), n && (h == null || h()), A(), de();
109
- }, [u, h, t, n]);
110
- return ee({
111
- shortcuts: D(() => {
107
+ }, [m, e.onOpenSurface, n]), W = b(() => {
108
+ var o;
109
+ if (v) {
110
+ p == null || p();
111
+ return;
112
+ }
113
+ (o = e.onOpenSidebar) == null || o.call(e);
114
+ }, [p, e.onOpenSidebar, v]), P = b(() => {
115
+ t && (h == null || h()), n && (m == null || m()), E(), fe();
116
+ }, [h, m, t, n]);
117
+ return oe({
118
+ shortcuts: F(() => {
112
119
  const o = [];
113
- return v && o.push({ key: "1", mod: !0, handler: y }), x && o.push({ key: "2", mod: !0, handler: k }), c === "chat" && o.push({ key: "Escape", allowInEditable: !0, handler: _ }), o;
114
- }, [v, x, c, _, y, k])
115
- }), S(() => {
116
- const o = "workspace:chat-layout", m = "agent:chat-layout";
117
- return f.unregisterByPluginId(o), f.unregisterByPluginId(m), f.registerCommand({
120
+ return k && o.push({ key: "1", mod: !0, handler: S }), _ && o.push({ key: "2", mod: !0, handler: N }), C && o.push({ key: "3", mod: !0, allowInEditable: !0, handler: W }), c === "chat" && o.push({ key: "Escape", allowInEditable: !0, handler: P }), o;
121
+ }, [k, C, _, c, P, S, W, N])
122
+ }), I(() => {
123
+ const o = "workspace:chat-layout", f = "agent:chat-layout";
124
+ return u.unregisterByPluginId(o), u.unregisterByPluginId(f), u.registerCommand({
118
125
  id: "workspace:open-session-history",
119
126
  title: t ? "Close Session History" : "Open Session History",
120
127
  keywords: ["sessions", "history", "drawer", t ? "close" : "open"],
121
128
  shortcut: "⌘1",
122
129
  pluginId: o,
123
- when: () => v,
124
- run: y
125
- }), f.registerCommand({
130
+ when: () => k,
131
+ run: S
132
+ }), u.registerCommand({
126
133
  id: "workspace:open-workbench",
127
134
  title: n ? "Close Workbench" : "Open Workbench",
128
135
  keywords: ["surface", "artifacts", "sources", "workbench", n ? "close" : "open"],
129
136
  shortcut: "⌘2",
130
137
  pluginId: o,
131
- when: () => x,
132
- run: k
133
- }), c === "chat" && f.registerCommand({
138
+ when: () => _,
139
+ run: N
140
+ }), u.registerCommand({
141
+ id: "workspace:toggle-workbench-left-panel",
142
+ title: v ? "Close Workbench Left Panel" : "Open Workbench Left Panel",
143
+ keywords: ["left", "sidebar", "tabs", "workbench", v ? "close" : "open"],
144
+ shortcut: "⌘3",
145
+ pluginId: o,
146
+ when: () => C,
147
+ run: W
148
+ }), c === "chat" && u.registerCommand({
134
149
  id: "agent:focus-chat",
135
150
  title: "Focus Chat",
136
151
  keywords: ["agent", "chat", "prompt", "composer", "input", "focus"],
137
- pluginId: m,
138
- run: _
139
- }), B && f.registerCommand({
152
+ pluginId: f,
153
+ run: P
154
+ }), M && u.registerCommand({
140
155
  id: "agent:new-chat",
141
156
  title: "New Chat",
142
157
  keywords: ["agent", "chat", "session", "new"],
143
- pluginId: m,
144
- run: B
158
+ pluginId: f,
159
+ run: M
145
160
  }), () => {
146
- f.unregisterByPluginId(o), f.unregisterByPluginId(m);
161
+ u.unregisterByPluginId(o), u.unregisterByPluginId(f);
147
162
  };
148
163
  }, [
149
- f,
164
+ u,
150
165
  t,
151
166
  c,
152
167
  r,
@@ -155,25 +170,31 @@ function xe(e) {
155
170
  e.surfaceParams,
156
171
  e.onOpenNav,
157
172
  e.onOpenSurface,
158
- v,
159
- x,
160
- u,
161
- h,
162
- B,
173
+ e.onOpenSidebar,
174
+ k,
163
175
  _,
164
- y,
165
- k
166
- ]), S(() => {
167
- if (!z || !I || !O) return;
176
+ C,
177
+ h,
178
+ m,
179
+ p,
180
+ M,
181
+ P,
182
+ v,
183
+ S,
184
+ N,
185
+ W
186
+ ]), I(() => {
187
+ if (!R || !D || !A) return;
168
188
  const o = {
169
- surface: z,
170
- isWorkbenchOpen: I,
171
- openWorkbench: O
189
+ surface: R,
190
+ isWorkbenchOpen: D,
191
+ openWorkbench: A,
192
+ closeWorkbench: j
172
193
  };
173
- return te.on(ne.uiCommand, ({ command: m }) => {
174
- re(m, o);
194
+ return ie.on(se.uiCommand, ({ command: f }) => {
195
+ ce(f, o);
175
196
  });
176
- }, [z, I, O]), /* @__PURE__ */ d(
197
+ }, [R, D, A, j]), /* @__PURE__ */ d(
177
198
  "div",
178
199
  {
179
200
  "data-boring-workspace": "",
@@ -193,9 +214,9 @@ function xe(e) {
193
214
  t && "border-r border-[color:oklch(from_var(--border)_l_c_h/0.6)]"
194
215
  ),
195
216
  style: {
196
- width: t ? W : 0,
197
- minWidth: t ? W : 0,
198
- maxWidth: t ? W : 0,
217
+ width: t ? z : 0,
218
+ minWidth: t ? z : 0,
219
+ maxWidth: t ? z : 0,
199
220
  willChange: "width"
200
221
  },
201
222
  children: [
@@ -207,15 +228,15 @@ function xe(e) {
207
228
  "transition-opacity duration-[200ms] ease-[cubic-bezier(0.22,1,0.36,1)]",
208
229
  t ? "opacity-100" : "opacity-0"
209
230
  ),
210
- children: /* @__PURE__ */ a(L, { id: i, params: e.navParams })
231
+ children: /* @__PURE__ */ a(H, { id: i, params: e.navParams })
211
232
  }
212
233
  ),
213
234
  t ? /* @__PURE__ */ a(
214
- K,
235
+ X,
215
236
  {
216
237
  side: "drawer-right",
217
238
  ariaLabel: "Resize sessions drawer",
218
- onResize: (o) => b((m) => C(m + o, 200, 360))
239
+ onResize: (o) => w((f) => O(f + o, 200, 360))
219
240
  }
220
241
  ) : null
221
242
  ]
@@ -228,9 +249,9 @@ function xe(e) {
228
249
  "aria-label": "Chat stage",
229
250
  className: "relative h-full min-h-0 min-w-0 flex-1 overflow-hidden bg-background",
230
251
  children: [
231
- /* @__PURE__ */ a(L, { id: c, params: e.centerParams }),
252
+ /* @__PURE__ */ a(H, { id: c, params: e.centerParams }),
232
253
  !t && e.onOpenNav ? /* @__PURE__ */ a(
233
- j,
254
+ U,
234
255
  {
235
256
  side: "left",
236
257
  icon: "sessions",
@@ -240,7 +261,7 @@ function xe(e) {
240
261
  }
241
262
  ) : null,
242
263
  !n && e.onOpenSurface ? /* @__PURE__ */ a(
243
- j,
264
+ U,
244
265
  {
245
266
  side: "right",
246
267
  icon: "workbench",
@@ -265,9 +286,9 @@ function xe(e) {
265
286
  n && "border-l border-[color:oklch(from_var(--border)_l_c_h/0.6)]"
266
287
  ),
267
288
  style: {
268
- width: n ? P : 0,
269
- minWidth: n ? P : 0,
270
- maxWidth: n ? P : 0,
289
+ width: n ? L : 0,
290
+ minWidth: n ? L : 0,
291
+ maxWidth: n ? L : 0,
271
292
  willChange: "width"
272
293
  },
273
294
  children: [
@@ -279,15 +300,15 @@ function xe(e) {
279
300
  "transition-opacity duration-[200ms] ease-[cubic-bezier(0.22,1,0.36,1)]",
280
301
  n ? "opacity-100" : "opacity-0"
281
302
  ),
282
- children: /* @__PURE__ */ a(L, { id: l, params: e.surfaceParams })
303
+ children: /* @__PURE__ */ a(H, { id: l, params: e.surfaceParams })
283
304
  }
284
305
  ),
285
306
  n ? /* @__PURE__ */ a(
286
- K,
307
+ X,
287
308
  {
288
309
  side: "surface-left",
289
310
  ariaLabel: "Resize workbench",
290
- onResize: (o) => X((m) => C(m - o, 480, M))
311
+ onResize: (o) => J((f) => O(f - o, 480, K))
291
312
  }
292
313
  ) : null
293
314
  ]
@@ -297,46 +318,46 @@ function xe(e) {
297
318
  }
298
319
  );
299
320
  }
300
- function C(e, t, r) {
321
+ function O(e, t, r) {
301
322
  return Math.max(t, Math.min(r, e));
302
323
  }
303
- function E(e, t) {
304
- const [r, n] = V(
305
- () => e ? F(e, t) : t
324
+ function $(e, t) {
325
+ const [r, n] = q(
326
+ () => e ? T(e, t) : t
306
327
  );
307
- S(() => {
308
- n(e ? F(e, t) : t);
328
+ I(() => {
329
+ n(e ? T(e, t) : t);
309
330
  }, [e, t]);
310
- const i = p(
331
+ const i = b(
311
332
  (c) => {
312
333
  n((l) => {
313
334
  const s = typeof c == "function" ? c(l) : c;
314
- return e && se(e, s), s;
335
+ return e && he(e, s), s;
315
336
  });
316
337
  },
317
338
  [e]
318
339
  );
319
340
  return [r, i];
320
341
  }
321
- function ce() {
322
- const [e, t] = V(() => typeof window < "u" ? window.innerWidth : 1200);
323
- return S(() => {
342
+ function me() {
343
+ const [e, t] = q(() => typeof window < "u" ? window.innerWidth : 1200);
344
+ return I(() => {
324
345
  const r = () => t(window.innerWidth);
325
346
  return window.addEventListener("resize", r), () => window.removeEventListener("resize", r);
326
347
  }, []), e;
327
348
  }
328
- function K({ side: e, ariaLabel: t, onResize: r }) {
329
- const n = q(null), i = p((s) => {
349
+ function X({ side: e, ariaLabel: t, onResize: r }) {
350
+ const n = Y(null), i = b((s) => {
330
351
  s.preventDefault(), n.current = s.clientX, s.currentTarget.setPointerCapture(s.pointerId), document.body.style.cursor = "col-resize", document.body.style.userSelect = "none";
331
- }, []), c = p((s) => {
352
+ }, []), c = b((s) => {
332
353
  if (n.current === null) return;
333
- const w = s.clientX - n.current;
334
- n.current = s.clientX, r(w);
335
- }, [r]), l = p((s) => {
354
+ const x = s.clientX - n.current;
355
+ n.current = s.clientX, r(x);
356
+ }, [r]), l = b((s) => {
336
357
  n.current !== null && (n.current = null, s.currentTarget.releasePointerCapture(s.pointerId), document.body.style.cursor = "", document.body.style.userSelect = "");
337
358
  }, []);
338
359
  return /* @__PURE__ */ a(
339
- G,
360
+ te,
340
361
  {
341
362
  "aria-label": t,
342
363
  orientation: "vertical",
@@ -354,28 +375,28 @@ function K({ side: e, ariaLabel: t, onResize: r }) {
354
375
  }
355
376
  );
356
377
  }
357
- function N(e, t) {
378
+ function y(e, t) {
358
379
  const r = e == null ? void 0 : e[t];
359
380
  return typeof r == "function" ? r : void 0;
360
381
  }
361
- function R(e, t) {
362
- return N(e, t);
382
+ function B(e, t) {
383
+ return y(e, t);
363
384
  }
364
- function A() {
385
+ function E() {
365
386
  if (typeof document > "u") return;
366
387
  const e = document.querySelector(
367
388
  '[data-boring-agent] textarea[name="message"], textarea[name="message"]'
368
389
  );
369
390
  e == null || e.focus();
370
391
  }
371
- function de() {
392
+ function fe() {
372
393
  typeof window > "u" || window.requestAnimationFrame(() => {
373
- A(), window.setTimeout(A, 320);
394
+ E(), window.setTimeout(E, 320);
374
395
  });
375
396
  }
376
- function L({ id: e, params: t }) {
377
- const r = ae(), i = D(() => r.getComponents(), [r])[e], c = D(() => le(e), [e]);
378
- return i ? /* @__PURE__ */ a(U, { fallback: /* @__PURE__ */ a(Z, { centered: !0 }), children: /* @__PURE__ */ a(
397
+ function H({ id: e, params: t }) {
398
+ const r = de(), i = F(() => r.getComponents(), [r])[e], c = F(() => ge(e), [e]);
399
+ return i ? /* @__PURE__ */ a(Q, { fallback: /* @__PURE__ */ a(ee, { centered: !0 }), children: /* @__PURE__ */ a(
379
400
  i,
380
401
  {
381
402
  params: t,
@@ -384,7 +405,7 @@ function L({ id: e, params: t }) {
384
405
  }
385
406
  ) }) : null;
386
407
  }
387
- function le(e) {
408
+ function ge(e) {
388
409
  return {
389
410
  id: e,
390
411
  title: e,
@@ -420,7 +441,7 @@ function le(e) {
420
441
  } })
421
442
  };
422
443
  }
423
- function j({
444
+ function U({
424
445
  side: e,
425
446
  icon: t,
426
447
  onClick: r,
@@ -428,7 +449,7 @@ function j({
428
449
  hint: i
429
450
  }) {
430
451
  return /* @__PURE__ */ a(
431
- $,
452
+ Z,
432
453
  {
433
454
  type: "button",
434
455
  variant: "ghost",
@@ -450,7 +471,7 @@ function j({
450
471
  }
451
472
  );
452
473
  }
453
- function ye({
474
+ function Ne({
454
475
  appTitle: e = "Boring",
455
476
  sessionTitle: t,
456
477
  onCommandPalette: r,
@@ -472,7 +493,7 @@ function ye({
472
493
  style: { height: 40 },
473
494
  "aria-label": "App top bar",
474
495
  children: [
475
- /* @__PURE__ */ a("div", { className: "flex min-w-0 flex-1 items-center gap-2.5", children: i ?? /* @__PURE__ */ d(H, { children: [
496
+ /* @__PURE__ */ a("div", { className: "flex min-w-0 flex-1 items-center gap-2.5", children: i ?? /* @__PURE__ */ d(V, { children: [
476
497
  /* @__PURE__ */ a(
477
498
  "img",
478
499
  {
@@ -482,31 +503,31 @@ function ye({
482
503
  }
483
504
  ),
484
505
  /* @__PURE__ */ a("span", { className: "truncate text-[12px] font-medium tracking-tight text-foreground", children: e }),
485
- t && /* @__PURE__ */ d(H, { children: [
506
+ t && /* @__PURE__ */ d(V, { children: [
486
507
  /* @__PURE__ */ a("span", { "aria-hidden": "true", className: "text-muted-foreground/30", children: "/" }),
487
508
  /* @__PURE__ */ a("span", { className: "truncate text-[12px] font-normal text-muted-foreground", children: t })
488
509
  ] })
489
510
  ] }) }),
490
511
  /* @__PURE__ */ d(
491
- J,
512
+ ne,
492
513
  {
493
514
  type: "button",
494
515
  variant: "ghost",
495
516
  size: "sm",
496
517
  onClick: r,
497
- className: "group h-6 gap-1 px-1.5 text-[12px] text-muted-foreground/60 hover:bg-transparent hover:text-foreground focus-visible:text-foreground",
518
+ className: "group h-6 gap-1 px-1.5 text-[12px] text-muted-foreground/60 hover:bg-muted/60 hover:text-foreground focus-visible:text-foreground",
498
519
  "aria-label": "Search catalogs and commands",
499
520
  title: "Command palette (⌘K)",
500
521
  children: [
501
- /* @__PURE__ */ a(oe, { className: "h-3 w-3 shrink-0 opacity-70", strokeWidth: 1.75 }),
522
+ /* @__PURE__ */ a(le, { className: "h-3 w-3 shrink-0 opacity-70", strokeWidth: 1.75 }),
502
523
  /* @__PURE__ */ a("span", { className: "font-normal tracking-tight", children: "Search" }),
503
- /* @__PURE__ */ a(Q, { className: "ml-1 border-0 bg-transparent p-0 text-[10px] shadow-none group-hover:text-muted-foreground", children: "⌘K" })
524
+ /* @__PURE__ */ a(re, { className: "ml-1 border-0 bg-transparent p-0 text-[10px] shadow-none group-hover:text-muted-foreground", children: "⌘K" })
504
525
  ]
505
526
  }
506
527
  ),
507
528
  /* @__PURE__ */ d("div", { className: "flex flex-1 shrink-0 items-center justify-end gap-1", children: [
508
529
  n && /* @__PURE__ */ a(
509
- $,
530
+ Z,
510
531
  {
511
532
  type: "button",
512
533
  variant: "ghost",
@@ -514,7 +535,7 @@ function ye({
514
535
  onClick: n,
515
536
  "aria-label": "New chat",
516
537
  title: "New chat",
517
- children: /* @__PURE__ */ a(ie, { className: "h-4 w-4" })
538
+ children: /* @__PURE__ */ a(ue, { className: "h-4 w-4" })
518
539
  }
519
540
  ),
520
541
  s
@@ -523,7 +544,7 @@ function ye({
523
544
  }
524
545
  );
525
546
  }
526
- function ke({
547
+ function We({
527
548
  title: e = "Loading workspace",
528
549
  description: t = "Preparing the workspace context.",
529
550
  status: r = "Loading",
@@ -559,10 +580,10 @@ function ke({
559
580
  );
560
581
  }
561
582
  export {
562
- xe as C,
563
- ye as T,
564
- ke as W,
565
- ve as b,
566
- pe as r,
567
- we as w
583
+ Se as C,
584
+ Ne as T,
585
+ We as W,
586
+ Ce as b,
587
+ ke as r,
588
+ _e as w
568
589
  };
@@ -0,0 +1,100 @@
1
+ interface UiBridge {
2
+ getState(): Promise<UiState | null>;
3
+ setState(state: UiState): Promise<void>;
4
+ postCommand(cmd: UiCommand): Promise<CommandResult>;
5
+ subscribeCommands(handler: (cmd: UiCommand & {
6
+ seq: number;
7
+ }) => void): () => void;
8
+ drainCommands?(): Promise<Array<UiCommand & {
9
+ seq: number;
10
+ }>>;
11
+ }
12
+ type UiState = Record<string, unknown>;
13
+ type UiCommand = {
14
+ kind: 'openFile';
15
+ params: {
16
+ path: string;
17
+ mode?: 'view' | 'edit' | 'diff';
18
+ };
19
+ } | {
20
+ kind: 'openSurface';
21
+ params: {
22
+ kind: string;
23
+ target: string;
24
+ meta?: Record<string, unknown>;
25
+ };
26
+ } | {
27
+ kind: 'openPanel';
28
+ params: {
29
+ id: string;
30
+ component: string;
31
+ params?: Record<string, unknown>;
32
+ };
33
+ } | {
34
+ kind: 'closePanel';
35
+ params: {
36
+ id: string;
37
+ };
38
+ } | {
39
+ kind: 'closeWorkbenchLeftPane';
40
+ params: Record<string, never>;
41
+ } | {
42
+ kind: 'showNotification';
43
+ params: {
44
+ msg: string;
45
+ level?: 'info' | 'warn' | 'error';
46
+ };
47
+ } | {
48
+ kind: 'navigateToLine';
49
+ params: {
50
+ file: string;
51
+ line: number;
52
+ };
53
+ } | {
54
+ kind: 'expandToFile';
55
+ params: {
56
+ path: string;
57
+ };
58
+ } | {
59
+ kind: string;
60
+ params: Record<string, unknown>;
61
+ };
62
+ interface CommandResult {
63
+ seq: number;
64
+ status: 'ok' | 'error';
65
+ error?: {
66
+ code: string;
67
+ message: string;
68
+ };
69
+ }
70
+
71
+ type JSONSchema = Record<string, unknown>;
72
+ interface ToolExecContext {
73
+ abortSignal: AbortSignal;
74
+ toolCallId: string;
75
+ onUpdate?: (partial: string) => void;
76
+ /** Agent chat/session id executing this tool, when known. */
77
+ sessionId?: string;
78
+ }
79
+ interface ToolResult {
80
+ content: Array<{
81
+ type: "text";
82
+ text: string;
83
+ }>;
84
+ isError?: boolean;
85
+ details?: unknown;
86
+ }
87
+ /**
88
+ * Structural tool contract accepted from workspace plugins and UI tool
89
+ * factories. Kept agent-runtime-neutral so only the app integration layer
90
+ * needs to import @hachej/boring-agent.
91
+ */
92
+ interface AgentTool {
93
+ name: string;
94
+ description: string;
95
+ promptSnippet?: string;
96
+ parameters: JSONSchema;
97
+ execute(params: Record<string, unknown>, ctx: ToolExecContext): Promise<ToolResult>;
98
+ }
99
+
100
+ export type { AgentTool as A, CommandResult as C, JSONSchema as J, ToolExecContext as T, UiBridge as U, UiCommand as a, UiState as b, ToolResult as c };