contentbase 0.4.0 → 0.4.2

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 (323) hide show
  1. package/dist/adapters/node-fs.d.ts +17 -0
  2. package/dist/adapters/node-fs.d.ts.map +1 -0
  3. package/dist/adapters/node-fs.js +71 -0
  4. package/dist/adapters/node-fs.js.map +1 -0
  5. package/dist/ast-query.d.ts +44 -0
  6. package/dist/ast-query.d.ts.map +1 -0
  7. package/dist/ast-query.js +95 -0
  8. package/dist/ast-query.js.map +1 -0
  9. package/dist/base-model.d.ts +8 -0
  10. package/dist/base-model.d.ts.map +1 -0
  11. package/dist/base-model.js +12 -0
  12. package/dist/base-model.js.map +1 -0
  13. package/dist/cli/commands/action.d.ts +2 -0
  14. package/dist/cli/commands/action.d.ts.map +1 -0
  15. package/dist/cli/commands/action.js +73 -0
  16. package/dist/cli/commands/action.js.map +1 -0
  17. package/dist/cli/commands/api/endpoints/actions.d.ts +13 -0
  18. package/dist/cli/commands/api/endpoints/actions.d.ts.map +1 -0
  19. package/dist/cli/commands/api/endpoints/actions.js +28 -0
  20. package/dist/cli/commands/api/endpoints/actions.js.map +1 -0
  21. package/dist/cli/commands/api/endpoints/doc.d.ts +5 -0
  22. package/dist/cli/commands/api/endpoints/doc.d.ts.map +1 -0
  23. package/dist/cli/commands/api/endpoints/doc.js +186 -0
  24. package/dist/cli/commands/api/endpoints/doc.js.map +1 -0
  25. package/dist/cli/commands/api/endpoints/docs-index.d.ts +8 -0
  26. package/dist/cli/commands/api/endpoints/docs-index.d.ts.map +1 -0
  27. package/dist/cli/commands/api/endpoints/docs-index.js +23 -0
  28. package/dist/cli/commands/api/endpoints/docs-index.js.map +1 -0
  29. package/dist/cli/commands/api/endpoints/document.d.ts +47 -0
  30. package/dist/cli/commands/api/endpoints/document.d.ts.map +1 -0
  31. package/dist/cli/commands/api/endpoints/document.js +146 -0
  32. package/dist/cli/commands/api/endpoints/document.js.map +1 -0
  33. package/dist/cli/commands/api/endpoints/documents.d.ts +35 -0
  34. package/dist/cli/commands/api/endpoints/documents.d.ts.map +1 -0
  35. package/dist/cli/commands/api/endpoints/documents.js +56 -0
  36. package/dist/cli/commands/api/endpoints/documents.js.map +1 -0
  37. package/dist/cli/commands/api/endpoints/index.d.ts +22 -0
  38. package/dist/cli/commands/api/endpoints/index.d.ts.map +1 -0
  39. package/dist/cli/commands/api/endpoints/index.js +38 -0
  40. package/dist/cli/commands/api/endpoints/index.js.map +1 -0
  41. package/dist/cli/commands/api/endpoints/inspect.d.ts +10 -0
  42. package/dist/cli/commands/api/endpoints/inspect.d.ts.map +1 -0
  43. package/dist/cli/commands/api/endpoints/inspect.js +15 -0
  44. package/dist/cli/commands/api/endpoints/inspect.js.map +1 -0
  45. package/dist/cli/commands/api/endpoints/models.d.ts +5 -0
  46. package/dist/cli/commands/api/endpoints/models.d.ts.map +1 -0
  47. package/dist/cli/commands/api/endpoints/models.js +9 -0
  48. package/dist/cli/commands/api/endpoints/models.js.map +1 -0
  49. package/dist/cli/commands/api/endpoints/query.d.ts +40 -0
  50. package/dist/cli/commands/api/endpoints/query.d.ts.map +1 -0
  51. package/dist/cli/commands/api/endpoints/query.js +106 -0
  52. package/dist/cli/commands/api/endpoints/query.js.map +1 -0
  53. package/dist/cli/commands/api/endpoints/root.d.ts +5 -0
  54. package/dist/cli/commands/api/endpoints/root.d.ts.map +1 -0
  55. package/dist/cli/commands/api/endpoints/root.js +7 -0
  56. package/dist/cli/commands/api/endpoints/root.js.map +1 -0
  57. package/dist/cli/commands/api/endpoints/search-reindex.d.ts +10 -0
  58. package/dist/cli/commands/api/endpoints/search-reindex.d.ts.map +1 -0
  59. package/dist/cli/commands/api/endpoints/search-reindex.js +38 -0
  60. package/dist/cli/commands/api/endpoints/search-reindex.js.map +1 -0
  61. package/dist/cli/commands/api/endpoints/search-status.d.ts +7 -0
  62. package/dist/cli/commands/api/endpoints/search-status.d.ts.map +1 -0
  63. package/dist/cli/commands/api/endpoints/search-status.js +33 -0
  64. package/dist/cli/commands/api/endpoints/search-status.js.map +1 -0
  65. package/dist/cli/commands/api/endpoints/search.d.ts +24 -0
  66. package/dist/cli/commands/api/endpoints/search.d.ts.map +1 -0
  67. package/dist/cli/commands/api/endpoints/search.js +61 -0
  68. package/dist/cli/commands/api/endpoints/search.js.map +1 -0
  69. package/dist/cli/commands/api/endpoints/semantic-search.d.ts +28 -0
  70. package/dist/cli/commands/api/endpoints/semantic-search.d.ts.map +1 -0
  71. package/dist/cli/commands/api/endpoints/semantic-search.js +76 -0
  72. package/dist/cli/commands/api/endpoints/semantic-search.js.map +1 -0
  73. package/dist/cli/commands/api/endpoints/text-search.d.ts +17 -0
  74. package/dist/cli/commands/api/endpoints/text-search.d.ts.map +1 -0
  75. package/dist/cli/commands/api/endpoints/text-search.js +55 -0
  76. package/dist/cli/commands/api/endpoints/text-search.js.map +1 -0
  77. package/dist/cli/commands/api/endpoints/validate.d.ts +12 -0
  78. package/dist/cli/commands/api/endpoints/validate.d.ts.map +1 -0
  79. package/dist/cli/commands/api/endpoints/validate.js +27 -0
  80. package/dist/cli/commands/api/endpoints/validate.js.map +1 -0
  81. package/dist/cli/commands/api/helpers.d.ts +8 -0
  82. package/dist/cli/commands/api/helpers.d.ts.map +1 -0
  83. package/dist/cli/commands/api/helpers.js +89 -0
  84. package/dist/cli/commands/api/helpers.js.map +1 -0
  85. package/dist/cli/commands/console.d.ts +2 -0
  86. package/dist/cli/commands/console.d.ts.map +1 -0
  87. package/dist/cli/commands/console.js +117 -0
  88. package/dist/cli/commands/console.js.map +1 -0
  89. package/dist/cli/commands/create.d.ts +2 -0
  90. package/dist/cli/commands/create.d.ts.map +1 -0
  91. package/dist/cli/commands/create.js +185 -0
  92. package/dist/cli/commands/create.js.map +1 -0
  93. package/dist/cli/commands/embed.d.ts +2 -0
  94. package/dist/cli/commands/embed.d.ts.map +1 -0
  95. package/dist/cli/commands/embed.js +231 -0
  96. package/dist/cli/commands/embed.js.map +1 -0
  97. package/dist/cli/commands/export.d.ts +2 -0
  98. package/dist/cli/commands/export.d.ts.map +1 -0
  99. package/dist/cli/commands/export.js +55 -0
  100. package/dist/cli/commands/export.js.map +1 -0
  101. package/dist/cli/commands/extract.d.ts +2 -0
  102. package/dist/cli/commands/extract.d.ts.map +1 -0
  103. package/dist/cli/commands/extract.js +149 -0
  104. package/dist/cli/commands/extract.js.map +1 -0
  105. package/dist/cli/commands/help.d.ts +2 -0
  106. package/dist/cli/commands/help.d.ts.map +1 -0
  107. package/dist/cli/commands/help.js +58 -0
  108. package/dist/cli/commands/help.js.map +1 -0
  109. package/dist/cli/commands/index.d.ts +18 -0
  110. package/dist/cli/commands/index.d.ts.map +1 -0
  111. package/dist/cli/commands/index.js +19 -0
  112. package/dist/cli/commands/index.js.map +1 -0
  113. package/dist/cli/commands/init.d.ts +2 -0
  114. package/dist/cli/commands/init.d.ts.map +1 -0
  115. package/dist/cli/commands/init.js +82 -0
  116. package/dist/cli/commands/init.js.map +1 -0
  117. package/dist/cli/commands/inspect.d.ts +2 -0
  118. package/dist/cli/commands/inspect.d.ts.map +1 -0
  119. package/dist/cli/commands/inspect.js +53 -0
  120. package/dist/cli/commands/inspect.js.map +1 -0
  121. package/dist/cli/commands/mcp.d.ts +2 -0
  122. package/dist/cli/commands/mcp.d.ts.map +1 -0
  123. package/dist/cli/commands/mcp.js +92 -0
  124. package/dist/cli/commands/mcp.js.map +1 -0
  125. package/dist/cli/commands/search.d.ts +2 -0
  126. package/dist/cli/commands/search.d.ts.map +1 -0
  127. package/dist/cli/commands/search.js +212 -0
  128. package/dist/cli/commands/search.js.map +1 -0
  129. package/dist/cli/commands/serve.d.ts +2 -0
  130. package/dist/cli/commands/serve.d.ts.map +1 -0
  131. package/dist/cli/commands/serve.js +298 -0
  132. package/dist/cli/commands/serve.js.map +1 -0
  133. package/dist/cli/commands/summary.d.ts +2 -0
  134. package/dist/cli/commands/summary.d.ts.map +1 -0
  135. package/dist/cli/commands/summary.js +58 -0
  136. package/dist/cli/commands/summary.js.map +1 -0
  137. package/dist/cli/commands/teach.d.ts +2 -0
  138. package/dist/cli/commands/teach.d.ts.map +1 -0
  139. package/dist/cli/commands/teach.js +80 -0
  140. package/dist/cli/commands/teach.js.map +1 -0
  141. package/dist/cli/commands/text-search.d.ts +2 -0
  142. package/dist/cli/commands/text-search.d.ts.map +1 -0
  143. package/dist/cli/commands/text-search.js +125 -0
  144. package/dist/cli/commands/text-search.js.map +1 -0
  145. package/dist/cli/commands/update.d.ts +2 -0
  146. package/dist/cli/commands/update.d.ts.map +1 -0
  147. package/dist/cli/commands/update.js +167 -0
  148. package/dist/cli/commands/update.js.map +1 -0
  149. package/dist/cli/commands/validate.d.ts +2 -0
  150. package/dist/cli/commands/validate.d.ts.map +1 -0
  151. package/dist/cli/commands/validate.js +129 -0
  152. package/dist/cli/commands/validate.js.map +1 -0
  153. package/dist/cli/index.d.ts +3 -0
  154. package/dist/cli/index.d.ts.map +1 -0
  155. package/dist/cli/index.js +84 -0
  156. package/dist/cli/index.js.map +1 -0
  157. package/dist/cli/load-collection.d.ts +7 -0
  158. package/dist/cli/load-collection.d.ts.map +1 -0
  159. package/dist/cli/load-collection.js +201 -0
  160. package/dist/cli/load-collection.js.map +1 -0
  161. package/dist/cli/registry.d.ts +17 -0
  162. package/dist/cli/registry.d.ts.map +1 -0
  163. package/dist/cli/registry.js +16 -0
  164. package/dist/cli/registry.js.map +1 -0
  165. package/dist/cnotes +0 -0
  166. package/dist/collection.d.ts +145 -0
  167. package/dist/collection.d.ts.map +1 -0
  168. package/dist/collection.js +684 -0
  169. package/dist/collection.js.map +1 -0
  170. package/dist/define-model.d.ts +45 -0
  171. package/dist/define-model.d.ts.map +1 -0
  172. package/dist/define-model.js +106 -0
  173. package/dist/define-model.js.map +1 -0
  174. package/dist/document.d.ts +123 -0
  175. package/dist/document.d.ts.map +1 -0
  176. package/dist/document.js +434 -0
  177. package/dist/document.js.map +1 -0
  178. package/dist/extract-sections.d.ts +46 -0
  179. package/dist/extract-sections.d.ts.map +1 -0
  180. package/dist/extract-sections.js +153 -0
  181. package/dist/extract-sections.js.map +1 -0
  182. package/dist/index.d.ts +28 -0
  183. package/dist/index.d.ts.map +1 -0
  184. package/dist/index.js +31 -0
  185. package/dist/index.js.map +1 -0
  186. package/dist/mcp/helpers.d.ts +14 -0
  187. package/dist/mcp/helpers.d.ts.map +1 -0
  188. package/dist/mcp/helpers.js +7 -0
  189. package/dist/mcp/helpers.js.map +1 -0
  190. package/dist/mcp/model-info.d.ts +2 -0
  191. package/dist/mcp/model-info.d.ts.map +1 -0
  192. package/dist/mcp/model-info.js +94 -0
  193. package/dist/mcp/model-info.js.map +1 -0
  194. package/dist/mcp/prompts.d.ts +2 -0
  195. package/dist/mcp/prompts.d.ts.map +1 -0
  196. package/dist/mcp/prompts.js +180 -0
  197. package/dist/mcp/prompts.js.map +1 -0
  198. package/dist/mcp/readme.d.ts +2 -0
  199. package/dist/mcp/readme.d.ts.map +1 -0
  200. package/dist/mcp/readme.js +71 -0
  201. package/dist/mcp/readme.js.map +1 -0
  202. package/dist/mcp/resources.d.ts +2 -0
  203. package/dist/mcp/resources.d.ts.map +1 -0
  204. package/dist/mcp/resources.js +85 -0
  205. package/dist/mcp/resources.js.map +1 -0
  206. package/dist/mcp/server.d.ts +18 -0
  207. package/dist/mcp/server.d.ts.map +1 -0
  208. package/dist/mcp/server.js +83 -0
  209. package/dist/mcp/server.js.map +1 -0
  210. package/dist/mcp/tools/mutation.d.ts +2 -0
  211. package/dist/mcp/tools/mutation.d.ts.map +1 -0
  212. package/dist/mcp/tools/mutation.js +155 -0
  213. package/dist/mcp/tools/mutation.js.map +1 -0
  214. package/dist/mcp/tools/query.d.ts +2 -0
  215. package/dist/mcp/tools/query.d.ts.map +1 -0
  216. package/dist/mcp/tools/query.js +130 -0
  217. package/dist/mcp/tools/query.js.map +1 -0
  218. package/dist/mcp/tools/search.d.ts +2 -0
  219. package/dist/mcp/tools/search.d.ts.map +1 -0
  220. package/dist/mcp/tools/search.js +168 -0
  221. package/dist/mcp/tools/search.js.map +1 -0
  222. package/dist/model-instance.d.ts +11 -0
  223. package/dist/model-instance.d.ts.map +1 -0
  224. package/dist/model-instance.js +208 -0
  225. package/dist/model-instance.js.map +1 -0
  226. package/dist/node-shortcuts.d.ts +25 -0
  227. package/dist/node-shortcuts.d.ts.map +1 -0
  228. package/dist/node-shortcuts.js +67 -0
  229. package/dist/node-shortcuts.js.map +1 -0
  230. package/dist/parse.d.ts +45 -0
  231. package/dist/parse.d.ts.map +1 -0
  232. package/dist/parse.js +98 -0
  233. package/dist/parse.js.map +1 -0
  234. package/dist/query/collection-query.d.ts +39 -0
  235. package/dist/query/collection-query.d.ts.map +1 -0
  236. package/dist/query/collection-query.js +184 -0
  237. package/dist/query/collection-query.js.map +1 -0
  238. package/dist/query/index.d.ts +8 -0
  239. package/dist/query/index.d.ts.map +1 -0
  240. package/dist/query/index.js +5 -0
  241. package/dist/query/index.js.map +1 -0
  242. package/dist/query/operators.d.ts +3 -0
  243. package/dist/query/operators.d.ts.map +1 -0
  244. package/dist/query/operators.js +18 -0
  245. package/dist/query/operators.js.map +1 -0
  246. package/dist/query/query-builder.d.ts +34 -0
  247. package/dist/query/query-builder.d.ts.map +1 -0
  248. package/dist/query/query-builder.js +84 -0
  249. package/dist/query/query-builder.js.map +1 -0
  250. package/dist/query/query-dsl.d.ts +36 -0
  251. package/dist/query/query-dsl.d.ts.map +1 -0
  252. package/dist/query/query-dsl.js +195 -0
  253. package/dist/query/query-dsl.js.map +1 -0
  254. package/dist/relationships/belongs-to.d.ts +9 -0
  255. package/dist/relationships/belongs-to.d.ts.map +1 -0
  256. package/dist/relationships/belongs-to.js +34 -0
  257. package/dist/relationships/belongs-to.js.map +1 -0
  258. package/dist/relationships/has-many.d.ts +23 -0
  259. package/dist/relationships/has-many.d.ts.map +1 -0
  260. package/dist/relationships/has-many.js +136 -0
  261. package/dist/relationships/has-many.js.map +1 -0
  262. package/dist/relationships/index.d.ts +26 -0
  263. package/dist/relationships/index.d.ts.map +1 -0
  264. package/dist/relationships/index.js +32 -0
  265. package/dist/relationships/index.js.map +1 -0
  266. package/dist/relationships/types.d.ts +2 -0
  267. package/dist/relationships/types.d.ts.map +1 -0
  268. package/dist/relationships/types.js +2 -0
  269. package/dist/relationships/types.js.map +1 -0
  270. package/dist/search/document-inputs.d.ts +30 -0
  271. package/dist/search/document-inputs.d.ts.map +1 -0
  272. package/dist/search/document-inputs.js +52 -0
  273. package/dist/search/document-inputs.js.map +1 -0
  274. package/dist/search/luca-semantic-search.d.ts +27 -0
  275. package/dist/search/luca-semantic-search.d.ts.map +1 -0
  276. package/dist/search/luca-semantic-search.js +56 -0
  277. package/dist/search/luca-semantic-search.js.map +1 -0
  278. package/dist/section.d.ts +21 -0
  279. package/dist/section.d.ts.map +1 -0
  280. package/dist/section.js +21 -0
  281. package/dist/section.js.map +1 -0
  282. package/dist/types.d.ts +185 -0
  283. package/dist/types.d.ts.map +1 -0
  284. package/dist/types.js +2 -0
  285. package/dist/types.js.map +1 -0
  286. package/dist/utils/index.d.ts +9 -0
  287. package/dist/utils/index.d.ts.map +1 -0
  288. package/dist/utils/index.js +8 -0
  289. package/dist/utils/index.js.map +1 -0
  290. package/dist/utils/inflect.d.ts +6 -0
  291. package/dist/utils/inflect.d.ts.map +1 -0
  292. package/dist/utils/inflect.js +75 -0
  293. package/dist/utils/inflect.js.map +1 -0
  294. package/dist/utils/match-pattern.d.ts +25 -0
  295. package/dist/utils/match-pattern.d.ts.map +1 -0
  296. package/dist/utils/match-pattern.js +52 -0
  297. package/dist/utils/match-pattern.js.map +1 -0
  298. package/dist/utils/normalize-headings.d.ts +8 -0
  299. package/dist/utils/normalize-headings.d.ts.map +1 -0
  300. package/dist/utils/normalize-headings.js +19 -0
  301. package/dist/utils/normalize-headings.js.map +1 -0
  302. package/dist/utils/parse-table.d.ts +7 -0
  303. package/dist/utils/parse-table.d.ts.map +1 -0
  304. package/dist/utils/parse-table.js +17 -0
  305. package/dist/utils/parse-table.js.map +1 -0
  306. package/dist/utils/read-directory.d.ts +5 -0
  307. package/dist/utils/read-directory.d.ts.map +1 -0
  308. package/dist/utils/read-directory.js +29 -0
  309. package/dist/utils/read-directory.js.map +1 -0
  310. package/dist/utils/stringify-ast.d.ts +6 -0
  311. package/dist/utils/stringify-ast.d.ts.map +1 -0
  312. package/dist/utils/stringify-ast.js +8 -0
  313. package/dist/utils/stringify-ast.js.map +1 -0
  314. package/dist/utils/strip-markdown.d.ts +11 -0
  315. package/dist/utils/strip-markdown.d.ts.map +1 -0
  316. package/dist/utils/strip-markdown.js +48 -0
  317. package/dist/utils/strip-markdown.js.map +1 -0
  318. package/dist/validator.d.ts +10 -0
  319. package/dist/validator.d.ts.map +1 -0
  320. package/dist/validator.js +55 -0
  321. package/dist/validator.js.map +1 -0
  322. package/package.json +3 -3
  323. package/src/document.ts +26 -8
@@ -0,0 +1,212 @@
1
+ import { z } from 'zod';
2
+ import path from 'node:path';
3
+ import { commands } from '../registry.js';
4
+ import { loadCollection } from '../load-collection.js';
5
+ import { collectDocumentInputs } from '../../search/document-inputs.js';
6
+ import { getInitializedSemanticSearch, hasSearchIndex } from '../../search/luca-semantic-search.js';
7
+ const argsSchema = z.object({
8
+ mode: z.enum(['hybrid', 'keyword', 'vector']).default('hybrid'),
9
+ model: z.string().optional(),
10
+ where: z.string().optional(),
11
+ n: z.number().default(10),
12
+ json: z.boolean().default(false),
13
+ full: z.boolean().default(false),
14
+ bootstrap: z.boolean().default(false),
15
+ contentFolder: z.string().optional(),
16
+ });
17
+ async function buildIndex(container, collection) {
18
+ const ss = await getInitializedSemanticSearch(container, collection.rootPath);
19
+ const docs = collectDocumentInputs(collection);
20
+ const toIndex = docs.filter((doc) => ss.needsReindex(doc));
21
+ ss.removeStale(docs.map((d) => d.pathId));
22
+ if (toIndex.length === 0) {
23
+ console.error('Index is up to date.');
24
+ return ss;
25
+ }
26
+ console.error(`Indexing ${toIndex.length} document(s)...`);
27
+ const batchSize = 5;
28
+ for (let i = 0; i < toIndex.length; i += batchSize) {
29
+ const batch = toIndex.slice(i, i + batchSize);
30
+ await ss.indexDocuments(batch);
31
+ console.error(` ${Math.min(i + batchSize, toIndex.length)}/${toIndex.length}`);
32
+ }
33
+ console.error('Index ready.');
34
+ return ss;
35
+ }
36
+ async function handler(options, { container }) {
37
+ const ui = container.feature('ui');
38
+ const query = container.argv._[1];
39
+ if (!query) {
40
+ console.error('Usage: cnotes search <query> [options]');
41
+ console.error(' --mode hybrid|keyword|vector (default: hybrid)');
42
+ console.error(' --model Filter by model name');
43
+ console.error(' --where Metadata filter, e.g. "status=approved"');
44
+ console.error(' -n Max results (default: 10)');
45
+ console.error(' --json Output as JSON');
46
+ console.error(' --full Include full document content');
47
+ console.error(' --bootstrap Build index if missing, then search');
48
+ process.exit(1);
49
+ }
50
+ const collection = await loadCollection({
51
+ contentFolder: options.contentFolder,
52
+ });
53
+ if (!hasSearchIndex(collection.rootPath) && !options.bootstrap) {
54
+ console.error('No search index found. Run: cnotes embed');
55
+ process.exit(1);
56
+ }
57
+ let ss;
58
+ if (options.bootstrap && !hasSearchIndex(collection.rootPath)) {
59
+ ss = await buildIndex(container, collection);
60
+ }
61
+ else {
62
+ ss = await getInitializedSemanticSearch(container, collection.rootPath);
63
+ }
64
+ // Parse where clause: "key=value,key2=value2"
65
+ let where;
66
+ if (options.where) {
67
+ where = {};
68
+ for (const pair of options.where.split(',')) {
69
+ const [key, ...rest] = pair.split('=');
70
+ if (key && rest.length > 0) {
71
+ where[key.trim()] = rest.join('=').trim();
72
+ }
73
+ }
74
+ }
75
+ const searchOptions = {
76
+ limit: options.n,
77
+ model: options.model,
78
+ where,
79
+ };
80
+ let results;
81
+ switch (options.mode) {
82
+ case 'keyword':
83
+ results = await ss.search(query, searchOptions);
84
+ break;
85
+ case 'vector':
86
+ results = await ss.vectorSearch(query, searchOptions);
87
+ break;
88
+ case 'hybrid':
89
+ default:
90
+ results = await ss.hybridSearch(query, searchOptions);
91
+ break;
92
+ }
93
+ if (options.json) {
94
+ if (options.full) {
95
+ for (const r of results) {
96
+ try {
97
+ const doc = collection.document(r.pathId);
98
+ r.content = doc.content;
99
+ }
100
+ catch { }
101
+ }
102
+ }
103
+ console.log(JSON.stringify(results, null, 2));
104
+ return;
105
+ }
106
+ if (results.length === 0) {
107
+ console.log('No results found.');
108
+ return;
109
+ }
110
+ const colors = ui.colors;
111
+ const cols = process.stdout.columns || 80;
112
+ const pad = ' ';
113
+ const maxSnippet = cols - pad.length - 2;
114
+ for (let i = 0; i < results.length; i++) {
115
+ const r = results[i];
116
+ const title = r.title || r.pathId;
117
+ console.log(`${colors.dim(`${i + 1}.`)} ${colors.bold(title)}`);
118
+ let relPath = r.pathId;
119
+ try {
120
+ relPath = path.relative(process.cwd(), collection.document(r.pathId).path);
121
+ }
122
+ catch { }
123
+ console.log(`${pad}${colors.cyan(relPath)}`);
124
+ if (r.snippet) {
125
+ let snippet = r.snippet
126
+ .replace(/>>>/g, '').replace(/<<</g, '')
127
+ .replace(/\n/g, ' ').replace(/\s+/g, ' ')
128
+ .replace(/[`*_~\[\]]/g, '').trim();
129
+ if (r.matchedSection)
130
+ snippet = `${r.matchedSection} — ${snippet}`;
131
+ if (snippet.length > maxSnippet)
132
+ snippet = snippet.substring(0, maxSnippet - 1) + '…';
133
+ console.log(`${pad}${colors.dim(snippet)}`);
134
+ }
135
+ if (i < results.length - 1)
136
+ console.log();
137
+ }
138
+ if (options.full) {
139
+ for (const r of results) {
140
+ try {
141
+ const doc = collection.document(r.pathId);
142
+ console.log(ui.colors.cyan(`\n--- ${r.pathId} ---\n`));
143
+ console.log(doc.content);
144
+ }
145
+ catch { }
146
+ }
147
+ }
148
+ }
149
+ commands.register('search', {
150
+ description: 'Semantic search across collection documents',
151
+ usage: '<query>',
152
+ help: `# cnotes search
153
+
154
+ Search documents in the collection using keyword, semantic, or hybrid search modes. Requires a search index — run \`cnotes embed\` first.
155
+
156
+ ## Usage
157
+
158
+ \`\`\`
159
+ cnotes search <query> [options]
160
+ \`\`\`
161
+
162
+ ## Arguments
163
+
164
+ | Argument | Description |
165
+ |----------|-------------|
166
+ | \`query\` | Search query text |
167
+
168
+ ## Options
169
+
170
+ | Option | Default | Description |
171
+ |--------|---------|-------------|
172
+ | \`--mode\` | \`hybrid\` | Search mode: \`hybrid\`, \`keyword\`, or \`vector\` |
173
+ | \`--model\` | | Filter results to a specific model |
174
+ | \`--where\` | | Metadata filter (e.g. \`"status=approved"\`) |
175
+ | \`-n\` | \`10\` | Maximum results to return |
176
+ | \`--json\` | \`false\` | Output as JSON |
177
+ | \`--full\` | \`false\` | Include full document content |
178
+ | \`--bootstrap\` | \`false\` | Build index if missing, then search |
179
+ | \`--contentFolder\` | | Path to content folder |
180
+
181
+ ## Examples
182
+
183
+ \`\`\`bash
184
+ # Hybrid search (default)
185
+ cnotes search "authentication patterns"
186
+
187
+ # Keyword-only search (BM25)
188
+ cnotes search "deploymentConfig" --mode keyword
189
+
190
+ # Semantic vector search
191
+ cnotes search "how do deployments work" --mode vector
192
+
193
+ # Filter by model
194
+ cnotes search "auth" --model Epic
195
+
196
+ # Filter by metadata
197
+ cnotes search "approved plans" --where "status=approved"
198
+
199
+ # Limit results
200
+ cnotes search "auth" -n 20
201
+
202
+ # JSON output
203
+ cnotes search "auth" --json
204
+
205
+ # Build index if missing, then search
206
+ cnotes search "auth" --bootstrap
207
+ \`\`\`
208
+ `,
209
+ argsSchema,
210
+ handler,
211
+ });
212
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/cli/commands/search.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=serve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":""}
@@ -0,0 +1,298 @@
1
+ import { z } from 'zod';
2
+ import path from 'node:path';
3
+ import fs from 'node:fs';
4
+ import { commands } from '../registry.js';
5
+ import { loadCollection } from '../load-collection.js';
6
+ import { buildSchemaJSON } from './api/helpers.js';
7
+ import { builtinEndpoints } from './api/endpoints/index.js';
8
+ import { collectDocumentInputs } from '../../search/document-inputs.js';
9
+ import { getInitializedSemanticSearch, hasSearchIndex } from '../../search/luca-semantic-search.js';
10
+ const argsSchema = z.object({
11
+ port: z.number().default(8000),
12
+ contentFolder: z.string().optional(),
13
+ modulePath: z.string().optional(),
14
+ endpointsDir: z.string().optional(),
15
+ staticDir: z.string().optional(),
16
+ cors: z.boolean().default(true),
17
+ force: z.boolean().default(false),
18
+ anyPort: z.boolean().default(false),
19
+ open: z.boolean().default(false),
20
+ readOnly: z.boolean().default(false),
21
+ refreshInterval: z.number().optional(),
22
+ watch: z.boolean().default(true),
23
+ search: z.boolean().default(false),
24
+ });
25
+ async function handler(options, context) {
26
+ const container = context.container;
27
+ const { networking, proc } = container;
28
+ // Resolve content folder from positional arg or option
29
+ const positionalFolder = container.argv._[1];
30
+ const contentFolder = positionalFolder || options.contentFolder || undefined;
31
+ const modulePath = options.modulePath || undefined;
32
+ const collection = await loadCollection({ contentFolder, modulePath });
33
+ const modelDefs = collection.modelDefinitions;
34
+ // Attach collection to container so endpoints can access it
35
+ container._contentbaseCollection = collection;
36
+ container._contentbaseReadOnly = options.readOnly;
37
+ // ---------------------------------------------------------------------------
38
+ // Port handling
39
+ // ---------------------------------------------------------------------------
40
+ let port = options.port;
41
+ if (options.anyPort) {
42
+ port = await networking.findOpenPort(port + 1);
43
+ }
44
+ const isPortAvailable = await networking.isPortOpen(port);
45
+ if (!isPortAvailable) {
46
+ if (!options.force) {
47
+ console.error(`Port ${port} is already in use.`);
48
+ console.error(`Use --force to kill the process on this port, or --any-port to find another port.`);
49
+ process.exit(1);
50
+ }
51
+ const pids = proc.findPidsByPort(port);
52
+ if (!pids.length) {
53
+ console.error(`Port ${port} is in use, but no PID could be discovered for termination.`);
54
+ process.exit(1);
55
+ }
56
+ for (const pid of pids) {
57
+ proc.kill(pid);
58
+ }
59
+ let portFreed = false;
60
+ for (let i = 0; i < 10; i++) {
61
+ if (await networking.isPortOpen(port)) {
62
+ portFreed = true;
63
+ break;
64
+ }
65
+ await new Promise((resolve) => setTimeout(resolve, 100));
66
+ }
67
+ if (!portFreed) {
68
+ console.error(`Failed to free port ${port} after terminating process(es): ${pids.join(', ')}`);
69
+ process.exit(1);
70
+ }
71
+ }
72
+ // ---------------------------------------------------------------------------
73
+ // Static directory
74
+ // ---------------------------------------------------------------------------
75
+ const cwd = process.cwd();
76
+ const staticDir = options.staticDir ? path.resolve(cwd, options.staticDir) : path.resolve(cwd, 'public');
77
+ let resolvedStaticDir;
78
+ if (fs.existsSync(staticDir)) {
79
+ resolvedStaticDir = staticDir;
80
+ }
81
+ else if (fs.existsSync(path.resolve(cwd, 'index.html'))) {
82
+ resolvedStaticDir = cwd;
83
+ }
84
+ // ---------------------------------------------------------------------------
85
+ // User endpoints directory
86
+ // ---------------------------------------------------------------------------
87
+ let userEndpointsDir = null;
88
+ if (options.endpointsDir) {
89
+ const dir = path.resolve(cwd, options.endpointsDir);
90
+ if (fs.existsSync(dir))
91
+ userEndpointsDir = dir;
92
+ }
93
+ else {
94
+ for (const candidate of ['endpoints', 'src/endpoints']) {
95
+ const dir = path.resolve(cwd, candidate);
96
+ if (fs.existsSync(dir)) {
97
+ userEndpointsDir = dir;
98
+ break;
99
+ }
100
+ }
101
+ }
102
+ // ---------------------------------------------------------------------------
103
+ // Express server
104
+ // ---------------------------------------------------------------------------
105
+ const expressServer = container.server('express', {
106
+ port,
107
+ cors: options.cors,
108
+ static: resolvedStaticDir,
109
+ historyFallback: false,
110
+ });
111
+ // Load built-in contentbase endpoints (statically imported so they survive bun compile)
112
+ await expressServer.useEndpointModules(builtinEndpoints);
113
+ // Load user endpoints if present
114
+ if (userEndpointsDir) {
115
+ await expressServer.useEndpoints(userEndpointsDir);
116
+ }
117
+ // Redirect root to /docs/ table of contents when no static index.html exists
118
+ if (!resolvedStaticDir || !fs.existsSync(path.join(resolvedStaticDir, 'index.html'))) {
119
+ expressServer.app.get('/', (_req, res) => {
120
+ res.redirect('/docs/');
121
+ });
122
+ }
123
+ // OpenAPI spec
124
+ expressServer.serveOpenAPISpec({
125
+ title: 'Contentbase API',
126
+ version: '1.0.0',
127
+ description: `REST API for ${collection.rootPath}`,
128
+ });
129
+ await expressServer.start({ port });
130
+ // ---------------------------------------------------------------------------
131
+ // Startup summary
132
+ // ---------------------------------------------------------------------------
133
+ const schema = buildSchemaJSON(collection);
134
+ const modelNames = Object.keys(schema);
135
+ console.log(`\nContentbase server listening on http://localhost:${port}`);
136
+ console.log(`Collection: ${collection.rootPath}`);
137
+ console.log(`Models: ${modelNames.join(', ') || '(none)'}`);
138
+ console.log(`Documents: ${collection.available.length}`);
139
+ if (options.readOnly) {
140
+ console.log(`Mode: read-only (write endpoints disabled)`);
141
+ }
142
+ console.log(`OpenAPI spec: http://localhost:${port}/openapi.json`);
143
+ if (resolvedStaticDir) {
144
+ console.log(`Static files: ${resolvedStaticDir}`);
145
+ }
146
+ if (expressServer._mountedEndpoints?.length) {
147
+ console.log(`\nEndpoints:`);
148
+ for (const ep of expressServer._mountedEndpoints) {
149
+ console.log(` ${ep.methods.map((m) => m.toUpperCase()).join(', ').padEnd(20)} ${ep.path}`);
150
+ }
151
+ }
152
+ console.log();
153
+ if (options.open) {
154
+ try {
155
+ const opener = container.feature('opener');
156
+ await opener.open(`http://localhost:${port}`);
157
+ }
158
+ catch (error) {
159
+ console.warn(`Could not open browser automatically: ${error.message}`);
160
+ }
161
+ }
162
+ // ---------------------------------------------------------------------------
163
+ // Search index auto-update
164
+ // ---------------------------------------------------------------------------
165
+ if (options.search) {
166
+ if (hasSearchIndex(collection.rootPath)) {
167
+ try {
168
+ const ss = await getInitializedSemanticSearch(container, collection.rootPath);
169
+ const docs = collectDocumentInputs(collection);
170
+ const stale = docs.filter((d) => ss.needsReindex(d));
171
+ ss.removeStale(docs.map((d) => d.pathId));
172
+ if (stale.length > 0) {
173
+ console.log(`[search] Updating ${stale.length} stale document(s)...`);
174
+ await ss.indexDocuments(stale);
175
+ console.log(`[search] Index updated.`);
176
+ }
177
+ else {
178
+ console.log(`[search] Index is up to date.`);
179
+ }
180
+ }
181
+ catch (error) {
182
+ console.warn(`[search] Auto-index failed: ${error.message}`);
183
+ }
184
+ }
185
+ else {
186
+ console.log(`[search] No search index found. Run: cnotes embed`);
187
+ }
188
+ }
189
+ // ---------------------------------------------------------------------------
190
+ // File watching
191
+ // ---------------------------------------------------------------------------
192
+ if (options.watch !== false) {
193
+ const fileManager = container.feature('fileManager');
194
+ await fileManager.start({ rootPath: collection.rootPath });
195
+ await fileManager.watch();
196
+ const { debounce } = container.utils.lodash;
197
+ const refreshCollection = debounce(async () => {
198
+ try {
199
+ const before = collection.available.length;
200
+ await collection.load({ refresh: true });
201
+ const after = collection.available.length;
202
+ if (after !== before) {
203
+ console.log(`[watch] Collection refreshed: ${before} → ${after} documents`);
204
+ }
205
+ }
206
+ catch (error) {
207
+ console.warn(`[watch] Refresh failed: ${error.message}`);
208
+ }
209
+ }, 500);
210
+ fileManager.on('file:change', (event) => {
211
+ if (/\.(md|mdx)$/i.test(event.path)) {
212
+ refreshCollection();
213
+ }
214
+ });
215
+ console.log(`Watching for file changes in ${collection.rootPath}`);
216
+ }
217
+ // ---------------------------------------------------------------------------
218
+ // Collection refresh interval (safety-net fallback)
219
+ // ---------------------------------------------------------------------------
220
+ const defaultInterval = container.isProduction ? 10 * 60 : 60; // seconds
221
+ const intervalSeconds = options.refreshInterval ?? defaultInterval;
222
+ setInterval(async () => {
223
+ try {
224
+ const before = collection.available.length;
225
+ await collection.load({ refresh: true });
226
+ const after = collection.available.length;
227
+ if (after !== before) {
228
+ console.log(`[refresh] Collection rescanned: ${before} → ${after} documents`);
229
+ }
230
+ }
231
+ catch (error) {
232
+ console.warn(`[refresh] Failed to rescan collection: ${error.message}`);
233
+ }
234
+ }, intervalSeconds * 1000);
235
+ console.log(`Refresh interval: every ${intervalSeconds}s`);
236
+ }
237
+ commands.register('serve', {
238
+ description: 'Start an HTTP server for the collection with REST API and document serving',
239
+ help: `# cnotes serve
240
+
241
+ Start an HTTP server with REST API endpoints for querying, creating, updating, and deleting documents. Serves static files and auto-generates an OpenAPI spec.
242
+
243
+ ## Usage
244
+
245
+ \`\`\`
246
+ cnotes serve [contentFolder] [options]
247
+ \`\`\`
248
+
249
+ ## Arguments
250
+
251
+ | Argument | Description |
252
+ |----------|-------------|
253
+ | \`contentFolder\` | Path to content folder (positional or via \`--contentFolder\`) |
254
+
255
+ ## Options
256
+
257
+ | Option | Default | Description |
258
+ |--------|---------|-------------|
259
+ | \`--port\` | \`8000\` | Port to listen on |
260
+ | \`--force\` | \`false\` | Kill existing process on the port |
261
+ | \`--anyPort\` | \`false\` | Find next available port if taken |
262
+ | \`--open\` | \`false\` | Open browser after starting |
263
+ | \`--readOnly\` | \`false\` | Disable write endpoints |
264
+ | \`--cors\` | \`true\` | Enable CORS |
265
+ | \`--staticDir\` | \`public/\` | Directory for static file serving |
266
+ | \`--endpointsDir\` | auto | Directory for user endpoint modules |
267
+ | \`--modulePath\` | | Path to collection entry module |
268
+ | \`--refreshInterval\` | \`60\` | Seconds between collection rescans (fallback) |
269
+ | \`--disable-watch\` | \`false\` | Disable file watching for automatic collection refresh |
270
+ | \`--contentFolder\` | | Path to content folder |
271
+
272
+ ## User Endpoints
273
+
274
+ Place endpoint modules in \`endpoints/\` or \`src/endpoints/\` and they'll be auto-mounted. Use \`--endpointsDir\` to override.
275
+
276
+ ## Examples
277
+
278
+ \`\`\`bash
279
+ # Start on default port
280
+ cnotes serve
281
+
282
+ # Serve a specific folder on a custom port
283
+ cnotes serve ./docs --port 3000
284
+
285
+ # Force kill existing server and open browser
286
+ cnotes serve --port 8000 --force --open
287
+
288
+ # Read-only mode for production
289
+ cnotes serve --readOnly --port 8080
290
+
291
+ # Find any available port
292
+ cnotes serve --anyPort
293
+ \`\`\`
294
+ `,
295
+ argsSchema,
296
+ handler,
297
+ });
298
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/summary.ts"],"names":[],"mappings":""}
@@ -0,0 +1,58 @@
1
+ import { z } from 'zod';
2
+ import { writeFile } from 'node:fs/promises';
3
+ import { join } from 'node:path';
4
+ import { commands } from '../registry.js';
5
+ import { loadCollection } from '../load-collection.js';
6
+ const argsSchema = z.object({
7
+ contentFolder: z.string().optional(),
8
+ includeIds: z.boolean().optional().default(false),
9
+ });
10
+ async function handler(options) {
11
+ const collection = await loadCollection({
12
+ contentFolder: options.contentFolder,
13
+ });
14
+ await collection.saveModelSummary({ includeIds: options.includeIds });
15
+ console.log(`README.md written to ${collection.rootPath}/README.md`);
16
+ const toc = collection.tableOfContents({ title: 'Table of Contents' });
17
+ const tocPath = join(collection.rootPath, 'TABLE-OF-CONTENTS.md');
18
+ await writeFile(tocPath, toc, 'utf-8');
19
+ console.log(`TABLE-OF-CONTENTS.md written to ${tocPath}`);
20
+ }
21
+ commands.register('summary', {
22
+ description: 'Generate README.md and TABLE-OF-CONTENTS.md for the collection',
23
+ help: `# cnotes summary
24
+
25
+ Generate documentation files for the collection. Writes \`README.md\` (model definitions summary) and \`TABLE-OF-CONTENTS.md\` (document listing) to the content root.
26
+
27
+ ## Usage
28
+
29
+ \`\`\`
30
+ cnotes summary [options]
31
+ \`\`\`
32
+
33
+ ## Options
34
+
35
+ | Option | Description |
36
+ |--------|-------------|
37
+ | \`--contentFolder\` | Path to content folder |
38
+ | \`--include-ids\` | Include document IDs in the summary (default: false) |
39
+
40
+ ## Generated Files
41
+
42
+ - **README.md** — Overview of all registered models with fields, sections, and relationships
43
+ - **TABLE-OF-CONTENTS.md** — Listing of all documents organized by model
44
+
45
+ ## Examples
46
+
47
+ \`\`\`bash
48
+ # Generate summary files
49
+ cnotes summary
50
+
51
+ # Generate for a specific content folder
52
+ cnotes summary --contentFolder ./docs
53
+ \`\`\`
54
+ `,
55
+ argsSchema,
56
+ handler,
57
+ });
58
+ //# sourceMappingURL=summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summary.js","sourceRoot":"","sources":["../../../src/cli/commands/summary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAA;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1B,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACpC,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;CAClD,CAAC,CAAA;AAEF,KAAK,UAAU,OAAO,CAAC,OAAmC;IACxD,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC;QACtC,aAAa,EAAE,OAAO,CAAC,aAAa;KACrC,CAAC,CAAA;IAEF,MAAM,UAAU,CAAC,gBAAgB,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;IACrE,OAAO,CAAC,GAAG,CAAC,wBAAwB,UAAU,CAAC,QAAQ,YAAY,CAAC,CAAA;IAEpE,MAAM,GAAG,GAAG,UAAU,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,CAAC,CAAA;IACtE,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,sBAAsB,CAAC,CAAA;IACjE,MAAM,SAAS,CAAC,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,CAAA;IACtC,OAAO,CAAC,GAAG,CAAC,mCAAmC,OAAO,EAAE,CAAC,CAAA;AAC3D,CAAC;AAED,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE;IAC3B,WAAW,EAAE,gEAAgE;IAC7E,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BP;IACC,UAAU;IACV,OAAO;CACR,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=teach.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teach.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/teach.ts"],"names":[],"mappings":""}