@hachej/boring-workspace 0.1.13 → 0.1.16

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,502 +0,0 @@
1
- import { jsxs as T, jsx as r } from "react/jsx-runtime";
2
- import { useState as R, useCallback as z, useRef as L, useEffect as N, useMemo as D } from "react";
3
- import { ReactNodeViewRenderer as W, NodeViewWrapper as P, useEditor as j, EditorContent as q, useEditorState as _ } from "@tiptap/react";
4
- import V from "@tiptap/starter-kit";
5
- import O from "@tiptap/extension-underline";
6
- import X from "@tiptap/extension-link";
7
- import B from "@tiptap/extension-placeholder";
8
- import K from "@tiptap/extension-task-list";
9
- import Q from "@tiptap/extension-task-item";
10
- import Z from "@tiptap/extension-text-align";
11
- import G from "@tiptap/extension-highlight";
12
- import { Table as J } from "@tiptap/extension-table";
13
- import { TableRow as Y } from "@tiptap/extension-table-row";
14
- import { TableHeader as tt } from "@tiptap/extension-table-header";
15
- import { TableCell as et } from "@tiptap/extension-table-cell";
16
- import rt from "@tiptap/extension-image";
17
- import { c as y } from "./utils-B6yFEsav.js";
18
- import { an as U, ao as it } from "./CommandPalette-Dme9em28.js";
19
- import { uploadFile as nt } from "@hachej/boring-agent/front";
20
- import at from "@tiptap/extension-code-block-lowlight";
21
- import { createLowlight as ot, common as lt } from "lowlight";
22
- import { Markdown as st } from "@tiptap/markdown";
23
- import { BoldIcon as ct, ItalicIcon as ut, UnderlineIcon as gt, StrikethroughIcon as ft, Heading1Icon as dt, Heading2Icon as mt, Heading3Icon as ht, ListIcon as pt, ListOrderedIcon as wt, ListChecksIcon as kt, QuoteIcon as vt, CodeIcon as bt, LinkIcon as It, ImageIcon as At, HighlighterIcon as Lt, AlignLeftIcon as xt, AlignCenterIcon as yt, AlignRightIcon as Ct, MinusIcon as Nt } from "lucide-react";
24
- import { Toolbar as Tt, Input as Rt, ToolbarButton as Ht, ToolbarSeparator as Mt } from "@hachej/boring-ui-kit";
25
- function St(t) {
26
- const i = U(), n = it(), [a, s] = R(0);
27
- return { upload: z(
28
- async (o, d) => {
29
- s((m) => m + 1);
30
- try {
31
- return await nt(o, {
32
- apiBaseUrl: i,
33
- workspaceRequestId: n,
34
- directory: (d == null ? void 0 : d.directory) ?? (t == null ? void 0 : t.directory),
35
- sourcePath: d == null ? void 0 : d.sourcePath
36
- });
37
- } finally {
38
- s((m) => m - 1);
39
- }
40
- },
41
- [i, n, t == null ? void 0 : t.directory]
42
- ), uploading: a > 0 };
43
- }
44
- const H = 64, M = 2e3;
45
- function $t(t) {
46
- return t.replace(/\\/g, "\\\\").replace(/]/g, "\\]");
47
- }
48
- function C(t) {
49
- return t.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
50
- }
51
- function S(t) {
52
- if (typeof t == "number" && Number.isFinite(t) && t > 0) return t;
53
- if (typeof t == "string" && t.trim()) {
54
- const i = Number(t);
55
- if (Number.isFinite(i) && i > 0) return i;
56
- }
57
- return null;
58
- }
59
- const E = rt.extend({
60
- name: "image",
61
- draggable: !0,
62
- addOptions() {
63
- var t;
64
- return {
65
- ...(t = this.parent) == null ? void 0 : t.call(this),
66
- resolveSrc: (i) => i
67
- };
68
- },
69
- parseMarkdown: (t, i) => i.createNode("image", {
70
- src: t.href,
71
- title: t.title,
72
- alt: t.text
73
- }),
74
- renderMarkdown: (t) => {
75
- var I, b, e, p, k, v, A;
76
- const i = typeof ((I = t.attrs) == null ? void 0 : I.src) == "string" ? t.attrs.src : "", n = typeof ((b = t.attrs) == null ? void 0 : b.alt) == "string" ? t.attrs.alt : "", a = typeof ((e = t.attrs) == null ? void 0 : e.title) == "string" ? t.attrs.title : "", s = S((p = t.attrs) == null ? void 0 : p.width), c = S((k = t.attrs) == null ? void 0 : k.height), o = ((v = t.attrs) == null ? void 0 : v.align) === "center" || ((A = t.attrs) == null ? void 0 : A.align) === "right" ? t.attrs.align : "left";
77
- if (!s && !c && o === "left") {
78
- const w = $t(n);
79
- return a ? `![${w}](${i} "${a.replace(/"/g, '\\"')}")` : `![${w}](${i})`;
80
- }
81
- const m = `<img ${[
82
- `src="${C(i)}"`,
83
- n ? `alt="${C(n)}"` : null,
84
- a ? `title="${C(a)}"` : null,
85
- s ? `width="${s}"` : null,
86
- c ? `height="${c}"` : null
87
- ].filter(Boolean).join(" ")} />`;
88
- return o === "center" || o === "right" ? `<p align="${o}">${m}</p>` : m;
89
- },
90
- addAttributes() {
91
- var i;
92
- return {
93
- ...((i = this.parent) == null ? void 0 : i.call(this)) ?? {},
94
- width: {
95
- default: null,
96
- parseHTML: (n) => {
97
- const a = n.getAttribute("width");
98
- if (a) {
99
- const c = parseInt(a, 10);
100
- return Number.isFinite(c) ? c : null;
101
- }
102
- const s = n.style.width;
103
- if (s && s.endsWith("px")) {
104
- const c = parseInt(s, 10);
105
- return Number.isFinite(c) ? c : null;
106
- }
107
- return null;
108
- },
109
- renderHTML: (n) => n.width ? { width: String(n.width) } : {}
110
- },
111
- align: {
112
- default: "left",
113
- parseHTML: (n) => {
114
- const a = n.getAttribute("data-align");
115
- return a === "left" || a === "center" || a === "right" ? a : n.style.marginLeft === "auto" && n.style.marginRight === "auto" ? "center" : n.style.marginLeft === "auto" ? "right" : "left";
116
- },
117
- renderHTML: (n) => ({ "data-align": n.align ?? "left" })
118
- }
119
- };
120
- },
121
- addNodeView() {
122
- return W(Bt);
123
- }
124
- });
125
- function Bt({ node: t, updateAttributes: i, selected: n, extension: a }) {
126
- const s = L(null), c = L(null), [o, d] = R(!1), m = t.attrs.src ?? "", b = (a.options.resolveSrc ?? ((w) => w))(m), e = t.attrs.alt ?? "", p = t.attrs.title ?? void 0, k = t.attrs.width, v = t.attrs.align ?? "left";
127
- N(() => {
128
- if (!o) return;
129
- const w = (g) => {
130
- const l = c.current;
131
- if (!l) return;
132
- const h = g.clientX - l.x, F = Math.max(H, Math.min(M, l.width + h));
133
- i({ width: Math.round(F) });
134
- }, u = () => {
135
- c.current = null, d(!1);
136
- };
137
- return window.addEventListener("pointermove", w), window.addEventListener("pointerup", u), window.addEventListener("pointercancel", u), () => {
138
- window.removeEventListener("pointermove", w), window.removeEventListener("pointerup", u), window.removeEventListener("pointercancel", u);
139
- };
140
- }, [o, i]);
141
- const A = (w) => {
142
- var l;
143
- w.preventDefault(), w.stopPropagation();
144
- const u = (l = s.current) == null ? void 0 : l.querySelector("img"), g = k ?? (u == null ? void 0 : u.getBoundingClientRect().width) ?? 320;
145
- c.current = { x: w.clientX, width: g }, d(!0);
146
- };
147
- return /* @__PURE__ */ T(
148
- P,
149
- {
150
- ref: s,
151
- "data-resizable-image": "",
152
- "data-selected": n ? "true" : void 0,
153
- className: y(
154
- "relative block max-w-full align-baseline",
155
- "[&>img]:block [&>img]:max-w-full [&>img]:h-auto [&>img]:rounded-md",
156
- v === "left" && "mr-auto",
157
- v === "center" && "mx-auto",
158
- v === "right" && "ml-auto",
159
- n && "ring-2 ring-[color:var(--accent)] ring-offset-1 ring-offset-background"
160
- ),
161
- style: { width: k ? `${k}px` : void 0 },
162
- children: [
163
- /* @__PURE__ */ r("img", { src: b, alt: e, title: p, draggable: !1 }),
164
- /* @__PURE__ */ r(
165
- "span",
166
- {
167
- role: "slider",
168
- "aria-label": "Resize image",
169
- "aria-valuenow": k ?? 0,
170
- "aria-valuemin": H,
171
- "aria-valuemax": M,
172
- "data-testid": "resize-handle",
173
- onPointerDown: A,
174
- className: y(
175
- "absolute right-0 bottom-0 h-3 w-3 translate-x-1/2 translate-y-1/2 cursor-nwse-resize",
176
- "rounded-full border border-background bg-[color:var(--accent)] shadow",
177
- "opacity-0 transition-opacity duration-150 ease-out",
178
- (n || o) && "opacity-100"
179
- )
180
- }
181
- )
182
- ]
183
- }
184
- );
185
- }
186
- const Ut = ot(lt), Et = [
187
- /<script[\s>][\s\S]*?<\/script>/gi,
188
- /<iframe[\s>][\s\S]*?<\/iframe>/gi,
189
- /\s+on\w+\s*=\s*["'][^"']*["']/gi,
190
- /\s+on\w+\s*=\s*\S+/gi,
191
- /href\s*=\s*["']?\s*javascript:[^"'\s>]*/gi,
192
- /src\s*=\s*["']?\s*javascript:[^"'\s>]*/gi
193
- ];
194
- function Ft(t) {
195
- let i = t;
196
- for (const n of Et)
197
- i = i.replace(n, "");
198
- return i;
199
- }
200
- function zt(t) {
201
- return /^(?:[a-z][a-z0-9+.-]*:|\/|#)/i.test(t);
202
- }
203
- function Dt(t, i) {
204
- const n = t.match(/^([^?#]*)([?#].*)?$/), a = (n == null ? void 0 : n[1]) ?? t, s = (n == null ? void 0 : n[2]) ?? "", c = i != null && i.includes("/") ? i.slice(0, i.lastIndexOf("/")) : "", o = `${c ? `${c}/` : ""}${a}`.split("/"), d = [];
205
- for (const m of o)
206
- !m || m === "." || (m === ".." ? d.pop() : d.push(m));
207
- return `${d.join("/")}${s}`;
208
- }
209
- function Wt(t, i, n) {
210
- if (!t || zt(t)) return t;
211
- const a = Dt(t, i);
212
- return `${n.replace(/\/$/, "")}/api/v1/files/raw?path=${encodeURIComponent(a)}`;
213
- }
214
- const Pt = [
215
- V.configure({
216
- codeBlock: !1,
217
- link: !1,
218
- underline: !1
219
- }),
220
- O,
221
- X.configure({
222
- openOnClick: !0,
223
- autolink: !0,
224
- linkOnPaste: !0,
225
- defaultProtocol: "https",
226
- HTMLAttributes: { rel: "noopener noreferrer nofollow", target: "_blank" }
227
- }),
228
- B.configure({
229
- placeholder: "Start writing..."
230
- }),
231
- K,
232
- Q.configure({ nested: !0 }),
233
- Z.configure({
234
- types: ["heading", "paragraph"]
235
- }),
236
- G,
237
- J.configure({
238
- resizable: !0
239
- }),
240
- Y,
241
- tt,
242
- et,
243
- E.configure({
244
- inline: !1,
245
- allowBase64: !0
246
- }),
247
- at.configure({ lowlight: Ut }),
248
- st.configure({
249
- markedOptions: {
250
- gfm: !0,
251
- breaks: !1,
252
- pedantic: !1
253
- }
254
- })
255
- ];
256
- function f({ onClick: t, active: i, disabled: n, title: a, children: s }) {
257
- return /* @__PURE__ */ r(
258
- Ht,
259
- {
260
- type: "button",
261
- size: "icon-xs",
262
- onClick: t,
263
- disabled: n,
264
- title: a,
265
- "aria-pressed": i,
266
- className: y(
267
- "text-muted-foreground/70",
268
- i && "bg-[color:var(--accent-soft)] text-[color:var(--accent)]"
269
- ),
270
- children: s
271
- }
272
- );
273
- }
274
- function x() {
275
- return /* @__PURE__ */ r(Mt, { className: "mx-2 h-3.5" });
276
- }
277
- function $(t) {
278
- const i = t.trim().toLowerCase();
279
- return !i.startsWith("javascript:") && !i.startsWith("data:text/html");
280
- }
281
- function jt(t) {
282
- return new Promise((i, n) => {
283
- const a = new FileReader();
284
- a.onload = () => i(a.result), a.onerror = () => n(a.error ?? new Error("Read failed")), a.readAsDataURL(t);
285
- });
286
- }
287
- function qt(t) {
288
- if (!t) return null;
289
- for (const i of Array.from(t.files ?? []))
290
- if (i.type.startsWith("image/")) return i;
291
- for (const i of Array.from(t.items ?? [])) {
292
- if (i.kind !== "file" || !i.type.startsWith("image/")) continue;
293
- const n = i.getAsFile();
294
- if (n) return n;
295
- }
296
- return null;
297
- }
298
- function _t({
299
- editor: t,
300
- onInsertImage: i,
301
- rawMode: n,
302
- onToggleRawMode: a
303
- }) {
304
- const s = (e) => {
305
- if (t) {
306
- if (t.isActive("image")) {
307
- t.chain().focus().updateAttributes("image", { align: e }).run();
308
- return;
309
- }
310
- t.chain().focus().setTextAlign(e).run();
311
- }
312
- }, c = L(null), o = _({
313
- editor: t,
314
- selector: ({ editor: e }) => e ? {
315
- bold: e.isActive("bold"),
316
- italic: e.isActive("italic"),
317
- underline: e.isActive("underline"),
318
- strike: e.isActive("strike"),
319
- h1: e.isActive("heading", { level: 1 }),
320
- h2: e.isActive("heading", { level: 2 }),
321
- h3: e.isActive("heading", { level: 3 }),
322
- bulletList: e.isActive("bulletList"),
323
- orderedList: e.isActive("orderedList"),
324
- taskList: e.isActive("taskList"),
325
- blockquote: e.isActive("blockquote"),
326
- codeBlock: e.isActive("codeBlock"),
327
- link: e.isActive("link"),
328
- highlight: e.isActive("highlight"),
329
- alignLeft: e.isActive("image") ? (e.getAttributes("image").align ?? "left") === "left" : e.isActive({ textAlign: "left" }),
330
- alignCenter: e.isActive("image") ? e.getAttributes("image").align === "center" : e.isActive({ textAlign: "center" }),
331
- alignRight: e.isActive("image") ? e.getAttributes("image").align === "right" : e.isActive({ textAlign: "right" })
332
- } : null
333
- });
334
- if (!t || !o) return null;
335
- const d = () => {
336
- const e = window.prompt("URL:");
337
- e && $(e) && t.chain().focus().extendMarkRange("link").setLink({ href: e }).run();
338
- }, m = () => {
339
- const e = window.prompt("Image URL:");
340
- e && $(e) && t.chain().focus().setImage({ src: e }).run();
341
- }, I = (e) => {
342
- var p;
343
- if (e != null && e.shiftKey) {
344
- m();
345
- return;
346
- }
347
- (p = c.current) == null || p.click();
348
- }, b = async (e) => {
349
- var k;
350
- const p = (k = e.target.files) == null ? void 0 : k[0];
351
- e.target.value = "", !(!p || !p.type.startsWith("image/")) && await i(p);
352
- };
353
- return /* @__PURE__ */ T(Tt, { className: "border-b border-border/60 bg-background px-3 py-1.5", "aria-label": "Formatting toolbar", children: [
354
- /* @__PURE__ */ r(f, { onClick: () => t.chain().focus().toggleBold().run(), active: o.bold, title: "Bold", children: /* @__PURE__ */ r(ct, { className: "h-4 w-4" }) }),
355
- /* @__PURE__ */ r(f, { onClick: () => t.chain().focus().toggleItalic().run(), active: o.italic, title: "Italic", children: /* @__PURE__ */ r(ut, { className: "h-4 w-4" }) }),
356
- /* @__PURE__ */ r(f, { onClick: () => t.chain().focus().toggleUnderline().run(), active: o.underline, title: "Underline", children: /* @__PURE__ */ r(gt, { className: "h-4 w-4" }) }),
357
- /* @__PURE__ */ r(f, { onClick: () => t.chain().focus().toggleStrike().run(), active: o.strike, title: "Strikethrough", children: /* @__PURE__ */ r(ft, { className: "h-4 w-4" }) }),
358
- /* @__PURE__ */ r(x, {}),
359
- /* @__PURE__ */ r(f, { onClick: () => t.chain().focus().toggleHeading({ level: 1 }).run(), active: o.h1, title: "Heading 1", children: /* @__PURE__ */ r(dt, { className: "h-4 w-4" }) }),
360
- /* @__PURE__ */ r(f, { onClick: () => t.chain().focus().toggleHeading({ level: 2 }).run(), active: o.h2, title: "Heading 2", children: /* @__PURE__ */ r(mt, { className: "h-4 w-4" }) }),
361
- /* @__PURE__ */ r(f, { onClick: () => t.chain().focus().toggleHeading({ level: 3 }).run(), active: o.h3, title: "Heading 3", children: /* @__PURE__ */ r(ht, { className: "h-4 w-4" }) }),
362
- /* @__PURE__ */ r(x, {}),
363
- /* @__PURE__ */ r(f, { onClick: () => t.chain().focus().toggleBulletList().run(), active: o.bulletList, title: "Bullet list", children: /* @__PURE__ */ r(pt, { className: "h-4 w-4" }) }),
364
- /* @__PURE__ */ r(f, { onClick: () => t.chain().focus().toggleOrderedList().run(), active: o.orderedList, title: "Ordered list", children: /* @__PURE__ */ r(wt, { className: "h-4 w-4" }) }),
365
- /* @__PURE__ */ r(f, { onClick: () => t.chain().focus().toggleTaskList().run(), active: o.taskList, title: "Task list", children: /* @__PURE__ */ r(kt, { className: "h-4 w-4" }) }),
366
- /* @__PURE__ */ r(x, {}),
367
- /* @__PURE__ */ r(f, { onClick: () => t.chain().focus().toggleBlockquote().run(), active: o.blockquote, title: "Quote", children: /* @__PURE__ */ r(vt, { className: "h-4 w-4" }) }),
368
- /* @__PURE__ */ r(f, { onClick: () => t.chain().focus().toggleCodeBlock().run(), active: o.codeBlock, title: "Code block", children: /* @__PURE__ */ r(bt, { className: "h-4 w-4" }) }),
369
- /* @__PURE__ */ r(f, { onClick: d, active: o.link, title: "Link", children: /* @__PURE__ */ r(It, { className: "h-4 w-4" }) }),
370
- /* @__PURE__ */ r(
371
- f,
372
- {
373
- onClick: I,
374
- title: "Image (click to upload, Shift+click for URL)",
375
- children: /* @__PURE__ */ r(At, { className: "h-4 w-4" })
376
- }
377
- ),
378
- /* @__PURE__ */ r(
379
- Rt,
380
- {
381
- ref: c,
382
- "data-testid": "image-file-input",
383
- type: "file",
384
- accept: "image/*",
385
- className: "hidden",
386
- onChange: b
387
- }
388
- ),
389
- /* @__PURE__ */ r(f, { onClick: () => t.chain().focus().toggleHighlight().run(), active: o.highlight, title: "Highlight", children: /* @__PURE__ */ r(Lt, { className: "h-4 w-4" }) }),
390
- /* @__PURE__ */ r(x, {}),
391
- /* @__PURE__ */ r(f, { onClick: () => s("left"), active: o.alignLeft, title: "Align left", children: /* @__PURE__ */ r(xt, { className: "h-4 w-4" }) }),
392
- /* @__PURE__ */ r(f, { onClick: () => s("center"), active: o.alignCenter, title: "Center align", children: /* @__PURE__ */ r(yt, { className: "h-4 w-4" }) }),
393
- /* @__PURE__ */ r(f, { onClick: () => s("right"), active: o.alignRight, title: "Align right", children: /* @__PURE__ */ r(Ct, { className: "h-4 w-4" }) }),
394
- /* @__PURE__ */ r(x, {}),
395
- /* @__PURE__ */ r(f, { onClick: () => t.chain().focus().setHorizontalRule().run(), title: "Horizontal rule", children: /* @__PURE__ */ r(Nt, { className: "h-4 w-4" }) }),
396
- /* @__PURE__ */ r(x, {}),
397
- /* @__PURE__ */ r(
398
- f,
399
- {
400
- onClick: a,
401
- active: n,
402
- title: n ? "Rich text" : "Raw markdown",
403
- children: /* @__PURE__ */ r("span", { className: "font-mono text-[10px] font-semibold leading-none tracking-[-0.02em]", children: "MD" })
404
- }
405
- )
406
- ] });
407
- }
408
- function he({
409
- content: t,
410
- onChange: i,
411
- readOnly: n = !1,
412
- placeholder: a,
413
- className: s,
414
- documentPath: c
415
- }) {
416
- const o = U(), { upload: d } = St(), [m, I] = R(!1), b = D(() => {
417
- const g = E.configure({
418
- inline: !1,
419
- allowBase64: !0,
420
- resolveSrc: (h) => Wt(h, c, o)
421
- }), l = Pt.map((h) => h.name === "image" ? g : h);
422
- return a ? [
423
- ...l.filter((h) => h.name !== "placeholder"),
424
- B.configure({ placeholder: a })
425
- ] : l;
426
- }, [o, c, a]), e = L(i);
427
- e.current = i;
428
- const p = L(!1), k = L(null), v = L(async () => {
429
- });
430
- v.current = async (g) => {
431
- const l = k.current;
432
- if (l)
433
- try {
434
- const { url: h } = await d(g, { sourcePath: c });
435
- l.chain().focus().setImage({ src: h, alt: g.name }).run();
436
- } catch {
437
- try {
438
- const h = await jt(g);
439
- l.chain().focus().setImage({ src: h, alt: g.name }).run();
440
- } catch {
441
- }
442
- }
443
- };
444
- const A = t || { type: "doc", content: [{ type: "paragraph" }] }, w = t ? "markdown" : "json", u = j({
445
- extensions: b,
446
- content: A,
447
- contentType: w,
448
- editable: !n,
449
- editorProps: {
450
- attributes: {
451
- class: "tiptap-prose max-w-[68ch] px-8 py-6 focus:outline-none min-h-[200px]"
452
- },
453
- transformPastedHTML: Ft,
454
- handlePaste: (g, l) => {
455
- if (n) return !1;
456
- const h = qt(l.clipboardData);
457
- return h ? (l.preventDefault(), v.current(h), !0) : !1;
458
- }
459
- },
460
- onUpdate: ({ editor: g }) => {
461
- var l, h;
462
- p.current || (h = e.current) == null || h.call(e, ((l = g.getMarkdown) == null ? void 0 : l.call(g)) ?? g.getHTML());
463
- }
464
- });
465
- return k.current = u, N(() => {
466
- !u || u.isDestroyed || u.setEditable(!n);
467
- }, [u, n]), N(() => {
468
- var l;
469
- !u || u.isDestroyed || (((l = u.getMarkdown) == null ? void 0 : l.call(u)) ?? u.getHTML()) === t || (p.current = !0, u.commands.setContent(A, { contentType: w }), p.current = !1);
470
- }, [u, t]), /* @__PURE__ */ T("div", { className: y("flex h-full flex-col overflow-hidden", s), children: [
471
- !n && /* @__PURE__ */ r(
472
- _t,
473
- {
474
- editor: u,
475
- onInsertImage: (g) => v.current(g),
476
- rawMode: m,
477
- onToggleRawMode: () => I((g) => !g)
478
- }
479
- ),
480
- /* @__PURE__ */ r("div", { className: "flex-1 overflow-auto", children: m && !n ? /* @__PURE__ */ r(
481
- "textarea",
482
- {
483
- "aria-label": "Raw markdown",
484
- "data-testid": "markdown-raw-editor",
485
- className: "h-full min-h-[200px] w-full resize-none bg-background px-8 py-6 font-mono text-[13px] leading-6 text-foreground outline-none placeholder:text-muted-foreground/70",
486
- value: t,
487
- placeholder: a,
488
- spellCheck: !1,
489
- onChange: (g) => {
490
- var l;
491
- return (l = e.current) == null ? void 0 : l.call(e, g.target.value);
492
- }
493
- }
494
- ) : /* @__PURE__ */ r(q, { editor: u }) })
495
- ] });
496
- }
497
- export {
498
- he as MarkdownEditor,
499
- $ as isSafeUrl,
500
- jt as readFileAsDataUrl,
501
- Ft as sanitizeHtml
502
- };
@@ -1,28 +0,0 @@
1
- type JSONSchema = Record<string, unknown>;
2
- interface ToolExecContext {
3
- abortSignal: AbortSignal;
4
- toolCallId: string;
5
- onUpdate?: (partial: string) => void;
6
- }
7
- interface ToolResult {
8
- content: Array<{
9
- type: "text";
10
- text: string;
11
- }>;
12
- isError?: boolean;
13
- details?: unknown;
14
- }
15
- /**
16
- * Structural tool contract accepted from workspace plugins and UI tool
17
- * factories. Kept agent-runtime-neutral so only the app integration layer
18
- * needs to import @hachej/boring-agent.
19
- */
20
- interface AgentTool {
21
- name: string;
22
- description: string;
23
- promptSnippet?: string;
24
- parameters: JSONSchema;
25
- execute(params: Record<string, unknown>, ctx: ToolExecContext): Promise<ToolResult>;
26
- }
27
-
28
- export type { AgentTool as A, JSONSchema as J, ToolExecContext as T, ToolResult as a };
@@ -1,129 +0,0 @@
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
- /**
72
- * DataExplorer shared types — no runtime deps.
73
- *
74
- * Importable from BOTH front and server bundles without dragging in
75
- * platform-specific code.
76
- */
77
- type Badge = {
78
- /** 1–4 char mono code rendered as a chip. */
79
- code: string;
80
- tooltip?: string;
81
- };
82
- type ExplorerRow = {
83
- id: string;
84
- title: string;
85
- /** Optional muted second line (truncates with title). */
86
- subtitle?: string;
87
- /** Group key — must match one of the facet values for `groupBy`. */
88
- group?: string;
89
- /** Leading mono chip (e.g. type code, frequency). */
90
- leading?: Badge;
91
- /** Trailing mono chips for status flags (e.g. [D] derived, [LIVE]). */
92
- trailing?: Badge[];
93
- /** Right-aligned plain text for numeric metadata (e.g. "1.2M", "2.4s"). */
94
- meta?: string;
95
- };
96
- type FacetValue = {
97
- value: string;
98
- count: number;
99
- };
100
- type Facets = Record<string, FacetValue[]>;
101
- type SearchArgs = {
102
- query: string;
103
- filters: Record<string, string[]>;
104
- /** Scope to a single group's value (only set when paginating inside a group). */
105
- group?: {
106
- key: string;
107
- value: string;
108
- };
109
- limit: number;
110
- offset: number;
111
- signal?: AbortSignal;
112
- };
113
- type SearchResult = {
114
- items: ExplorerRow[];
115
- /** Total count for the current scope (query + filters + optional group). */
116
- total: number;
117
- hasMore: boolean;
118
- };
119
- type FacetsArgs = {
120
- filters: Record<string, string[]>;
121
- signal?: AbortSignal;
122
- };
123
- type ExplorerAdapter = {
124
- search(args: SearchArgs): Promise<SearchResult>;
125
- /** Optional. When omitted, the explorer renders flat (no facet popover). */
126
- fetchFacets?(args: FacetsArgs): Promise<Facets>;
127
- };
128
-
129
- export type { CommandResult as C, ExplorerAdapter as E, SearchResult as S, UiBridge as U, UiCommand as a, UiState as b, ExplorerRow as c };