contentbase 0.4.0 → 0.4.1

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 (322) hide show
  1. package/dist/adapters/node-fs.d.ts +17 -0
  2. package/dist/adapters/node-fs.d.ts.map +1 -0
  3. package/dist/adapters/node-fs.js +71 -0
  4. package/dist/adapters/node-fs.js.map +1 -0
  5. package/dist/ast-query.d.ts +44 -0
  6. package/dist/ast-query.d.ts.map +1 -0
  7. package/dist/ast-query.js +95 -0
  8. package/dist/ast-query.js.map +1 -0
  9. package/dist/base-model.d.ts +8 -0
  10. package/dist/base-model.d.ts.map +1 -0
  11. package/dist/base-model.js +12 -0
  12. package/dist/base-model.js.map +1 -0
  13. package/dist/cli/commands/action.d.ts +2 -0
  14. package/dist/cli/commands/action.d.ts.map +1 -0
  15. package/dist/cli/commands/action.js +73 -0
  16. package/dist/cli/commands/action.js.map +1 -0
  17. package/dist/cli/commands/api/endpoints/actions.d.ts +13 -0
  18. package/dist/cli/commands/api/endpoints/actions.d.ts.map +1 -0
  19. package/dist/cli/commands/api/endpoints/actions.js +28 -0
  20. package/dist/cli/commands/api/endpoints/actions.js.map +1 -0
  21. package/dist/cli/commands/api/endpoints/doc.d.ts +5 -0
  22. package/dist/cli/commands/api/endpoints/doc.d.ts.map +1 -0
  23. package/dist/cli/commands/api/endpoints/doc.js +186 -0
  24. package/dist/cli/commands/api/endpoints/doc.js.map +1 -0
  25. package/dist/cli/commands/api/endpoints/docs-index.d.ts +8 -0
  26. package/dist/cli/commands/api/endpoints/docs-index.d.ts.map +1 -0
  27. package/dist/cli/commands/api/endpoints/docs-index.js +23 -0
  28. package/dist/cli/commands/api/endpoints/docs-index.js.map +1 -0
  29. package/dist/cli/commands/api/endpoints/document.d.ts +47 -0
  30. package/dist/cli/commands/api/endpoints/document.d.ts.map +1 -0
  31. package/dist/cli/commands/api/endpoints/document.js +146 -0
  32. package/dist/cli/commands/api/endpoints/document.js.map +1 -0
  33. package/dist/cli/commands/api/endpoints/documents.d.ts +35 -0
  34. package/dist/cli/commands/api/endpoints/documents.d.ts.map +1 -0
  35. package/dist/cli/commands/api/endpoints/documents.js +56 -0
  36. package/dist/cli/commands/api/endpoints/documents.js.map +1 -0
  37. package/dist/cli/commands/api/endpoints/index.d.ts +22 -0
  38. package/dist/cli/commands/api/endpoints/index.d.ts.map +1 -0
  39. package/dist/cli/commands/api/endpoints/index.js +38 -0
  40. package/dist/cli/commands/api/endpoints/index.js.map +1 -0
  41. package/dist/cli/commands/api/endpoints/inspect.d.ts +10 -0
  42. package/dist/cli/commands/api/endpoints/inspect.d.ts.map +1 -0
  43. package/dist/cli/commands/api/endpoints/inspect.js +15 -0
  44. package/dist/cli/commands/api/endpoints/inspect.js.map +1 -0
  45. package/dist/cli/commands/api/endpoints/models.d.ts +5 -0
  46. package/dist/cli/commands/api/endpoints/models.d.ts.map +1 -0
  47. package/dist/cli/commands/api/endpoints/models.js +9 -0
  48. package/dist/cli/commands/api/endpoints/models.js.map +1 -0
  49. package/dist/cli/commands/api/endpoints/query.d.ts +40 -0
  50. package/dist/cli/commands/api/endpoints/query.d.ts.map +1 -0
  51. package/dist/cli/commands/api/endpoints/query.js +106 -0
  52. package/dist/cli/commands/api/endpoints/query.js.map +1 -0
  53. package/dist/cli/commands/api/endpoints/root.d.ts +5 -0
  54. package/dist/cli/commands/api/endpoints/root.d.ts.map +1 -0
  55. package/dist/cli/commands/api/endpoints/root.js +7 -0
  56. package/dist/cli/commands/api/endpoints/root.js.map +1 -0
  57. package/dist/cli/commands/api/endpoints/search-reindex.d.ts +10 -0
  58. package/dist/cli/commands/api/endpoints/search-reindex.d.ts.map +1 -0
  59. package/dist/cli/commands/api/endpoints/search-reindex.js +38 -0
  60. package/dist/cli/commands/api/endpoints/search-reindex.js.map +1 -0
  61. package/dist/cli/commands/api/endpoints/search-status.d.ts +7 -0
  62. package/dist/cli/commands/api/endpoints/search-status.d.ts.map +1 -0
  63. package/dist/cli/commands/api/endpoints/search-status.js +33 -0
  64. package/dist/cli/commands/api/endpoints/search-status.js.map +1 -0
  65. package/dist/cli/commands/api/endpoints/search.d.ts +24 -0
  66. package/dist/cli/commands/api/endpoints/search.d.ts.map +1 -0
  67. package/dist/cli/commands/api/endpoints/search.js +61 -0
  68. package/dist/cli/commands/api/endpoints/search.js.map +1 -0
  69. package/dist/cli/commands/api/endpoints/semantic-search.d.ts +28 -0
  70. package/dist/cli/commands/api/endpoints/semantic-search.d.ts.map +1 -0
  71. package/dist/cli/commands/api/endpoints/semantic-search.js +76 -0
  72. package/dist/cli/commands/api/endpoints/semantic-search.js.map +1 -0
  73. package/dist/cli/commands/api/endpoints/text-search.d.ts +17 -0
  74. package/dist/cli/commands/api/endpoints/text-search.d.ts.map +1 -0
  75. package/dist/cli/commands/api/endpoints/text-search.js +55 -0
  76. package/dist/cli/commands/api/endpoints/text-search.js.map +1 -0
  77. package/dist/cli/commands/api/endpoints/validate.d.ts +12 -0
  78. package/dist/cli/commands/api/endpoints/validate.d.ts.map +1 -0
  79. package/dist/cli/commands/api/endpoints/validate.js +27 -0
  80. package/dist/cli/commands/api/endpoints/validate.js.map +1 -0
  81. package/dist/cli/commands/api/helpers.d.ts +8 -0
  82. package/dist/cli/commands/api/helpers.d.ts.map +1 -0
  83. package/dist/cli/commands/api/helpers.js +89 -0
  84. package/dist/cli/commands/api/helpers.js.map +1 -0
  85. package/dist/cli/commands/console.d.ts +2 -0
  86. package/dist/cli/commands/console.d.ts.map +1 -0
  87. package/dist/cli/commands/console.js +117 -0
  88. package/dist/cli/commands/console.js.map +1 -0
  89. package/dist/cli/commands/create.d.ts +2 -0
  90. package/dist/cli/commands/create.d.ts.map +1 -0
  91. package/dist/cli/commands/create.js +185 -0
  92. package/dist/cli/commands/create.js.map +1 -0
  93. package/dist/cli/commands/embed.d.ts +2 -0
  94. package/dist/cli/commands/embed.d.ts.map +1 -0
  95. package/dist/cli/commands/embed.js +231 -0
  96. package/dist/cli/commands/embed.js.map +1 -0
  97. package/dist/cli/commands/export.d.ts +2 -0
  98. package/dist/cli/commands/export.d.ts.map +1 -0
  99. package/dist/cli/commands/export.js +55 -0
  100. package/dist/cli/commands/export.js.map +1 -0
  101. package/dist/cli/commands/extract.d.ts +2 -0
  102. package/dist/cli/commands/extract.d.ts.map +1 -0
  103. package/dist/cli/commands/extract.js +149 -0
  104. package/dist/cli/commands/extract.js.map +1 -0
  105. package/dist/cli/commands/help.d.ts +2 -0
  106. package/dist/cli/commands/help.d.ts.map +1 -0
  107. package/dist/cli/commands/help.js +58 -0
  108. package/dist/cli/commands/help.js.map +1 -0
  109. package/dist/cli/commands/index.d.ts +18 -0
  110. package/dist/cli/commands/index.d.ts.map +1 -0
  111. package/dist/cli/commands/index.js +19 -0
  112. package/dist/cli/commands/index.js.map +1 -0
  113. package/dist/cli/commands/init.d.ts +2 -0
  114. package/dist/cli/commands/init.d.ts.map +1 -0
  115. package/dist/cli/commands/init.js +82 -0
  116. package/dist/cli/commands/init.js.map +1 -0
  117. package/dist/cli/commands/inspect.d.ts +2 -0
  118. package/dist/cli/commands/inspect.d.ts.map +1 -0
  119. package/dist/cli/commands/inspect.js +53 -0
  120. package/dist/cli/commands/inspect.js.map +1 -0
  121. package/dist/cli/commands/mcp.d.ts +2 -0
  122. package/dist/cli/commands/mcp.d.ts.map +1 -0
  123. package/dist/cli/commands/mcp.js +92 -0
  124. package/dist/cli/commands/mcp.js.map +1 -0
  125. package/dist/cli/commands/search.d.ts +2 -0
  126. package/dist/cli/commands/search.d.ts.map +1 -0
  127. package/dist/cli/commands/search.js +212 -0
  128. package/dist/cli/commands/search.js.map +1 -0
  129. package/dist/cli/commands/serve.d.ts +2 -0
  130. package/dist/cli/commands/serve.d.ts.map +1 -0
  131. package/dist/cli/commands/serve.js +298 -0
  132. package/dist/cli/commands/serve.js.map +1 -0
  133. package/dist/cli/commands/summary.d.ts +2 -0
  134. package/dist/cli/commands/summary.d.ts.map +1 -0
  135. package/dist/cli/commands/summary.js +58 -0
  136. package/dist/cli/commands/summary.js.map +1 -0
  137. package/dist/cli/commands/teach.d.ts +2 -0
  138. package/dist/cli/commands/teach.d.ts.map +1 -0
  139. package/dist/cli/commands/teach.js +80 -0
  140. package/dist/cli/commands/teach.js.map +1 -0
  141. package/dist/cli/commands/text-search.d.ts +2 -0
  142. package/dist/cli/commands/text-search.d.ts.map +1 -0
  143. package/dist/cli/commands/text-search.js +125 -0
  144. package/dist/cli/commands/text-search.js.map +1 -0
  145. package/dist/cli/commands/update.d.ts +2 -0
  146. package/dist/cli/commands/update.d.ts.map +1 -0
  147. package/dist/cli/commands/update.js +167 -0
  148. package/dist/cli/commands/update.js.map +1 -0
  149. package/dist/cli/commands/validate.d.ts +2 -0
  150. package/dist/cli/commands/validate.d.ts.map +1 -0
  151. package/dist/cli/commands/validate.js +129 -0
  152. package/dist/cli/commands/validate.js.map +1 -0
  153. package/dist/cli/index.d.ts +3 -0
  154. package/dist/cli/index.d.ts.map +1 -0
  155. package/dist/cli/index.js +84 -0
  156. package/dist/cli/index.js.map +1 -0
  157. package/dist/cli/load-collection.d.ts +7 -0
  158. package/dist/cli/load-collection.d.ts.map +1 -0
  159. package/dist/cli/load-collection.js +201 -0
  160. package/dist/cli/load-collection.js.map +1 -0
  161. package/dist/cli/registry.d.ts +17 -0
  162. package/dist/cli/registry.d.ts.map +1 -0
  163. package/dist/cli/registry.js +16 -0
  164. package/dist/cli/registry.js.map +1 -0
  165. package/dist/cnotes +0 -0
  166. package/dist/collection.d.ts +145 -0
  167. package/dist/collection.d.ts.map +1 -0
  168. package/dist/collection.js +684 -0
  169. package/dist/collection.js.map +1 -0
  170. package/dist/define-model.d.ts +45 -0
  171. package/dist/define-model.d.ts.map +1 -0
  172. package/dist/define-model.js +106 -0
  173. package/dist/define-model.js.map +1 -0
  174. package/dist/document.d.ts +119 -0
  175. package/dist/document.d.ts.map +1 -0
  176. package/dist/document.js +418 -0
  177. package/dist/document.js.map +1 -0
  178. package/dist/extract-sections.d.ts +46 -0
  179. package/dist/extract-sections.d.ts.map +1 -0
  180. package/dist/extract-sections.js +153 -0
  181. package/dist/extract-sections.js.map +1 -0
  182. package/dist/index.d.ts +28 -0
  183. package/dist/index.d.ts.map +1 -0
  184. package/dist/index.js +31 -0
  185. package/dist/index.js.map +1 -0
  186. package/dist/mcp/helpers.d.ts +14 -0
  187. package/dist/mcp/helpers.d.ts.map +1 -0
  188. package/dist/mcp/helpers.js +7 -0
  189. package/dist/mcp/helpers.js.map +1 -0
  190. package/dist/mcp/model-info.d.ts +2 -0
  191. package/dist/mcp/model-info.d.ts.map +1 -0
  192. package/dist/mcp/model-info.js +94 -0
  193. package/dist/mcp/model-info.js.map +1 -0
  194. package/dist/mcp/prompts.d.ts +2 -0
  195. package/dist/mcp/prompts.d.ts.map +1 -0
  196. package/dist/mcp/prompts.js +180 -0
  197. package/dist/mcp/prompts.js.map +1 -0
  198. package/dist/mcp/readme.d.ts +2 -0
  199. package/dist/mcp/readme.d.ts.map +1 -0
  200. package/dist/mcp/readme.js +71 -0
  201. package/dist/mcp/readme.js.map +1 -0
  202. package/dist/mcp/resources.d.ts +2 -0
  203. package/dist/mcp/resources.d.ts.map +1 -0
  204. package/dist/mcp/resources.js +85 -0
  205. package/dist/mcp/resources.js.map +1 -0
  206. package/dist/mcp/server.d.ts +18 -0
  207. package/dist/mcp/server.d.ts.map +1 -0
  208. package/dist/mcp/server.js +83 -0
  209. package/dist/mcp/server.js.map +1 -0
  210. package/dist/mcp/tools/mutation.d.ts +2 -0
  211. package/dist/mcp/tools/mutation.d.ts.map +1 -0
  212. package/dist/mcp/tools/mutation.js +155 -0
  213. package/dist/mcp/tools/mutation.js.map +1 -0
  214. package/dist/mcp/tools/query.d.ts +2 -0
  215. package/dist/mcp/tools/query.d.ts.map +1 -0
  216. package/dist/mcp/tools/query.js +130 -0
  217. package/dist/mcp/tools/query.js.map +1 -0
  218. package/dist/mcp/tools/search.d.ts +2 -0
  219. package/dist/mcp/tools/search.d.ts.map +1 -0
  220. package/dist/mcp/tools/search.js +168 -0
  221. package/dist/mcp/tools/search.js.map +1 -0
  222. package/dist/model-instance.d.ts +11 -0
  223. package/dist/model-instance.d.ts.map +1 -0
  224. package/dist/model-instance.js +208 -0
  225. package/dist/model-instance.js.map +1 -0
  226. package/dist/node-shortcuts.d.ts +25 -0
  227. package/dist/node-shortcuts.d.ts.map +1 -0
  228. package/dist/node-shortcuts.js +67 -0
  229. package/dist/node-shortcuts.js.map +1 -0
  230. package/dist/parse.d.ts +45 -0
  231. package/dist/parse.d.ts.map +1 -0
  232. package/dist/parse.js +98 -0
  233. package/dist/parse.js.map +1 -0
  234. package/dist/query/collection-query.d.ts +39 -0
  235. package/dist/query/collection-query.d.ts.map +1 -0
  236. package/dist/query/collection-query.js +184 -0
  237. package/dist/query/collection-query.js.map +1 -0
  238. package/dist/query/index.d.ts +8 -0
  239. package/dist/query/index.d.ts.map +1 -0
  240. package/dist/query/index.js +5 -0
  241. package/dist/query/index.js.map +1 -0
  242. package/dist/query/operators.d.ts +3 -0
  243. package/dist/query/operators.d.ts.map +1 -0
  244. package/dist/query/operators.js +18 -0
  245. package/dist/query/operators.js.map +1 -0
  246. package/dist/query/query-builder.d.ts +34 -0
  247. package/dist/query/query-builder.d.ts.map +1 -0
  248. package/dist/query/query-builder.js +84 -0
  249. package/dist/query/query-builder.js.map +1 -0
  250. package/dist/query/query-dsl.d.ts +36 -0
  251. package/dist/query/query-dsl.d.ts.map +1 -0
  252. package/dist/query/query-dsl.js +195 -0
  253. package/dist/query/query-dsl.js.map +1 -0
  254. package/dist/relationships/belongs-to.d.ts +9 -0
  255. package/dist/relationships/belongs-to.d.ts.map +1 -0
  256. package/dist/relationships/belongs-to.js +34 -0
  257. package/dist/relationships/belongs-to.js.map +1 -0
  258. package/dist/relationships/has-many.d.ts +23 -0
  259. package/dist/relationships/has-many.d.ts.map +1 -0
  260. package/dist/relationships/has-many.js +136 -0
  261. package/dist/relationships/has-many.js.map +1 -0
  262. package/dist/relationships/index.d.ts +26 -0
  263. package/dist/relationships/index.d.ts.map +1 -0
  264. package/dist/relationships/index.js +32 -0
  265. package/dist/relationships/index.js.map +1 -0
  266. package/dist/relationships/types.d.ts +2 -0
  267. package/dist/relationships/types.d.ts.map +1 -0
  268. package/dist/relationships/types.js +2 -0
  269. package/dist/relationships/types.js.map +1 -0
  270. package/dist/search/document-inputs.d.ts +30 -0
  271. package/dist/search/document-inputs.d.ts.map +1 -0
  272. package/dist/search/document-inputs.js +52 -0
  273. package/dist/search/document-inputs.js.map +1 -0
  274. package/dist/search/luca-semantic-search.d.ts +27 -0
  275. package/dist/search/luca-semantic-search.d.ts.map +1 -0
  276. package/dist/search/luca-semantic-search.js +56 -0
  277. package/dist/search/luca-semantic-search.js.map +1 -0
  278. package/dist/section.d.ts +21 -0
  279. package/dist/section.d.ts.map +1 -0
  280. package/dist/section.js +21 -0
  281. package/dist/section.js.map +1 -0
  282. package/dist/types.d.ts +185 -0
  283. package/dist/types.d.ts.map +1 -0
  284. package/dist/types.js +2 -0
  285. package/dist/types.js.map +1 -0
  286. package/dist/utils/index.d.ts +9 -0
  287. package/dist/utils/index.d.ts.map +1 -0
  288. package/dist/utils/index.js +8 -0
  289. package/dist/utils/index.js.map +1 -0
  290. package/dist/utils/inflect.d.ts +6 -0
  291. package/dist/utils/inflect.d.ts.map +1 -0
  292. package/dist/utils/inflect.js +75 -0
  293. package/dist/utils/inflect.js.map +1 -0
  294. package/dist/utils/match-pattern.d.ts +25 -0
  295. package/dist/utils/match-pattern.d.ts.map +1 -0
  296. package/dist/utils/match-pattern.js +52 -0
  297. package/dist/utils/match-pattern.js.map +1 -0
  298. package/dist/utils/normalize-headings.d.ts +8 -0
  299. package/dist/utils/normalize-headings.d.ts.map +1 -0
  300. package/dist/utils/normalize-headings.js +19 -0
  301. package/dist/utils/normalize-headings.js.map +1 -0
  302. package/dist/utils/parse-table.d.ts +7 -0
  303. package/dist/utils/parse-table.d.ts.map +1 -0
  304. package/dist/utils/parse-table.js +17 -0
  305. package/dist/utils/parse-table.js.map +1 -0
  306. package/dist/utils/read-directory.d.ts +5 -0
  307. package/dist/utils/read-directory.d.ts.map +1 -0
  308. package/dist/utils/read-directory.js +29 -0
  309. package/dist/utils/read-directory.js.map +1 -0
  310. package/dist/utils/stringify-ast.d.ts +6 -0
  311. package/dist/utils/stringify-ast.d.ts.map +1 -0
  312. package/dist/utils/stringify-ast.js +8 -0
  313. package/dist/utils/stringify-ast.js.map +1 -0
  314. package/dist/utils/strip-markdown.d.ts +11 -0
  315. package/dist/utils/strip-markdown.d.ts.map +1 -0
  316. package/dist/utils/strip-markdown.js +48 -0
  317. package/dist/utils/strip-markdown.js.map +1 -0
  318. package/dist/validator.d.ts +10 -0
  319. package/dist/validator.d.ts.map +1 -0
  320. package/dist/validator.js +55 -0
  321. package/dist/validator.js.map +1 -0
  322. package/package.json +1 -1
@@ -0,0 +1,418 @@
1
+ import { unified } from "unified";
2
+ import remarkParse from "remark-parse";
3
+ import remarkGfm from "remark-gfm";
4
+ import remarkRehype from "remark-rehype";
5
+ import rehypeStringify from "rehype-stringify";
6
+ import yaml from "js-yaml";
7
+ import { toString } from "mdast-util-to-string";
8
+ import { kebabCase } from "./utils/inflect";
9
+ import { AstQuery } from "./ast-query";
10
+ import { NodeShortcuts } from "./node-shortcuts";
11
+ import { stringifyAst } from "./utils/stringify-ast";
12
+ import { normalizeHeadings } from "./utils/normalize-headings";
13
+ import { parseTable } from "./utils/parse-table";
14
+ import { stripMarkdown } from "./utils/strip-markdown";
15
+ export class Document {
16
+ id;
17
+ collection;
18
+ #content;
19
+ #meta;
20
+ #ast;
21
+ constructor(options) {
22
+ this.id = options.id;
23
+ this.collection = options.collection;
24
+ this.#content = options.content;
25
+ this.#meta = options.meta ?? {};
26
+ this.#ast = options.ast ?? null;
27
+ }
28
+ // ─── Core getters ───
29
+ get meta() {
30
+ return this.#meta;
31
+ }
32
+ get content() {
33
+ return this.#content;
34
+ }
35
+ get ast() {
36
+ if (!this.#ast) {
37
+ this.#ast = this.processor.parse(this.#content);
38
+ }
39
+ return this.#ast;
40
+ }
41
+ get title() {
42
+ if (this.#meta.title)
43
+ return String(this.#meta.title);
44
+ const heading = this.astQuery.select("heading");
45
+ return heading ? toString(heading) : this.id;
46
+ }
47
+ get slug() {
48
+ return kebabCase(this.title.toLowerCase());
49
+ }
50
+ get createdAt() {
51
+ return this.collection.items.get(this.id)?.createdAt;
52
+ }
53
+ get updatedAt() {
54
+ return this.collection.items.get(this.id)?.updatedAt;
55
+ }
56
+ get size() {
57
+ return this.collection.items.get(this.id)?.size;
58
+ }
59
+ get rawContent() {
60
+ if (Object.keys(this.#meta).length === 0) {
61
+ return this.content;
62
+ }
63
+ const frontmatter = yaml.dump(this.#meta).trim();
64
+ return `---\n${frontmatter}\n---\n\n${this.content}`;
65
+ }
66
+ get path() {
67
+ return this.collection.resolve(this.id) + ".md";
68
+ }
69
+ // ─── Processor ───
70
+ /**
71
+ * Returns a unified processor configured for parsing markdown with GFM.
72
+ * This is intentionally NOT the MDX processor -- MDX compilation is a
73
+ * separate concern handled by plugins.
74
+ */
75
+ get processor() {
76
+ return unified().use(remarkParse).use(remarkGfm);
77
+ }
78
+ // ─── AST access ───
79
+ get astQuery() {
80
+ return new AstQuery(this.ast);
81
+ }
82
+ get nodes() {
83
+ return new NodeShortcuts(this.astQuery);
84
+ }
85
+ query(ast = this.ast) {
86
+ return new AstQuery(ast);
87
+ }
88
+ // ─── Section operations ───
89
+ /**
90
+ * Extract a section of the document, starting with a heading.
91
+ * Returns all nodes underneath the heading until another heading
92
+ * of the same depth is encountered, or the end of the document.
93
+ */
94
+ extractSection(startHeading) {
95
+ let heading;
96
+ if (typeof startHeading === "string") {
97
+ heading = this.astQuery.findHeadingByText(startHeading);
98
+ // If not found, try alternatives from the model definition's sections
99
+ if (!heading) {
100
+ heading = this.#resolveAlternativeHeading(startHeading);
101
+ }
102
+ }
103
+ else {
104
+ heading = startHeading;
105
+ }
106
+ if (!heading) {
107
+ throw new Error(`Heading not found: ${typeof startHeading === "string" ? startHeading : toString(startHeading)}`);
108
+ }
109
+ const endHeading = this.astQuery.findNextSiblingHeadingTo(heading);
110
+ const sectionNodes = endHeading
111
+ ? this.astQuery.findBetween(heading, endHeading)
112
+ : this.astQuery.findAllAfter(heading);
113
+ return [heading, ...sectionNodes];
114
+ }
115
+ /**
116
+ * Look up section alternatives from the model definition.
117
+ * If the requested heading matches a section's heading or is one of its alternatives,
118
+ * try all variants (primary + alternatives) until one is found in the AST.
119
+ */
120
+ #resolveAlternativeHeading(requestedHeading) {
121
+ const def = this.collection?.findModelDefinition?.(this.id);
122
+ if (!def?.sections)
123
+ return undefined;
124
+ for (const sectionDef of Object.values(def.sections)) {
125
+ const allNames = [sectionDef.heading, ...(sectionDef.alternatives ?? [])];
126
+ if (!allNames.some((n) => n === requestedHeading))
127
+ continue;
128
+ for (const name of allNames) {
129
+ const found = this.astQuery.findHeadingByText(name);
130
+ if (found)
131
+ return found;
132
+ }
133
+ }
134
+ return undefined;
135
+ }
136
+ /**
137
+ * Returns an AstQuery scoped to the nodes underneath a particular heading,
138
+ * excluding the heading itself.
139
+ */
140
+ querySection(startHeading) {
141
+ let children = [];
142
+ try {
143
+ children = this.extractSection(startHeading).slice(1);
144
+ }
145
+ catch {
146
+ // Section not found: return empty query
147
+ }
148
+ return new AstQuery({
149
+ type: "root",
150
+ children: children,
151
+ });
152
+ }
153
+ // ─── Section mutations ───
154
+ /**
155
+ * Removes the nodes under the given heading from the AST.
156
+ * Returns a new Document by default. Pass { mutate: true } to modify in place.
157
+ */
158
+ removeSection(heading, opts = {}) {
159
+ const headingNode = typeof heading === "string"
160
+ ? this.astQuery.findHeadingByText(heading)
161
+ : heading;
162
+ if (!headingNode)
163
+ throw new Error(`Heading not found: ${heading}`);
164
+ const sectionNodes = this.extractSection(headingNode);
165
+ const newChildren = this.ast.children.filter((n) => !sectionNodes.includes(n));
166
+ if (opts.mutate) {
167
+ this.ast.children = newChildren;
168
+ this.#content = stringifyAst(this.ast);
169
+ return this;
170
+ }
171
+ const newAst = { type: "root", children: [...newChildren] };
172
+ return new Document({
173
+ id: this.id,
174
+ content: stringifyAst(newAst),
175
+ meta: { ...this.#meta },
176
+ collection: this.collection,
177
+ ast: newAst,
178
+ });
179
+ }
180
+ /**
181
+ * Replaces the content underneath a heading with new content.
182
+ */
183
+ replaceSectionContent(heading, nodesOrMarkdown, opts = {}) {
184
+ const headingNode = typeof heading === "string"
185
+ ? this.astQuery.findHeadingByText(heading)
186
+ : heading;
187
+ if (!headingNode)
188
+ throw new Error(`Heading not found: ${heading}`);
189
+ let newNodes;
190
+ if (typeof nodesOrMarkdown === "string") {
191
+ newNodes = this.processor.parse(nodesOrMarkdown)
192
+ .children;
193
+ }
194
+ else {
195
+ newNodes = nodesOrMarkdown;
196
+ }
197
+ const sectionNodes = this.extractSection(headingNode).slice(1);
198
+ const headingIndex = this.ast.children.indexOf(headingNode);
199
+ if (opts.mutate) {
200
+ this.ast.children.splice(headingIndex + 1, sectionNodes.length, ...newNodes);
201
+ this.#content = stringifyAst(this.ast);
202
+ return this;
203
+ }
204
+ const children = [...this.ast.children];
205
+ children.splice(headingIndex + 1, sectionNodes.length, ...newNodes);
206
+ const newAst = { type: "root", children };
207
+ return new Document({
208
+ id: this.id,
209
+ content: stringifyAst(newAst),
210
+ meta: { ...this.#meta },
211
+ collection: this.collection,
212
+ ast: newAst,
213
+ });
214
+ }
215
+ /** Insert new content before a given node. */
216
+ insertBefore(node, nodesOrMarkdown, opts = {}) {
217
+ let newNodes;
218
+ if (typeof nodesOrMarkdown === "string") {
219
+ newNodes = this.processor.parse(nodesOrMarkdown)
220
+ .children;
221
+ }
222
+ else {
223
+ newNodes = nodesOrMarkdown;
224
+ }
225
+ const index = this.ast.children.indexOf(node);
226
+ if (opts.mutate) {
227
+ this.ast.children.splice(index, 0, ...newNodes);
228
+ this.#content = stringifyAst(this.ast);
229
+ return this;
230
+ }
231
+ const children = [...this.ast.children];
232
+ children.splice(index, 0, ...newNodes);
233
+ const newAst = { type: "root", children };
234
+ return new Document({
235
+ id: this.id,
236
+ content: stringifyAst(newAst),
237
+ meta: { ...this.#meta },
238
+ collection: this.collection,
239
+ ast: newAst,
240
+ });
241
+ }
242
+ /** Insert new content after a given node. */
243
+ insertAfter(node, nodesOrMarkdown, opts = {}) {
244
+ let newNodes;
245
+ if (typeof nodesOrMarkdown === "string") {
246
+ newNodes = this.processor.parse(nodesOrMarkdown)
247
+ .children;
248
+ }
249
+ else {
250
+ newNodes = nodesOrMarkdown;
251
+ }
252
+ const index = this.ast.children.indexOf(node);
253
+ if (opts.mutate) {
254
+ this.ast.children.splice(index + 1, 0, ...newNodes);
255
+ this.#content = stringifyAst(this.ast);
256
+ return this;
257
+ }
258
+ const children = [...this.ast.children];
259
+ children.splice(index + 1, 0, ...newNodes);
260
+ const newAst = { type: "root", children };
261
+ return new Document({
262
+ id: this.id,
263
+ content: stringifyAst(newAst),
264
+ meta: { ...this.#meta },
265
+ collection: this.collection,
266
+ ast: newAst,
267
+ });
268
+ }
269
+ /** Append new content at the end of a section. */
270
+ appendToSection(heading, nodesOrMarkdown, opts = {}) {
271
+ const headingNode = typeof heading === "string"
272
+ ? this.astQuery.findHeadingByText(heading)
273
+ : heading;
274
+ if (!headingNode)
275
+ throw new Error(`Heading not found: ${heading}`);
276
+ let newNodes;
277
+ if (typeof nodesOrMarkdown === "string") {
278
+ newNodes = this.processor.parse(nodesOrMarkdown)
279
+ .children;
280
+ }
281
+ else {
282
+ newNodes = nodesOrMarkdown;
283
+ }
284
+ const sectionNodes = this.extractSection(headingNode);
285
+ const lastNode = sectionNodes[sectionNodes.length - 1];
286
+ const lastIndex = this.ast.children.indexOf(lastNode);
287
+ if (opts.mutate) {
288
+ this.ast.children.splice(lastIndex + 1, 0, ...newNodes);
289
+ this.#content = stringifyAst(this.ast);
290
+ return this;
291
+ }
292
+ const children = [...this.ast.children];
293
+ children.splice(lastIndex + 1, 0, ...newNodes);
294
+ const newAst = { type: "root", children };
295
+ return new Document({
296
+ id: this.id,
297
+ content: stringifyAst(newAst),
298
+ meta: { ...this.#meta },
299
+ collection: this.collection,
300
+ ast: newAst,
301
+ });
302
+ }
303
+ // ─── Content manipulation ───
304
+ replaceContent(content) {
305
+ return new Document({
306
+ id: this.id,
307
+ content,
308
+ meta: { ...this.#meta },
309
+ collection: this.collection,
310
+ });
311
+ }
312
+ appendContent(content) {
313
+ return new Document({
314
+ id: this.id,
315
+ content: this.#content + content,
316
+ meta: { ...this.#meta },
317
+ collection: this.collection,
318
+ });
319
+ }
320
+ /** Re-parse the AST from the current content. Mutable. */
321
+ rerenderAST(newContent = this.content) {
322
+ this.#content = newContent;
323
+ this.#ast = this.processor.parse(newContent);
324
+ return this;
325
+ }
326
+ /** Update content from the current AST state. Mutable. */
327
+ reloadFromAST(newAst = this.ast) {
328
+ this.#ast = newAst;
329
+ this.#content = stringifyAst(newAst);
330
+ return this;
331
+ }
332
+ stringify(ast = this.ast) {
333
+ return stringifyAst(ast);
334
+ }
335
+ normalizeHeadings() {
336
+ normalizeHeadings(this.ast);
337
+ this.#content = stringifyAst(this.ast);
338
+ return this;
339
+ }
340
+ // ─── Serialization ───
341
+ toJSON() {
342
+ return {
343
+ id: this.id,
344
+ meta: this.meta,
345
+ content: this.content,
346
+ ast: this.ast,
347
+ createdAt: this.createdAt,
348
+ updatedAt: this.updatedAt,
349
+ size: this.size,
350
+ };
351
+ }
352
+ stripMarkdown(options) {
353
+ return stripMarkdown(this.ast, options);
354
+ }
355
+ toText(filterFn = () => true) {
356
+ return this.ast.children
357
+ .filter(filterFn)
358
+ .map((n) => toString(n))
359
+ .join("\n");
360
+ }
361
+ /**
362
+ * Returns an indented text outline of the document's headings.
363
+ * Each heading is indented based on its depth relative to the
364
+ * minimum heading depth found in the document.
365
+ */
366
+ async toHtml() {
367
+ const result = await unified()
368
+ .use(remarkParse)
369
+ .use(remarkGfm)
370
+ .use(remarkRehype)
371
+ .use(rehypeStringify)
372
+ .process(this.content);
373
+ return String(result);
374
+ }
375
+ toOutline() {
376
+ const headings = this.ast.children.filter((n) => n.type === "heading");
377
+ if (headings.length === 0)
378
+ return "";
379
+ const minDepth = Math.min(...headings.map((h) => h.depth));
380
+ return headings
381
+ .map((h) => {
382
+ const indent = " ".repeat(h.depth - minDepth);
383
+ return `${indent}- ${toString(h)}`;
384
+ })
385
+ .join("\n");
386
+ }
387
+ // ─── Utility access ───
388
+ get utils() {
389
+ return {
390
+ kebabCase,
391
+ toString,
392
+ stringifyAst,
393
+ parseTable,
394
+ normalizeHeadings,
395
+ extractSection: (heading) => this.extractSection(heading),
396
+ createNewAst: (children = []) => ({ type: "root", children }),
397
+ };
398
+ }
399
+ // ─── Persistence ───
400
+ async save(options = {}) {
401
+ if (options.normalize !== false) {
402
+ this.normalizeHeadings();
403
+ }
404
+ await this.collection.saveItem(this.id, {
405
+ content: this.rawContent,
406
+ extension: options.extension,
407
+ });
408
+ return this;
409
+ }
410
+ async reload() {
411
+ const item = await this.collection.readItem(this.id);
412
+ this.#content = item.content;
413
+ this.#meta = item.meta;
414
+ this.#ast = null; // Will be lazily re-parsed
415
+ return this;
416
+ }
417
+ }
418
+ //# sourceMappingURL=document.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document.js","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { Content } from "mdast";
2
+ import type { ParsedDocument } from "./parse";
3
+ /** Any object that exposes a title and section extraction — satisfied by both Document and ParsedDocument. */
4
+ export type SectionSource = {
5
+ title: string;
6
+ extractSection(heading: string | Content): Content[];
7
+ };
8
+ export interface ExtractionEntry {
9
+ /** The source document or parsed document */
10
+ source: SectionSource;
11
+ /** Section heading name(s) to extract. A string extracts one section; an array extracts multiple. */
12
+ sections: string | string[];
13
+ }
14
+ export interface ExtractSectionsOptions {
15
+ /** Optional title for the combined document (becomes an h1). */
16
+ title?: string;
17
+ /**
18
+ * How to organize extracted sections.
19
+ * - `"grouped"` (default): Each source document gets a heading (its title),
20
+ * with extracted sections nested underneath.
21
+ * - `"flat"`: All extracted sections are placed sequentially with no source grouping.
22
+ */
23
+ mode?: "grouped" | "flat";
24
+ /**
25
+ * What to do when a requested section is not found in a source document.
26
+ * - `"skip"` (default): silently omit the missing section
27
+ * - `"throw"`: throw an error
28
+ */
29
+ onMissing?: "skip" | "throw";
30
+ }
31
+ /**
32
+ * Extract named sections from multiple documents into a single combined document.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * const combined = extractSections([
37
+ * { source: doc1, sections: "Acceptance Criteria" },
38
+ * { source: doc2, sections: ["Acceptance Criteria", "Mockups"] },
39
+ * ], {
40
+ * title: "All Acceptance Criteria",
41
+ * mode: "grouped",
42
+ * });
43
+ * ```
44
+ */
45
+ export declare function extractSections(entries: ExtractionEntry[], options?: ExtractSectionsOptions): ParsedDocument;
46
+ //# sourceMappingURL=extract-sections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-sections.d.ts","sourceRoot":"","sources":["../src/extract-sections.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAQ,OAAO,EAAwB,MAAM,OAAO,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,8GAA8G;AAC9G,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,EAAE,CAAC;CACtD,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,MAAM,EAAE,aAAa,CAAC;IACtB,qGAAqG;IACrG,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,sBAAsB;IACrC,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;CAC9B;AA8HD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,eAAe,EAAE,EAC1B,OAAO,GAAE,sBAA2B,GACnC,cAAc,CA2ChB"}
@@ -0,0 +1,153 @@
1
+ import { toString } from "mdast-util-to-string";
2
+ import { AstQuery } from "./ast-query";
3
+ import { NodeShortcuts } from "./node-shortcuts";
4
+ import { stringifyAst } from "./utils/stringify-ast";
5
+ import { stripMarkdown } from "./utils/strip-markdown";
6
+ // ---------------------------------------------------------------------------
7
+ // Helpers
8
+ // ---------------------------------------------------------------------------
9
+ function createHeadingNode(text, depth) {
10
+ return {
11
+ type: "heading",
12
+ depth,
13
+ children: [{ type: "text", value: text }],
14
+ };
15
+ }
16
+ function clampDepth(d) {
17
+ return Math.max(1, Math.min(6, d));
18
+ }
19
+ /** Deep-clone section nodes and shift all heading depths to the target depth. */
20
+ function cloneAndShiftHeadings(nodes, targetDepth) {
21
+ if (nodes.length === 0)
22
+ return [];
23
+ const firstNode = nodes[0];
24
+ const originalDepth = firstNode.type === "heading" ? firstNode.depth : 1;
25
+ const depthShift = targetDepth - originalDepth;
26
+ const cloned = structuredClone(nodes);
27
+ if (depthShift !== 0) {
28
+ for (const node of cloned) {
29
+ if (node.type === "heading") {
30
+ node.depth = clampDepth(node.depth + depthShift);
31
+ }
32
+ }
33
+ }
34
+ return cloned;
35
+ }
36
+ function tryExtractSection(source, sectionName, onMissing) {
37
+ try {
38
+ return source.extractSection(sectionName);
39
+ }
40
+ catch (err) {
41
+ if (onMissing === "throw")
42
+ throw err;
43
+ return null;
44
+ }
45
+ }
46
+ function normalizeSections(sections) {
47
+ return Array.isArray(sections) ? sections : [sections];
48
+ }
49
+ /** Build a fully queryable ParsedDocument from an AST root (mirrors parse.ts). */
50
+ function buildParsedDocument(ast) {
51
+ const astQuery = new AstQuery(ast);
52
+ const nodes = new NodeShortcuts(astQuery);
53
+ const firstHeading = astQuery.select("heading");
54
+ const title = firstHeading ? toString(firstHeading) : "";
55
+ const content = stringifyAst(ast);
56
+ function extractSection(startHeading) {
57
+ let heading;
58
+ if (typeof startHeading === "string") {
59
+ heading = astQuery.findHeadingByText(startHeading);
60
+ }
61
+ else {
62
+ heading = startHeading;
63
+ }
64
+ if (!heading) {
65
+ throw new Error(`Heading not found: ${typeof startHeading === "string" ? startHeading : toString(startHeading)}`);
66
+ }
67
+ const endHeading = astQuery.findNextSiblingHeadingTo(heading);
68
+ const sectionNodes = endHeading
69
+ ? astQuery.findBetween(heading, endHeading)
70
+ : astQuery.findAllAfter(heading);
71
+ return [heading, ...sectionNodes];
72
+ }
73
+ function querySection(startHeading) {
74
+ let children = [];
75
+ try {
76
+ children = extractSection(startHeading).slice(1);
77
+ }
78
+ catch {
79
+ // Section not found: return empty query
80
+ }
81
+ return new AstQuery({
82
+ type: "root",
83
+ children: children,
84
+ });
85
+ }
86
+ return {
87
+ meta: {},
88
+ content,
89
+ ast,
90
+ astQuery,
91
+ nodes,
92
+ title,
93
+ stringify: (tree = ast) => stringifyAst(tree),
94
+ stripMarkdown: (options) => stripMarkdown(ast, options),
95
+ extractSection,
96
+ querySection,
97
+ };
98
+ }
99
+ // ---------------------------------------------------------------------------
100
+ // Main
101
+ // ---------------------------------------------------------------------------
102
+ /**
103
+ * Extract named sections from multiple documents into a single combined document.
104
+ *
105
+ * @example
106
+ * ```ts
107
+ * const combined = extractSections([
108
+ * { source: doc1, sections: "Acceptance Criteria" },
109
+ * { source: doc2, sections: ["Acceptance Criteria", "Mockups"] },
110
+ * ], {
111
+ * title: "All Acceptance Criteria",
112
+ * mode: "grouped",
113
+ * });
114
+ * ```
115
+ */
116
+ export function extractSections(entries, options = {}) {
117
+ const { title, mode = "grouped", onMissing = "skip" } = options;
118
+ const combinedChildren = [];
119
+ let baseDepth = 1;
120
+ if (title) {
121
+ combinedChildren.push(createHeadingNode(title, 1));
122
+ baseDepth = 2;
123
+ }
124
+ for (const entry of entries) {
125
+ const { source } = entry;
126
+ const sectionNames = normalizeSections(entry.sections);
127
+ if (mode === "grouped") {
128
+ const sourceTitle = source.title || "(Untitled)";
129
+ combinedChildren.push(createHeadingNode(sourceTitle, clampDepth(baseDepth)));
130
+ const sectionTargetDepth = baseDepth + 1;
131
+ for (const sectionName of sectionNames) {
132
+ const sectionNodes = tryExtractSection(source, sectionName, onMissing);
133
+ if (!sectionNodes)
134
+ continue;
135
+ const shifted = cloneAndShiftHeadings(sectionNodes, sectionTargetDepth);
136
+ combinedChildren.push(...shifted);
137
+ }
138
+ }
139
+ else {
140
+ // flat mode
141
+ for (const sectionName of sectionNames) {
142
+ const sectionNodes = tryExtractSection(source, sectionName, onMissing);
143
+ if (!sectionNodes)
144
+ continue;
145
+ const shifted = cloneAndShiftHeadings(sectionNodes, baseDepth);
146
+ combinedChildren.push(...shifted);
147
+ }
148
+ }
149
+ }
150
+ const ast = { type: "root", children: combinedChildren };
151
+ return buildParsedDocument(ast);
152
+ }
153
+ //# sourceMappingURL=extract-sections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-sections.js","sourceRoot":"","sources":["../src/extract-sections.ts"],"names":[],"mappings":"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"}