ragcode-context-engine 0.1.0

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 (174) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +366 -0
  3. package/README.zh-CN.md +363 -0
  4. package/dist/src/cli/configure/app.d.ts +6 -0
  5. package/dist/src/cli/configure/app.js +81 -0
  6. package/dist/src/cli/configure/run.d.ts +5 -0
  7. package/dist/src/cli/configure/run.js +85 -0
  8. package/dist/src/cli/configure/state.d.ts +42 -0
  9. package/dist/src/cli/configure/state.js +174 -0
  10. package/dist/src/cli/configure.d.ts +31 -0
  11. package/dist/src/cli/configure.js +101 -0
  12. package/dist/src/cli/index.d.ts +2 -0
  13. package/dist/src/cli/index.js +503 -0
  14. package/dist/src/cli/tui/index-progress.d.ts +12 -0
  15. package/dist/src/cli/tui/index-progress.js +49 -0
  16. package/dist/src/cli/tui/watch-status.d.ts +10 -0
  17. package/dist/src/cli/tui/watch-status.js +27 -0
  18. package/dist/src/cli/update.d.ts +18 -0
  19. package/dist/src/cli/update.js +111 -0
  20. package/dist/src/config/dotenv.d.ts +1 -0
  21. package/dist/src/config/dotenv.js +14 -0
  22. package/dist/src/config/graph-runtime.d.ts +13 -0
  23. package/dist/src/config/graph-runtime.js +29 -0
  24. package/dist/src/config/runtime-config.d.ts +87 -0
  25. package/dist/src/config/runtime-config.js +215 -0
  26. package/dist/src/config/semantic-runtime.d.ts +24 -0
  27. package/dist/src/config/semantic-runtime.js +89 -0
  28. package/dist/src/context/context-builder.d.ts +20 -0
  29. package/dist/src/context/context-builder.js +277 -0
  30. package/dist/src/context/expansion-policy.d.ts +6 -0
  31. package/dist/src/context/expansion-policy.js +49 -0
  32. package/dist/src/context/skeletonizer.d.ts +2 -0
  33. package/dist/src/context/skeletonizer.js +79 -0
  34. package/dist/src/context/snippet-renderer.d.ts +2 -0
  35. package/dist/src/context/snippet-renderer.js +67 -0
  36. package/dist/src/core/contracts.d.ts +74 -0
  37. package/dist/src/core/contracts.js +1 -0
  38. package/dist/src/core/engine.d.ts +64 -0
  39. package/dist/src/core/engine.js +442 -0
  40. package/dist/src/core/types.d.ts +490 -0
  41. package/dist/src/core/types.js +1 -0
  42. package/dist/src/diagnostics/doctor.d.ts +66 -0
  43. package/dist/src/diagnostics/doctor.js +193 -0
  44. package/dist/src/diagnostics/embedding-test.d.ts +24 -0
  45. package/dist/src/diagnostics/embedding-test.js +83 -0
  46. package/dist/src/graph/diff-files.d.ts +1 -0
  47. package/dist/src/graph/diff-files.js +14 -0
  48. package/dist/src/graph/impact-report.d.ts +10 -0
  49. package/dist/src/graph/impact-report.js +173 -0
  50. package/dist/src/graph/in-memory-graph-store.d.ts +36 -0
  51. package/dist/src/graph/in-memory-graph-store.js +395 -0
  52. package/dist/src/graph/owner-ranking.d.ts +2 -0
  53. package/dist/src/graph/owner-ranking.js +41 -0
  54. package/dist/src/graph/sqlite-graph-store.d.ts +51 -0
  55. package/dist/src/graph/sqlite-graph-store.js +724 -0
  56. package/dist/src/graph/sqlite-statements.d.ts +36 -0
  57. package/dist/src/graph/sqlite-statements.js +105 -0
  58. package/dist/src/graph/target-matcher.d.ts +13 -0
  59. package/dist/src/graph/target-matcher.js +64 -0
  60. package/dist/src/index.d.ts +32 -0
  61. package/dist/src/index.js +32 -0
  62. package/dist/src/indexing/analyzers/fallback-analyzer.d.ts +6 -0
  63. package/dist/src/indexing/analyzers/fallback-analyzer.js +45 -0
  64. package/dist/src/indexing/analyzers/go-treesitter-analyzer.d.ts +2 -0
  65. package/dist/src/indexing/analyzers/go-treesitter-analyzer.js +87 -0
  66. package/dist/src/indexing/analyzers/java-treesitter-analyzer.d.ts +2 -0
  67. package/dist/src/indexing/analyzers/java-treesitter-analyzer.js +88 -0
  68. package/dist/src/indexing/analyzers/python-treesitter-analyzer.d.ts +2 -0
  69. package/dist/src/indexing/analyzers/python-treesitter-analyzer.js +96 -0
  70. package/dist/src/indexing/analyzers/registry.d.ts +5 -0
  71. package/dist/src/indexing/analyzers/registry.js +23 -0
  72. package/dist/src/indexing/analyzers/rust-treesitter-analyzer.d.ts +2 -0
  73. package/dist/src/indexing/analyzers/rust-treesitter-analyzer.js +96 -0
  74. package/dist/src/indexing/analyzers/tree-sitter-base.d.ts +30 -0
  75. package/dist/src/indexing/analyzers/tree-sitter-base.js +163 -0
  76. package/dist/src/indexing/analyzers/types.d.ts +17 -0
  77. package/dist/src/indexing/analyzers/types.js +1 -0
  78. package/dist/src/indexing/analyzers/typescript-analyzer.d.ts +5 -0
  79. package/dist/src/indexing/analyzers/typescript-analyzer.js +199 -0
  80. package/dist/src/indexing/ast-analyzer.d.ts +11 -0
  81. package/dist/src/indexing/ast-analyzer.js +11 -0
  82. package/dist/src/indexing/chunker.d.ts +11 -0
  83. package/dist/src/indexing/chunker.js +157 -0
  84. package/dist/src/indexing/ignore-policy.d.ts +6 -0
  85. package/dist/src/indexing/ignore-policy.js +40 -0
  86. package/dist/src/indexing/indexer.d.ts +13 -0
  87. package/dist/src/indexing/indexer.js +189 -0
  88. package/dist/src/indexing/language.d.ts +3 -0
  89. package/dist/src/indexing/language.js +24 -0
  90. package/dist/src/indexing/scanner.d.ts +13 -0
  91. package/dist/src/indexing/scanner.js +87 -0
  92. package/dist/src/lsp/definition-resolver.d.ts +6 -0
  93. package/dist/src/lsp/definition-resolver.js +60 -0
  94. package/dist/src/lsp/typescript-language-service.d.ts +21 -0
  95. package/dist/src/lsp/typescript-language-service.js +82 -0
  96. package/dist/src/mcp/server.d.ts +11 -0
  97. package/dist/src/mcp/server.js +64 -0
  98. package/dist/src/mcp/tools.d.ts +266 -0
  99. package/dist/src/mcp/tools.js +309 -0
  100. package/dist/src/project/project-identity.d.ts +2 -0
  101. package/dist/src/project/project-identity.js +24 -0
  102. package/dist/src/project/project-registry.d.ts +12 -0
  103. package/dist/src/project/project-registry.js +49 -0
  104. package/dist/src/project/workspace-resolver.d.ts +20 -0
  105. package/dist/src/project/workspace-resolver.js +62 -0
  106. package/dist/src/retrieval/graph-reranker.d.ts +11 -0
  107. package/dist/src/retrieval/graph-reranker.js +0 -0
  108. package/dist/src/retrieval/hybrid-retriever.d.ts +31 -0
  109. package/dist/src/retrieval/hybrid-retriever.js +111 -0
  110. package/dist/src/retrieval/path-classification.d.ts +6 -0
  111. package/dist/src/retrieval/path-classification.js +22 -0
  112. package/dist/src/retrieval/query-matching.d.ts +22 -0
  113. package/dist/src/retrieval/query-matching.js +166 -0
  114. package/dist/src/retrieval/query-planner.d.ts +5 -0
  115. package/dist/src/retrieval/query-planner.js +77 -0
  116. package/dist/src/retrieval/ranking-signals.d.ts +19 -0
  117. package/dist/src/retrieval/ranking-signals.js +97 -0
  118. package/dist/src/retrieval/topology-distance.d.ts +21 -0
  119. package/dist/src/retrieval/topology-distance.js +116 -0
  120. package/dist/src/reuse/reuse-detector.d.ts +12 -0
  121. package/dist/src/reuse/reuse-detector.js +564 -0
  122. package/dist/src/semantic/deterministic-embedding.d.ts +7 -0
  123. package/dist/src/semantic/deterministic-embedding.js +31 -0
  124. package/dist/src/semantic/in-memory-semantic-store.d.ts +11 -0
  125. package/dist/src/semantic/in-memory-semantic-store.js +65 -0
  126. package/dist/src/semantic/lance-semantic-store.d.ts +131 -0
  127. package/dist/src/semantic/lance-semantic-store.js +623 -0
  128. package/dist/src/semantic/openai-compatible-embedding.d.ts +19 -0
  129. package/dist/src/semantic/openai-compatible-embedding.js +75 -0
  130. package/dist/src/service/service-identity.d.ts +13 -0
  131. package/dist/src/service/service-identity.js +48 -0
  132. package/dist/src/service/service-manager.d.ts +29 -0
  133. package/dist/src/service/service-manager.js +231 -0
  134. package/dist/src/service/service-templates.d.ts +22 -0
  135. package/dist/src/service/service-templates.js +101 -0
  136. package/dist/src/subgraph/impact-explainer.d.ts +2 -0
  137. package/dist/src/subgraph/impact-explainer.js +54 -0
  138. package/dist/src/subgraph/node-expander.d.ts +13 -0
  139. package/dist/src/subgraph/node-expander.js +139 -0
  140. package/dist/src/subgraph/output-preset.d.ts +3 -0
  141. package/dist/src/subgraph/output-preset.js +102 -0
  142. package/dist/src/subgraph/subgraph-builder.d.ts +17 -0
  143. package/dist/src/subgraph/subgraph-builder.js +688 -0
  144. package/dist/src/topology/export-index.d.ts +7 -0
  145. package/dist/src/topology/export-index.js +14 -0
  146. package/dist/src/topology/framework-topology.d.ts +3 -0
  147. package/dist/src/topology/framework-topology.js +460 -0
  148. package/dist/src/topology/import-resolver.d.ts +2 -0
  149. package/dist/src/topology/import-resolver.js +29 -0
  150. package/dist/src/topology/orm-topology.d.ts +3 -0
  151. package/dist/src/topology/orm-topology.js +200 -0
  152. package/dist/src/topology/runtime-topology.d.ts +3 -0
  153. package/dist/src/topology/runtime-topology.js +204 -0
  154. package/dist/src/topology/symbol-resolver.d.ts +6 -0
  155. package/dist/src/topology/symbol-resolver.js +74 -0
  156. package/dist/src/topology/test-topology.d.ts +2 -0
  157. package/dist/src/topology/test-topology.js +82 -0
  158. package/dist/src/utils/hash.d.ts +2 -0
  159. package/dist/src/utils/hash.js +7 -0
  160. package/dist/src/utils/path.d.ts +2 -0
  161. package/dist/src/utils/path.js +7 -0
  162. package/dist/src/watch/event-journal.d.ts +17 -0
  163. package/dist/src/watch/event-journal.js +81 -0
  164. package/dist/src/watch/file-event-coalescer.d.ts +9 -0
  165. package/dist/src/watch/file-event-coalescer.js +39 -0
  166. package/dist/src/watch/index-scheduler.d.ts +52 -0
  167. package/dist/src/watch/index-scheduler.js +190 -0
  168. package/dist/src/watch/watch-daemon.d.ts +73 -0
  169. package/dist/src/watch/watch-daemon.js +368 -0
  170. package/dist/src/watch/watcher-liveness.d.ts +47 -0
  171. package/dist/src/watch/watcher-liveness.js +168 -0
  172. package/dist/src/web/server.d.ts +1 -0
  173. package/dist/src/web/server.js +375 -0
  174. package/package.json +94 -0
@@ -0,0 +1,174 @@
1
+ export function createWizardState(mode, repoRoot, current) {
2
+ const steps = [
3
+ {
4
+ key: "graphStore",
5
+ kind: "select",
6
+ title: "Graph store",
7
+ options: [
8
+ { value: "sqlite", label: "sqlite (persistent, recommended)" },
9
+ { value: "memory", label: "memory (ephemeral)" }
10
+ ],
11
+ defaultValue: current.graphStore
12
+ },
13
+ {
14
+ key: "semanticStore",
15
+ kind: "select",
16
+ title: "Semantic store",
17
+ options: [
18
+ { value: "lancedb", label: "lancedb (persistent vectors, recommended)" },
19
+ { value: "memory", label: "memory (ephemeral)" }
20
+ ],
21
+ defaultValue: current.semanticStore
22
+ },
23
+ {
24
+ key: "embeddingProvider",
25
+ kind: "select",
26
+ title: "Embedding provider",
27
+ options: [
28
+ { value: "deterministic", label: "deterministic (offline, no API key)" },
29
+ { value: "openai-compatible", label: "openai-compatible (better recall, needs API key)" }
30
+ ],
31
+ defaultValue: current.embeddingProvider
32
+ },
33
+ {
34
+ key: "embeddingBaseUrl",
35
+ kind: "text",
36
+ title: "Embedding base URL",
37
+ defaultValue: current.embeddingBaseUrl ?? "https://api.openai.com/v1",
38
+ skip: (answers) => answers.embeddingProvider !== "openai-compatible"
39
+ },
40
+ {
41
+ key: "embeddingModel",
42
+ kind: "text",
43
+ title: "Embedding model",
44
+ defaultValue: current.embeddingModel ?? "text-embedding-3-small",
45
+ skip: (answers) => answers.embeddingProvider !== "openai-compatible"
46
+ },
47
+ {
48
+ key: "embeddingApiKey",
49
+ kind: "text",
50
+ title: current.embeddingApiKey === "set" ? "Embedding API key (Enter keeps existing)" : "Embedding API key",
51
+ defaultValue: "",
52
+ secret: true,
53
+ skip: (answers) => answers.embeddingProvider !== "openai-compatible"
54
+ },
55
+ {
56
+ key: "embeddingDimensions",
57
+ kind: "text",
58
+ title: "Embedding dimensions (empty = provider default)",
59
+ defaultValue: current.embeddingDimensions !== undefined ? String(current.embeddingDimensions) : "",
60
+ skip: (answers) => answers.embeddingProvider !== "openai-compatible"
61
+ },
62
+ {
63
+ key: "embeddingRequestDimensions",
64
+ kind: "confirm",
65
+ title: "Send the dimensions parameter to the provider?",
66
+ defaultValue: current.embeddingRequestDimensions ? "yes" : "no",
67
+ skip: (answers) => answers.embeddingProvider !== "openai-compatible" || !answers.embeddingDimensions
68
+ },
69
+ {
70
+ key: "testEmbedding",
71
+ kind: "confirm",
72
+ title: "Test the embedding provider now?",
73
+ defaultValue: "yes"
74
+ },
75
+ {
76
+ key: "save",
77
+ kind: "confirm",
78
+ title: "Save this configuration to .ragcode/config.json?",
79
+ defaultValue: "yes"
80
+ },
81
+ {
82
+ key: "indexNow",
83
+ kind: "confirm",
84
+ title: "Index the repository now?",
85
+ defaultValue: mode === "first_run" ? "yes" : "no",
86
+ skip: (answers) => answers.save !== "yes"
87
+ },
88
+ {
89
+ key: "setupMcp",
90
+ kind: "confirm",
91
+ title: "Register the MCP server for your agent client now?",
92
+ defaultValue: mode === "first_run" ? "yes" : "no",
93
+ skip: (answers) => answers.save !== "yes"
94
+ },
95
+ {
96
+ key: "installWatcherService",
97
+ kind: "confirm",
98
+ // Without this, freshness silently depends on a long-lived `ragcode watch` nobody starts.
99
+ // Installing the OS service is what actually closes the onboarding loop.
100
+ title: "Enable a background watcher service so the index stays fresh automatically?",
101
+ defaultValue: mode === "first_run" ? "yes" : "no",
102
+ skip: (answers) => answers.save !== "yes"
103
+ }
104
+ ];
105
+ return {
106
+ mode,
107
+ repoRoot,
108
+ steps,
109
+ stepIndex: firstActiveStep(steps, {}, 0),
110
+ answers: {},
111
+ done: false,
112
+ cancelled: false
113
+ };
114
+ }
115
+ export function currentStep(state) {
116
+ return state.done || state.cancelled ? undefined : state.steps[state.stepIndex];
117
+ }
118
+ // Records the answer for the current step and advances past any steps whose skip()
119
+ // predicate now holds. An empty answer falls back to the step's default.
120
+ export function answerCurrentStep(state, rawValue) {
121
+ const step = currentStep(state);
122
+ if (!step)
123
+ return state;
124
+ const value = rawValue.trim() === "" ? step.defaultValue : rawValue.trim();
125
+ const answers = { ...state.answers, [step.key]: value };
126
+ const nextIndex = firstActiveStep(state.steps, answers, state.stepIndex + 1);
127
+ return {
128
+ ...state,
129
+ answers,
130
+ stepIndex: nextIndex,
131
+ done: nextIndex >= state.steps.length
132
+ };
133
+ }
134
+ export function cancelWizard(state) {
135
+ return { ...state, cancelled: true };
136
+ }
137
+ export function wizardResult(state) {
138
+ if (!state.done || state.cancelled)
139
+ return undefined;
140
+ const answers = state.answers;
141
+ const updates = {
142
+ graphStore: answers.graphStore,
143
+ semanticStore: answers.semanticStore,
144
+ embeddingProvider: answers.embeddingProvider
145
+ };
146
+ if (answers.embeddingProvider === "openai-compatible") {
147
+ if (answers.embeddingBaseUrl)
148
+ updates.embeddingBaseUrl = answers.embeddingBaseUrl;
149
+ if (answers.embeddingModel)
150
+ updates.embeddingModel = answers.embeddingModel;
151
+ if (answers.embeddingApiKey)
152
+ updates.embeddingApiKey = answers.embeddingApiKey;
153
+ if (answers.embeddingDimensions)
154
+ updates.embeddingDimensions = Number(answers.embeddingDimensions);
155
+ if (answers.embeddingRequestDimensions)
156
+ updates.embeddingRequestDimensions = answers.embeddingRequestDimensions === "yes";
157
+ }
158
+ return {
159
+ updates,
160
+ actions: {
161
+ testEmbedding: answers.testEmbedding === "yes",
162
+ save: answers.save === "yes",
163
+ indexNow: answers.indexNow === "yes",
164
+ setupMcp: answers.setupMcp === "yes",
165
+ installWatcherService: answers.installWatcherService === "yes"
166
+ }
167
+ };
168
+ }
169
+ function firstActiveStep(steps, answers, from) {
170
+ let index = from;
171
+ while (index < steps.length && steps[index].skip?.(answers))
172
+ index += 1;
173
+ return index;
174
+ }
@@ -0,0 +1,31 @@
1
+ import { type RedactedRuntimeConfig } from "../config/runtime-config.js";
2
+ import { type EmbeddingTestResult } from "../diagnostics/embedding-test.js";
3
+ export interface ConfigureUpdates {
4
+ graphStore?: string;
5
+ sqlitePath?: string;
6
+ semanticStore?: string;
7
+ lancedbUri?: string;
8
+ embeddingProvider?: string;
9
+ embeddingBaseUrl?: string;
10
+ embeddingModel?: string;
11
+ embeddingApiKey?: string;
12
+ embeddingDimensions?: number;
13
+ embeddingRequestDimensions?: boolean;
14
+ }
15
+ export interface ConfigureResult {
16
+ configPath: string;
17
+ config: RedactedRuntimeConfig;
18
+ embeddingTest?: EmbeddingTestResult;
19
+ }
20
+ export declare function applyConfigureUpdates(options: {
21
+ repoRoot: string;
22
+ updates: ConfigureUpdates;
23
+ env?: NodeJS.ProcessEnv;
24
+ testEmbedding?: boolean;
25
+ }): Promise<ConfigureResult>;
26
+ export interface ConfigureCommandOptions extends ConfigureUpdates {
27
+ show?: boolean;
28
+ test?: boolean;
29
+ yes?: boolean;
30
+ }
31
+ export declare function runConfigureCommand(repoRootArg: string | undefined, options: ConfigureCommandOptions): Promise<void>;
@@ -0,0 +1,101 @@
1
+ import { loadRuntimeConfig, readRuntimeConfigFile, redactRuntimeConfig, writeRuntimeConfigFile } from "../config/runtime-config.js";
2
+ import { testEmbeddingForConfig } from "../diagnostics/embedding-test.js";
3
+ // Non-interactive core of `ragcode configure`: merge updates into .ragcode/config.json,
4
+ // then re-resolve the effective config through the shared loader. Returns redacted output
5
+ // so callers never see the API key back. Kept UI-free so tests and a future Ink app can
6
+ // drive it directly.
7
+ export async function applyConfigureUpdates(options) {
8
+ const env = options.env ?? process.env;
9
+ const existingPath = loadRuntimeConfig({ cwd: options.repoRoot, env, overrides: { repoRoot: options.repoRoot } }).configPath;
10
+ const merged = mergeConfigFile(readRuntimeConfigFile(existingPath), options.updates);
11
+ const configPath = writeRuntimeConfigFile(options.repoRoot, merged);
12
+ const effective = loadRuntimeConfig({ cwd: options.repoRoot, env, overrides: { repoRoot: options.repoRoot } });
13
+ const embeddingTest = options.testEmbedding ? await testEmbeddingForConfig(effective) : undefined;
14
+ return { configPath, config: redactRuntimeConfig(effective), embeddingTest };
15
+ }
16
+ function mergeConfigFile(existing, updates) {
17
+ const merged = { ...existing };
18
+ if (updates.graphStore !== undefined)
19
+ merged.graphStore = updates.graphStore;
20
+ if (updates.sqlitePath !== undefined)
21
+ merged.sqlitePath = updates.sqlitePath;
22
+ if (updates.semanticStore !== undefined)
23
+ merged.semanticStore = updates.semanticStore;
24
+ if (updates.lancedbUri !== undefined)
25
+ merged.lancedbUri = updates.lancedbUri;
26
+ if (updates.embeddingProvider !== undefined)
27
+ merged.embeddingProvider = updates.embeddingProvider === "openai" ? "openai-compatible" : updates.embeddingProvider;
28
+ if (updates.embeddingBaseUrl !== undefined)
29
+ merged.embeddingBaseUrl = updates.embeddingBaseUrl;
30
+ if (updates.embeddingModel !== undefined)
31
+ merged.embeddingModel = updates.embeddingModel;
32
+ if (updates.embeddingApiKey !== undefined)
33
+ merged.embeddingApiKey = updates.embeddingApiKey;
34
+ if (updates.embeddingDimensions !== undefined)
35
+ merged.embeddingDimensions = updates.embeddingDimensions;
36
+ if (updates.embeddingRequestDimensions !== undefined)
37
+ merged.embeddingRequestDimensions = updates.embeddingRequestDimensions;
38
+ return merged;
39
+ }
40
+ export async function runConfigureCommand(repoRootArg, options) {
41
+ const repoRoot = repoRootArg ?? process.cwd();
42
+ const hasEditFlags = configureUpdateKeys.some((key) => options[key] !== undefined);
43
+ if (options.show || (!hasEditFlags && !options.test && !process.stdin.isTTY)) {
44
+ const effective = loadRuntimeConfig({ cwd: repoRoot, overrides: { repoRoot } });
45
+ console.log(JSON.stringify(redactRuntimeConfig(effective), null, 2));
46
+ return;
47
+ }
48
+ if (options.test && !hasEditFlags) {
49
+ const effective = loadRuntimeConfig({ cwd: repoRoot, overrides: { repoRoot } });
50
+ printEmbeddingTest(await testEmbeddingForConfig(effective));
51
+ return;
52
+ }
53
+ if (!hasEditFlags) {
54
+ // Interactive path: the Ink wizard (loaded lazily so flag-driven runs never pull in
55
+ // ink/react). It collects answers via the state machine and executes test/save/index/
56
+ // setup-mcp itself.
57
+ const { runInkConfigure } = await import("./configure/run.js");
58
+ await runInkConfigure({ repoRoot, mode: "configure" });
59
+ return;
60
+ }
61
+ const updates = pickUpdates(options);
62
+ const result = await applyConfigureUpdates({
63
+ repoRoot,
64
+ updates,
65
+ testEmbedding: options.test ?? true
66
+ });
67
+ console.log(`✅ Configuration saved to: ${result.configPath}`);
68
+ console.log(JSON.stringify(result.config, null, 2));
69
+ if (result.embeddingTest)
70
+ printEmbeddingTest(result.embeddingTest);
71
+ }
72
+ const configureUpdateKeys = [
73
+ "graphStore",
74
+ "sqlitePath",
75
+ "semanticStore",
76
+ "lancedbUri",
77
+ "embeddingProvider",
78
+ "embeddingBaseUrl",
79
+ "embeddingModel",
80
+ "embeddingApiKey",
81
+ "embeddingDimensions",
82
+ "embeddingRequestDimensions"
83
+ ];
84
+ function pickUpdates(options) {
85
+ const updates = {};
86
+ for (const key of configureUpdateKeys) {
87
+ if (options[key] !== undefined)
88
+ updates[key] = options[key];
89
+ }
90
+ return updates;
91
+ }
92
+ function printEmbeddingTest(result) {
93
+ if (result.ok) {
94
+ console.log(`🧪 Embedding test OK: provider=${result.provider}${result.model ? ` model=${result.model}` : ""} dimensions=${result.dimensions} latency=${result.latencyMs}ms`);
95
+ return;
96
+ }
97
+ console.log(`🧪 Embedding test FAILED (${result.failure?.kind}): ${result.failure?.message}`);
98
+ if (result.provider === "openai-compatible") {
99
+ console.log(" Fix the provider settings with `ragcode configure`, or fall back to the offline deterministic provider.");
100
+ }
101
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};