@deskwork/core 0.9.5

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 (188) hide show
  1. package/dist/body-state.d.ts +27 -0
  2. package/dist/body-state.d.ts.map +1 -0
  3. package/dist/body-state.js +62 -0
  4. package/dist/body-state.js.map +1 -0
  5. package/dist/calendar-mutations.d.ts +124 -0
  6. package/dist/calendar-mutations.d.ts.map +1 -0
  7. package/dist/calendar-mutations.js +305 -0
  8. package/dist/calendar-mutations.js.map +1 -0
  9. package/dist/calendar.d.ts +54 -0
  10. package/dist/calendar.d.ts.map +1 -0
  11. package/dist/calendar.js +430 -0
  12. package/dist/calendar.js.map +1 -0
  13. package/dist/cli.d.ts +38 -0
  14. package/dist/cli.d.ts.map +1 -0
  15. package/dist/cli.js +72 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/config.d.ts +91 -0
  18. package/dist/config.d.ts.map +1 -0
  19. package/dist/config.js +216 -0
  20. package/dist/config.js.map +1 -0
  21. package/dist/content-index.d.ts +74 -0
  22. package/dist/content-index.d.ts.map +1 -0
  23. package/dist/content-index.js +205 -0
  24. package/dist/content-index.js.map +1 -0
  25. package/dist/content-tree-fs-walk.d.ts +54 -0
  26. package/dist/content-tree-fs-walk.d.ts.map +1 -0
  27. package/dist/content-tree-fs-walk.js +112 -0
  28. package/dist/content-tree-fs-walk.js.map +1 -0
  29. package/dist/content-tree-helpers.d.ts +52 -0
  30. package/dist/content-tree-helpers.d.ts.map +1 -0
  31. package/dist/content-tree-helpers.js +116 -0
  32. package/dist/content-tree-helpers.js.map +1 -0
  33. package/dist/content-tree-types.d.ts +175 -0
  34. package/dist/content-tree-types.d.ts.map +1 -0
  35. package/dist/content-tree-types.js +10 -0
  36. package/dist/content-tree-types.js.map +1 -0
  37. package/dist/content-tree.d.ts +93 -0
  38. package/dist/content-tree.d.ts.map +1 -0
  39. package/dist/content-tree.js +385 -0
  40. package/dist/content-tree.js.map +1 -0
  41. package/dist/doctor/index.d.ts +11 -0
  42. package/dist/doctor/index.d.ts.map +1 -0
  43. package/dist/doctor/index.js +10 -0
  44. package/dist/doctor/index.js.map +1 -0
  45. package/dist/doctor/project-rules.d.ts +59 -0
  46. package/dist/doctor/project-rules.d.ts.map +1 -0
  47. package/dist/doctor/project-rules.js +143 -0
  48. package/dist/doctor/project-rules.js.map +1 -0
  49. package/dist/doctor/rules/calendar-uuid-missing.d.ts +19 -0
  50. package/dist/doctor/rules/calendar-uuid-missing.d.ts.map +1 -0
  51. package/dist/doctor/rules/calendar-uuid-missing.js +176 -0
  52. package/dist/doctor/rules/calendar-uuid-missing.js.map +1 -0
  53. package/dist/doctor/rules/duplicate-id.d.ts +27 -0
  54. package/dist/doctor/rules/duplicate-id.d.ts.map +1 -0
  55. package/dist/doctor/rules/duplicate-id.js +157 -0
  56. package/dist/doctor/rules/duplicate-id.js.map +1 -0
  57. package/dist/doctor/rules/legacy-top-level-id-migration.d.ts +40 -0
  58. package/dist/doctor/rules/legacy-top-level-id-migration.d.ts.map +1 -0
  59. package/dist/doctor/rules/legacy-top-level-id-migration.js +232 -0
  60. package/dist/doctor/rules/legacy-top-level-id-migration.js.map +1 -0
  61. package/dist/doctor/rules/missing-frontmatter-id.d.ts +45 -0
  62. package/dist/doctor/rules/missing-frontmatter-id.d.ts.map +1 -0
  63. package/dist/doctor/rules/missing-frontmatter-id.js +283 -0
  64. package/dist/doctor/rules/missing-frontmatter-id.js.map +1 -0
  65. package/dist/doctor/rules/orphan-frontmatter-id.d.ts +18 -0
  66. package/dist/doctor/rules/orphan-frontmatter-id.d.ts.map +1 -0
  67. package/dist/doctor/rules/orphan-frontmatter-id.js +154 -0
  68. package/dist/doctor/rules/orphan-frontmatter-id.js.map +1 -0
  69. package/dist/doctor/rules/schema-rejected.d.ts +20 -0
  70. package/dist/doctor/rules/schema-rejected.d.ts.map +1 -0
  71. package/dist/doctor/rules/schema-rejected.js +44 -0
  72. package/dist/doctor/rules/schema-rejected.js.map +1 -0
  73. package/dist/doctor/rules/slug-collision.d.ts +18 -0
  74. package/dist/doctor/rules/slug-collision.d.ts.map +1 -0
  75. package/dist/doctor/rules/slug-collision.js +65 -0
  76. package/dist/doctor/rules/slug-collision.js.map +1 -0
  77. package/dist/doctor/rules/workflow-stale.d.ts +20 -0
  78. package/dist/doctor/rules/workflow-stale.d.ts.map +1 -0
  79. package/dist/doctor/rules/workflow-stale.js +136 -0
  80. package/dist/doctor/rules/workflow-stale.js.map +1 -0
  81. package/dist/doctor/runner.d.ts +75 -0
  82. package/dist/doctor/runner.d.ts.map +1 -0
  83. package/dist/doctor/runner.js +289 -0
  84. package/dist/doctor/runner.js.map +1 -0
  85. package/dist/doctor/schema-patch.d.ts +21 -0
  86. package/dist/doctor/schema-patch.d.ts.map +1 -0
  87. package/dist/doctor/schema-patch.js +92 -0
  88. package/dist/doctor/schema-patch.js.map +1 -0
  89. package/dist/doctor/types.d.ts +185 -0
  90. package/dist/doctor/types.d.ts.map +1 -0
  91. package/dist/doctor/types.js +13 -0
  92. package/dist/doctor/types.js.map +1 -0
  93. package/dist/frontmatter.d.ts +103 -0
  94. package/dist/frontmatter.d.ts.map +1 -0
  95. package/dist/frontmatter.js +306 -0
  96. package/dist/frontmatter.js.map +1 -0
  97. package/dist/index.d.ts +27 -0
  98. package/dist/index.d.ts.map +1 -0
  99. package/dist/index.js +27 -0
  100. package/dist/index.js.map +1 -0
  101. package/dist/ingest-derive.d.ts +79 -0
  102. package/dist/ingest-derive.d.ts.map +1 -0
  103. package/dist/ingest-derive.js +299 -0
  104. package/dist/ingest-derive.js.map +1 -0
  105. package/dist/ingest-paths.d.ts +37 -0
  106. package/dist/ingest-paths.d.ts.map +1 -0
  107. package/dist/ingest-paths.js +176 -0
  108. package/dist/ingest-paths.js.map +1 -0
  109. package/dist/ingest.d.ts +162 -0
  110. package/dist/ingest.d.ts.map +1 -0
  111. package/dist/ingest.js +269 -0
  112. package/dist/ingest.js.map +1 -0
  113. package/dist/journal.d.ts +49 -0
  114. package/dist/journal.d.ts.map +1 -0
  115. package/dist/journal.js +113 -0
  116. package/dist/journal.js.map +1 -0
  117. package/dist/outline-split.d.ts +38 -0
  118. package/dist/outline-split.d.ts.map +1 -0
  119. package/dist/outline-split.js +84 -0
  120. package/dist/outline-split.js.map +1 -0
  121. package/dist/overrides.d.ts +83 -0
  122. package/dist/overrides.d.ts.map +1 -0
  123. package/dist/overrides.js +88 -0
  124. package/dist/overrides.js.map +1 -0
  125. package/dist/paths.d.ts +183 -0
  126. package/dist/paths.d.ts.map +1 -0
  127. package/dist/paths.js +266 -0
  128. package/dist/paths.js.map +1 -0
  129. package/dist/remark-image-figure.mjs +77 -0
  130. package/dist/remark-strip-first-h1.mjs +26 -0
  131. package/dist/remark-strip-outline.mjs +44 -0
  132. package/dist/rename-slug.d.ts +49 -0
  133. package/dist/rename-slug.d.ts.map +1 -0
  134. package/dist/rename-slug.js +161 -0
  135. package/dist/rename-slug.js.map +1 -0
  136. package/dist/review/handlers.d.ts +55 -0
  137. package/dist/review/handlers.d.ts.map +1 -0
  138. package/dist/review/handlers.js +307 -0
  139. package/dist/review/handlers.js.map +1 -0
  140. package/dist/review/index.d.ts +14 -0
  141. package/dist/review/index.d.ts.map +1 -0
  142. package/dist/review/index.js +13 -0
  143. package/dist/review/index.js.map +1 -0
  144. package/dist/review/journal-mappers.d.ts +35 -0
  145. package/dist/review/journal-mappers.d.ts.map +1 -0
  146. package/dist/review/journal-mappers.js +48 -0
  147. package/dist/review/journal-mappers.js.map +1 -0
  148. package/dist/review/pipeline.d.ts +79 -0
  149. package/dist/review/pipeline.d.ts.map +1 -0
  150. package/dist/review/pipeline.js +234 -0
  151. package/dist/review/pipeline.js.map +1 -0
  152. package/dist/review/render.d.ts +27 -0
  153. package/dist/review/render.d.ts.map +1 -0
  154. package/dist/review/render.js +42 -0
  155. package/dist/review/render.js.map +1 -0
  156. package/dist/review/report.d.ts +50 -0
  157. package/dist/review/report.d.ts.map +1 -0
  158. package/dist/review/report.js +164 -0
  159. package/dist/review/report.js.map +1 -0
  160. package/dist/review/result.d.ts +12 -0
  161. package/dist/review/result.d.ts.map +1 -0
  162. package/dist/review/result.js +12 -0
  163. package/dist/review/result.js.map +1 -0
  164. package/dist/review/start-handlers.d.ts +62 -0
  165. package/dist/review/start-handlers.d.ts.map +1 -0
  166. package/dist/review/start-handlers.js +223 -0
  167. package/dist/review/start-handlers.js.map +1 -0
  168. package/dist/review/types.d.ts +169 -0
  169. package/dist/review/types.d.ts.map +1 -0
  170. package/dist/review/types.js +26 -0
  171. package/dist/review/types.js.map +1 -0
  172. package/dist/review/workflow-paths.d.ts +68 -0
  173. package/dist/review/workflow-paths.d.ts.map +1 -0
  174. package/dist/review/workflow-paths.js +112 -0
  175. package/dist/review/workflow-paths.js.map +1 -0
  176. package/dist/scaffold.d.ts +67 -0
  177. package/dist/scaffold.d.ts.map +1 -0
  178. package/dist/scaffold.js +122 -0
  179. package/dist/scaffold.js.map +1 -0
  180. package/dist/scrapbook.d.ts +229 -0
  181. package/dist/scrapbook.d.ts.map +1 -0
  182. package/dist/scrapbook.js +500 -0
  183. package/dist/scrapbook.js.map +1 -0
  184. package/dist/types.d.ts +197 -0
  185. package/dist/types.d.ts.map +1 -0
  186. package/dist/types.js +120 -0
  187. package/dist/types.js.map +1 -0
  188. package/package.json +160 -0
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Blog post scaffolder.
3
+ *
4
+ * Creates the markdown file for a calendar entry with YAML frontmatter
5
+ * matching the host project's conventions. Called by the outline skill
6
+ * for entries with `contentType: 'blog'`. YouTube and tool entries
7
+ * skip this step entirely.
8
+ *
9
+ * Knobs (all per-site config):
10
+ * - blogFilenameTemplate path template under contentDir. `{slug}` is
11
+ * replaced. Default `"{slug}/index.md"`.
12
+ * - blogLayout if set, emit `layout: <value>` frontmatter
13
+ * - blogInitialState if set, emit `state: <value>` frontmatter
14
+ * (typical: `"draft"` to gate prod builds)
15
+ * - blogOutlineSection if true, body includes `## Outline` section
16
+ *
17
+ * Author comes from `config.author` (or an explicit override).
18
+ */
19
+ import type { CalendarEntry } from './types.ts';
20
+ import type { DeskworkConfig } from './config.ts';
21
+ import type { ContentIndex } from './content-index.ts';
22
+ export interface ScaffoldResult {
23
+ /** Absolute path to the created markdown file */
24
+ filePath: string;
25
+ /** Path relative to the project root */
26
+ relativePath: string;
27
+ /**
28
+ * Path of the file relative to `contentDir` — reported to the
29
+ * caller so it can show the operator where the file landed. The
30
+ * file's connection to the calendar entry is now carried by its
31
+ * frontmatter `id:` field, not by a path string on the calendar
32
+ * row (Phase 19a).
33
+ */
34
+ contentRelativePath: string;
35
+ }
36
+ /** Layout options for `scaffoldBlogPost`. Picks the on-disk shape. */
37
+ export type ScaffoldLayout = 'index' | 'readme' | 'flat';
38
+ export interface ScaffoldOptions {
39
+ /** Override `config.author` for this post. */
40
+ authorOverride?: string;
41
+ /**
42
+ * Pick the on-disk shape of the scaffolded file. When omitted, falls
43
+ * back to the site's `blogFilenameTemplate` (preserving legacy
44
+ * audiocontrol behavior).
45
+ *
46
+ * - `'index'` → `<slug>/index.md` (hub-style, public route in most
47
+ * single-level Astro patterns)
48
+ * - `'readme'` → `<slug>/README.md` (editorial-private — directory
49
+ * exists, but content collections that match `*\/index.md` won't
50
+ * pick it up)
51
+ * - `'flat'` → `<slug>.md` (a sibling file at the parent dir, no
52
+ * own directory; useful for many small chapters under one parent)
53
+ */
54
+ layout?: ScaffoldLayout;
55
+ /**
56
+ * Pre-built content index (per-request memoization). When omitted,
57
+ * the scaffolder builds one fresh. Used for the duplicate-binding
58
+ * preflight (Issue #66): if the entry's id already binds a file
59
+ * elsewhere under contentDir, refuse to scaffold a parallel file.
60
+ */
61
+ index?: ContentIndex;
62
+ }
63
+ /**
64
+ * Create the blog post markdown for a calendar entry.
65
+ */
66
+ export declare function scaffoldBlogPost(projectRoot: string, config: DeskworkConfig, site: string | null | undefined, entry: CalendarEntry, opts?: ScaffoldOptions): ScaffoldResult;
67
+ //# sourceMappingURL=scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKvD,MAAM,WAAW,cAAc;IAC7B,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB;;;;;;OAMG;IACH,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,sEAAsE;AACtE,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAEzD,MAAM,WAAW,eAAe;IAC9B,8CAA8C;IAC9C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;;;;;;;;OAYG;IACH,MAAM,CAAC,EAAE,cAAc,CAAC;IACxB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,KAAK,EAAE,aAAa,EACpB,IAAI,GAAE,eAAoB,GACzB,cAAc,CA2FhB"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Blog post scaffolder.
3
+ *
4
+ * Creates the markdown file for a calendar entry with YAML frontmatter
5
+ * matching the host project's conventions. Called by the outline skill
6
+ * for entries with `contentType: 'blog'`. YouTube and tool entries
7
+ * skip this step entirely.
8
+ *
9
+ * Knobs (all per-site config):
10
+ * - blogFilenameTemplate path template under contentDir. `{slug}` is
11
+ * replaced. Default `"{slug}/index.md"`.
12
+ * - blogLayout if set, emit `layout: <value>` frontmatter
13
+ * - blogInitialState if set, emit `state: <value>` frontmatter
14
+ * (typical: `"draft"` to gate prod builds)
15
+ * - blogOutlineSection if true, body includes `## Outline` section
16
+ *
17
+ * Author comes from `config.author` (or an explicit override).
18
+ */
19
+ import { existsSync, mkdirSync } from 'node:fs';
20
+ import { dirname, join, relative } from 'node:path';
21
+ import { buildContentIndex } from "./content-index.js";
22
+ import { resolveSite, resolveBlogFilePath } from "./paths.js";
23
+ import { writeFrontmatter } from "./frontmatter.js";
24
+ /**
25
+ * Create the blog post markdown for a calendar entry.
26
+ */
27
+ export function scaffoldBlogPost(projectRoot, config, site, entry, opts = {}) {
28
+ const slug = resolveSite(config, site);
29
+ const siteCfg = config.sites[slug];
30
+ const author = opts.authorOverride ?? config.author;
31
+ if (!author) {
32
+ throw new Error(`Cannot scaffold blog post: no author configured. ` +
33
+ `Set "author" at the top level of .deskwork/config.json, or pass an explicit author.`);
34
+ }
35
+ // The `deskwork.id` field binds this file to its CalendarEntry
36
+ // refactor-proof. Phase 19 made entry id (UUID) the canonical internal
37
+ // identifier; writing it into frontmatter lets the content-index pick
38
+ // this file up regardless of slug renames or fs relocations. The id
39
+ // lives under a `deskwork:` namespace (Issue #38) so deskwork doesn't
40
+ // claim the global top-level `id:` keyspace — operators may use that
41
+ // freely. `addEntry` always sets `entry.id` to a UUID; if it's missing
42
+ // here we have a real bug upstream — fail loud rather than scaffold an
43
+ // unbindable file. Validated UP FRONT so the duplicate-binding check
44
+ // below can rely on it.
45
+ if (!entry.id || entry.id.trim() === '') {
46
+ throw new Error('Cannot scaffold entry without id; this is a bug in calendar-mutations or upstream. ' +
47
+ `Entry slug: "${entry.slug}".`);
48
+ }
49
+ // Issue #66: if this entry's id is already bound to a file elsewhere
50
+ // under contentDir, refuse to scaffold a parallel file. Two files
51
+ // sharing the same `deskwork.id` is exactly the duplicate-id state
52
+ // doctor flags; better to bail here with an actionable message than
53
+ // create the bug.
54
+ const index = opts.index ?? buildContentIndex(projectRoot, config, slug);
55
+ const existingBinding = index.byId.get(entry.id);
56
+ if (existingBinding !== undefined) {
57
+ const existingRel = relative(projectRoot, existingBinding);
58
+ throw new Error(`Cannot scaffold: entry "${entry.slug}" is already bound to file at ` +
59
+ `"${existingRel}". Use that file directly, or unbind it first ` +
60
+ `(remove its frontmatter \`deskwork.id\`) before scaffolding a new one.`);
61
+ }
62
+ // When a layout is requested, compute the contentDir-relative path
63
+ // explicitly. Otherwise fall back to the site template.
64
+ const contentRelativePath = opts.layout
65
+ ? layoutToContentRelativePath(opts.layout, entry.slug)
66
+ : undefined;
67
+ const filePath = resolveBlogFilePath(projectRoot, config, slug, entry.slug, contentRelativePath);
68
+ const relativePath = relative(projectRoot, filePath);
69
+ if (existsSync(filePath)) {
70
+ throw new Error(`Blog post already exists at ${relativePath}`);
71
+ }
72
+ const dateStr = new Date().toISOString().slice(0, 10);
73
+ const data = {};
74
+ // `deskwork` block first so it's the visually-stable top of the
75
+ // frontmatter — operators reading the file see the namespaced
76
+ // binding immediately and won't mistake it for a host-rendering field.
77
+ data.deskwork = { id: entry.id };
78
+ if (siteCfg.blogLayout)
79
+ data.layout = siteCfg.blogLayout;
80
+ data.title = entry.title;
81
+ data.description = entry.description;
82
+ data.date = formatDateHuman(dateStr);
83
+ data.datePublished = dateStr;
84
+ data.dateModified = dateStr;
85
+ data.author = author;
86
+ if (siteCfg.blogInitialState)
87
+ data.state = siteCfg.blogInitialState;
88
+ const body = buildBody(entry.title, siteCfg.blogOutlineSection === true);
89
+ mkdirSync(dirname(filePath), { recursive: true });
90
+ writeFrontmatter(filePath, data, body);
91
+ // Always report the contentDir-relative path so the caller can show
92
+ // the operator where the file landed. When no explicit layout was
93
+ // requested we derive it from the resolved file path.
94
+ const reported = contentRelativePath ??
95
+ relative(join(projectRoot, siteCfg.contentDir), filePath);
96
+ return { filePath, relativePath, contentRelativePath: reported };
97
+ }
98
+ /** Map a ScaffoldLayout + slug to the contentDir-relative file path. */
99
+ function layoutToContentRelativePath(layout, slug) {
100
+ switch (layout) {
101
+ case 'index':
102
+ return `${slug}/index.md`;
103
+ case 'readme':
104
+ return `${slug}/README.md`;
105
+ case 'flat':
106
+ return `${slug}.md`;
107
+ }
108
+ }
109
+ function buildBody(title, withOutline) {
110
+ const parts = ['', `# ${title}`, ''];
111
+ if (withOutline) {
112
+ parts.push('## Outline', '', '<!-- Sketch the shape of the post here before drafting the body. -->', '');
113
+ }
114
+ parts.push('<!-- Write your post here -->', '');
115
+ return parts.join('\n');
116
+ }
117
+ /** Format a date as "Month YYYY" (e.g. "March 2026"). */
118
+ function formatDateHuman(isoDate) {
119
+ const d = new Date(`${isoDate}T00:00:00`);
120
+ return d.toLocaleDateString('en-US', { month: 'long', year: 'numeric' });
121
+ }
122
+ //# sourceMappingURL=scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAIpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AA8CpD;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,WAAmB,EACnB,MAAsB,EACtB,IAA+B,EAC/B,KAAoB,EACpB,OAAwB,EAAE;IAE1B,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEnC,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,IAAI,MAAM,CAAC,MAAM,CAAC;IACpD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,mDAAmD;YACjD,qFAAqF,CACxF,CAAC;IACJ,CAAC;IAED,+DAA+D;IAC/D,uEAAuE;IACvE,sEAAsE;IACtE,oEAAoE;IACpE,sEAAsE;IACtE,qEAAqE;IACrE,uEAAuE;IACvE,uEAAuE;IACvE,qEAAqE;IACrE,wBAAwB;IACxB,IAAI,CAAC,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CACb,qFAAqF;YACnF,gBAAgB,KAAK,CAAC,IAAI,IAAI,CACjC,CAAC;IACJ,CAAC;IAED,qEAAqE;IACrE,kEAAkE;IAClE,mEAAmE;IACnE,oEAAoE;IACpE,kBAAkB;IAClB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACzE,MAAM,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACjD,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QAC3D,MAAM,IAAI,KAAK,CACb,2BAA2B,KAAK,CAAC,IAAI,gCAAgC;YACnE,IAAI,WAAW,gDAAgD;YAC/D,wEAAwE,CAC3E,CAAC;IACJ,CAAC;IAED,mEAAmE;IACnE,wDAAwD;IACxD,MAAM,mBAAmB,GAAG,IAAI,CAAC,MAAM;QACrC,CAAC,CAAC,2BAA2B,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC;QACtD,CAAC,CAAC,SAAS,CAAC;IACd,MAAM,QAAQ,GAAG,mBAAmB,CAClC,WAAW,EACX,MAAM,EACN,IAAI,EACJ,KAAK,CAAC,IAAI,EACV,mBAAmB,CACpB,CAAC;IACF,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAErD,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,+BAA+B,YAAY,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEtD,MAAM,IAAI,GAA4B,EAAE,CAAC;IACzC,gEAAgE;IAChE,8DAA8D;IAC9D,uEAAuE;IACvE,IAAI,CAAC,QAAQ,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;IACjC,IAAI,OAAO,CAAC,UAAU;QAAE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IACzD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IACzB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;IACrC,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACrC,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC;IAC7B,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC;IAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACrB,IAAI,OAAO,CAAC,gBAAgB;QAAE,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAEpE,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,kBAAkB,KAAK,IAAI,CAAC,CAAC;IAEzE,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,gBAAgB,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAEvC,oEAAoE;IACpE,kEAAkE;IAClE,sDAAsD;IACtD,MAAM,QAAQ,GACZ,mBAAmB;QACnB,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC5D,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,mBAAmB,EAAE,QAAQ,EAAE,CAAC;AACnE,CAAC;AAED,wEAAwE;AACxE,SAAS,2BAA2B,CAClC,MAAsB,EACtB,IAAY;IAEZ,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,OAAO;YACV,OAAO,GAAG,IAAI,WAAW,CAAC;QAC5B,KAAK,QAAQ;YACX,OAAO,GAAG,IAAI,YAAY,CAAC;QAC7B,KAAK,MAAM;YACT,OAAO,GAAG,IAAI,KAAK,CAAC;IACxB,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,KAAa,EAAE,WAAoB;IACpD,MAAM,KAAK,GAAa,CAAC,EAAE,EAAE,KAAK,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IAC/C,IAAI,WAAW,EAAE,CAAC;QAChB,KAAK,CAAC,IAAI,CACR,YAAY,EACZ,EAAE,EACF,sEAAsE,EACtE,EAAE,CACH,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,+BAA+B,EAAE,EAAE,CAAC,CAAC;IAChD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,yDAAyD;AACzD,SAAS,eAAe,CAAC,OAAe;IACtC,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,OAAO,WAAW,CAAC,CAAC;IAC1C,OAAO,CAAC,CAAC,kBAAkB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;AAC3E,CAAC"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Scrapbook helpers — the per-article `<contentDir>/<slug>/scrapbook/`
3
+ * directory. The scrapbook is a working-notes home for receipts,
4
+ * research, and references attached to an in-flight article. Committed
5
+ * to git alongside the article; not baked to the public site.
6
+ *
7
+ * Responsibilities:
8
+ * - Resolve + validate slug + filename (reject `..`, absolute paths,
9
+ * and anything outside the article's scrapbook dir)
10
+ * - List + read + mutate files inside one scrapbook
11
+ * - Classify files by extension into the design type buckets
12
+ * - Format relative mtime + total size for the studio chip / viewer
13
+ *
14
+ * The API endpoints that wrap these helpers should 404 in PROD; this
15
+ * library contains no PROD check of its own (enforcement stays at the
16
+ * endpoint boundary).
17
+ */
18
+ import type { DeskworkConfig } from './config.ts';
19
+ import type { ContentIndex } from './content-index.ts';
20
+ /** Type buckets for scrapbook entries. */
21
+ export type ScrapbookItemKind = 'md' | 'json' | 'js' | 'img' | 'txt' | 'other';
22
+ export interface ScrapbookItem {
23
+ name: string;
24
+ kind: ScrapbookItemKind;
25
+ size: number;
26
+ mtime: string;
27
+ }
28
+ export interface ScrapbookSummary {
29
+ site: string;
30
+ /**
31
+ * The scrapbook's location identifier — a slug for entries tied to a
32
+ * calendar row, or any directory path within `contentDir` for
33
+ * scrapbooks that hang off purely organizational nodes (e.g. an
34
+ * intermediate project directory that isn't itself a calendar entry).
35
+ */
36
+ slug: string;
37
+ dir: string;
38
+ exists: boolean;
39
+ /** Files at the top of `scrapbook/` (public/published-side notes). */
40
+ items: ScrapbookItem[];
41
+ /**
42
+ * Files inside `scrapbook/secret/` — never to be published. Operators
43
+ * can drop research, drafts, or sensitive notes here knowing the host
44
+ * project's content collection patterns won't pick them up.
45
+ */
46
+ secretItems: ScrapbookItem[];
47
+ }
48
+ /** Well-known subdirectory name for editorially-private scrapbook items. */
49
+ export declare const SECRET_SUBDIR = "secret";
50
+ /**
51
+ * A single slug segment — kebab-case lowercase. Used both for flat
52
+ * slugs and as the building block of hierarchical paths.
53
+ */
54
+ declare const SLUG_SEGMENT_RE: RegExp;
55
+ export declare function assertSlug(slug: string): void;
56
+ /**
57
+ * Split a hierarchical slug into its segments. Each segment is a
58
+ * standalone kebab-case identifier.
59
+ */
60
+ export declare function slugSegments(slug: string): string[];
61
+ /**
62
+ * True if a slug refers to a nested entry (has at least one `/`).
63
+ */
64
+ export declare function isNestedSlug(slug: string): boolean;
65
+ export { SLUG_SEGMENT_RE };
66
+ export declare function assertFilename(name: string): void;
67
+ /**
68
+ * Resolve the scrapbook directory for (site, slug) and ensure the
69
+ * return path stays inside the site's content directory.
70
+ * Doesn't require the directory to exist.
71
+ */
72
+ export declare function scrapbookDir(projectRoot: string, config: DeskworkConfig, site: string, slug: string): string;
73
+ /**
74
+ * Resolve the scrapbook directory for an arbitrary path under the site's
75
+ * content directory. Used by Phase 19c+ callers (e.g. the studio) that
76
+ * already know the fs-relative path of an organizational or tracked node
77
+ * and don't want to re-derive it through the slug regex. The path may
78
+ * contain `/` segments; no `..` or absolute paths allowed.
79
+ *
80
+ * Path-shape validation matches `assertSlug` since the on-disk layout
81
+ * is the same shape — kebab-case segments separated by `/`. Different
82
+ * helper, same constraint.
83
+ */
84
+ export declare function scrapbookDirAtPath(projectRoot: string, config: DeskworkConfig, site: string, relPath: string): string;
85
+ /**
86
+ * Resolve the scrapbook directory for a tracked calendar entry.
87
+ *
88
+ * Derives the scrapbook location from the parent directory of the
89
+ * entry's content file (located via `findEntryFile`, which prefers the
90
+ * frontmatter-id index over the slug template). Falls back to today's
91
+ * slug-based addressing for entries that haven't been bound to
92
+ * frontmatter yet (pre-doctor state).
93
+ *
94
+ * Refactor-proof: when the operator renames an entry's directory on
95
+ * disk, the next request rebuilds the index and the scrapbook now
96
+ * lives at the new path automatically.
97
+ *
98
+ * @param entry Calendar entry — `id` preferred (Phase 19+); `slug` is
99
+ * used both as the legacy fallback and to locate the
100
+ * `<dirname>/scrapbook/` when the entry has no id yet.
101
+ * @param index Optional pre-built index (per-request memoization). When
102
+ * omitted, this function builds one.
103
+ */
104
+ export declare function scrapbookDirForEntry(projectRoot: string, config: DeskworkConfig, site: string, entry: {
105
+ id?: string;
106
+ slug: string;
107
+ }, index?: ContentIndex): string;
108
+ /** Options that select between the public scrapbook root and `secret/`. */
109
+ export interface ScrapbookLocation {
110
+ /** When true, the file lives under `scrapbook/secret/`. Default: false. */
111
+ secret?: boolean;
112
+ }
113
+ /**
114
+ * Resolve a filename INSIDE a scrapbook dir and return the absolute
115
+ * path. Throws if the resolved path escapes the scrapbook dir (guards
116
+ * against `..` sequences that slipped through assertFilename).
117
+ *
118
+ * When `opts.secret` is true, the returned path is rooted at
119
+ * `<scrapbook>/secret/<filename>` instead of `<scrapbook>/<filename>`.
120
+ */
121
+ export declare function scrapbookFilePath(projectRoot: string, config: DeskworkConfig, site: string, slug: string, filename: string, opts?: ScrapbookLocation): string;
122
+ export declare function classify(filename: string): ScrapbookItemKind;
123
+ /**
124
+ * List the items in a scrapbook, sorted newest-mtime first. Returns
125
+ * both public items (top-level files) and secret items (files inside
126
+ * `scrapbook/secret/`). Subdirectories at the top level OTHER than
127
+ * `secret/` are ignored — deskwork doesn't recurse into arbitrary
128
+ * trees inside a scrapbook.
129
+ */
130
+ export declare function listScrapbook(projectRoot: string, config: DeskworkConfig, site: string, slug: string): ScrapbookSummary;
131
+ /**
132
+ * List a scrapbook by absolute directory path. Used by callers that
133
+ * have already resolved the on-disk path via `scrapbookDirForEntry`
134
+ * (id-driven) or `scrapbookDirAtPath` (fs-path-driven) and don't want
135
+ * to re-derive through the slug template. The `slug` parameter is only
136
+ * used to populate the returned summary's identifier field — it does
137
+ * not influence path resolution.
138
+ *
139
+ * Internal primitive shared by `listScrapbook` (slug-based) and
140
+ * `listScrapbookForEntry` (id-driven).
141
+ */
142
+ export declare function listScrapbookAtDir(site: string, slug: string, dir: string): ScrapbookSummary;
143
+ /**
144
+ * List scrapbook items for a tracked calendar entry. Resolves the
145
+ * scrapbook directory via the content index when available (id binding),
146
+ * falling back to slug-based addressing for entries that haven't been
147
+ * bound to frontmatter yet (pre-doctor state).
148
+ *
149
+ * Mirrors the shape of `countScrapbookForEntry`. Used by the studio
150
+ * review-page drawer + content-detail panel so writingcontrol-shape
151
+ * entries (where the file path diverges from the slug template) list
152
+ * items at the correct on-disk location.
153
+ *
154
+ * @param entry Calendar entry — `id` preferred; `slug` is both the
155
+ * legacy fallback and the disambiguator the underlying
156
+ * resolver uses when the index is incomplete.
157
+ * @param index Optional pre-built per-request index. When omitted, the
158
+ * resolver builds one on demand.
159
+ */
160
+ export declare function listScrapbookForEntry(projectRoot: string, config: DeskworkConfig, site: string, entry: {
161
+ id?: string;
162
+ slug: string;
163
+ }, index?: ContentIndex): ScrapbookSummary;
164
+ /**
165
+ * Total item count (public + secret). Used by the studio chip for the
166
+ * badge — operators want a single "has scrapbook content" signal that
167
+ * counts everything attached to this entry.
168
+ *
169
+ * Slug-based addressing: resolves `<contentDir>/<slug>/scrapbook/`. For
170
+ * entries whose on-disk path doesn't match the slug template (e.g.
171
+ * writingcontrol-shape projects where slug `the-outbound` lives at
172
+ * `projects/the-outbound/index.md`), use `countScrapbookForEntry`
173
+ * instead — it derives the path from the bound file via the content
174
+ * index.
175
+ */
176
+ export declare function countScrapbook(projectRoot: string, config: DeskworkConfig, site: string, slug: string): number;
177
+ /**
178
+ * Count scrapbook items for a tracked calendar entry. Resolves the
179
+ * scrapbook directory via the content index when available (id binding),
180
+ * falling back to slug-based addressing for entries that haven't been
181
+ * bound to frontmatter yet (pre-doctor state).
182
+ *
183
+ * Mirrors the shape of `scrapbookDirForEntry` — same resolver, same
184
+ * legacy-slug fallback. Used by the studio dashboard chip so writing-
185
+ * control-shape entries (where the file path diverges from the slug
186
+ * template) report the correct count.
187
+ *
188
+ * @param entry Calendar entry — `id` preferred (Phase 19+); `slug` is
189
+ * both the legacy fallback and the disambiguator the
190
+ * underlying resolver uses when the index is incomplete.
191
+ * @param index Optional pre-built per-request index. When omitted, the
192
+ * resolver builds one on demand.
193
+ */
194
+ export declare function countScrapbookForEntry(projectRoot: string, config: DeskworkConfig, site: string, entry: {
195
+ id?: string;
196
+ slug: string;
197
+ }, index?: ContentIndex): number;
198
+ export declare function readScrapbookFile(projectRoot: string, config: DeskworkConfig, site: string, slug: string, filename: string, opts?: ScrapbookLocation): {
199
+ name: string;
200
+ kind: ScrapbookItemKind;
201
+ size: number;
202
+ mtime: string;
203
+ content: Buffer;
204
+ };
205
+ /**
206
+ * Create a new markdown note in the scrapbook. Creates the scrapbook
207
+ * dir (and `secret/` subdir, if needed) if it doesn't exist. Refuses
208
+ * to overwrite existing files.
209
+ */
210
+ export declare function createScrapbookMarkdown(projectRoot: string, config: DeskworkConfig, site: string, slug: string, filename: string, body: string, opts?: ScrapbookLocation): ScrapbookItem;
211
+ /** Overwrite an existing file's contents. Refuses if the file is absent. */
212
+ export declare function saveScrapbookFile(projectRoot: string, config: DeskworkConfig, site: string, slug: string, filename: string, body: string | Buffer, opts?: ScrapbookLocation): ScrapbookItem;
213
+ export declare function renameScrapbookFile(projectRoot: string, config: DeskworkConfig, site: string, slug: string, oldName: string, newName: string, opts?: ScrapbookLocation): ScrapbookItem;
214
+ export declare function deleteScrapbookFile(projectRoot: string, config: DeskworkConfig, site: string, slug: string, filename: string, opts?: ScrapbookLocation): void;
215
+ /**
216
+ * Seed a scrapbook's `README.md` at plan time. Idempotent — if the
217
+ * README already exists, returns null without touching it. Used by
218
+ * the plan skill so every Planned article gets a scrapbook home with
219
+ * a template that names the article and invites receipts.
220
+ */
221
+ export declare function seedScrapbookReadme(projectRoot: string, config: DeskworkConfig, site: string, slug: string, title: string): ScrapbookItem | null;
222
+ /**
223
+ * Write an uploaded file into the scrapbook. Filename + content come
224
+ * from the multipart body upstream; we validate and persist.
225
+ */
226
+ export declare function writeScrapbookUpload(projectRoot: string, config: DeskworkConfig, site: string, slug: string, filename: string, content: Buffer, opts?: ScrapbookLocation): ScrapbookItem;
227
+ export declare function formatRelativeTime(iso: string, now?: Date): string;
228
+ export declare function formatSize(bytes: number): string;
229
+ //# sourceMappingURL=scrapbook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scrapbook.d.ts","sourceRoot":"","sources":["../src/scrapbook.ts"],"names":[],"mappings":"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"}