iosm-cli 0.1.2 → 0.2.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 (103) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +37 -3
  3. package/dist/cli/args.d.ts.map +1 -1
  4. package/dist/cli/args.js +4 -2
  5. package/dist/cli/args.js.map +1 -1
  6. package/dist/core/agent-profiles.d.ts.map +1 -1
  7. package/dist/core/agent-profiles.js +1 -0
  8. package/dist/core/agent-profiles.js.map +1 -1
  9. package/dist/core/agent-session.d.ts.map +1 -1
  10. package/dist/core/agent-session.js +3 -0
  11. package/dist/core/agent-session.js.map +1 -1
  12. package/dist/core/blast.d.ts +62 -0
  13. package/dist/core/blast.d.ts.map +1 -0
  14. package/dist/core/blast.js +448 -0
  15. package/dist/core/blast.js.map +1 -0
  16. package/dist/core/contract.d.ts +54 -0
  17. package/dist/core/contract.d.ts.map +1 -0
  18. package/dist/core/contract.js +300 -0
  19. package/dist/core/contract.js.map +1 -0
  20. package/dist/core/sdk.d.ts +3 -3
  21. package/dist/core/sdk.d.ts.map +1 -1
  22. package/dist/core/sdk.js +11 -19
  23. package/dist/core/sdk.js.map +1 -1
  24. package/dist/core/semantic/chunking.d.ts +10 -0
  25. package/dist/core/semantic/chunking.d.ts.map +1 -0
  26. package/dist/core/semantic/chunking.js +82 -0
  27. package/dist/core/semantic/chunking.js.map +1 -0
  28. package/dist/core/semantic/cli.d.ts +23 -0
  29. package/dist/core/semantic/cli.d.ts.map +1 -0
  30. package/dist/core/semantic/cli.js +86 -0
  31. package/dist/core/semantic/cli.js.map +1 -0
  32. package/dist/core/semantic/config.d.ts +8 -0
  33. package/dist/core/semantic/config.d.ts.map +1 -0
  34. package/dist/core/semantic/config.js +266 -0
  35. package/dist/core/semantic/config.js.map +1 -0
  36. package/dist/core/semantic/index-store.d.ts +21 -0
  37. package/dist/core/semantic/index-store.d.ts.map +1 -0
  38. package/dist/core/semantic/index-store.js +73 -0
  39. package/dist/core/semantic/index-store.js.map +1 -0
  40. package/dist/core/semantic/index.d.ts +8 -0
  41. package/dist/core/semantic/index.d.ts.map +1 -0
  42. package/dist/core/semantic/index.js +7 -0
  43. package/dist/core/semantic/index.js.map +1 -0
  44. package/dist/core/semantic/providers.d.ts +22 -0
  45. package/dist/core/semantic/providers.d.ts.map +1 -0
  46. package/dist/core/semantic/providers.js +317 -0
  47. package/dist/core/semantic/providers.js.map +1 -0
  48. package/dist/core/semantic/runtime.d.ts +32 -0
  49. package/dist/core/semantic/runtime.d.ts.map +1 -0
  50. package/dist/core/semantic/runtime.js +510 -0
  51. package/dist/core/semantic/runtime.js.map +1 -0
  52. package/dist/core/semantic/types.d.ts +157 -0
  53. package/dist/core/semantic/types.d.ts.map +1 -0
  54. package/dist/core/semantic/types.js +23 -0
  55. package/dist/core/semantic/types.js.map +1 -0
  56. package/dist/core/shadow-guard.d.ts +30 -0
  57. package/dist/core/shadow-guard.d.ts.map +1 -0
  58. package/dist/core/shadow-guard.js +81 -0
  59. package/dist/core/shadow-guard.js.map +1 -0
  60. package/dist/core/singular.d.ts +73 -0
  61. package/dist/core/singular.d.ts.map +1 -0
  62. package/dist/core/singular.js +413 -0
  63. package/dist/core/singular.js.map +1 -0
  64. package/dist/core/slash-commands.d.ts.map +1 -1
  65. package/dist/core/slash-commands.js +12 -0
  66. package/dist/core/slash-commands.js.map +1 -1
  67. package/dist/core/system-prompt.d.ts.map +1 -1
  68. package/dist/core/system-prompt.js +21 -3
  69. package/dist/core/system-prompt.js.map +1 -1
  70. package/dist/core/tools/ast-grep.js +1 -1
  71. package/dist/core/tools/ast-grep.js.map +1 -1
  72. package/dist/core/tools/comby.js +1 -1
  73. package/dist/core/tools/comby.js.map +1 -1
  74. package/dist/core/tools/index.d.ts +9 -0
  75. package/dist/core/tools/index.d.ts.map +1 -1
  76. package/dist/core/tools/index.js +6 -0
  77. package/dist/core/tools/index.js.map +1 -1
  78. package/dist/core/tools/rg.js +1 -1
  79. package/dist/core/tools/rg.js.map +1 -1
  80. package/dist/core/tools/semantic-search.d.ts +21 -0
  81. package/dist/core/tools/semantic-search.d.ts.map +1 -0
  82. package/dist/core/tools/semantic-search.js +123 -0
  83. package/dist/core/tools/semantic-search.js.map +1 -0
  84. package/dist/index.d.ts +4 -2
  85. package/dist/index.d.ts.map +1 -1
  86. package/dist/index.js +3 -2
  87. package/dist/index.js.map +1 -1
  88. package/dist/main.d.ts.map +1 -1
  89. package/dist/main.js +124 -0
  90. package/dist/main.js.map +1 -1
  91. package/dist/modes/interactive/components/custom-editor.d.ts +8 -0
  92. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  93. package/dist/modes/interactive/components/custom-editor.js +70 -1
  94. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  95. package/dist/modes/interactive/interactive-mode.d.ts +58 -0
  96. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  97. package/dist/modes/interactive/interactive-mode.js +2067 -104
  98. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  99. package/docs/cli-reference.md +36 -1
  100. package/docs/configuration.md +79 -2
  101. package/docs/getting-started.md +1 -0
  102. package/docs/interactive-mode.md +135 -1
  103. package/package.json +1 -1
@@ -0,0 +1,266 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { dirname, join } from "node:path";
3
+ import { SemanticConfigError } from "./types.js";
4
+ const DEFAULT_INCLUDE_GLOBS = ["**/*.{ts,tsx,js,jsx,py,go,rs,java,md,json,yaml,yml}"];
5
+ const DEFAULT_EXCLUDE_GLOBS = ["**/.git/**", "**/node_modules/**", "**/dist/**", "**/build/**", "**/.iosm/**"];
6
+ const DEFAULT_CONFIG = {
7
+ enabled: true,
8
+ autoIndex: true,
9
+ provider: {
10
+ type: "openrouter",
11
+ model: "openai/text-embedding-3-small",
12
+ batchSize: 32,
13
+ timeoutMs: 30_000,
14
+ },
15
+ index: {
16
+ includeGlobs: [...DEFAULT_INCLUDE_GLOBS],
17
+ excludeGlobs: [...DEFAULT_EXCLUDE_GLOBS],
18
+ chunkMaxChars: 1200,
19
+ chunkOverlapChars: 200,
20
+ maxFileBytes: 262_144,
21
+ maxFiles: 20_000,
22
+ },
23
+ };
24
+ function isRecord(value) {
25
+ return typeof value === "object" && value !== null;
26
+ }
27
+ function asString(value) {
28
+ return typeof value === "string" ? value : undefined;
29
+ }
30
+ function asBoolean(value) {
31
+ return typeof value === "boolean" ? value : undefined;
32
+ }
33
+ function asNumber(value) {
34
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
35
+ }
36
+ function sanitizeStringArray(value) {
37
+ if (!Array.isArray(value))
38
+ return undefined;
39
+ const normalized = value
40
+ .filter((item) => typeof item === "string")
41
+ .map((item) => item.trim())
42
+ .filter((item) => item.length > 0);
43
+ return normalized.length > 0 ? normalized : undefined;
44
+ }
45
+ function sanitizeStringRecord(value) {
46
+ if (!isRecord(value))
47
+ return undefined;
48
+ const result = {};
49
+ for (const [key, rawValue] of Object.entries(value)) {
50
+ if (typeof rawValue !== "string")
51
+ continue;
52
+ const normalizedKey = key.trim();
53
+ if (!normalizedKey)
54
+ continue;
55
+ result[normalizedKey] = rawValue;
56
+ }
57
+ return Object.keys(result).length > 0 ? result : undefined;
58
+ }
59
+ function sanitizeProviderType(value) {
60
+ if (value === "openrouter" || value === "ollama" || value === "custom_openai") {
61
+ return value;
62
+ }
63
+ return undefined;
64
+ }
65
+ function clampInt(value, fallback, min, max) {
66
+ if (value === undefined)
67
+ return fallback;
68
+ const normalized = Math.floor(value);
69
+ if (!Number.isFinite(normalized))
70
+ return fallback;
71
+ if (normalized < min)
72
+ return min;
73
+ if (normalized > max)
74
+ return max;
75
+ return normalized;
76
+ }
77
+ function parseSemanticConfigFile(path) {
78
+ if (!existsSync(path)) {
79
+ return {};
80
+ }
81
+ const raw = readFileSync(path, "utf8");
82
+ const parsed = JSON.parse(raw);
83
+ if (!isRecord(parsed)) {
84
+ throw new SemanticConfigError(`Expected JSON object in ${path}`);
85
+ }
86
+ const result = {};
87
+ const rawSemantic = parsed.semanticSearch;
88
+ if (!isRecord(rawSemantic)) {
89
+ return result;
90
+ }
91
+ const provider = isRecord(rawSemantic.provider)
92
+ ? {
93
+ type: sanitizeProviderType(rawSemantic.provider.type),
94
+ model: asString(rawSemantic.provider.model),
95
+ baseUrl: asString(rawSemantic.provider.baseUrl),
96
+ apiKeyEnv: asString(rawSemantic.provider.apiKeyEnv),
97
+ headers: sanitizeStringRecord(rawSemantic.provider.headers),
98
+ batchSize: asNumber(rawSemantic.provider.batchSize),
99
+ timeoutMs: asNumber(rawSemantic.provider.timeoutMs),
100
+ }
101
+ : undefined;
102
+ const index = isRecord(rawSemantic.index)
103
+ ? {
104
+ includeGlobs: sanitizeStringArray(rawSemantic.index.includeGlobs),
105
+ excludeGlobs: sanitizeStringArray(rawSemantic.index.excludeGlobs),
106
+ chunkMaxChars: asNumber(rawSemantic.index.chunkMaxChars),
107
+ chunkOverlapChars: asNumber(rawSemantic.index.chunkOverlapChars),
108
+ maxFileBytes: asNumber(rawSemantic.index.maxFileBytes),
109
+ maxFiles: asNumber(rawSemantic.index.maxFiles),
110
+ }
111
+ : undefined;
112
+ result.semanticSearch = {
113
+ enabled: asBoolean(rawSemantic.enabled),
114
+ autoIndex: asBoolean(rawSemantic.autoIndex),
115
+ provider,
116
+ index,
117
+ };
118
+ return result;
119
+ }
120
+ function mergeSemanticConfig(base, override) {
121
+ if (!base && !override)
122
+ return undefined;
123
+ return {
124
+ ...(base ?? {}),
125
+ ...(override ?? {}),
126
+ provider: {
127
+ ...(base?.provider ?? {}),
128
+ ...(override?.provider ?? {}),
129
+ },
130
+ index: {
131
+ ...(base?.index ?? {}),
132
+ ...(override?.index ?? {}),
133
+ },
134
+ };
135
+ }
136
+ function resolveSemanticSearchConfig(partial) {
137
+ if (!partial)
138
+ return undefined;
139
+ const providerType = partial.provider?.type ?? DEFAULT_CONFIG.provider.type;
140
+ const model = (partial.provider?.model ?? DEFAULT_CONFIG.provider.model).trim();
141
+ if (!model) {
142
+ throw new SemanticConfigError(`semanticSearch.provider.model cannot be empty`);
143
+ }
144
+ return {
145
+ enabled: partial.enabled ?? DEFAULT_CONFIG.enabled,
146
+ autoIndex: partial.autoIndex ?? DEFAULT_CONFIG.autoIndex,
147
+ provider: {
148
+ type: providerType,
149
+ model,
150
+ baseUrl: partial.provider?.baseUrl?.trim() || undefined,
151
+ apiKeyEnv: partial.provider?.apiKeyEnv?.trim() || undefined,
152
+ headers: partial.provider?.headers && Object.keys(partial.provider.headers).length > 0 ? partial.provider.headers : undefined,
153
+ batchSize: clampInt(partial.provider?.batchSize, DEFAULT_CONFIG.provider.batchSize, 1, 512),
154
+ timeoutMs: clampInt(partial.provider?.timeoutMs, DEFAULT_CONFIG.provider.timeoutMs, 1_000, 300_000),
155
+ },
156
+ index: {
157
+ includeGlobs: partial.index?.includeGlobs && partial.index.includeGlobs.length > 0 ? partial.index.includeGlobs : [...DEFAULT_CONFIG.index.includeGlobs],
158
+ excludeGlobs: partial.index?.excludeGlobs && partial.index.excludeGlobs.length > 0 ? partial.index.excludeGlobs : [...DEFAULT_CONFIG.index.excludeGlobs],
159
+ chunkMaxChars: clampInt(partial.index?.chunkMaxChars, DEFAULT_CONFIG.index.chunkMaxChars, 200, 20_000),
160
+ chunkOverlapChars: clampInt(partial.index?.chunkOverlapChars, DEFAULT_CONFIG.index.chunkOverlapChars, 0, 5_000),
161
+ maxFileBytes: clampInt(partial.index?.maxFileBytes, DEFAULT_CONFIG.index.maxFileBytes, 1_024, 16 * 1024 * 1024),
162
+ maxFiles: clampInt(partial.index?.maxFiles, DEFAULT_CONFIG.index.maxFiles, 1, 1_000_000),
163
+ },
164
+ };
165
+ }
166
+ export function getSemanticConfigPath(scope, cwd, agentDir) {
167
+ return scope === "project" ? join(cwd, ".iosm", "semantic.json") : join(agentDir, "semantic.json");
168
+ }
169
+ export function readScopedSemanticConfig(scope, cwd, agentDir) {
170
+ const path = getSemanticConfigPath(scope, cwd, agentDir);
171
+ try {
172
+ return {
173
+ scope,
174
+ path,
175
+ file: parseSemanticConfigFile(path),
176
+ };
177
+ }
178
+ catch (error) {
179
+ return {
180
+ scope,
181
+ path,
182
+ file: {},
183
+ error: error instanceof Error ? error : new Error(String(error)),
184
+ };
185
+ }
186
+ }
187
+ export function loadMergedSemanticConfig(cwd, agentDir) {
188
+ const scoped = [readScopedSemanticConfig("user", cwd, agentDir), readScopedSemanticConfig("project", cwd, agentDir)];
189
+ const errors = [];
190
+ for (const entry of scoped) {
191
+ if (entry.error) {
192
+ errors.push(`${entry.scope} config (${entry.path}): ${entry.error.message}`);
193
+ }
194
+ }
195
+ const mergedPartial = mergeSemanticConfig(scoped[0]?.file.semanticSearch, scoped[1]?.file.semanticSearch);
196
+ let config;
197
+ try {
198
+ config = resolveSemanticSearchConfig(mergedPartial);
199
+ }
200
+ catch (error) {
201
+ const message = error instanceof Error ? error.message : String(error);
202
+ errors.push(`semanticSearch: ${message}`);
203
+ config = undefined;
204
+ }
205
+ return {
206
+ config,
207
+ errors,
208
+ scoped,
209
+ };
210
+ }
211
+ export function writeScopedSemanticConfig(scope, file, cwd, agentDir) {
212
+ const path = getSemanticConfigPath(scope, cwd, agentDir);
213
+ const dir = dirname(path);
214
+ if (!existsSync(dir)) {
215
+ mkdirSync(dir, { recursive: true });
216
+ }
217
+ writeFileSync(path, `${JSON.stringify(file, null, 2)}\n`, "utf8");
218
+ return path;
219
+ }
220
+ export function upsertScopedSemanticSearchConfig(scope, config, cwd, agentDir) {
221
+ const current = readScopedSemanticConfig(scope, cwd, agentDir);
222
+ if (current.error) {
223
+ throw new SemanticConfigError(`Cannot update ${scope} semantic config (${current.path}): ${current.error.message}`);
224
+ }
225
+ const nextFile = {
226
+ ...current.file,
227
+ semanticSearch: {
228
+ enabled: config.enabled,
229
+ autoIndex: config.autoIndex,
230
+ provider: {
231
+ type: config.provider.type,
232
+ model: config.provider.model,
233
+ baseUrl: config.provider.baseUrl,
234
+ apiKeyEnv: config.provider.apiKeyEnv,
235
+ headers: config.provider.headers,
236
+ batchSize: config.provider.batchSize,
237
+ timeoutMs: config.provider.timeoutMs,
238
+ },
239
+ index: {
240
+ includeGlobs: [...config.index.includeGlobs],
241
+ excludeGlobs: [...config.index.excludeGlobs],
242
+ chunkMaxChars: config.index.chunkMaxChars,
243
+ chunkOverlapChars: config.index.chunkOverlapChars,
244
+ maxFileBytes: config.index.maxFileBytes,
245
+ maxFiles: config.index.maxFiles,
246
+ },
247
+ },
248
+ };
249
+ return writeScopedSemanticConfig(scope, nextFile, cwd, agentDir);
250
+ }
251
+ export function getDefaultSemanticSearchConfig() {
252
+ return {
253
+ enabled: DEFAULT_CONFIG.enabled,
254
+ autoIndex: DEFAULT_CONFIG.autoIndex,
255
+ provider: { ...DEFAULT_CONFIG.provider },
256
+ index: {
257
+ includeGlobs: [...DEFAULT_CONFIG.index.includeGlobs],
258
+ excludeGlobs: [...DEFAULT_CONFIG.index.excludeGlobs],
259
+ chunkMaxChars: DEFAULT_CONFIG.index.chunkMaxChars,
260
+ chunkOverlapChars: DEFAULT_CONFIG.index.chunkOverlapChars,
261
+ maxFileBytes: DEFAULT_CONFIG.index.maxFileBytes,
262
+ maxFiles: DEFAULT_CONFIG.index.maxFiles,
263
+ },
264
+ };
265
+ }
266
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/core/semantic/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport type {\n\tSemanticConfigFile,\n\tSemanticMergedConfig,\n\tSemanticScope,\n\tSemanticScopedLoadResult,\n\tSemanticSearchConfig,\n\tSemanticProviderType,\n} from \"./types.js\";\nimport { SemanticConfigError } from \"./types.js\";\n\nconst DEFAULT_INCLUDE_GLOBS = [\"**/*.{ts,tsx,js,jsx,py,go,rs,java,md,json,yaml,yml}\"];\nconst DEFAULT_EXCLUDE_GLOBS = [\"**/.git/**\", \"**/node_modules/**\", \"**/dist/**\", \"**/build/**\", \"**/.iosm/**\"];\n\nconst DEFAULT_CONFIG: SemanticSearchConfig = {\n\tenabled: true,\n\tautoIndex: true,\n\tprovider: {\n\t\ttype: \"openrouter\",\n\t\tmodel: \"openai/text-embedding-3-small\",\n\t\tbatchSize: 32,\n\t\ttimeoutMs: 30_000,\n\t},\n\tindex: {\n\t\tincludeGlobs: [...DEFAULT_INCLUDE_GLOBS],\n\t\texcludeGlobs: [...DEFAULT_EXCLUDE_GLOBS],\n\t\tchunkMaxChars: 1200,\n\t\tchunkOverlapChars: 200,\n\t\tmaxFileBytes: 262_144,\n\t\tmaxFiles: 20_000,\n\t},\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction asString(value: unknown): string | undefined {\n\treturn typeof value === \"string\" ? value : undefined;\n}\n\nfunction asBoolean(value: unknown): boolean | undefined {\n\treturn typeof value === \"boolean\" ? value : undefined;\n}\n\nfunction asNumber(value: unknown): number | undefined {\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction sanitizeStringArray(value: unknown): string[] | undefined {\n\tif (!Array.isArray(value)) return undefined;\n\tconst normalized = value\n\t\t.filter((item): item is string => typeof item === \"string\")\n\t\t.map((item) => item.trim())\n\t\t.filter((item) => item.length > 0);\n\treturn normalized.length > 0 ? normalized : undefined;\n}\n\nfunction sanitizeStringRecord(value: unknown): Record<string, string> | undefined {\n\tif (!isRecord(value)) return undefined;\n\tconst result: Record<string, string> = {};\n\tfor (const [key, rawValue] of Object.entries(value)) {\n\t\tif (typeof rawValue !== \"string\") continue;\n\t\tconst normalizedKey = key.trim();\n\t\tif (!normalizedKey) continue;\n\t\tresult[normalizedKey] = rawValue;\n\t}\n\treturn Object.keys(result).length > 0 ? result : undefined;\n}\n\nfunction sanitizeProviderType(value: unknown): SemanticProviderType | undefined {\n\tif (value === \"openrouter\" || value === \"ollama\" || value === \"custom_openai\") {\n\t\treturn value;\n\t}\n\treturn undefined;\n}\n\nfunction clampInt(value: number | undefined, fallback: number, min: number, max: number): number {\n\tif (value === undefined) return fallback;\n\tconst normalized = Math.floor(value);\n\tif (!Number.isFinite(normalized)) return fallback;\n\tif (normalized < min) return min;\n\tif (normalized > max) return max;\n\treturn normalized;\n}\n\nfunction parseSemanticConfigFile(path: string): SemanticConfigFile {\n\tif (!existsSync(path)) {\n\t\treturn {};\n\t}\n\tconst raw = readFileSync(path, \"utf8\");\n\tconst parsed = JSON.parse(raw) as unknown;\n\tif (!isRecord(parsed)) {\n\t\tthrow new SemanticConfigError(`Expected JSON object in ${path}`);\n\t}\n\n\tconst result: SemanticConfigFile = {};\n\tconst rawSemantic = parsed.semanticSearch;\n\tif (!isRecord(rawSemantic)) {\n\t\treturn result;\n\t}\n\n\tconst provider = isRecord(rawSemantic.provider)\n\t\t? {\n\t\t\t\ttype: sanitizeProviderType(rawSemantic.provider.type),\n\t\t\t\tmodel: asString(rawSemantic.provider.model),\n\t\t\t\tbaseUrl: asString(rawSemantic.provider.baseUrl),\n\t\t\t\tapiKeyEnv: asString(rawSemantic.provider.apiKeyEnv),\n\t\t\t\theaders: sanitizeStringRecord(rawSemantic.provider.headers),\n\t\t\t\tbatchSize: asNumber(rawSemantic.provider.batchSize),\n\t\t\t\ttimeoutMs: asNumber(rawSemantic.provider.timeoutMs),\n\t\t\t}\n\t\t: undefined;\n\n\tconst index = isRecord(rawSemantic.index)\n\t\t? {\n\t\t\t\tincludeGlobs: sanitizeStringArray(rawSemantic.index.includeGlobs),\n\t\t\t\texcludeGlobs: sanitizeStringArray(rawSemantic.index.excludeGlobs),\n\t\t\t\tchunkMaxChars: asNumber(rawSemantic.index.chunkMaxChars),\n\t\t\t\tchunkOverlapChars: asNumber(rawSemantic.index.chunkOverlapChars),\n\t\t\t\tmaxFileBytes: asNumber(rawSemantic.index.maxFileBytes),\n\t\t\t\tmaxFiles: asNumber(rawSemantic.index.maxFiles),\n\t\t\t}\n\t\t: undefined;\n\n\tresult.semanticSearch = {\n\t\tenabled: asBoolean(rawSemantic.enabled),\n\t\tautoIndex: asBoolean(rawSemantic.autoIndex),\n\t\tprovider,\n\t\tindex,\n\t};\n\n\treturn result;\n}\n\nfunction mergeSemanticConfig(\n\tbase: SemanticConfigFile[\"semanticSearch\"] | undefined,\n\toverride: SemanticConfigFile[\"semanticSearch\"] | undefined,\n): SemanticConfigFile[\"semanticSearch\"] | undefined {\n\tif (!base && !override) return undefined;\n\treturn {\n\t\t...(base ?? {}),\n\t\t...(override ?? {}),\n\t\tprovider: {\n\t\t\t...(base?.provider ?? {}),\n\t\t\t...(override?.provider ?? {}),\n\t\t},\n\t\tindex: {\n\t\t\t...(base?.index ?? {}),\n\t\t\t...(override?.index ?? {}),\n\t\t},\n\t};\n}\n\nfunction resolveSemanticSearchConfig(\n\tpartial: SemanticConfigFile[\"semanticSearch\"] | undefined,\n): SemanticSearchConfig | undefined {\n\tif (!partial) return undefined;\n\n\tconst providerType = partial.provider?.type ?? DEFAULT_CONFIG.provider.type;\n\tconst model = (partial.provider?.model ?? DEFAULT_CONFIG.provider.model).trim();\n\tif (!model) {\n\t\tthrow new SemanticConfigError(`semanticSearch.provider.model cannot be empty`);\n\t}\n\n\treturn {\n\t\tenabled: partial.enabled ?? DEFAULT_CONFIG.enabled,\n\t\tautoIndex: partial.autoIndex ?? DEFAULT_CONFIG.autoIndex,\n\t\tprovider: {\n\t\t\ttype: providerType,\n\t\t\tmodel,\n\t\t\tbaseUrl: partial.provider?.baseUrl?.trim() || undefined,\n\t\t\tapiKeyEnv: partial.provider?.apiKeyEnv?.trim() || undefined,\n\t\t\theaders: partial.provider?.headers && Object.keys(partial.provider.headers).length > 0 ? partial.provider.headers : undefined,\n\t\t\tbatchSize: clampInt(partial.provider?.batchSize, DEFAULT_CONFIG.provider.batchSize, 1, 512),\n\t\t\ttimeoutMs: clampInt(partial.provider?.timeoutMs, DEFAULT_CONFIG.provider.timeoutMs, 1_000, 300_000),\n\t\t},\n\t\tindex: {\n\t\t\tincludeGlobs: partial.index?.includeGlobs && partial.index.includeGlobs.length > 0 ? partial.index.includeGlobs : [...DEFAULT_CONFIG.index.includeGlobs],\n\t\t\texcludeGlobs: partial.index?.excludeGlobs && partial.index.excludeGlobs.length > 0 ? partial.index.excludeGlobs : [...DEFAULT_CONFIG.index.excludeGlobs],\n\t\t\tchunkMaxChars: clampInt(partial.index?.chunkMaxChars, DEFAULT_CONFIG.index.chunkMaxChars, 200, 20_000),\n\t\t\tchunkOverlapChars: clampInt(partial.index?.chunkOverlapChars, DEFAULT_CONFIG.index.chunkOverlapChars, 0, 5_000),\n\t\t\tmaxFileBytes: clampInt(partial.index?.maxFileBytes, DEFAULT_CONFIG.index.maxFileBytes, 1_024, 16 * 1024 * 1024),\n\t\t\tmaxFiles: clampInt(partial.index?.maxFiles, DEFAULT_CONFIG.index.maxFiles, 1, 1_000_000),\n\t\t},\n\t};\n}\n\nexport function getSemanticConfigPath(scope: SemanticScope, cwd: string, agentDir: string): string {\n\treturn scope === \"project\" ? join(cwd, \".iosm\", \"semantic.json\") : join(agentDir, \"semantic.json\");\n}\n\nexport function readScopedSemanticConfig(scope: SemanticScope, cwd: string, agentDir: string): SemanticScopedLoadResult {\n\tconst path = getSemanticConfigPath(scope, cwd, agentDir);\n\ttry {\n\t\treturn {\n\t\t\tscope,\n\t\t\tpath,\n\t\t\tfile: parseSemanticConfigFile(path),\n\t\t};\n\t} catch (error) {\n\t\treturn {\n\t\t\tscope,\n\t\t\tpath,\n\t\t\tfile: {},\n\t\t\terror: error instanceof Error ? error : new Error(String(error)),\n\t\t};\n\t}\n}\n\nexport function loadMergedSemanticConfig(cwd: string, agentDir: string): SemanticMergedConfig {\n\tconst scoped = [readScopedSemanticConfig(\"user\", cwd, agentDir), readScopedSemanticConfig(\"project\", cwd, agentDir)];\n\tconst errors: string[] = [];\n\n\tfor (const entry of scoped) {\n\t\tif (entry.error) {\n\t\t\terrors.push(`${entry.scope} config (${entry.path}): ${entry.error.message}`);\n\t\t}\n\t}\n\n\tconst mergedPartial = mergeSemanticConfig(scoped[0]?.file.semanticSearch, scoped[1]?.file.semanticSearch);\n\tlet config: SemanticSearchConfig | undefined;\n\ttry {\n\t\tconfig = resolveSemanticSearchConfig(mergedPartial);\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\terrors.push(`semanticSearch: ${message}`);\n\t\tconfig = undefined;\n\t}\n\n\treturn {\n\t\tconfig,\n\t\terrors,\n\t\tscoped,\n\t};\n}\n\nexport function writeScopedSemanticConfig(\n\tscope: SemanticScope,\n\tfile: SemanticConfigFile,\n\tcwd: string,\n\tagentDir: string,\n): string {\n\tconst path = getSemanticConfigPath(scope, cwd, agentDir);\n\tconst dir = dirname(path);\n\tif (!existsSync(dir)) {\n\t\tmkdirSync(dir, { recursive: true });\n\t}\n\twriteFileSync(path, `${JSON.stringify(file, null, 2)}\\n`, \"utf8\");\n\treturn path;\n}\n\nexport function upsertScopedSemanticSearchConfig(\n\tscope: SemanticScope,\n\tconfig: SemanticSearchConfig,\n\tcwd: string,\n\tagentDir: string,\n): string {\n\tconst current = readScopedSemanticConfig(scope, cwd, agentDir);\n\tif (current.error) {\n\t\tthrow new SemanticConfigError(`Cannot update ${scope} semantic config (${current.path}): ${current.error.message}`);\n\t}\n\tconst nextFile: SemanticConfigFile = {\n\t\t...current.file,\n\t\tsemanticSearch: {\n\t\t\tenabled: config.enabled,\n\t\t\tautoIndex: config.autoIndex,\n\t\t\tprovider: {\n\t\t\t\ttype: config.provider.type,\n\t\t\t\tmodel: config.provider.model,\n\t\t\t\tbaseUrl: config.provider.baseUrl,\n\t\t\t\tapiKeyEnv: config.provider.apiKeyEnv,\n\t\t\t\theaders: config.provider.headers,\n\t\t\t\tbatchSize: config.provider.batchSize,\n\t\t\t\ttimeoutMs: config.provider.timeoutMs,\n\t\t\t},\n\t\t\tindex: {\n\t\t\t\tincludeGlobs: [...config.index.includeGlobs],\n\t\t\t\texcludeGlobs: [...config.index.excludeGlobs],\n\t\t\t\tchunkMaxChars: config.index.chunkMaxChars,\n\t\t\t\tchunkOverlapChars: config.index.chunkOverlapChars,\n\t\t\t\tmaxFileBytes: config.index.maxFileBytes,\n\t\t\t\tmaxFiles: config.index.maxFiles,\n\t\t\t},\n\t\t},\n\t};\n\treturn writeScopedSemanticConfig(scope, nextFile, cwd, agentDir);\n}\n\nexport function getDefaultSemanticSearchConfig(): SemanticSearchConfig {\n\treturn {\n\t\tenabled: DEFAULT_CONFIG.enabled,\n\t\tautoIndex: DEFAULT_CONFIG.autoIndex,\n\t\tprovider: { ...DEFAULT_CONFIG.provider },\n\t\tindex: {\n\t\t\tincludeGlobs: [...DEFAULT_CONFIG.index.includeGlobs],\n\t\t\texcludeGlobs: [...DEFAULT_CONFIG.index.excludeGlobs],\n\t\t\tchunkMaxChars: DEFAULT_CONFIG.index.chunkMaxChars,\n\t\t\tchunkOverlapChars: DEFAULT_CONFIG.index.chunkOverlapChars,\n\t\t\tmaxFileBytes: DEFAULT_CONFIG.index.maxFileBytes,\n\t\t\tmaxFiles: DEFAULT_CONFIG.index.maxFiles,\n\t\t},\n\t};\n}\n"]}
@@ -0,0 +1,21 @@
1
+ import type { SemanticIndexMeta, SemanticIndexedChunk, SemanticIndexedVector } from "./types.js";
2
+ export interface SemanticIndexFiles {
3
+ metaPath: string;
4
+ chunksPath: string;
5
+ vectorsPath: string;
6
+ }
7
+ export interface LoadedSemanticIndex {
8
+ exists: boolean;
9
+ meta?: SemanticIndexMeta;
10
+ chunks: SemanticIndexedChunk[];
11
+ vectors: SemanticIndexedVector[];
12
+ }
13
+ export declare function getSemanticRootDir(agentDir: string): string;
14
+ export declare function getSemanticIndexesDir(agentDir: string): string;
15
+ export declare function getSemanticProjectHash(cwd: string): string;
16
+ export declare function getSemanticIndexDir(cwd: string, agentDir: string): string;
17
+ export declare function getSemanticIndexFiles(indexDir: string): SemanticIndexFiles;
18
+ export declare function loadSemanticIndex(indexDir: string): LoadedSemanticIndex;
19
+ export declare function writeSemanticIndex(indexDir: string, meta: SemanticIndexMeta, chunks: SemanticIndexedChunk[], vectors: SemanticIndexedVector[]): SemanticIndexFiles;
20
+ export declare function clearSemanticIndex(indexDir: string): void;
21
+ //# sourceMappingURL=index-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-store.d.ts","sourceRoot":"","sources":["../../../src/core/semantic/index-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAEjG,MAAM,WAAW,kBAAkB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAC/B,OAAO,EAAE,qBAAqB,EAAE,CAAC;CACjC;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,CAM1E;AAoBD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,mBAAmB,CAevE;AAED,wBAAgB,kBAAkB,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,iBAAiB,EACvB,MAAM,EAAE,oBAAoB,EAAE,EAC9B,OAAO,EAAE,qBAAqB,EAAE,GAC9B,kBAAkB,CASpB;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAGzD"}
@@ -0,0 +1,73 @@
1
+ import { createHash } from "node:crypto";
2
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
3
+ import { join, resolve } from "node:path";
4
+ export function getSemanticRootDir(agentDir) {
5
+ return join(agentDir, "semantic");
6
+ }
7
+ export function getSemanticIndexesDir(agentDir) {
8
+ return join(getSemanticRootDir(agentDir), "indexes");
9
+ }
10
+ export function getSemanticProjectHash(cwd) {
11
+ return createHash("sha256").update(resolve(cwd)).digest("hex").slice(0, 20);
12
+ }
13
+ export function getSemanticIndexDir(cwd, agentDir) {
14
+ return join(getSemanticIndexesDir(agentDir), getSemanticProjectHash(cwd));
15
+ }
16
+ export function getSemanticIndexFiles(indexDir) {
17
+ return {
18
+ metaPath: join(indexDir, "meta.json"),
19
+ chunksPath: join(indexDir, "chunks.jsonl"),
20
+ vectorsPath: join(indexDir, "vectors.jsonl"),
21
+ };
22
+ }
23
+ function parseJsonLines(path) {
24
+ if (!existsSync(path))
25
+ return [];
26
+ const raw = readFileSync(path, "utf8");
27
+ if (!raw.trim())
28
+ return [];
29
+ const rows = [];
30
+ for (const line of raw.split(/\r?\n/)) {
31
+ const trimmed = line.trim();
32
+ if (!trimmed)
33
+ continue;
34
+ rows.push(JSON.parse(trimmed));
35
+ }
36
+ return rows;
37
+ }
38
+ function stringifyJsonLines(values) {
39
+ if (values.length === 0)
40
+ return "";
41
+ return `${values.map((value) => JSON.stringify(value)).join("\n")}\n`;
42
+ }
43
+ export function loadSemanticIndex(indexDir) {
44
+ const files = getSemanticIndexFiles(indexDir);
45
+ if (!existsSync(files.metaPath)) {
46
+ return { exists: false, chunks: [], vectors: [] };
47
+ }
48
+ const meta = JSON.parse(readFileSync(files.metaPath, "utf8"));
49
+ const chunks = parseJsonLines(files.chunksPath);
50
+ const vectors = parseJsonLines(files.vectorsPath);
51
+ return {
52
+ exists: true,
53
+ meta,
54
+ chunks,
55
+ vectors,
56
+ };
57
+ }
58
+ export function writeSemanticIndex(indexDir, meta, chunks, vectors) {
59
+ if (!existsSync(indexDir)) {
60
+ mkdirSync(indexDir, { recursive: true });
61
+ }
62
+ const files = getSemanticIndexFiles(indexDir);
63
+ writeFileSync(files.metaPath, `${JSON.stringify(meta, null, 2)}\n`, "utf8");
64
+ writeFileSync(files.chunksPath, stringifyJsonLines(chunks), "utf8");
65
+ writeFileSync(files.vectorsPath, stringifyJsonLines(vectors), "utf8");
66
+ return files;
67
+ }
68
+ export function clearSemanticIndex(indexDir) {
69
+ if (!existsSync(indexDir))
70
+ return;
71
+ rmSync(indexDir, { recursive: true, force: true });
72
+ }
73
+ //# sourceMappingURL=index-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-store.js","sourceRoot":"","sources":["../../../src/core/semantic/index-store.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { join, resolve } from \"node:path\";\nimport type { SemanticIndexMeta, SemanticIndexedChunk, SemanticIndexedVector } from \"./types.js\";\n\nexport interface SemanticIndexFiles {\n\tmetaPath: string;\n\tchunksPath: string;\n\tvectorsPath: string;\n}\n\nexport interface LoadedSemanticIndex {\n\texists: boolean;\n\tmeta?: SemanticIndexMeta;\n\tchunks: SemanticIndexedChunk[];\n\tvectors: SemanticIndexedVector[];\n}\n\nexport function getSemanticRootDir(agentDir: string): string {\n\treturn join(agentDir, \"semantic\");\n}\n\nexport function getSemanticIndexesDir(agentDir: string): string {\n\treturn join(getSemanticRootDir(agentDir), \"indexes\");\n}\n\nexport function getSemanticProjectHash(cwd: string): string {\n\treturn createHash(\"sha256\").update(resolve(cwd)).digest(\"hex\").slice(0, 20);\n}\n\nexport function getSemanticIndexDir(cwd: string, agentDir: string): string {\n\treturn join(getSemanticIndexesDir(agentDir), getSemanticProjectHash(cwd));\n}\n\nexport function getSemanticIndexFiles(indexDir: string): SemanticIndexFiles {\n\treturn {\n\t\tmetaPath: join(indexDir, \"meta.json\"),\n\t\tchunksPath: join(indexDir, \"chunks.jsonl\"),\n\t\tvectorsPath: join(indexDir, \"vectors.jsonl\"),\n\t};\n}\n\nfunction parseJsonLines<T>(path: string): T[] {\n\tif (!existsSync(path)) return [];\n\tconst raw = readFileSync(path, \"utf8\");\n\tif (!raw.trim()) return [];\n\tconst rows: T[] = [];\n\tfor (const line of raw.split(/\\r?\\n/)) {\n\t\tconst trimmed = line.trim();\n\t\tif (!trimmed) continue;\n\t\trows.push(JSON.parse(trimmed) as T);\n\t}\n\treturn rows;\n}\n\nfunction stringifyJsonLines(values: unknown[]): string {\n\tif (values.length === 0) return \"\";\n\treturn `${values.map((value) => JSON.stringify(value)).join(\"\\n\")}\\n`;\n}\n\nexport function loadSemanticIndex(indexDir: string): LoadedSemanticIndex {\n\tconst files = getSemanticIndexFiles(indexDir);\n\tif (!existsSync(files.metaPath)) {\n\t\treturn { exists: false, chunks: [], vectors: [] };\n\t}\n\n\tconst meta = JSON.parse(readFileSync(files.metaPath, \"utf8\")) as SemanticIndexMeta;\n\tconst chunks = parseJsonLines<SemanticIndexedChunk>(files.chunksPath);\n\tconst vectors = parseJsonLines<SemanticIndexedVector>(files.vectorsPath);\n\treturn {\n\t\texists: true,\n\t\tmeta,\n\t\tchunks,\n\t\tvectors,\n\t};\n}\n\nexport function writeSemanticIndex(\n\tindexDir: string,\n\tmeta: SemanticIndexMeta,\n\tchunks: SemanticIndexedChunk[],\n\tvectors: SemanticIndexedVector[],\n): SemanticIndexFiles {\n\tif (!existsSync(indexDir)) {\n\t\tmkdirSync(indexDir, { recursive: true });\n\t}\n\tconst files = getSemanticIndexFiles(indexDir);\n\twriteFileSync(files.metaPath, `${JSON.stringify(meta, null, 2)}\\n`, \"utf8\");\n\twriteFileSync(files.chunksPath, stringifyJsonLines(chunks), \"utf8\");\n\twriteFileSync(files.vectorsPath, stringifyJsonLines(vectors), \"utf8\");\n\treturn files;\n}\n\nexport function clearSemanticIndex(indexDir: string): void {\n\tif (!existsSync(indexDir)) return;\n\trmSync(indexDir, { recursive: true, force: true });\n}\n"]}
@@ -0,0 +1,8 @@
1
+ export { getDefaultSemanticSearchConfig, getSemanticConfigPath, loadMergedSemanticConfig, readScopedSemanticConfig, upsertScopedSemanticSearchConfig, writeScopedSemanticConfig, } from "./config.js";
2
+ export { getSemanticCommandHelp, parseSemanticCliCommand, type ParseSemanticCliResult, type SemanticCliCommand, } from "./cli.js";
3
+ export { clearSemanticIndex, getSemanticIndexDir, getSemanticIndexFiles, getSemanticIndexesDir, getSemanticProjectHash, getSemanticRootDir, loadSemanticIndex, writeSemanticIndex, } from "./index-store.js";
4
+ export { createSemanticEmbeddingProvider, isLikelyEmbeddingModelId, listOllamaLocalModels, listOpenRouterEmbeddingModels, } from "./providers.js";
5
+ export { SemanticSearchRuntime } from "./runtime.js";
6
+ export type { SemanticAction, SemanticChunkForEmbedding, SemanticConfigFile, SemanticFileFingerprint, SemanticIndexConfig, SemanticIndexMeta, SemanticIndexOperationResult, SemanticIndexedChunk, SemanticIndexedVector, SemanticMergedConfig, SemanticProviderConfig, SemanticProviderType, SemanticQueryHit, SemanticQueryResult, SemanticScope, SemanticScopedLoadResult, SemanticSearchConfig, SemanticStatusResult, SemanticStaleReason, SemanticToolResult, } from "./types.js";
7
+ export { SemanticConfigError, SemanticConfigMissingError, SemanticIndexRequiredError, SemanticRebuildRequiredError, } from "./types.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/semantic/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,8BAA8B,EAC9B,qBAAqB,EACrB,wBAAwB,EACxB,wBAAwB,EACxB,gCAAgC,EAChC,yBAAyB,GACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,sBAAsB,EACtB,uBAAuB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,GACvB,MAAM,UAAU,CAAC;AAClB,OAAO,EACN,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,+BAA+B,EAC/B,wBAAwB,EACxB,qBAAqB,EACrB,6BAA6B,GAC7B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EACX,cAAc,EACd,yBAAyB,EACzB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,iBAAiB,EACjB,4BAA4B,EAC5B,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,aAAa,EACb,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,GAClB,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,EAC1B,4BAA4B,GAC5B,MAAM,YAAY,CAAC"}
@@ -0,0 +1,7 @@
1
+ export { getDefaultSemanticSearchConfig, getSemanticConfigPath, loadMergedSemanticConfig, readScopedSemanticConfig, upsertScopedSemanticSearchConfig, writeScopedSemanticConfig, } from "./config.js";
2
+ export { getSemanticCommandHelp, parseSemanticCliCommand, } from "./cli.js";
3
+ export { clearSemanticIndex, getSemanticIndexDir, getSemanticIndexFiles, getSemanticIndexesDir, getSemanticProjectHash, getSemanticRootDir, loadSemanticIndex, writeSemanticIndex, } from "./index-store.js";
4
+ export { createSemanticEmbeddingProvider, isLikelyEmbeddingModelId, listOllamaLocalModels, listOpenRouterEmbeddingModels, } from "./providers.js";
5
+ export { SemanticSearchRuntime } from "./runtime.js";
6
+ export { SemanticConfigError, SemanticConfigMissingError, SemanticIndexRequiredError, SemanticRebuildRequiredError, } from "./types.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/semantic/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,8BAA8B,EAC9B,qBAAqB,EACrB,wBAAwB,EACxB,wBAAwB,EACxB,gCAAgC,EAChC,yBAAyB,GACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,sBAAsB,EACtB,uBAAuB,GAGvB,MAAM,UAAU,CAAC;AAClB,OAAO,EACN,kBAAkB,EAClB,mBAAmB,EACnB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,+BAA+B,EAC/B,wBAAwB,EACxB,qBAAqB,EACrB,6BAA6B,GAC7B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAuBrD,OAAO,EACN,mBAAmB,EACnB,0BAA0B,EAC1B,0BAA0B,EAC1B,4BAA4B,GAC5B,MAAM,YAAY,CAAC","sourcesContent":["export {\n\tgetDefaultSemanticSearchConfig,\n\tgetSemanticConfigPath,\n\tloadMergedSemanticConfig,\n\treadScopedSemanticConfig,\n\tupsertScopedSemanticSearchConfig,\n\twriteScopedSemanticConfig,\n} from \"./config.js\";\nexport {\n\tgetSemanticCommandHelp,\n\tparseSemanticCliCommand,\n\ttype ParseSemanticCliResult,\n\ttype SemanticCliCommand,\n} from \"./cli.js\";\nexport {\n\tclearSemanticIndex,\n\tgetSemanticIndexDir,\n\tgetSemanticIndexFiles,\n\tgetSemanticIndexesDir,\n\tgetSemanticProjectHash,\n\tgetSemanticRootDir,\n\tloadSemanticIndex,\n\twriteSemanticIndex,\n} from \"./index-store.js\";\nexport {\n\tcreateSemanticEmbeddingProvider,\n\tisLikelyEmbeddingModelId,\n\tlistOllamaLocalModels,\n\tlistOpenRouterEmbeddingModels,\n} from \"./providers.js\";\nexport { SemanticSearchRuntime } from \"./runtime.js\";\nexport type {\n\tSemanticAction,\n\tSemanticChunkForEmbedding,\n\tSemanticConfigFile,\n\tSemanticFileFingerprint,\n\tSemanticIndexConfig,\n\tSemanticIndexMeta,\n\tSemanticIndexOperationResult,\n\tSemanticIndexedChunk,\n\tSemanticIndexedVector,\n\tSemanticMergedConfig,\n\tSemanticProviderConfig,\n\tSemanticProviderType,\n\tSemanticQueryHit,\n\tSemanticQueryResult,\n\tSemanticScope,\n\tSemanticScopedLoadResult,\n\tSemanticSearchConfig,\n\tSemanticStatusResult,\n\tSemanticStaleReason,\n\tSemanticToolResult,\n} from \"./types.js\";\nexport {\n\tSemanticConfigError,\n\tSemanticConfigMissingError,\n\tSemanticIndexRequiredError,\n\tSemanticRebuildRequiredError,\n} from \"./types.js\";\n"]}
@@ -0,0 +1,22 @@
1
+ import type { AuthStorage } from "../auth-storage.js";
2
+ import type { SemanticProviderConfig } from "./types.js";
3
+ export interface SemanticEmbeddingProvider {
4
+ embed(texts: string[]): Promise<number[][]>;
5
+ }
6
+ export interface SemanticProviderFactoryOptions {
7
+ authStorage?: AuthStorage;
8
+ }
9
+ export interface SemanticOpenRouterModelListOptions {
10
+ timeoutMs?: number;
11
+ authStorage?: AuthStorage;
12
+ }
13
+ export interface SemanticOllamaModelListOptions {
14
+ baseUrl?: string;
15
+ timeoutMs?: number;
16
+ headers?: Record<string, string>;
17
+ }
18
+ export declare function isLikelyEmbeddingModelId(modelId: string): boolean;
19
+ export declare function listOpenRouterEmbeddingModels(options?: SemanticOpenRouterModelListOptions): Promise<string[]>;
20
+ export declare function listOllamaLocalModels(options?: SemanticOllamaModelListOptions): Promise<string[]>;
21
+ export declare function createSemanticEmbeddingProvider(config: SemanticProviderConfig, options?: SemanticProviderFactoryOptions): Promise<SemanticEmbeddingProvider>;
22
+ //# sourceMappingURL=providers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../../src/core/semantic/providers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD,MAAM,WAAW,yBAAyB;IACzC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;CAC5C;AAED,MAAM,WAAW,8BAA8B;IAC9C,WAAW,CAAC,EAAE,WAAW,CAAC;CAC1B;AAED,MAAM,WAAW,kCAAkC;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,WAAW,CAAC;CAC1B;AAED,MAAM,WAAW,8BAA8B;IAC9C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAoJD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAWjE;AAED,wBAAsB,6BAA6B,CAClD,OAAO,GAAE,kCAAuC,GAC9C,OAAO,CAAC,MAAM,EAAE,CAAC,CA8CnB;AAED,wBAAsB,qBAAqB,CAC1C,OAAO,GAAE,8BAAmC,GAC1C,OAAO,CAAC,MAAM,EAAE,CAAC,CA4BnB;AAED,wBAAsB,+BAA+B,CACpD,MAAM,EAAE,sBAAsB,EAC9B,OAAO,GAAE,8BAAmC,GAC1C,OAAO,CAAC,yBAAyB,CAAC,CAkHpC"}