contentbase 0.2.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.
- package/CNAME +1 -0
- package/LAUNCH-PLAN.md +419 -0
- package/dist/adapters/node-fs.d.ts +17 -0
- package/dist/adapters/node-fs.d.ts.map +1 -0
- package/dist/adapters/node-fs.js +71 -0
- package/dist/adapters/node-fs.js.map +1 -0
- package/dist/ast-query.d.ts +44 -0
- package/dist/ast-query.d.ts.map +1 -0
- package/dist/ast-query.js +95 -0
- package/dist/ast-query.js.map +1 -0
- package/dist/base-model.d.ts +8 -0
- package/dist/base-model.d.ts.map +1 -0
- package/dist/base-model.js +12 -0
- package/dist/base-model.js.map +1 -0
- package/dist/cli/commands/action.d.ts +2 -0
- package/dist/cli/commands/action.d.ts.map +1 -0
- package/dist/cli/commands/action.js +73 -0
- package/dist/cli/commands/action.js.map +1 -0
- package/dist/cli/commands/api/endpoints/actions.d.ts +13 -0
- package/dist/cli/commands/api/endpoints/actions.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/actions.js +28 -0
- package/dist/cli/commands/api/endpoints/actions.js.map +1 -0
- package/dist/cli/commands/api/endpoints/doc.d.ts +5 -0
- package/dist/cli/commands/api/endpoints/doc.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/doc.js +186 -0
- package/dist/cli/commands/api/endpoints/doc.js.map +1 -0
- package/dist/cli/commands/api/endpoints/docs-index.d.ts +8 -0
- package/dist/cli/commands/api/endpoints/docs-index.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/docs-index.js +23 -0
- package/dist/cli/commands/api/endpoints/docs-index.js.map +1 -0
- package/dist/cli/commands/api/endpoints/document.d.ts +47 -0
- package/dist/cli/commands/api/endpoints/document.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/document.js +146 -0
- package/dist/cli/commands/api/endpoints/document.js.map +1 -0
- package/dist/cli/commands/api/endpoints/documents.d.ts +35 -0
- package/dist/cli/commands/api/endpoints/documents.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/documents.js +56 -0
- package/dist/cli/commands/api/endpoints/documents.js.map +1 -0
- package/dist/cli/commands/api/endpoints/index.d.ts +22 -0
- package/dist/cli/commands/api/endpoints/index.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/index.js +38 -0
- package/dist/cli/commands/api/endpoints/index.js.map +1 -0
- package/dist/cli/commands/api/endpoints/inspect.d.ts +10 -0
- package/dist/cli/commands/api/endpoints/inspect.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/inspect.js +15 -0
- package/dist/cli/commands/api/endpoints/inspect.js.map +1 -0
- package/dist/cli/commands/api/endpoints/models.d.ts +5 -0
- package/dist/cli/commands/api/endpoints/models.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/models.js +9 -0
- package/dist/cli/commands/api/endpoints/models.js.map +1 -0
- package/dist/cli/commands/api/endpoints/query.d.ts +40 -0
- package/dist/cli/commands/api/endpoints/query.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/query.js +106 -0
- package/dist/cli/commands/api/endpoints/query.js.map +1 -0
- package/dist/cli/commands/api/endpoints/root.d.ts +5 -0
- package/dist/cli/commands/api/endpoints/root.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/root.js +7 -0
- package/dist/cli/commands/api/endpoints/root.js.map +1 -0
- package/dist/cli/commands/api/endpoints/search-reindex.d.ts +10 -0
- package/dist/cli/commands/api/endpoints/search-reindex.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/search-reindex.js +38 -0
- package/dist/cli/commands/api/endpoints/search-reindex.js.map +1 -0
- package/dist/cli/commands/api/endpoints/search-status.d.ts +7 -0
- package/dist/cli/commands/api/endpoints/search-status.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/search-status.js +33 -0
- package/dist/cli/commands/api/endpoints/search-status.js.map +1 -0
- package/dist/cli/commands/api/endpoints/search.d.ts +24 -0
- package/dist/cli/commands/api/endpoints/search.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/search.js +61 -0
- package/dist/cli/commands/api/endpoints/search.js.map +1 -0
- package/dist/cli/commands/api/endpoints/semantic-search.d.ts +28 -0
- package/dist/cli/commands/api/endpoints/semantic-search.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/semantic-search.js +76 -0
- package/dist/cli/commands/api/endpoints/semantic-search.js.map +1 -0
- package/dist/cli/commands/api/endpoints/text-search.d.ts +17 -0
- package/dist/cli/commands/api/endpoints/text-search.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/text-search.js +55 -0
- package/dist/cli/commands/api/endpoints/text-search.js.map +1 -0
- package/dist/cli/commands/api/endpoints/validate.d.ts +12 -0
- package/dist/cli/commands/api/endpoints/validate.d.ts.map +1 -0
- package/dist/cli/commands/api/endpoints/validate.js +27 -0
- package/dist/cli/commands/api/endpoints/validate.js.map +1 -0
- package/dist/cli/commands/api/helpers.d.ts +8 -0
- package/dist/cli/commands/api/helpers.d.ts.map +1 -0
- package/dist/cli/commands/api/helpers.js +89 -0
- package/dist/cli/commands/api/helpers.js.map +1 -0
- package/dist/cli/commands/console.d.ts +2 -0
- package/dist/cli/commands/console.d.ts.map +1 -0
- package/dist/cli/commands/console.js +117 -0
- package/dist/cli/commands/console.js.map +1 -0
- package/dist/cli/commands/create.d.ts +2 -0
- package/dist/cli/commands/create.d.ts.map +1 -0
- package/dist/cli/commands/create.js +185 -0
- package/dist/cli/commands/create.js.map +1 -0
- package/dist/cli/commands/embed.d.ts +2 -0
- package/dist/cli/commands/embed.d.ts.map +1 -0
- package/dist/cli/commands/embed.js +231 -0
- package/dist/cli/commands/embed.js.map +1 -0
- package/dist/cli/commands/export.d.ts +2 -0
- package/dist/cli/commands/export.d.ts.map +1 -0
- package/dist/cli/commands/export.js +55 -0
- package/dist/cli/commands/export.js.map +1 -0
- package/dist/cli/commands/extract.d.ts +2 -0
- package/dist/cli/commands/extract.d.ts.map +1 -0
- package/dist/cli/commands/extract.js +149 -0
- package/dist/cli/commands/extract.js.map +1 -0
- package/dist/cli/commands/help.d.ts +2 -0
- package/dist/cli/commands/help.d.ts.map +1 -0
- package/dist/cli/commands/help.js +58 -0
- package/dist/cli/commands/help.js.map +1 -0
- package/dist/cli/commands/index.d.ts +18 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +19 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +82 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/inspect.d.ts +2 -0
- package/dist/cli/commands/inspect.d.ts.map +1 -0
- package/dist/cli/commands/inspect.js +53 -0
- package/dist/cli/commands/inspect.js.map +1 -0
- package/dist/cli/commands/mcp.d.ts +2 -0
- package/dist/cli/commands/mcp.d.ts.map +1 -0
- package/dist/cli/commands/mcp.js +92 -0
- package/dist/cli/commands/mcp.js.map +1 -0
- package/dist/cli/commands/search.d.ts +2 -0
- package/dist/cli/commands/search.d.ts.map +1 -0
- package/dist/cli/commands/search.js +212 -0
- package/dist/cli/commands/search.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +2 -0
- package/dist/cli/commands/serve.d.ts.map +1 -0
- package/dist/cli/commands/serve.js +298 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/summary.d.ts +2 -0
- package/dist/cli/commands/summary.d.ts.map +1 -0
- package/dist/cli/commands/summary.js +58 -0
- package/dist/cli/commands/summary.js.map +1 -0
- package/dist/cli/commands/teach.d.ts +2 -0
- package/dist/cli/commands/teach.d.ts.map +1 -0
- package/dist/cli/commands/teach.js +80 -0
- package/dist/cli/commands/teach.js.map +1 -0
- package/dist/cli/commands/text-search.d.ts +2 -0
- package/dist/cli/commands/text-search.d.ts.map +1 -0
- package/dist/cli/commands/text-search.js +125 -0
- package/dist/cli/commands/text-search.js.map +1 -0
- package/dist/cli/commands/update.d.ts +2 -0
- package/dist/cli/commands/update.d.ts.map +1 -0
- package/dist/cli/commands/update.js +167 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +2 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +129 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +84 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/load-collection.d.ts +7 -0
- package/dist/cli/load-collection.d.ts.map +1 -0
- package/dist/cli/load-collection.js +201 -0
- package/dist/cli/load-collection.js.map +1 -0
- package/dist/cli/registry.d.ts +17 -0
- package/dist/cli/registry.d.ts.map +1 -0
- package/dist/cli/registry.js +16 -0
- package/dist/cli/registry.js.map +1 -0
- package/dist/cnotes +0 -0
- package/dist/collection.d.ts +145 -0
- package/dist/collection.d.ts.map +1 -0
- package/dist/collection.js +684 -0
- package/dist/collection.js.map +1 -0
- package/dist/define-model.d.ts +45 -0
- package/dist/define-model.d.ts.map +1 -0
- package/dist/define-model.js +106 -0
- package/dist/define-model.js.map +1 -0
- package/dist/document.d.ts +119 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +418 -0
- package/dist/document.js.map +1 -0
- package/dist/extract-sections.d.ts +46 -0
- package/dist/extract-sections.d.ts.map +1 -0
- package/dist/extract-sections.js +153 -0
- package/dist/extract-sections.js.map +1 -0
- package/dist/index.d.ts +28 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/helpers.d.ts +14 -0
- package/dist/mcp/helpers.d.ts.map +1 -0
- package/dist/mcp/helpers.js +7 -0
- package/dist/mcp/helpers.js.map +1 -0
- package/dist/mcp/model-info.d.ts +2 -0
- package/dist/mcp/model-info.d.ts.map +1 -0
- package/dist/mcp/model-info.js +94 -0
- package/dist/mcp/model-info.js.map +1 -0
- package/dist/mcp/prompts.d.ts +2 -0
- package/dist/mcp/prompts.d.ts.map +1 -0
- package/dist/mcp/prompts.js +180 -0
- package/dist/mcp/prompts.js.map +1 -0
- package/dist/mcp/readme.d.ts +2 -0
- package/dist/mcp/readme.d.ts.map +1 -0
- package/dist/mcp/readme.js +71 -0
- package/dist/mcp/readme.js.map +1 -0
- package/dist/mcp/resources.d.ts +2 -0
- package/dist/mcp/resources.d.ts.map +1 -0
- package/dist/mcp/resources.js +85 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/server.d.ts +18 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +83 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/mutation.d.ts +2 -0
- package/dist/mcp/tools/mutation.d.ts.map +1 -0
- package/dist/mcp/tools/mutation.js +155 -0
- package/dist/mcp/tools/mutation.js.map +1 -0
- package/dist/mcp/tools/query.d.ts +2 -0
- package/dist/mcp/tools/query.d.ts.map +1 -0
- package/dist/mcp/tools/query.js +130 -0
- package/dist/mcp/tools/query.js.map +1 -0
- package/dist/mcp/tools/search.d.ts +2 -0
- package/dist/mcp/tools/search.d.ts.map +1 -0
- package/dist/mcp/tools/search.js +168 -0
- package/dist/mcp/tools/search.js.map +1 -0
- package/dist/model-instance.d.ts +11 -0
- package/dist/model-instance.d.ts.map +1 -0
- package/dist/model-instance.js +208 -0
- package/dist/model-instance.js.map +1 -0
- package/dist/node-shortcuts.d.ts +25 -0
- package/dist/node-shortcuts.d.ts.map +1 -0
- package/dist/node-shortcuts.js +67 -0
- package/dist/node-shortcuts.js.map +1 -0
- package/dist/parse.d.ts +45 -0
- package/dist/parse.d.ts.map +1 -0
- package/dist/parse.js +98 -0
- package/dist/parse.js.map +1 -0
- package/dist/query/collection-query.d.ts +39 -0
- package/dist/query/collection-query.d.ts.map +1 -0
- package/dist/query/collection-query.js +184 -0
- package/dist/query/collection-query.js.map +1 -0
- package/dist/query/index.d.ts +8 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +5 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/operators.d.ts +3 -0
- package/dist/query/operators.d.ts.map +1 -0
- package/dist/query/operators.js +18 -0
- package/dist/query/operators.js.map +1 -0
- package/dist/query/query-builder.d.ts +34 -0
- package/dist/query/query-builder.d.ts.map +1 -0
- package/dist/query/query-builder.js +84 -0
- package/dist/query/query-builder.js.map +1 -0
- package/dist/query/query-dsl.d.ts +36 -0
- package/dist/query/query-dsl.d.ts.map +1 -0
- package/dist/query/query-dsl.js +195 -0
- package/dist/query/query-dsl.js.map +1 -0
- package/dist/relationships/belongs-to.d.ts +9 -0
- package/dist/relationships/belongs-to.d.ts.map +1 -0
- package/dist/relationships/belongs-to.js +34 -0
- package/dist/relationships/belongs-to.js.map +1 -0
- package/dist/relationships/has-many.d.ts +23 -0
- package/dist/relationships/has-many.d.ts.map +1 -0
- package/dist/relationships/has-many.js +136 -0
- package/dist/relationships/has-many.js.map +1 -0
- package/dist/relationships/index.d.ts +26 -0
- package/dist/relationships/index.d.ts.map +1 -0
- package/dist/relationships/index.js +32 -0
- package/dist/relationships/index.js.map +1 -0
- package/dist/relationships/types.d.ts +2 -0
- package/dist/relationships/types.d.ts.map +1 -0
- package/dist/relationships/types.js +2 -0
- package/dist/relationships/types.js.map +1 -0
- package/dist/search/document-inputs.d.ts +30 -0
- package/dist/search/document-inputs.d.ts.map +1 -0
- package/dist/search/document-inputs.js +52 -0
- package/dist/search/document-inputs.js.map +1 -0
- package/dist/search/luca-semantic-search.d.ts +27 -0
- package/dist/search/luca-semantic-search.d.ts.map +1 -0
- package/dist/search/luca-semantic-search.js +56 -0
- package/dist/search/luca-semantic-search.js.map +1 -0
- package/dist/section.d.ts +21 -0
- package/dist/section.d.ts.map +1 -0
- package/dist/section.js +21 -0
- package/dist/section.js.map +1 -0
- package/dist/types.d.ts +185 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/index.d.ts +9 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +8 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/inflect.d.ts +6 -0
- package/dist/utils/inflect.d.ts.map +1 -0
- package/dist/utils/inflect.js +75 -0
- package/dist/utils/inflect.js.map +1 -0
- package/dist/utils/match-pattern.d.ts +25 -0
- package/dist/utils/match-pattern.d.ts.map +1 -0
- package/dist/utils/match-pattern.js +52 -0
- package/dist/utils/match-pattern.js.map +1 -0
- package/dist/utils/normalize-headings.d.ts +8 -0
- package/dist/utils/normalize-headings.d.ts.map +1 -0
- package/dist/utils/normalize-headings.js +19 -0
- package/dist/utils/normalize-headings.js.map +1 -0
- package/dist/utils/parse-table.d.ts +7 -0
- package/dist/utils/parse-table.d.ts.map +1 -0
- package/dist/utils/parse-table.js +17 -0
- package/dist/utils/parse-table.js.map +1 -0
- package/dist/utils/read-directory.d.ts +5 -0
- package/dist/utils/read-directory.d.ts.map +1 -0
- package/dist/utils/read-directory.js +29 -0
- package/dist/utils/read-directory.js.map +1 -0
- package/dist/utils/stringify-ast.d.ts +6 -0
- package/dist/utils/stringify-ast.d.ts.map +1 -0
- package/dist/utils/stringify-ast.js +8 -0
- package/dist/utils/stringify-ast.js.map +1 -0
- package/dist/utils/strip-markdown.d.ts +11 -0
- package/dist/utils/strip-markdown.d.ts.map +1 -0
- package/dist/utils/strip-markdown.js +48 -0
- package/dist/utils/strip-markdown.js.map +1 -0
- package/dist/validator.d.ts +10 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +55 -0
- package/dist/validator.js.map +1 -0
- package/index.html +1636 -0
- package/package.json +5 -4
- package/src/adapters/node-fs.ts +80 -0
- package/src/cli/commands/api/endpoints/doc.ts +2 -2
- package/src/cli/commands/api/endpoints/document.ts +2 -2
- package/src/cli/commands/api/endpoints/search-reindex.ts +6 -25
- package/src/cli/commands/api/endpoints/search-status.ts +3 -20
- package/src/cli/commands/api/endpoints/search.ts +3 -33
- package/src/cli/commands/api/endpoints/semantic-search.ts +3 -33
- package/src/cli/commands/embed.ts +8 -81
- package/src/cli/commands/mcp.ts +5 -1128
- package/src/cli/commands/search.ts +4 -76
- package/src/cli/commands/serve.ts +7 -32
- package/src/cli/index.ts +1 -1
- package/src/cli/load-collection.ts +2 -2
- package/src/collection.ts +31 -30
- package/src/document.ts +18 -0
- package/src/extract-sections.ts +3 -0
- package/src/index.ts +10 -0
- package/src/mcp/helpers.ts +7 -0
- package/src/mcp/model-info.ts +102 -0
- package/src/mcp/prompts.ts +199 -0
- package/src/mcp/readme.ts +153 -0
- package/src/mcp/resources.ts +89 -0
- package/src/mcp/server.ts +103 -0
- package/src/mcp/tools/mutation.ts +176 -0
- package/src/mcp/tools/query.ts +141 -0
- package/src/mcp/tools/search.ts +180 -0
- package/src/parse.ts +5 -0
- package/src/query/query-dsl.ts +1 -1
- package/src/relationships/has-many.ts +2 -2
- package/src/search/document-inputs.ts +85 -0
- package/src/search/luca-semantic-search.ts +75 -0
- package/src/types.ts +54 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/match-pattern.ts +2 -2
- package/src/utils/strip-markdown.ts +59 -0
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import picomatch from 'picomatch';
|
|
3
|
+
import { commands } from '../registry.js';
|
|
4
|
+
import { loadCollection } from '../load-collection.js';
|
|
5
|
+
const argsSchema = z.object({
|
|
6
|
+
contentFolder: z.string().optional(),
|
|
7
|
+
force: z.boolean().default(false),
|
|
8
|
+
dry: z.boolean().default(false),
|
|
9
|
+
});
|
|
10
|
+
/**
|
|
11
|
+
* Parse "meta.status=spark" into a nested path assignment.
|
|
12
|
+
* Supports dotted paths like "meta.status" or bare keys like "status"
|
|
13
|
+
* (bare keys are treated as meta.<key>).
|
|
14
|
+
*/
|
|
15
|
+
function parseAssignment(raw) {
|
|
16
|
+
const eqIdx = raw.indexOf('=');
|
|
17
|
+
if (eqIdx === -1)
|
|
18
|
+
return null;
|
|
19
|
+
const key = raw.slice(0, eqIdx).trim();
|
|
20
|
+
const value = raw.slice(eqIdx + 1).trim();
|
|
21
|
+
// Normalise: if path doesn't start with "meta.", prepend it
|
|
22
|
+
const fullKey = key.startsWith('meta.') ? key : `meta.${key}`;
|
|
23
|
+
const path = fullKey.split('.');
|
|
24
|
+
return { path, value };
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Coerce a string value to a JS primitive if it looks like one.
|
|
28
|
+
*/
|
|
29
|
+
function coerceValue(raw) {
|
|
30
|
+
if (raw === 'true')
|
|
31
|
+
return true;
|
|
32
|
+
if (raw === 'false')
|
|
33
|
+
return false;
|
|
34
|
+
if (raw === 'null')
|
|
35
|
+
return null;
|
|
36
|
+
if (/^-?\d+(\.\d+)?$/.test(raw))
|
|
37
|
+
return Number(raw);
|
|
38
|
+
return raw;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Set a nested value on an object via a path array.
|
|
42
|
+
* e.g. setNested(obj, ['meta', 'status'], 'spark') → obj.meta.status = 'spark'
|
|
43
|
+
*/
|
|
44
|
+
function setNested(obj, path, value) {
|
|
45
|
+
let current = obj;
|
|
46
|
+
for (let i = 1; i < path.length - 1; i++) {
|
|
47
|
+
if (!(path[i] in current) || typeof current[path[i]] !== 'object') {
|
|
48
|
+
current[path[i]] = {};
|
|
49
|
+
}
|
|
50
|
+
current = current[path[i]];
|
|
51
|
+
}
|
|
52
|
+
current[path[path.length - 1]] = value;
|
|
53
|
+
}
|
|
54
|
+
async function handler(options, context) {
|
|
55
|
+
const { container } = context;
|
|
56
|
+
const args = container.argv._.slice(1); // everything after "update"
|
|
57
|
+
if (args.length < 2) {
|
|
58
|
+
console.error('Usage: cnotes update <glob> <key=value> [key=value ...] [--force] [--dry]');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
const globPattern = args[0];
|
|
62
|
+
const assignments = args.slice(1).map(parseAssignment).filter(Boolean);
|
|
63
|
+
if (assignments.length === 0) {
|
|
64
|
+
console.error('No valid key=value assignments found. Use format: meta.status=spark');
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
const collection = await loadCollection({
|
|
68
|
+
contentFolder: options.contentFolder,
|
|
69
|
+
});
|
|
70
|
+
// Match pathIds against the glob pattern
|
|
71
|
+
const isMatch = picomatch(globPattern);
|
|
72
|
+
const matchedIds = collection.available.filter((id) => isMatch(id));
|
|
73
|
+
if (matchedIds.length === 0) {
|
|
74
|
+
console.log(`No documents matched "${globPattern}"`);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
console.log(`Matched ${matchedIds.length} document(s)\n`);
|
|
78
|
+
let updated = 0;
|
|
79
|
+
let skipped = 0;
|
|
80
|
+
let validationErrors = 0;
|
|
81
|
+
for (const pathId of matchedIds) {
|
|
82
|
+
const doc = collection.document(pathId);
|
|
83
|
+
const def = collection.findModelDefinition(pathId);
|
|
84
|
+
// Apply assignments to a draft copy of meta for validation
|
|
85
|
+
const draftMeta = structuredClone(doc.meta);
|
|
86
|
+
for (const { path, value } of assignments) {
|
|
87
|
+
setNested({ meta: draftMeta }, ['meta', ...path.slice(1)], coerceValue(value));
|
|
88
|
+
}
|
|
89
|
+
// Validate unless --force
|
|
90
|
+
if (!options.force && def) {
|
|
91
|
+
const rawMeta = { ...(def.defaults ?? {}), ...draftMeta };
|
|
92
|
+
const metaResult = def.meta.safeParse(rawMeta);
|
|
93
|
+
if (!metaResult.success) {
|
|
94
|
+
validationErrors++;
|
|
95
|
+
console.log(`INVALID: ${pathId}`);
|
|
96
|
+
for (const issue of metaResult.error.issues) {
|
|
97
|
+
console.log(` ${issue.path.join('.')}: ${issue.message}`);
|
|
98
|
+
}
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (options.dry) {
|
|
103
|
+
console.log(`WOULD UPDATE: ${pathId}`);
|
|
104
|
+
for (const { path, value } of assignments) {
|
|
105
|
+
console.log(` ${path.join('.')} = ${value}`);
|
|
106
|
+
}
|
|
107
|
+
updated++;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
// Apply to the real document
|
|
111
|
+
for (const { path, value } of assignments) {
|
|
112
|
+
setNested({ meta: doc.meta }, ['meta', ...path.slice(1)], coerceValue(value));
|
|
113
|
+
}
|
|
114
|
+
await doc.save({ normalize: false });
|
|
115
|
+
updated++;
|
|
116
|
+
console.log(`UPDATED: ${pathId}`);
|
|
117
|
+
}
|
|
118
|
+
console.log();
|
|
119
|
+
console.log(`${updated} updated, ${validationErrors} invalid, ${matchedIds.length - updated - validationErrors} skipped`);
|
|
120
|
+
}
|
|
121
|
+
commands.register('update', {
|
|
122
|
+
description: 'Bulk-update document frontmatter by glob pattern',
|
|
123
|
+
help: `# cnotes update
|
|
124
|
+
|
|
125
|
+
Bulk-update frontmatter fields on documents matching a glob pattern. Validates changes against the model schema before writing (bypass with \`--force\`).
|
|
126
|
+
|
|
127
|
+
## Usage
|
|
128
|
+
|
|
129
|
+
\`\`\`
|
|
130
|
+
cnotes update <glob> <key=value> [key=value ...] [options]
|
|
131
|
+
\`\`\`
|
|
132
|
+
|
|
133
|
+
## Arguments
|
|
134
|
+
|
|
135
|
+
| Argument | Description |
|
|
136
|
+
|----------|-------------|
|
|
137
|
+
| \`glob\` | Glob pattern to match document path IDs (e.g. \`docs/ideas/**\`) |
|
|
138
|
+
| \`key=value\` | One or more assignments. Prefix with \`meta.\` or use bare keys (auto-prefixed). |
|
|
139
|
+
|
|
140
|
+
## Options
|
|
141
|
+
|
|
142
|
+
| Option | Description |
|
|
143
|
+
|--------|-------------|
|
|
144
|
+
| \`--force\` | Skip schema validation |
|
|
145
|
+
| \`--dry\` | Preview changes without writing |
|
|
146
|
+
| \`--contentFolder\` | Path to content folder |
|
|
147
|
+
|
|
148
|
+
## Examples
|
|
149
|
+
|
|
150
|
+
\`\`\`bash
|
|
151
|
+
# Set status on all ideas
|
|
152
|
+
cnotes update "ideas/**" meta.status=spark
|
|
153
|
+
|
|
154
|
+
# Multiple fields at once
|
|
155
|
+
cnotes update "epics/*" status=approved priority=high
|
|
156
|
+
|
|
157
|
+
# Preview what would change
|
|
158
|
+
cnotes update "ideas/**" status=spark --dry
|
|
159
|
+
|
|
160
|
+
# Force past schema validation
|
|
161
|
+
cnotes update "ideas/**" status=spark --force
|
|
162
|
+
\`\`\`
|
|
163
|
+
`,
|
|
164
|
+
argsSchema,
|
|
165
|
+
handler,
|
|
166
|
+
});
|
|
167
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/cli/commands/update.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { commands } from '../registry.js';
|
|
3
|
+
import { loadCollection } from '../load-collection.js';
|
|
4
|
+
import { validateDocument } from '../../validator.js';
|
|
5
|
+
const argsSchema = z.object({
|
|
6
|
+
contentFolder: z.string().optional(),
|
|
7
|
+
setDefaultMeta: z.boolean().default(false),
|
|
8
|
+
});
|
|
9
|
+
async function handler(options, context) {
|
|
10
|
+
const collection = await loadCollection({
|
|
11
|
+
contentFolder: options.contentFolder,
|
|
12
|
+
});
|
|
13
|
+
const setDefaultMeta = options.setDefaultMeta;
|
|
14
|
+
const target = context.container.argv._[1] || 'all';
|
|
15
|
+
let pathIds;
|
|
16
|
+
if (target === 'all') {
|
|
17
|
+
pathIds = collection.available;
|
|
18
|
+
}
|
|
19
|
+
else if (collection.items.has(target)) {
|
|
20
|
+
pathIds = [target];
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
const def = collection.getModelDefinition(target);
|
|
24
|
+
if (def) {
|
|
25
|
+
pathIds = collection.available.filter((id) => id.startsWith(def.prefix));
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
console.error(`Not found: "${target}"`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
let valid = 0;
|
|
33
|
+
let invalid = 0;
|
|
34
|
+
let updated = 0;
|
|
35
|
+
for (const pathId of pathIds) {
|
|
36
|
+
const def = collection.findModelDefinition(pathId);
|
|
37
|
+
if (!def)
|
|
38
|
+
continue;
|
|
39
|
+
const doc = collection.document(pathId);
|
|
40
|
+
if (setDefaultMeta && Object.keys(doc.meta).length === 0) {
|
|
41
|
+
const defaults = def.meta.parse({});
|
|
42
|
+
if (Object.keys(defaults).length > 0) {
|
|
43
|
+
const cleanDefaults = {};
|
|
44
|
+
for (const [k, v] of Object.entries(defaults)) {
|
|
45
|
+
if (v !== undefined)
|
|
46
|
+
cleanDefaults[k] = v;
|
|
47
|
+
}
|
|
48
|
+
if (Object.keys(cleanDefaults).length > 0) {
|
|
49
|
+
Object.assign(doc.meta, cleanDefaults);
|
|
50
|
+
await doc.save({ normalize: false });
|
|
51
|
+
updated++;
|
|
52
|
+
console.log(`SET DEFAULTS: ${pathId}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const result = validateDocument(doc, def);
|
|
57
|
+
if (result.valid) {
|
|
58
|
+
valid++;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
invalid++;
|
|
62
|
+
console.log(`INVALID: ${pathId}`);
|
|
63
|
+
for (const error of result.errors) {
|
|
64
|
+
console.log(` ${error.path.join('.')}: ${error.message}`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
console.log();
|
|
69
|
+
if (updated > 0) {
|
|
70
|
+
console.log(`Updated ${updated} document(s) with default meta.`);
|
|
71
|
+
}
|
|
72
|
+
console.log(`Validated ${valid + invalid} documents: ${valid} valid, ${invalid} invalid`);
|
|
73
|
+
if (invalid > 0)
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
commands.register('validate', {
|
|
77
|
+
description: 'Validate documents against their model schemas',
|
|
78
|
+
usage: '[model]',
|
|
79
|
+
help: `# cnotes validate
|
|
80
|
+
|
|
81
|
+
Validate documents against their model schemas. Check frontmatter types, required fields, and optionally fill in missing defaults.
|
|
82
|
+
|
|
83
|
+
## Usage
|
|
84
|
+
|
|
85
|
+
\`\`\`
|
|
86
|
+
cnotes validate [target] [options]
|
|
87
|
+
\`\`\`
|
|
88
|
+
|
|
89
|
+
## Arguments
|
|
90
|
+
|
|
91
|
+
| Argument | Description | Default |
|
|
92
|
+
|----------|-------------|---------|
|
|
93
|
+
| \`target\` | A path ID, model name, or \`all\` | \`all\` |
|
|
94
|
+
|
|
95
|
+
## Options
|
|
96
|
+
|
|
97
|
+
| Option | Description |
|
|
98
|
+
|--------|-------------|
|
|
99
|
+
| \`--setDefaultMeta\` | Write Zod schema defaults to documents with empty frontmatter |
|
|
100
|
+
| \`--contentFolder\` | Path to content folder |
|
|
101
|
+
|
|
102
|
+
## Exit Codes
|
|
103
|
+
|
|
104
|
+
- \`0\` — All documents valid
|
|
105
|
+
- \`1\` — One or more validation errors
|
|
106
|
+
|
|
107
|
+
## Examples
|
|
108
|
+
|
|
109
|
+
\`\`\`bash
|
|
110
|
+
# Validate everything
|
|
111
|
+
cnotes validate
|
|
112
|
+
|
|
113
|
+
# Validate a single document
|
|
114
|
+
cnotes validate epics/auth-system
|
|
115
|
+
|
|
116
|
+
# Validate all documents of a model
|
|
117
|
+
cnotes validate Epic
|
|
118
|
+
|
|
119
|
+
# Fill in missing defaults and validate
|
|
120
|
+
cnotes validate all --setDefaultMeta
|
|
121
|
+
|
|
122
|
+
# Validate a different content folder
|
|
123
|
+
cnotes validate --contentFolder ./docs
|
|
124
|
+
\`\`\`
|
|
125
|
+
`,
|
|
126
|
+
argsSchema,
|
|
127
|
+
handler,
|
|
128
|
+
});
|
|
129
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAErD,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;CAC3C,CAAC,CAAA;AAEF,KAAK,UAAU,OAAO,CAAC,OAAmC,EAAE,OAA2B;IACrF,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC;QACtC,aAAa,EAAE,OAAO,CAAC,aAAa;KACrC,CAAC,CAAA;IAEF,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,CAAA;IAC7C,MAAM,MAAM,GAAI,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAY,IAAI,KAAK,CAAA;IAC/D,IAAI,OAAiB,CAAA;IAErB,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;QACrB,OAAO,GAAG,UAAU,CAAC,SAAS,CAAA;IAChC,CAAC;SAAM,IAAI,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;QACxC,OAAO,GAAG,CAAC,MAAM,CAAC,CAAA;IACpB,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,GAAG,UAAU,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAA;QACjD,IAAI,GAAG,EAAE,CAAC;YACR,OAAO,GAAG,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAC3C,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAC1B,CAAA;QACH,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,eAAe,MAAM,GAAG,CAAC,CAAA;YACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;IAED,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,IAAI,OAAO,GAAG,CAAC,CAAA;IAEf,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,UAAU,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAA;QAClD,IAAI,CAAC,GAAG;YAAE,SAAQ;QAElB,MAAM,GAAG,GAAG,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QAEvC,IAAI,cAAc,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzD,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YACnC,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrC,MAAM,aAAa,GAA4B,EAAE,CAAA;gBACjD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAC9C,IAAI,CAAC,KAAK,SAAS;wBAAE,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;gBAC3C,CAAC;gBACD,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC1C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,aAAa,CAAC,CAAA;oBACtC,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAA;oBACpC,OAAO,EAAE,CAAA;oBACT,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,EAAE,CAAC,CAAA;gBACxC,CAAC;YACH,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QAEzC,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,KAAK,EAAE,CAAA;QACT,CAAC;aAAM,CAAC;YACN,OAAO,EAAE,CAAA;YACT,OAAO,CAAC,GAAG,CAAC,YAAY,MAAM,EAAE,CAAC,CAAA;YACjC,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBAClC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAA;YAC5D,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,CAAA;IACb,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,WAAW,OAAO,iCAAiC,CAAC,CAAA;IAClE,CAAC;IACD,OAAO,CAAC,GAAG,CACT,aAAa,KAAK,GAAG,OAAO,eAAe,KAAK,WAAW,OAAO,UAAU,CAC7E,CAAA;IAED,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAClC,CAAC;AAED,QAAQ,CAAC,QAAQ,CAAC,UAAU,EAAE;IAC5B,WAAW,EAAE,gDAAgD;IAC7D,KAAK,EAAE,SAAS;IAChB,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CP;IACC,UAAU;IACV,OAAO;CACR,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AAKA,OAAO,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { commands } from './registry.js';
|
|
3
|
+
import pkg from '../../package.json';
|
|
4
|
+
// Side-effect imports register all commands
|
|
5
|
+
import './commands/index.js';
|
|
6
|
+
async function renderMarkdown(container, text) {
|
|
7
|
+
const ui = container.feature('ui');
|
|
8
|
+
console.log(ui.markdown(text));
|
|
9
|
+
}
|
|
10
|
+
async function main() {
|
|
11
|
+
// Dynamic import so the library stays luca-free; only the CLI pulls it in
|
|
12
|
+
const luca = await import('luca/node');
|
|
13
|
+
const container = luca.default;
|
|
14
|
+
const commandName = container.argv._[0];
|
|
15
|
+
if (container.argv.version || container.argv.v || commandName === 'version') {
|
|
16
|
+
console.log(`cnotes ${pkg.version}\n${pkg.repository}`);
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
const wantsHelp = container.argv.help || container.argv.h;
|
|
20
|
+
// Bare invocation or explicit "help" with no subcommand
|
|
21
|
+
if (!commandName || (commandName === 'help' && !container.argv._[1])) {
|
|
22
|
+
const help = commands.get('help');
|
|
23
|
+
await help.handler({}, { container });
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// `cnotes help <command>` — show that command's help
|
|
27
|
+
if (commandName === 'help' && container.argv._[1]) {
|
|
28
|
+
const target = container.argv._[1];
|
|
29
|
+
if (!commands.has(target)) {
|
|
30
|
+
console.error(`Unknown command: ${target}`);
|
|
31
|
+
console.error(`Run "cnotes help" to see available commands.\n`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
const def = commands.get(target);
|
|
35
|
+
if (def.help) {
|
|
36
|
+
await renderMarkdown(container, def.help);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
console.log(`${target} — ${def.description}\n`);
|
|
40
|
+
console.log(`No detailed help available for this command.`);
|
|
41
|
+
}
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (!commands.has(commandName)) {
|
|
45
|
+
console.error(`Unknown command: ${commandName}`);
|
|
46
|
+
console.error(`Run "cnotes help" to see available commands.\n`);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
const def = commands.get(commandName);
|
|
50
|
+
// `cnotes <command> --help` — show that command's help
|
|
51
|
+
if (wantsHelp) {
|
|
52
|
+
if (def.help) {
|
|
53
|
+
await renderMarkdown(container, def.help);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
console.log(`${commandName} — ${def.description}\n`);
|
|
57
|
+
console.log(`No detailed help available for this command.`);
|
|
58
|
+
}
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// Parse args from container.argv (minimist-parsed)
|
|
62
|
+
const { _: _positional, ...flags } = container.argv;
|
|
63
|
+
let options = flags;
|
|
64
|
+
if (def.argsSchema) {
|
|
65
|
+
const result = def.argsSchema.safeParse(flags);
|
|
66
|
+
if (!result.success) {
|
|
67
|
+
console.error(`Invalid options for "${commandName}":`);
|
|
68
|
+
for (const issue of result.error.issues) {
|
|
69
|
+
console.error(` ${issue.path.join('.')}: ${issue.message}`);
|
|
70
|
+
}
|
|
71
|
+
if (def.help) {
|
|
72
|
+
console.error(`\nRun "cnotes ${commandName} --help" for usage information.`);
|
|
73
|
+
}
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
options = result.data;
|
|
77
|
+
}
|
|
78
|
+
await def.handler(options, { container });
|
|
79
|
+
}
|
|
80
|
+
main().catch((err) => {
|
|
81
|
+
console.error(err);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
});
|
|
84
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-collection.d.ts","sourceRoot":"","sources":["../../src/cli/load-collection.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AA6H3C,wBAAsB,cAAc,CAAC,OAAO,EAAE;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,GAAG,CAAC;CACjB,GAAG,OAAO,CAAC,UAAU,CAAC,CAoGtB"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import fs from "fs/promises";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { existsSync } from "fs";
|
|
4
|
+
import { Collection } from "../collection";
|
|
5
|
+
import { defineModel } from "../define-model";
|
|
6
|
+
import { singularize, upperFirst } from "../utils/inflect";
|
|
7
|
+
import * as contentbaseExports from "../index";
|
|
8
|
+
/**
|
|
9
|
+
* Search for a file with the given basename and common extensions.
|
|
10
|
+
*/
|
|
11
|
+
async function findFile(dir, basename) {
|
|
12
|
+
for (const ext of ["ts", "js", "mjs"]) {
|
|
13
|
+
const candidate = path.resolve(dir, `${basename}.${ext}`);
|
|
14
|
+
try {
|
|
15
|
+
await fs.stat(candidate);
|
|
16
|
+
return candidate;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
// Not found, try next
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Duck-type check: does this value look like a ModelDefinition?
|
|
26
|
+
*/
|
|
27
|
+
function isModelDefinition(value) {
|
|
28
|
+
return (typeof value === "object" &&
|
|
29
|
+
value !== null &&
|
|
30
|
+
typeof value.name === "string" &&
|
|
31
|
+
typeof value.prefix === "string" &&
|
|
32
|
+
"meta" in value);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Check if a directory (up to 2 levels deep) contains .md or .mdx files.
|
|
36
|
+
*/
|
|
37
|
+
async function directoryContainsMarkdown(dirPath) {
|
|
38
|
+
try {
|
|
39
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
40
|
+
for (const entry of entries) {
|
|
41
|
+
if (entry.isFile() &&
|
|
42
|
+
(entry.name.endsWith(".md") || entry.name.endsWith(".mdx"))) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
if (entry.isDirectory()) {
|
|
46
|
+
const subEntries = await fs.readdir(path.join(dirPath, entry.name), { withFileTypes: true });
|
|
47
|
+
for (const sub of subEntries) {
|
|
48
|
+
if (sub.isFile() &&
|
|
49
|
+
(sub.name.endsWith(".md") || sub.name.endsWith(".mdx"))) {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Directory unreadable
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Tier 3: Auto-discover models from top-level subdirectories containing markdown.
|
|
63
|
+
*/
|
|
64
|
+
async function autoDiscoverModels(collection) {
|
|
65
|
+
const rootPath = collection.rootPath;
|
|
66
|
+
let registered = 0;
|
|
67
|
+
try {
|
|
68
|
+
const entries = await fs.readdir(rootPath, { withFileTypes: true });
|
|
69
|
+
for (const entry of entries) {
|
|
70
|
+
if (!entry.isDirectory())
|
|
71
|
+
continue;
|
|
72
|
+
const dirPath = path.join(rootPath, entry.name);
|
|
73
|
+
if (await directoryContainsMarkdown(dirPath)) {
|
|
74
|
+
const folderName = entry.name;
|
|
75
|
+
const modelName = upperFirst(singularize(folderName));
|
|
76
|
+
const model = defineModel(modelName, { prefix: folderName });
|
|
77
|
+
collection.register(model);
|
|
78
|
+
registered++;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// Root path unreadable
|
|
84
|
+
}
|
|
85
|
+
return registered;
|
|
86
|
+
}
|
|
87
|
+
/** Seed the luca VM with contentbase and common deps so models.ts can resolve imports */
|
|
88
|
+
function seedContentbaseModules(container) {
|
|
89
|
+
const vm = container.feature('vm');
|
|
90
|
+
// Seed luca modules first
|
|
91
|
+
const helpers = container.feature('helpers');
|
|
92
|
+
if (helpers?.seedVirtualModules) {
|
|
93
|
+
helpers.seedVirtualModules();
|
|
94
|
+
}
|
|
95
|
+
vm.defineModule('contentbase', contentbaseExports);
|
|
96
|
+
try {
|
|
97
|
+
vm.defineModule('js-yaml', require('js-yaml'));
|
|
98
|
+
}
|
|
99
|
+
catch { }
|
|
100
|
+
try {
|
|
101
|
+
vm.defineModule('mdast-util-to-string', require('mdast-util-to-string'));
|
|
102
|
+
}
|
|
103
|
+
catch { }
|
|
104
|
+
}
|
|
105
|
+
/** Build a VM-backed module loader using the luca container */
|
|
106
|
+
function createVmModuleLoader(container) {
|
|
107
|
+
let seeded = false;
|
|
108
|
+
return (filePath) => {
|
|
109
|
+
if (!seeded) {
|
|
110
|
+
seedContentbaseModules(container);
|
|
111
|
+
seeded = true;
|
|
112
|
+
}
|
|
113
|
+
return container.feature('vm').loadModule(filePath);
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
export async function loadCollection(options) {
|
|
117
|
+
let { contentFolder, modulePath } = options;
|
|
118
|
+
let container = options.container;
|
|
119
|
+
let rootPath;
|
|
120
|
+
const cwd = process.cwd();
|
|
121
|
+
// If no container was passed, try to grab the luca singleton.
|
|
122
|
+
// This works when running inside the cnotes CLI (which imports luca/node).
|
|
123
|
+
if (!container) {
|
|
124
|
+
try {
|
|
125
|
+
const luca = await import('luca/node');
|
|
126
|
+
container = luca.default;
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// Not running in a luca context — that's fine, native imports will be used
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (contentFolder) {
|
|
133
|
+
// Resolve relative to cwd
|
|
134
|
+
rootPath = path.resolve(cwd, contentFolder);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
// Check package.json for configured content folder
|
|
138
|
+
const pkgPath = path.resolve(cwd, "package.json");
|
|
139
|
+
try {
|
|
140
|
+
const manifest = JSON.parse(await fs.readFile(pkgPath, "utf8"));
|
|
141
|
+
if (manifest.contentbase?.contentFolder) {
|
|
142
|
+
rootPath = path.resolve(cwd, manifest.contentbase.contentFolder);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
catch {
|
|
146
|
+
// No package.json found
|
|
147
|
+
}
|
|
148
|
+
// Default to ./docs
|
|
149
|
+
rootPath = rootPath ?? path.resolve(cwd, "docs");
|
|
150
|
+
}
|
|
151
|
+
// Determine if we need a VM-based loader (no contentbase in node_modules)
|
|
152
|
+
const needsVmLoader = container?.feature && !existsSync(path.resolve(cwd, "node_modules", "contentbase"));
|
|
153
|
+
const moduleLoader = needsVmLoader ? createVmModuleLoader(container) : undefined;
|
|
154
|
+
// Helper to import a module file, falling back to VM when needed
|
|
155
|
+
const importModule = async (filePath) => {
|
|
156
|
+
if (moduleLoader) {
|
|
157
|
+
return moduleLoader(filePath);
|
|
158
|
+
}
|
|
159
|
+
return import(filePath);
|
|
160
|
+
};
|
|
161
|
+
// Tier 1: index.ts — full collection with models already registered
|
|
162
|
+
if (!modulePath) {
|
|
163
|
+
modulePath = await findFile(rootPath, "index");
|
|
164
|
+
}
|
|
165
|
+
if (modulePath) {
|
|
166
|
+
const mod = await importModule(modulePath);
|
|
167
|
+
const collection = mod.collection ?? mod.default;
|
|
168
|
+
if (!(collection instanceof Collection)) {
|
|
169
|
+
throw new Error("Module must export a Collection as 'collection' or default export.");
|
|
170
|
+
}
|
|
171
|
+
await collection.load();
|
|
172
|
+
return collection;
|
|
173
|
+
}
|
|
174
|
+
// Tier 2: models.ts — import model definitions and auto-register
|
|
175
|
+
const modelsPath = await findFile(rootPath, "models");
|
|
176
|
+
if (modelsPath) {
|
|
177
|
+
const mod = await importModule(modelsPath);
|
|
178
|
+
const collection = new Collection({ rootPath, moduleLoader });
|
|
179
|
+
let registered = 0;
|
|
180
|
+
for (const [, value] of Object.entries(mod)) {
|
|
181
|
+
if (isModelDefinition(value)) {
|
|
182
|
+
collection.register(value);
|
|
183
|
+
registered++;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
await collection.load();
|
|
187
|
+
return collection;
|
|
188
|
+
}
|
|
189
|
+
// Tier 3: Auto-discover models from folder structure
|
|
190
|
+
const collection = new Collection({ rootPath, moduleLoader });
|
|
191
|
+
const discovered = await autoDiscoverModels(collection);
|
|
192
|
+
if (discovered > 0) {
|
|
193
|
+
console.warn(`[contentbase] Auto-discovered ${discovered} model(s) from folder structure. These models have no schema validation. Create a models.ts or index.ts for proper type definitions.`);
|
|
194
|
+
}
|
|
195
|
+
else {
|
|
196
|
+
console.warn(`[contentbase] No models or markdown files found in ${rootPath}. Run 'cnotes init' to set up a project.`);
|
|
197
|
+
}
|
|
198
|
+
await collection.load();
|
|
199
|
+
return collection;
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=load-collection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load-collection.js","sourceRoot":"","sources":["../../src/cli/load-collection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
export interface CommandDefinition {
|
|
3
|
+
description: string;
|
|
4
|
+
usage?: string;
|
|
5
|
+
help?: string;
|
|
6
|
+
argsSchema?: z.ZodType<any>;
|
|
7
|
+
handler: (options: any, context: {
|
|
8
|
+
container: any;
|
|
9
|
+
}) => Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export declare const commands: {
|
|
12
|
+
register(name: string, definition: CommandDefinition): void;
|
|
13
|
+
has(name: string): boolean;
|
|
14
|
+
get(name: string): CommandDefinition | undefined;
|
|
15
|
+
readonly available: string[];
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=registry.d.ts.map
|