@deskwork/studio 0.15.0 → 0.17.0

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 (75) hide show
  1. package/dist/components/scrapbook-item.d.ts +20 -0
  2. package/dist/components/scrapbook-item.d.ts.map +1 -1
  3. package/dist/components/scrapbook-item.js +21 -2
  4. package/dist/components/scrapbook-item.js.map +1 -1
  5. package/dist/lib/entry-resolver.d.ts +19 -6
  6. package/dist/lib/entry-resolver.d.ts.map +1 -1
  7. package/dist/lib/entry-resolver.js +40 -33
  8. package/dist/lib/entry-resolver.js.map +1 -1
  9. package/dist/pages/dashboard/affordances.d.ts.map +1 -1
  10. package/dist/pages/dashboard/affordances.js +13 -1
  11. package/dist/pages/dashboard/affordances.js.map +1 -1
  12. package/dist/pages/dashboard/affordances.ts +13 -1
  13. package/dist/pages/review-scrapbook-drawer.d.ts.map +1 -1
  14. package/dist/pages/review-scrapbook-drawer.js +10 -1
  15. package/dist/pages/review-scrapbook-drawer.js.map +1 -1
  16. package/dist/pages/review-scrapbook-drawer.ts +11 -1
  17. package/dist/pages/scrapbook/dispatch.d.ts +50 -0
  18. package/dist/pages/scrapbook/dispatch.d.ts.map +1 -0
  19. package/dist/pages/scrapbook/dispatch.js +104 -0
  20. package/dist/pages/scrapbook/dispatch.js.map +1 -0
  21. package/dist/pages/scrapbook/image-readers.d.ts +24 -0
  22. package/dist/pages/scrapbook/image-readers.d.ts.map +1 -0
  23. package/dist/pages/scrapbook/image-readers.js +135 -0
  24. package/dist/pages/scrapbook/image-readers.js.map +1 -0
  25. package/dist/pages/scrapbook/index.d.ts +21 -0
  26. package/dist/pages/scrapbook/index.d.ts.map +1 -0
  27. package/dist/pages/scrapbook/index.js +96 -0
  28. package/dist/pages/scrapbook/index.js.map +1 -0
  29. package/dist/pages/scrapbook/render.d.ts +68 -0
  30. package/dist/pages/scrapbook/render.d.ts.map +1 -0
  31. package/dist/pages/scrapbook/render.js +315 -0
  32. package/dist/pages/scrapbook/render.js.map +1 -0
  33. package/dist/pages/scrapbook/text-helpers.d.ts +40 -0
  34. package/dist/pages/scrapbook/text-helpers.d.ts.map +1 -0
  35. package/dist/pages/scrapbook/text-helpers.js +92 -0
  36. package/dist/pages/scrapbook/text-helpers.js.map +1 -0
  37. package/dist/pages/scrapbook/types.d.ts +26 -0
  38. package/dist/pages/scrapbook/types.d.ts.map +1 -0
  39. package/dist/pages/scrapbook/types.js +12 -0
  40. package/dist/pages/scrapbook/types.js.map +1 -0
  41. package/dist/pages/scrapbook.d.ts +8 -8
  42. package/dist/pages/scrapbook.d.ts.map +1 -1
  43. package/dist/pages/scrapbook.js +8 -600
  44. package/dist/pages/scrapbook.js.map +1 -1
  45. package/dist/pages/scrapbook.ts +11 -660
  46. package/dist/routes/api.d.ts.map +1 -1
  47. package/dist/routes/api.js +111 -2
  48. package/dist/routes/api.js.map +1 -1
  49. package/dist/routes/entry-annotation-body.d.ts +29 -0
  50. package/dist/routes/entry-annotation-body.d.ts.map +1 -1
  51. package/dist/routes/entry-annotation-body.js +80 -0
  52. package/dist/routes/entry-annotation-body.js.map +1 -1
  53. package/dist/routes/scrapbook-file.d.ts +1 -1
  54. package/dist/routes/scrapbook-file.js +1 -1
  55. package/dist/routes/scrapbook-mutation-dispatch.d.ts +29 -0
  56. package/dist/routes/scrapbook-mutation-dispatch.d.ts.map +1 -0
  57. package/dist/routes/scrapbook-mutation-dispatch.js +63 -0
  58. package/dist/routes/scrapbook-mutation-dispatch.js.map +1 -0
  59. package/dist/routes/scrapbook-mutation-envelope.d.ts +93 -0
  60. package/dist/routes/scrapbook-mutation-envelope.d.ts.map +1 -0
  61. package/dist/routes/scrapbook-mutation-envelope.js +147 -0
  62. package/dist/routes/scrapbook-mutation-envelope.js.map +1 -0
  63. package/dist/routes/scrapbook-mutations.d.ts +25 -7
  64. package/dist/routes/scrapbook-mutations.d.ts.map +1 -1
  65. package/dist/routes/scrapbook-mutations.js +67 -92
  66. package/dist/routes/scrapbook-mutations.js.map +1 -1
  67. package/dist/server.d.ts.map +1 -1
  68. package/dist/server.js +16 -2
  69. package/dist/server.js.map +1 -1
  70. package/package.json +2 -2
  71. package/dist/pages/review.d.ts +0 -68
  72. package/dist/pages/review.d.ts.map +0 -1
  73. package/dist/pages/review.js +0 -561
  74. package/dist/pages/review.js.map +0 -1
  75. package/dist/pages/review.ts +0 -710
@@ -1,606 +1,14 @@
1
1
  /**
2
2
  * Scrapbook viewer — `/dev/scrapbook/:site/<path>`.
3
3
  *
4
- * Issue #161 redesign: aside-left folder card with numbered item list,
5
- * vertical card grid with per-kind colored ribbons + always-visible foot
6
- * toolbar + per-kind preview rendering, drop zone, secret section,
7
- * single-expanded card invariant, aside cross-linking.
4
+ * The implementation lives in the `scrapbook/` directory (one module
5
+ * per concern, each under the 500-line cap). This file re-exports the
6
+ * public render function + error type so the existing `server.ts`
7
+ * import keeps working.
8
8
  *
9
- * Mockup: docs/superpowers/frontend-design/2026-05-02-review-redesign/scrapbook-redesign.html
10
- * Spec: docs/superpowers/specs/2026-05-02-scrapbook-redesign-impl-spec.md
9
+ * Mirrors the post-#191 envelope/dispatch split for mutations
10
+ * (`routes/scrapbook-mutation-{envelope,dispatch}.ts`): the slim entry
11
+ * is the public surface; the directory holds the concerns.
11
12
  */
12
- import { existsSync, readFileSync } from 'node:fs';
13
- import { readCalendar } from '@deskwork/core/calendar';
14
- import { findEntry } from '@deskwork/core/calendar-mutations';
15
- import { resolveCalendarPath } from '@deskwork/core/paths';
16
- import { formatRelativeTime, formatSize, listScrapbook, scrapbookFilePath, } from '@deskwork/core/scrapbook';
17
- import { html, unsafe } from "./html.js";
18
- import { layout } from "./layout.js";
19
- import { renderEditorialFolio } from "./chrome.js";
20
- const KIND_LABEL = {
21
- md: 'MD',
22
- img: 'IMG',
23
- json: 'JSON',
24
- js: 'JS',
25
- txt: 'TXT',
26
- other: '·',
27
- };
28
- function escapeHtml(s) {
29
- return s
30
- .replace(/&/g, '&amp;')
31
- .replace(/</g, '&lt;')
32
- .replace(/>/g, '&gt;')
33
- .replace(/"/g, '&quot;')
34
- .replace(/'/g, '&#39;');
35
- }
36
- /**
37
- * Strip a YAML frontmatter block from the top of an md file. Only strips
38
- * the leading `---\n...\n---\n` block; body-level `---` separators (Setext
39
- * H2 underline, thematic break) are preserved because the function only
40
- * looks at the first 4 chars for the opener.
41
- */
42
- function stripFrontmatter(text) {
43
- if (!text.startsWith('---\n'))
44
- return text;
45
- const closeIdx = text.indexOf('\n---\n', 4);
46
- if (closeIdx < 0)
47
- return text;
48
- return text.slice(closeIdx + 5).replace(/^\n+/, '');
49
- }
50
- /**
51
- * Build the closed-state preview excerpt for md/json/txt. Returns null
52
- * when there's nothing useful to render — empty file, frontmatter-only
53
- * file, or binary masquerading as text — so the caller can omit the
54
- * preview block entirely (matches "other" kind treatment, avoids the
55
- * 6rem min-height void).
56
- *
57
- * For json: pretty-print via JSON.parse + JSON.stringify(_, null, 2) so
58
- * minified single-line files still render multi-line. Falls back to raw
59
- * content on parse error (bad JSON is still readable as text).
60
- *
61
- * Binary detection: NUL byte presence after UTF-8 decode. Real text
62
- * almost never has NUL; binary files have it within the first KB.
63
- */
64
- function previewExcerpt(buf, kind) {
65
- let text = buf.subarray(0, Math.min(buf.byteLength, 2400)).toString('utf-8');
66
- if (text.indexOf('\0') >= 0)
67
- return null;
68
- if (kind === 'md')
69
- text = stripFrontmatter(text);
70
- if (kind === 'json') {
71
- try {
72
- const fullText = buf.toString('utf-8');
73
- text = JSON.stringify(JSON.parse(fullText), null, 2);
74
- }
75
- catch {
76
- // Invalid JSON — fall through to the raw-text excerpt below.
77
- }
78
- }
79
- const excerpt = text.split('\n').slice(0, 8).join('\n').slice(0, 600);
80
- if (excerpt.trim() === '')
81
- return null;
82
- return excerpt;
83
- }
84
- /**
85
- * Count lines in a text file: number of `\n` bytes plus 1 if the last
86
- * byte isn't `\n` (so a 3-line file whether or not it has a trailing
87
- * newline reports 3).
88
- */
89
- function countLines(buf) {
90
- let count = 0;
91
- for (const b of buf)
92
- if (b === 0x0a)
93
- count++;
94
- if (buf.length > 0 && buf[buf.length - 1] !== 0x0a)
95
- count++;
96
- return count;
97
- }
98
- /**
99
- * Count top-level keys in a JSON object. Returns null if the file is not
100
- * valid JSON or its root is not a plain object (arrays, primitives →
101
- * null; caller renders no extra meta).
102
- */
103
- function countJsonKeys(buf) {
104
- try {
105
- const obj = JSON.parse(buf.toString('utf-8'));
106
- if (obj !== null && typeof obj === 'object' && !Array.isArray(obj)) {
107
- return Object.keys(obj).length;
108
- }
109
- return null;
110
- }
111
- catch {
112
- return null;
113
- }
114
- }
115
- /**
116
- * Read width × height from a buffer. Recognizes PNG, JPEG, WebP, and
117
- * GIF; returns null for unrecognized signatures or truncated/malformed
118
- * buffers. Used by the scrapbook card meta to render `{W} × {H}` next
119
- * to the image kind chip.
120
- *
121
- * Each format is parsed from its file-header structure (no external
122
- * dependency); each branch returns null on any unexpected byte rather
123
- * than throwing, so a corrupt image still renders with empty meta.
124
- */
125
- function readImageDimensions(buf) {
126
- if (buf.length < 12)
127
- return null;
128
- // PNG: 89 50 4E 47 0D 0A 1A 0A then IHDR (chunk-length 4, "IHDR" 4,
129
- // width 4, height 4 — width@16, height@20).
130
- if (buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47) {
131
- if (buf.length < 24)
132
- return null;
133
- return { width: buf.readUInt32BE(16), height: buf.readUInt32BE(20) };
134
- }
135
- // GIF: "GIF87a" or "GIF89a" + logical screen descriptor (width LE @6,
136
- // height LE @8).
137
- if (buf[0] === 0x47 && buf[1] === 0x49 && buf[2] === 0x46 &&
138
- buf[3] === 0x38 && (buf[4] === 0x37 || buf[4] === 0x39) && buf[5] === 0x61) {
139
- if (buf.length < 10)
140
- return null;
141
- return { width: buf.readUInt16LE(6), height: buf.readUInt16LE(8) };
142
- }
143
- // JPEG: starts FF D8. Width/height live in a Start-Of-Frame marker
144
- // (FF C0–CF, excluding DHT C4 / JPG C8 / DAC CC). Walk markers
145
- // skipping their payloads until the SOF is found.
146
- if (buf[0] === 0xff && buf[1] === 0xd8) {
147
- return readJpegDimensions(buf);
148
- }
149
- // WebP: "RIFF" {size} "WEBP" then a chunk (VP8 / VP8L / VP8X).
150
- if (buf[0] === 0x52 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x46 &&
151
- buf[8] === 0x57 && buf[9] === 0x45 && buf[10] === 0x42 && buf[11] === 0x50) {
152
- return readWebpDimensions(buf);
153
- }
154
- return null;
155
- }
156
- function readJpegDimensions(buf) {
157
- // Marker walk: skip FF D8 (SOI), then each marker is FF Xn followed
158
- // by a 2-byte big-endian segment length (which includes its own 2
159
- // bytes). The SOF segment's payload is: 1 byte precision, 2 bytes
160
- // height, 2 bytes width (the rest is component info).
161
- let i = 2;
162
- while (i + 4 <= buf.length) {
163
- if (buf[i] !== 0xff)
164
- return null;
165
- let marker = buf[i + 1] ?? 0;
166
- // Skip fill bytes (0xff padding before the actual marker byte).
167
- while (marker === 0xff && i + 2 < buf.length) {
168
- i++;
169
- marker = buf[i + 1] ?? 0;
170
- }
171
- i += 2;
172
- // Standalone markers (no length): RST0–7 (D0–D7) and SOI/EOI/TEM.
173
- if (marker === 0xd9 || marker === 0xd8 || marker === 0x01)
174
- return null;
175
- if (marker >= 0xd0 && marker <= 0xd7)
176
- continue;
177
- if (i + 2 > buf.length)
178
- return null;
179
- const segLen = buf.readUInt16BE(i);
180
- // SOF markers carry the dimensions. Exclusions per JPEG spec:
181
- // C4 (DHT — Huffman tables), C8 (JPG reserved), CC (DAC — arithmetic
182
- // coding conditioning).
183
- const isSof = marker >= 0xc0 && marker <= 0xcf &&
184
- marker !== 0xc4 && marker !== 0xc8 && marker !== 0xcc;
185
- if (isSof) {
186
- if (i + 7 > buf.length)
187
- return null;
188
- return {
189
- width: buf.readUInt16BE(i + 5),
190
- height: buf.readUInt16BE(i + 3),
191
- };
192
- }
193
- i += segLen;
194
- }
195
- return null;
196
- }
197
- function readWebpDimensions(buf) {
198
- // Three sub-formats (per RFC 6386 / VP8L spec / WebP container spec):
199
- // - "VP8 " (lossy): header @20-22: signature 9D 01 2A, then
200
- // 14-bit width LE @23, 14-bit height LE @25
201
- // (each masked to 14 bits — top 2 bits are
202
- // horizontal/vertical scale).
203
- // - "VP8L" (lossless): header @20: signature 0x2F, then 32 bits
204
- // packed: width-1 (14 bits) + height-1 (14
205
- // bits) + alpha-flag + version (4 bits).
206
- // - "VP8X" (extended): flags @20, reserved @21-23, width-1 (24
207
- // bits LE) @24, height-1 (24 bits LE) @27.
208
- // Need at least the RIFF header + chunk fourcc; per-variant length
209
- // checks below cover the variant-specific payload sizes.
210
- if (buf.length < 16)
211
- return null;
212
- const fourcc = buf.subarray(12, 16).toString('ascii');
213
- if (fourcc === 'VP8 ') {
214
- if (buf.length < 30)
215
- return null;
216
- if (buf[23] !== 0x9d || buf[24] !== 0x01 || buf[25] !== 0x2a)
217
- return null;
218
- const w = buf.readUInt16LE(26) & 0x3fff;
219
- const h = buf.readUInt16LE(28) & 0x3fff;
220
- return { width: w, height: h };
221
- }
222
- if (fourcc === 'VP8L') {
223
- if (buf.length < 25)
224
- return null;
225
- if (buf[20] !== 0x2f)
226
- return null;
227
- // Read 4 bytes LE at offset 21, then unpack.
228
- const packed = buf.readUInt32LE(21);
229
- const widthMinus1 = packed & 0x3fff;
230
- const heightMinus1 = (packed >>> 14) & 0x3fff;
231
- return { width: widthMinus1 + 1, height: heightMinus1 + 1 };
232
- }
233
- if (fourcc === 'VP8X') {
234
- if (buf.length < 30)
235
- return null;
236
- // 24-bit little-endian: low byte + (mid << 8) + (high << 16).
237
- const w = ((buf[24] ?? 0) | ((buf[25] ?? 0) << 8) | ((buf[26] ?? 0) << 16)) + 1;
238
- const h = ((buf[27] ?? 0) | ((buf[28] ?? 0) << 8) | ((buf[29] ?? 0) << 16)) + 1;
239
- return { width: w, height: h };
240
- }
241
- return null;
242
- }
243
- /**
244
- * Compute the per-kind extra meta string shown after the kind chip + size:
245
- * md / txt → "{N} lines"
246
- * json → "{N} keys" (root must be a plain object; otherwise empty)
247
- * img → "{W} × {H}" (PNG only; other formats → empty)
248
- * other → empty
249
- *
250
- * ENOENT (race-window with delete) returns empty so the card still
251
- * renders; other errors propagate to the page renderer.
252
- */
253
- function computeKindMeta(ctx, site, path, item) {
254
- if (item.kind !== 'md' && item.kind !== 'txt' && item.kind !== 'json' && item.kind !== 'img') {
255
- return '';
256
- }
257
- let buf;
258
- try {
259
- const fullPath = scrapbookFilePath(ctx.projectRoot, ctx.config, site, path, item.name);
260
- buf = readFileSync(fullPath);
261
- }
262
- catch (e) {
263
- if (e instanceof Error && 'code' in e && e.code === 'ENOENT')
264
- return '';
265
- throw e;
266
- }
267
- if (item.kind === 'md' || item.kind === 'txt')
268
- return `${countLines(buf)} lines`;
269
- if (item.kind === 'json') {
270
- const keys = countJsonKeys(buf);
271
- return keys !== null ? `${keys} keys` : '';
272
- }
273
- // img
274
- const dims = readImageDimensions(buf);
275
- return dims ? `${dims.width} × ${dims.height}` : '';
276
- }
277
- /**
278
- * Server-side preview for the closed-state card. Img → bg-frame URL;
279
- * md → italic Newsreader excerpt with frontmatter stripped; json → mono
280
- * pre with parse-then-stringify pretty-print; txt → mono pre raw excerpt.
281
- * Other / empty / binary-as-text → no preview block.
282
- */
283
- function renderPreview(ctx, site, path, item, opts = {}) {
284
- const { secret = false } = opts;
285
- if (item.kind === 'img') {
286
- const params = new URLSearchParams({ site, path, name: item.name });
287
- if (secret)
288
- params.set('secret', '1');
289
- const url = `/api/dev/scrapbook-file?${params.toString()}`;
290
- return unsafe(html `
291
- <div class="scrap-preview scrap-preview--img" aria-hidden="true">
292
- <div class="scrap-preview--img-frame" style="background-image: url(&quot;${url}&quot;);"></div>
293
- </div>`);
294
- }
295
- if (item.kind !== 'md' && item.kind !== 'txt' && item.kind !== 'json') {
296
- return unsafe('');
297
- }
298
- try {
299
- const fullPath = scrapbookFilePath(ctx.projectRoot, ctx.config, site, path, item.name, secret ? { secret: true } : {});
300
- const buf = readFileSync(fullPath);
301
- const excerpt = previewExcerpt(buf, item.kind);
302
- if (excerpt === null)
303
- return unsafe('');
304
- const safe = escapeHtml(excerpt);
305
- if (item.kind === 'json' || item.kind === 'txt') {
306
- return unsafe(html `
307
- <pre class="scrap-preview scrap-preview--mono" aria-hidden="true">${unsafe(safe)}</pre>`);
308
- }
309
- return unsafe(html `
310
- <div class="scrap-preview scrap-preview-md" aria-hidden="true"><p>${unsafe(safe)}</p></div>`);
311
- }
312
- catch (e) {
313
- // ENOENT = file disappeared between listScrapbook and this read (race
314
- // window with delete); rendering an empty preview is the right call.
315
- // Anything else (EACCES, EISDIR, encoding bugs) propagates so the
316
- // operator sees a real error instead of a silently-broken page.
317
- if (e instanceof Error && 'code' in e && e.code === 'ENOENT') {
318
- return unsafe('');
319
- }
320
- throw e;
321
- }
322
- }
323
- function countByKind(items) {
324
- const counts = {
325
- all: items.length,
326
- md: 0,
327
- img: 0,
328
- json: 0,
329
- js: 0,
330
- txt: 0,
331
- other: 0,
332
- };
333
- for (const i of items)
334
- counts[i.kind]++;
335
- return counts;
336
- }
337
- function renderFilterChips(counts) {
338
- const chip = (kind, label, isAll = false) => unsafe(html `
339
- <button class="scrap-filter" type="button" data-filter="${kind}"
340
- aria-pressed="${isAll ? 'true' : 'false'}">${label} · ${counts[kind]}</button>`);
341
- return unsafe(html `
342
- <div class="scrap-filters" role="toolbar" aria-label="filter by kind">
343
- ${chip('all', 'all', true)}
344
- ${chip('md', 'md')}
345
- ${chip('img', 'img')}
346
- ${chip('json', 'json')}
347
- ${chip('txt', 'txt')}
348
- ${chip('other', 'other')}
349
- </div>`);
350
- }
351
- function renderSearch() {
352
- return unsafe(html `
353
- <div class="scrap-search">
354
- <input type="search" placeholder="filter by name or content" aria-label="filter scrapbook" data-scrap-search />
355
- <span class="scrap-search-kbd">/</span>
356
- </div>`);
357
- }
358
- function renderBreadcrumb(site, path) {
359
- const segments = path.split('/').filter(Boolean);
360
- const last = segments[segments.length - 1] ?? path;
361
- return unsafe(html `
362
- <nav class="scrap-breadcrumb" aria-label="hierarchy">
363
- <a href="/dev/content/${site}">${site}</a><span class="sep">›</span>
364
- <b>${last}</b>
365
- </nav>`);
366
- }
367
- function renderAside(site, path, items, totalSize, lastModified, secretCount, reviewLink) {
368
- const lastModifiedLabel = lastModified ? formatRelativeTime(lastModified) : '—';
369
- const publicCount = items.length;
370
- const sizeLabel = formatSize(totalSize);
371
- const folderLabel = path.split('/').filter(Boolean).pop() ?? path;
372
- const fullPath = `${site}/${path}/scrapbook/`;
373
- // #168 Phase 34 ship-pass — when this scrapbook belongs to a tracked
374
- // calendar entry, expose a "← back to review" link so the operator
375
- // who arrived from the entry-review surface (or via the dashboard's
376
- // scrapbook chip) has an obvious path back. Pre-fix the only nav
377
- // affordance was the breadcrumb's site link, which lands on the
378
- // content tree, not the entry-review.
379
- const backLink = reviewLink !== null
380
- ? unsafe(html `<p class="scrap-aside-back"><a href="${reviewLink}">← back to review</a></p><hr />`)
381
- : unsafe('');
382
- return unsafe(html `
383
- <aside class="scrap-aside">
384
- ${backLink}
385
- <p class="scrap-aside-kicker"><em>§</em> The folder</p>
386
- <h1 class="scrap-aside-title">${folderLabel}</h1>
387
- <p class="scrap-aside-meta">${site}</p>
388
- <hr />
389
- <p class="scrap-aside-totals">
390
- <strong>${publicCount}</strong> public ·
391
- <strong>${secretCount}</strong> secret ·
392
- <em>${sizeLabel}</em>
393
- </p>
394
- <p class="scrap-aside-meta">last modified ${lastModifiedLabel}</p>
395
- <hr />
396
- <ol class="scrap-aside-list" data-scrap-aside-list>
397
- ${items.map((item, i) => {
398
- const seq = String(i + 1).padStart(2, '0');
399
- return unsafe(html `<li><span class="num">${seq}</span><a href="#item-${i + 1}" data-scrap-aside-link>${item.name}</a></li>`);
400
- })}
401
- </ol>
402
- <hr />
403
- <div class="scrap-aside-actions">
404
- <button class="scrap-aside-btn scrap-aside-btn--primary" type="button" data-action="new-note">+ new note</button>
405
- <button class="scrap-aside-btn" type="button" data-action="upload">+ upload file</button>
406
- </div>
407
- <hr />
408
- <p class="scrap-aside-path">${fullPath}</p>
409
- </aside>`);
410
- }
411
- function renderCard(ctx, site, path, item, index, opts = {}) {
412
- const { secret = false } = opts;
413
- const seq = String(index + 1).padStart(2, '0');
414
- const kindLabel = KIND_LABEL[item.kind];
415
- const kindClass = item.kind === 'other' ? '' : `scrap-kind--${item.kind}`;
416
- const time = item.mtime
417
- ? html `<time class="scrap-time" datetime="${item.mtime}">${formatRelativeTime(item.mtime)}</time>`
418
- : '';
419
- const preview = renderPreview(ctx, site, path, item, { secret });
420
- const kindMeta = computeKindMeta(ctx, site, path, item);
421
- const kindMetaHtml = kindMeta
422
- ? unsafe(html `<span>·</span><span>${kindMeta}</span>`)
423
- : unsafe('');
424
- const editBtn = item.kind === 'img'
425
- ? unsafe('')
426
- : unsafe(html `<button class="scrap-tool" type="button" data-action="edit">edit</button>`);
427
- // Secret cards get id="secret-item-N" to disambiguate from public ids in
428
- // restoreFromHash + aside cross-link lookups (F4 contract); the
429
- // mark-secret action toggle reads "mark public" since clicking it moves
430
- // the card OUT of the secret section.
431
- const id = secret ? `secret-item-${index + 1}` : `item-${index + 1}`;
432
- const markSecretLabel = secret ? 'mark public' : 'mark secret';
433
- const dataSecretAttr = secret ? ' data-secret="true"' : '';
434
- // #164 Phase 34b — small ⚿ glyph next to .scrap-name on secret
435
- // cards. Provides visual continuity for the secret marker once a
436
- // card is expanded (where it grows outside the grouped section's
437
- // visual scope).
438
- const secretGlyph = secret
439
- ? unsafe(html `<span class="scrap-name-secret-mark" aria-label="secret" title="secret — never published">⚿</span>`)
440
- : unsafe('');
441
- return unsafe(html `
442
- <li class="scrap-card" data-kind="${item.kind}" data-state="closed" id="${id}"${unsafe(dataSecretAttr)}>
443
- <div class="scrap-card-head">
444
- <span class="scrap-seq">N° ${seq}</span>
445
- ${secretGlyph}
446
- <span class="scrap-name" data-action="open">${item.name}</span>
447
- ${unsafe(time)}
448
- </div>
449
- <div class="scrap-card-meta">
450
- <span class="scrap-kind ${kindClass}">${kindLabel}</span>
451
- <span class="scrap-size">${formatSize(item.size)}</span>
452
- ${kindMetaHtml}
453
- </div>
454
- ${preview}
455
- <div class="scrap-card-foot">
456
- <button class="scrap-tool scrap-tool--primary" type="button" data-action="open">open</button>
457
- ${editBtn}
458
- <button class="scrap-tool" type="button" data-action="rename">rename</button>
459
- <button class="scrap-tool" type="button" data-action="mark-secret">${markSecretLabel}</button>
460
- <span class="spacer"></span>
461
- <button class="scrap-tool scrap-tool--delete" type="button" data-action="delete">delete</button>
462
- </div>
463
- </li>`);
464
- }
465
- /**
466
- * Inline new-note composer (Phase 34b — #166).
467
- *
468
- * Mirrors the pre-F1 inline composer (`44094ee^:scrapbook.ts:274-294`),
469
- * adapted to the F1 `.scrap-*` design vocabulary. Hidden by default;
470
- * the aside's `+ new note` button reveals it via the client wire-up.
471
- *
472
- * Per `.claude/rules/affordance-placement.md`: component-attached to
473
- * the page (not a generic toolbar), placed where the resulting note
474
- * will appear in sorted position. Direct manipulation: in-page form,
475
- * filename + body + secret toggle visible inline, Cmd/Ctrl+S saves,
476
- * Esc cancels. Replaces the F1 `window.prompt()` regression (#166).
477
- */
478
- function renderComposer() {
479
- return unsafe(html `
480
- <form class="scrap-composer" data-scrap-composer hidden>
481
- <header class="scrap-composer-head">
482
- <span class="scrap-composer-glyph" aria-hidden="true">✎</span>
483
- <span class="scrap-composer-kicker">NEW NOTE</span>
484
- <input type="text" class="scrap-composer-filename" data-composer-filename
485
- placeholder="note-name.md" aria-label="new note filename" />
486
- <label class="scrap-composer-secret" title="save under scrapbook/secret/ — never published">
487
- <input type="checkbox" data-composer-secret />
488
- <span>secret</span>
489
- </label>
490
- <button class="scrap-tool" type="button" data-action="composer-cancel">cancel</button>
491
- <button class="scrap-tool scrap-tool--primary" type="submit" data-action="composer-save">save →</button>
492
- </header>
493
- <textarea class="scrap-composer-body" data-composer-body
494
- placeholder="Write the note in markdown. Cmd/Ctrl+S saves, Esc cancels."
495
- aria-label="new note body" rows="8"></textarea>
496
- </form>`);
497
- }
498
- function renderDropZone() {
499
- return unsafe(html `
500
- <div class="scrap-drop" role="button" tabindex="0" data-action="upload"
501
- aria-label="Drop a file here, or press Enter to pick one">
502
- ── drop a file here, or pick one ──
503
- </div>`);
504
- }
505
- function renderSecretSection(ctx, site, path, secretItems) {
506
- if (secretItems.length === 0)
507
- return unsafe('');
508
- const cards = secretItems.map((item, i) => renderCard(ctx, site, path, item, i, { secret: true }));
509
- return unsafe(html `
510
- <section class="scrap-secret" aria-label="secret items">
511
- <header class="scrap-secret-head">
512
- <span class="scrap-secret-mark" aria-hidden="true">⚿</span>
513
- <h2 class="scrap-secret-title">Secret</h2>
514
- <span class="scrap-secret-badge">private — never published</span>
515
- </header>
516
- <ol class="scrap-cards">
517
- ${cards}
518
- </ol>
519
- </section>`);
520
- }
521
- /**
522
- * #168 Phase 34 ship-pass — when the scrapbook path matches a tracked
523
- * calendar entry with a stamped UUID, return the entry-keyed review
524
- * URL so the aside can render a "← back to review" link. Returns null
525
- * when no entry matches (organizational subdirs, ad-hoc paths, or
526
- * pre-doctor entries lacking an id) — the link is then omitted.
527
- *
528
- * Failures (calendar absent, parse error) fall through to null so a
529
- * transient calendar issue never blocks the scrapbook render.
530
- */
531
- function lookupEntryReviewLink(ctx, site, path) {
532
- if (!(site in ctx.config.sites))
533
- return null;
534
- try {
535
- const calendarPath = resolveCalendarPath(ctx.projectRoot, ctx.config, site);
536
- if (!existsSync(calendarPath))
537
- return null;
538
- const cal = readCalendar(calendarPath);
539
- const entry = findEntry(cal, path);
540
- if (!entry || !entry.id)
541
- return null;
542
- return `/dev/editorial-review/entry/${entry.id}`;
543
- }
544
- catch {
545
- return null;
546
- }
547
- }
548
- export function renderScrapbookPage(ctx, site, path) {
549
- // Validate site against the project's configured site list. Without
550
- // this check, an unknown site key reaches the path resolver and
551
- // produces either an opaque error or a path traversal vector.
552
- if (!(site in ctx.config.sites)) {
553
- throw new Error(`unknown site: ${site}`);
554
- }
555
- // listScrapbook returns { exists: false, items: [] } for missing dirs
556
- // (packages/core/src/scrapbook.ts:337-339), so an empty scrapbook is not
557
- // an error path. Real errors (slug validation, scrapbookDir resolution
558
- // failures, FS permission issues) propagate to the studio's error handler.
559
- const result = listScrapbook(ctx.projectRoot, ctx.config, site, path);
560
- const items = result.items;
561
- const secretItems = result.secretItems;
562
- const totalSize = items.reduce((s, i) => s + i.size, 0);
563
- const lastModified = items.reduce((acc, i) => {
564
- if (!i.mtime)
565
- return acc;
566
- if (!acc || i.mtime > acc)
567
- return i.mtime;
568
- return acc;
569
- }, null);
570
- const counts = countByKind(items);
571
- const folderLabel = path.split('/').filter(Boolean).pop() ?? path;
572
- const cards = items.map((item, i) => renderCard(ctx, site, path, item, i));
573
- const cardsHtml = cards.map((c) => c.__raw).join('');
574
- const reviewLink = lookupEntryReviewLink(ctx, site, path);
575
- const body = html `
576
- ${renderEditorialFolio('content', `scrapbook · ${site}/${path}`)}
577
- <main class="scrap-page" data-site="${site}" data-path="${path}">
578
- ${renderAside(site, path, items, totalSize, lastModified, secretItems.length, reviewLink)}
579
- <section class="scrap-main">
580
- <header class="scrap-main-header">
581
- ${renderBreadcrumb(site, path)}
582
- ${renderSearch()}
583
- </header>
584
- ${renderFilterChips(counts)}
585
- ${renderComposer()}
586
- <ol class="scrap-cards" id="cards" data-scrap-cards>
587
- ${unsafe(cardsHtml)}
588
- </ol>
589
- ${renderDropZone()}
590
- ${renderSecretSection(ctx, site, path, secretItems)}
591
- </section>
592
- </main>`;
593
- return layout({
594
- title: `scrapbook · ${folderLabel} — dev`,
595
- cssHrefs: [
596
- '/static/css/editorial-review.css',
597
- '/static/css/editorial-nav.css',
598
- '/static/css/scrapbook.css',
599
- '/static/css/blog-figure.css',
600
- ],
601
- bodyAttrs: 'data-review-ui="scrapbook"',
602
- bodyHtml: body,
603
- scriptModules: ['scrapbook-client'],
604
- });
605
- }
13
+ export { renderScrapbookPage, ScrapbookPageError, } from "./scrapbook/index.js";
606
14
  //# sourceMappingURL=scrapbook.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"scrapbook.js","sourceRoot":"","sources":["../../src/pages/scrapbook.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scrapbook.js","sourceRoot":"","sources":["../../src/pages/scrapbook.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EACL,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC"}