@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,103 @@
1
+ /**
2
+ * YAML frontmatter reader/writer for markdown files.
3
+ *
4
+ * Deskwork skills that touch blog posts (draft, publish, distribute) need to
5
+ * read and update frontmatter — e.g. setting `datePublished` when a post
6
+ * ships, reading `contentUrl` when recording a distribution. This module
7
+ * wraps the `yaml` library so callers don't have to hand-roll YAML parsing.
8
+ *
9
+ * ## Shape
10
+ *
11
+ * A file with frontmatter looks like:
12
+ *
13
+ * ```markdown
14
+ * ---
15
+ * title: My Post
16
+ * datePublished: 2026-01-15
17
+ * ---
18
+ *
19
+ * # Body
20
+ * ```
21
+ *
22
+ * `parseFrontmatter` splits this into `data` (parsed YAML) and `body` (the
23
+ * remainder, including the leading newline if present). `stringifyFrontmatter`
24
+ * is the inverse for callers that need to construct frontmatter from scratch.
25
+ *
26
+ * ## Round-trip preservation (Issue #37)
27
+ *
28
+ * Naive parse → mutate → stringify normalizes everything: quoting styles
29
+ * dissolve, comments evaporate, key order shuffles. That bites Astro
30
+ * schemas that demand string scalars: `datePublished: "2020-10-01"`
31
+ * round-trips to `datePublished: 2020-10-01` and re-parses as a `Date`,
32
+ * which `z.string()` rejects.
33
+ *
34
+ * `updateFrontmatter` and `writeFrontmatter` use the yaml library's
35
+ * Document mode (`parseDocument` → mutate AST → `Document.toString()`)
36
+ * so the only bytes that change are the keys we touched. Existing
37
+ * quoting, comments, blank lines, and key order are byte-preserved.
38
+ *
39
+ * Read-only consumers (`parseFrontmatter`, `readFrontmatter`) still use
40
+ * the simpler `parse` API since they don't write anything back.
41
+ */
42
+ /** Frontmatter values come back as whatever YAML parses them to. */
43
+ export type FrontmatterData = Record<string, unknown>;
44
+ export interface ParsedMarkdown {
45
+ data: FrontmatterData;
46
+ body: string;
47
+ }
48
+ /** Split a markdown string into its frontmatter data and body. */
49
+ export declare function parseFrontmatter(markdown: string): ParsedMarkdown;
50
+ /**
51
+ * Build a markdown string from frontmatter data and body.
52
+ *
53
+ * The body is joined to the frontmatter with a single newline — callers that
54
+ * want a blank line between the closing `---` and the body should start their
55
+ * body with `'\n'`.
56
+ *
57
+ * This is for callers that build frontmatter from scratch (e.g. the
58
+ * scaffolder writing a brand-new file). It does NOT preserve formatting
59
+ * since there's no existing source to preserve. Callers performing a
60
+ * read/mutate/write round-trip should use `updateFrontmatter` instead.
61
+ */
62
+ export declare function stringifyFrontmatter(data: FrontmatterData, body: string): string;
63
+ /**
64
+ * Merge a patch into a markdown file's frontmatter and return the new contents.
65
+ *
66
+ * Round-trip-preserving (Issue #37): edits the existing YAML AST in place
67
+ * so untouched keys remain byte-identical. Quoting styles, comments, blank
68
+ * lines, and key order are preserved exactly. Patched keys overwrite
69
+ * existing values; new keys are appended at the bottom of the map.
70
+ *
71
+ * If the file has no frontmatter, one is created with the patch as its
72
+ * only contents.
73
+ */
74
+ export declare function updateFrontmatter(markdown: string, patch: FrontmatterData): string;
75
+ /**
76
+ * Delete keys (or nested key paths) from a markdown file's frontmatter
77
+ * while preserving every other byte (round-trip-preserving, like
78
+ * `updateFrontmatter`).
79
+ *
80
+ * Each path is an array of string keys describing the descent into
81
+ * nested mappings, e.g. `['deskwork', 'id']` removes the `id` field
82
+ * inside the top-level `deskwork:` mapping. Top-level keys can be
83
+ * passed as a single-element path (`['datePublished']`).
84
+ *
85
+ * After a deletion, if the parent collection is left empty AND
86
+ * `pruneEmptyParents` is true (default), the parent collection is also
87
+ * removed. Set false to keep the empty container.
88
+ */
89
+ export declare function removeFrontmatterPaths(markdown: string, paths: ReadonlyArray<ReadonlyArray<string>>, options?: {
90
+ pruneEmptyParents?: boolean;
91
+ }): string;
92
+ /** Read and parse a markdown file with frontmatter. */
93
+ export declare function readFrontmatter(path: string): ParsedMarkdown;
94
+ /**
95
+ * Write a markdown file with frontmatter.
96
+ *
97
+ * Like `stringifyFrontmatter`, this is for callers that build frontmatter
98
+ * from scratch (the scaffolder, primarily). For "read existing file →
99
+ * mutate → write back" flows, prefer reading the file and applying
100
+ * `updateFrontmatter` so existing formatting is preserved.
101
+ */
102
+ export declare function writeFrontmatter(path: string, data: FrontmatterData, body: string): void;
103
+ //# sourceMappingURL=frontmatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAeH,oEAAoE;AACpE,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEtD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,eAAe,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAID,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAsBjE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,MAAM,GACX,MAAM,CAGR;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,eAAe,GACrB,MAAM,CAkBR;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,EAC3C,OAAO,GAAE;IAAE,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAAO,GAC5C,MAAM,CAkCR;AAED,uDAAuD;AACvD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAE5D;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,MAAM,GACX,IAAI,CAEN"}
@@ -0,0 +1,306 @@
1
+ /**
2
+ * YAML frontmatter reader/writer for markdown files.
3
+ *
4
+ * Deskwork skills that touch blog posts (draft, publish, distribute) need to
5
+ * read and update frontmatter — e.g. setting `datePublished` when a post
6
+ * ships, reading `contentUrl` when recording a distribution. This module
7
+ * wraps the `yaml` library so callers don't have to hand-roll YAML parsing.
8
+ *
9
+ * ## Shape
10
+ *
11
+ * A file with frontmatter looks like:
12
+ *
13
+ * ```markdown
14
+ * ---
15
+ * title: My Post
16
+ * datePublished: 2026-01-15
17
+ * ---
18
+ *
19
+ * # Body
20
+ * ```
21
+ *
22
+ * `parseFrontmatter` splits this into `data` (parsed YAML) and `body` (the
23
+ * remainder, including the leading newline if present). `stringifyFrontmatter`
24
+ * is the inverse for callers that need to construct frontmatter from scratch.
25
+ *
26
+ * ## Round-trip preservation (Issue #37)
27
+ *
28
+ * Naive parse → mutate → stringify normalizes everything: quoting styles
29
+ * dissolve, comments evaporate, key order shuffles. That bites Astro
30
+ * schemas that demand string scalars: `datePublished: "2020-10-01"`
31
+ * round-trips to `datePublished: 2020-10-01` and re-parses as a `Date`,
32
+ * which `z.string()` rejects.
33
+ *
34
+ * `updateFrontmatter` and `writeFrontmatter` use the yaml library's
35
+ * Document mode (`parseDocument` → mutate AST → `Document.toString()`)
36
+ * so the only bytes that change are the keys we touched. Existing
37
+ * quoting, comments, blank lines, and key order are byte-preserved.
38
+ *
39
+ * Read-only consumers (`parseFrontmatter`, `readFrontmatter`) still use
40
+ * the simpler `parse` API since they don't write anything back.
41
+ */
42
+ import { readFileSync, writeFileSync } from 'node:fs';
43
+ import { parse as parseYaml, stringify as stringifyYaml, parseDocument, isMap, isScalar, Scalar, YAMLMap, } from 'yaml';
44
+ const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?([\s\S]*)$/;
45
+ /** Split a markdown string into its frontmatter data and body. */
46
+ export function parseFrontmatter(markdown) {
47
+ const match = markdown.match(FRONTMATTER_RE);
48
+ if (!match) {
49
+ return { data: {}, body: markdown };
50
+ }
51
+ const [, yamlContent, body] = match;
52
+ let data;
53
+ try {
54
+ data = parseYaml(yamlContent);
55
+ }
56
+ catch (err) {
57
+ const reason = err instanceof Error ? err.message : String(err);
58
+ throw new Error(`Invalid YAML frontmatter: ${reason}`);
59
+ }
60
+ if (data === null || data === undefined) {
61
+ return { data: {}, body };
62
+ }
63
+ if (typeof data !== 'object' || Array.isArray(data)) {
64
+ throw new Error(`Invalid frontmatter: expected a YAML mapping at the top level, got ${typeof data}.`);
65
+ }
66
+ return { data: toFrontmatterData(data), body };
67
+ }
68
+ /**
69
+ * Build a markdown string from frontmatter data and body.
70
+ *
71
+ * The body is joined to the frontmatter with a single newline — callers that
72
+ * want a blank line between the closing `---` and the body should start their
73
+ * body with `'\n'`.
74
+ *
75
+ * This is for callers that build frontmatter from scratch (e.g. the
76
+ * scaffolder writing a brand-new file). It does NOT preserve formatting
77
+ * since there's no existing source to preserve. Callers performing a
78
+ * read/mutate/write round-trip should use `updateFrontmatter` instead.
79
+ */
80
+ export function stringifyFrontmatter(data, body) {
81
+ const doc = buildDocument(data);
82
+ return `---\n${doc.toString({ lineWidth: 0 }).replace(/\n$/, '')}\n---\n${body}`;
83
+ }
84
+ /**
85
+ * Merge a patch into a markdown file's frontmatter and return the new contents.
86
+ *
87
+ * Round-trip-preserving (Issue #37): edits the existing YAML AST in place
88
+ * so untouched keys remain byte-identical. Quoting styles, comments, blank
89
+ * lines, and key order are preserved exactly. Patched keys overwrite
90
+ * existing values; new keys are appended at the bottom of the map.
91
+ *
92
+ * If the file has no frontmatter, one is created with the patch as its
93
+ * only contents.
94
+ */
95
+ export function updateFrontmatter(markdown, patch) {
96
+ const match = markdown.match(FRONTMATTER_RE);
97
+ if (!match) {
98
+ // No existing frontmatter — emit a fresh block. The body becomes
99
+ // the entire input; we prepend a fresh `---…---` block.
100
+ return stringifyFrontmatter(patch, markdown);
101
+ }
102
+ const [, yamlContent, body] = match;
103
+ const doc = parseDocument(yamlContent, { keepSourceTokens: false });
104
+ if (doc.errors.length > 0) {
105
+ const first = doc.errors[0];
106
+ throw new Error(`Invalid YAML frontmatter: ${first.message}`);
107
+ }
108
+ applyPatchToDocument(doc, patch);
109
+ // doc.toString() always ends with `\n`; trim it and re-add inside our
110
+ // delimiters so the on-disk shape stays `---\n<yaml>\n---\n<body>`.
111
+ const yamlOut = doc.toString({ lineWidth: 0 }).replace(/\n$/, '');
112
+ return `---\n${yamlOut}\n---\n${body}`;
113
+ }
114
+ /**
115
+ * Delete keys (or nested key paths) from a markdown file's frontmatter
116
+ * while preserving every other byte (round-trip-preserving, like
117
+ * `updateFrontmatter`).
118
+ *
119
+ * Each path is an array of string keys describing the descent into
120
+ * nested mappings, e.g. `['deskwork', 'id']` removes the `id` field
121
+ * inside the top-level `deskwork:` mapping. Top-level keys can be
122
+ * passed as a single-element path (`['datePublished']`).
123
+ *
124
+ * After a deletion, if the parent collection is left empty AND
125
+ * `pruneEmptyParents` is true (default), the parent collection is also
126
+ * removed. Set false to keep the empty container.
127
+ */
128
+ export function removeFrontmatterPaths(markdown, paths, options = {}) {
129
+ const match = markdown.match(FRONTMATTER_RE);
130
+ if (!match)
131
+ return markdown;
132
+ const [, yamlContent, body] = match;
133
+ const doc = parseDocument(yamlContent);
134
+ if (doc.errors.length > 0) {
135
+ const first = doc.errors[0];
136
+ throw new Error(`Invalid YAML frontmatter: ${first.message}`);
137
+ }
138
+ const prune = options.pruneEmptyParents ?? true;
139
+ let mutated = false;
140
+ for (const path of paths) {
141
+ if (path.length === 0)
142
+ continue;
143
+ if (!doc.hasIn(path))
144
+ continue;
145
+ doc.deleteIn(path);
146
+ mutated = true;
147
+ if (prune && path.length > 1) {
148
+ // Walk parents, deleting any that became empty maps.
149
+ for (let depth = path.length - 1; depth >= 1; depth--) {
150
+ const parentPath = path.slice(0, depth);
151
+ const parent = doc.getIn(parentPath, true);
152
+ if (isMap(parent) && parent.items.length === 0) {
153
+ doc.deleteIn(parentPath);
154
+ }
155
+ else {
156
+ break;
157
+ }
158
+ }
159
+ }
160
+ }
161
+ if (!mutated)
162
+ return markdown;
163
+ const yamlOut = doc.toString({ lineWidth: 0 }).replace(/\n$/, '');
164
+ return `---\n${yamlOut}\n---\n${body}`;
165
+ }
166
+ /** Read and parse a markdown file with frontmatter. */
167
+ export function readFrontmatter(path) {
168
+ return parseFrontmatter(readFileSync(path, 'utf-8'));
169
+ }
170
+ /**
171
+ * Write a markdown file with frontmatter.
172
+ *
173
+ * Like `stringifyFrontmatter`, this is for callers that build frontmatter
174
+ * from scratch (the scaffolder, primarily). For "read existing file →
175
+ * mutate → write back" flows, prefer reading the file and applying
176
+ * `updateFrontmatter` so existing formatting is preserved.
177
+ */
178
+ export function writeFrontmatter(path, data, body) {
179
+ writeFileSync(path, stringifyFrontmatter(data, body), 'utf-8');
180
+ }
181
+ // ---------------------------------------------------------------------------
182
+ // Internal helpers — Document AST mutation.
183
+ // ---------------------------------------------------------------------------
184
+ /**
185
+ * Apply a `{key: value}` patch to a parsed YAML Document, mutating the
186
+ * AST in place. Existing keys keep their quoting style; new keys are
187
+ * appended at the bottom of the top-level map.
188
+ *
189
+ * Nested objects are written via `setIn` so that `{deskwork: {id: …}}`
190
+ * patches the deeper key without clobbering siblings of `deskwork`.
191
+ */
192
+ function applyPatchToDocument(doc, patch) {
193
+ // The frontmatter block must be a mapping. parseFrontmatter validates
194
+ // this on the read path; for the write path here we treat empty/null
195
+ // contents as a fresh empty map by setting keys directly through the
196
+ // Document API (which lazily creates the top-level container).
197
+ if (doc.contents !== null && !isMap(doc.contents)) {
198
+ throw new Error('Cannot patch frontmatter: top-level YAML node is not a mapping.');
199
+ }
200
+ for (const [key, value] of Object.entries(patch)) {
201
+ if (isPlainObject(value)) {
202
+ // Merge into nested map: only keys present in the patch are
203
+ // overwritten; existing siblings under the same parent stay.
204
+ mergeNestedObject(doc, [key], value);
205
+ continue;
206
+ }
207
+ if (isMap(doc.contents)) {
208
+ setScalarPreservingStyle(doc.contents, key, value);
209
+ }
210
+ else {
211
+ doc.set(key, value);
212
+ }
213
+ }
214
+ }
215
+ /**
216
+ * Set a scalar (or array) value on a YAMLMap, preserving the existing
217
+ * Scalar node's `type` (quoting style) when the key already exists. This
218
+ * is the round-trip-preservation hook: editing an already-double-quoted
219
+ * key keeps the double quotes.
220
+ */
221
+ function setScalarPreservingStyle(map, key, value) {
222
+ const existing = map.get(key, true);
223
+ if (isScalar(existing)) {
224
+ const next = new Scalar(value);
225
+ if (existing.type !== undefined)
226
+ next.type = existing.type;
227
+ map.set(key, next);
228
+ return;
229
+ }
230
+ // No existing key, or the existing value was a collection — let the
231
+ // library pick the default representation.
232
+ map.set(key, value);
233
+ }
234
+ /**
235
+ * Merge a nested-object patch under `path` (e.g. `['deskwork']`) into
236
+ * the document. If the parent doesn't exist, create it as an empty map
237
+ * BEFORE descending. If individual keys under the parent collide,
238
+ * recursively merge so untouched siblings stay put.
239
+ *
240
+ * `Document.setIn` does not auto-vivify intermediate collections; it
241
+ * throws if the parent isn't a YAML collection. We materialize each
242
+ * level explicitly with `setIn(parentPath, {})` whenever it's missing.
243
+ */
244
+ function mergeNestedObject(doc, path, value) {
245
+ // Ensure every prefix of `path` exists as a YAMLMap. setIn does not
246
+ // auto-vivify intermediate collections; passing a plain `{}` puts a
247
+ // JS object at the slot (which the next setIn refuses to descend
248
+ // into). We materialize each missing level explicitly with a real
249
+ // YAMLMap node so subsequent setIn calls can write into it.
250
+ for (let depth = 1; depth <= path.length; depth++) {
251
+ const prefix = path.slice(0, depth);
252
+ if (!doc.hasIn(prefix)) {
253
+ doc.setIn(prefix, new YAMLMap(doc.schema));
254
+ }
255
+ }
256
+ for (const [k, v] of Object.entries(value)) {
257
+ const fullPath = [...path, k];
258
+ if (isPlainObject(v)) {
259
+ mergeNestedObject(doc, fullPath, v);
260
+ continue;
261
+ }
262
+ doc.setIn(fullPath, v);
263
+ }
264
+ }
265
+ /**
266
+ * Plain-object check used to decide whether a value should be merged
267
+ * via setIn (preserving sibling keys) or replaced wholesale via set.
268
+ *
269
+ * Plain objects are non-null, non-array, prototype-Object values —
270
+ * Records of unknown.
271
+ */
272
+ function isPlainObject(value) {
273
+ if (value === null || typeof value !== 'object')
274
+ return false;
275
+ if (Array.isArray(value))
276
+ return false;
277
+ const proto = Object.getPrototypeOf(value);
278
+ return proto === Object.prototype || proto === null;
279
+ }
280
+ /**
281
+ * Build a fresh Document from plain data. Used by `stringifyFrontmatter`
282
+ * for write-from-scratch callers. We round-trip the data through
283
+ * `parseDocument(stringify(...))` rather than constructing nodes by
284
+ * hand so that block-style output (with proper indentation for nested
285
+ * collections) is the default — that's the format every existing
286
+ * scaffold/test asserts on.
287
+ */
288
+ function buildDocument(data) {
289
+ const initialYaml = stringifyYaml(data, { lineWidth: 0 });
290
+ // Empty data renders as `{}\n`; parseDocument handles both shapes.
291
+ return parseDocument(initialYaml);
292
+ }
293
+ /**
294
+ * Narrow `unknown` from yaml's `parse` return type to FrontmatterData.
295
+ * The caller has already asserted the parse result is an object and
296
+ * not an array; this is the single point that crosses the typing gap
297
+ * between yaml's `unknown` and our typed surface.
298
+ */
299
+ function toFrontmatterData(value) {
300
+ const out = {};
301
+ for (const k of Object.keys(value)) {
302
+ out[k] = value[k];
303
+ }
304
+ return out;
305
+ }
306
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EACL,KAAK,IAAI,SAAS,EAClB,SAAS,IAAI,aAAa,EAC1B,aAAa,EACb,KAAK,EACL,QAAQ,EACR,MAAM,EACN,OAAO,GAGR,MAAM,MAAM,CAAC;AAUd,MAAM,cAAc,GAAG,6CAA6C,CAAC;AAErE,kEAAkE;AAClE,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IACtC,CAAC;IACD,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;IACpC,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,MAAM,IAAI,KAAK,CAAC,6BAA6B,MAAM,EAAE,CAAC,CAAC;IACzD,CAAC;IACD,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxC,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAC5B,CAAC;IACD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CACb,sEAAsE,OAAO,IAAI,GAAG,CACrF,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,iBAAiB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC;AACjD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,oBAAoB,CAClC,IAAqB,EACrB,IAAY;IAEZ,MAAM,GAAG,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAChC,OAAO,QAAQ,GAAG,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,UAAU,IAAI,EAAE,CAAC;AACnF,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAgB,EAChB,KAAsB;IAEtB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,iEAAiE;QACjE,wDAAwD;QACxD,OAAO,oBAAoB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAC/C,CAAC;IACD,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;IACpC,MAAM,GAAG,GAAG,aAAa,CAAC,WAAW,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC,CAAC;IACpE,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,6BAA6B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,oBAAoB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACjC,sEAAsE;IACtE,oEAAoE;IACpE,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAClE,OAAO,QAAQ,OAAO,UAAU,IAAI,EAAE,CAAC;AACzC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAAgB,EAChB,KAA2C,EAC3C,UAA2C,EAAE;IAE7C,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,QAAQ,CAAC;IAC5B,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,KAAK,CAAC;IACpC,MAAM,GAAG,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IACvC,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,6BAA6B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,iBAAiB,IAAI,IAAI,CAAC;IAEhD,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAChC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QAC/B,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,GAAG,IAAI,CAAC;QACf,IAAI,KAAK,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,qDAAqD;YACrD,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;gBACtD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;gBACxC,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;gBAC3C,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC/C,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;gBAC3B,CAAC;qBAAM,CAAC;oBACN,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAO;QAAE,OAAO,QAAQ,CAAC;IAC9B,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAClE,OAAO,QAAQ,OAAO,UAAU,IAAI,EAAE,CAAC;AACzC,CAAC;AAED,uDAAuD;AACvD,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,gBAAgB,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,IAAqB,EACrB,IAAY;IAEZ,aAAa,CAAC,IAAI,EAAE,oBAAoB,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC;AACjE,CAAC;AAED,8EAA8E;AAC9E,4CAA4C;AAC5C,8EAA8E;AAE9E;;;;;;;GAOG;AACH,SAAS,oBAAoB,CAC3B,GAAgC,EAChC,KAAsB;IAEtB,sEAAsE;IACtE,qEAAqE;IACrE,qEAAqE;IACrE,+DAA+D;IAC/D,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CACb,iEAAiE,CAClE,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACjD,IAAI,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,4DAA4D;YAC5D,6DAA6D;YAC7D,iBAAiB,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;YACrC,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxB,wBAAwB,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAS,wBAAwB,CAC/B,GAAY,EACZ,GAAW,EACX,KAAc;IAEd,MAAM,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACpC,IAAI,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS;YAAE,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;QAC3D,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACnB,OAAO;IACT,CAAC;IACD,oEAAoE;IACpE,2CAA2C;IAC3C,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACtB,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,iBAAiB,CACxB,GAAgC,EAChC,IAAc,EACd,KAA8B;IAE9B,oEAAoE;IACpE,oEAAoE;IACpE,iEAAiE;IACjE,kEAAkE;IAClE,4DAA4D;IAC5D,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;YACvB,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;QAC9B,IAAI,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;YACrB,iBAAiB,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;YACpC,SAAS;QACX,CAAC;QACD,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IACzB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,KAAc;IACnC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;IAC3C,OAAO,KAAK,KAAK,MAAM,CAAC,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC;AACtD,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,aAAa,CAAC,IAAqB;IAC1C,MAAM,WAAW,GAAG,aAAa,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;IAC1D,mEAAmE;IACnE,OAAO,aAAa,CAAC,WAAW,CAAC,CAAC;AACpC,CAAC;AAED;;;;;GAKG;AACH,SAAS,iBAAiB,CAAC,KAAa;IACtC,MAAM,GAAG,GAAoB,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACnC,GAAG,CAAC,CAAC,CAAC,GAAI,KAAiC,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @deskwork/core — barrel export of every public symbol used across
3
+ * the cli and studio packages.
4
+ *
5
+ * Subpath imports (e.g. `@deskwork/core/calendar`) are also supported
6
+ * for callers that want to be explicit about which module they pull
7
+ * from. Both forms resolve to the same source files.
8
+ */
9
+ export * from './types.ts';
10
+ export * from './config.ts';
11
+ export * from './paths.ts';
12
+ export * from './cli.ts';
13
+ export * from './calendar.ts';
14
+ export * from './calendar-mutations.ts';
15
+ export * from './frontmatter.ts';
16
+ export * from './journal.ts';
17
+ export * from './scaffold.ts';
18
+ export * from './body-state.ts';
19
+ export * from './ingest.ts';
20
+ export * as scrapbook from './scrapbook.ts';
21
+ export * as renameSlug from './rename-slug.ts';
22
+ export * as review from './review/index.ts';
23
+ export * as contentTree from './content-tree.ts';
24
+ export * from './content-index.ts';
25
+ export * as doctor from './doctor/index.ts';
26
+ export * from './overrides.ts';
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,cAAc,oBAAoB,CAAC;AACnC,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,cAAc,gBAAgB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @deskwork/core — barrel export of every public symbol used across
3
+ * the cli and studio packages.
4
+ *
5
+ * Subpath imports (e.g. `@deskwork/core/calendar`) are also supported
6
+ * for callers that want to be explicit about which module they pull
7
+ * from. Both forms resolve to the same source files.
8
+ */
9
+ export * from "./types.js";
10
+ export * from "./config.js";
11
+ export * from "./paths.js";
12
+ export * from "./cli.js";
13
+ export * from "./calendar.js";
14
+ export * from "./calendar-mutations.js";
15
+ export * from "./frontmatter.js";
16
+ export * from "./journal.js";
17
+ export * from "./scaffold.js";
18
+ export * from "./body-state.js";
19
+ export * from "./ingest.js";
20
+ export * as scrapbook from "./scrapbook.js";
21
+ export * as renameSlug from "./rename-slug.js";
22
+ export * as review from "./review/index.js";
23
+ export * as contentTree from "./content-tree.js";
24
+ export * from "./content-index.js";
25
+ export * as doctor from "./doctor/index.js";
26
+ export * from "./overrides.js";
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,cAAc,CAAC;AAC7B,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,aAAa,CAAC;AAC5B,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAC;AAC/C,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,WAAW,MAAM,mBAAmB,CAAC;AACjD,cAAc,oBAAoB,CAAC;AACnC,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,cAAc,gBAAgB,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * ingest-derive.ts — slug / state / date / title derivation for ingest.
3
+ *
4
+ * Each `derive*` function takes the file's absolute path, its discovery
5
+ * root (for path-based slug derivation), the parsed frontmatter, the
6
+ * effective field-name table, and the operator's options. It returns a
7
+ * `<thing>Derivation` record that records both the derived value AND
8
+ * where it came from — the dry-run plan surfaces these sources so the
9
+ * operator can sanity-check before committing.
10
+ */
11
+ import { type Stage } from './types.ts';
12
+ import type { FrontmatterData } from './frontmatter.ts';
13
+ /**
14
+ * Where a derived value came from. `'frontmatter'` is reserved for
15
+ * values that actually appear in the file's frontmatter — when a field
16
+ * is absent and we substitute a hardcoded fallback (e.g. defaulting
17
+ * state to `Ideas` when the frontmatter has no `state:` key), the
18
+ * source is `'default'`. The dry-run plan surfaces this so the
19
+ * operator can tell at a glance whether a row reflects the file or
20
+ * was filled in by the ingest layer.
21
+ */
22
+ export type DerivationSource = 'frontmatter' | 'path' | 'mtime' | 'today' | 'explicit' | 'default';
23
+ export interface SlugDerivation {
24
+ value: string;
25
+ source: DerivationSource;
26
+ reason?: string;
27
+ }
28
+ export interface StateDerivation {
29
+ value: Stage | null;
30
+ source: DerivationSource;
31
+ rawValue?: string;
32
+ }
33
+ export interface DateDerivation {
34
+ value: string;
35
+ source: DerivationSource;
36
+ }
37
+ /**
38
+ * Canonical state-string normalization. Maps frontmatter values that
39
+ * editorial projects commonly use onto our six lanes. Anything outside
40
+ * this table comes back ambiguous — the operator must pass `--state`.
41
+ */
42
+ export declare const STATE_ALIASES: Record<string, Stage>;
43
+ export interface SlugDeriveInput {
44
+ filePath: string;
45
+ root: string;
46
+ frontmatter: FrontmatterData;
47
+ fieldName: string;
48
+ slugFrom: 'frontmatter' | 'path';
49
+ explicitSlug?: string;
50
+ }
51
+ /**
52
+ * Derive a slug for a discovered file. Order:
53
+ *
54
+ * 1. `explicitSlug` (operator's `--slug`) — wins, marked 'explicit'.
55
+ * 2. When `slugFrom === 'frontmatter'`, the named frontmatter field
56
+ * (default `slug:`) when set; otherwise falls through to path.
57
+ * 3. Path-based derivation — see `slugFromPath`.
58
+ */
59
+ export declare function deriveSlug(input: SlugDeriveInput): SlugDerivation;
60
+ export interface StateDeriveInput {
61
+ frontmatter: FrontmatterData;
62
+ stateField: string;
63
+ dateField: string;
64
+ stateFrom: 'frontmatter' | 'datePublished';
65
+ explicitState?: Stage;
66
+ now?: Date;
67
+ }
68
+ export declare function deriveState(input: StateDeriveInput): StateDerivation;
69
+ export interface DateDeriveInput {
70
+ filePath: string;
71
+ frontmatter: FrontmatterData;
72
+ dateField: string;
73
+ explicitDate?: string;
74
+ now?: Date;
75
+ }
76
+ export declare function deriveDate(input: DateDeriveInput): DateDerivation;
77
+ export declare function deriveTitle(frontmatter: FrontmatterData, fieldName: string, slug: string): string;
78
+ export declare function deriveDescription(frontmatter: FrontmatterData, fieldName: string): string;
79
+ //# sourceMappingURL=ingest-derive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ingest-derive.d.ts","sourceRoot":"","sources":["../src/ingest-derive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EAAW,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGxD;;;;;;;;GAQG;AACH,MAAM,MAAM,gBAAgB,GACxB,aAAa,GACb,MAAM,GACN,OAAO,GACP,OAAO,GACP,UAAU,GACV,SAAS,CAAC;AAEd,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,gBAAgB,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,gBAAgB,CAAC;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAKD;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAe/C,CAAC;AAMF,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,aAAa,GAAG,MAAM,CAAC;IACjC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,cAAc,CAYjE;AA0HD,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,eAAe,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,aAAa,GAAG,eAAe,CAAC;IAC3C,aAAa,CAAC,EAAE,KAAK,CAAC;IACtB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,eAAe,CA+BpE;AAiBD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,eAAe,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,GAAG,cAAc,CA8BjE;AAMD,wBAAgB,WAAW,CACzB,WAAW,EAAE,eAAe,EAC5B,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,GACX,MAAM,CAWR;AAED,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,eAAe,EAC5B,SAAS,EAAE,MAAM,GAChB,MAAM,CAER"}