@hachej/boring-workspace 0.1.7 → 0.1.10
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/{CommandPalette-DzIDQUfk.js → CommandPalette-D5KPKtKA.js} +1765 -1590
- package/dist/{FileTree-CspphShP.js → FileTree-CwC01Ijr.js} +1 -1
- package/dist/MarkdownEditor-CB7nfhN9.js +502 -0
- package/dist/{WorkspaceLoadingState-Cd8nkNHp.js → WorkspaceLoadingState-J8XVhEyL.js} +1 -1
- package/dist/app-front.js +2 -2
- package/dist/testing.js +1 -1
- package/dist/workspace.css +4 -0
- package/dist/workspace.js +5 -5
- package/package.json +3 -3
- package/dist/MarkdownEditor-wDDxxED5.js +0 -474
|
@@ -2,7 +2,7 @@ import { jsx as i, jsxs as C } from "react/jsx-runtime";
|
|
|
2
2
|
import { useRef as w, useEffect as R, useMemo as P, useCallback as x, createContext as H, useContext as L } from "react";
|
|
3
3
|
import { Tree as q } from "react-arborist";
|
|
4
4
|
import { FolderOpenIcon as z, FolderIcon as B, ChevronRightIcon as K, Loader2Icon as E } from "lucide-react";
|
|
5
|
-
import { K as Y } from "./CommandPalette-
|
|
5
|
+
import { K as Y } from "./CommandPalette-D5KPKtKA.js";
|
|
6
6
|
import { Input as G } from "@hachej/boring-ui-kit";
|
|
7
7
|
import { c as v } from "./utils-B6yFEsav.js";
|
|
8
8
|
const T = /* @__PURE__ */ new Set(), A = H({
|
|
@@ -0,0 +1,502 @@
|
|
|
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-D5KPKtKA.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, "&").replace(/"/g, """).replace(/</g, "<").replace(/>/g, ">");
|
|
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 ? `}")` : ``;
|
|
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
|
+
};
|
|
@@ -2,7 +2,7 @@ import { jsxs as d, jsx as o, Fragment as H } from "react/jsx-runtime";
|
|
|
2
2
|
import { useCallback as b, useMemo as A, useEffect as S, useState as V, Suspense as X, useRef as q } from "react";
|
|
3
3
|
import { LoadingState as Z, ResizeHandle as G, IconButton as $, Button as J, Kbd as Q } 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 oe } from "./CommandPalette-
|
|
5
|
+
import { $ as Y, a6 as ee, E as te, am as ne, ak as re, u as oe } from "./CommandPalette-D5KPKtKA.js";
|
|
6
6
|
import { Search as ae, Plus as ie } from "lucide-react";
|
|
7
7
|
function be(e, t, r = !0) {
|
|
8
8
|
if (!r || typeof window > "u") return t;
|
package/dist/app-front.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as d, jsxs as Te, Fragment as x } from "react/jsx-runtime";
|
|
2
2
|
import { useSyncExternalStore as ze, useMemo as v, useRef as K, useState as X, useEffect as y, useCallback as P } from "react";
|
|
3
3
|
import { ChatPanel as Fe, useSessions as Ge } from "@hachej/boring-agent/front";
|
|
4
|
-
import { aj as ke, q as Ye, ak as Qe, u as Xe, al as Ze } from "./CommandPalette-
|
|
5
|
-
import { T as He, C as qe, r as Ee, w as et, W as $e } from "./WorkspaceLoadingState-
|
|
4
|
+
import { aj as ke, q as Ye, ak as Qe, u as Xe, al as Ze } from "./CommandPalette-D5KPKtKA.js";
|
|
5
|
+
import { T as He, C as qe, r as Ee, w as et, W as $e } from "./WorkspaceLoadingState-J8XVhEyL.js";
|
|
6
6
|
function tt() {
|
|
7
7
|
const e = `s${Date.now()}`;
|
|
8
8
|
return {
|
package/dist/testing.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as ka } from "react/jsx-runtime";
|
|
2
2
|
import * as Pa from "react";
|
|
3
3
|
import { createElement as ds, useMemo as Tn, useLayoutEffect as fs, isValidElement as ps, cloneElement as ms, useSyncExternalStore as Ji } from "react";
|
|
4
|
-
import { i as vs, q as bs, ai as hs } from "./CommandPalette-
|
|
4
|
+
import { i as vs, q as bs, ai as hs } from "./CommandPalette-D5KPKtKA.js";
|
|
5
5
|
import { d as ys } from "./panel-DnvDNQac.js";
|
|
6
6
|
import * as Rs from "react-dom/test-utils";
|
|
7
7
|
import Ba from "react-dom";
|
package/dist/workspace.css
CHANGED
|
@@ -1240,6 +1240,7 @@
|
|
|
1240
1240
|
--font-sans: var(--boring-font-sans);
|
|
1241
1241
|
--font-mono: var(--boring-font-mono);
|
|
1242
1242
|
--color-black: #000;
|
|
1243
|
+
--color-white: #fff;
|
|
1243
1244
|
--spacing: 0.25rem;
|
|
1244
1245
|
--container-xs: 20rem;
|
|
1245
1246
|
--container-sm: 24rem;
|
|
@@ -2566,6 +2567,9 @@
|
|
|
2566
2567
|
.bg-transparent {
|
|
2567
2568
|
background-color: transparent;
|
|
2568
2569
|
}
|
|
2570
|
+
.bg-white {
|
|
2571
|
+
background-color: var(--color-white);
|
|
2572
|
+
}
|
|
2569
2573
|
.fill-foreground {
|
|
2570
2574
|
fill: var(--boring-foreground);
|
|
2571
2575
|
}
|
package/dist/workspace.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
var qe = Object.defineProperty;
|
|
2
2
|
var _e = (e, t, r) => t in e ? qe(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
|
|
3
3
|
var ne = (e, t, r) => _e(e, typeof t != "symbol" ? t + "" : t, r);
|
|
4
|
-
import { d as ae, u as Ne, p as Be, P as Ae, a as $e, b as Ke, D as Ve } from "./CommandPalette-
|
|
5
|
-
import { A as xr, C as yr, c as br, e as vr, f as Sr, F as Nr, g as Cr, M as Tr, h as Pr, i as kr, j as Er, k as wr, l as Mr, R as Dr, S as Ir, m as Rr, n as Or, T as Fr, W as Lr, o as zr, q as qr, r as _r, s as Br, t as Ar, v as $r, w as Kr, x as Vr, y as Qr, z as jr, B as Gr, E as Hr, G as Wr, H as Ur, I as Xr, J as Jr, K as Yr, L as Zr, N as ea, O as ta, Q as ra, U as aa, V as na, X as la, Y as oa, Z as sa, _ as ca, $ as ia, a0 as ua, a1 as da, a2 as pa, a3 as fa, a4 as ma, a5 as ga, a6 as ha, a7 as xa, a8 as ya, a9 as ba, aa as va, ab as Sa, ac as Na, ad as Ca, ae as Ta, af as Pa, ag as ka, ah as Ea } from "./CommandPalette-
|
|
4
|
+
import { d as ae, u as Ne, p as Be, P as Ae, a as $e, b as Ke, D as Ve } from "./CommandPalette-D5KPKtKA.js";
|
|
5
|
+
import { A as xr, C as yr, c as br, e as vr, f as Sr, F as Nr, g as Cr, M as Tr, h as Pr, i as kr, j as Er, k as wr, l as Mr, R as Dr, S as Ir, m as Rr, n as Or, T as Fr, W as Lr, o as zr, q as qr, r as _r, s as Br, t as Ar, v as $r, w as Kr, x as Vr, y as Qr, z as jr, B as Gr, E as Hr, G as Wr, H as Ur, I as Xr, J as Jr, K as Yr, L as Zr, N as ea, O as ta, Q as ra, U as aa, V as na, X as la, Y as oa, Z as sa, _ as ca, $ as ia, a0 as ua, a1 as da, a2 as pa, a3 as fa, a4 as ma, a5 as ga, a6 as ha, a7 as xa, a8 as ya, a9 as ba, aa as va, ab as Sa, ac as Na, ad as Ca, ae as Ta, af as Pa, ag as ka, ah as Ea } from "./CommandPalette-D5KPKtKA.js";
|
|
6
6
|
import { jsxs as h, jsx as a, Fragment as Qe } from "react/jsx-runtime";
|
|
7
7
|
import { useSyncExternalStore as je, useState as V, useEffect as U, useRef as w, useCallback as S, useReducer as Ge, useMemo as Z, Suspense as He, Component as We } from "react";
|
|
8
8
|
import { FilterIcon as Ue, XIcon as Xe, ChevronDownIcon as Ce, ChevronRightIcon as Te, Database as Je, BarChart3 as pe, MenuIcon as Ye, PanelLeftOpenIcon as Ze, PanelLeftCloseIcon as et, PinIcon as tt } from "lucide-react";
|
|
@@ -10,10 +10,10 @@ import { EmptyState as Pe, Toolbar as rt, Input as ke, Popover as at, PopoverTri
|
|
|
10
10
|
import { Toaster as Ma, dismissToast as Da, toast as Ia } from "@hachej/boring-ui-kit";
|
|
11
11
|
import { c as H } from "./utils-B6yFEsav.js";
|
|
12
12
|
import { d as we } from "./panel-DnvDNQac.js";
|
|
13
|
-
import { C as Oa, T as Fa, W as La, b as za } from "./WorkspaceLoadingState-
|
|
13
|
+
import { C as Oa, T as Fa, W as La, b as za } from "./WorkspaceLoadingState-J8XVhEyL.js";
|
|
14
14
|
import { C as _a, c as Ba } from "./CodeEditor-DQqOn4xz.js";
|
|
15
|
-
import { FileTree as $a } from "./FileTree-
|
|
16
|
-
import { MarkdownEditor as Va } from "./MarkdownEditor-
|
|
15
|
+
import { FileTree as $a } from "./FileTree-CwC01Ijr.js";
|
|
16
|
+
import { MarkdownEditor as Va } from "./MarkdownEditor-CB7nfhN9.js";
|
|
17
17
|
function re(e, t) {
|
|
18
18
|
const { pluginId: r, ...n } = e;
|
|
19
19
|
return t ? { ...n, pluginId: t } : n;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hachej/boring-workspace",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
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.",
|
|
@@ -125,8 +125,8 @@
|
|
|
125
125
|
"tailwind-merge": "^2.0.0",
|
|
126
126
|
"zod": "^3.23.0",
|
|
127
127
|
"zustand": "^5.0.0",
|
|
128
|
-
"@hachej/boring-
|
|
129
|
-
"@hachej/boring-
|
|
128
|
+
"@hachej/boring-agent": "0.1.10",
|
|
129
|
+
"@hachej/boring-ui-kit": "0.1.10"
|
|
130
130
|
},
|
|
131
131
|
"devDependencies": {
|
|
132
132
|
"@tailwindcss/postcss": "^4.0.0",
|