contentbase 0.0.2 → 0.0.4

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 (85) hide show
  1. package/.mcp.json +9 -0
  2. package/CLI.md +593 -0
  3. package/MCP-DESCRIPTIONS-REVIEW.md +122 -0
  4. package/MCP-SERVER-SPEC.md +453 -0
  5. package/PRIMER.md +540 -0
  6. package/README.md +289 -13
  7. package/bun.lock +43 -4
  8. package/dist/cnotes +0 -0
  9. package/docs/README.md +110 -0
  10. package/docs/TABLE-OF-CONTENTS.md +7 -0
  11. package/docs/models.ts +38 -0
  12. package/models.ts +38 -0
  13. package/package.json +12 -3
  14. package/public/web-demo/index.html +813 -0
  15. package/showcases/node_modules/.cache/.repl_history +3 -0
  16. package/showcases/vinyl-collection/artists/nina-simone.mdx +1 -1
  17. package/src/__tests__/semantic-search.integration.test.ts +284 -0
  18. package/src/api/endpoints/actions.ts +34 -0
  19. package/src/api/endpoints/doc.ts +187 -0
  20. package/src/api/endpoints/docs-index.ts +26 -0
  21. package/src/api/endpoints/document.ts +171 -0
  22. package/src/api/endpoints/documents.ts +71 -0
  23. package/src/api/endpoints/inspect.ts +16 -0
  24. package/src/api/endpoints/models.ts +10 -0
  25. package/src/api/endpoints/query.ts +88 -0
  26. package/src/api/endpoints/root.ts +7 -0
  27. package/src/api/endpoints/search-reindex.ts +65 -0
  28. package/src/api/endpoints/search-status.ts +55 -0
  29. package/src/api/endpoints/search.ts +104 -0
  30. package/src/api/endpoints/semantic-search.ts +120 -0
  31. package/src/api/endpoints/text-search.ts +63 -0
  32. package/src/api/endpoints/validate.ts +34 -0
  33. package/src/api/helpers.ts +97 -0
  34. package/src/base-model.ts +12 -0
  35. package/src/cli/commands/action.ts +82 -44
  36. package/src/cli/commands/console.ts +124 -0
  37. package/src/cli/commands/create.ts +179 -53
  38. package/src/cli/commands/embed.ts +323 -0
  39. package/src/cli/commands/export.ts +58 -24
  40. package/src/cli/commands/extract.ts +174 -0
  41. package/src/cli/commands/help.ts +81 -0
  42. package/src/cli/commands/index.ts +17 -0
  43. package/src/cli/commands/init.ts +72 -48
  44. package/src/cli/commands/inspect.ts +56 -46
  45. package/src/cli/commands/mcp.ts +1219 -0
  46. package/src/cli/commands/search.ts +285 -0
  47. package/src/cli/commands/serve.ts +348 -0
  48. package/src/cli/commands/summary.ts +60 -0
  49. package/src/cli/commands/teach.ts +86 -0
  50. package/src/cli/commands/text-search.ts +134 -0
  51. package/src/cli/commands/validate.ts +126 -64
  52. package/src/cli/index.ts +88 -19
  53. package/src/cli/load-collection.ts +144 -17
  54. package/src/cli/registry.ts +28 -0
  55. package/src/collection.ts +361 -10
  56. package/src/define-model.ts +101 -4
  57. package/src/document.ts +47 -1
  58. package/src/extract-sections.ts +1 -1
  59. package/src/index.ts +14 -2
  60. package/src/model-instance.ts +35 -5
  61. package/src/node-shortcuts.ts +1 -1
  62. package/src/query/collection-query.ts +96 -9
  63. package/src/query/index.ts +7 -0
  64. package/src/query/query-dsl.ts +259 -0
  65. package/src/relationships/has-many.ts +39 -0
  66. package/src/relationships/index.ts +7 -2
  67. package/src/section.ts +2 -0
  68. package/src/types.ts +23 -1
  69. package/src/utils/index.ts +1 -0
  70. package/src/utils/match-pattern.ts +65 -0
  71. package/src/validator.ts +18 -1
  72. package/test/collection.test.ts +118 -2
  73. package/test/fixtures/sdlc/MODELS.md +106 -0
  74. package/test/fixtures/sdlc/SKILL.md +404 -0
  75. package/test/fixtures/sdlc/index.ts +9 -0
  76. package/test/fixtures/sdlc/models.ts +8 -6
  77. package/test/fixtures/sdlc/stories/authentication/a-user-should-be-able-to-login.mdx +20 -0
  78. package/test/fixtures/sdlc/templates/epic.md +23 -0
  79. package/test/fixtures/sdlc/templates/story.md +19 -0
  80. package/test/pattern.test.ts +191 -0
  81. package/test/query-dsl.test.ts +431 -0
  82. package/test/query.test.ts +29 -0
  83. package/test/relationships.test.ts +130 -0
  84. package/test/section.test.ts +61 -0
  85. package/test/table-of-contents.test.ts +49 -5
package/README.md CHANGED
@@ -5,8 +5,7 @@
5
5
  Contentbase treats a folder of Markdown and MDX files as a typed, queryable database. Define models with Zod schemas, extract structured data from headings and lists, traverse parent/child relationships across documents, validate everything, and query it all with a fluent API.
6
6
 
7
7
  ```ts
8
- import { Collection, defineModel, section, hasMany, z } from "contentbase";
9
- import { toString } from "mdast-util-to-string";
8
+ import { Collection, defineModel, section, hasMany, z, toString } from "contentbase";
10
9
 
11
10
  const Story = defineModel("Story", {
12
11
  meta: z.object({
@@ -79,14 +78,18 @@ content/
79
78
 
80
79
  A model is a config object that describes one type of document. It declares:
81
80
 
81
+ - **description** -- human-readable summary (auto-generated from schema if omitted)
82
82
  - **meta** -- a Zod schema for frontmatter
83
83
  - **sections** -- named extractions from heading-based sections
84
84
  - **relationships** -- `hasMany` / `belongsTo` links between models
85
85
  - **computed** -- derived values calculated from instance data
86
+ - **defaults** -- static default values for frontmatter fields
87
+ - **pattern** -- Express-style path patterns for inferring meta from file paths
86
88
 
87
89
  ```ts
88
90
  const Epic = defineModel("Epic", {
89
91
  prefix: "epics",
92
+ description: "A project epic that groups related user stories.",
90
93
  meta: z.object({
91
94
  priority: z.enum(["low", "medium", "high"]).optional(),
92
95
  status: z.enum(["created", "in-progress", "complete"]).default("created"),
@@ -103,14 +106,71 @@ const Epic = defineModel("Epic", {
103
106
  });
104
107
  ```
105
108
 
109
+ If `description` is omitted, one is generated on first access from the model's schema: *"An Epic has metadata (priority, status), relationship (stories → Story), and computed property (isComplete)."*
110
+
106
111
  The `prefix` determines which files match this model. Files whose path starts with `"epics"` are Epics. If omitted, the prefix is auto-pluralized from the name (`"Epic"` -> `"epics"`).
107
112
 
113
+ #### Explicit Model Assignment with `_model`
114
+
115
+ Documents at the root of a collection (not in a subfolder) can't be matched by prefix. You can explicitly assign a model by adding `_model` to the frontmatter:
116
+
117
+ ```yaml
118
+ ---
119
+ _model: Epic
120
+ title: Platform Migration
121
+ status: created
122
+ ---
123
+ ```
124
+
125
+ The `_model` key takes priority over prefix matching, so this works even if the file lives outside the model's prefix folder.
126
+
127
+ #### The Base Model
128
+
129
+ Every collection automatically registers a built-in `Base` model as a catch-all. Documents that don't match any other model (by `_model` or prefix) are assigned to Base. You can query these unmatched documents:
130
+
131
+ ```ts
132
+ import { Base } from "contentbase";
133
+
134
+ const misc = await collection.query(Base).fetchAll();
135
+ ```
136
+
137
+ If you want to customize the Base model (e.g. add a meta schema), register your own before calling `load()`:
138
+
139
+ ```ts
140
+ const MyBase = defineModel("Base", {
141
+ meta: z.object({ tags: z.array(z.string()).optional() }),
142
+ });
143
+ collection.register(MyBase);
144
+ await collection.load(); // won't auto-register the built-in Base
145
+ ```
146
+
147
+ #### Path Patterns
148
+
149
+ Models can declare Express-style path patterns to automatically infer meta values from the document's file path:
150
+
151
+ ```ts
152
+ const Story = defineModel("Story", {
153
+ prefix: "stories",
154
+ pattern: "stories/:epic/:slug",
155
+ meta: z.object({
156
+ epic: z.string(),
157
+ slug: z.string(),
158
+ }),
159
+ });
160
+ ```
161
+
162
+ A file at `stories/authentication/user-can-register.mdx` will automatically have `{ epic: "authentication", slug: "user-can-register" }` inferred into its meta. Explicit frontmatter values always take precedence over pattern-inferred values. You can also supply an array of patterns -- the first match wins.
163
+
108
164
  ### Collections
109
165
 
110
166
  A `Collection` loads a directory tree and gives you access to documents and typed model instances.
111
167
 
112
168
  ```ts
113
- const collection = new Collection({ rootPath: "./content" });
169
+ const collection = new Collection({
170
+ rootPath: "./content",
171
+ extensions: ["mdx", "md"], // default
172
+ autoDiscover: true, // auto-load models.ts if no models registered
173
+ });
114
174
  await collection.load();
115
175
 
116
176
  // Register models for prefix-based matching
@@ -141,8 +201,7 @@ Given this Markdown:
141
201
  Define a section to extract the list items:
142
202
 
143
203
  ```ts
144
- import { section } from "contentbase";
145
- import { toString } from "mdast-util-to-string";
204
+ import { section, toString } from "contentbase";
146
205
 
147
206
  const Story = defineModel("Story", {
148
207
  sections: {
@@ -150,12 +209,13 @@ const Story = defineModel("Story", {
150
209
  extract: (query) =>
151
210
  query.selectAll("listItem").map((node) => toString(node)),
152
211
  schema: z.array(z.string()),
212
+ alternatives: ["Requirements"], // fallback heading names
153
213
  }),
154
214
  },
155
215
  });
156
216
  ```
157
217
 
158
- The `extract` function receives an `AstQuery` scoped to the content under that heading. The `schema` is optional and used during validation.
218
+ The `extract` function receives an `AstQuery` scoped to the content under that heading. The `schema` is optional and used during validation. The `alternatives` array provides fallback heading names -- if "Acceptance Criteria" isn't found, it tries "Requirements" next.
159
219
 
160
220
  Section data is **lazily computed and cached** -- the extract function only runs the first time you access the property.
161
221
 
@@ -272,6 +332,9 @@ const results = await collection
272
332
  .query(Story)
273
333
  .whereIn("meta.status", ["created", "in-progress"])
274
334
  .whereExists("meta.epic")
335
+ .sort("meta.status", "asc")
336
+ .limit(10)
337
+ .offset(0)
275
338
  .fetchAll();
276
339
 
277
340
  // Convenience accessors
@@ -283,6 +346,60 @@ Available operators: `eq`, `neq`, `in`, `notIn`, `gt`, `lt`, `gte`, `lte`, `cont
283
346
 
284
347
  Queries filter by model type **before** creating instances, so you only pay the parsing cost for matching documents.
285
348
 
349
+ ### JSON Query DSL
350
+
351
+ For querying over the wire (REST API, MCP server) without executing arbitrary code, Contentbase provides a MongoDB-style JSON query DSL:
352
+
353
+ ```json
354
+ {
355
+ "model": "Epic",
356
+ "where": {
357
+ "meta.status": "created",
358
+ "meta.priority": { "$gt": 3 }
359
+ },
360
+ "sort": { "meta.priority": "desc" },
361
+ "select": ["id", "title", "meta.status"],
362
+ "limit": 10,
363
+ "offset": 0
364
+ }
365
+ ```
366
+
367
+ **Where value shortcuts:**
368
+
369
+ | Value type | Interpretation | Example |
370
+ |------------|---------------|---------|
371
+ | Literal (string, number, boolean, null) | Implicit `$eq` | `"meta.status": "active"` |
372
+ | Array | Implicit `$in` | `"meta.tags": ["a", "b"]` |
373
+ | Operator object | Explicit operator | `"meta.priority": { "$gt": 5 }` |
374
+ | Multiple operators | AND on same field | `"meta.priority": { "$gte": 3, "$lte": 8 }` |
375
+
376
+ **Available operators:** `$eq`, `$neq`, `$in`, `$notIn`, `$gt`, `$lt`, `$gte`, `$lte`, `$contains`, `$startsWith`, `$endsWith`, `$regex`, `$exists`
377
+
378
+ **Options:**
379
+
380
+ | Field | Type | Default | Description |
381
+ |-------|------|---------|-------------|
382
+ | `model` | string | *(required)* | Model name or prefix |
383
+ | `where` | object | -- | MongoDB-style filter conditions |
384
+ | `sort` | object or array | -- | `{ "field": "asc"\|"desc" }` or `[{ "path": "...", "direction": "asc" }]` |
385
+ | `select` | string[] | -- | Fields to include in output |
386
+ | `limit` | number | -- | Maximum results to return |
387
+ | `offset` | number | -- | Number of results to skip |
388
+ | `method` | string | `"fetchAll"` | `"fetchAll"`, `"first"`, `"last"`, or `"count"` |
389
+
390
+ Use via `POST /api/query` with a JSON body, or through the MCP `query` tool. The DSL parser is also available programmatically:
391
+
392
+ ```ts
393
+ import { executeQueryDSL, queryDSLSchema } from "contentbase";
394
+
395
+ const result = await executeQueryDSL(collection, {
396
+ model: "Epic",
397
+ where: { "meta.status": "created" },
398
+ sort: { title: "asc" },
399
+ limit: 5,
400
+ });
401
+ ```
402
+
286
403
  ---
287
404
 
288
405
  ## Validation
@@ -489,6 +606,32 @@ collection.tableOfContents({ basePath: "./content" });
489
606
  // links become: ./content/epics/authentication.mdx
490
607
  ```
491
608
 
609
+ ### File Tree
610
+
611
+ Render an ASCII file tree of all documents in the collection:
612
+
613
+ ```ts
614
+ const tree = collection.renderFileTree();
615
+ ```
616
+
617
+ ```
618
+ epics/
619
+ ├── authentication.mdx
620
+ └── searching-and-browsing.mdx
621
+ stories/
622
+ └── authentication/
623
+ └── a-user-should-be-able-to-register.mdx
624
+ ```
625
+
626
+ ### Model Summary
627
+
628
+ Generate comprehensive documentation of all registered models, including schema fields, sections, relationships, and defaults:
629
+
630
+ ```ts
631
+ const summary = await collection.generateModelSummary();
632
+ // Returns markdown documenting each model's schema, sections, relationships
633
+ ```
634
+
492
635
  ---
493
636
 
494
637
  ## Computed Properties
@@ -537,16 +680,141 @@ collection.use(timestampPlugin, { format: "iso" });
537
680
 
538
681
  ## CLI
539
682
 
540
- Contentbase ships with a CLI for common operations:
683
+ Contentbase ships with a CLI available as both `cnotes` and `contentbase`. See [CLI.md](./CLI.md) for the full reference with examples for every command.
684
+
685
+ ```bash
686
+ bun add contentbase
687
+
688
+ # Then use it via bunx, or in package.json scripts
689
+ bunx cnotes inspect
690
+ ```
691
+
692
+ ### Commands
693
+
694
+ ```bash
695
+ cnotes init [name] # scaffold a new project
696
+ cnotes create <Model> --title "..." # scaffold a new document (uses templates if available)
697
+ cnotes inspect # show models, sections, relationships, doc counts
698
+ cnotes validate [target] # validate documents ('all', a model name, or a path ID)
699
+ cnotes export # export collection as JSON
700
+ cnotes extract <glob> --sections "A, B" # extract specific sections from matching documents
701
+ cnotes summary # generate MODELS.md and TABLE-OF-CONTENTS.md
702
+ cnotes teach # output combined documentation for LLM context
703
+ cnotes action <name> # run a named action
704
+ cnotes text-search <pattern> # search file contents with pattern matching
705
+ cnotes serve # start HTTP server with REST API and doc serving
706
+ cnotes mcp # start MCP server for AI agent integration
707
+ cnotes console # interactive REPL with collection in scope
708
+ cnotes help # list available commands
709
+ ```
710
+
711
+ All commands accept `--contentFolder` to specify which folder contains your content. Defaults to `./docs`. You can also set it in `package.json`:
712
+
713
+ ```json
714
+ {
715
+ "contentbase": {
716
+ "contentFolder": "content"
717
+ }
718
+ }
719
+ ```
720
+
721
+ ### serve
722
+
723
+ Start an HTTP server that exposes a full REST API for the collection. Documents are available as JSON, rendered HTML, or raw markdown.
724
+
725
+ ```bash
726
+ # Start on default port 8000
727
+ cnotes serve
728
+
729
+ # Custom port, specific content folder
730
+ cnotes serve --port 9000 --contentFolder ./sdlc
731
+
732
+ # Read-only mode: disables all write endpoints (POST/PUT/PATCH/DELETE)
733
+ cnotes serve --read-only
734
+ ```
735
+
736
+ **Built-in endpoints:**
737
+
738
+ | Path | Description |
739
+ |------|-------------|
740
+ | `GET /api/inspect` | Collection overview |
741
+ | `GET /api/models` | All model definitions |
742
+ | `GET /api/documents` | List documents (filter with `?model=`) |
743
+ | `GET/POST/PUT/PATCH/DELETE /api/documents/:pathId` | Document CRUD |
744
+ | `GET /api/query?model=&where=&select=` | Query model instances (flat condition format) |
745
+ | `POST /api/query` | Query with JSON DSL body (MongoDB-style) |
746
+ | `GET /api/search?pattern=` | Full-text regex search across documents |
747
+ | `GET /api/text-search?pattern=` | File-level text search (`expanded=true` for line detail) |
748
+ | `GET /api/validate?pathId=` | Validate against schema |
749
+ | `GET/POST /api/actions` | List or execute actions |
750
+ | `GET /docs/:path.json\|.md\|.html` | Content-negotiated doc serving |
751
+ | `GET /openapi.json` | Auto-generated OpenAPI 3.1 spec |
752
+
753
+ When `--read-only` is passed, all mutating endpoints return `403 Forbidden`. This includes `POST /api/documents`, `PUT/PATCH/DELETE /api/documents/:pathId`, and `POST /api/actions`. Read endpoints are unaffected.
754
+
755
+ You can also add your own endpoints by placing files in an `endpoints/` directory. See [CLI.md](./CLI.md#user-defined-endpoints) for details.
756
+
757
+ ### mcp
758
+
759
+ Start a Model Context Protocol server for AI agent integration. Exposes tools, resources, and prompts for the collection.
541
760
 
542
761
  ```bash
543
- contentbase inspect # show collection info
544
- contentbase validate # validate all documents
545
- contentbase export # export collection as JSON
546
- contentbase create Story # scaffold a new document
547
- contentbase action publish # run a named action
762
+ cnotes mcp # stdio transport (for Claude Desktop, etc.)
763
+ cnotes mcp --transport http --port 3003 # HTTP transport
548
764
  ```
549
765
 
766
+ ### extract
767
+
768
+ The `extract` command outputs document titles, leading content, and only the requested sections -- combined into a single document suitable for creating new content:
769
+
770
+ ```bash
771
+ # Extract Acceptance Criteria from all stories
772
+ cnotes extract "stories/**/*" --sections "Acceptance Criteria"
773
+
774
+ # Combine epics into a single document with a title
775
+ cnotes extract "epics/*" -s "Stories" --title "All Stories"
776
+
777
+ # Multiple sections, include frontmatter, raw heading depths
778
+ cnotes extract "epics/*" -s "Stories, Notes" --frontmatter --no-normalize-headings
779
+ ```
780
+
781
+ Glob patterns are matched against document path IDs using [picomatch](https://github.com/micromatch/picomatch). Sections that don't exist in a document are silently skipped.
782
+
783
+ By default, heading depths are normalized so each document's content nests properly in the combined output. When `--title` is provided, it becomes the h1 and document titles shift to h2. Use `--no-normalize-headings` to preserve original heading depths.
784
+
785
+ ### create
786
+
787
+ The `create` command scaffolds new documents with smart defaults:
788
+
789
+ ```bash
790
+ cnotes create Story --title "User can logout"
791
+ cnotes create Epic --title "Payments" --meta.priority high
792
+ ```
793
+
794
+ If a template exists at `templates/<model>.md` (or `.mdx`) in your content directory, it's used as the base. Meta values are merged with this priority: Zod defaults < model defaults < template frontmatter < CLI `--meta.*` flags.
795
+
796
+ ### Model Discovery
797
+
798
+ The CLI uses a 3-tier system to find your models:
799
+
800
+ **Tier 1 — `index.ts`** (recommended): If your content directory has an `index.ts` that exports a `Collection` with models registered, the CLI uses it directly. This is what `contentbase init` scaffolds.
801
+
802
+ ```ts
803
+ // docs/index.ts
804
+ import { Collection, defineModel, z } from "contentbase";
805
+
806
+ const Post = defineModel("Post", {
807
+ meta: z.object({ draft: z.boolean().default(false) }),
808
+ });
809
+
810
+ export const collection = new Collection({ rootPath: import.meta.dir });
811
+ collection.register(Post);
812
+ ```
813
+
814
+ **Tier 2 — `models.ts`**: If no `index.ts` exists but a `models.ts` is found, the CLI imports it, detects model definitions from exports, and auto-registers them on a new Collection.
815
+
816
+ **Tier 3 — Auto-discovery**: If neither file exists, the CLI scans top-level subdirectories for markdown files and generates bare models from folder names (`epics/` → `Epic`). These models have no schema validation — useful for quick inspection, but you'll want a `models.ts` or `index.ts` for real use.
817
+
550
818
  ---
551
819
 
552
820
  ## API Reference
@@ -557,18 +825,26 @@ contentbase action publish # run a named action
557
825
  | --- | --- |
558
826
  | `Collection` | Loads and manages a directory of documents |
559
827
  | `Document` | A single Markdown/MDX file with AST operations |
560
- | `defineModel()` | Create a typed model definition |
828
+ | `defineModel()` | Create a typed model definition (accepts optional `description`, auto-generated if omitted) |
829
+ | `generateDescription()` | Generate a human-readable model description from its schema |
561
830
  | `section()` | Declare a section extraction |
562
831
  | `hasMany()` | Declare a one-to-many relationship |
563
832
  | `belongsTo()` | Declare a many-to-one relationship |
564
833
  | `parse()` | Parse a file path or markdown string into a queryable `ParsedDocument` |
565
834
  | `extractSections()` | Combine sections from multiple documents into one |
566
835
  | `CollectionQuery` | Fluent query builder for model instances |
836
+ | `queryDSLSchema` | Zod schema for validating JSON query DSL input |
837
+ | `parseWhereClause()` | Parse MongoDB-style where object into internal conditions |
838
+ | `executeQueryDSL()` | Execute a JSON query DSL against a collection |
567
839
  | `AstQuery` | MDAST query wrapper (select, visit, find) |
568
840
  | `NodeShortcuts` | Convenience getters for common AST nodes |
569
841
  | `createModelInstance()` | Low-level factory for model instances |
570
842
  | `validateDocument()` | Standalone validation function |
843
+ | `matchPattern()` | Express-style path pattern matching (`:param` syntax) |
844
+ | `matchPatterns()` | Try multiple patterns against a path, first match wins |
845
+ | `introspectMetaSchema()` | Extract field info (name, type, required, default) from a Zod schema |
571
846
  | `z` | Re-exported from Zod (no extra dependency needed) |
847
+ | `toString` | Re-exported from `mdast-util-to-string` |
572
848
 
573
849
  ---
574
850
 
package/bun.lock CHANGED
@@ -4,14 +4,16 @@
4
4
  "": {
5
5
  "name": "contentbase",
6
6
  "dependencies": {
7
- "citty": "^0.1.6",
8
7
  "gray-matter": "^4.0.3",
9
8
  "js-yaml": "^4.1.0",
10
9
  "mdast-util-mdxjs-esm": "^2.0.1",
11
10
  "mdast-util-to-markdown": "^2.1.2",
12
11
  "mdast-util-to-string": "^4.0.0",
12
+ "picomatch": "^4.0.3",
13
+ "rehype-stringify": "^10.0.1",
13
14
  "remark-gfm": "^4.0.0",
14
15
  "remark-parse": "^11.0.0",
16
+ "remark-rehype": "^11.1.2",
15
17
  "remark-stringify": "^11.0.0",
16
18
  "unified": "^11.0.5",
17
19
  "unist-util-find-after": "^5.0.0",
@@ -25,10 +27,17 @@
25
27
  "devDependencies": {
26
28
  "@types/js-yaml": "^4.0.9",
27
29
  "@types/mdast": "^4.0.4",
30
+ "@types/picomatch": "^4.0.2",
28
31
  "bun-types": "^1.1.0",
29
32
  "typescript": "^5.4.0",
30
33
  "vitest": "^1.6.0",
31
34
  },
35
+ "peerDependencies": {
36
+ "@soederpop/luca": ">=0.0.1",
37
+ },
38
+ "optionalPeers": [
39
+ "@soederpop/luca",
40
+ ],
32
41
  },
33
42
  },
34
43
  "packages": {
@@ -150,8 +159,12 @@
150
159
 
151
160
  "@types/node": ["@types/node@25.2.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-BkmoP5/FhRYek5izySdkOneRyXYN35I860MFAGupTdebyE66uZaR+bXLHq8k4DirE5DwQi3NuhvRU1jqTVwUrQ=="],
152
161
 
162
+ "@types/picomatch": ["@types/picomatch@4.0.2", "", {}, "sha512-qHHxQ+P9PysNEGbALT8f8YOSHW0KJu6l2xU8DYY0fu/EmGxXdVnuTLvFUvBgPJMSqXq29SYHveejeAha+4AYgA=="],
163
+
153
164
  "@types/unist": ["@types/unist@3.0.3", "", {}, "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q=="],
154
165
 
166
+ "@ungap/structured-clone": ["@ungap/structured-clone@1.3.0", "", {}, "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g=="],
167
+
155
168
  "@vitest/expect": ["@vitest/expect@1.6.1", "", { "dependencies": { "@vitest/spy": "1.6.1", "@vitest/utils": "1.6.1", "chai": "^4.3.10" } }, "sha512-jXL+9+ZNIJKruofqXuuTClf44eSpcHlgj3CiuNihUF3Ioujtmc0zIa3UJOW5RjDK1YLBJZnWBlPuqhYycLioog=="],
156
169
 
157
170
  "@vitest/runner": ["@vitest/runner@1.6.1", "", { "dependencies": { "@vitest/utils": "1.6.1", "p-limit": "^5.0.0", "pathe": "^1.1.1" } }, "sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA=="],
@@ -186,14 +199,16 @@
186
199
 
187
200
  "character-entities": ["character-entities@2.0.2", "", {}, "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ=="],
188
201
 
202
+ "character-entities-html4": ["character-entities-html4@2.1.0", "", {}, "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA=="],
203
+
204
+ "character-entities-legacy": ["character-entities-legacy@3.0.0", "", {}, "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ=="],
205
+
189
206
  "check-error": ["check-error@1.0.3", "", { "dependencies": { "get-func-name": "^2.0.2" } }, "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg=="],
190
207
 
191
- "citty": ["citty@0.1.6", "", { "dependencies": { "consola": "^3.2.3" } }, "sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ=="],
208
+ "comma-separated-tokens": ["comma-separated-tokens@2.0.3", "", {}, "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg=="],
192
209
 
193
210
  "confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="],
194
211
 
195
- "consola": ["consola@3.4.2", "", {}, "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA=="],
196
-
197
212
  "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
198
213
 
199
214
  "css-selector-parser": ["css-selector-parser@3.3.0", "", {}, "sha512-Y2asgMGFqJKF4fq4xHDSlFYIkeVfRsm69lQC1q9kbEsH5XtnINTMrweLkjYMeaUgiXBy/uvKeO/a1JHTNnmB2g=="],
@@ -232,6 +247,12 @@
232
247
 
233
248
  "gray-matter": ["gray-matter@4.0.3", "", { "dependencies": { "js-yaml": "^3.13.1", "kind-of": "^6.0.2", "section-matter": "^1.0.0", "strip-bom-string": "^1.0.0" } }, "sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q=="],
234
249
 
250
+ "hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="],
251
+
252
+ "hast-util-whitespace": ["hast-util-whitespace@3.0.0", "", { "dependencies": { "@types/hast": "^3.0.0" } }, "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw=="],
253
+
254
+ "html-void-elements": ["html-void-elements@3.0.0", "", {}, "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg=="],
255
+
235
256
  "human-signals": ["human-signals@5.0.0", "", {}, "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ=="],
236
257
 
237
258
  "is-extendable": ["is-extendable@0.1.1", "", {}, "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw=="],
@@ -278,6 +299,8 @@
278
299
 
279
300
  "mdast-util-phrasing": ["mdast-util-phrasing@4.1.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "unist-util-is": "^6.0.0" } }, "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w=="],
280
301
 
302
+ "mdast-util-to-hast": ["mdast-util-to-hast@13.2.1", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@ungap/structured-clone": "^1.0.0", "devlop": "^1.0.0", "micromark-util-sanitize-uri": "^2.0.0", "trim-lines": "^3.0.0", "unist-util-position": "^5.0.0", "unist-util-visit": "^5.0.0", "vfile": "^6.0.0" } }, "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA=="],
303
+
281
304
  "mdast-util-to-markdown": ["mdast-util-to-markdown@2.1.2", "", { "dependencies": { "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "longest-streak": "^3.0.0", "mdast-util-phrasing": "^4.0.0", "mdast-util-to-string": "^4.0.0", "micromark-util-classify-character": "^2.0.0", "micromark-util-decode-string": "^2.0.0", "unist-util-visit": "^5.0.0", "zwitch": "^2.0.0" } }, "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA=="],
282
305
 
283
306
  "mdast-util-to-string": ["mdast-util-to-string@4.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0" } }, "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg=="],
@@ -364,18 +387,26 @@
364
387
 
365
388
  "picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
366
389
 
390
+ "picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
391
+
367
392
  "pkg-types": ["pkg-types@1.3.1", "", { "dependencies": { "confbox": "^0.1.8", "mlly": "^1.7.4", "pathe": "^2.0.1" } }, "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ=="],
368
393
 
369
394
  "postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
370
395
 
371
396
  "pretty-format": ["pretty-format@29.7.0", "", { "dependencies": { "@jest/schemas": "^29.6.3", "ansi-styles": "^5.0.0", "react-is": "^18.0.0" } }, "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ=="],
372
397
 
398
+ "property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="],
399
+
373
400
  "react-is": ["react-is@18.3.1", "", {}, "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="],
374
401
 
402
+ "rehype-stringify": ["rehype-stringify@10.0.1", "", { "dependencies": { "@types/hast": "^3.0.0", "hast-util-to-html": "^9.0.0", "unified": "^11.0.0" } }, "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA=="],
403
+
375
404
  "remark-gfm": ["remark-gfm@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-gfm": "^3.0.0", "micromark-extension-gfm": "^3.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg=="],
376
405
 
377
406
  "remark-parse": ["remark-parse@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-from-markdown": "^2.0.0", "micromark-util-types": "^2.0.0", "unified": "^11.0.0" } }, "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA=="],
378
407
 
408
+ "remark-rehype": ["remark-rehype@11.1.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "mdast-util-to-hast": "^13.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw=="],
409
+
379
410
  "remark-stringify": ["remark-stringify@11.0.0", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-to-markdown": "^2.0.0", "unified": "^11.0.0" } }, "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw=="],
380
411
 
381
412
  "rollup": ["rollup@4.57.1", "", { "dependencies": { "@types/estree": "1.0.8" }, "optionalDependencies": { "@rollup/rollup-android-arm-eabi": "4.57.1", "@rollup/rollup-android-arm64": "4.57.1", "@rollup/rollup-darwin-arm64": "4.57.1", "@rollup/rollup-darwin-x64": "4.57.1", "@rollup/rollup-freebsd-arm64": "4.57.1", "@rollup/rollup-freebsd-x64": "4.57.1", "@rollup/rollup-linux-arm-gnueabihf": "4.57.1", "@rollup/rollup-linux-arm-musleabihf": "4.57.1", "@rollup/rollup-linux-arm64-gnu": "4.57.1", "@rollup/rollup-linux-arm64-musl": "4.57.1", "@rollup/rollup-linux-loong64-gnu": "4.57.1", "@rollup/rollup-linux-loong64-musl": "4.57.1", "@rollup/rollup-linux-ppc64-gnu": "4.57.1", "@rollup/rollup-linux-ppc64-musl": "4.57.1", "@rollup/rollup-linux-riscv64-gnu": "4.57.1", "@rollup/rollup-linux-riscv64-musl": "4.57.1", "@rollup/rollup-linux-s390x-gnu": "4.57.1", "@rollup/rollup-linux-x64-gnu": "4.57.1", "@rollup/rollup-linux-x64-musl": "4.57.1", "@rollup/rollup-openbsd-x64": "4.57.1", "@rollup/rollup-openharmony-arm64": "4.57.1", "@rollup/rollup-win32-arm64-msvc": "4.57.1", "@rollup/rollup-win32-ia32-msvc": "4.57.1", "@rollup/rollup-win32-x64-gnu": "4.57.1", "@rollup/rollup-win32-x64-msvc": "4.57.1", "fsevents": "~2.3.2" }, "bin": { "rollup": "dist/bin/rollup" } }, "sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A=="],
@@ -392,12 +423,16 @@
392
423
 
393
424
  "source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
394
425
 
426
+ "space-separated-tokens": ["space-separated-tokens@2.0.2", "", {}, "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q=="],
427
+
395
428
  "sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="],
396
429
 
397
430
  "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="],
398
431
 
399
432
  "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="],
400
433
 
434
+ "stringify-entities": ["stringify-entities@4.0.4", "", { "dependencies": { "character-entities-html4": "^2.0.0", "character-entities-legacy": "^3.0.0" } }, "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg=="],
435
+
401
436
  "strip-bom-string": ["strip-bom-string@1.0.0", "", {}, "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g=="],
402
437
 
403
438
  "strip-final-newline": ["strip-final-newline@3.0.0", "", {}, "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw=="],
@@ -410,6 +445,8 @@
410
445
 
411
446
  "tinyspy": ["tinyspy@2.2.1", "", {}, "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A=="],
412
447
 
448
+ "trim-lines": ["trim-lines@3.0.1", "", {}, "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg=="],
449
+
413
450
  "trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="],
414
451
 
415
452
  "type-detect": ["type-detect@4.1.0", "", {}, "sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw=="],
@@ -432,6 +469,8 @@
432
469
 
433
470
  "unist-util-is": ["unist-util-is@6.0.1", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g=="],
434
471
 
472
+ "unist-util-position": ["unist-util-position@5.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA=="],
473
+
435
474
  "unist-util-select": ["unist-util-select@5.1.0", "", { "dependencies": { "@types/unist": "^3.0.0", "css-selector-parser": "^3.0.0", "devlop": "^1.1.0", "nth-check": "^2.0.0", "zwitch": "^2.0.0" } }, "sha512-4A5mfokSHG/rNQ4g7gSbdEs+H586xyd24sdJqF1IWamqrLHvYb+DH48fzxowyOhOfK7YSqX+XlCojAyuuyyT2A=="],
436
475
 
437
476
  "unist-util-stringify-position": ["unist-util-stringify-position@4.0.0", "", { "dependencies": { "@types/unist": "^3.0.0" } }, "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ=="],
package/dist/cnotes ADDED
Binary file