contentbase 0.0.1 → 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 (97) 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 +406 -13
  7. package/bun.lock +45 -6
  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 +14 -4
  14. package/public/web-demo/index.html +813 -0
  15. package/scripts/examples/01-collection-setup.ts +46 -0
  16. package/scripts/examples/02-querying.ts +67 -0
  17. package/scripts/examples/03-sections.ts +36 -0
  18. package/scripts/examples/04-relationships.ts +54 -0
  19. package/scripts/examples/05-document-api.ts +54 -0
  20. package/scripts/examples/06-extract-sections.ts +55 -0
  21. package/scripts/examples/07-validation.ts +46 -0
  22. package/scripts/examples/08-serialization.ts +51 -0
  23. package/scripts/examples/lib/format.ts +87 -0
  24. package/scripts/examples/lib/setup.ts +21 -0
  25. package/scripts/examples/run-all.ts +43 -0
  26. package/showcases/node_modules/.cache/.repl_history +3 -0
  27. package/showcases/vinyl-collection/artists/nina-simone.mdx +1 -1
  28. package/src/__tests__/semantic-search.integration.test.ts +284 -0
  29. package/src/api/endpoints/actions.ts +34 -0
  30. package/src/api/endpoints/doc.ts +187 -0
  31. package/src/api/endpoints/docs-index.ts +26 -0
  32. package/src/api/endpoints/document.ts +171 -0
  33. package/src/api/endpoints/documents.ts +71 -0
  34. package/src/api/endpoints/inspect.ts +16 -0
  35. package/src/api/endpoints/models.ts +10 -0
  36. package/src/api/endpoints/query.ts +88 -0
  37. package/src/api/endpoints/root.ts +7 -0
  38. package/src/api/endpoints/search-reindex.ts +65 -0
  39. package/src/api/endpoints/search-status.ts +55 -0
  40. package/src/api/endpoints/search.ts +104 -0
  41. package/src/api/endpoints/semantic-search.ts +120 -0
  42. package/src/api/endpoints/text-search.ts +63 -0
  43. package/src/api/endpoints/validate.ts +34 -0
  44. package/src/api/helpers.ts +97 -0
  45. package/src/base-model.ts +12 -0
  46. package/src/cli/commands/action.ts +82 -44
  47. package/src/cli/commands/console.ts +124 -0
  48. package/src/cli/commands/create.ts +179 -53
  49. package/src/cli/commands/embed.ts +323 -0
  50. package/src/cli/commands/export.ts +58 -24
  51. package/src/cli/commands/extract.ts +174 -0
  52. package/src/cli/commands/help.ts +81 -0
  53. package/src/cli/commands/index.ts +17 -0
  54. package/src/cli/commands/init.ts +72 -48
  55. package/src/cli/commands/inspect.ts +56 -46
  56. package/src/cli/commands/mcp.ts +1219 -0
  57. package/src/cli/commands/search.ts +285 -0
  58. package/src/cli/commands/serve.ts +348 -0
  59. package/src/cli/commands/summary.ts +60 -0
  60. package/src/cli/commands/teach.ts +86 -0
  61. package/src/cli/commands/text-search.ts +134 -0
  62. package/src/cli/commands/validate.ts +126 -64
  63. package/src/cli/index.ts +88 -19
  64. package/src/cli/load-collection.ts +144 -17
  65. package/src/cli/registry.ts +28 -0
  66. package/src/collection.ts +455 -6
  67. package/src/define-model.ts +104 -7
  68. package/src/document.ts +47 -1
  69. package/src/extract-sections.ts +222 -0
  70. package/src/index.ts +20 -2
  71. package/src/model-instance.ts +35 -5
  72. package/src/node-shortcuts.ts +1 -1
  73. package/src/query/collection-query.ts +96 -9
  74. package/src/query/index.ts +7 -0
  75. package/src/query/query-dsl.ts +259 -0
  76. package/src/relationships/has-many.ts +39 -0
  77. package/src/relationships/index.ts +7 -2
  78. package/src/section.ts +2 -0
  79. package/src/types.ts +24 -2
  80. package/src/utils/index.ts +1 -0
  81. package/src/utils/match-pattern.ts +65 -0
  82. package/src/validator.ts +18 -1
  83. package/test/collection.test.ts +118 -2
  84. package/test/extract-sections.test.ts +356 -0
  85. package/test/fixtures/sdlc/MODELS.md +106 -0
  86. package/test/fixtures/sdlc/SKILL.md +404 -0
  87. package/test/fixtures/sdlc/index.ts +9 -0
  88. package/test/fixtures/sdlc/models.ts +8 -6
  89. package/test/fixtures/sdlc/stories/authentication/a-user-should-be-able-to-login.mdx +20 -0
  90. package/test/fixtures/sdlc/templates/epic.md +23 -0
  91. package/test/fixtures/sdlc/templates/story.md +19 -0
  92. package/test/pattern.test.ts +191 -0
  93. package/test/query-dsl.test.ts +431 -0
  94. package/test/query.test.ts +29 -0
  95. package/test/relationships.test.ts +130 -0
  96. package/test/section.test.ts +65 -4
  97. package/test/table-of-contents.test.ts +135 -0
@@ -1,30 +1,17 @@
1
- import { defineCommand } from "citty";
2
- import fs from "fs/promises";
3
- import path from "path";
4
-
5
- export default defineCommand({
6
- meta: {
7
- name: "init",
8
- description: "Initialize a new contentbase project",
9
- },
10
- args: {
11
- name: {
12
- type: "positional",
13
- description: "Project name",
14
- required: false,
15
- },
16
- },
17
- async run({ args }) {
18
- const name = (args.name as string) || "my-content";
19
- const dir = path.resolve(process.cwd(), name);
20
-
21
- await fs.mkdir(dir, { recursive: true });
22
- await fs.mkdir(path.join(dir, "posts"), { recursive: true });
23
-
24
- // Create a sample model file
25
- await fs.writeFile(
26
- path.join(dir, "models.ts"),
27
- `import { defineModel, z } from "contentbase";
1
+ import fs from 'fs/promises'
2
+ import path from 'path'
3
+ import { commands } from '../registry.js'
4
+
5
+ async function handler(_options: any, context: { container: any }) {
6
+ const name = (context.container.argv._[1] as string) || 'my-content'
7
+ const dir = path.resolve(process.cwd(), name)
8
+
9
+ await fs.mkdir(dir, { recursive: true })
10
+ await fs.mkdir(path.join(dir, 'posts'), { recursive: true })
11
+
12
+ await fs.writeFile(
13
+ path.join(dir, 'models.ts'),
14
+ `import { defineModel, z } from "contentbase";
28
15
 
29
16
  export const Post = defineModel("Post", {
30
17
  prefix: "posts",
@@ -34,13 +21,12 @@ export const Post = defineModel("Post", {
34
21
  }),
35
22
  });
36
23
  `,
37
- "utf8"
38
- );
24
+ 'utf8'
25
+ )
39
26
 
40
- // Create a sample post
41
- await fs.writeFile(
42
- path.join(dir, "posts", "hello-world.mdx"),
43
- `---
27
+ await fs.writeFile(
28
+ path.join(dir, 'posts', 'hello-world.md'),
29
+ `---
44
30
  status: draft
45
31
  author: me
46
32
  ---
@@ -49,13 +35,12 @@ author: me
49
35
 
50
36
  Welcome to your contentbase project!
51
37
  `,
52
- "utf8"
53
- );
38
+ 'utf8'
39
+ )
54
40
 
55
- // Create index.ts
56
- await fs.writeFile(
57
- path.join(dir, "index.ts"),
58
- `import { Collection } from "contentbase";
41
+ await fs.writeFile(
42
+ path.join(dir, 'index.ts'),
43
+ `import { Collection } from "contentbase";
59
44
  import { Post } from "./models";
60
45
 
61
46
  export const collection = new Collection({
@@ -64,12 +49,51 @@ export const collection = new Collection({
64
49
 
65
50
  collection.register(Post);
66
51
  `,
67
- "utf8"
68
- );
69
-
70
- console.log(`Created contentbase project at ${dir}`);
71
- console.log(` ${name}/models.ts`);
72
- console.log(` ${name}/index.ts`);
73
- console.log(` ${name}/posts/hello-world.mdx`);
74
- },
75
- });
52
+ 'utf8'
53
+ )
54
+
55
+ console.log(`Created contentbase project at ${dir}`)
56
+ console.log(` ${name}/models.ts`)
57
+ console.log(` ${name}/index.ts`)
58
+ console.log(` ${name}/posts/hello-world.md`)
59
+ }
60
+
61
+ commands.register('init', {
62
+ description: 'Initialize a new contentbase project',
63
+ help: `# cnotes init
64
+
65
+ Scaffold a new contentbase project with a sample model and document.
66
+
67
+ ## Usage
68
+
69
+ \`\`\`
70
+ cnotes init [name]
71
+ \`\`\`
72
+
73
+ ## Arguments
74
+
75
+ | Argument | Description | Default |
76
+ |----------|-------------|---------|
77
+ | \`name\` | Directory name for the project | \`my-content\` |
78
+
79
+ ## What It Creates
80
+
81
+ - \`<name>/models.ts\` — Model definitions with a sample Post model
82
+ - \`<name>/index.ts\` — Collection entry point
83
+ - \`<name>/posts/hello-world.md\` — Sample document
84
+
85
+ ## Examples
86
+
87
+ \`\`\`bash
88
+ # Create with default name
89
+ cnotes init
90
+
91
+ # Create with custom name
92
+ cnotes init docs
93
+
94
+ # Create in a subdirectory
95
+ cnotes init content/blog
96
+ \`\`\`
97
+ `,
98
+ handler,
99
+ })
@@ -1,46 +1,56 @@
1
- import { defineCommand } from "citty";
2
- import { loadCollection } from "../load-collection";
3
-
4
- export default defineCommand({
5
- meta: {
6
- name: "inspect",
7
- description: "Display collection info and registered models",
8
- },
9
- args: {
10
- rootPath: {
11
- type: "string",
12
- description: "Root path for the collection",
13
- alias: "r",
14
- },
15
- },
16
- async run({ args }) {
17
- const collection = await loadCollection({
18
- rootPath: args.rootPath as string | undefined,
19
- });
20
-
21
- console.log(`Collection: ${collection.name}`);
22
- console.log(`Root: ${collection.rootPath}`);
23
- console.log(`Items: ${collection.available.length}`);
24
- console.log();
25
-
26
- for (const def of collection.modelDefinitions) {
27
- const matchingItems = collection.available.filter((id) =>
28
- id.startsWith(def.prefix)
29
- );
30
- console.log(` Model: ${def.name}`);
31
- console.log(` Prefix: ${def.prefix}`);
32
- console.log(
33
- ` Sections: ${Object.keys(def.sections).join(", ") || "(none)"}`
34
- );
35
- console.log(
36
- ` Relationships: ${Object.keys(def.relationships).join(", ") || "(none)"}`
37
- );
38
- console.log(` Documents: ${matchingItems.length}`);
39
- console.log();
40
- }
41
-
42
- if (collection.availableActions.length > 0) {
43
- console.log(`Actions: ${collection.availableActions.join(", ")}`);
44
- }
45
- },
46
- });
1
+ import { z } from 'zod'
2
+ import { commands } from '../registry.js'
3
+ import { loadCollection } from '../load-collection.js'
4
+
5
+ const argsSchema = z.object({
6
+ contentFolder: z.string().optional(),
7
+ })
8
+
9
+ async function handler(options: z.infer<typeof argsSchema>) {
10
+ const collection = await loadCollection({
11
+ contentFolder: options.contentFolder,
12
+ })
13
+
14
+ console.log(collection.generateModelSummary())
15
+ }
16
+
17
+ commands.register('inspect', {
18
+ description: 'Display collection info and registered models',
19
+ help: `# cnotes inspect
20
+
21
+ Display a summary of the collection: registered models, their fields, sections, relationships, and document counts.
22
+
23
+ ## Usage
24
+
25
+ \`\`\`
26
+ cnotes inspect [options]
27
+ \`\`\`
28
+
29
+ ## Options
30
+
31
+ | Option | Description |
32
+ |--------|-------------|
33
+ | \`--contentFolder\` | Path to content folder |
34
+
35
+ ## Output
36
+
37
+ Shows for each model:
38
+ - Prefix and document count
39
+ - Meta field definitions (name, type, required, default)
40
+ - Section headings
41
+ - Relationships (belongsTo, hasMany)
42
+ - Computed properties and named scopes
43
+
44
+ ## Examples
45
+
46
+ \`\`\`bash
47
+ # Inspect current directory's collection
48
+ cnotes inspect
49
+
50
+ # Inspect a specific content folder
51
+ cnotes inspect --contentFolder test/fixtures/sdlc
52
+ \`\`\`
53
+ `,
54
+ argsSchema,
55
+ handler,
56
+ })