@hadoku/resume-bot 0.0.0-stage → 3.15.2

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 (71) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +135 -3
  3. package/dist/App.d.ts +9 -0
  4. package/dist/App.d.ts.map +1 -0
  5. package/dist/ChatInterface-mHtxUGpp.js +128 -0
  6. package/dist/ChatInterface-mHtxUGpp.js.map +1 -0
  7. package/dist/ResumeViewer-C-uxZ-7E.js +296 -0
  8. package/dist/ResumeViewer-C-uxZ-7E.js.map +1 -0
  9. package/dist/builder/BlockCard.d.ts +15 -0
  10. package/dist/builder/BlockCard.d.ts.map +1 -0
  11. package/dist/builder/BuilderApp.d.ts +3 -0
  12. package/dist/builder/BuilderApp.d.ts.map +1 -0
  13. package/dist/builder/api.d.ts +37 -0
  14. package/dist/builder/api.d.ts.map +1 -0
  15. package/dist/builder/entry.d.ts +8 -0
  16. package/dist/builder/entry.d.ts.map +1 -0
  17. package/dist/builder/useBuilderAuth.d.ts +10 -0
  18. package/dist/builder/useBuilderAuth.d.ts.map +1 -0
  19. package/dist/builder.js +537 -0
  20. package/dist/builder.js.map +1 -0
  21. package/dist/components/ChatInterface.d.ts +10 -0
  22. package/dist/components/ChatInterface.d.ts.map +1 -0
  23. package/dist/components/ResumeDocument.d.ts +30 -0
  24. package/dist/components/ResumeDocument.d.ts.map +1 -0
  25. package/dist/components/ResumeViewer.d.ts +12 -0
  26. package/dist/components/ResumeViewer.d.ts.map +1 -0
  27. package/dist/entry-BTJjyohQ.js +154 -0
  28. package/dist/entry-BTJjyohQ.js.map +1 -0
  29. package/dist/entry.d.ts +22 -0
  30. package/dist/entry.d.ts.map +1 -0
  31. package/dist/index.js +9 -0
  32. package/dist/index.js.map +1 -0
  33. package/dist/markdown-vendor-61sRGACd.js +10510 -0
  34. package/dist/markdown-vendor-61sRGACd.js.map +1 -0
  35. package/dist/rehype-vendor-C_Q-vwLE.js +5647 -0
  36. package/dist/rehype-vendor-C_Q-vwLE.js.map +1 -0
  37. package/dist/services/api.d.ts +62 -0
  38. package/dist/services/api.d.ts.map +1 -0
  39. package/dist/style.css +1 -0
  40. package/dist/worker/application-extras.d.ts +56 -0
  41. package/dist/worker/application-extras.d.ts.map +1 -0
  42. package/dist/worker/blocks.d.ts +12 -0
  43. package/dist/worker/blocks.d.ts.map +1 -0
  44. package/dist/worker/builder.d.ts +33 -0
  45. package/dist/worker/builder.d.ts.map +1 -0
  46. package/dist/worker/constants.d.ts +39 -0
  47. package/dist/worker/constants.d.ts.map +1 -0
  48. package/dist/worker/contact.d.ts +34 -0
  49. package/dist/worker/contact.d.ts.map +1 -0
  50. package/dist/worker/cover-letter.d.ts +16 -0
  51. package/dist/worker/cover-letter.d.ts.map +1 -0
  52. package/dist/worker/index.d.ts +38 -0
  53. package/dist/worker/index.d.ts.map +1 -0
  54. package/dist/worker/llm.d.ts +77 -0
  55. package/dist/worker/llm.d.ts.map +1 -0
  56. package/dist/worker/pdf.d.ts +46 -0
  57. package/dist/worker/pdf.d.ts.map +1 -0
  58. package/dist/worker/rate-limit.d.ts +10 -0
  59. package/dist/worker/rate-limit.d.ts.map +1 -0
  60. package/dist/worker/resume.d.ts +33 -0
  61. package/dist/worker/resume.d.ts.map +1 -0
  62. package/dist/worker/skeleton.d.ts +73 -0
  63. package/dist/worker/skeleton.d.ts.map +1 -0
  64. package/dist/worker/tailored-resume.d.ts +31 -0
  65. package/dist/worker/tailored-resume.d.ts.map +1 -0
  66. package/dist/worker/typography.d.ts +12 -0
  67. package/dist/worker/typography.d.ts.map +1 -0
  68. package/dist/worker/variants.d.ts +51 -0
  69. package/dist/worker/variants.d.ts.map +1 -0
  70. package/dist/worker.js +42508 -0
  71. package/package.json +44 -4
@@ -0,0 +1,537 @@
1
+ import { jsxs as c, jsx as a } from "react/jsx-runtime";
2
+ import { createRoot as Z } from "react-dom/client";
3
+ import { logger as E } from "@wolffm/logger/client";
4
+ import { useState as d, useRef as ee, useEffect as W, useMemo as D } from "react";
5
+ class H extends Error {
6
+ constructor(i, l) {
7
+ super(i), this.status = l, this.name = "BuilderApiError";
8
+ }
9
+ }
10
+ let X = "";
11
+ function re(e) {
12
+ X = e.replace(/\/+$/, "");
13
+ }
14
+ async function j(e, i) {
15
+ const l = await fetch(`${X}/builder${e}`, {
16
+ ...i,
17
+ credentials: "include",
18
+ headers: { "Content-Type": "application/json", ...i?.headers ?? {} }
19
+ });
20
+ if (!l.ok) {
21
+ let s = `${l.status}`;
22
+ try {
23
+ const u = await l.json();
24
+ s = u.message ? `${u.error}: ${u.message}` : u.error ?? s;
25
+ } catch {
26
+ }
27
+ throw new H(s, l.status);
28
+ }
29
+ return await l.json();
30
+ }
31
+ function ae() {
32
+ return j("/blocks");
33
+ }
34
+ function oe(e) {
35
+ return j(`/blocks/${encodeURIComponent(e.id)}`, {
36
+ method: "PUT",
37
+ body: JSON.stringify(e)
38
+ });
39
+ }
40
+ function te(e) {
41
+ return j(`/blocks/${encodeURIComponent(e)}`, { method: "DELETE" });
42
+ }
43
+ function ne(e, i) {
44
+ return j(`/feedback/${encodeURIComponent(e)}`, {
45
+ method: "POST",
46
+ body: JSON.stringify({ text: i })
47
+ });
48
+ }
49
+ const le = [
50
+ "experience",
51
+ "project",
52
+ "skills",
53
+ "education",
54
+ "summary",
55
+ "header"
56
+ ];
57
+ function M({
58
+ block: e,
59
+ feedback: i,
60
+ existingIds: l,
61
+ isNew: s = !1,
62
+ onSave: u,
63
+ onDelete: p,
64
+ onCancel: O,
65
+ onFeedback: R,
66
+ onTagClick: I
67
+ }) {
68
+ const [b, m] = d(e), [y, _] = d(e.tags.join(" ")), [N, g] = d(!1), [B, f] = d(null), [A, v] = d(i?.text ?? ""), [F, k] = d(""), x = ee(void 0);
69
+ W(() => {
70
+ s || (m(e), _(e.tags.join(" ")));
71
+ }, [e, s]);
72
+ const w = s || JSON.stringify({ ...b, tags: C(y) }) !== JSON.stringify(e);
73
+ function C(o) {
74
+ return [...new Set(o.split(/[\s,]+/).filter(Boolean))];
75
+ }
76
+ const T = s && (!/^[a-z0-9][a-z0-9-]*$/.test(b.id) || l.includes(b.id));
77
+ async function S() {
78
+ g(!0), f(null);
79
+ try {
80
+ await u({ ...b, tags: C(y) });
81
+ } catch (o) {
82
+ f(o instanceof Error ? o.message : "Save failed");
83
+ } finally {
84
+ g(!1);
85
+ }
86
+ }
87
+ async function $() {
88
+ if (p && confirm(`Delete block "${e.id}"? This removes it from the live resume.`)) {
89
+ g(!0);
90
+ try {
91
+ await p();
92
+ } catch (o) {
93
+ f(o instanceof Error ? o.message : "Delete failed"), g(!1);
94
+ }
95
+ }
96
+ }
97
+ function L(o) {
98
+ v(o), k("typing…"), clearTimeout(x.current), x.current = setTimeout(() => {
99
+ R(e.id, o).then(() => k(o.trim() ? "saved ✓" : "")).catch(() => k("save failed"));
100
+ }, 600);
101
+ }
102
+ return /* @__PURE__ */ c(
103
+ "div",
104
+ {
105
+ className: `rb-block${i ? " rb-block--has-feedback" : ""}${w ? " rb-block--dirty" : ""}`,
106
+ children: [
107
+ /* @__PURE__ */ c("div", { className: "rb-block__row", children: [
108
+ s ? /* @__PURE__ */ a(
109
+ "input",
110
+ {
111
+ className: "rb-block__id-input",
112
+ placeholder: "block-id (kebab-case)",
113
+ value: b.id,
114
+ onChange: (o) => m({ ...b, id: o.target.value })
115
+ }
116
+ ) : /* @__PURE__ */ a("span", { className: "rb-block__id", children: b.id }),
117
+ /* @__PURE__ */ a(
118
+ "select",
119
+ {
120
+ className: "rb-block__type",
121
+ value: b.type,
122
+ onChange: (o) => m({ ...b, type: o.target.value }),
123
+ children: le.map((o) => /* @__PURE__ */ a("option", { value: o, children: o }, o))
124
+ }
125
+ ),
126
+ /* @__PURE__ */ c(
127
+ "label",
128
+ {
129
+ className: "rb-block__prio",
130
+ title: "Priority — how strongly you want this block in a tailored resume. Higher sorts first; a ranking hint, not a hard rule.",
131
+ children: [
132
+ "prio",
133
+ /* @__PURE__ */ a(
134
+ "input",
135
+ {
136
+ type: "number",
137
+ min: 0,
138
+ max: 10,
139
+ value: b.priority,
140
+ onChange: (o) => m({ ...b, priority: Number(o.target.value) })
141
+ }
142
+ )
143
+ ]
144
+ }
145
+ )
146
+ ] }),
147
+ /* @__PURE__ */ a(
148
+ "input",
149
+ {
150
+ className: "rb-block__title",
151
+ placeholder: "title (review label — not rendered into the resume)",
152
+ value: b.title,
153
+ onChange: (o) => m({ ...b, title: o.target.value })
154
+ }
155
+ ),
156
+ /* @__PURE__ */ a("div", { className: "rb-block__chips", children: C(y).map((o) => /* @__PURE__ */ a(
157
+ "button",
158
+ {
159
+ type: "button",
160
+ className: `rb-tag rb-tag--${U(o)}`,
161
+ onClick: () => I(o),
162
+ title: "filter by this tag",
163
+ children: o
164
+ },
165
+ o
166
+ )) }),
167
+ /* @__PURE__ */ a(
168
+ "input",
169
+ {
170
+ className: "rb-block__tags-input",
171
+ placeholder: "tags (space or comma separated, e.g. tech:python story:scale)",
172
+ value: y,
173
+ onChange: (o) => _(o.target.value)
174
+ }
175
+ ),
176
+ /* @__PURE__ */ a(
177
+ "textarea",
178
+ {
179
+ className: "rb-block__content",
180
+ rows: 8,
181
+ placeholder: "content (markdown)",
182
+ value: b.content,
183
+ onChange: (o) => m({ ...b, content: o.target.value })
184
+ }
185
+ ),
186
+ /* @__PURE__ */ c("div", { className: "rb-block__actions", children: [
187
+ /* @__PURE__ */ a(
188
+ "button",
189
+ {
190
+ type: "button",
191
+ className: "rb-builder__btn rb-builder__btn--primary",
192
+ onClick: () => {
193
+ S();
194
+ },
195
+ disabled: N || !w || T,
196
+ children: N ? "Saving…" : s ? "Create" : "Save"
197
+ }
198
+ ),
199
+ s ? /* @__PURE__ */ a("button", { type: "button", className: "rb-builder__btn", onClick: O, children: "Cancel" }) : /* @__PURE__ */ a(
200
+ "button",
201
+ {
202
+ type: "button",
203
+ className: "rb-builder__btn rb-builder__btn--danger",
204
+ onClick: () => {
205
+ $();
206
+ },
207
+ disabled: N,
208
+ children: "Delete"
209
+ }
210
+ ),
211
+ T && /* @__PURE__ */ a("span", { className: "rb-block__hint", children: "id must be unique kebab-case" }),
212
+ B && /* @__PURE__ */ a("span", { className: "rb-block__hint rb-block__hint--error", children: B })
213
+ ] }),
214
+ !s && /* @__PURE__ */ c("div", { className: "rb-block__feedback", children: [
215
+ /* @__PURE__ */ a(
216
+ "textarea",
217
+ {
218
+ rows: 2,
219
+ placeholder: "review note (autosaves)…",
220
+ value: A,
221
+ onChange: (o) => L(o.target.value)
222
+ }
223
+ ),
224
+ /* @__PURE__ */ a("span", { className: "rb-block__fb-status", children: F })
225
+ ] })
226
+ ]
227
+ }
228
+ );
229
+ }
230
+ var ie = "https://hadoku.me/prefs", Y = "anon", K = "__hadokuWhoami", se = "sess:", ce = "unscoped";
231
+ function q(e) {
232
+ if (!e || e.valid === !1)
233
+ return { userId: Y, userType: "public", scope: "anon" };
234
+ const i = e.userType === "admin" || e.userType === "wife" || e.userType === "service" || e.userType === "friend" || e.userType === "member" || e.userType === "public" ? e.userType : "public", l = typeof e.name == "string" ? e.name : null;
235
+ return typeof e.userId == "string" && e.userId ? { userId: e.userId, userType: i, name: l, scope: "user" } : typeof e.sessionId == "string" && e.sessionId ? {
236
+ userId: `${se}${e.sessionId}`,
237
+ userType: i,
238
+ name: l,
239
+ scope: "session"
240
+ } : { userId: ce, userType: i, name: l, scope: "none" };
241
+ }
242
+ async function G(e, i) {
243
+ const l = {};
244
+ i && (l["X-User-Key"] = i);
245
+ try {
246
+ const s = await fetch(e, {
247
+ method: "GET",
248
+ headers: l,
249
+ credentials: "include",
250
+ cache: "no-store"
251
+ });
252
+ return s.ok ? await s.json() : null;
253
+ } catch {
254
+ return null;
255
+ }
256
+ }
257
+ function de() {
258
+ const e = globalThis.location;
259
+ return e && (e.protocol === "http:" || e.protocol === "https:") ? "/session/whoami" : `${ie.replace(/\/prefs$/, "")}/session/whoami`;
260
+ }
261
+ async function be(e = {}) {
262
+ const i = e.whoamiUrl ?? de();
263
+ if (e.userKey)
264
+ return q(await G(i, e.userKey));
265
+ const l = globalThis;
266
+ let s = l[K];
267
+ s || (s = G(i), l[K] = s);
268
+ try {
269
+ return q(await s);
270
+ } catch {
271
+ return { userId: Y, userType: "public", scope: "anon" };
272
+ }
273
+ }
274
+ function P() {
275
+ if (typeof window > "u") return;
276
+ const e = encodeURIComponent(window.location.pathname + window.location.search);
277
+ window.location.replace(`/auth?return=${e}`);
278
+ }
279
+ function ue() {
280
+ const [e, i] = d("checking"), [l, s] = d(null);
281
+ return W(() => {
282
+ let u = !1;
283
+ return be().then((p) => {
284
+ if (!u) {
285
+ if (p.userType === "admin") {
286
+ s(p.name ?? null), i("authorized");
287
+ return;
288
+ }
289
+ E.info("[builder] not admin, redirecting to sign in", { userType: p.userType }), i("redirecting"), P();
290
+ }
291
+ }).catch((p) => {
292
+ u || (E.error("[builder] whoami failed", {
293
+ error: p instanceof Error ? p.message : String(p)
294
+ }), i("redirecting"), P());
295
+ }), () => {
296
+ u = !0;
297
+ };
298
+ }, []), { status: e, name: l };
299
+ }
300
+ const pe = [
301
+ "experience",
302
+ "project",
303
+ "skills",
304
+ "education",
305
+ "summary",
306
+ "header"
307
+ ];
308
+ function U(e) {
309
+ return e.startsWith("tech:") ? "tech" : e.startsWith("layer:") ? "layer" : e.startsWith("story:") ? "story" : "plain";
310
+ }
311
+ function he() {
312
+ return { id: "", type: "experience", tags: [], title: "", content: "", priority: 5 };
313
+ }
314
+ function me() {
315
+ const { status: e, name: i } = ue(), [l, s] = d([]), [u, p] = d({}), [O, R] = d(!0), [I, b] = d(null), [m, y] = d(""), [_, N] = d(""), [g, B] = d(/* @__PURE__ */ new Set()), [f, A] = d(!0), [v, F] = d("order"), [k, x] = d(null);
316
+ W(() => {
317
+ if (e !== "authorized") return;
318
+ let r = !1;
319
+ return ae().then((t) => {
320
+ r || (s(t.blocks), p(t.feedback));
321
+ }).catch((t) => {
322
+ if (r) return;
323
+ if (t instanceof H && (t.status === 401 || t.status === 403)) {
324
+ P();
325
+ return;
326
+ }
327
+ const n = t instanceof Error ? t.message : "Failed to load blocks";
328
+ b(n), E.error("[builder] load failed", { error: n });
329
+ }).finally(() => {
330
+ r || R(!1);
331
+ }), () => {
332
+ r = !0;
333
+ };
334
+ }, [e]);
335
+ const w = D(() => {
336
+ const r = /* @__PURE__ */ new Map();
337
+ for (const t of l) for (const n of t.tags) r.set(n, (r.get(n) ?? 0) + 1);
338
+ return r;
339
+ }, [l]), C = D(
340
+ () => [...w.keys()].sort(
341
+ (r, t) => U(r).localeCompare(U(t)) || r.localeCompare(t)
342
+ ),
343
+ [w]
344
+ ), T = D(() => {
345
+ const r = m.trim().toLowerCase();
346
+ let t = l.filter((n) => {
347
+ if (_ && n.type !== _ || r && !(n.id + n.title + n.content).toLowerCase().includes(r)) return !1;
348
+ if (g.size) {
349
+ const h = [...g].filter((z) => n.tags.includes(z)).length;
350
+ if (f ? h !== g.size : h === 0) return !1;
351
+ }
352
+ return !0;
353
+ });
354
+ return v === "priority" ? t = [...t].sort((n, h) => h.priority - n.priority) : v === "type" ? t = [...t].sort((n, h) => n.type.localeCompare(h.type)) : v === "feedback" && (t = [...t].sort((n, h) => (u[h.id] ? 1 : 0) - (u[n.id] ? 1 : 0))), t;
355
+ }, [l, m, _, g, f, v, u]);
356
+ function S(r) {
357
+ B((t) => {
358
+ const n = new Set(t);
359
+ return n.has(r) ? n.delete(r) : n.add(r), n;
360
+ });
361
+ }
362
+ async function $(r, t) {
363
+ const { block: n } = await oe(r);
364
+ s((h) => {
365
+ const z = h.findIndex((V) => V.id === n.id);
366
+ if (z === -1) return [...h, n];
367
+ const J = [...h];
368
+ return J[z] = n, J;
369
+ }), t && x(null);
370
+ }
371
+ async function L(r) {
372
+ await te(r), s((t) => t.filter((n) => n.id !== r));
373
+ }
374
+ async function o(r, t) {
375
+ const n = await ne(r, t);
376
+ p(n.feedback);
377
+ }
378
+ function Q() {
379
+ const r = new Blob([JSON.stringify(l, null, 2)], { type: "application/json" }), t = URL.createObjectURL(r), n = document.createElement("a");
380
+ n.href = t, n.download = "blocks.json", n.click(), URL.revokeObjectURL(t);
381
+ }
382
+ return e === "checking" ? /* @__PURE__ */ a("p", { className: "rb-builder__status", children: "Checking access…" }) : e === "redirecting" ? /* @__PURE__ */ a("p", { className: "rb-builder__status", children: "Redirecting to sign in…" }) : O ? /* @__PURE__ */ a("p", { className: "rb-builder__status", children: "Loading blocks…" }) : I ? /* @__PURE__ */ a("p", { className: "rb-builder__status rb-builder__status--error", children: I }) : /* @__PURE__ */ c("div", { className: "rb-builder", children: [
383
+ /* @__PURE__ */ c("div", { className: "rb-builder__toolbar", children: [
384
+ /* @__PURE__ */ c("header", { className: "rb-builder__header", children: [
385
+ /* @__PURE__ */ a("h1", { children: "Resume Builder" }),
386
+ /* @__PURE__ */ c("div", { className: "rb-builder__count", children: [
387
+ T.length,
388
+ " / ",
389
+ l.length,
390
+ " blocks"
391
+ ] }),
392
+ i && /* @__PURE__ */ c("div", { className: "rb-builder__whoami", children: [
393
+ "Signed in as ",
394
+ /* @__PURE__ */ a("span", { className: "rb-builder__whoami-name", children: i })
395
+ ] }),
396
+ /* @__PURE__ */ c("div", { className: "rb-builder__header-actions", children: [
397
+ /* @__PURE__ */ a("button", { type: "button", onClick: Q, className: "rb-builder__btn", children: "Export blocks.json" }),
398
+ /* @__PURE__ */ a(
399
+ "button",
400
+ {
401
+ type: "button",
402
+ onClick: () => x(he()),
403
+ className: "rb-builder__btn rb-builder__btn--primary",
404
+ disabled: k !== null,
405
+ children: "+ New block"
406
+ }
407
+ )
408
+ ] })
409
+ ] }),
410
+ /* @__PURE__ */ c("div", { className: "rb-builder__controls", children: [
411
+ /* @__PURE__ */ a(
412
+ "input",
413
+ {
414
+ type: "search",
415
+ placeholder: "Search id, title, content…",
416
+ value: m,
417
+ onChange: (r) => y(r.target.value),
418
+ className: "rb-builder__search"
419
+ }
420
+ ),
421
+ /* @__PURE__ */ c(
422
+ "select",
423
+ {
424
+ value: _,
425
+ onChange: (r) => N(r.target.value),
426
+ className: "rb-builder__select",
427
+ children: [
428
+ /* @__PURE__ */ a("option", { value: "", children: "all types" }),
429
+ pe.map((r) => /* @__PURE__ */ a("option", { value: r, children: r }, r))
430
+ ]
431
+ }
432
+ ),
433
+ /* @__PURE__ */ c(
434
+ "select",
435
+ {
436
+ value: v,
437
+ onChange: (r) => F(r.target.value),
438
+ className: "rb-builder__select",
439
+ children: [
440
+ /* @__PURE__ */ a("option", { value: "order", children: "render order" }),
441
+ /* @__PURE__ */ a("option", { value: "priority", children: "priority ↓" }),
442
+ /* @__PURE__ */ a("option", { value: "type", children: "type" }),
443
+ /* @__PURE__ */ a("option", { value: "feedback", children: "has feedback" })
444
+ ]
445
+ }
446
+ ),
447
+ /* @__PURE__ */ c("label", { className: "rb-builder__andmode", children: [
448
+ /* @__PURE__ */ a("input", { type: "checkbox", checked: f, onChange: (r) => A(r.target.checked) }),
449
+ "match all tags"
450
+ ] })
451
+ ] }),
452
+ /* @__PURE__ */ c("div", { className: "rb-builder__legend", children: [
453
+ /* @__PURE__ */ c("span", { className: "rb-builder__legend-item", children: [
454
+ /* @__PURE__ */ a("span", { className: "rb-builder__legend-dot rb-builder__legend-dot--tech" }),
455
+ "tech:"
456
+ ] }),
457
+ /* @__PURE__ */ c("span", { className: "rb-builder__legend-item", children: [
458
+ /* @__PURE__ */ a("span", { className: "rb-builder__legend-dot rb-builder__legend-dot--layer" }),
459
+ "layer:"
460
+ ] }),
461
+ /* @__PURE__ */ c("span", { className: "rb-builder__legend-item", children: [
462
+ /* @__PURE__ */ a("span", { className: "rb-builder__legend-dot rb-builder__legend-dot--story" }),
463
+ "story:"
464
+ ] }),
465
+ /* @__PURE__ */ c("span", { className: "rb-builder__legend-item", children: [
466
+ /* @__PURE__ */ a("span", { className: "rb-builder__legend-dot rb-builder__legend-dot--plain" }),
467
+ "other / always"
468
+ ] }),
469
+ /* @__PURE__ */ c("span", { className: "rb-builder__legend-item", children: [
470
+ /* @__PURE__ */ a("strong", { children: "prio" }),
471
+ " = how strongly you want a block (sort/rank hint)"
472
+ ] })
473
+ ] }),
474
+ /* @__PURE__ */ a("div", { className: "rb-builder__tagbar", children: C.map((r) => /* @__PURE__ */ c(
475
+ "button",
476
+ {
477
+ type: "button",
478
+ onClick: () => S(r),
479
+ className: `rb-tag rb-tag--${U(r)}${g.has(r) ? " rb-tag--active" : ""}`,
480
+ children: [
481
+ r,
482
+ /* @__PURE__ */ a("span", { className: "rb-tag__n", children: w.get(r) })
483
+ ]
484
+ },
485
+ r
486
+ )) })
487
+ ] }),
488
+ /* @__PURE__ */ c("div", { className: "rb-builder__list", children: [
489
+ k && /* @__PURE__ */ a(
490
+ M,
491
+ {
492
+ block: k,
493
+ feedback: void 0,
494
+ isNew: !0,
495
+ existingIds: l.map((r) => r.id),
496
+ onSave: (r) => $(r, !0),
497
+ onCancel: () => x(null),
498
+ onFeedback: o,
499
+ onTagClick: S
500
+ },
501
+ "__new__"
502
+ ),
503
+ T.map((r) => /* @__PURE__ */ a(
504
+ M,
505
+ {
506
+ block: r,
507
+ feedback: u[r.id],
508
+ existingIds: l.map((t) => t.id),
509
+ onSave: (t) => $(t, !1),
510
+ onDelete: () => L(r.id),
511
+ onFeedback: o,
512
+ onTagClick: S
513
+ },
514
+ r.id
515
+ ))
516
+ ] })
517
+ ] });
518
+ }
519
+ const ge = "#resume-builder-root{height:100vh;overflow-y:auto}.rb-builder{box-sizing:border-box;max-width:1000px;margin:0 auto;padding:0 var(--hdk-space-lg) var(--hdk-space-3xl);color:var(--color-text);font-size:var(--hdk-text-sm)}.rb-builder *,.rb-builder *:before,.rb-builder *:after{box-sizing:border-box}.rb-builder__status{padding:var(--hdk-space-lg);color:var(--color-text-secondary)}.rb-builder__status--error{border-left:3px solid var(--color-danger);padding-left:.5rem;color:var(--color-text)}.rb-builder__toolbar{position:sticky;top:0;z-index:5;background:var(--color-bg);padding-top:var(--hdk-space-lg);margin-bottom:var(--hdk-space-lg);border-bottom:1px solid var(--color-border)}.rb-builder__header{display:flex;align-items:center;gap:var(--hdk-space-md);flex-wrap:wrap;margin-bottom:var(--hdk-space-md)}.rb-builder__header h1{font-size:var(--hdk-text-lg);margin:0;line-height:1.2}.rb-builder__count{color:var(--color-text-secondary);font-variant-numeric:tabular-nums}.rb-builder__whoami{margin-left:auto;color:var(--color-text-secondary);font-size:var(--hdk-text-xs);white-space:nowrap}.rb-builder__whoami-name{color:var(--color-text);font-weight:600}.rb-builder__header-actions{margin-left:auto;display:flex;gap:var(--hdk-space-sm)}.rb-builder__whoami+.rb-builder__header-actions{margin-left:var(--hdk-space-md)}.rb-builder__controls{display:flex;gap:var(--hdk-space-sm);flex-wrap:wrap;align-items:center;margin-bottom:var(--hdk-space-sm)}.rb-builder__search{flex:1 1 220px;min-width:200px}.rb-builder__andmode{display:flex;align-items:center;gap:.4rem;color:var(--color-text-secondary);white-space:nowrap;cursor:pointer;user-select:none}.rb-builder__andmode input{accent-color:var(--color-primary)}.rb-builder__legend{display:flex;flex-wrap:wrap;align-items:center;gap:var(--hdk-space-md);padding:var(--hdk-space-sm) 0;color:var(--color-text-secondary);font-size:var(--hdk-text-xs)}.rb-builder__legend-item{display:inline-flex;align-items:center;gap:.4rem;white-space:nowrap}.rb-builder__legend-dot{width:.7rem;height:.7rem;border-radius:999px;border:1px solid var(--color-neutral);background:var(--color-neutral);flex:none}.rb-builder__legend-dot--tech{border-color:var(--color-success);background:var(--color-success)}.rb-builder__legend-dot--layer{border-color:var(--color-primary);background:var(--color-primary)}.rb-builder__legend-dot--story{border-color:var(--color-warning);background:var(--color-warning)}.rb-builder__search,.rb-builder__select,.rb-block__id-input,.rb-block__title,.rb-block__tags-input,.rb-block__type,.rb-block__prio input,.rb-block__content,.rb-block__feedback textarea{background:var(--color-bg);color:var(--color-text);border:1px solid var(--color-border);border-radius:var(--hdk-radius-sm);padding:.45rem .6rem;font-family:inherit;font-size:var(--hdk-text-sm);line-height:1.4}.rb-builder__search:focus,.rb-builder__select:focus,.rb-block__id-input:focus,.rb-block__title:focus,.rb-block__tags-input:focus,.rb-block__type:focus,.rb-block__prio input:focus,.rb-block__content:focus,.rb-block__feedback textarea:focus{outline:none;border-color:var(--color-primary);box-shadow:var(--hdk-shadow-focus)}.rb-builder__tagbar{display:flex;flex-wrap:wrap;gap:.4rem;max-height:116px;overflow-y:auto;padding:var(--hdk-space-sm) 0 var(--hdk-space-md)}.rb-tag{display:inline-flex;align-items:center;gap:.35rem;padding:.15rem .55rem;border-radius:999px;border:1px solid var(--color-neutral);background:var(--color-neutral-bg);color:var(--color-on-neutral-bg);font-size:var(--hdk-text-xs);line-height:1.5;cursor:pointer;font-family:ui-monospace,monospace;transition:background .12s ease,color .12s ease}.rb-tag:hover{background:color-mix(in srgb,currentcolor 15%,transparent)}.rb-tag--tech{border-color:var(--color-success);background:var(--color-success-bg);color:var(--color-on-success-bg)}.rb-tag--layer{border-color:var(--color-primary);background:var(--color-primary-bg);color:var(--color-on-primary-bg)}.rb-tag--story{border-color:var(--color-warning);background:var(--color-warning-bg);color:var(--color-on-warning-bg)}.rb-tag--active{background:var(--color-neutral);color:var(--color-on-neutral)}.rb-tag--tech.rb-tag--active{background:var(--color-success);color:var(--color-on-success)}.rb-tag--layer.rb-tag--active{background:var(--color-primary);color:var(--color-on-primary)}.rb-tag--story.rb-tag--active{background:var(--color-warning);color:var(--color-on-warning)}.rb-tag--active .rb-tag__n{color:inherit}.rb-tag__n{opacity:.75;font-size:.9em;font-variant-numeric:tabular-nums}.rb-builder__list{display:flex;flex-direction:column;gap:var(--hdk-space-md)}.rb-block{border:1px solid var(--color-border);border-left:3px solid transparent;border-radius:var(--hdk-radius-sm);padding:var(--hdk-space-md);display:flex;flex-direction:column;gap:var(--hdk-space-sm);background:var(--color-bg-card);box-shadow:var(--hdk-shadow-sm)}.rb-block--has-feedback{border-left-color:var(--color-success)}.rb-block--dirty{border-left-color:var(--color-warning)}.rb-block__row{display:flex;align-items:center;gap:var(--hdk-space-sm)}.rb-block__id{font-family:ui-monospace,monospace;color:var(--color-text);font-weight:600;word-break:break-all}.rb-block__id-input{flex:1;font-family:ui-monospace,monospace}.rb-block__type{flex:none}.rb-block__prio{display:flex;align-items:center;gap:.4rem;margin-left:auto;color:var(--color-text-secondary);white-space:nowrap}.rb-block__prio input{width:3.5rem;text-align:center}.rb-block__title{width:100%}.rb-block__content{width:100%;resize:vertical;min-height:8rem;font-family:ui-monospace,monospace;line-height:1.5}.rb-block__chips{display:flex;flex-wrap:wrap;gap:.35rem}.rb-block__chips:empty{display:none}.rb-block__tags-input{width:100%;font-family:ui-monospace,monospace}.rb-block__actions{display:flex;align-items:center;flex-wrap:wrap;gap:var(--hdk-space-sm);margin-top:.15rem}.rb-block__hint{color:var(--color-text-secondary);font-size:var(--hdk-text-xs)}.rb-block__hint--error{border-left:3px solid var(--color-danger);padding-left:.5rem;color:var(--color-text)}.rb-block__feedback{display:flex;align-items:flex-start;gap:var(--hdk-space-sm);padding-top:var(--hdk-space-sm);margin-top:var(--hdk-space-xs);border-top:1px dashed var(--color-border)}.rb-block__feedback textarea{flex:1;resize:vertical}.rb-block__fb-status{color:var(--color-text-secondary);font-size:var(--hdk-text-xs);white-space:nowrap;padding-top:.5rem}.rb-builder__btn{display:inline-flex;align-items:center;justify-content:center;gap:.4rem;padding:.45rem .9rem;border-radius:var(--hdk-radius-sm);border:1px solid var(--color-border);background:var(--color-bg-card);color:var(--color-text);cursor:pointer;font-family:inherit;font-size:var(--hdk-text-sm);font-weight:500;line-height:1.4;white-space:nowrap;transition:background .12s ease,border-color .12s ease,opacity .12s ease}.rb-builder__btn:hover:not(:disabled){background:var(--color-bg-hover);border-color:var(--color-text-secondary)}.rb-builder__btn:focus-visible{outline:none;box-shadow:var(--hdk-shadow-focus)}.rb-builder__btn:disabled{opacity:.45;cursor:not-allowed}.rb-builder__btn--primary{background:var(--color-primary);border-color:var(--color-primary);color:var(--color-on-primary)}.rb-builder__btn--primary:hover:not(:disabled){background:var(--color-primary-dark);border-color:var(--color-primary-dark)}.rb-builder__btn--danger{color:var(--color-text);border-color:var(--color-danger);background:transparent}.rb-builder__btn--danger:hover:not(:disabled){background:var(--color-danger);border-color:var(--color-danger);color:var(--color-on-danger)}";
520
+ function _e() {
521
+ if (document.getElementById("rb-builder-styles")) return;
522
+ const e = document.createElement("style");
523
+ e.id = "rb-builder-styles", e.textContent = ge, document.head.appendChild(e);
524
+ }
525
+ function xe(e, i) {
526
+ _e(), re(i.apiBaseUrl);
527
+ const l = Z(e);
528
+ l.render(/* @__PURE__ */ a(me, {})), e.__root = l, E.info("[resume-builder] Mounted", { apiBaseUrl: i.apiBaseUrl });
529
+ }
530
+ function we(e) {
531
+ e.__root?.unmount(), E.info("[resume-builder] Unmounted");
532
+ }
533
+ export {
534
+ xe as mount,
535
+ we as unmount
536
+ };
537
+ //# sourceMappingURL=builder.js.map