@gmickel/gno 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +90 -50
  3. package/THIRD_PARTY_NOTICES.md +22 -0
  4. package/assets/screenshots/webui-ask-answer.png +0 -0
  5. package/assets/screenshots/webui-collections.png +0 -0
  6. package/assets/screenshots/webui-editor.png +0 -0
  7. package/assets/screenshots/webui-home.png +0 -0
  8. package/assets/skill/SKILL.md +12 -12
  9. package/assets/skill/cli-reference.md +59 -57
  10. package/assets/skill/examples.md +8 -7
  11. package/assets/skill/mcp-reference.md +8 -4
  12. package/package.json +31 -24
  13. package/src/app/constants.ts +43 -42
  14. package/src/cli/colors.ts +1 -1
  15. package/src/cli/commands/ask.ts +44 -43
  16. package/src/cli/commands/cleanup.ts +9 -8
  17. package/src/cli/commands/collection/add.ts +12 -12
  18. package/src/cli/commands/collection/index.ts +4 -4
  19. package/src/cli/commands/collection/list.ts +26 -25
  20. package/src/cli/commands/collection/remove.ts +10 -10
  21. package/src/cli/commands/collection/rename.ts +10 -10
  22. package/src/cli/commands/context/add.ts +1 -1
  23. package/src/cli/commands/context/check.ts +17 -17
  24. package/src/cli/commands/context/index.ts +4 -4
  25. package/src/cli/commands/context/list.ts +11 -11
  26. package/src/cli/commands/context/rm.ts +1 -1
  27. package/src/cli/commands/doctor.ts +86 -84
  28. package/src/cli/commands/embed.ts +30 -28
  29. package/src/cli/commands/get.ts +27 -26
  30. package/src/cli/commands/index-cmd.ts +9 -9
  31. package/src/cli/commands/index.ts +16 -16
  32. package/src/cli/commands/init.ts +13 -12
  33. package/src/cli/commands/ls.ts +20 -19
  34. package/src/cli/commands/mcp/config.ts +30 -28
  35. package/src/cli/commands/mcp/index.ts +4 -4
  36. package/src/cli/commands/mcp/install.ts +17 -17
  37. package/src/cli/commands/mcp/paths.ts +133 -133
  38. package/src/cli/commands/mcp/status.ts +21 -21
  39. package/src/cli/commands/mcp/uninstall.ts +13 -13
  40. package/src/cli/commands/mcp.ts +2 -2
  41. package/src/cli/commands/models/clear.ts +12 -11
  42. package/src/cli/commands/models/index.ts +5 -5
  43. package/src/cli/commands/models/list.ts +31 -30
  44. package/src/cli/commands/models/path.ts +1 -1
  45. package/src/cli/commands/models/pull.ts +19 -18
  46. package/src/cli/commands/models/use.ts +4 -4
  47. package/src/cli/commands/multi-get.ts +38 -36
  48. package/src/cli/commands/query.ts +21 -20
  49. package/src/cli/commands/ref-parser.ts +10 -10
  50. package/src/cli/commands/reset.ts +40 -39
  51. package/src/cli/commands/search.ts +14 -13
  52. package/src/cli/commands/serve.ts +4 -4
  53. package/src/cli/commands/shared.ts +11 -10
  54. package/src/cli/commands/skill/index.ts +5 -5
  55. package/src/cli/commands/skill/install.ts +18 -17
  56. package/src/cli/commands/skill/paths-cmd.ts +11 -10
  57. package/src/cli/commands/skill/paths.ts +23 -23
  58. package/src/cli/commands/skill/show.ts +13 -12
  59. package/src/cli/commands/skill/uninstall.ts +16 -15
  60. package/src/cli/commands/status.ts +25 -24
  61. package/src/cli/commands/update.ts +3 -3
  62. package/src/cli/commands/vsearch.ts +17 -16
  63. package/src/cli/context.ts +5 -5
  64. package/src/cli/errors.ts +3 -3
  65. package/src/cli/format/search-results.ts +37 -37
  66. package/src/cli/options.ts +43 -43
  67. package/src/cli/program.ts +455 -459
  68. package/src/cli/progress.ts +1 -1
  69. package/src/cli/run.ts +24 -23
  70. package/src/collection/add.ts +9 -8
  71. package/src/collection/index.ts +3 -3
  72. package/src/collection/remove.ts +7 -6
  73. package/src/collection/types.ts +6 -6
  74. package/src/config/defaults.ts +1 -1
  75. package/src/config/index.ts +5 -5
  76. package/src/config/loader.ts +19 -18
  77. package/src/config/paths.ts +9 -8
  78. package/src/config/saver.ts +14 -13
  79. package/src/config/types.ts +53 -52
  80. package/src/converters/adapters/markitdownTs/adapter.ts +21 -19
  81. package/src/converters/adapters/officeparser/adapter.ts +18 -16
  82. package/src/converters/canonicalize.ts +12 -12
  83. package/src/converters/errors.ts +26 -22
  84. package/src/converters/index.ts +8 -8
  85. package/src/converters/mime.ts +25 -25
  86. package/src/converters/native/markdown.ts +10 -9
  87. package/src/converters/native/plaintext.ts +8 -7
  88. package/src/converters/path.ts +2 -2
  89. package/src/converters/pipeline.ts +11 -10
  90. package/src/converters/registry.ts +8 -8
  91. package/src/converters/types.ts +14 -14
  92. package/src/converters/versions.ts +4 -4
  93. package/src/index.ts +4 -4
  94. package/src/ingestion/chunker.ts +10 -9
  95. package/src/ingestion/index.ts +6 -6
  96. package/src/ingestion/language.ts +62 -62
  97. package/src/ingestion/sync.ts +50 -49
  98. package/src/ingestion/types.ts +10 -10
  99. package/src/ingestion/walker.ts +14 -13
  100. package/src/llm/cache.ts +51 -49
  101. package/src/llm/errors.ts +40 -36
  102. package/src/llm/index.ts +9 -9
  103. package/src/llm/lockfile.ts +6 -6
  104. package/src/llm/nodeLlamaCpp/adapter.ts +13 -12
  105. package/src/llm/nodeLlamaCpp/embedding.ts +9 -8
  106. package/src/llm/nodeLlamaCpp/generation.ts +7 -6
  107. package/src/llm/nodeLlamaCpp/lifecycle.ts +11 -10
  108. package/src/llm/nodeLlamaCpp/rerank.ts +6 -5
  109. package/src/llm/policy.ts +5 -5
  110. package/src/llm/registry.ts +6 -5
  111. package/src/llm/types.ts +2 -2
  112. package/src/mcp/resources/index.ts +15 -13
  113. package/src/mcp/server.ts +25 -23
  114. package/src/mcp/tools/get.ts +25 -23
  115. package/src/mcp/tools/index.ts +32 -29
  116. package/src/mcp/tools/multi-get.ts +34 -32
  117. package/src/mcp/tools/query.ts +29 -27
  118. package/src/mcp/tools/search.ts +14 -12
  119. package/src/mcp/tools/status.ts +12 -11
  120. package/src/mcp/tools/vsearch.ts +26 -24
  121. package/src/pipeline/answer.ts +9 -9
  122. package/src/pipeline/chunk-lookup.ts +1 -1
  123. package/src/pipeline/contextual.ts +4 -4
  124. package/src/pipeline/expansion.ts +23 -21
  125. package/src/pipeline/explain.ts +21 -21
  126. package/src/pipeline/fusion.ts +9 -9
  127. package/src/pipeline/hybrid.ts +41 -42
  128. package/src/pipeline/index.ts +10 -10
  129. package/src/pipeline/query-language.ts +39 -39
  130. package/src/pipeline/rerank.ts +8 -7
  131. package/src/pipeline/search.ts +22 -22
  132. package/src/pipeline/types.ts +8 -8
  133. package/src/pipeline/vsearch.ts +21 -24
  134. package/src/serve/CLAUDE.md +21 -15
  135. package/src/serve/config-sync.ts +9 -8
  136. package/src/serve/context.ts +19 -18
  137. package/src/serve/index.ts +1 -1
  138. package/src/serve/jobs.ts +7 -7
  139. package/src/serve/public/app.tsx +79 -25
  140. package/src/serve/public/components/AddCollectionDialog.tsx +382 -0
  141. package/src/serve/public/components/CaptureButton.tsx +60 -0
  142. package/src/serve/public/components/CaptureModal.tsx +365 -0
  143. package/src/serve/public/components/IndexingProgress.tsx +333 -0
  144. package/src/serve/public/components/ShortcutHelpModal.tsx +106 -0
  145. package/src/serve/public/components/ai-elements/code-block.tsx +42 -32
  146. package/src/serve/public/components/ai-elements/conversation.tsx +16 -14
  147. package/src/serve/public/components/ai-elements/inline-citation.tsx +33 -32
  148. package/src/serve/public/components/ai-elements/loader.tsx +5 -4
  149. package/src/serve/public/components/ai-elements/message.tsx +39 -37
  150. package/src/serve/public/components/ai-elements/prompt-input.tsx +97 -95
  151. package/src/serve/public/components/ai-elements/sources.tsx +12 -10
  152. package/src/serve/public/components/ai-elements/suggestion.tsx +10 -9
  153. package/src/serve/public/components/editor/CodeMirrorEditor.tsx +142 -0
  154. package/src/serve/public/components/editor/MarkdownPreview.tsx +311 -0
  155. package/src/serve/public/components/editor/index.ts +6 -0
  156. package/src/serve/public/components/preset-selector.tsx +29 -28
  157. package/src/serve/public/components/ui/badge.tsx +13 -12
  158. package/src/serve/public/components/ui/button-group.tsx +13 -12
  159. package/src/serve/public/components/ui/button.tsx +23 -22
  160. package/src/serve/public/components/ui/card.tsx +16 -16
  161. package/src/serve/public/components/ui/carousel.tsx +36 -35
  162. package/src/serve/public/components/ui/collapsible.tsx +1 -1
  163. package/src/serve/public/components/ui/command.tsx +17 -15
  164. package/src/serve/public/components/ui/dialog.tsx +13 -12
  165. package/src/serve/public/components/ui/dropdown-menu.tsx +13 -12
  166. package/src/serve/public/components/ui/hover-card.tsx +6 -5
  167. package/src/serve/public/components/ui/input-group.tsx +45 -43
  168. package/src/serve/public/components/ui/input.tsx +6 -6
  169. package/src/serve/public/components/ui/progress.tsx +5 -4
  170. package/src/serve/public/components/ui/scroll-area.tsx +11 -10
  171. package/src/serve/public/components/ui/select.tsx +19 -18
  172. package/src/serve/public/components/ui/separator.tsx +6 -5
  173. package/src/serve/public/components/ui/table.tsx +18 -18
  174. package/src/serve/public/components/ui/textarea.tsx +4 -4
  175. package/src/serve/public/components/ui/tooltip.tsx +5 -4
  176. package/src/serve/public/globals.css +27 -4
  177. package/src/serve/public/hooks/use-api.ts +8 -8
  178. package/src/serve/public/hooks/useCaptureModal.tsx +83 -0
  179. package/src/serve/public/hooks/useKeyboardShortcuts.ts +85 -0
  180. package/src/serve/public/index.html +4 -4
  181. package/src/serve/public/lib/utils.ts +6 -0
  182. package/src/serve/public/pages/Ask.tsx +27 -26
  183. package/src/serve/public/pages/Browse.tsx +28 -27
  184. package/src/serve/public/pages/Collections.tsx +439 -0
  185. package/src/serve/public/pages/Dashboard.tsx +166 -40
  186. package/src/serve/public/pages/DocView.tsx +258 -73
  187. package/src/serve/public/pages/DocumentEditor.tsx +510 -0
  188. package/src/serve/public/pages/Search.tsx +80 -58
  189. package/src/serve/routes/api.ts +272 -155
  190. package/src/serve/security.ts +4 -4
  191. package/src/serve/server.ts +66 -48
  192. package/src/store/index.ts +5 -5
  193. package/src/store/migrations/001-initial.ts +24 -23
  194. package/src/store/migrations/002-documents-fts.ts +7 -6
  195. package/src/store/migrations/index.ts +4 -4
  196. package/src/store/migrations/runner.ts +17 -15
  197. package/src/store/sqlite/adapter.ts +123 -121
  198. package/src/store/sqlite/fts5-snowball.ts +24 -23
  199. package/src/store/sqlite/index.ts +1 -1
  200. package/src/store/sqlite/setup.ts +12 -12
  201. package/src/store/sqlite/types.ts +4 -4
  202. package/src/store/types.ts +19 -19
  203. package/src/store/vector/index.ts +3 -3
  204. package/src/store/vector/sqlite-vec.ts +23 -20
  205. package/src/store/vector/stats.ts +10 -8
  206. package/src/store/vector/types.ts +2 -2
  207. package/vendor/fts5-snowball/README.md +6 -6
  208. package/assets/screenshots/webui-ask-answer.jpg +0 -0
  209. package/assets/screenshots/webui-home.jpg +0 -0
@@ -5,10 +5,11 @@
5
5
  * @module src/cli/commands/get
6
6
  */
7
7
 
8
- import type { DocumentRow, StorePort, StoreResult } from '../../store/types';
9
- import type { ParsedRef } from './ref-parser';
10
- import { parseRef } from './ref-parser';
11
- import { initStore } from './shared';
8
+ import type { DocumentRow, StorePort, StoreResult } from "../../store/types";
9
+ import type { ParsedRef } from "./ref-parser";
10
+
11
+ import { parseRef } from "./ref-parser";
12
+ import { initStore } from "./shared";
12
13
 
13
14
  // ─────────────────────────────────────────────────────────────────────────────
14
15
  // Types
@@ -68,11 +69,11 @@ function lookupDocument(
68
69
  parsed: ParsedRef
69
70
  ): Promise<StoreResult<DocumentRow | null>> {
70
71
  switch (parsed.type) {
71
- case 'docid':
72
+ case "docid":
72
73
  return store.getDocumentByDocid(parsed.value);
73
- case 'uri':
74
+ case "uri":
74
75
  return store.getDocumentByUri(parsed.value);
75
- case 'collPath':
76
+ case "collPath":
76
77
  if (!(parsed.collection && parsed.relPath)) {
77
78
  return Promise.resolve({ ok: true as const, value: null });
78
79
  }
@@ -100,7 +101,7 @@ export async function get(
100
101
  }
101
102
 
102
103
  const parsed = parseRef(ref);
103
- if ('error' in parsed) {
104
+ if ("error" in parsed) {
104
105
  return { success: false, error: parsed.error, isValidation: true };
105
106
  }
106
107
 
@@ -121,14 +122,14 @@ function validateOptions(options: GetCommandOptions): GetResult | null {
121
122
  if (options.from !== undefined && options.from <= 0) {
122
123
  return {
123
124
  success: false,
124
- error: '--from must be a positive integer',
125
+ error: "--from must be a positive integer",
125
126
  isValidation: true,
126
127
  };
127
128
  }
128
129
  if (options.limit !== undefined && options.limit < 0) {
129
130
  return {
130
131
  success: false,
131
- error: '-l/--limit cannot be negative',
132
+ error: "-l/--limit cannot be negative",
132
133
  isValidation: true,
133
134
  };
134
135
  }
@@ -152,19 +153,19 @@ async function fetchDocument(
152
153
 
153
154
  const doc = docResult.value;
154
155
  if (!doc?.active) {
155
- return { success: false, error: 'Document not found' };
156
+ return { success: false, error: "Document not found" };
156
157
  }
157
158
 
158
159
  if (!doc.mirrorHash) {
159
160
  return {
160
161
  success: false,
161
- error: 'Mirror content unavailable (conversion error)',
162
+ error: "Mirror content unavailable (conversion error)",
162
163
  };
163
164
  }
164
165
 
165
166
  const contentResult = await store.getContent(doc.mirrorHash);
166
167
  if (!contentResult.ok || contentResult.value === null) {
167
- return { success: false, error: 'Mirror content unavailable' };
168
+ return { success: false, error: "Mirror content unavailable" };
168
169
  }
169
170
 
170
171
  return buildResponse({
@@ -186,7 +187,7 @@ interface BuildResponseContext {
186
187
 
187
188
  function buildResponse(ctx: BuildResponseContext): GetResult {
188
189
  const { doc, fullContent, parsed, options, config } = ctx;
189
- const lines = fullContent.split('\n');
190
+ const lines = fullContent.split("\n");
190
191
  const totalLines = lines.length;
191
192
 
192
193
  // Handle -l 0 case - return empty content
@@ -197,7 +198,7 @@ function buildResponse(ctx: BuildResponseContext): GetResult {
197
198
  docid: doc.docid,
198
199
  uri: doc.uri,
199
200
  title: doc.title ?? undefined,
200
- content: '',
201
+ content: "",
201
202
  totalLines,
202
203
  language: doc.languageHint ?? undefined,
203
204
  source: buildSourceMeta(doc, config),
@@ -215,7 +216,7 @@ function buildResponse(ctx: BuildResponseContext): GetResult {
215
216
  const clampedEnd = Math.min(clampedStart + limit - 1, totalLines);
216
217
 
217
218
  const selectedLines = lines.slice(clampedStart - 1, clampedEnd);
218
- const content = selectedLines.join('\n');
219
+ const content = selectedLines.join("\n");
219
220
  const isPartial = clampedStart > 1 || clampedEnd < totalLines;
220
221
 
221
222
  return {
@@ -252,7 +253,7 @@ interface DocRow {
252
253
  function buildSourceMeta(
253
254
  doc: DocRow,
254
255
  config: ConfigLike
255
- ): GetResponse['source'] {
256
+ ): GetResponse["source"] {
256
257
  const coll = config.collections.find((c) => c.name === doc.collection);
257
258
  const absPath = coll ? `${coll.path}/${doc.relPath}` : undefined;
258
259
 
@@ -274,7 +275,7 @@ interface ConversionDoc {
274
275
 
275
276
  function buildConversionMeta(
276
277
  doc: ConversionDoc
277
- ): GetResponse['conversion'] | undefined {
278
+ ): GetResponse["conversion"] | undefined {
278
279
  if (!doc.converterId) {
279
280
  return;
280
281
  }
@@ -291,9 +292,9 @@ function buildConversionMeta(
291
292
 
292
293
  function addLineNumbers(text: string, startLine: number): string {
293
294
  return text
294
- .split('\n')
295
+ .split("\n")
295
296
  .map((line, i) => `${startLine + i}: ${line}`)
296
- .join('\n');
297
+ .join("\n");
297
298
  }
298
299
 
299
300
  function getContentWithLineNumbers(
@@ -317,7 +318,7 @@ export function formatGet(
317
318
  if (!result.success) {
318
319
  if (options.json) {
319
320
  return JSON.stringify({
320
- error: { code: 'GET_FAILED', message: result.error },
321
+ error: { code: "GET_FAILED", message: result.error },
321
322
  });
322
323
  }
323
324
  return `Error: ${result.error}`;
@@ -340,7 +341,7 @@ export function formatGet(
340
341
  function formatMarkdown(data: GetResponse, options: GetCommandOptions): string {
341
342
  const lines: string[] = [];
342
343
  lines.push(`# ${data.title || data.source.relPath}`);
343
- lines.push('');
344
+ lines.push("");
344
345
  lines.push(`- **URI**: \`${data.uri}\``);
345
346
  lines.push(`- **DocID**: \`${data.docid}\``);
346
347
  if (data.returnedLines) {
@@ -348,9 +349,9 @@ function formatMarkdown(data: GetResponse, options: GetCommandOptions): string {
348
349
  `- **Lines**: ${data.returnedLines.start}-${data.returnedLines.end} of ${data.totalLines}`
349
350
  );
350
351
  }
351
- lines.push('');
352
- lines.push('```');
352
+ lines.push("");
353
+ lines.push("```");
353
354
  lines.push(getContentWithLineNumbers(data, options));
354
- lines.push('```');
355
- return lines.join('\n');
355
+ lines.push("```");
356
+ return lines.join("\n");
356
357
  }
@@ -5,8 +5,8 @@
5
5
  * @module src/cli/commands/indexCmd
6
6
  */
7
7
 
8
- import { defaultSyncService, type SyncResult } from '../../ingestion';
9
- import { formatSyncResultLines, initStore } from './shared';
8
+ import { defaultSyncService, type SyncResult } from "../../ingestion";
9
+ import { formatSyncResultLines, initStore } from "./shared";
10
10
 
11
11
  /**
12
12
  * Options for index command.
@@ -68,7 +68,7 @@ export async function index(options: IndexOptions = {}): Promise<IndexResult> {
68
68
  | undefined;
69
69
 
70
70
  if (!embedSkipped) {
71
- const { embed } = await import('./embed');
71
+ const { embed } = await import("./embed");
72
72
  const result = await embed({
73
73
  configPath: options.configPath,
74
74
  });
@@ -99,21 +99,21 @@ export function formatIndex(
99
99
  }
100
100
 
101
101
  const { syncResult, embedSkipped } = result;
102
- const lines: string[] = ['Indexing complete.', ''];
102
+ const lines: string[] = ["Indexing complete.", ""];
103
103
 
104
104
  lines.push(...formatSyncResultLines(syncResult, options));
105
105
 
106
106
  if (embedSkipped) {
107
- lines.push('');
108
- lines.push('Embedding skipped (--no-embed)');
107
+ lines.push("");
108
+ lines.push("Embedding skipped (--no-embed)");
109
109
  } else if (result.embedResult) {
110
- lines.push('');
110
+ lines.push("");
111
111
  const { embedded, errors, duration } = result.embedResult;
112
- const errPart = errors > 0 ? ` (${errors} errors)` : '';
112
+ const errPart = errors > 0 ? ` (${errors} errors)` : "";
113
113
  lines.push(
114
114
  `Embedded ${embedded} chunks in ${(duration / 1000).toFixed(1)}s${errPart}`
115
115
  );
116
116
  }
117
117
 
118
- return lines.join('\n');
118
+ return lines.join("\n");
119
119
  }
@@ -9,13 +9,13 @@ export {
9
9
  type AskCommandResult,
10
10
  ask,
11
11
  formatAsk,
12
- } from './ask';
12
+ } from "./ask";
13
13
  export {
14
14
  type CleanupOptions,
15
15
  type CleanupResult,
16
16
  cleanup,
17
17
  formatCleanup,
18
- } from './cleanup';
18
+ } from "./cleanup";
19
19
  export {
20
20
  type DoctorCheck,
21
21
  type DoctorCheckStatus,
@@ -23,27 +23,27 @@ export {
23
23
  type DoctorResult,
24
24
  doctor,
25
25
  formatDoctor,
26
- } from './doctor';
26
+ } from "./doctor";
27
27
  export {
28
28
  type EmbedOptions,
29
29
  type EmbedResult,
30
30
  embed,
31
31
  formatEmbed,
32
- } from './embed';
32
+ } from "./embed";
33
33
  export {
34
34
  formatGet,
35
35
  type GetCommandOptions,
36
36
  type GetResponse,
37
37
  type GetResult,
38
38
  get,
39
- } from './get';
39
+ } from "./get";
40
40
  export {
41
41
  formatIndex,
42
42
  type IndexOptions,
43
43
  type IndexResult,
44
44
  index,
45
- } from './index-cmd';
46
- export { type InitOptions, type InitResult, init } from './init';
45
+ } from "./index-cmd";
46
+ export { type InitOptions, type InitResult, init } from "./init";
47
47
  export {
48
48
  formatLs,
49
49
  type LsCommandOptions,
@@ -51,8 +51,8 @@ export {
51
51
  type LsResponse,
52
52
  type LsResult,
53
53
  ls,
54
- } from './ls';
55
- export * from './models';
54
+ } from "./ls";
55
+ export * from "./models";
56
56
  export {
57
57
  formatMultiGet,
58
58
  type MultiGetCommandOptions,
@@ -61,13 +61,13 @@ export {
61
61
  type MultiGetResult,
62
62
  multiGet,
63
63
  type SkippedDoc,
64
- } from './multi-get';
64
+ } from "./multi-get";
65
65
  export {
66
66
  formatQuery,
67
67
  type QueryCommandOptions,
68
68
  type QueryResult,
69
69
  query,
70
- } from './query';
70
+ } from "./query";
71
71
  export {
72
72
  isGlobPattern,
73
73
  type ParsedRef,
@@ -75,28 +75,28 @@ export {
75
75
  parseRef,
76
76
  type RefType,
77
77
  splitRefs,
78
- } from './ref-parser';
78
+ } from "./ref-parser";
79
79
  export {
80
80
  formatSearch,
81
81
  type SearchCommandOptions,
82
82
  type SearchResult,
83
83
  search,
84
- } from './search';
84
+ } from "./search";
85
85
  export {
86
86
  formatStatus,
87
87
  type StatusOptions,
88
88
  type StatusResult,
89
89
  status,
90
- } from './status';
90
+ } from "./status";
91
91
  export {
92
92
  formatUpdate,
93
93
  type UpdateOptions,
94
94
  type UpdateResult,
95
95
  update,
96
- } from './update';
96
+ } from "./update";
97
97
  export {
98
98
  formatVsearch,
99
99
  type VsearchCommandOptions,
100
100
  type VsearchResult,
101
101
  vsearch,
102
- } from './vsearch';
102
+ } from "./vsearch";
@@ -5,8 +5,9 @@
5
5
  * @module src/cli/commands/init
6
6
  */
7
7
 
8
- import { basename } from 'node:path';
9
- import { getIndexDbPath } from '../../app/constants';
8
+ import { basename } from "node:path";
9
+
10
+ import { getIndexDbPath } from "../../app/constants";
10
11
  import {
11
12
  type Collection,
12
13
  createDefaultConfig,
@@ -22,7 +23,7 @@ import {
22
23
  pathExists,
23
24
  saveConfig,
24
25
  toAbsolutePath,
25
- } from '../../config';
26
+ } from "../../config";
26
27
 
27
28
  /** Pattern to replace invalid chars in collection names with hyphens */
28
29
  const INVALID_NAME_CHARS = /[^a-z0-9_-]/g;
@@ -98,7 +99,7 @@ async function handleAlreadyInitialized(
98
99
  configPath: paths.configFile,
99
100
  dataDir: paths.dataDir,
100
101
  dbPath,
101
- error: 'Config exists but could not be loaded',
102
+ error: "Config exists but could not be loaded",
102
103
  };
103
104
  }
104
105
 
@@ -165,7 +166,7 @@ export async function init(options: InitOptions = {}): Promise<InitResult> {
165
166
  configPath: paths.configFile,
166
167
  dataDir: paths.dataDir,
167
168
  dbPath: getIndexDbPath(),
168
- error: `Invalid tokenizer: ${options.tokenizer}. Valid: ${FTS_TOKENIZERS.join(', ')}`,
169
+ error: `Invalid tokenizer: ${options.tokenizer}. Valid: ${FTS_TOKENIZERS.join(", ")}`,
169
170
  };
170
171
  }
171
172
 
@@ -211,7 +212,7 @@ export async function init(options: InitOptions = {}): Promise<InitResult> {
211
212
  const dbExists = await dbFile.exists();
212
213
  if (!dbExists) {
213
214
  try {
214
- await Bun.write(dbPath, '');
215
+ await Bun.write(dbPath, "");
215
216
  } catch (error) {
216
217
  return {
217
218
  success: false,
@@ -242,7 +243,7 @@ async function addCollectionToConfig(
242
243
  { success: true; collectionName: string } | { success: false; error: string }
243
244
  > {
244
245
  if (!options.path) {
245
- return { success: false, error: 'Path is required' };
246
+ return { success: false, error: "Path is required" };
246
247
  }
247
248
 
248
249
  // Convert to absolute path
@@ -260,17 +261,17 @@ async function addCollectionToConfig(
260
261
  // Determine collection name
261
262
  let collectionName =
262
263
  options.name ??
263
- basename(absolutePath).toLowerCase().replace(INVALID_NAME_CHARS, '-');
264
+ basename(absolutePath).toLowerCase().replace(INVALID_NAME_CHARS, "-");
264
265
 
265
266
  // Ensure name starts with alphanumeric (strip leading non-alphanumeric)
266
- collectionName = collectionName.replace(LEADING_NON_ALPHANUMERIC, '');
267
+ collectionName = collectionName.replace(LEADING_NON_ALPHANUMERIC, "");
267
268
 
268
269
  // Validate derived name
269
270
  if (!collectionName || collectionName.length > 64) {
270
271
  return {
271
272
  success: false,
272
273
  error:
273
- 'Cannot derive valid collection name from path. Please specify --name explicitly.',
274
+ "Cannot derive valid collection name from path. Please specify --name explicitly.",
274
275
  };
275
276
  }
276
277
 
@@ -285,14 +286,14 @@ async function addCollectionToConfig(
285
286
  // Parse include/exclude CSV if provided (filter empty entries)
286
287
  const include = options.include
287
288
  ? options.include
288
- .split(',')
289
+ .split(",")
289
290
  .map((ext) => ext.trim())
290
291
  .filter(Boolean)
291
292
  : [];
292
293
 
293
294
  const exclude = options.exclude
294
295
  ? options.exclude
295
- .split(',')
296
+ .split(",")
296
297
  .map((pattern) => pattern.trim())
297
298
  .filter(Boolean)
298
299
  : [...DEFAULT_EXCLUDES];
@@ -5,8 +5,9 @@
5
5
  * @module src/cli/commands/ls
6
6
  */
7
7
 
8
- import type { DocumentRow, StorePort, StoreResult } from '../../store/types';
9
- import { initStore } from './shared';
8
+ import type { DocumentRow, StorePort, StoreResult } from "../../store/types";
9
+
10
+ import { initStore } from "./shared";
10
11
 
11
12
  // ─────────────────────────────────────────────────────────────────────────────
12
13
  // Types
@@ -65,7 +66,7 @@ async function fetchDocuments(
65
66
  return store.listDocuments();
66
67
  }
67
68
 
68
- if (scope.startsWith('gno://')) {
69
+ if (scope.startsWith("gno://")) {
69
70
  const allDocs = await store.listDocuments();
70
71
  if (!allDocs.ok) {
71
72
  return allDocs;
@@ -91,18 +92,18 @@ export async function ls(
91
92
  options: LsCommandOptions = {}
92
93
  ): Promise<LsResult> {
93
94
  // Validate scope if it's a gno:// URI
94
- if (scope?.startsWith('gno://')) {
95
- if (scope === 'gno://') {
95
+ if (scope?.startsWith("gno://")) {
96
+ if (scope === "gno://") {
96
97
  return {
97
98
  success: false,
98
- error: 'Invalid scope: missing collection',
99
+ error: "Invalid scope: missing collection",
99
100
  isValidation: true,
100
101
  };
101
102
  }
102
103
  if (!URI_PREFIX_PATTERN.test(scope)) {
103
104
  return {
104
105
  success: false,
105
- error: 'Invalid scope: missing trailing path (use gno://collection/)',
106
+ error: "Invalid scope: missing trailing path (use gno://collection/)",
106
107
  isValidation: true,
107
108
  };
108
109
  }
@@ -167,7 +168,7 @@ export function formatLs(result: LsResult, options: LsCommandOptions): string {
167
168
  if (!result.success) {
168
169
  if (options.json) {
169
170
  return JSON.stringify({
170
- error: { code: 'LS_FAILED', message: result.error },
171
+ error: { code: "LS_FAILED", message: result.error },
171
172
  });
172
173
  }
173
174
  return `Error: ${result.error}`;
@@ -181,31 +182,31 @@ export function formatLs(result: LsResult, options: LsCommandOptions): string {
181
182
  }
182
183
 
183
184
  if (options.files) {
184
- return docs.map((d) => `${d.docid},${d.uri}`).join('\n');
185
+ return docs.map((d) => `${d.docid},${d.uri}`).join("\n");
185
186
  }
186
187
 
187
188
  if (options.md) {
188
189
  if (docs.length === 0) {
189
- return '# Documents\n\nNo documents found.';
190
+ return "# Documents\n\nNo documents found.";
190
191
  }
191
192
  const lines: string[] = [];
192
- lines.push('# Documents');
193
- lines.push('');
193
+ lines.push("# Documents");
194
+ lines.push("");
194
195
  lines.push(
195
196
  `*Showing ${data.meta.returned} of ${data.meta.total} documents*`
196
197
  );
197
- lines.push('');
198
- lines.push('| DocID | URI | Title |');
199
- lines.push('|-------|-----|-------|');
198
+ lines.push("");
199
+ lines.push("| DocID | URI | Title |");
200
+ lines.push("|-------|-----|-------|");
200
201
  for (const d of docs) {
201
- lines.push(`| \`${d.docid}\` | \`${d.uri}\` | ${d.title || '-'} |`);
202
+ lines.push(`| \`${d.docid}\` | \`${d.uri}\` | ${d.title || "-"} |`);
202
203
  }
203
- return lines.join('\n');
204
+ return lines.join("\n");
204
205
  }
205
206
 
206
207
  // Terminal format
207
208
  if (docs.length === 0) {
208
- return 'No documents found.';
209
+ return "No documents found.";
209
210
  }
210
211
  const lines = docs.map((d) => `${d.docid}\t${d.uri}`);
211
212
  if (data.meta.returned < data.meta.total) {
@@ -213,5 +214,5 @@ export function formatLs(result: LsResult, options: LsCommandOptions): string {
213
214
  `\n(${data.meta.returned} of ${data.meta.total} documents shown)`
214
215
  );
215
216
  }
216
- return lines.join('\n');
217
+ return lines.join("\n");
217
218
  }
@@ -5,10 +5,12 @@
5
5
  * @module src/cli/commands/mcp/config
6
6
  */
7
7
 
8
- import { copyFile, mkdir, rename, stat, unlink } from 'node:fs/promises';
9
- import { dirname } from 'node:path';
10
- import { CliError } from '../../errors.js';
11
- import type { McpConfigFormat } from './paths.js';
8
+ import { copyFile, mkdir, rename, stat, unlink } from "node:fs/promises";
9
+ import { dirname } from "node:path";
10
+
11
+ import type { McpConfigFormat } from "./paths.js";
12
+
13
+ import { CliError } from "../../errors.js";
12
14
 
13
15
  // ─────────────────────────────────────────────────────────────────────────────
14
16
  // Types
@@ -22,7 +24,7 @@ export interface StandardMcpEntry {
22
24
 
23
25
  /** OpenCode mcp entry (command is array, has type and enabled) */
24
26
  export interface OpenCodeMcpEntry {
25
- type: 'local';
27
+ type: "local";
26
28
  command: string[];
27
29
  enabled: boolean;
28
30
  }
@@ -47,7 +49,7 @@ export interface OpenCodeConfig {
47
49
 
48
50
  /** Amp config with amp.mcpServers key */
49
51
  export interface AmpConfig {
50
- 'amp.mcpServers'?: Record<string, StandardMcpEntry>;
52
+ "amp.mcpServers"?: Record<string, StandardMcpEntry>;
51
53
  [key: string]: unknown;
52
54
  }
53
55
 
@@ -64,19 +66,19 @@ export type AnyMcpConfig = McpConfig | ZedConfig | OpenCodeConfig | AmpConfig;
64
66
  */
65
67
  async function checkConfigPath(
66
68
  configPath: string
67
- ): Promise<'file' | 'missing'> {
69
+ ): Promise<"file" | "missing"> {
68
70
  try {
69
71
  const stats = await stat(configPath);
70
72
  if (!stats.isFile()) {
71
73
  throw new CliError(
72
- 'RUNTIME',
74
+ "RUNTIME",
73
75
  `Config path exists but is not a file: ${configPath}`
74
76
  );
75
77
  }
76
- return 'file';
78
+ return "file";
77
79
  } catch (err) {
78
- if ((err as NodeJS.ErrnoException).code === 'ENOENT') {
79
- return 'missing';
80
+ if ((err as NodeJS.ErrnoException).code === "ENOENT") {
81
+ return "missing";
80
82
  }
81
83
  throw err;
82
84
  }
@@ -94,7 +96,7 @@ export async function readMcpConfig(
94
96
  ): Promise<McpConfig | null> {
95
97
  const pathStatus = await checkConfigPath(configPath);
96
98
 
97
- if (pathStatus === 'missing') {
99
+ if (pathStatus === "missing") {
98
100
  return options?.returnNullOnMissing ? null : {};
99
101
  }
100
102
 
@@ -112,9 +114,9 @@ export async function readMcpConfig(
112
114
  }
113
115
  return JSON.parse(content) as McpConfig;
114
116
  } catch {
115
- const format = options?.yaml ? 'YAML' : 'JSON';
117
+ const format = options?.yaml ? "YAML" : "JSON";
116
118
  throw new CliError(
117
- 'RUNTIME',
119
+ "RUNTIME",
118
120
  `Malformed ${format} in ${configPath}. Please fix or backup and delete the file.`
119
121
  );
120
122
  }
@@ -175,20 +177,20 @@ export async function writeMcpConfig(
175
177
  */
176
178
  export function getServersKey(
177
179
  format: McpConfigFormat
178
- ): 'mcpServers' | 'context_servers' | 'mcp' | 'amp.mcpServers' {
180
+ ): "mcpServers" | "context_servers" | "mcp" | "amp.mcpServers" {
179
181
  switch (format) {
180
- case 'standard':
181
- case 'yaml_standard':
182
- return 'mcpServers';
183
- case 'context_servers':
184
- return 'context_servers';
185
- case 'mcp':
186
- return 'mcp';
187
- case 'amp_mcp':
188
- return 'amp.mcpServers';
182
+ case "standard":
183
+ case "yaml_standard":
184
+ return "mcpServers";
185
+ case "context_servers":
186
+ return "context_servers";
187
+ case "mcp":
188
+ return "mcp";
189
+ case "amp_mcp":
190
+ return "amp.mcpServers";
189
191
  default: {
190
192
  const _exhaustive: never = format;
191
- throw new Error(`Unknown format: ${_exhaustive}`);
193
+ throw new Error(`Unknown format: ${String(_exhaustive)}`);
192
194
  }
193
195
  }
194
196
  }
@@ -197,7 +199,7 @@ export function getServersKey(
197
199
  * Check if format uses YAML.
198
200
  */
199
201
  export function isYamlFormat(format: McpConfigFormat): boolean {
200
- return format === 'yaml_standard';
202
+ return format === "yaml_standard";
201
203
  }
202
204
 
203
205
  /**
@@ -236,10 +238,10 @@ export function buildEntry(
236
238
  args: string[],
237
239
  format: McpConfigFormat
238
240
  ): StandardMcpEntry | OpenCodeMcpEntry {
239
- if (format === 'mcp') {
241
+ if (format === "mcp") {
240
242
  // OpenCode: command is array [command, ...args]
241
243
  return {
242
- type: 'local',
244
+ type: "local",
243
245
  command: [command, ...args],
244
246
  enabled: true,
245
247
  };
@@ -4,7 +4,7 @@
4
4
  * @module src/cli/commands/mcp
5
5
  */
6
6
 
7
- export { type InstallOptions, installMcp } from './install.js';
7
+ export { type InstallOptions, installMcp } from "./install.js";
8
8
  export {
9
9
  buildMcpServerEntry,
10
10
  findBunPath,
@@ -19,6 +19,6 @@ export {
19
19
  resolveAllMcpPaths,
20
20
  resolveMcpConfigPath,
21
21
  TARGETS_WITH_PROJECT_SCOPE,
22
- } from './paths.js';
23
- export { type StatusOptions, statusMcp } from './status.js';
24
- export { type UninstallOptions, uninstallMcp } from './uninstall.js';
22
+ } from "./paths.js";
23
+ export { type StatusOptions, statusMcp } from "./status.js";
24
+ export { type UninstallOptions, uninstallMcp } from "./uninstall.js";