sensemaking 0.24.0 → 0.24.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/cjs/cli/status.js +6 -3
- package/dist/cjs/cli/status.js.map +1 -1
- package/dist/cjs/cli/watch.js +1 -1
- package/dist/cjs/cli/watch.js.map +1 -1
- package/dist/cjs/commands/related.js +2 -2
- package/dist/cjs/commands/related.js.map +1 -1
- package/dist/cjs/commands/search.js +3 -2
- package/dist/cjs/commands/search.js.map +1 -1
- package/dist/cjs/config/access.js +7 -1
- package/dist/cjs/config/access.js.map +1 -1
- package/dist/cjs/config/load.js +6 -1
- package/dist/cjs/config/load.js.map +1 -1
- package/dist/cjs/config/types.d.cts +3 -0
- package/dist/cjs/config/types.d.ts +3 -0
- package/dist/cjs/config/types.js.map +1 -1
- package/dist/cjs/config/validate.js +4 -0
- package/dist/cjs/config/validate.js.map +1 -1
- package/dist/cjs/embed/query.js +4 -4
- package/dist/cjs/embed/query.js.map +1 -1
- package/dist/cjs/store/cache.js +2 -1
- package/dist/cjs/store/cache.js.map +1 -1
- package/dist/cjs/store/open.js +13 -6
- package/dist/cjs/store/open.js.map +1 -1
- package/dist/cjs/watch.d.cts +1 -1
- package/dist/cjs/watch.d.ts +1 -1
- package/dist/cjs/watch.js +5 -4
- package/dist/cjs/watch.js.map +1 -1
- package/dist/esm/cli/status.js +6 -3
- package/dist/esm/cli/status.js.map +1 -1
- package/dist/esm/cli/watch.js +1 -1
- package/dist/esm/cli/watch.js.map +1 -1
- package/dist/esm/commands/related.js +2 -1
- package/dist/esm/commands/related.js.map +1 -1
- package/dist/esm/commands/search.js +2 -1
- package/dist/esm/commands/search.js.map +1 -1
- package/dist/esm/config/access.js +7 -0
- package/dist/esm/config/access.js.map +1 -1
- package/dist/esm/config/load.js +6 -1
- package/dist/esm/config/load.js.map +1 -1
- package/dist/esm/config/types.d.ts +3 -0
- package/dist/esm/config/types.js.map +1 -1
- package/dist/esm/config/validate.js +4 -0
- package/dist/esm/config/validate.js.map +1 -1
- package/dist/esm/embed/query.js +4 -4
- package/dist/esm/embed/query.js.map +1 -1
- package/dist/esm/store/cache.js +2 -1
- package/dist/esm/store/cache.js.map +1 -1
- package/dist/esm/store/open.js +14 -4
- package/dist/esm/store/open.js.map +1 -1
- package/dist/esm/watch.d.ts +1 -1
- package/dist/esm/watch.js +5 -4
- package/dist/esm/watch.js.map +1 -1
- package/package.json +1 -1
- package/schema.json +6 -1
- package/skills/sense-setup/EXAMPLES.md +21 -0
- package/skills/sense-setup/SKILL.md +2 -2
package/README.md
CHANGED
|
@@ -74,7 +74,7 @@ Lexical words are case- and accent-insensitive. SQLite and DuckDB use their nati
|
|
|
74
74
|
|
|
75
75
|
## Config
|
|
76
76
|
|
|
77
|
-
`sense init` writes `sense.config.json`; discovery walks up from cwd like git (`--config <path>` overrides).
|
|
77
|
+
`sense init` writes `sense.config.json`; discovery walks up from cwd like git (`--config <path>` overrides). A config normally indexes its own directory. Set optional top-level `root` to keep configuration and cache state elsewhere: relative roots resolve from the config directory, never from the invocation cwd. Globs and stored `path` values are relative to that root; `.sense/` remains beside the config, so separate consumers can index one vault with separate presets, queries, and caches.
|
|
78
78
|
|
|
79
79
|
```json
|
|
80
80
|
{
|
|
@@ -95,6 +95,7 @@ Lexical words are case- and accent-insensitive. SQLite and DuckDB use their nati
|
|
|
95
95
|
|
|
96
96
|
| key | holds |
|
|
97
97
|
|---|---|
|
|
98
|
+
| `root` | optional markdown-tree path. Relative to the config directory; omitted means that directory. Preset globs, filesystem reads, watcher events, and indexed `path` values use this root. `.sense/` state stays beside the config. Changing it rebuilds the index. |
|
|
98
99
|
| `presets` | named bundles of `include`/`exclude` globs, `k` (result count), `signals` (which engines this scope searches with, `words`, `links`, `vectors`; every signal whose prerequisites hold, unless the preset lists them exhaustively), `where` (a standing SQL filter). A file is indexed if any preset includes it, embedded if a model is named and some covering preset's `signals` include `vectors`; `status` shows each preset's coverage. |
|
|
99
100
|
| `embed` | the model vectors are built with. Naming one gives the tree vectors; omitting the block means none at all, whatever the presets say. `sense download` fetches it. |
|
|
100
101
|
| `store` | backing store engine: `sqlite` (default, zero-dependency, Node's built-in SQLite), or the experimental `duckdb` and `turso`. The first command that opens such a tree installs that engine's package on its own (`@duckdb/node-api`, a one-time native download of ~110 MB; `@tursodatabase/database`, much smaller). The same commands and table names run on all three; what does not port is FTS5 syntax. Under `duckdb` and `turso`, `search` text and raw `MATCH` reject FTS5's prefix (`foo*`), boolean (`AND`/`OR`/`NOT`), `NEAR`, initial-token (`^`), and column-filter (`title:foo`) operators with a named error that says how to rephrase or set `store` to `sqlite`; bare words and quoted phrases work on all three. Raw `sql` is a per-store dialect: the tables are portable, but sqlite's FTS5 `MATCH`/`snippet()`/`bm25()` do not run under `duckdb` or `turso`, so saved queries written in FTS5 syntax are sqlite dialect, and of the SQL functions `has`/`basename` run on all three (`turso` rewrites them into portable SQL) while `segment` runs on `sqlite` and `duckdb` only, so a tree whose queries call `segment` stays off `turso`. `sense watch` runs on all three; on `duckdb` and `turso`, which lock the cache file per connection, a concurrent command waits out the watcher's current cycle instead of failing. Each store keeps its own cache file (`.sense/cache.db`, `.sense/cache.duckdb`, `.sense/cache.turso.db`); switching stores is a rebuild, not a migration. Speed is a separate axis. The current per-store figures are historical diagnostics, not an identical-work leaderboard; workload, readiness, and selected downstream work differ. Speed is not the only reason to choose, though: the cache is an ordinary database file, so a tree indexed under duckdb is readable by anything in DuckDB's ecosystem, and turso brings concurrent access, non-blocking I/O and encryption. Pick for what you intend to do with the file, then check the per-store figures. Per-store figures: [BENCHMARKING.md](BENCHMARKING.md). |
|
package/dist/cjs/cli/status.js
CHANGED
|
@@ -354,7 +354,7 @@ function languagesInfo(e) {
|
|
|
354
354
|
}
|
|
355
355
|
var status = function status(ctx) {
|
|
356
356
|
return _async_to_generator(function() {
|
|
357
|
-
var _ref, _process_env_e_key, _cfg_migratedFrom, _cfg_unknownKeys, _cfg_queries, values, format, cfg, _ref1, store, dbPath, warnings, features, e, hasModel, reachable, _tmp, vectors, _tmp1, presets, _ref2, declaredLanguages, languagesState, languagesSource, detectedLanguages, heartbeat, cacheSchema, engine, keyEnv, result, _tmp2, migrated, shown, total, breakdown, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, line, pid, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, _step_value, key, value;
|
|
357
|
+
var _ref, _process_env_e_key, _cfg_migratedFrom, _cfg_unknownKeys, _cfg_rootDir, _cfg_rootDir1, _cfg_configDir, _cfg_queries, values, format, cfg, _ref1, store, dbPath, warnings, features, e, hasModel, reachable, _tmp, vectors, _tmp1, presets, _ref2, declaredLanguages, languagesState, languagesSource, detectedLanguages, heartbeat, cacheSchema, engine, keyEnv, result, _tmp2, migrated, shown, total, breakdown, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, line, pid, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, _step_value, key, value;
|
|
358
358
|
return _ts_generator(this, function(_state) {
|
|
359
359
|
switch(_state.label){
|
|
360
360
|
case 0:
|
|
@@ -454,7 +454,9 @@ var status = function status(ctx) {
|
|
|
454
454
|
configVersion: _indexts.SUPPORTED_CONFIG_VERSION,
|
|
455
455
|
migratedFrom: (_cfg_migratedFrom = cfg.migratedFrom) !== null && _cfg_migratedFrom !== void 0 ? _cfg_migratedFrom : null,
|
|
456
456
|
unknownConfigKeys: (_cfg_unknownKeys = cfg.unknownKeys) !== null && _cfg_unknownKeys !== void 0 ? _cfg_unknownKeys : null,
|
|
457
|
-
tree: cfg.baseDir,
|
|
457
|
+
tree: (_cfg_rootDir = cfg.rootDir) !== null && _cfg_rootDir !== void 0 ? _cfg_rootDir : cfg.baseDir,
|
|
458
|
+
treeRoot: (_cfg_rootDir1 = cfg.rootDir) !== null && _cfg_rootDir1 !== void 0 ? _cfg_rootDir1 : cfg.baseDir,
|
|
459
|
+
configDir: (_cfg_configDir = cfg.configDir) !== null && _cfg_configDir !== void 0 ? _cfg_configDir : cfg.baseDir,
|
|
458
460
|
cache: (0, _nodepath.dirname)(dbPath),
|
|
459
461
|
db: dbPath,
|
|
460
462
|
cacheSchema: cacheSchema
|
|
@@ -495,7 +497,8 @@ var status = function status(ctx) {
|
|
|
495
497
|
console.log("config: ".concat(result.config, " (v").concat(_indexts.SUPPORTED_CONFIG_VERSION).concat(migrated, ")"));
|
|
496
498
|
// A load-time stderr warning has scrolled away by the time anyone looks here.
|
|
497
499
|
if (cfg.unknownKeys) console.log(" unknown keys, ignored: ".concat(cfg.unknownKeys.join(', ')));
|
|
498
|
-
console.log("tree:
|
|
500
|
+
console.log("tree root: ".concat(result.treeRoot));
|
|
501
|
+
console.log("configDir: ".concat(result.configDir));
|
|
499
502
|
console.log("cache: ".concat(result.cache, " (schema ").concat(result.cacheSchema, "; delete this directory to reset)"));
|
|
500
503
|
console.log("docs: ".concat(result.docs).concat(result.unparseableFrontmatter > 0 ? " (".concat(result.unparseableFrontmatter, " with unparseable frontmatter: WHERE _parse_error IS NOT NULL)") : ''));
|
|
501
504
|
console.log('');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/status.ts"],"sourcesContent":["import { dirname } from 'node:path';\nimport { presetCoverage } from '../commands/status.ts';\nimport { embedConfig, featureStates, SUPPORTED_CONFIG_VERSION } from '../config/index.ts';\nimport { languageDistribution } from '../embed/distribution.ts';\nimport { probeReachable } from '../embed/http.ts';\nimport { isDownloadable, MODEL_FILENAMES, modelDir, modelPresent, readLanguages } from '../embed/store.ts';\nimport { featuresLine, presetsLines, stringifyJson } from '../output/output.ts';\nimport { docCount, getMeta, openStore } from '../store/index.ts';\nimport type { Store } from '../store/types.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// status names what you cannot read off the config file: locations sense chose, values it derived, state it stored. Config content itself is not echoed, since duplicating its globs here would create two places that disagree after an edit.\n// The exception is the embed block's url and key, whose effect is remote and otherwise invisible.\n\n// Vectors are computed on the first semantic query, not at reconcile, so a tree can have a semantic-on preset with nothing embedded yet.\n// Reported here because a fast reconcile on such a tree otherwise reads as \"the feature isn't on\".\nasync function vectorState(store: Store): Promise<{ embedded: number; pending: number } | null> {\n try {\n const stmt = await store.prepare('SELECT COUNT(vector) AS embedded, COUNT(*) - COUNT(vector) AS pending FROM embeddings');\n return (await stmt.get()) as { embedded: number; pending: number };\n } catch {\n return null;\n }\n}\n\nasync function parseErrorCount(store: Store): Promise<number> {\n const stmt = await store.prepare(`SELECT COUNT(*) AS n FROM frontmatter WHERE \"_parse_error\" IS NOT NULL`);\n return ((await stmt.get()) as { n: number }).n;\n}\n\n// A URL can carry credentials in its userinfo (https://user:pass@host/v1). status output gets\n// pasted into issues and transcripts, so it is always safe to paste.\nexport function redactUrl(url: string): string {\n try {\n const parsed = new URL(url);\n if (!parsed.username && !parsed.password) return url;\n parsed.username = '';\n parsed.password = '';\n return `${parsed.toString().replace(/\\/$/, '')} (credentials redacted)`;\n } catch {\n return url;\n }\n}\n\n// A stopped Ollama/LM Studio/Cohere endpoint prints identically to a running one otherwise; any\n// HTTP response counts as reachable (probeReachable), so this only distinguishes up from down.\nasync function embedReachable(e: { provider: string; url?: string }): Promise<boolean | null> {\n if (e.provider === 'static' || (e.provider === 'openai' && !e.url)) return null;\n const base = (e.url ?? 'https://api.cohere.com').replace(/\\/+$/, '');\n return probeReachable(e.provider === 'openai' ? `${base}/models` : base);\n}\n\ntype LanguagesState = 'declared' | 'none' | 'unresolved' | null;\n\n// Config-declared languages win over the model card, for every provider, as registry.ts does.\n// A local-path model has no card by design, so it is never \"unresolved\": that means an HF id.\nfunction languagesInfo(e: NonNullable<ReturnType<typeof embedConfig>>): { languages: string[] | null; state: LanguagesState; source: 'config' | 'card' | null } {\n if (e.languages) return { languages: e.languages, state: 'declared', source: 'config' };\n if (e.provider !== 'static' || !isDownloadable(e.model)) return { languages: null, state: null, source: null };\n const cardLanguages = readLanguages(e.model);\n if (cardLanguages === undefined) return { languages: null, state: 'unresolved', source: null };\n if (cardLanguages.length === 0) return { languages: null, state: 'none', source: null };\n return { languages: cardLanguages, state: 'declared', source: 'card' };\n}\n\nconst status: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.status}`, { ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const cfg = ctx.resolveConfig(values.config as string | undefined);\n const { store, dbPath, warnings } = await openStore(cfg);\n printWarnings(warnings);\n\n const features = featureStates(cfg);\n const e = embedConfig(cfg);\n const hasModel = e ? modelPresent(cfg) : false;\n const reachable = e ? await embedReachable(e) : null;\n const vectors = e ? await vectorState(store) : null;\n const presets = await presetCoverage(store, cfg);\n const { languages: declaredLanguages, state: languagesState, source: languagesSource } = e ? languagesInfo(e) : { languages: null, state: null, source: null };\n const detectedLanguages = (await languageDistribution(store)) ?? null;\n const heartbeat = await getMeta(store, 'watch_heartbeat');\n // Written by the store's open() on every open, so it is this cache's true version on either\n // store (sqlite 18, duckdb 2); a version mismatch already triggered a rebuild before this read.\n const cacheSchema = await getMeta(store, 'schema_version');\n // Each store owns what it reports and how it is worded (Store.engineStatus); this command\n // prints entries generically, without branching on any store's name.\n const engine = await store.engineStatus();\n // The env var holds the token; only its name and whether it is set are ever reported.\n const keyEnv = e?.key ? { name: e.key, set: (process.env[e.key] ?? '') !== '' } : null;\n const result = {\n config: cfg.configPath,\n configVersion: SUPPORTED_CONFIG_VERSION,\n migratedFrom: cfg.migratedFrom ?? null,\n unknownConfigKeys: cfg.unknownKeys ?? null,\n tree: cfg.baseDir,\n cache: dirname(dbPath),\n db: dbPath,\n cacheSchema,\n docs: await docCount(store),\n unparseableFrontmatter: await parseErrorCount(store),\n features: features.on,\n featuresOff: features.off,\n embed: e ? { provider: e.provider, model: e.model, dir: e.provider === 'static' ? modelDir(e.model) : null, url: e.url ? redactUrl(e.url) : null, reachable, keyEnv, downloaded: hasModel, languages: declaredLanguages, languagesState, detectedLanguages, ...(vectors ?? {}) } : null,\n presets,\n queries: Object.keys(cfg.queries ?? {}).length,\n watcherPid: await getMeta(store, 'watch_pid'),\n watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null,\n engine,\n };\n\n if (format === 'json') {\n console.log(stringifyJson(result, 2));\n } else {\n const migrated = cfg.migratedFrom !== undefined ? `, migrated from v${cfg.migratedFrom} on this run` : '';\n console.log(`config: ${result.config} (v${SUPPORTED_CONFIG_VERSION}${migrated})`);\n // A load-time stderr warning has scrolled away by the time anyone looks here.\n if (cfg.unknownKeys) console.log(` unknown keys, ignored: ${cfg.unknownKeys.join(', ')}`);\n console.log(`tree: ${result.tree}`);\n console.log(`cache: ${result.cache} (schema ${result.cacheSchema}; delete this directory to reset)`);\n console.log(`docs: ${result.docs}${result.unparseableFrontmatter > 0 ? ` (${result.unparseableFrontmatter} with unparseable frontmatter: WHERE _parse_error IS NOT NULL)` : ''}`);\n console.log('');\n console.log(featuresLine(features));\n // One authoritative block, off states included: an absent model reads as a degraded search,\n // not as an empty corpus.\n if (!e) console.log('embed: off (no preset asks for vectors)');\n else {\n console.log(`embed: ${e.provider} ${e.model}`);\n if (e.provider === 'static') console.log(` model: ${modelDir(e.model)} (${hasModel ? 'present' : `missing, ${isDownloadable(e.model) ? `fetches automatically at first search, or run \\`${ctx.name} download\\` to prefetch` : `no ${MODEL_FILENAMES} in that directory`}`})`);\n if (declaredLanguages && languagesSource === 'config') console.log(` languages: ${declaredLanguages.join(', ')} (declared in embed.languages)`);\n else if (declaredLanguages && languagesSource === 'card') console.log(` languages: ${declaredLanguages.join(', ')} (declared by the model card)`);\n else if (languagesState === 'none') console.log(' languages: none declared by the model card');\n else if (languagesState === 'unresolved') console.log(` languages: unresolved (model card unreachable; run \\`${ctx.name} download\\`)`);\n // Cohere defaults to api.cohere.com with no url in the config; show it anyway so the\n // reachability probe below has something to name.\n if (e.url || reachable !== null) {\n const shown = e.url ? redactUrl(e.url) : 'https://api.cohere.com (default)';\n console.log(` url: ${shown}${reachable === null ? '' : reachable ? ' (reachable)' : ' (unreachable)'}`);\n }\n if (keyEnv) console.log(` key: env ${keyEnv.name} (${keyEnv.set ? 'set' : 'NOT SET'})`);\n if (!hasModel) console.log(' vectors: off until the model is present; search runs on words and links');\n else if (vectors) console.log(` vectors: ${vectors.embedded} embedded, ${vectors.pending} pending (embedded on the first semantic search)`);\n if (detectedLanguages) {\n const total = Object.values(detectedLanguages).reduce((a, b) => a + b, 0);\n const breakdown = Object.entries(detectedLanguages)\n .sort((a, b) => b[1] - a[1])\n .map(([code, n]) => `${code} ${Math.round((n / total) * 100)}%`)\n .join(', ');\n console.log(` detected: ${breakdown} (${total} chunks classified)`);\n }\n }\n console.log('');\n for (const line of presetsLines(presets)) console.log(line);\n console.log('');\n console.log(`queries: ${result.queries} saved (${ctx.name} --list)`);\n const pid = result.watcherPid ? `pid ${result.watcherPid}, ` : '';\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: none' : `watcher: ${pid}last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n for (const [key, value] of Object.entries(result.engine)) console.log(`${`${store.name}:`.padEnd(10)}${key} ${value}`);\n }\n await store.close();\n};\nexport default status;\n"],"names":["redactUrl","vectorState","store","stmt","prepare","get","parseErrorCount","n","url","parsed","URL","username","password","toString","replace","embedReachable","e","base","provider","probeReachable","languagesInfo","languages","state","source","isDownloadable","model","cardLanguages","readLanguages","undefined","length","status","ctx","process","cfg","values","format","dbPath","warnings","features","hasModel","reachable","vectors","presets","declaredLanguages","languagesState","languagesSource","detectedLanguages","heartbeat","cacheSchema","engine","keyEnv","result","migrated","shown","total","breakdown","line","pid","key","value","parse","argv","USAGE","name","FORMAT","CONFIG","formatOf","resolveConfig","config","openStore","printWarnings","featureStates","embedConfig","modelPresent","presetCoverage","languageDistribution","getMeta","engineStatus","set","env","configPath","configVersion","SUPPORTED_CONFIG_VERSION","migratedFrom","unknownConfigKeys","unknownKeys","tree","baseDir","cache","dirname","db","docCount","docs","unparseableFrontmatter","on","featuresOff","off","embed","dir","modelDir","downloaded","queries","Object","keys","watcherPid","watcherHeartbeatSecondsAgo","Math","round","Date","now","console","log","stringifyJson","join","featuresLine","MODEL_FILENAMES","embedded","pending","reduce","a","b","entries","sort","map","code","presetsLines","padEnd","close"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/status.ts"],"sourcesContent":["import { dirname } from 'node:path';\nimport { presetCoverage } from '../commands/status.ts';\nimport { embedConfig, featureStates, SUPPORTED_CONFIG_VERSION } from '../config/index.ts';\nimport { languageDistribution } from '../embed/distribution.ts';\nimport { probeReachable } from '../embed/http.ts';\nimport { isDownloadable, MODEL_FILENAMES, modelDir, modelPresent, readLanguages } from '../embed/store.ts';\nimport { featuresLine, presetsLines, stringifyJson } from '../output/output.ts';\nimport { docCount, getMeta, openStore } from '../store/index.ts';\nimport type { Store } from '../store/types.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// status names what you cannot read off the config file: locations sense chose, values it derived, state it stored. Config content itself is not echoed, since duplicating its globs here would create two places that disagree after an edit.\n// The exception is the embed block's url and key, whose effect is remote and otherwise invisible.\n\n// Vectors are computed on the first semantic query, not at reconcile, so a tree can have a semantic-on preset with nothing embedded yet.\n// Reported here because a fast reconcile on such a tree otherwise reads as \"the feature isn't on\".\nasync function vectorState(store: Store): Promise<{ embedded: number; pending: number } | null> {\n try {\n const stmt = await store.prepare('SELECT COUNT(vector) AS embedded, COUNT(*) - COUNT(vector) AS pending FROM embeddings');\n return (await stmt.get()) as { embedded: number; pending: number };\n } catch {\n return null;\n }\n}\n\nasync function parseErrorCount(store: Store): Promise<number> {\n const stmt = await store.prepare(`SELECT COUNT(*) AS n FROM frontmatter WHERE \"_parse_error\" IS NOT NULL`);\n return ((await stmt.get()) as { n: number }).n;\n}\n\n// A URL can carry credentials in its userinfo (https://user:pass@host/v1). status output gets\n// pasted into issues and transcripts, so it is always safe to paste.\nexport function redactUrl(url: string): string {\n try {\n const parsed = new URL(url);\n if (!parsed.username && !parsed.password) return url;\n parsed.username = '';\n parsed.password = '';\n return `${parsed.toString().replace(/\\/$/, '')} (credentials redacted)`;\n } catch {\n return url;\n }\n}\n\n// A stopped Ollama/LM Studio/Cohere endpoint prints identically to a running one otherwise; any\n// HTTP response counts as reachable (probeReachable), so this only distinguishes up from down.\nasync function embedReachable(e: { provider: string; url?: string }): Promise<boolean | null> {\n if (e.provider === 'static' || (e.provider === 'openai' && !e.url)) return null;\n const base = (e.url ?? 'https://api.cohere.com').replace(/\\/+$/, '');\n return probeReachable(e.provider === 'openai' ? `${base}/models` : base);\n}\n\ntype LanguagesState = 'declared' | 'none' | 'unresolved' | null;\n\n// Config-declared languages win over the model card, for every provider, as registry.ts does.\n// A local-path model has no card by design, so it is never \"unresolved\": that means an HF id.\nfunction languagesInfo(e: NonNullable<ReturnType<typeof embedConfig>>): { languages: string[] | null; state: LanguagesState; source: 'config' | 'card' | null } {\n if (e.languages) return { languages: e.languages, state: 'declared', source: 'config' };\n if (e.provider !== 'static' || !isDownloadable(e.model)) return { languages: null, state: null, source: null };\n const cardLanguages = readLanguages(e.model);\n if (cardLanguages === undefined) return { languages: null, state: 'unresolved', source: null };\n if (cardLanguages.length === 0) return { languages: null, state: 'none', source: null };\n return { languages: cardLanguages, state: 'declared', source: 'card' };\n}\n\nconst status: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.status}`, { ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const cfg = ctx.resolveConfig(values.config as string | undefined);\n const { store, dbPath, warnings } = await openStore(cfg);\n printWarnings(warnings);\n\n const features = featureStates(cfg);\n const e = embedConfig(cfg);\n const hasModel = e ? modelPresent(cfg) : false;\n const reachable = e ? await embedReachable(e) : null;\n const vectors = e ? await vectorState(store) : null;\n const presets = await presetCoverage(store, cfg);\n const { languages: declaredLanguages, state: languagesState, source: languagesSource } = e ? languagesInfo(e) : { languages: null, state: null, source: null };\n const detectedLanguages = (await languageDistribution(store)) ?? null;\n const heartbeat = await getMeta(store, 'watch_heartbeat');\n // Written by the store's open() on every open, so it is this cache's true version on either\n // store (sqlite 18, duckdb 2); a version mismatch already triggered a rebuild before this read.\n const cacheSchema = await getMeta(store, 'schema_version');\n // Each store owns what it reports and how it is worded (Store.engineStatus); this command\n // prints entries generically, without branching on any store's name.\n const engine = await store.engineStatus();\n // The env var holds the token; only its name and whether it is set are ever reported.\n const keyEnv = e?.key ? { name: e.key, set: (process.env[e.key] ?? '') !== '' } : null;\n const result = {\n config: cfg.configPath,\n configVersion: SUPPORTED_CONFIG_VERSION,\n migratedFrom: cfg.migratedFrom ?? null,\n unknownConfigKeys: cfg.unknownKeys ?? null,\n tree: cfg.rootDir ?? cfg.baseDir,\n treeRoot: cfg.rootDir ?? cfg.baseDir,\n configDir: cfg.configDir ?? cfg.baseDir,\n cache: dirname(dbPath),\n db: dbPath,\n cacheSchema,\n docs: await docCount(store),\n unparseableFrontmatter: await parseErrorCount(store),\n features: features.on,\n featuresOff: features.off,\n embed: e ? { provider: e.provider, model: e.model, dir: e.provider === 'static' ? modelDir(e.model) : null, url: e.url ? redactUrl(e.url) : null, reachable, keyEnv, downloaded: hasModel, languages: declaredLanguages, languagesState, detectedLanguages, ...(vectors ?? {}) } : null,\n presets,\n queries: Object.keys(cfg.queries ?? {}).length,\n watcherPid: await getMeta(store, 'watch_pid'),\n watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null,\n engine,\n };\n\n if (format === 'json') {\n console.log(stringifyJson(result, 2));\n } else {\n const migrated = cfg.migratedFrom !== undefined ? `, migrated from v${cfg.migratedFrom} on this run` : '';\n console.log(`config: ${result.config} (v${SUPPORTED_CONFIG_VERSION}${migrated})`);\n // A load-time stderr warning has scrolled away by the time anyone looks here.\n if (cfg.unknownKeys) console.log(` unknown keys, ignored: ${cfg.unknownKeys.join(', ')}`);\n console.log(`tree root: ${result.treeRoot}`);\n console.log(`configDir: ${result.configDir}`);\n console.log(`cache: ${result.cache} (schema ${result.cacheSchema}; delete this directory to reset)`);\n console.log(`docs: ${result.docs}${result.unparseableFrontmatter > 0 ? ` (${result.unparseableFrontmatter} with unparseable frontmatter: WHERE _parse_error IS NOT NULL)` : ''}`);\n console.log('');\n console.log(featuresLine(features));\n // One authoritative block, off states included: an absent model reads as a degraded search,\n // not as an empty corpus.\n if (!e) console.log('embed: off (no preset asks for vectors)');\n else {\n console.log(`embed: ${e.provider} ${e.model}`);\n if (e.provider === 'static') console.log(` model: ${modelDir(e.model)} (${hasModel ? 'present' : `missing, ${isDownloadable(e.model) ? `fetches automatically at first search, or run \\`${ctx.name} download\\` to prefetch` : `no ${MODEL_FILENAMES} in that directory`}`})`);\n if (declaredLanguages && languagesSource === 'config') console.log(` languages: ${declaredLanguages.join(', ')} (declared in embed.languages)`);\n else if (declaredLanguages && languagesSource === 'card') console.log(` languages: ${declaredLanguages.join(', ')} (declared by the model card)`);\n else if (languagesState === 'none') console.log(' languages: none declared by the model card');\n else if (languagesState === 'unresolved') console.log(` languages: unresolved (model card unreachable; run \\`${ctx.name} download\\`)`);\n // Cohere defaults to api.cohere.com with no url in the config; show it anyway so the\n // reachability probe below has something to name.\n if (e.url || reachable !== null) {\n const shown = e.url ? redactUrl(e.url) : 'https://api.cohere.com (default)';\n console.log(` url: ${shown}${reachable === null ? '' : reachable ? ' (reachable)' : ' (unreachable)'}`);\n }\n if (keyEnv) console.log(` key: env ${keyEnv.name} (${keyEnv.set ? 'set' : 'NOT SET'})`);\n if (!hasModel) console.log(' vectors: off until the model is present; search runs on words and links');\n else if (vectors) console.log(` vectors: ${vectors.embedded} embedded, ${vectors.pending} pending (embedded on the first semantic search)`);\n if (detectedLanguages) {\n const total = Object.values(detectedLanguages).reduce((a, b) => a + b, 0);\n const breakdown = Object.entries(detectedLanguages)\n .sort((a, b) => b[1] - a[1])\n .map(([code, n]) => `${code} ${Math.round((n / total) * 100)}%`)\n .join(', ');\n console.log(` detected: ${breakdown} (${total} chunks classified)`);\n }\n }\n console.log('');\n for (const line of presetsLines(presets)) console.log(line);\n console.log('');\n console.log(`queries: ${result.queries} saved (${ctx.name} --list)`);\n const pid = result.watcherPid ? `pid ${result.watcherPid}, ` : '';\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: none' : `watcher: ${pid}last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n for (const [key, value] of Object.entries(result.engine)) console.log(`${`${store.name}:`.padEnd(10)}${key} ${value}`);\n }\n await store.close();\n};\nexport default status;\n"],"names":["redactUrl","vectorState","store","stmt","prepare","get","parseErrorCount","n","url","parsed","URL","username","password","toString","replace","embedReachable","e","base","provider","probeReachable","languagesInfo","languages","state","source","isDownloadable","model","cardLanguages","readLanguages","undefined","length","status","ctx","process","cfg","values","format","dbPath","warnings","features","hasModel","reachable","vectors","presets","declaredLanguages","languagesState","languagesSource","detectedLanguages","heartbeat","cacheSchema","engine","keyEnv","result","migrated","shown","total","breakdown","line","pid","key","value","parse","argv","USAGE","name","FORMAT","CONFIG","formatOf","resolveConfig","config","openStore","printWarnings","featureStates","embedConfig","modelPresent","presetCoverage","languageDistribution","getMeta","engineStatus","set","env","configPath","configVersion","SUPPORTED_CONFIG_VERSION","migratedFrom","unknownConfigKeys","unknownKeys","tree","rootDir","baseDir","treeRoot","configDir","cache","dirname","db","docCount","docs","unparseableFrontmatter","on","featuresOff","off","embed","dir","modelDir","downloaded","queries","Object","keys","watcherPid","watcherHeartbeatSecondsAgo","Math","round","Date","now","console","log","stringifyJson","join","featuresLine","MODEL_FILENAMES","embedded","pending","reduce","a","b","entries","sort","map","code","presetsLines","padEnd","close"],"mappings":"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"}
|
package/dist/cjs/cli/watch.js
CHANGED
|
@@ -180,7 +180,7 @@ var watch = function watch(ctx) {
|
|
|
180
180
|
force: values.force,
|
|
181
181
|
onEvent: function onEvent(event) {
|
|
182
182
|
if (event.type === 'started') {
|
|
183
|
-
console.log("".concat(ctx.name, " watch: watching ").concat(event.
|
|
183
|
+
console.log("".concat(ctx.name, " watch: watching ").concat(event.rootDir));
|
|
184
184
|
console.log("".concat(ctx.name, " watch: db ").concat(event.dbPath));
|
|
185
185
|
} else if (event.type === 'reconciled') {
|
|
186
186
|
(0, _sharedts.printWarnings)(event.warnings);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/watch.ts"],"sourcesContent":["import type { WatchEvent } from '../watch.ts';\nimport { runWatch } from '../watch.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst watch: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.watch}`, { force: { type: 'boolean', default: false }, ...CONFIG });\n await runWatch(ctx.resolveConfig(values.config as string | undefined), {\n force: values.force as boolean,\n onEvent: (event: WatchEvent) => {\n if (event.type === 'started') {\n console.log(`${ctx.name} watch: watching ${event.
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/watch.ts"],"sourcesContent":["import type { WatchEvent } from '../watch.ts';\nimport { runWatch } from '../watch.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst watch: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.watch}`, { force: { type: 'boolean', default: false }, ...CONFIG });\n await runWatch(ctx.resolveConfig(values.config as string | undefined), {\n force: values.force as boolean,\n onEvent: (event: WatchEvent) => {\n if (event.type === 'started') {\n console.log(`${ctx.name} watch: watching ${event.rootDir}`);\n console.log(`${ctx.name} watch: db ${event.dbPath}`);\n } else if (event.type === 'reconciled') {\n printWarnings(event.warnings);\n if (event.parsed > 0) console.log(`${ctx.name} watch: reconciled, ${event.parsed} file(s) reparsed (${event.total} total)`);\n } else {\n console.error(`${ctx.name} watch: reconcile error: ${event.message}`);\n }\n },\n });\n};\nexport default watch;\n"],"names":["watch","ctx","values","parse","argv","USAGE","name","force","type","default","CONFIG","runWatch","resolveConfig","config","onEvent","event","console","log","rootDir","dbPath","printWarnings","warnings","parsed","total","error","message"],"mappings":";;;;+BAuBA;;;eAAA;;;uBAtByB;uBACH;wBACuB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAG7C,IAAMA,QAAiB,eAAOC;;YACpBC;;;;oBAAAA,SAAWC,IAAAA,eAAK,EAACF,IAAIG,IAAI,EAAE,AAAC,UAAqBC,OAAZJ,IAAIK,IAAI,EAAC,KAAe,OAAZD,cAAK,CAACL,KAAK,GAAI;wBAAEO,OAAO;4BAAEC,MAAM;4BAAWC,SAAS;wBAAM;uBAAMC,gBAAM,GAAvHR;oBACR;;wBAAMS,IAAAA,iBAAQ,EAACV,IAAIW,aAAa,CAACV,OAAOW,MAAM,GAAyB;4BACrEN,OAAOL,OAAOK,KAAK;4BACnBO,SAAS,SAATA,QAAUC;gCACR,IAAIA,MAAMP,IAAI,KAAK,WAAW;oCAC5BQ,QAAQC,GAAG,CAAC,AAAC,GAA8BF,OAA5Bd,IAAIK,IAAI,EAAC,qBAAiC,OAAdS,MAAMG,OAAO;oCACxDF,QAAQC,GAAG,CAAC,AAAC,GAAwBF,OAAtBd,IAAIK,IAAI,EAAC,eAA0B,OAAbS,MAAMI,MAAM;gCACnD,OAAO,IAAIJ,MAAMP,IAAI,KAAK,cAAc;oCACtCY,IAAAA,uBAAa,EAACL,MAAMM,QAAQ;oCAC5B,IAAIN,MAAMO,MAAM,GAAG,GAAGN,QAAQC,GAAG,CAAC,AAAC,GAAiCF,OAA/Bd,IAAIK,IAAI,EAAC,wBAAwDS,OAAlCA,MAAMO,MAAM,EAAC,uBAAiC,OAAZP,MAAMQ,KAAK,EAAC;gCACpH,OAAO;oCACLP,QAAQQ,KAAK,CAAC,AAAC,GAAsCT,OAApCd,IAAIK,IAAI,EAAC,6BAAyC,OAAdS,MAAMU,OAAO;gCACpE;4BACF;wBACF;;;oBAbA;;;;;;IAcF;;IACA,WAAezB"}
|
|
@@ -168,7 +168,7 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
168
168
|
}
|
|
169
169
|
function relatedNotes(store, cfg, pathArg, overrides, k) {
|
|
170
170
|
return _async_to_generator(function() {
|
|
171
|
-
var paths, path, outbound, backlinks, exclude, effective, e, allowed;
|
|
171
|
+
var _cfg_rootDir, paths, path, outbound, backlinks, exclude, effective, e, allowed;
|
|
172
172
|
return _ts_generator(this, function(_state) {
|
|
173
173
|
switch(_state.label){
|
|
174
174
|
case 0:
|
|
@@ -242,7 +242,7 @@ function relatedNotes(store, cfg, pathArg, overrides, k) {
|
|
|
242
242
|
// having no indexed text until some search has run.
|
|
243
243
|
return [
|
|
244
244
|
4,
|
|
245
|
-
(0, _queryts.embedPending)(store, cfg, cfg.baseDir)
|
|
245
|
+
(0, _queryts.embedPending)(store, cfg, (_cfg_rootDir = cfg.rootDir) !== null && _cfg_rootDir !== void 0 ? _cfg_rootDir : cfg.baseDir)
|
|
246
246
|
];
|
|
247
247
|
case 8:
|
|
248
248
|
_state.sent();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/related.ts"],"sourcesContent":["import type { ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { embedConfig, embedEnabled, resolveSearch } from '../config/index.ts';\nimport { embedPending, hasEmbedding, similarNotes } from '../embed/query.ts';\nimport { localModelMissing, MODEL_FILENAMES } from '../embed/store.ts';\nimport { SenseError } from '../errors.ts';\nimport type { Store } from '../store/types.ts';\nimport { resolveNote } from './peek.ts';\nimport { scopedPaths, scopeHasEmbeddings } from './scope.ts';\n\n// Notes most similar by cosine, excluding self and everything already linked either way.\n// Its own command, not a peek section: a full embeddings scan is ~480ms at 26k notes.\nexport async function relatedNotes(store: Store, cfg: ResolvedConfig, pathArg: string, overrides: SearchOverrides, k: number): Promise<Array<{ path: string; similarity: number }>> {\n const paths = ((await (await store.prepare('SELECT \"path\" FROM frontmatter')).all()) as Array<{ path: string }>).map((r) => r.path);\n const path = resolveNote(paths, pathArg);\n\n const outbound = ((await (await store.prepare('SELECT DISTINCT dst FROM links WHERE src = ? AND dst IS NOT NULL AND dst != src')).all(path)) as Array<{ dst: string }>).map((r) => r.dst);\n const backlinks = ((await (await store.prepare('SELECT DISTINCT src FROM links WHERE dst = ? AND src != dst')).all(path)) as Array<{ src: string }>).map((r) => r.src);\n const exclude = new Set([path, ...outbound, ...backlinks]);\n\n // Vectors are the only signal `related` has, so every way of not having them is an error\n // naming the cause; an empty result means one thing, nothing near in meaning.\n const effective = resolveSearch(cfg, overrides);\n if (!embedEnabled(cfg)) {\n throw new SenseError('EMBED_DISABLED', 'related ranks notes by meaning, and this tree has no embedding model; add an \"embed\" block naming one to sense.config.json (a Hugging Face id fetches automatically at first use; `sense download` prefetches it) -- search works without it, on words and links');\n }\n // search gates on the same signal, so a preset's declared signals mean one thing: without\n // this check an overlapping vectors-on preset would answer for a scope that declined them.\n if (effective.signals.vectors === undefined) {\n throw new SenseError('PRESET_NOT_SEMANTIC', `preset \"${effective.presetName}\" has no \"vectors\" signal, so this scope has no vectors and related has no other signal; search it instead (words and links), or add \"vectors\" to that preset's signals`);\n }\n // A downloadable HF id proceeds -- embedPending's getProvider call fetches it lazily on\n // consent. Only a local path with missing files can never fetch itself.\n const e = embedConfig(cfg); // embedEnabled(cfg) above guarantees this is set\n if (localModelMissing(e)) {\n throw new SenseError('EMBED_MODEL_MISSING', `related ranks notes by meaning, so it needs the embedding model, but the local model path \"${e.model}\" is missing ${MODEL_FILENAMES}; point embed.model at a directory containing them (search still works without it, on words and links)`);\n }\n const allowed = await scopedPaths(store, cfg, overrides);\n // Top up pending rows before the seed check, or a fresh index reports every note as\n // having no indexed text until some search has run.\n await embedPending(store, cfg, cfg.baseDir);\n if (!(await hasEmbedding(store, path))) {\n throw new SenseError('NOTE_NOT_EMBEDDED', `${path} has no indexed text to compare -- a note that is frontmatter only, or empty, has nothing to rank by meaning`);\n }\n if (!(await scopeHasEmbeddings(store, cfg, allowed))) return [];\n return similarNotes(store, cfg, path, { exclude, allowed, k });\n}\n"],"names":["relatedNotes","store","cfg","pathArg","overrides","k","paths","path","outbound","backlinks","exclude","effective","e","allowed","prepare","all","map","r","resolveNote","dst","src","Set","resolveSearch","embedEnabled","SenseError","signals","vectors","undefined","presetName","embedConfig","localModelMissing","MODEL_FILENAMES","model","scopedPaths","embedPending","baseDir","hasEmbedding","scopeHasEmbeddings","similarNotes"],"mappings":";;;;+BAWsBA;;;eAAAA;;;uBAVmC;uBACA;uBACN;wBACxB;sBAEC;uBACoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIzC,SAAeA,aAAaC,KAAY,EAAEC,GAAmB,EAAEC,OAAe,EAAEC,SAA0B,EAAEC,CAAS;;
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/related.ts"],"sourcesContent":["import type { ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { embedConfig, embedEnabled, resolveSearch } from '../config/index.ts';\nimport { embedPending, hasEmbedding, similarNotes } from '../embed/query.ts';\nimport { localModelMissing, MODEL_FILENAMES } from '../embed/store.ts';\nimport { SenseError } from '../errors.ts';\nimport type { Store } from '../store/types.ts';\nimport { resolveNote } from './peek.ts';\nimport { scopedPaths, scopeHasEmbeddings } from './scope.ts';\n\n// Notes most similar by cosine, excluding self and everything already linked either way.\n// Its own command, not a peek section: a full embeddings scan is ~480ms at 26k notes.\nexport async function relatedNotes(store: Store, cfg: ResolvedConfig, pathArg: string, overrides: SearchOverrides, k: number): Promise<Array<{ path: string; similarity: number }>> {\n const paths = ((await (await store.prepare('SELECT \"path\" FROM frontmatter')).all()) as Array<{ path: string }>).map((r) => r.path);\n const path = resolveNote(paths, pathArg);\n\n const outbound = ((await (await store.prepare('SELECT DISTINCT dst FROM links WHERE src = ? AND dst IS NOT NULL AND dst != src')).all(path)) as Array<{ dst: string }>).map((r) => r.dst);\n const backlinks = ((await (await store.prepare('SELECT DISTINCT src FROM links WHERE dst = ? AND src != dst')).all(path)) as Array<{ src: string }>).map((r) => r.src);\n const exclude = new Set([path, ...outbound, ...backlinks]);\n\n // Vectors are the only signal `related` has, so every way of not having them is an error\n // naming the cause; an empty result means one thing, nothing near in meaning.\n const effective = resolveSearch(cfg, overrides);\n if (!embedEnabled(cfg)) {\n throw new SenseError('EMBED_DISABLED', 'related ranks notes by meaning, and this tree has no embedding model; add an \"embed\" block naming one to sense.config.json (a Hugging Face id fetches automatically at first use; `sense download` prefetches it) -- search works without it, on words and links');\n }\n // search gates on the same signal, so a preset's declared signals mean one thing: without\n // this check an overlapping vectors-on preset would answer for a scope that declined them.\n if (effective.signals.vectors === undefined) {\n throw new SenseError('PRESET_NOT_SEMANTIC', `preset \"${effective.presetName}\" has no \"vectors\" signal, so this scope has no vectors and related has no other signal; search it instead (words and links), or add \"vectors\" to that preset's signals`);\n }\n // A downloadable HF id proceeds -- embedPending's getProvider call fetches it lazily on\n // consent. Only a local path with missing files can never fetch itself.\n const e = embedConfig(cfg); // embedEnabled(cfg) above guarantees this is set\n if (localModelMissing(e)) {\n throw new SenseError('EMBED_MODEL_MISSING', `related ranks notes by meaning, so it needs the embedding model, but the local model path \"${e.model}\" is missing ${MODEL_FILENAMES}; point embed.model at a directory containing them (search still works without it, on words and links)`);\n }\n const allowed = await scopedPaths(store, cfg, overrides);\n // Top up pending rows before the seed check, or a fresh index reports every note as\n // having no indexed text until some search has run.\n await embedPending(store, cfg, cfg.rootDir ?? cfg.baseDir);\n if (!(await hasEmbedding(store, path))) {\n throw new SenseError('NOTE_NOT_EMBEDDED', `${path} has no indexed text to compare -- a note that is frontmatter only, or empty, has nothing to rank by meaning`);\n }\n if (!(await scopeHasEmbeddings(store, cfg, allowed))) return [];\n return similarNotes(store, cfg, path, { exclude, allowed, k });\n}\n"],"names":["relatedNotes","store","cfg","pathArg","overrides","k","paths","path","outbound","backlinks","exclude","effective","e","allowed","prepare","all","map","r","resolveNote","dst","src","Set","resolveSearch","embedEnabled","SenseError","signals","vectors","undefined","presetName","embedConfig","localModelMissing","MODEL_FILENAMES","model","scopedPaths","embedPending","rootDir","baseDir","hasEmbedding","scopeHasEmbeddings","similarNotes"],"mappings":";;;;+BAWsBA;;;eAAAA;;;uBAVmC;uBACA;uBACN;wBACxB;sBAEC;uBACoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIzC,SAAeA,aAAaC,KAAY,EAAEC,GAAmB,EAAEC,OAAe,EAAEC,SAA0B,EAAEC,CAAS;;YA4B3FH,cA3BzBI,OACAC,MAEAC,UACAC,WACAC,SAIAC,WAWAC,GAIAC;;;;oBAxBiB;;wBAAMZ,MAAMa,OAAO,CAAC;;;oBAA3B;;wBAAO,cAAuDC,GAAG;;;oBAA3ET,QAAQ,AAAE,cAAiGU,GAAG,CAAC,SAACC;+BAAMA,EAAEV,IAAI;;oBAC5HA,OAAOW,IAAAA,mBAAW,EAACZ,OAAOH;oBAEN;;wBAAMF,MAAMa,OAAO,CAAC;;;oBAA3B;;wBAAO,cAAwGC,GAAG,CAACR;;;oBAAhIC,WAAW,AAAE,cAAqJQ,GAAG,CAAC,SAACC;+BAAMA,EAAEE,GAAG;;oBAC7J;;wBAAMlB,MAAMa,OAAO,CAAC;;;oBAA3B;;wBAAO,cAAoFC,GAAG,CAACR;;;oBAA7GE,YAAY,AAAE,cAAiIO,GAAG,CAAC,SAACC;+BAAMA,EAAEG,GAAG;;oBAC/JV,UAAU,IAAIW,IAAI;wBAACd;sBAAD,OAAO,qBAAGC,WAAU,qBAAGC;oBAE/C,yFAAyF;oBACzF,8EAA8E;oBACxEE,YAAYW,IAAAA,sBAAa,EAACpB,KAAKE;oBACrC,IAAI,CAACmB,IAAAA,qBAAY,EAACrB,MAAM;wBACtB,MAAM,IAAIsB,oBAAU,CAAC,kBAAkB;oBACzC;oBACA,0FAA0F;oBAC1F,2FAA2F;oBAC3F,IAAIb,UAAUc,OAAO,CAACC,OAAO,KAAKC,WAAW;wBAC3C,MAAM,IAAIH,oBAAU,CAAC,uBAAuB,AAAC,WAA+B,OAArBb,UAAUiB,UAAU,EAAC;oBAC9E;oBACA,wFAAwF;oBACxF,wEAAwE;oBAClEhB,IAAIiB,IAAAA,oBAAW,EAAC3B,MAAM,iDAAiD;oBAC7E,IAAI4B,IAAAA,0BAAiB,EAAClB,IAAI;wBACxB,MAAM,IAAIY,oBAAU,CAAC,uBAAuB,AAAC,8FAAoHO,OAAvBnB,EAAEoB,KAAK,EAAC,iBAA+B,OAAhBD,wBAAe,EAAC;oBACnL;oBACgB;;wBAAME,IAAAA,oBAAW,EAAChC,OAAOC,KAAKE;;;oBAAxCS,UAAU;oBAChB,oFAAoF;oBACpF,oDAAoD;oBACpD;;wBAAMqB,IAAAA,qBAAY,EAACjC,OAAOC,MAAKA,eAAAA,IAAIiC,OAAO,cAAXjC,0BAAAA,eAAeA,IAAIkC,OAAO;;;oBAAzD;oBACM;;wBAAMC,IAAAA,qBAAY,EAACpC,OAAOM;;;oBAAhC,IAAI,CAAE,eAAkC;wBACtC,MAAM,IAAIiB,oBAAU,CAAC,qBAAqB,AAAC,GAAO,OAALjB,MAAK;oBACpD;oBACM;;wBAAM+B,IAAAA,2BAAkB,EAACrC,OAAOC,KAAKW;;;oBAA3C,IAAI,CAAE,eAAgD;;;;oBACtD;;wBAAO0B,IAAAA,qBAAY,EAACtC,OAAOC,KAAKK,MAAM;4BAAEG,SAAAA;4BAASG,SAAAA;4BAASR,GAAAA;wBAAE;;;;IAC9D"}
|
|
@@ -629,7 +629,7 @@ function lineRangeFor(store, path, line) {
|
|
|
629
629
|
}
|
|
630
630
|
function hydrateSearchRows(_0, _1, _2, _3, _4) {
|
|
631
631
|
return _async_to_generator(function(store, cfg, rows, matchedPaths, terms) {
|
|
632
|
-
var opts, _opts_snippetCharLimit, _opts_snippetCountLimit, bareTerms, charLimit, countLimit, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, row, text, _computeSnippets, snippets, offset, _tmp, err;
|
|
632
|
+
var opts, _opts_snippetCharLimit, _opts_snippetCountLimit, bareTerms, charLimit, countLimit, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, row, text, _cfg_rootDir, _computeSnippets, snippets, offset, _tmp, err;
|
|
633
633
|
var _arguments = arguments;
|
|
634
634
|
return _ts_generator(this, function(_state) {
|
|
635
635
|
switch(_state.label){
|
|
@@ -664,7 +664,8 @@ function hydrateSearchRows(_0, _1, _2, _3, _4) {
|
|
|
664
664
|
];
|
|
665
665
|
text = void 0;
|
|
666
666
|
try {
|
|
667
|
-
|
|
667
|
+
;
|
|
668
|
+
text = (0, _nodefs.readFileSync)((0, _nodepath.join)((_cfg_rootDir = cfg.rootDir) !== null && _cfg_rootDir !== void 0 ? _cfg_rootDir : cfg.baseDir, row.path), 'utf8');
|
|
668
669
|
} catch (unused) {
|
|
669
670
|
return [
|
|
670
671
|
3,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/search.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { stemmer } from 'stemmer';\nimport type { ResolvedConfig } from '../config/index.ts';\nimport { embedConfig, featureEnabled, resolveSearch } from '../config/index.ts';\nimport { localModelMissing, MODEL_FILENAMES } from '../embed/store.ts';\nimport { SenseError } from '../errors.ts';\nimport type { Row } from '../output/output.ts';\nimport { bareTermSyntaxError, searchError } from '../output/search-error.ts';\nimport type { LexicalHit, Store } from '../store/types.ts';\nimport { foldForSearch, hasUnspacedRun, searchTokens, unspacedRuns } from '../text/segment.ts';\nimport { materializeScope, narrowByWhere, rawScope, scopeHasEmbeddings } from './scope.ts';\nimport { linksCandidates, vectorsCandidates, wordsCandidates } from './signals.ts';\n\n// Default budget behind --snippet-char-limit/--snippet-count-limit: the limit is whatever the\n// caller passes, these only say what happens when they pass nothing (DESIGN.md \"Search snippets\").\nexport const SNIPPET_CHAR_LIMIT_DEFAULT = 80;\nexport const SNIPPET_COUNT_LIMIT_DEFAULT = 1;\n\n// Bare terms from an FTS5 query string: strips operators/quoting, not real terms, so the\n// snippet scan matches what the query matched -- FTS5 operators are uppercase-only, so this is too.\nfunction extractBareTerms(query: string): string[] {\n const cleaned = query\n .replace(/\"/g, ' ')\n .replace(/[()*]/g, ' ')\n .replace(/\\b(AND|OR|NOT|NEAR)\\b(\\/\\d+)?/g, ' ');\n return cleaned\n .split(/\\s+/)\n .map((tok) => tok.replace(/^[A-Za-z_]\\w*:/, '')) // column filter, e.g. title:term\n .flatMap((tok) => searchTokens(tok).map(({ text }) => text))\n .map((tok) => tok.toLowerCase().trim())\n .filter((tok) => tok.length > 0);\n}\n\n// House convention (src/chunk/group.ts): Intl.Segmenter word boundaries, not a bare \\b, which\n// is ASCII-only. Built on first use: construction is a few ms, paid only when a term matches.\nlet wordSegmenter: Intl.Segmenter | undefined;\n\nfunction findOccurrences(text: string, terms: string[]): Array<{ start: number; end: number; term: string }> {\n const occ: Array<{ start: number; end: number; term: string }> = [];\n const textLower = text.toLowerCase();\n\n // Unspaced scripts (UNSPACED_SCRIPTS) mark no word boundaries: the sense-setup skill promises\n // substring semantics there, so a matching term is found wherever it occurs in the run.\n const unspacedTerms = terms.filter(hasUnspacedRun);\n if (unspacedTerms.length > 0) {\n for (const run of unspacedRuns(text)) {\n const runLower = textLower.slice(run.start, run.end);\n for (const term of unspacedTerms) {\n let idx = 0;\n for (;;) {\n const found = runLower.indexOf(term, idx);\n if (found === -1) break;\n occ.push({ start: run.start + found, end: run.start + found + term.length, term });\n idx = found + term.length;\n }\n }\n }\n }\n\n // Spaced scripts: a word is marked when its porter stem equals a query term's stem, the same\n // algorithm both indexes tokenize with (sqlite's TOKENIZE = 'porter unicode61'; duckdb's fts default).\n const spacedTerms = terms.filter((t) => !hasUnspacedRun(t));\n if (spacedTerms.length > 0) {\n const termByStem = new Map(spacedTerms.map((t) => [stemmer(foldForSearch(t)), t]));\n const stemInitials = new Set(Array.from(termByStem.keys(), (term) => term[0]));\n for (const match of searchTokens(text)) {\n const segment = match.text;\n if (match.unspaced) continue;\n const folded = foldForSearch(segment);\n // Porter stemming changes suffixes only, so a different initial cannot match a query stem.\n if (!stemInitials.has(folded[0])) continue;\n const term = termByStem.get(stemmer(folded));\n if (term !== undefined) occ.push({ start: match.start, end: match.end, term });\n }\n }\n\n return occ.sort((a, b) => a.start - b.start || b.end - a.end);\n}\n\n// Segment boundaries of the whole text, word granularity: the only cut points a snippet edge\n// may land on. One rule for every script (DESIGN.md \"Cutting\") -- a regex \\b is ASCII-only and\n// would mis-cut Japanese, Chinese and Thai, which Intl.Segmenter divides by dictionary instead.\nfunction wordBoundaries(text: string): number[] {\n wordSegmenter ??= new Intl.Segmenter('en', { granularity: 'word' });\n const bounds = [0];\n for (const { index, segment } of wordSegmenter.segment(text)) bounds.push(index + segment.length);\n return bounds;\n}\n\n// bounds is sorted: snaps are binary searches, since each runs once per candidate window.\nfunction snapForward(bounds: number[], pos: number): number {\n let lo = 0;\n let hi = bounds.length - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (bounds[mid] < pos) lo = mid + 1;\n else hi = mid;\n }\n return bounds[lo];\n}\n\nfunction snapBackward(bounds: number[], pos: number): number {\n let lo = 0;\n let hi = bounds.length - 1;\n let result = bounds[0];\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (bounds[mid] <= pos) {\n lo = mid;\n result = bounds[mid];\n } else hi = mid - 1;\n }\n return result;\n}\n\nfunction firstBoundAfter(bounds: number[], pos: number): number | undefined {\n let lo = 0;\n let hi = bounds.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (bounds[mid] <= pos) lo = mid + 1;\n else hi = mid;\n }\n return bounds[lo];\n}\n\n// A raw, unmarked upper bound: [start, end) inside [anchor, anchor+charLimit), edges on\n// boundaries. Markup (guillemets, ellipses) added on top of this can push the rendered result\n// past charLimit, which is what fitEnd() below corrects for; this is only the starting guess.\n// A single segment spanning the whole target window (a word longer than the char limit) is the\n// one case where holding the boundary rule means the budget is not a hard ceiling.\nfunction cutWindow(text: string, bounds: number[], anchor: number, charLimit: number): { start: number; end: number } {\n const rawEnd = Math.min(text.length, anchor + charLimit);\n const start = snapForward(bounds, anchor);\n let end = snapBackward(bounds, rawEnd);\n if (end <= start) end = firstBoundAfter(bounds, start) ?? text.length;\n return { start, end: Math.min(end, text.length) };\n}\n\n// The largest boundary <= upperBound, > floor, whose rendered [*, end) fits charLimit. Markup\n// only ever adds characters as end grows, so rendered length is non-decreasing in end and\n// shrinking from upperBound is guaranteed to find the true fit rather than guess at it.\n// `floor` is the one end this never shrinks past (the anchor's own marked word, or the first\n// word in the unmarked fallback): DESIGN.md's budget is a ceiling except here, where returning\n// nothing is worse than a single word that overruns it.\nfunction fitEnd(render: (end: number) => string, bounds: number[], floor: number, upperBound: number, charLimit: number): number {\n let lo = 0;\n let hi = bounds.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (bounds[mid] <= upperBound) lo = mid;\n else hi = mid - 1;\n }\n for (; lo >= 0 && bounds[lo] > floor; lo--) {\n if (render(bounds[lo]).length <= charLimit) return bounds[lo];\n }\n return floor;\n}\n\ninterface Span {\n start: number;\n end: number;\n}\n\ninterface SnippetWindow extends Span {\n distinct: number;\n count: number;\n}\n\n// occ is start-sorted: a window's first candidate occurrence is a binary search, not a walk.\nfunction firstOccAtOrAfter(occ: Array<{ start: number; end: number; term: string }>, pos: number): number {\n let lo = 0;\n let hi = occ.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (occ[mid].start < pos) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\nfunction renderWindow(text: string, occ: Array<{ start: number; end: number; term: string }>, win: Span): string {\n let out = '';\n let cursor = win.start;\n for (let i = firstOccAtOrAfter(occ, win.start); i < occ.length && occ[i].start < win.end; i++) {\n const o = occ[i];\n if (o.end > win.end) continue;\n // Occurrences of duplicate or substring-overlapping terms (\"test tests\") can overlap;\n // emitting each would duplicate document text. Keep the first, absorb the rest.\n if (o.start < cursor) continue;\n out += `${text.slice(cursor, o.start)}«${text.slice(o.start, o.end)}»`;\n cursor = o.end;\n }\n out += text.slice(cursor, win.end);\n const prefix = win.start > 0 ? '…' : '';\n const suffix = win.end < text.length ? '…' : '';\n return `${prefix}${out.replace(/\\s+/g, ' ')}${suffix}`;\n}\n\n// Scores every occurrence-anchored candidate window: most distinct terms wins, ties broken by\n// most total hits -- coverage now that occurrences are real words, not the false-fragment counts\n// a substring scan produced. Selection itself is unevaluated (DESIGN.md \"Selection, unsettled\").\n// The window's `end` is fitted to the *rendered* text, markup included, not the raw span: a\n// window dense with marks (every guillemet pair adds two characters) shrinks to fit the same\n// budget a sparse one fills almost exactly.\nfunction scoreWindows(occ: Array<{ start: number; end: number; term: string }>, bounds: number[], text: string, charLimit: number): SnippetWindow[] {\n const candidates: SnippetWindow[] = [];\n for (let i = 0; i < occ.length; i++) {\n const winEnd = occ[i].start + charLimit;\n const seen = new Set<string>();\n let count = 0;\n for (let j = i; j < occ.length && occ[j].start < winEnd; j++) {\n seen.add(occ[j].term);\n count++;\n }\n const start = snapForward(bounds, occ[i].start);\n const floor = Math.max(start, occ[i].end);\n const upperBound = Math.max(floor, cutWindow(text, bounds, occ[i].start, charLimit).end);\n const end = fitEnd((e) => renderWindow(text, occ, { start, end: e }), bounds, floor, upperBound, charLimit);\n candidates.push({ start, end, distinct: seen.size, count });\n }\n return candidates;\n}\n\nfunction overlaps(a: Span, b: Span): boolean {\n return a.start < b.end && b.start < a.end;\n}\n\n// Same scoring function as a single snippet, kept rather than discarded (DESIGN.md \"Several\n// snippets per note\"): rank by score, take the top non-overlapping windows, then reorder to the\n// note's own order, since several passages from one note read as an abridged note.\nfunction selectWindows(candidates: SnippetWindow[], countLimit: number): { chosen: SnippetWindow[]; best: SnippetWindow } {\n const ranked = candidates.slice().sort((a, b) => b.distinct - a.distinct || b.count - a.count);\n const chosen: SnippetWindow[] = [];\n for (const c of ranked) {\n if (chosen.length >= countLimit) break;\n if (chosen.some((s) => overlaps(s, c))) continue;\n chosen.push(c);\n }\n chosen.sort((a, b) => a.start - b.start);\n return { chosen, best: ranked[0] };\n}\n\n// Builds bounded marked passages and returns the best window's offset for section lookup.\nexport function computeSnippets(text: string, terms: string[], charLimit: number, countLimit: number): { snippets: string[]; offset: number } {\n const occ = findOccurrences(text, terms);\n const bounds = wordBoundaries(text);\n if (occ.length === 0) {\n // A term matched only via title/summary, not this body text, finds no occurrence here;\n // fall back to the doc's start, unmarked.\n const render = (end: number): string => `${text.slice(0, end).replace(/\\s+/g, ' ').trim()}${end < text.length ? '…' : ''}`;\n const floor = bounds.find((b) => b > 0) ?? text.length;\n const upperBound = Math.max(floor, cutWindow(text, bounds, 0, charLimit).end);\n const end = fitEnd(render, bounds, floor, upperBound, charLimit);\n return { snippets: [render(end)], offset: 0 };\n }\n const candidates = scoreWindows(occ, bounds, text, charLimit);\n const { chosen, best } = selectWindows(candidates, countLimit);\n return { snippets: chosen.map((win) => renderWindow(text, occ, win)), offset: best.start };\n}\n\n// Converts an offset in the original text to its one-based line number.\nexport function lineNumberAt(text: string, offset: number): number {\n let line = 1;\n for (let i = 0; i < offset; i++) if (text.charCodeAt(i) === 10) line++;\n return line;\n}\n\nasync function lineRangeFor(store: Store, path: string, line: number): Promise<string | null> {\n const stmt = await store.prepare('SELECT start_line, end_line FROM sections WHERE \"path\" = ? AND start_line <= ? AND end_line >= ? ORDER BY start_line DESC LIMIT 1');\n const row = (await stmt.get(path, line, line)) as { start_line: number; end_line: number } | undefined;\n return row ? `L${row.start_line}-${row.end_line}` : null;\n}\n\nexport interface SearchOptions {\n k?: number;\n where?: string; // SQL fragment against frontmatter alias `f`, e.g. \"f.status = 'active'\"\n preset?: string; // named preset; unknown name throws listing declared presets, undefined -> \"default\"\n include?: string[]; // ad hoc scope override (repeatable --include); independent of exclude\n exclude?: string[]; // ad hoc scope override (repeatable --exclude); independent of include\n noExclude?: boolean; // --no-exclude: drop the preset's exclude for this command\n snippetCharLimit?: number; // --snippet-char-limit; defaults to SNIPPET_CHAR_LIMIT_DEFAULT\n snippetCountLimit?: number; // --snippet-count-limit; defaults to SNIPPET_COUNT_LIMIT_DEFAULT\n}\n\n// Hydrates already-ranked rows with snippets and containing-section ranges without reranking.\nexport async function hydrateSearchRows(store: Store, cfg: ResolvedConfig, rows: Row[], matchedPaths: Set<string>, terms: string, opts: Pick<SearchOptions, 'snippetCharLimit' | 'snippetCountLimit'> = {}): Promise<void> {\n if (matchedPaths.size === 0) return;\n const bareTerms = extractBareTerms(terms);\n const charLimit = opts.snippetCharLimit ?? SNIPPET_CHAR_LIMIT_DEFAULT;\n const countLimit = opts.snippetCountLimit ?? SNIPPET_COUNT_LIMIT_DEFAULT;\n for (const row of rows) {\n if (!matchedPaths.has(row.path as string)) continue;\n let text: string;\n try {\n text = readFileSync(join(cfg.baseDir, row.path as string), 'utf8');\n } catch {\n continue; // vanished since the match; leave snippets/lines empty rather than throw\n }\n const { snippets, offset } = computeSnippets(text, bareTerms, charLimit, countLimit);\n row.snippets = snippets;\n if (row.lines == null) row.lines = featureEnabled(cfg, 'sections') ? await lineRangeFor(store, row.path as string, lineNumberAt(text, offset)) : null;\n }\n}\n\n// The declared or defaulted signals compose via RRF; `via` names which ones produced each row.\n// `opts` arrives already resolved (config.ts:resolveSearch).\nexport async function search(store: Store, cfg: ResolvedConfig, terms: string, opts: SearchOptions = {}): Promise<Row[]> {\n const effective = resolveSearch(cfg, opts);\n const { k, signals } = effective;\n\n const allPaths = ((await (await store.prepare('SELECT \"path\" FROM frontmatter')).all()) as Array<{ path: string }>).map((r) => r.path);\n const scopePaths = await rawScope(store, cfg, opts, allPaths);\n const scopeActive = scopePaths.size < allPaths.length;\n // The set every candidate pool must be filtered to before truncation: scope narrowed by\n // --where, the same composition scopedPaths() gives the other commands.\n let allowedPaths: Set<string>;\n try {\n allowedPaths = await narrowByWhere(store, scopePaths, effective.where);\n } catch (err) {\n throw searchError(err as Error, terms, effective.where);\n }\n const fetch = Math.max(k * 3, 30);\n\n // A downloadable HF id proceeds -- getProvider fetches it lazily on consent. Only a\n // local path with missing files errors here, since nothing will ever fetch it for itself.\n const wantsVectors = signals.vectors !== undefined;\n if (wantsVectors) {\n const e = embedConfig(cfg); // validate.ts guarantees this is set whenever \"vectors\" is declared\n if (localModelMissing(e)) {\n throw new SenseError('EMBED_MODEL_MISSING', `preset \"${effective.presetName}\" searches with vectors, but the local model path \"${e.model}\" is missing ${MODEL_FILENAMES}; point embed.model at a directory containing them, or drop \"vectors\" from that preset's signals to search without them`);\n }\n }\n const semanticEnabled = wantsVectors && (await scopeHasEmbeddings(store, cfg, allowedPaths));\n\n // --where applies inside the candidate query (a post-filter would drop matches ranked past\n // the pool) and again on the final select, for link-derived rows.\n const scope = effective.where;\n const whereJoin = scope ? `JOIN frontmatter f ON f.\"path\" = content.path` : '';\n const whereCond = scope ? `AND (${scope})` : '';\n // Filtered before LIMIT, not after, or scoped notes ranking below the global top-`fetch`\n // never reach the filter; joined against a temp table since real scopes exceed SQLITE_MAX_VARIABLE_NUMBER.\n if (scopeActive) await materializeScope(store, '_search_scope', scopePaths);\n const scopeCond = scopeActive ? `AND content.path IN (SELECT \"path\" FROM _search_scope)` : '';\n\n const candidates = new Map<string, { score: number; via: string }>();\n let matchRows: LexicalHit[] = [];\n const hasEmptyPhrase = [...terms.matchAll(/\"([^\"]*)\"/g)].some((match) => !/[\\p{L}\\p{N}_]/u.test(match[1]));\n const hasBareSyntaxOnly = /[()]/u.test(terms.replace(/\"[^\"]*\"/g, ' '));\n // A query that is only whitespace or punctuation has no lexical rows; other declared signals\n // compose normally. In particular, unspaced-script punctuation can rewrite to an empty MATCH.\n if (signals.words !== undefined && terms.trim() !== '' && (/[\\p{L}\\p{N}_]/u.test(terms) || hasBareSyntaxOnly) && !hasEmptyPhrase) {\n const syntaxError = bareTermSyntaxError(terms);\n if (syntaxError) throw syntaxError;\n try {\n matchRows = await wordsCandidates(store, candidates, terms, whereJoin, whereCond, scopeCond, fetch, signals.words);\n } catch (err) {\n throw searchError(err as Error, terms, scope);\n }\n }\n // Every store's lexical `snippets` is NULL; the snippet text is always computed below.\n // Distinguish from via='link' rows, which never appear in matchRows.\n const matchedPaths = new Set(matchRows.map((r) => r.path));\n\n if (signals.links !== undefined) await linksCandidates(store, candidates, matchRows, allPaths, allowedPaths, fetch, signals.links);\n\n let chunkLines = new Map<string, string>();\n let chunkSimilarity = new Map<string, number>();\n if (semanticEnabled) {\n ({ chunkLines, chunkSimilarity } = await vectorsCandidates(store, cfg, candidates, terms, fetch, allowedPaths, signals.vectors as number));\n }\n\n await store.exec('DROP TABLE IF EXISTS _search');\n // DOUBLE, not REAL: sqlite's REAL is an 8-byte double but duckdb's is a 4-byte float, and the\n // rounded score/similarity are printed at full precision in rows.\n await store.exec('CREATE TEMP TABLE _search (\"path\" TEXT PRIMARY KEY, score DOUBLE, via TEXT, lines TEXT, similarity DOUBLE)');\n if (candidates.size > 0) {\n await store.runBatch(\n 'INSERT INTO _search (\"path\", score, via, lines, similarity) VALUES (?, ?, ?, ?, ?)',\n [...candidates].map(([path, c]) => [path, c.score, c.via, chunkLines.get(path) ?? null, chunkSimilarity.get(path) ?? null])\n );\n }\n\n // Reapplies --where even though _search is already scope+where filtered, since the join to\n // frontmatter is already needed for the path column.\n const where = scope ? `WHERE (${scope})` : '';\n // lines: semantic rows carry their chunk's range, lexical rows gain one below,\n // everything else stays null; similarity stays semantic-only.\n const similarityCol = semanticEnabled ? ', _search.similarity' : '';\n // NULL AS snippets holds this column's position (between summary and via) for every row;\n // overwritten below, always to an array, never left null (DESIGN.md).\n const selectStmt = await store.prepare(\n `SELECT f.\"path\" AS path, content.title, content.summary, NULL AS snippets, _search.via, round(_search.score, 4) AS score, _search.lines${similarityCol}\n FROM _search JOIN frontmatter f ON f.\"path\" = _search.\"path\" JOIN content ON content.path = _search.\"path\"\n ${where} ORDER BY _search.score DESC LIMIT ?`\n );\n const rows = (await selectStmt.all(k)) as Row[];\n for (const row of rows) row.snippets = [];\n\n await hydrateSearchRows(store, cfg, rows, matchedPaths, terms, opts);\n\n return rows;\n}\n"],"names":["SNIPPET_CHAR_LIMIT_DEFAULT","SNIPPET_COUNT_LIMIT_DEFAULT","computeSnippets","hydrateSearchRows","lineNumberAt","search","extractBareTerms","query","cleaned","replace","split","map","tok","flatMap","searchTokens","text","toLowerCase","trim","filter","length","wordSegmenter","findOccurrences","terms","occ","textLower","unspacedTerms","hasUnspacedRun","unspacedRuns","run","runLower","slice","start","end","term","idx","found","indexOf","push","spacedTerms","t","termByStem","Map","stemmer","foldForSearch","stemInitials","Set","Array","from","keys","match","segment","unspaced","folded","has","get","undefined","sort","a","b","wordBoundaries","Intl","Segmenter","granularity","bounds","index","snapForward","pos","lo","hi","mid","snapBackward","result","firstBoundAfter","cutWindow","anchor","charLimit","rawEnd","Math","min","fitEnd","render","floor","upperBound","firstOccAtOrAfter","renderWindow","win","out","cursor","i","o","prefix","suffix","scoreWindows","winEnd","seen","count","j","add","max","e","candidates","distinct","size","overlaps","selectWindows","countLimit","ranked","chosen","c","some","s","best","find","snippets","offset","line","charCodeAt","lineRangeFor","store","path","stmt","row","prepare","start_line","end_line","cfg","rows","matchedPaths","opts","bareTerms","snippetCharLimit","snippetCountLimit","readFileSync","join","baseDir","lines","featureEnabled","effective","k","signals","allPaths","scopePaths","scopeActive","allowedPaths","err","fetch","wantsVectors","semanticEnabled","scope","whereJoin","whereCond","scopeCond","matchRows","hasEmptyPhrase","hasBareSyntaxOnly","syntaxError","chunkLines","chunkSimilarity","where","similarityCol","selectStmt","resolveSearch","all","r","rawScope","narrowByWhere","searchError","vectors","embedConfig","localModelMissing","SenseError","presetName","MODEL_FILENAMES","model","scopeHasEmbeddings","materializeScope","matchAll","test","words","bareTermSyntaxError","wordsCandidates","links","linksCandidates","vectorsCandidates","exec","runBatch","score","via"],"mappings":";;;;;;;;;;;QAgBaA;eAAAA;;QACAC;eAAAA;;QAoOGC;eAAAA;;QA0CMC;eAAAA;;QAxBNC;eAAAA;;QA6CMC;eAAAA;;;sBApTO;wBACR;uBACG;uBAEmC;uBACR;wBACxB;6BAEsB;yBAEyB;uBACI;yBACV;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAI7D,IAAML,6BAA6B;AACnC,IAAMC,8BAA8B;AAE3C,yFAAyF;AACzF,oGAAoG;AACpG,SAASK,iBAAiBC,KAAa;IACrC,IAAMC,UAAUD,MACbE,OAAO,CAAC,MAAM,KACdA,OAAO,CAAC,UAAU,KAClBA,OAAO,CAAC,kCAAkC;IAC7C,OAAOD,QACJE,KAAK,CAAC,OACNC,GAAG,CAAC,SAACC;eAAQA,IAAIH,OAAO,CAAC,kBAAkB;OAAK,iCAAiC;KACjFI,OAAO,CAAC,SAACD;eAAQE,IAAAA,uBAAY,EAACF,KAAKD,GAAG,CAAC;gBAAGI,aAAAA;mBAAWA;;OACrDJ,GAAG,CAAC,SAACC;eAAQA,IAAII,WAAW,GAAGC,IAAI;OACnCC,MAAM,CAAC,SAACN;eAAQA,IAAIO,MAAM,GAAG;;AAClC;AAEA,8FAA8F;AAC9F,8FAA8F;AAC9F,IAAIC;AAEJ,SAASC,gBAAgBN,IAAY,EAAEO,KAAe;IACpD,IAAMC,MAA2D,EAAE;IACnE,IAAMC,YAAYT,KAAKC,WAAW;IAElC,8FAA8F;IAC9F,wFAAwF;IACxF,IAAMS,gBAAgBH,MAAMJ,MAAM,CAACQ,yBAAc;IACjD,IAAID,cAAcN,MAAM,GAAG,GAAG;YACvB,kCAAA,2BAAA;;YAAL,QAAK,YAAaQ,IAAAA,uBAAY,EAACZ,0BAA1B,SAAA,6BAAA,QAAA,yBAAA,iCAAiC;gBAAjC,IAAMa,MAAN;gBACH,IAAMC,WAAWL,UAAUM,KAAK,CAACF,IAAIG,KAAK,EAAEH,IAAII,GAAG;oBAC9C,mCAAA,4BAAA;;oBAAL,QAAK,aAAcP,kCAAd,UAAA,8BAAA,SAAA,0BAAA,kCAA6B;wBAA7B,IAAMQ,OAAN;wBACH,IAAIC,MAAM;wBACV,OAAS;4BACP,IAAMC,QAAQN,SAASO,OAAO,CAACH,MAAMC;4BACrC,IAAIC,UAAU,CAAC,GAAG;4BAClBZ,IAAIc,IAAI,CAAC;gCAAEN,OAAOH,IAAIG,KAAK,GAAGI;gCAAOH,KAAKJ,IAAIG,KAAK,GAAGI,QAAQF,KAAKd,MAAM;gCAAEc,MAAAA;4BAAK;4BAChFC,MAAMC,QAAQF,KAAKd,MAAM;wBAC3B;oBACF;;oBARK;oBAAA;;;6BAAA,8BAAA;4BAAA;;;4BAAA;kCAAA;;;;YASP;;YAXK;YAAA;;;qBAAA,6BAAA;oBAAA;;;oBAAA;0BAAA;;;;IAYP;IAEA,6FAA6F;IAC7F,uGAAuG;IACvG,IAAMmB,cAAchB,MAAMJ,MAAM,CAAC,SAACqB;eAAM,CAACb,IAAAA,yBAAc,EAACa;;IACxD,IAAID,YAAYnB,MAAM,GAAG,GAAG;QAC1B,IAAMqB,aAAa,IAAIC,IAAIH,YAAY3B,GAAG,CAAC,SAAC4B;mBAAM;gBAACG,IAAAA,gBAAO,EAACC,IAAAA,wBAAa,EAACJ;gBAAKA;aAAE;;QAChF,IAAMK,eAAe,IAAIC,IAAIC,MAAMC,IAAI,CAACP,WAAWQ,IAAI,IAAI,SAACf;mBAASA,IAAI,CAAC,EAAE;;YACvE,mCAAA,4BAAA;;YAAL,QAAK,aAAenB,IAAAA,uBAAY,EAACC,0BAA5B,UAAA,8BAAA,SAAA,0BAAA,kCAAmC;gBAAnC,IAAMkC,QAAN;gBACH,IAAMC,UAAUD,MAAMlC,IAAI;gBAC1B,IAAIkC,MAAME,QAAQ,EAAE;gBACpB,IAAMC,SAAST,IAAAA,wBAAa,EAACO;gBAC7B,2FAA2F;gBAC3F,IAAI,CAACN,aAAaS,GAAG,CAACD,MAAM,CAAC,EAAE,GAAG;gBAClC,IAAMnB,QAAOO,WAAWc,GAAG,CAACZ,IAAAA,gBAAO,EAACU;gBACpC,IAAInB,UAASsB,WAAWhC,IAAIc,IAAI,CAAC;oBAAEN,OAAOkB,MAAMlB,KAAK;oBAAEC,KAAKiB,MAAMjB,GAAG;oBAAEC,MAAAA;gBAAK;YAC9E;;YARK;YAAA;;;qBAAA,8BAAA;oBAAA;;;oBAAA;0BAAA;;;;IASP;IAEA,OAAOV,IAAIiC,IAAI,CAAC,SAACC,GAAGC;eAAMD,EAAE1B,KAAK,GAAG2B,EAAE3B,KAAK,IAAI2B,EAAE1B,GAAG,GAAGyB,EAAEzB,GAAG;;AAC9D;AAEA,6FAA6F;AAC7F,+FAA+F;AAC/F,gGAAgG;AAChG,SAAS2B,eAAe5C,IAAY;IAClCK,0BAAAA,2BAAAA,gBAAAA,gBAAkB,IAAIwC,KAAKC,SAAS,CAAC,MAAM;QAAEC,aAAa;IAAO;IACjE,IAAMC,SAAS;QAAC;KAAE;QACb,kCAAA,2BAAA;;QAAL,QAAK,YAA4B3C,cAAc8B,OAAO,CAACnC,0BAAlD,SAAA,6BAAA,QAAA,yBAAA;YAAA,kBAAA,aAAQiD,oBAAAA,OAAOd,sBAAAA;YAA0Ca,OAAO1B,IAAI,CAAC2B,QAAQd,QAAQ/B,MAAM;;;QAA3F;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IACL,OAAO4C;AACT;AAEA,0FAA0F;AAC1F,SAASE,YAAYF,MAAgB,EAAEG,GAAW;IAChD,IAAIC,KAAK;IACT,IAAIC,KAAKL,OAAO5C,MAAM,GAAG;IACzB,MAAOgD,KAAKC,GAAI;QACd,IAAMC,MAAM,AAACF,KAAKC,MAAO;QACzB,IAAIL,MAAM,CAACM,IAAI,GAAGH,KAAKC,KAAKE,MAAM;aAC7BD,KAAKC;IACZ;IACA,OAAON,MAAM,CAACI,GAAG;AACnB;AAEA,SAASG,aAAaP,MAAgB,EAAEG,GAAW;IACjD,IAAIC,KAAK;IACT,IAAIC,KAAKL,OAAO5C,MAAM,GAAG;IACzB,IAAIoD,SAASR,MAAM,CAAC,EAAE;IACtB,MAAOI,KAAKC,GAAI;QACd,IAAMC,MAAM,AAACF,KAAKC,KAAK,KAAM;QAC7B,IAAIL,MAAM,CAACM,IAAI,IAAIH,KAAK;YACtBC,KAAKE;YACLE,SAASR,MAAM,CAACM,IAAI;QACtB,OAAOD,KAAKC,MAAM;IACpB;IACA,OAAOE;AACT;AAEA,SAASC,gBAAgBT,MAAgB,EAAEG,GAAW;IACpD,IAAIC,KAAK;IACT,IAAIC,KAAKL,OAAO5C,MAAM;IACtB,MAAOgD,KAAKC,GAAI;QACd,IAAMC,MAAM,AAACF,KAAKC,MAAO;QACzB,IAAIL,MAAM,CAACM,IAAI,IAAIH,KAAKC,KAAKE,MAAM;aAC9BD,KAAKC;IACZ;IACA,OAAON,MAAM,CAACI,GAAG;AACnB;AAEA,wFAAwF;AACxF,8FAA8F;AAC9F,8FAA8F;AAC9F,+FAA+F;AAC/F,mFAAmF;AACnF,SAASM,UAAU1D,IAAY,EAAEgD,MAAgB,EAAEW,MAAc,EAAEC,SAAiB;QAI1DH;IAHxB,IAAMI,SAASC,KAAKC,GAAG,CAAC/D,KAAKI,MAAM,EAAEuD,SAASC;IAC9C,IAAM5C,QAAQkC,YAAYF,QAAQW;IAClC,IAAI1C,MAAMsC,aAAaP,QAAQa;IAC/B,IAAI5C,OAAOD,OAAOC,OAAMwC,mBAAAA,gBAAgBT,QAAQhC,oBAAxByC,8BAAAA,mBAAkCzD,KAAKI,MAAM;IACrE,OAAO;QAAEY,OAAAA;QAAOC,KAAK6C,KAAKC,GAAG,CAAC9C,KAAKjB,KAAKI,MAAM;IAAE;AAClD;AAEA,8FAA8F;AAC9F,0FAA0F;AAC1F,wFAAwF;AACxF,6FAA6F;AAC7F,+FAA+F;AAC/F,wDAAwD;AACxD,SAAS4D,OAAOC,MAA+B,EAAEjB,MAAgB,EAAEkB,KAAa,EAAEC,UAAkB,EAAEP,SAAiB;IACrH,IAAIR,KAAK;IACT,IAAIC,KAAKL,OAAO5C,MAAM,GAAG;IACzB,MAAOgD,KAAKC,GAAI;QACd,IAAMC,MAAM,AAACF,KAAKC,KAAK,KAAM;QAC7B,IAAIL,MAAM,CAACM,IAAI,IAAIa,YAAYf,KAAKE;aAC/BD,KAAKC,MAAM;IAClB;IACA,MAAOF,MAAM,KAAKJ,MAAM,CAACI,GAAG,GAAGc,OAAOd,KAAM;QAC1C,IAAIa,OAAOjB,MAAM,CAACI,GAAG,EAAEhD,MAAM,IAAIwD,WAAW,OAAOZ,MAAM,CAACI,GAAG;IAC/D;IACA,OAAOc;AACT;AAYA,6FAA6F;AAC7F,SAASE,kBAAkB5D,GAAwD,EAAE2C,GAAW;IAC9F,IAAIC,KAAK;IACT,IAAIC,KAAK7C,IAAIJ,MAAM;IACnB,MAAOgD,KAAKC,GAAI;QACd,IAAMC,MAAM,AAACF,KAAKC,MAAO;QACzB,IAAI7C,GAAG,CAAC8C,IAAI,CAACtC,KAAK,GAAGmC,KAAKC,KAAKE,MAAM;aAChCD,KAAKC;IACZ;IACA,OAAOF;AACT;AAEA,SAASiB,aAAarE,IAAY,EAAEQ,GAAwD,EAAE8D,GAAS;IACrG,IAAIC,MAAM;IACV,IAAIC,SAASF,IAAItD,KAAK;IACtB,IAAK,IAAIyD,IAAIL,kBAAkB5D,KAAK8D,IAAItD,KAAK,GAAGyD,IAAIjE,IAAIJ,MAAM,IAAII,GAAG,CAACiE,EAAE,CAACzD,KAAK,GAAGsD,IAAIrD,GAAG,EAAEwD,IAAK;QAC7F,IAAMC,IAAIlE,GAAG,CAACiE,EAAE;QAChB,IAAIC,EAAEzD,GAAG,GAAGqD,IAAIrD,GAAG,EAAE;QACrB,sFAAsF;QACtF,gFAAgF;QAChF,IAAIyD,EAAE1D,KAAK,GAAGwD,QAAQ;QACtBD,OAAO,AAAC,GAAiCvE,OAA/BA,KAAKe,KAAK,CAACyD,QAAQE,EAAE1D,KAAK,GAAE,QAA8B,OAA3BhB,KAAKe,KAAK,CAAC2D,EAAE1D,KAAK,EAAE0D,EAAEzD,GAAG,GAAE;QACpEuD,SAASE,EAAEzD,GAAG;IAChB;IACAsD,OAAOvE,KAAKe,KAAK,CAACyD,QAAQF,IAAIrD,GAAG;IACjC,IAAM0D,SAASL,IAAItD,KAAK,GAAG,IAAI,MAAM;IACrC,IAAM4D,SAASN,IAAIrD,GAAG,GAAGjB,KAAKI,MAAM,GAAG,MAAM;IAC7C,OAAO,AAAC,GAAWmE,OAATI,QAAoCC,OAA3BL,IAAI7E,OAAO,CAAC,QAAQ,MAAc,OAAPkF;AAChD;AAEA,8FAA8F;AAC9F,iGAAiG;AACjG,iGAAiG;AACjG,4FAA4F;AAC5F,6FAA6F;AAC7F,4CAA4C;AAC5C,SAASC,aAAarE,GAAwD,EAAEwC,MAAgB,EAAEhD,IAAY,EAAE4D,SAAiB;;QAG7H,IAAMkB,SAAStE,GAAG,CAACiE,EAAE,CAACzD,KAAK,GAAG4C;QAC9B,IAAMmB,OAAO,IAAIjD;QACjB,IAAIkD,QAAQ;QACZ,IAAK,IAAIC,IAAIR,GAAGQ,IAAIzE,IAAIJ,MAAM,IAAII,GAAG,CAACyE,EAAE,CAACjE,KAAK,GAAG8D,QAAQG,IAAK;YAC5DF,KAAKG,GAAG,CAAC1E,GAAG,CAACyE,EAAE,CAAC/D,IAAI;YACpB8D;QACF;QACA,IAAMhE,QAAQkC,YAAYF,QAAQxC,GAAG,CAACiE,EAAE,CAACzD,KAAK;QAC9C,IAAMkD,QAAQJ,KAAKqB,GAAG,CAACnE,OAAOR,GAAG,CAACiE,EAAE,CAACxD,GAAG;QACxC,IAAMkD,aAAaL,KAAKqB,GAAG,CAACjB,OAAOR,UAAU1D,MAAMgD,QAAQxC,GAAG,CAACiE,EAAE,CAACzD,KAAK,EAAE4C,WAAW3C,GAAG;QACvF,IAAMA,MAAM+C,OAAO,SAACoB;mBAAMf,aAAarE,MAAMQ,KAAK;gBAAEQ,OAAAA;gBAAOC,KAAKmE;YAAE;WAAIpC,QAAQkB,OAAOC,YAAYP;QACjGyB,WAAW/D,IAAI,CAAC;YAAEN,OAAAA;YAAOC,KAAAA;YAAKqE,UAAUP,KAAKQ,IAAI;YAAEP,OAAAA;QAAM;IAC3D;IAdA,IAAMK,aAA8B,EAAE;IACtC,IAAK,IAAIZ,IAAI,GAAGA,IAAIjE,IAAIJ,MAAM,EAAEqE;IAchC,OAAOY;AACT;AAEA,SAASG,SAAS9C,CAAO,EAAEC,CAAO;IAChC,OAAOD,EAAE1B,KAAK,GAAG2B,EAAE1B,GAAG,IAAI0B,EAAE3B,KAAK,GAAG0B,EAAEzB,GAAG;AAC3C;AAEA,4FAA4F;AAC5F,gGAAgG;AAChG,mFAAmF;AACnF,SAASwE,cAAcJ,UAA2B,EAAEK,UAAkB;IACpE,IAAMC,SAASN,WAAWtE,KAAK,GAAG0B,IAAI,CAAC,SAACC,GAAGC;eAAMA,EAAE2C,QAAQ,GAAG5C,EAAE4C,QAAQ,IAAI3C,EAAEqC,KAAK,GAAGtC,EAAEsC,KAAK;;IAC7F,IAAMY,SAA0B,EAAE;QAC7B,kCAAA,2BAAA;;;YAAA,IAAMC,IAAN;YACH,IAAID,OAAOxF,MAAM,IAAIsF,YAAY,OAAA;YACjC,IAAIE,OAAOE,IAAI,CAAC,SAACC;uBAAMP,SAASO,GAAGF;gBAAK,OAAA;YACxCD,OAAOtE,IAAI,CAACuE;QACd;QAJA,QAAK,YAAWF,2BAAX,SAAA,6BAAA,QAAA,yBAAA;;;;;QAAA;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IAKLC,OAAOnD,IAAI,CAAC,SAACC,GAAGC;eAAMD,EAAE1B,KAAK,GAAG2B,EAAE3B,KAAK;;IACvC,OAAO;QAAE4E,QAAAA;QAAQI,MAAML,MAAM,CAAC,EAAE;IAAC;AACnC;AAGO,SAASxG,gBAAgBa,IAAY,EAAEO,KAAe,EAAEqD,SAAiB,EAAE8B,UAAkB;IAClG,IAAMlF,MAAMF,gBAAgBN,MAAMO;IAClC,IAAMyC,SAASJ,eAAe5C;IAC9B,IAAIQ,IAAIJ,MAAM,KAAK,GAAG;YAIN4C;QAHd,uFAAuF;QACvF,0CAA0C;QAC1C,IAAMiB,SAAS,gBAAChD;mBAAwB,AAAC,GAAmDA,OAAjDjB,KAAKe,KAAK,CAAC,GAAGE,KAAKvB,OAAO,CAAC,QAAQ,KAAKQ,IAAI,IAAkC,OAA7Be,MAAMjB,KAAKI,MAAM,GAAG,MAAM;;QACtH,IAAM8D,SAAQlB,eAAAA,OAAOiD,IAAI,CAAC,SAACtD;mBAAMA,IAAI;wBAAvBK,0BAAAA,eAA6BhD,KAAKI,MAAM;QACtD,IAAM+D,aAAaL,KAAKqB,GAAG,CAACjB,OAAOR,UAAU1D,MAAMgD,QAAQ,GAAGY,WAAW3C,GAAG;QAC5E,IAAMA,MAAM+C,OAAOC,QAAQjB,QAAQkB,OAAOC,YAAYP;QACtD,OAAO;YAAEsC,UAAU;gBAACjC,OAAOhD;aAAK;YAAEkF,QAAQ;QAAE;IAC9C;IACA,IAAMd,aAAaR,aAAarE,KAAKwC,QAAQhD,MAAM4D;IACnD,IAAyB6B,iBAAAA,cAAcJ,YAAYK,aAA3CE,SAAiBH,eAAjBG,QAAQI,OAASP,eAATO;IAChB,OAAO;QAAEE,UAAUN,OAAOhG,GAAG,CAAC,SAAC0E;mBAAQD,aAAarE,MAAMQ,KAAK8D;;QAAO6B,QAAQH,KAAKhF,KAAK;IAAC;AAC3F;AAGO,SAAS3B,aAAaW,IAAY,EAAEmG,MAAc;IACvD,IAAIC,OAAO;IACX,IAAK,IAAI3B,IAAI,GAAGA,IAAI0B,QAAQ1B,IAAK,IAAIzE,KAAKqG,UAAU,CAAC5B,OAAO,IAAI2B;IAChE,OAAOA;AACT;AAEA,SAAeE,aAAaC,KAAY,EAAEC,IAAY,EAAEJ,IAAY;;YAC5DK,MACAC;;;;oBADO;;wBAAMH,MAAMI,OAAO,CAAC;;;oBAA3BF,OAAO;oBACA;;wBAAMA,KAAKlE,GAAG,CAACiE,MAAMJ,MAAMA;;;oBAAlCM,MAAO;oBACb;;wBAAOA,MAAM,AAAC,IAAqBA,OAAlBA,IAAIE,UAAU,EAAC,KAAgB,OAAbF,IAAIG,QAAQ,IAAK;;;;IACtD;;AAcO,SAAezH;wCAAkBmH,KAAY,EAAEO,GAAmB,EAAEC,IAAW,EAAEC,YAAyB,EAAEzG,KAAa;YAAE0G,MAG9GA,wBACCA,yBAFbC,WACAtD,WACA8B,YACD,2BAAA,mBAAA,gBAAA,WAAA,OAAMgB,KAEL1G,MAMyBb,kBAArB+G,UAAUC;;;;;oBAb4Gc,OAAAA,oEAAsE,CAAC;oBACvM,IAAID,aAAazB,IAAI,KAAK,GAAG;;;oBACvB2B,YAAY3H,iBAAiBgB;oBAC7BqD,aAAYqD,yBAAAA,KAAKE,gBAAgB,cAArBF,oCAAAA,yBAAyBhI;oBACrCyG,cAAauB,0BAAAA,KAAKG,iBAAiB,cAAtBH,qCAAAA,0BAA0B/H;oBACxC,kCAAA,2BAAA;;;;;;;;;oBAAA,YAAa6H;;;2BAAb,6BAAA,QAAA;;;;oBAAML,MAAN;oBACH,IAAI,CAACM,aAAa1E,GAAG,CAACoE,IAAIF,IAAI,GAAa;;;;oBACvCxG,OAAAA,KAAAA;oBACJ,IAAI;wBACFA,OAAOqH,IAAAA,oBAAY,EAACC,IAAAA,cAAI,EAACR,IAAIS,OAAO,EAAEb,IAAIF,IAAI,GAAa;oBAC7D,EAAE,eAAM;wBACN;;;2BAAU,yEAAyE;oBACrF;oBAC6BrH,mBAAAA,gBAAgBa,MAAMkH,WAAWtD,WAAW8B,aAAjEQ,WAAqB/G,iBAArB+G,UAAUC,SAAWhH,iBAAXgH;oBAClBO,IAAIR,QAAQ,GAAGA;yBACXQ,CAAAA,IAAIc,KAAK,IAAI,IAAG,GAAhBd;;;;yBAA+Be,IAAAA,uBAAc,EAACX,KAAK,aAApBW;;;;oBAAkC;;wBAAMnB,aAAaC,OAAOG,IAAIF,IAAI,EAAYnH,aAAaW,MAAMmG;;;2BAAjE;;;;;;2BAA4E;;;oBAA1HO,IAAIc,KAAK;;;oBAV7B;;;;;;;;;;;;oBAAA;oBAAA;;;;;;;6BAAA,6BAAA;4BAAA;;;4BAAA;kCAAA;;;;;;;;;;;;IAYP;;AAIO,SAAelI;wCAAOiH,KAAY,EAAEO,GAAmB,EAAEvG,KAAa;YAAE0G,MACvES,WACEC,GAAGC,SAELC,UACAC,YACAC,aAGFC,cAGKC,MAGHC,OAIAC,cAEE/C,GAKFgD,uBAIAC,OACAC,WACAC,WAIAC,WAEAnD,YACFoD,WACEC,gBACAC,mBAIEC,aAIGX,MAMLjB,cAIF6B,YACAC,sBAkBEC,OAGAC,eAGAC,YAKAlC,MACD,2BAAA,mBAAA,gBAAA,WAAA,OAAML;;;;;oBA1FkEO,OAAAA,oEAAsB,CAAC;oBAC9FS,YAAYwB,IAAAA,sBAAa,EAACpC,KAAKG;oBAC7BU,IAAeD,UAAfC,GAAGC,UAAYF,UAAZE;oBAEe;;wBAAMrB,MAAMI,OAAO,CAAC;;;oBAA3B;;wBAAO,cAAuDwC,GAAG;;;oBAA9EtB,WAAW,AAAE,cAAiGjI,GAAG,CAAC,SAACwJ;+BAAMA,EAAE5C,IAAI;;oBAClH;;wBAAM6C,IAAAA,iBAAQ,EAAC9C,OAAOO,KAAKG,MAAMY;;;oBAA9CC,aAAa;oBACbC,cAAcD,WAAWvC,IAAI,GAAGsC,SAASzH,MAAM;;;;;;;;;oBAKpC;;wBAAMkJ,IAAAA,sBAAa,EAAC/C,OAAOuB,YAAYJ,UAAUqB,KAAK;;;oBAArEf,eAAe;;;;;;oBACRC;oBACP,MAAMsB,IAAAA,0BAAW,EAACtB,MAAc1H,OAAOmH,UAAUqB,KAAK;;oBAElDb,QAAQpE,KAAKqB,GAAG,CAACwC,IAAI,GAAG;oBAE9B,oFAAoF;oBACpF,0FAA0F;oBACpFQ,eAAeP,QAAQ4B,OAAO,KAAKhH;oBACzC,IAAI2F,cAAc;wBACV/C,IAAIqE,IAAAA,oBAAW,EAAC3C,MAAM,oEAAoE;wBAChG,IAAI4C,IAAAA,0BAAiB,EAACtE,IAAI;4BACxB,MAAM,IAAIuE,oBAAU,CAAC,uBAAuB,AAAC,WAAoFvE,OAA1EsC,UAAUkC,UAAU,EAAC,uDAA4EC,OAAvBzE,EAAE0E,KAAK,EAAC,iBAA+B,OAAhBD,wBAAe,EAAC;wBAC1K;oBACF;2BACwB1B;+BAAAA;;;;oBAAiB;;wBAAM4B,IAAAA,2BAAkB,EAACxD,OAAOO,KAAKkB;;;2BAArC;;;oBAAnCI;oBAEN,2FAA2F;oBAC3F,kEAAkE;oBAC5DC,QAAQX,UAAUqB,KAAK;oBACvBT,YAAYD,QAAQ,kDAAkD;oBACtEE,YAAYF,QAAQ,AAAC,QAAa,OAANA,OAAM,OAAK;yBAGzCN,aAAAA;;;;oBAAa;;wBAAMiC,IAAAA,yBAAgB,EAACzD,OAAO,iBAAiBuB;;;oBAA/C;;;oBACXU,YAAYT,cAAc,2DAA2D;oBAErF1C,aAAa,IAAI3D;oBACnB+G;oBACEC,iBAAiB,AAAC,qBAAGnI,MAAM0J,QAAQ,CAAC,eAAenE,IAAI,CAAC,SAAC5D;+BAAU,CAAC,4maAAiBgI,IAAI,CAAChI,KAAK,CAAC,EAAE;;oBAClGyG,oBAAoB,oBAAQuB,IAAI,CAAC3J,MAAMb,OAAO,CAAC,YAAY;yBAG7DkI,CAAAA,QAAQuC,KAAK,KAAK3H,aAAajC,MAAML,IAAI,OAAO,MAAO,CAAA,4maAAiBgK,IAAI,CAAC3J,UAAUoI,iBAAgB,KAAM,CAACD,cAAa,GAA3Hd;;;;oBACIgB,cAAcwB,IAAAA,kCAAmB,EAAC7J;oBACxC,IAAIqI,aAAa,MAAMA;;;;;;;;;oBAET;;wBAAMyB,IAAAA,0BAAe,EAAC9D,OAAOlB,YAAY9E,OAAO+H,WAAWC,WAAWC,WAAWN,OAAON,QAAQuC,KAAK;;;oBAAjH1B,YAAY;;;;;;oBACLR;oBACP,MAAMsB,IAAAA,0BAAW,EAACtB,MAAc1H,OAAO8H;;oBAG3C,uFAAuF;oBACvF,qEAAqE;oBAC/DrB,eAAe,IAAIlF,IAAI2G,UAAU7I,GAAG,CAAC,SAACwJ;+BAAMA,EAAE5C,IAAI;;yBAEpDoB,CAAAA,QAAQ0C,KAAK,KAAK9H,SAAQ,GAA1BoF;;;;oBAA6B;;wBAAM2C,IAAAA,0BAAe,EAAChE,OAAOlB,YAAYoD,WAAWZ,UAAUG,cAAcE,OAAON,QAAQ0C,KAAK;;;oBAAhG;;;oBAE7BzB,aAAa,IAAInH;oBACjBoH,kBAAkB,IAAIpH;yBACtB0G,iBAAAA;;;;oBACiC;;wBAAMoC,IAAAA,4BAAiB,EAACjE,OAAOO,KAAKzB,YAAY9E,OAAO2H,OAAOF,cAAcJ,QAAQ4B,OAAO;;;0BAA3F,eAAhCX,iBAAAA,YAAYC,sBAAAA;;;oBAGjB;;wBAAMvC,MAAMkE,IAAI,CAAC;;;oBAAjB;oBACA,8FAA8F;oBAC9F,kEAAkE;oBAClE;;wBAAMlE,MAAMkE,IAAI,CAAC;;;oBAAjB;yBACIpF,CAAAA,WAAWE,IAAI,GAAG,CAAA,GAAlBF;;;;oBACF;;wBAAMkB,MAAMmE,QAAQ,CAClB,sFACA,AAAC,qBAAGrF,YAAYzF,GAAG,CAAC;qEAAE4G,kBAAMX;gCAA8BgD,iBAA8BC;mCAArD;gCAACtC;gCAAMX,EAAE8E,KAAK;gCAAE9E,EAAE+E,GAAG;iCAAE/B,kBAAAA,WAAWtG,GAAG,CAACiE,mBAAfqC,6BAAAA,kBAAwB;iCAAMC,uBAAAA,gBAAgBvG,GAAG,CAACiE,mBAApBsC,kCAAAA,uBAA6B;6BAAK;;;;oBAF5H;;;oBAMF,2FAA2F;oBAC3F,qDAAqD;oBAC/CC,QAAQV,QAAQ,AAAC,UAAe,OAANA,OAAM,OAAK;oBAC3C,+EAA+E;oBAC/E,8DAA8D;oBACxDW,gBAAgBZ,kBAAkB,yBAAyB;oBAG9C;;wBAAM7B,MAAMI,OAAO,CACpC,AAAC,0IAEIoC,OAFqIC,eAAc,gIAE7I,OAAND,OAAM;;;oBAHPE,aAAa;oBAKL;;wBAAMA,WAAWE,GAAG,CAACxB;;;oBAA7BZ,OAAQ;oBACT,kCAAA,2BAAA;;wBAAL,IAAK,YAAaA,2BAAb,6BAAA,QAAA,yBAAA;4BAAML,MAAN;4BAAmBA,IAAIR,QAAQ;;;wBAA/B;wBAAA;;;iCAAA,6BAAA;gCAAA;;;gCAAA;sCAAA;;;;oBAEL;;wBAAM9G,kBAAkBmH,OAAOO,KAAKC,MAAMC,cAAczG,OAAO0G;;;oBAA/D;oBAEA;;wBAAOF;;;;IACT"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/search.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { stemmer } from 'stemmer';\nimport type { ResolvedConfig } from '../config/index.ts';\nimport { embedConfig, featureEnabled, resolveSearch } from '../config/index.ts';\nimport { localModelMissing, MODEL_FILENAMES } from '../embed/store.ts';\nimport { SenseError } from '../errors.ts';\nimport type { Row } from '../output/output.ts';\nimport { bareTermSyntaxError, searchError } from '../output/search-error.ts';\nimport type { LexicalHit, Store } from '../store/types.ts';\nimport { foldForSearch, hasUnspacedRun, searchTokens, unspacedRuns } from '../text/segment.ts';\nimport { materializeScope, narrowByWhere, rawScope, scopeHasEmbeddings } from './scope.ts';\nimport { linksCandidates, vectorsCandidates, wordsCandidates } from './signals.ts';\n\n// Default budget behind --snippet-char-limit/--snippet-count-limit: the limit is whatever the\n// caller passes, these only say what happens when they pass nothing (DESIGN.md \"Search snippets\").\nexport const SNIPPET_CHAR_LIMIT_DEFAULT = 80;\nexport const SNIPPET_COUNT_LIMIT_DEFAULT = 1;\n\n// Bare terms from an FTS5 query string: strips operators/quoting, not real terms, so the\n// snippet scan matches what the query matched -- FTS5 operators are uppercase-only, so this is too.\nfunction extractBareTerms(query: string): string[] {\n const cleaned = query\n .replace(/\"/g, ' ')\n .replace(/[()*]/g, ' ')\n .replace(/\\b(AND|OR|NOT|NEAR)\\b(\\/\\d+)?/g, ' ');\n return cleaned\n .split(/\\s+/)\n .map((tok) => tok.replace(/^[A-Za-z_]\\w*:/, '')) // column filter, e.g. title:term\n .flatMap((tok) => searchTokens(tok).map(({ text }) => text))\n .map((tok) => tok.toLowerCase().trim())\n .filter((tok) => tok.length > 0);\n}\n\n// House convention (src/chunk/group.ts): Intl.Segmenter word boundaries, not a bare \\b, which\n// is ASCII-only. Built on first use: construction is a few ms, paid only when a term matches.\nlet wordSegmenter: Intl.Segmenter | undefined;\n\nfunction findOccurrences(text: string, terms: string[]): Array<{ start: number; end: number; term: string }> {\n const occ: Array<{ start: number; end: number; term: string }> = [];\n const textLower = text.toLowerCase();\n\n // Unspaced scripts (UNSPACED_SCRIPTS) mark no word boundaries: the sense-setup skill promises\n // substring semantics there, so a matching term is found wherever it occurs in the run.\n const unspacedTerms = terms.filter(hasUnspacedRun);\n if (unspacedTerms.length > 0) {\n for (const run of unspacedRuns(text)) {\n const runLower = textLower.slice(run.start, run.end);\n for (const term of unspacedTerms) {\n let idx = 0;\n for (;;) {\n const found = runLower.indexOf(term, idx);\n if (found === -1) break;\n occ.push({ start: run.start + found, end: run.start + found + term.length, term });\n idx = found + term.length;\n }\n }\n }\n }\n\n // Spaced scripts: a word is marked when its porter stem equals a query term's stem, the same\n // algorithm both indexes tokenize with (sqlite's TOKENIZE = 'porter unicode61'; duckdb's fts default).\n const spacedTerms = terms.filter((t) => !hasUnspacedRun(t));\n if (spacedTerms.length > 0) {\n const termByStem = new Map(spacedTerms.map((t) => [stemmer(foldForSearch(t)), t]));\n const stemInitials = new Set(Array.from(termByStem.keys(), (term) => term[0]));\n for (const match of searchTokens(text)) {\n const segment = match.text;\n if (match.unspaced) continue;\n const folded = foldForSearch(segment);\n // Porter stemming changes suffixes only, so a different initial cannot match a query stem.\n if (!stemInitials.has(folded[0])) continue;\n const term = termByStem.get(stemmer(folded));\n if (term !== undefined) occ.push({ start: match.start, end: match.end, term });\n }\n }\n\n return occ.sort((a, b) => a.start - b.start || b.end - a.end);\n}\n\n// Segment boundaries of the whole text, word granularity: the only cut points a snippet edge\n// may land on. One rule for every script (DESIGN.md \"Cutting\") -- a regex \\b is ASCII-only and\n// would mis-cut Japanese, Chinese and Thai, which Intl.Segmenter divides by dictionary instead.\nfunction wordBoundaries(text: string): number[] {\n wordSegmenter ??= new Intl.Segmenter('en', { granularity: 'word' });\n const bounds = [0];\n for (const { index, segment } of wordSegmenter.segment(text)) bounds.push(index + segment.length);\n return bounds;\n}\n\n// bounds is sorted: snaps are binary searches, since each runs once per candidate window.\nfunction snapForward(bounds: number[], pos: number): number {\n let lo = 0;\n let hi = bounds.length - 1;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (bounds[mid] < pos) lo = mid + 1;\n else hi = mid;\n }\n return bounds[lo];\n}\n\nfunction snapBackward(bounds: number[], pos: number): number {\n let lo = 0;\n let hi = bounds.length - 1;\n let result = bounds[0];\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (bounds[mid] <= pos) {\n lo = mid;\n result = bounds[mid];\n } else hi = mid - 1;\n }\n return result;\n}\n\nfunction firstBoundAfter(bounds: number[], pos: number): number | undefined {\n let lo = 0;\n let hi = bounds.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (bounds[mid] <= pos) lo = mid + 1;\n else hi = mid;\n }\n return bounds[lo];\n}\n\n// A raw, unmarked upper bound: [start, end) inside [anchor, anchor+charLimit), edges on\n// boundaries. Markup (guillemets, ellipses) added on top of this can push the rendered result\n// past charLimit, which is what fitEnd() below corrects for; this is only the starting guess.\n// A single segment spanning the whole target window (a word longer than the char limit) is the\n// one case where holding the boundary rule means the budget is not a hard ceiling.\nfunction cutWindow(text: string, bounds: number[], anchor: number, charLimit: number): { start: number; end: number } {\n const rawEnd = Math.min(text.length, anchor + charLimit);\n const start = snapForward(bounds, anchor);\n let end = snapBackward(bounds, rawEnd);\n if (end <= start) end = firstBoundAfter(bounds, start) ?? text.length;\n return { start, end: Math.min(end, text.length) };\n}\n\n// The largest boundary <= upperBound, > floor, whose rendered [*, end) fits charLimit. Markup\n// only ever adds characters as end grows, so rendered length is non-decreasing in end and\n// shrinking from upperBound is guaranteed to find the true fit rather than guess at it.\n// `floor` is the one end this never shrinks past (the anchor's own marked word, or the first\n// word in the unmarked fallback): DESIGN.md's budget is a ceiling except here, where returning\n// nothing is worse than a single word that overruns it.\nfunction fitEnd(render: (end: number) => string, bounds: number[], floor: number, upperBound: number, charLimit: number): number {\n let lo = 0;\n let hi = bounds.length - 1;\n while (lo < hi) {\n const mid = (lo + hi + 1) >> 1;\n if (bounds[mid] <= upperBound) lo = mid;\n else hi = mid - 1;\n }\n for (; lo >= 0 && bounds[lo] > floor; lo--) {\n if (render(bounds[lo]).length <= charLimit) return bounds[lo];\n }\n return floor;\n}\n\ninterface Span {\n start: number;\n end: number;\n}\n\ninterface SnippetWindow extends Span {\n distinct: number;\n count: number;\n}\n\n// occ is start-sorted: a window's first candidate occurrence is a binary search, not a walk.\nfunction firstOccAtOrAfter(occ: Array<{ start: number; end: number; term: string }>, pos: number): number {\n let lo = 0;\n let hi = occ.length;\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (occ[mid].start < pos) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\nfunction renderWindow(text: string, occ: Array<{ start: number; end: number; term: string }>, win: Span): string {\n let out = '';\n let cursor = win.start;\n for (let i = firstOccAtOrAfter(occ, win.start); i < occ.length && occ[i].start < win.end; i++) {\n const o = occ[i];\n if (o.end > win.end) continue;\n // Occurrences of duplicate or substring-overlapping terms (\"test tests\") can overlap;\n // emitting each would duplicate document text. Keep the first, absorb the rest.\n if (o.start < cursor) continue;\n out += `${text.slice(cursor, o.start)}«${text.slice(o.start, o.end)}»`;\n cursor = o.end;\n }\n out += text.slice(cursor, win.end);\n const prefix = win.start > 0 ? '…' : '';\n const suffix = win.end < text.length ? '…' : '';\n return `${prefix}${out.replace(/\\s+/g, ' ')}${suffix}`;\n}\n\n// Scores every occurrence-anchored candidate window: most distinct terms wins, ties broken by\n// most total hits -- coverage now that occurrences are real words, not the false-fragment counts\n// a substring scan produced. Selection itself is unevaluated (DESIGN.md \"Selection, unsettled\").\n// The window's `end` is fitted to the *rendered* text, markup included, not the raw span: a\n// window dense with marks (every guillemet pair adds two characters) shrinks to fit the same\n// budget a sparse one fills almost exactly.\nfunction scoreWindows(occ: Array<{ start: number; end: number; term: string }>, bounds: number[], text: string, charLimit: number): SnippetWindow[] {\n const candidates: SnippetWindow[] = [];\n for (let i = 0; i < occ.length; i++) {\n const winEnd = occ[i].start + charLimit;\n const seen = new Set<string>();\n let count = 0;\n for (let j = i; j < occ.length && occ[j].start < winEnd; j++) {\n seen.add(occ[j].term);\n count++;\n }\n const start = snapForward(bounds, occ[i].start);\n const floor = Math.max(start, occ[i].end);\n const upperBound = Math.max(floor, cutWindow(text, bounds, occ[i].start, charLimit).end);\n const end = fitEnd((e) => renderWindow(text, occ, { start, end: e }), bounds, floor, upperBound, charLimit);\n candidates.push({ start, end, distinct: seen.size, count });\n }\n return candidates;\n}\n\nfunction overlaps(a: Span, b: Span): boolean {\n return a.start < b.end && b.start < a.end;\n}\n\n// Same scoring function as a single snippet, kept rather than discarded (DESIGN.md \"Several\n// snippets per note\"): rank by score, take the top non-overlapping windows, then reorder to the\n// note's own order, since several passages from one note read as an abridged note.\nfunction selectWindows(candidates: SnippetWindow[], countLimit: number): { chosen: SnippetWindow[]; best: SnippetWindow } {\n const ranked = candidates.slice().sort((a, b) => b.distinct - a.distinct || b.count - a.count);\n const chosen: SnippetWindow[] = [];\n for (const c of ranked) {\n if (chosen.length >= countLimit) break;\n if (chosen.some((s) => overlaps(s, c))) continue;\n chosen.push(c);\n }\n chosen.sort((a, b) => a.start - b.start);\n return { chosen, best: ranked[0] };\n}\n\n// Builds bounded marked passages and returns the best window's offset for section lookup.\nexport function computeSnippets(text: string, terms: string[], charLimit: number, countLimit: number): { snippets: string[]; offset: number } {\n const occ = findOccurrences(text, terms);\n const bounds = wordBoundaries(text);\n if (occ.length === 0) {\n // A term matched only via title/summary, not this body text, finds no occurrence here;\n // fall back to the doc's start, unmarked.\n const render = (end: number): string => `${text.slice(0, end).replace(/\\s+/g, ' ').trim()}${end < text.length ? '…' : ''}`;\n const floor = bounds.find((b) => b > 0) ?? text.length;\n const upperBound = Math.max(floor, cutWindow(text, bounds, 0, charLimit).end);\n const end = fitEnd(render, bounds, floor, upperBound, charLimit);\n return { snippets: [render(end)], offset: 0 };\n }\n const candidates = scoreWindows(occ, bounds, text, charLimit);\n const { chosen, best } = selectWindows(candidates, countLimit);\n return { snippets: chosen.map((win) => renderWindow(text, occ, win)), offset: best.start };\n}\n\n// Converts an offset in the original text to its one-based line number.\nexport function lineNumberAt(text: string, offset: number): number {\n let line = 1;\n for (let i = 0; i < offset; i++) if (text.charCodeAt(i) === 10) line++;\n return line;\n}\n\nasync function lineRangeFor(store: Store, path: string, line: number): Promise<string | null> {\n const stmt = await store.prepare('SELECT start_line, end_line FROM sections WHERE \"path\" = ? AND start_line <= ? AND end_line >= ? ORDER BY start_line DESC LIMIT 1');\n const row = (await stmt.get(path, line, line)) as { start_line: number; end_line: number } | undefined;\n return row ? `L${row.start_line}-${row.end_line}` : null;\n}\n\nexport interface SearchOptions {\n k?: number;\n where?: string; // SQL fragment against frontmatter alias `f`, e.g. \"f.status = 'active'\"\n preset?: string; // named preset; unknown name throws listing declared presets, undefined -> \"default\"\n include?: string[]; // ad hoc scope override (repeatable --include); independent of exclude\n exclude?: string[]; // ad hoc scope override (repeatable --exclude); independent of include\n noExclude?: boolean; // --no-exclude: drop the preset's exclude for this command\n snippetCharLimit?: number; // --snippet-char-limit; defaults to SNIPPET_CHAR_LIMIT_DEFAULT\n snippetCountLimit?: number; // --snippet-count-limit; defaults to SNIPPET_COUNT_LIMIT_DEFAULT\n}\n\n// Hydrates already-ranked rows with snippets and containing-section ranges without reranking.\nexport async function hydrateSearchRows(store: Store, cfg: ResolvedConfig, rows: Row[], matchedPaths: Set<string>, terms: string, opts: Pick<SearchOptions, 'snippetCharLimit' | 'snippetCountLimit'> = {}): Promise<void> {\n if (matchedPaths.size === 0) return;\n const bareTerms = extractBareTerms(terms);\n const charLimit = opts.snippetCharLimit ?? SNIPPET_CHAR_LIMIT_DEFAULT;\n const countLimit = opts.snippetCountLimit ?? SNIPPET_COUNT_LIMIT_DEFAULT;\n for (const row of rows) {\n if (!matchedPaths.has(row.path as string)) continue;\n let text: string;\n try {\n text = readFileSync(join(cfg.rootDir ?? cfg.baseDir, row.path as string), 'utf8');\n } catch {\n continue; // vanished since the match; leave snippets/lines empty rather than throw\n }\n const { snippets, offset } = computeSnippets(text, bareTerms, charLimit, countLimit);\n row.snippets = snippets;\n if (row.lines == null) row.lines = featureEnabled(cfg, 'sections') ? await lineRangeFor(store, row.path as string, lineNumberAt(text, offset)) : null;\n }\n}\n\n// The declared or defaulted signals compose via RRF; `via` names which ones produced each row.\n// `opts` arrives already resolved (config.ts:resolveSearch).\nexport async function search(store: Store, cfg: ResolvedConfig, terms: string, opts: SearchOptions = {}): Promise<Row[]> {\n const effective = resolveSearch(cfg, opts);\n const { k, signals } = effective;\n\n const allPaths = ((await (await store.prepare('SELECT \"path\" FROM frontmatter')).all()) as Array<{ path: string }>).map((r) => r.path);\n const scopePaths = await rawScope(store, cfg, opts, allPaths);\n const scopeActive = scopePaths.size < allPaths.length;\n // The set every candidate pool must be filtered to before truncation: scope narrowed by\n // --where, the same composition scopedPaths() gives the other commands.\n let allowedPaths: Set<string>;\n try {\n allowedPaths = await narrowByWhere(store, scopePaths, effective.where);\n } catch (err) {\n throw searchError(err as Error, terms, effective.where);\n }\n const fetch = Math.max(k * 3, 30);\n\n // A downloadable HF id proceeds -- getProvider fetches it lazily on consent. Only a\n // local path with missing files errors here, since nothing will ever fetch it for itself.\n const wantsVectors = signals.vectors !== undefined;\n if (wantsVectors) {\n const e = embedConfig(cfg); // validate.ts guarantees this is set whenever \"vectors\" is declared\n if (localModelMissing(e)) {\n throw new SenseError('EMBED_MODEL_MISSING', `preset \"${effective.presetName}\" searches with vectors, but the local model path \"${e.model}\" is missing ${MODEL_FILENAMES}; point embed.model at a directory containing them, or drop \"vectors\" from that preset's signals to search without them`);\n }\n }\n const semanticEnabled = wantsVectors && (await scopeHasEmbeddings(store, cfg, allowedPaths));\n\n // --where applies inside the candidate query (a post-filter would drop matches ranked past\n // the pool) and again on the final select, for link-derived rows.\n const scope = effective.where;\n const whereJoin = scope ? `JOIN frontmatter f ON f.\"path\" = content.path` : '';\n const whereCond = scope ? `AND (${scope})` : '';\n // Filtered before LIMIT, not after, or scoped notes ranking below the global top-`fetch`\n // never reach the filter; joined against a temp table since real scopes exceed SQLITE_MAX_VARIABLE_NUMBER.\n if (scopeActive) await materializeScope(store, '_search_scope', scopePaths);\n const scopeCond = scopeActive ? `AND content.path IN (SELECT \"path\" FROM _search_scope)` : '';\n\n const candidates = new Map<string, { score: number; via: string }>();\n let matchRows: LexicalHit[] = [];\n const hasEmptyPhrase = [...terms.matchAll(/\"([^\"]*)\"/g)].some((match) => !/[\\p{L}\\p{N}_]/u.test(match[1]));\n const hasBareSyntaxOnly = /[()]/u.test(terms.replace(/\"[^\"]*\"/g, ' '));\n // A query that is only whitespace or punctuation has no lexical rows; other declared signals\n // compose normally. In particular, unspaced-script punctuation can rewrite to an empty MATCH.\n if (signals.words !== undefined && terms.trim() !== '' && (/[\\p{L}\\p{N}_]/u.test(terms) || hasBareSyntaxOnly) && !hasEmptyPhrase) {\n const syntaxError = bareTermSyntaxError(terms);\n if (syntaxError) throw syntaxError;\n try {\n matchRows = await wordsCandidates(store, candidates, terms, whereJoin, whereCond, scopeCond, fetch, signals.words);\n } catch (err) {\n throw searchError(err as Error, terms, scope);\n }\n }\n // Every store's lexical `snippets` is NULL; the snippet text is always computed below.\n // Distinguish from via='link' rows, which never appear in matchRows.\n const matchedPaths = new Set(matchRows.map((r) => r.path));\n\n if (signals.links !== undefined) await linksCandidates(store, candidates, matchRows, allPaths, allowedPaths, fetch, signals.links);\n\n let chunkLines = new Map<string, string>();\n let chunkSimilarity = new Map<string, number>();\n if (semanticEnabled) {\n ({ chunkLines, chunkSimilarity } = await vectorsCandidates(store, cfg, candidates, terms, fetch, allowedPaths, signals.vectors as number));\n }\n\n await store.exec('DROP TABLE IF EXISTS _search');\n // DOUBLE, not REAL: sqlite's REAL is an 8-byte double but duckdb's is a 4-byte float, and the\n // rounded score/similarity are printed at full precision in rows.\n await store.exec('CREATE TEMP TABLE _search (\"path\" TEXT PRIMARY KEY, score DOUBLE, via TEXT, lines TEXT, similarity DOUBLE)');\n if (candidates.size > 0) {\n await store.runBatch(\n 'INSERT INTO _search (\"path\", score, via, lines, similarity) VALUES (?, ?, ?, ?, ?)',\n [...candidates].map(([path, c]) => [path, c.score, c.via, chunkLines.get(path) ?? null, chunkSimilarity.get(path) ?? null])\n );\n }\n\n // Reapplies --where even though _search is already scope+where filtered, since the join to\n // frontmatter is already needed for the path column.\n const where = scope ? `WHERE (${scope})` : '';\n // lines: semantic rows carry their chunk's range, lexical rows gain one below,\n // everything else stays null; similarity stays semantic-only.\n const similarityCol = semanticEnabled ? ', _search.similarity' : '';\n // NULL AS snippets holds this column's position (between summary and via) for every row;\n // overwritten below, always to an array, never left null (DESIGN.md).\n const selectStmt = await store.prepare(\n `SELECT f.\"path\" AS path, content.title, content.summary, NULL AS snippets, _search.via, round(_search.score, 4) AS score, _search.lines${similarityCol}\n FROM _search JOIN frontmatter f ON f.\"path\" = _search.\"path\" JOIN content ON content.path = _search.\"path\"\n ${where} ORDER BY _search.score DESC LIMIT ?`\n );\n const rows = (await selectStmt.all(k)) as Row[];\n for (const row of rows) row.snippets = [];\n\n await hydrateSearchRows(store, cfg, rows, matchedPaths, terms, opts);\n\n return rows;\n}\n"],"names":["SNIPPET_CHAR_LIMIT_DEFAULT","SNIPPET_COUNT_LIMIT_DEFAULT","computeSnippets","hydrateSearchRows","lineNumberAt","search","extractBareTerms","query","cleaned","replace","split","map","tok","flatMap","searchTokens","text","toLowerCase","trim","filter","length","wordSegmenter","findOccurrences","terms","occ","textLower","unspacedTerms","hasUnspacedRun","unspacedRuns","run","runLower","slice","start","end","term","idx","found","indexOf","push","spacedTerms","t","termByStem","Map","stemmer","foldForSearch","stemInitials","Set","Array","from","keys","match","segment","unspaced","folded","has","get","undefined","sort","a","b","wordBoundaries","Intl","Segmenter","granularity","bounds","index","snapForward","pos","lo","hi","mid","snapBackward","result","firstBoundAfter","cutWindow","anchor","charLimit","rawEnd","Math","min","fitEnd","render","floor","upperBound","firstOccAtOrAfter","renderWindow","win","out","cursor","i","o","prefix","suffix","scoreWindows","winEnd","seen","count","j","add","max","e","candidates","distinct","size","overlaps","selectWindows","countLimit","ranked","chosen","c","some","s","best","find","snippets","offset","line","charCodeAt","lineRangeFor","store","path","stmt","row","prepare","start_line","end_line","cfg","rows","matchedPaths","opts","bareTerms","snippetCharLimit","snippetCountLimit","readFileSync","join","rootDir","baseDir","lines","featureEnabled","effective","k","signals","allPaths","scopePaths","scopeActive","allowedPaths","err","fetch","wantsVectors","semanticEnabled","scope","whereJoin","whereCond","scopeCond","matchRows","hasEmptyPhrase","hasBareSyntaxOnly","syntaxError","chunkLines","chunkSimilarity","where","similarityCol","selectStmt","resolveSearch","all","r","rawScope","narrowByWhere","searchError","vectors","embedConfig","localModelMissing","SenseError","presetName","MODEL_FILENAMES","model","scopeHasEmbeddings","materializeScope","matchAll","test","words","bareTermSyntaxError","wordsCandidates","links","linksCandidates","vectorsCandidates","exec","runBatch","score","via"],"mappings":"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"}
|
|
@@ -162,7 +162,13 @@ function featureSignature(cfg, features) {
|
|
|
162
162
|
var exclude = _to_consumable_array((_p_exclude = p.exclude) !== null && _p_exclude !== void 0 ? _p_exclude : []).sort().join('+');
|
|
163
163
|
return "preset:".concat(name, ":").concat(include, ":").concat(exclude, ":").concat(presetHasSignal(cfg, name, 'vectors') ? 'on' : 'off');
|
|
164
164
|
}).join('|');
|
|
165
|
-
|
|
165
|
+
// A configured root changes every filesystem input while retaining the cache under the
|
|
166
|
+
// config directory. Its own segment therefore forces the safe full-rebuild path. Omission
|
|
167
|
+
// intentionally preserves the pre-root signature and cache behavior.
|
|
168
|
+
var rootPart = cfg.root === undefined ? [] : [
|
|
169
|
+
"root:".concat(cfg.root)
|
|
170
|
+
];
|
|
171
|
+
return _to_consumable_array(togglesPart).concat(_to_consumable_array(featureParts), _to_consumable_array(rootPart), [
|
|
166
172
|
presetsPart
|
|
167
173
|
]).join('|');
|
|
168
174
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/config/access.ts"],"sourcesContent":["import type { Feature } from '../features/types.ts';\nimport type { SignalName, SignalWeights } from './signals.ts';\nimport { type Config, type EmbedConfig, FEATURE_NAMES, type FeatureName, type StoreName } from './types.ts';\n\nexport function presetNames(cfg: Config): string[] {\n return Object.keys(cfg.presets);\n}\n\n// The backing store engine this tree uses; absent means the default.\nexport function storeName(cfg: Config): StoreName {\n return cfg.store ?? 'sqlite';\n}\n\n// Whether the tree names a model at all.\nexport function embedEnabled(cfg: Config): boolean {\n return typeof cfg.embed?.model === 'string' && cfg.embed.model.length > 0;\n}\n\n// A preset's effective signal weights: declared exhaustively when `signals` is present, else\n// every signal whose prerequisite holds at weight 1 (words always, links when on, vectors when a model is named).\nexport function presetSignals(cfg: Config, name: string): SignalWeights {\n const declared = cfg.presets[name]?.signals;\n if (declared) return declared;\n const signals: SignalWeights = { words: 1 };\n if (cfg.features?.links !== false) signals.links = 1;\n if (embedEnabled(cfg)) signals.vectors = 1;\n return signals;\n}\n\nexport function presetHasSignal(cfg: Config, name: string, signal: SignalName): boolean {\n return presetSignals(cfg, name)[signal] !== undefined;\n}\n\n// Whether embedding needs to run: a model is named AND some preset's effective signals include vectors.\nexport function anyPresetEmbeds(cfg: Config): boolean {\n return presetNames(cfg).some((name) => presetHasSignal(cfg, name, 'vectors'));\n}\n\n// Opt-out features (default on): absent block or key means enabled. `rank` additionally requires\n// `links`. `embed` is derived (not a features-block member): on iff some preset's signals include vectors.\nexport function featureEnabled(cfg: Config, name: FeatureName): boolean {\n if (name === 'embed') return anyPresetEmbeds(cfg);\n const enabled = cfg.features?.[name] !== false;\n if (name === 'rank') return enabled && featureEnabled(cfg, 'links');\n return enabled;\n}\n\nexport function enabledFeatures(cfg: Config): FeatureName[] {\n return FEATURE_NAMES.filter((name) => featureEnabled(cfg, name));\n}\n\n// Feature states, so \"off\" and \"empty\" stay distinguishable in output. `embed` is excluded:\n// it is not a features-block toggle, and `status` reports it on its own line.\nexport function featureStates(cfg: Config): { on: FeatureName[]; off: FeatureName[] } {\n const reported = FEATURE_NAMES.filter((name) => name !== 'embed');\n return {\n on: reported.filter((name) => featureEnabled(cfg, name)),\n off: reported.filter((name) => !featureEnabled(cfg, name)),\n };\n}\n\n// Resolved embed provider settings, or null when the config names no model. No fallback to\n// DEFAULT_EMBED_MODEL: that's a template constant `init` and the v4 migration write into the file, never a runtime default.\nexport function embedConfig(cfg: Config): { model: string; provider: 'static' | 'openai' | 'cohere'; url?: string; key?: string; languages?: string[]; chunkTokens?: number } | null {\n if (!embedEnabled(cfg)) return null;\n const e = cfg.embed as EmbedConfig;\n return { model: e.model as string, provider: e.provider ?? 'static', url: e.url, key: e.key, languages: e.languages, chunkTokens: e.chunkTokens };\n}\n\n// Cache key over everything indexing derives from, so any change to those inputs rebuilds.\n// Segment order is fixed (one `feature:<name>:on|off` per FEATURE_NAMES entry but embed, then\n// `features` in registry order, then presets) since reordering alone would fire a spurious\n// rebuild; presets stay here because no Feature module owns it.\nexport function featureSignature(cfg: Config, features: Feature[]): string {\n // One segment per toggle (not one lumped csv) so store/signature.ts's changedSignatureKeys can\n // tell which feature moved -- store/feature-scope.ts routes a recognised toggle to a narrow\n // per-table invalidation instead of the full clear.\n const togglesPart = FEATURE_NAMES.filter((name) => name !== 'embed').map((name) => `feature:${name}:${featureEnabled(cfg, name) ? 'on' : 'off'}`);\n const featureParts = features.map((feature) => feature.signature?.(cfg)).filter((part): part is string => part !== undefined);\n // One keyed segment per preset so a rebuild notice can name exactly which preset moved.\n const presetsPart = [...presetNames(cfg)]\n .sort()\n .map((name) => {\n const p = cfg.presets[name];\n const include = [...p.include].sort().join('+');\n const exclude = [...(p.exclude ?? [])].sort().join('+');\n return `preset:${name}:${include}:${exclude}:${presetHasSignal(cfg, name, 'vectors') ? 'on' : 'off'}`;\n })\n .join('|');\n return [...togglesPart, ...featureParts, presetsPart].join('|');\n}\n"],"names":["anyPresetEmbeds","embedConfig","embedEnabled","enabledFeatures","featureEnabled","featureSignature","featureStates","presetHasSignal","presetNames","presetSignals","storeName","cfg","Object","keys","presets","store","embed","model","length","name","declared","signals","words","features","links","vectors","signal","undefined","some","enabled","FEATURE_NAMES","filter","reported","on","off","e","provider","url","key","languages","chunkTokens","togglesPart","map","featureParts","feature","signature","part","presetsPart","sort","p","include","join","exclude"],"mappings":"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
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/config/access.ts"],"sourcesContent":["import type { Feature } from '../features/types.ts';\nimport type { SignalName, SignalWeights } from './signals.ts';\nimport { type Config, type EmbedConfig, FEATURE_NAMES, type FeatureName, type StoreName } from './types.ts';\n\nexport function presetNames(cfg: Config): string[] {\n return Object.keys(cfg.presets);\n}\n\n// The backing store engine this tree uses; absent means the default.\nexport function storeName(cfg: Config): StoreName {\n return cfg.store ?? 'sqlite';\n}\n\n// Whether the tree names a model at all.\nexport function embedEnabled(cfg: Config): boolean {\n return typeof cfg.embed?.model === 'string' && cfg.embed.model.length > 0;\n}\n\n// A preset's effective signal weights: declared exhaustively when `signals` is present, else\n// every signal whose prerequisite holds at weight 1 (words always, links when on, vectors when a model is named).\nexport function presetSignals(cfg: Config, name: string): SignalWeights {\n const declared = cfg.presets[name]?.signals;\n if (declared) return declared;\n const signals: SignalWeights = { words: 1 };\n if (cfg.features?.links !== false) signals.links = 1;\n if (embedEnabled(cfg)) signals.vectors = 1;\n return signals;\n}\n\nexport function presetHasSignal(cfg: Config, name: string, signal: SignalName): boolean {\n return presetSignals(cfg, name)[signal] !== undefined;\n}\n\n// Whether embedding needs to run: a model is named AND some preset's effective signals include vectors.\nexport function anyPresetEmbeds(cfg: Config): boolean {\n return presetNames(cfg).some((name) => presetHasSignal(cfg, name, 'vectors'));\n}\n\n// Opt-out features (default on): absent block or key means enabled. `rank` additionally requires\n// `links`. `embed` is derived (not a features-block member): on iff some preset's signals include vectors.\nexport function featureEnabled(cfg: Config, name: FeatureName): boolean {\n if (name === 'embed') return anyPresetEmbeds(cfg);\n const enabled = cfg.features?.[name] !== false;\n if (name === 'rank') return enabled && featureEnabled(cfg, 'links');\n return enabled;\n}\n\nexport function enabledFeatures(cfg: Config): FeatureName[] {\n return FEATURE_NAMES.filter((name) => featureEnabled(cfg, name));\n}\n\n// Feature states, so \"off\" and \"empty\" stay distinguishable in output. `embed` is excluded:\n// it is not a features-block toggle, and `status` reports it on its own line.\nexport function featureStates(cfg: Config): { on: FeatureName[]; off: FeatureName[] } {\n const reported = FEATURE_NAMES.filter((name) => name !== 'embed');\n return {\n on: reported.filter((name) => featureEnabled(cfg, name)),\n off: reported.filter((name) => !featureEnabled(cfg, name)),\n };\n}\n\n// Resolved embed provider settings, or null when the config names no model. No fallback to\n// DEFAULT_EMBED_MODEL: that's a template constant `init` and the v4 migration write into the file, never a runtime default.\nexport function embedConfig(cfg: Config): { model: string; provider: 'static' | 'openai' | 'cohere'; url?: string; key?: string; languages?: string[]; chunkTokens?: number } | null {\n if (!embedEnabled(cfg)) return null;\n const e = cfg.embed as EmbedConfig;\n return { model: e.model as string, provider: e.provider ?? 'static', url: e.url, key: e.key, languages: e.languages, chunkTokens: e.chunkTokens };\n}\n\n// Cache key over everything indexing derives from, so any change to those inputs rebuilds.\n// Segment order is fixed (one `feature:<name>:on|off` per FEATURE_NAMES entry but embed, then\n// `features` in registry order, then presets) since reordering alone would fire a spurious\n// rebuild; presets stay here because no Feature module owns it.\nexport function featureSignature(cfg: Config, features: Feature[]): string {\n // One segment per toggle (not one lumped csv) so store/signature.ts's changedSignatureKeys can\n // tell which feature moved -- store/feature-scope.ts routes a recognised toggle to a narrow\n // per-table invalidation instead of the full clear.\n const togglesPart = FEATURE_NAMES.filter((name) => name !== 'embed').map((name) => `feature:${name}:${featureEnabled(cfg, name) ? 'on' : 'off'}`);\n const featureParts = features.map((feature) => feature.signature?.(cfg)).filter((part): part is string => part !== undefined);\n // One keyed segment per preset so a rebuild notice can name exactly which preset moved.\n const presetsPart = [...presetNames(cfg)]\n .sort()\n .map((name) => {\n const p = cfg.presets[name];\n const include = [...p.include].sort().join('+');\n const exclude = [...(p.exclude ?? [])].sort().join('+');\n return `preset:${name}:${include}:${exclude}:${presetHasSignal(cfg, name, 'vectors') ? 'on' : 'off'}`;\n })\n .join('|');\n // A configured root changes every filesystem input while retaining the cache under the\n // config directory. Its own segment therefore forces the safe full-rebuild path. Omission\n // intentionally preserves the pre-root signature and cache behavior.\n const rootPart = cfg.root === undefined ? [] : [`root:${cfg.root}`];\n return [...togglesPart, ...featureParts, ...rootPart, presetsPart].join('|');\n}\n"],"names":["anyPresetEmbeds","embedConfig","embedEnabled","enabledFeatures","featureEnabled","featureSignature","featureStates","presetHasSignal","presetNames","presetSignals","storeName","cfg","Object","keys","presets","store","embed","model","length","name","declared","signals","words","features","links","vectors","signal","undefined","some","enabled","FEATURE_NAMES","filter","reported","on","off","e","provider","url","key","languages","chunkTokens","togglesPart","map","featureParts","feature","signature","part","presetsPart","sort","p","include","join","exclude","rootPart","root"],"mappings":"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"}
|
package/dist/cjs/config/load.js
CHANGED
|
@@ -459,6 +459,7 @@ function findConfigPath(startDir) {
|
|
|
459
459
|
}
|
|
460
460
|
}
|
|
461
461
|
function loadConfig(explicitPath) {
|
|
462
|
+
var _cfg_root;
|
|
462
463
|
var configPath;
|
|
463
464
|
if (explicitPath) {
|
|
464
465
|
configPath = (0, _nodepath.resolve)(process.cwd(), explicitPath);
|
|
@@ -497,8 +498,12 @@ function loadConfig(explicitPath) {
|
|
|
497
498
|
cfg = (0, _validatets.validateConfig)(parsed, configPath);
|
|
498
499
|
}
|
|
499
500
|
var unknownKeys = (0, _validatets.unknownConfigKeys)(cfg);
|
|
501
|
+
var configDir = (0, _nodepath.dirname)(configPath);
|
|
502
|
+
var rootDir = (0, _nodepath.resolve)(configDir, (_cfg_root = cfg.root) !== null && _cfg_root !== void 0 ? _cfg_root : '.');
|
|
500
503
|
return _object_spread_props(_object_spread({}, cfg), {
|
|
501
|
-
|
|
504
|
+
configDir: configDir,
|
|
505
|
+
rootDir: rootDir,
|
|
506
|
+
baseDir: rootDir,
|
|
502
507
|
configPath: configPath,
|
|
503
508
|
migratedFrom: migratedFrom,
|
|
504
509
|
unknownKeys: unknownKeys.length > 0 ? unknownKeys : undefined
|