sensemaking 0.25.0 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -10
- package/dist/cjs/cli/index.d.cts +1 -1
- package/dist/cjs/cli/index.d.ts +1 -1
- package/dist/cjs/cli/index.js +1 -1
- package/dist/cjs/cli/index.js.map +1 -1
- package/dist/cjs/cli/path.js +5 -29
- package/dist/cjs/cli/path.js.map +1 -1
- package/dist/cjs/cli/related.js +4 -3
- package/dist/cjs/cli/related.js.map +1 -1
- package/dist/cjs/commands/index.d.cts +6 -3
- package/dist/cjs/commands/index.d.ts +6 -3
- package/dist/cjs/commands/index.js +4 -0
- package/dist/cjs/commands/index.js.map +1 -1
- package/dist/cjs/commands/map.d.cts +14 -5
- package/dist/cjs/commands/map.d.ts +14 -5
- package/dist/cjs/commands/map.js +42 -35
- package/dist/cjs/commands/map.js.map +1 -1
- package/dist/cjs/commands/path.d.cts +14 -0
- package/dist/cjs/commands/path.d.ts +14 -0
- package/dist/cjs/commands/path.js +209 -0
- package/dist/cjs/commands/path.js.map +1 -0
- package/dist/cjs/commands/peek.d.cts +16 -1
- package/dist/cjs/commands/peek.d.ts +16 -1
- package/dist/cjs/commands/peek.js +71 -33
- package/dist/cjs/commands/peek.js.map +1 -1
- package/dist/cjs/commands/related.d.cts +16 -3
- package/dist/cjs/commands/related.d.ts +16 -3
- package/dist/cjs/commands/related.js +131 -98
- package/dist/cjs/commands/related.js.map +1 -1
- package/dist/cjs/commands/scope.d.cts +1 -0
- package/dist/cjs/commands/scope.d.ts +1 -0
- package/dist/cjs/commands/scope.js +149 -0
- package/dist/cjs/commands/scope.js.map +1 -1
- package/dist/cjs/commands/search.d.cts +26 -3
- package/dist/cjs/commands/search.d.ts +26 -3
- package/dist/cjs/commands/search.js +211 -71
- package/dist/cjs/commands/search.js.map +1 -1
- package/dist/cjs/commands/signals.d.cts +4 -3
- package/dist/cjs/commands/signals.d.ts +4 -3
- package/dist/cjs/commands/signals.js +13 -4
- package/dist/cjs/commands/signals.js.map +1 -1
- package/dist/cjs/commands/snapshot.d.cts +3 -0
- package/dist/cjs/commands/snapshot.d.ts +3 -0
- package/dist/cjs/commands/snapshot.js +180 -0
- package/dist/cjs/commands/snapshot.js.map +1 -0
- package/dist/cjs/embed/cohere.js +41 -16
- package/dist/cjs/embed/cohere.js.map +1 -1
- package/dist/cjs/embed/endpoint.d.cts +2 -0
- package/dist/cjs/embed/endpoint.d.ts +2 -0
- package/dist/cjs/embed/endpoint.js +30 -0
- package/dist/cjs/embed/endpoint.js.map +1 -0
- package/dist/cjs/embed/handoff.d.cts +7 -2
- package/dist/cjs/embed/handoff.d.ts +7 -2
- package/dist/cjs/embed/handoff.js +10 -0
- package/dist/cjs/embed/handoff.js.map +1 -1
- package/dist/cjs/embed/http.d.cts +18 -1
- package/dist/cjs/embed/http.d.ts +18 -1
- package/dist/cjs/embed/http.js +239 -40
- package/dist/cjs/embed/http.js.map +1 -1
- package/dist/cjs/embed/openai.js +39 -17
- package/dist/cjs/embed/openai.js.map +1 -1
- package/dist/cjs/embed/query.d.cts +9 -3
- package/dist/cjs/embed/query.d.ts +9 -3
- package/dist/cjs/embed/query.js +257 -90
- package/dist/cjs/embed/query.js.map +1 -1
- package/dist/cjs/embed/registry.d.cts +2 -2
- package/dist/cjs/embed/registry.d.ts +2 -2
- package/dist/cjs/embed/registry.js +36 -4
- package/dist/cjs/embed/registry.js.map +1 -1
- package/dist/cjs/embed/static.js +6 -2
- package/dist/cjs/embed/static.js.map +1 -1
- package/dist/cjs/embed/store.js +42 -77
- package/dist/cjs/embed/store.js.map +1 -1
- package/dist/cjs/embed/types.d.cts +5 -2
- package/dist/cjs/embed/types.d.ts +5 -2
- package/dist/cjs/embed/types.js.map +1 -1
- package/dist/cjs/features/embed.js +290 -43
- package/dist/cjs/features/embed.js.map +1 -1
- package/dist/cjs/graph/traverse.d.cts +2 -2
- package/dist/cjs/graph/traverse.d.ts +2 -2
- package/dist/cjs/graph/traverse.js +15 -5
- package/dist/cjs/graph/traverse.js.map +1 -1
- package/dist/cjs/index.d.cts +2 -2
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/output/output.d.cts +4 -36
- package/dist/cjs/output/output.d.ts +4 -36
- package/dist/cjs/output/output.js +1 -2
- package/dist/cjs/output/output.js.map +1 -1
- package/dist/cjs/scan/pool.d.cts +2 -1
- package/dist/cjs/scan/pool.d.ts +2 -1
- package/dist/cjs/scan/pool.js +116 -27
- package/dist/cjs/scan/pool.js.map +1 -1
- package/dist/cjs/scan/reparse.d.cts +1 -0
- package/dist/cjs/scan/reparse.d.ts +1 -0
- package/dist/cjs/scan/reparse.js +75 -21
- package/dist/cjs/scan/reparse.js.map +1 -1
- package/dist/cjs/store/builder.d.cts +11 -21
- package/dist/cjs/store/builder.d.ts +11 -21
- package/dist/cjs/store/builder.js +1077 -438
- package/dist/cjs/store/builder.js.map +1 -1
- package/dist/cjs/store/duckdb/connection.js +16 -2
- package/dist/cjs/store/duckdb/connection.js.map +1 -1
- package/dist/cjs/store/duckdb/open.d.cts +1 -1
- package/dist/cjs/store/duckdb/open.d.ts +1 -1
- package/dist/cjs/store/duckdb/open.js +73 -65
- package/dist/cjs/store/duckdb/open.js.map +1 -1
- package/dist/cjs/store/duckdb/reconcile.js +533 -15
- package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
- package/dist/cjs/store/embed-scope.js +19 -9
- package/dist/cjs/store/embed-scope.js.map +1 -1
- package/dist/cjs/store/index.d.cts +6 -0
- package/dist/cjs/store/index.d.ts +6 -0
- package/dist/cjs/store/index.js +8 -4
- package/dist/cjs/store/index.js.map +1 -1
- package/dist/cjs/store/open.d.cts +6 -1
- package/dist/cjs/store/open.d.ts +6 -1
- package/dist/cjs/store/open.js +230 -307
- package/dist/cjs/store/open.js.map +1 -1
- package/dist/cjs/store/readiness.d.cts +5 -0
- package/dist/cjs/store/readiness.d.ts +5 -0
- package/dist/cjs/store/readiness.js +39 -0
- package/dist/cjs/store/readiness.js.map +1 -0
- package/dist/cjs/store/reconcile.d.cts +26 -1
- package/dist/cjs/store/reconcile.d.ts +26 -1
- package/dist/cjs/store/reconcile.js +670 -576
- package/dist/cjs/store/reconcile.js.map +1 -1
- package/dist/cjs/store/signature.d.cts +1 -0
- package/dist/cjs/store/signature.d.ts +1 -0
- package/dist/cjs/store/signature.js +9 -0
- package/dist/cjs/store/signature.js.map +1 -1
- package/dist/cjs/store/sqlite/open.d.cts +1 -1
- package/dist/cjs/store/sqlite/open.d.ts +1 -1
- package/dist/cjs/store/sqlite/open.js +84 -90
- package/dist/cjs/store/sqlite/open.js.map +1 -1
- package/dist/cjs/store/sqlite/reconcile.js.map +1 -1
- package/dist/cjs/store/sqlite/store.js +63 -60
- package/dist/cjs/store/sqlite/store.js.map +1 -1
- package/dist/cjs/store/sqlite/vectors.d.cts +2 -2
- package/dist/cjs/store/sqlite/vectors.d.ts +2 -2
- package/dist/cjs/store/sqlite/vectors.js +8 -4
- package/dist/cjs/store/sqlite/vectors.js.map +1 -1
- package/dist/cjs/store/stages.js.map +1 -1
- package/dist/cjs/store/turso/connection.d.cts +1 -0
- package/dist/cjs/store/turso/connection.d.ts +1 -0
- package/dist/cjs/store/turso/connection.js +319 -94
- package/dist/cjs/store/turso/connection.js.map +1 -1
- package/dist/cjs/store/turso/open.d.cts +1 -1
- package/dist/cjs/store/turso/open.d.ts +1 -1
- package/dist/cjs/store/turso/open.js +70 -74
- package/dist/cjs/store/turso/open.js.map +1 -1
- package/dist/cjs/store/turso/store.js +25 -23
- package/dist/cjs/store/turso/store.js.map +1 -1
- package/dist/cjs/store/turso/vectors.d.cts +2 -2
- package/dist/cjs/store/turso/vectors.d.ts +2 -2
- package/dist/cjs/store/turso/vectors.js +26 -16
- package/dist/cjs/store/turso/vectors.js.map +1 -1
- package/dist/cjs/store/types.d.cts +4 -1
- package/dist/cjs/store/types.d.ts +4 -1
- package/dist/cjs/store/types.js.map +1 -1
- package/dist/cjs/store/vectors.d.cts +14 -1
- package/dist/cjs/store/vectors.d.ts +14 -1
- package/dist/cjs/store/vectors.js +61 -0
- package/dist/cjs/store/vectors.js.map +1 -1
- package/dist/cjs/watch.d.cts +6 -0
- package/dist/cjs/watch.d.ts +6 -0
- package/dist/cjs/watch.js +42 -10
- package/dist/cjs/watch.js.map +1 -1
- package/dist/cjs/workers/parse.d.cts +4 -3
- package/dist/cjs/workers/parse.d.ts +4 -3
- package/dist/cjs/workers/parse.js +19 -17
- package/dist/cjs/workers/parse.js.map +1 -1
- package/dist/esm/cli/index.d.ts +1 -1
- package/dist/esm/cli/index.js +1 -1
- package/dist/esm/cli/index.js.map +1 -1
- package/dist/esm/cli/path.js +4 -10
- package/dist/esm/cli/path.js.map +1 -1
- package/dist/esm/cli/related.js +5 -3
- package/dist/esm/cli/related.js.map +1 -1
- package/dist/esm/commands/index.d.ts +6 -3
- package/dist/esm/commands/index.js +1 -0
- package/dist/esm/commands/index.js.map +1 -1
- package/dist/esm/commands/map.d.ts +14 -5
- package/dist/esm/commands/map.js +2 -0
- package/dist/esm/commands/map.js.map +1 -1
- package/dist/esm/commands/path.d.ts +14 -0
- package/dist/esm/commands/path.js +33 -0
- package/dist/esm/commands/path.js.map +1 -0
- package/dist/esm/commands/peek.d.ts +16 -1
- package/dist/esm/commands/peek.js +35 -9
- package/dist/esm/commands/peek.js.map +1 -1
- package/dist/esm/commands/related.d.ts +16 -3
- package/dist/esm/commands/related.js +45 -28
- package/dist/esm/commands/related.js.map +1 -1
- package/dist/esm/commands/scope.d.ts +1 -0
- package/dist/esm/commands/scope.js +58 -0
- package/dist/esm/commands/scope.js.map +1 -1
- package/dist/esm/commands/search.d.ts +26 -3
- package/dist/esm/commands/search.js +85 -18
- package/dist/esm/commands/search.js.map +1 -1
- package/dist/esm/commands/signals.d.ts +4 -3
- package/dist/esm/commands/signals.js +11 -4
- package/dist/esm/commands/signals.js.map +1 -1
- package/dist/esm/commands/snapshot.d.ts +3 -0
- package/dist/esm/commands/snapshot.js +25 -0
- package/dist/esm/commands/snapshot.js.map +1 -0
- package/dist/esm/embed/cohere.js +35 -10
- package/dist/esm/embed/cohere.js.map +1 -1
- package/dist/esm/embed/endpoint.d.ts +2 -0
- package/dist/esm/embed/endpoint.js +11 -0
- package/dist/esm/embed/endpoint.js.map +1 -0
- package/dist/esm/embed/handoff.d.ts +7 -2
- package/dist/esm/embed/handoff.js +7 -0
- package/dist/esm/embed/handoff.js.map +1 -1
- package/dist/esm/embed/http.d.ts +18 -1
- package/dist/esm/embed/http.js +137 -17
- package/dist/esm/embed/http.js.map +1 -1
- package/dist/esm/embed/openai.js +34 -12
- package/dist/esm/embed/openai.js.map +1 -1
- package/dist/esm/embed/query.d.ts +9 -3
- package/dist/esm/embed/query.js +98 -26
- package/dist/esm/embed/query.js.map +1 -1
- package/dist/esm/embed/registry.d.ts +2 -2
- package/dist/esm/embed/registry.js +34 -5
- package/dist/esm/embed/registry.js.map +1 -1
- package/dist/esm/embed/static.js +10 -2
- package/dist/esm/embed/static.js.map +1 -1
- package/dist/esm/embed/store.js +30 -21
- package/dist/esm/embed/store.js.map +1 -1
- package/dist/esm/embed/types.d.ts +5 -2
- package/dist/esm/embed/types.js.map +1 -1
- package/dist/esm/features/embed.js +82 -21
- package/dist/esm/features/embed.js.map +1 -1
- package/dist/esm/graph/traverse.d.ts +2 -2
- package/dist/esm/graph/traverse.js +4 -2
- package/dist/esm/graph/traverse.js.map +1 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/output/output.d.ts +4 -36
- package/dist/esm/output/output.js +1 -2
- package/dist/esm/output/output.js.map +1 -1
- package/dist/esm/scan/pool.d.ts +2 -1
- package/dist/esm/scan/pool.js +80 -23
- package/dist/esm/scan/pool.js.map +1 -1
- package/dist/esm/scan/reparse.d.ts +1 -0
- package/dist/esm/scan/reparse.js +40 -12
- package/dist/esm/scan/reparse.js.map +1 -1
- package/dist/esm/store/builder.d.ts +11 -21
- package/dist/esm/store/builder.js +337 -133
- package/dist/esm/store/builder.js.map +1 -1
- package/dist/esm/store/duckdb/connection.js +9 -1
- package/dist/esm/store/duckdb/connection.js.map +1 -1
- package/dist/esm/store/duckdb/open.d.ts +1 -1
- package/dist/esm/store/duckdb/open.js +13 -9
- package/dist/esm/store/duckdb/open.js.map +1 -1
- package/dist/esm/store/duckdb/reconcile.js +145 -10
- package/dist/esm/store/duckdb/reconcile.js.map +1 -1
- package/dist/esm/store/embed-scope.js +16 -6
- package/dist/esm/store/embed-scope.js.map +1 -1
- package/dist/esm/store/index.d.ts +6 -0
- package/dist/esm/store/index.js +10 -4
- package/dist/esm/store/index.js.map +1 -1
- package/dist/esm/store/open.d.ts +6 -1
- package/dist/esm/store/open.js +77 -87
- package/dist/esm/store/open.js.map +1 -1
- package/dist/esm/store/readiness.d.ts +5 -0
- package/dist/esm/store/readiness.js +11 -0
- package/dist/esm/store/readiness.js.map +1 -0
- package/dist/esm/store/reconcile.d.ts +26 -1
- package/dist/esm/store/reconcile.js +142 -120
- package/dist/esm/store/reconcile.js.map +1 -1
- package/dist/esm/store/signature.d.ts +1 -0
- package/dist/esm/store/signature.js +8 -0
- package/dist/esm/store/signature.js.map +1 -1
- package/dist/esm/store/sqlite/open.d.ts +1 -1
- package/dist/esm/store/sqlite/open.js +12 -12
- package/dist/esm/store/sqlite/open.js.map +1 -1
- package/dist/esm/store/sqlite/reconcile.js +2 -2
- package/dist/esm/store/sqlite/reconcile.js.map +1 -1
- package/dist/esm/store/sqlite/store.js +21 -18
- package/dist/esm/store/sqlite/store.js.map +1 -1
- package/dist/esm/store/sqlite/vectors.d.ts +2 -2
- package/dist/esm/store/sqlite/vectors.js +7 -5
- package/dist/esm/store/sqlite/vectors.js.map +1 -1
- package/dist/esm/store/stages.js.map +1 -1
- package/dist/esm/store/turso/connection.d.ts +1 -0
- package/dist/esm/store/turso/connection.js +97 -28
- package/dist/esm/store/turso/connection.js.map +1 -1
- package/dist/esm/store/turso/open.d.ts +1 -1
- package/dist/esm/store/turso/open.js +9 -8
- package/dist/esm/store/turso/open.js.map +1 -1
- package/dist/esm/store/turso/store.js +16 -14
- package/dist/esm/store/turso/store.js.map +1 -1
- package/dist/esm/store/turso/vectors.d.ts +2 -2
- package/dist/esm/store/turso/vectors.js +27 -17
- package/dist/esm/store/turso/vectors.js.map +1 -1
- package/dist/esm/store/types.d.ts +4 -1
- package/dist/esm/store/types.js.map +1 -1
- package/dist/esm/store/vectors.d.ts +14 -1
- package/dist/esm/store/vectors.js +55 -0
- package/dist/esm/store/vectors.js.map +1 -1
- package/dist/esm/watch.d.ts +6 -0
- package/dist/esm/watch.js +40 -14
- package/dist/esm/watch.js.map +1 -1
- package/dist/esm/workers/parse.d.ts +4 -3
- package/dist/esm/workers/parse.js +19 -17
- package/dist/esm/workers/parse.js.map +1 -1
- package/package.json +1 -1
- package/skills/sense/SKILL.md +4 -2
- package/skills/sense/references/stores/duckdb.md +1 -1
- package/skills/sense-setup/SKILL.md +2 -2
- package/skills/sense-setup/references/embeddings.md +1 -1
- package/skills/sense-setup/references/store-benchmarks.md +5 -5
- package/skills/sense-setup/references/stores/duckdb.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/workers/parse.ts"],"sourcesContent":["import Tinypool from 'tinypool';\nimport type { Config, FeatureName } from '../config/index.ts';\nimport { FEATURES } from '../features/index.ts';\nimport type { ParsedDoc } from '../scan/index.ts';\nimport { parseFile } from '../scan/index.ts';\nimport type { FileStat } from '../scan/list.ts';\nimport { featuresForFile } from '../scan/reparse.ts';\nimport type { WorkerErrorPayload } from '../scan/worker-error.ts';\nimport { serializeError } from '../scan/worker-error.ts';\n\n// Constant for the whole dispatch, so it crosses once per worker instead of once per task. A\n// Feature carries closures and cannot cross the thread boundary; its name can, and the registry here resolves it back.\nexport interface ParseWorkerData {\n cfg: Config;\n featureNames: FeatureName[];\n}\n\n//
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/workers/parse.ts"],"sourcesContent":["import Tinypool from 'tinypool';\nimport type { Config, FeatureName } from '../config/index.ts';\nimport { FEATURES } from '../features/index.ts';\nimport type { ParsedDoc } from '../scan/index.ts';\nimport { parseFile } from '../scan/index.ts';\nimport type { FileStat } from '../scan/list.ts';\nimport { featuresForFile } from '../scan/reparse.ts';\nimport type { WorkerErrorPayload } from '../scan/worker-error.ts';\nimport { serializeError } from '../scan/worker-error.ts';\n\n// Constant for the whole dispatch, so it crosses once per worker instead of once per task. A\n// Feature carries closures and cannot cross the thread boundary; its name can, and the registry here resolves it back.\nexport interface ParseWorkerData {\n cfg: Config;\n featureNames: FeatureName[];\n}\n\n// Each task is a small file batch. Results stay per-file so one failure does not stop the\n// remaining files in that batch, and no token tree crosses the thread boundary.\nexport type ParseTask = FileStat[];\n\n// parseMs is the worker's own hrtime for parseFile, excluding dispatch and the return clone --\n// what separates it from the pool's dispatch-to-drain `parse` stage.\nexport type ParseFileResult = { ok: true; doc: ParsedDoc; warnings: string[]; parseMs: number } | { ok: false; error: WorkerErrorPayload };\nexport type ParseTaskResult = ParseFileResult[];\n\n// Read once per worker, not per task.\nconst { cfg, featureNames } = Tinypool.workerData as ParseWorkerData;\n// Filtering the registry (rather than mapping the names) keeps registry order, which is the\n// order `extracted` keys land in on the serial path.\nconst selected = FEATURES.filter((feature) => featureNames.includes(feature.name));\n\nexport default function parseTask(files: ParseTask): ParseTaskResult {\n return files.map((file): ParseFileResult => {\n try {\n const start = process.hrtime.bigint();\n const { doc, warnings } = parseFile(file, featuresForFile(selected, cfg, file), cfg);\n const parseMs = Number(process.hrtime.bigint() - start) / 1e6;\n return { ok: true, doc, warnings, parseMs };\n } catch (err) {\n return { ok: false, error: serializeError(err) };\n }\n });\n}\n"],"names":["parseTask","Tinypool","workerData","cfg","featureNames","selected","FEATURES","filter","feature","includes","name","files","map","file","start","process","hrtime","bigint","parseFile","featuresForFile","doc","warnings","parseMs","Number","ok","err","error","serializeError"],"mappings":";;;;+BAgCA;;;eAAwBA;;;+DAhCH;uBAEI;wBAEC;yBAEM;6BAED;;;;;;AAkB/B,sCAAsC;AACtC,IAA8BC,uBAAAA,iBAAQ,CAACC,UAAU,EAAzCC,MAAsBF,qBAAtBE,KAAKC,eAAiBH,qBAAjBG;AACb,4FAA4F;AAC5F,qDAAqD;AACrD,IAAMC,WAAWC,iBAAQ,CAACC,MAAM,CAAC,SAACC;WAAYJ,aAAaK,QAAQ,CAACD,QAAQE,IAAI;;AAEjE,SAASV,UAAUW,KAAgB;IAChD,OAAOA,MAAMC,GAAG,CAAC,SAACC;QAChB,IAAI;YACF,IAAMC,QAAQC,QAAQC,MAAM,CAACC,MAAM;YACnC,IAA0BC,aAAAA,IAAAA,mBAAS,EAACL,MAAMM,IAAAA,0BAAe,EAACd,UAAUF,KAAKU,OAAOV,MAAxEiB,MAAkBF,WAAlBE,KAAKC,WAAaH,WAAbG;YACb,IAAMC,UAAUC,OAAOR,QAAQC,MAAM,CAACC,MAAM,KAAKH,SAAS;YAC1D,OAAO;gBAAEU,IAAI;gBAAMJ,KAAAA;gBAAKC,UAAAA;gBAAUC,SAAAA;YAAQ;QAC5C,EAAE,OAAOG,KAAK;YACZ,OAAO;gBAAED,IAAI;gBAAOE,OAAOC,IAAAA,6BAAc,EAACF;YAAK;QACjD;IACF;AACF"}
|
package/dist/esm/cli/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export declare const USAGE: {
|
|
|
7
7
|
readonly download: "download [--config path]";
|
|
8
8
|
readonly sql: "sql \"<statement>\" [params...] [--preset name] [--no-build] [--format table|json|csv] [--config path]";
|
|
9
9
|
readonly search: "search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--no-build] [--format table|json|csv] [--config path]";
|
|
10
|
-
readonly map: "map [--no-build] [--format table|json] [--config path]";
|
|
10
|
+
readonly map: "map [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]";
|
|
11
11
|
readonly peek: "peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]";
|
|
12
12
|
readonly path: "path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--no-build] [--format table|json] [--config path]";
|
|
13
13
|
readonly related: "related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--no-build] [--format table|json|csv] [--config path]";
|
package/dist/esm/cli/index.js
CHANGED
|
@@ -8,7 +8,7 @@ export const USAGE = {
|
|
|
8
8
|
download: 'download [--config path]',
|
|
9
9
|
sql: 'sql "<statement>" [params...] [--preset name] [--no-build] [--format table|json|csv] [--config path]',
|
|
10
10
|
search: 'search "<terms>" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--no-build] [--format table|json|csv] [--config path]',
|
|
11
|
-
map: 'map [--no-build] [--format table|json] [--config path]',
|
|
11
|
+
map: 'map [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--no-build] [--format table|json] [--config path]',
|
|
12
12
|
peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--no-build] [--format table|json] [--config path]',
|
|
13
13
|
path: 'path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--max-depth n] [--no-build] [--format table|json] [--config path]',
|
|
14
14
|
related: 'related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--k n] [--no-build] [--format table|json|csv] [--config path]'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/index.ts"],"sourcesContent":["import type { Command } from './types.ts';\n\n// Each command's usage line, minus the leading \"usage: <name> \": shared by cli.ts's\n// usage() and the command's own parse() error/--help output so there is one copy, not two.\nexport const USAGE = {\n init: 'init [--model id-or-path] [--provider static|openai|cohere] [--url url]',\n build: 'build [--force] [--config path]',\n watch: 'watch [--force] [--config path]',\n status: 'status [--format table|json] [--config path]',\n download: 'download [--config path]',\n sql: 'sql \"<statement>\" [params...] [--preset name] [--no-build] [--format table|json|csv] [--config path]',\n search: 'search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--no-build] [--format table|json|csv] [--config path]',\n map: 'map [--no-build] [--format table|json] [--config path]',\n peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]',\n path: 'path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--no-build] [--format table|json] [--config path]',\n related: 'related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--no-build] [--format table|json|csv] [--config path]',\n} as const;\n\n// Lazy registry: a command's imports load only when it runs, so a heavy dependency in one\n// command never taxes the others (or --version/--help). These names are reserved from saved queries.\nexport const COMMANDS: Record<string, () => Promise<{ default: Command }>> = {\n init: () => import('./init.ts'),\n build: () => import('./build.ts'),\n watch: () => import('./watch.ts'),\n status: () => import('./status.ts'),\n download: () => import('./download.ts'),\n sql: () => import('./sql.ts'),\n search: () => import('./search.ts'),\n map: () => import('./map.ts'),\n peek: () => import('./peek.ts'),\n path: () => import('./path.ts'),\n related: () => import('./related.ts'),\n};\n\nexport type { Command, Ctx } from './types.ts';\n"],"names":["USAGE","init","build","watch","status","download","sql","search","map","peek","path","related","COMMANDS"],"mappings":"AAEA,oFAAoF;AACpF,2FAA2F;AAC3F,OAAO,MAAMA,QAAQ;IACnBC,MAAM;IACNC,OAAO;IACPC,OAAO;IACPC,QAAQ;IACRC,UAAU;IACVC,KAAK;IACLC,QAAQ;IACRC,KAAK;IACLC,MAAM;IACNC,MAAM;IACNC,SAAS;AACX,EAAW;AAEX,0FAA0F;AAC1F,qGAAqG;AACrG,OAAO,MAAMC,WAAgE;IAC3EX,MAAM,IAAM,MAAM,CAAC;IACnBC,OAAO,IAAM,MAAM,CAAC;IACpBC,OAAO,IAAM,MAAM,CAAC;IACpBC,QAAQ,IAAM,MAAM,CAAC;IACrBC,UAAU,IAAM,MAAM,CAAC;IACvBC,KAAK,IAAM,MAAM,CAAC;IAClBC,QAAQ,IAAM,MAAM,CAAC;IACrBC,KAAK,IAAM,MAAM,CAAC;IAClBC,MAAM,IAAM,MAAM,CAAC;IACnBC,MAAM,IAAM,MAAM,CAAC;IACnBC,SAAS,IAAM,MAAM,CAAC;AACxB,EAAE"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/index.ts"],"sourcesContent":["import type { Command } from './types.ts';\n\n// Each command's usage line, minus the leading \"usage: <name> \": shared by cli.ts's\n// usage() and the command's own parse() error/--help output so there is one copy, not two.\nexport const USAGE = {\n init: 'init [--model id-or-path] [--provider static|openai|cohere] [--url url]',\n build: 'build [--force] [--config path]',\n watch: 'watch [--force] [--config path]',\n status: 'status [--format table|json] [--config path]',\n download: 'download [--config path]',\n sql: 'sql \"<statement>\" [params...] [--preset name] [--no-build] [--format table|json|csv] [--config path]',\n search: 'search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--no-build] [--format table|json|csv] [--config path]',\n map: 'map [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]',\n peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--no-build] [--format table|json] [--config path]',\n path: 'path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--no-build] [--format table|json] [--config path]',\n related: 'related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--no-build] [--format table|json|csv] [--config path]',\n} as const;\n\n// Lazy registry: a command's imports load only when it runs, so a heavy dependency in one\n// command never taxes the others (or --version/--help). These names are reserved from saved queries.\nexport const COMMANDS: Record<string, () => Promise<{ default: Command }>> = {\n init: () => import('./init.ts'),\n build: () => import('./build.ts'),\n watch: () => import('./watch.ts'),\n status: () => import('./status.ts'),\n download: () => import('./download.ts'),\n sql: () => import('./sql.ts'),\n search: () => import('./search.ts'),\n map: () => import('./map.ts'),\n peek: () => import('./peek.ts'),\n path: () => import('./path.ts'),\n related: () => import('./related.ts'),\n};\n\nexport type { Command, Ctx } from './types.ts';\n"],"names":["USAGE","init","build","watch","status","download","sql","search","map","peek","path","related","COMMANDS"],"mappings":"AAEA,oFAAoF;AACpF,2FAA2F;AAC3F,OAAO,MAAMA,QAAQ;IACnBC,MAAM;IACNC,OAAO;IACPC,OAAO;IACPC,QAAQ;IACRC,UAAU;IACVC,KAAK;IACLC,QAAQ;IACRC,KAAK;IACLC,MAAM;IACNC,MAAM;IACNC,SAAS;AACX,EAAW;AAEX,0FAA0F;AAC1F,qGAAqG;AACrG,OAAO,MAAMC,WAAgE;IAC3EX,MAAM,IAAM,MAAM,CAAC;IACnBC,OAAO,IAAM,MAAM,CAAC;IACpBC,OAAO,IAAM,MAAM,CAAC;IACpBC,QAAQ,IAAM,MAAM,CAAC;IACrBC,UAAU,IAAM,MAAM,CAAC;IACvBC,KAAK,IAAM,MAAM,CAAC;IAClBC,QAAQ,IAAM,MAAM,CAAC;IACrBC,KAAK,IAAM,MAAM,CAAC;IAClBC,MAAM,IAAM,MAAM,CAAC;IACnBC,MAAM,IAAM,MAAM,CAAC;IACnBC,SAAS,IAAM,MAAM,CAAC;AACxB,EAAE"}
|
package/dist/esm/cli/path.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { scopedPaths } from '../commands/scope.js';
|
|
3
|
-
import { findPath } from '../graph/traverse.js';
|
|
1
|
+
import { findPath } from '../commands/path.js';
|
|
4
2
|
import { printRows } from '../output/output.js';
|
|
5
3
|
import { USAGE } from './index.js';
|
|
6
4
|
import { CONFIG, FORMAT, formatOf, NO_BUILD, parse, SCOPE, scopeOf, withDb } from './shared.js';
|
|
@@ -32,13 +30,9 @@ const pathCmd = (ctx)=>{
|
|
|
32
30
|
'core'
|
|
33
31
|
])
|
|
34
32
|
}, async (store, cfg)=>{
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const allowed = await scopedPaths(store, cfg, scopeOf(values));
|
|
39
|
-
const hops = await findPath(store, from, to, {
|
|
40
|
-
maxDepth,
|
|
41
|
-
allowed
|
|
33
|
+
const hops = await findPath(store, cfg, a, b, {
|
|
34
|
+
...scopeOf(values),
|
|
35
|
+
maxDepth
|
|
42
36
|
});
|
|
43
37
|
if (format === 'json') {
|
|
44
38
|
console.log(JSON.stringify(hops));
|
package/dist/esm/cli/path.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/path.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/path.ts"],"sourcesContent":["import { findPath } from '../commands/path.ts';\nimport type { Row } from '../output/output.ts';\nimport { printRows } from '../output/output.ts';\nimport type { BuildRequirement } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, NO_BUILD, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// --max-depth must be a positive integer, mirroring shared.ts's parseK.\nfunction parseMaxDepth(depth: string | undefined, usageError: (message: string) => never): number | undefined {\n if (depth === undefined) return undefined;\n const parsed = Number(depth);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--max-depth expects a positive integer, got \"${depth}\"`);\n return parsed;\n}\n\nconst pathCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.path}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG, 'max-depth': { type: 'string' } });\n const [a, b] = positionals;\n if (!a || !b) ctx.usageError(usage);\n const maxDepth = parseMaxDepth(values['max-depth'] as string | undefined, ctx.usageError);\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, { noBuild: values['no-build'] === true, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg) => {\n const hops = await findPath(store, cfg, a, b, { ...scopeOf(values), maxDepth });\n\n if (format === 'json') {\n console.log(JSON.stringify(hops));\n return;\n }\n if (hops === null) {\n console.log(maxDepth ? `no path within ${maxDepth} hops` : 'no path');\n return;\n }\n const rows: Row[] = hops.map((p, step) => ({ step, path: p }));\n printRows(rows, format);\n });\n};\nexport default pathCmd;\n"],"names":["findPath","printRows","USAGE","CONFIG","FORMAT","formatOf","NO_BUILD","parse","SCOPE","scopeOf","withDb","parseMaxDepth","depth","usageError","undefined","parsed","Number","isInteger","pathCmd","ctx","usage","name","path","values","positionals","argv","type","a","b","maxDepth","format","config","noBuild","requirements","Set","store","cfg","hops","console","log","JSON","stringify","rows","map","p","step"],"mappings":"AAAA,SAASA,QAAQ,QAAQ,sBAAsB;AAE/C,SAASC,SAAS,QAAQ,sBAAsB;AAEhD,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGhG,wEAAwE;AACxE,SAASC,cAAcC,KAAyB,EAAEC,UAAsC;IACtF,IAAID,UAAUE,WAAW,OAAOA;IAChC,MAAMC,SAASC,OAAOJ;IACtB,IAAI,CAACI,OAAOC,SAAS,CAACF,WAAWA,UAAU,GAAGF,WAAW,CAAC,6CAA6C,EAAED,MAAM,CAAC,CAAC;IACjH,OAAOG;AACT;AAEA,MAAMG,UAAmB,CAACC;IACxB,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEnB,MAAMoB,IAAI,EAAE;IAChD,MAAM,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGjB,MAAMY,IAAIM,IAAI,EAAEL,OAAO;QAAE,GAAGZ,KAAK;QAAE,GAAGF,QAAQ;QAAE,GAAGF,MAAM;QAAE,GAAGD,MAAM;QAAE,aAAa;YAAEuB,MAAM;QAAS;IAAE;IACtI,MAAM,CAACC,GAAGC,EAAE,GAAGJ;IACf,IAAI,CAACG,KAAK,CAACC,GAAGT,IAAIN,UAAU,CAACO;IAC7B,MAAMS,WAAWlB,cAAcY,MAAM,CAAC,YAAY,EAAwBJ,IAAIN,UAAU;IACxF,MAAMiB,SAASzB,SAASkB;IACxB,OAAOb,OAAOS,KAAKI,OAAOQ,MAAM,EAAwB;QAAEC,SAAST,MAAM,CAAC,WAAW,KAAK;QAAMU,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,OAAOC,OAAOC;QACjK,MAAMC,OAAO,MAAMrC,SAASmC,OAAOC,KAAKT,GAAGC,GAAG;YAAE,GAAGnB,QAAQc,OAAO;YAAEM;QAAS;QAE7E,IAAIC,WAAW,QAAQ;YACrBQ,QAAQC,GAAG,CAACC,KAAKC,SAAS,CAACJ;YAC3B;QACF;QACA,IAAIA,SAAS,MAAM;YACjBC,QAAQC,GAAG,CAACV,WAAW,CAAC,eAAe,EAAEA,SAAS,KAAK,CAAC,GAAG;YAC3D;QACF;QACA,MAAMa,OAAcL,KAAKM,GAAG,CAAC,CAACC,GAAGC,OAAU,CAAA;gBAAEA;gBAAMvB,MAAMsB;YAAE,CAAA;QAC3D3C,UAAUyC,MAAMZ;IAClB;AACF;AACA,eAAeZ,QAAQ"}
|
package/dist/esm/cli/related.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { relatedNotes, resolveRelatedSeed } from '../commands/related.js';
|
|
1
|
+
import { RELATED_DEFAULT_K, relatedNotes, resolveRelatedSeed } from '../commands/related.js';
|
|
2
2
|
import { scopedPaths } from '../commands/scope.js';
|
|
3
3
|
import { resolveSearch } from '../config/index.js';
|
|
4
4
|
import { printRows } from '../output/output.js';
|
|
5
5
|
import { prepareDocumentEmbeddings } from '../store/open.js';
|
|
6
6
|
import { USAGE } from './index.js';
|
|
7
7
|
import { CONFIG, FORMAT, NO_BUILD, parse, parseK, rowFormatOf, SCOPE, scopeOf, withDb } from './shared.js';
|
|
8
|
-
const RELATED_DEFAULT_K = 5;
|
|
9
8
|
const relatedCmd = (ctx)=>{
|
|
10
9
|
var _parseK;
|
|
11
10
|
const usage = `usage: ${ctx.name} ${USAGE.related}`;
|
|
@@ -38,7 +37,10 @@ const relatedCmd = (ctx)=>{
|
|
|
38
37
|
path
|
|
39
38
|
]));
|
|
40
39
|
}
|
|
41
|
-
printRows(await relatedNotes(store, cfg, pathArg,
|
|
40
|
+
printRows(await relatedNotes(store, cfg, pathArg, {
|
|
41
|
+
...overrides,
|
|
42
|
+
k
|
|
43
|
+
}), format);
|
|
42
44
|
});
|
|
43
45
|
};
|
|
44
46
|
export default relatedCmd;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/related.ts"],"sourcesContent":["import { relatedNotes, resolveRelatedSeed } from '../commands/related.ts';\nimport { scopedPaths } from '../commands/scope.ts';\nimport { resolveSearch } from '../config/index.ts';\nimport
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/related.ts"],"sourcesContent":["import { RELATED_DEFAULT_K, relatedNotes, resolveRelatedSeed } from '../commands/related.ts';\nimport { scopedPaths } from '../commands/scope.ts';\nimport { resolveSearch } from '../config/index.ts';\nimport { printRows } from '../output/output.ts';\nimport { type BuildRequirement, prepareDocumentEmbeddings } from '../store/open.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, NO_BUILD, parse, parseK, rowFormatOf, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst relatedCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.related}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...NO_BUILD, ...FORMAT, ...CONFIG, k: { type: 'string' } });\n const [pathArg] = positionals;\n if (!pathArg) ctx.usageError(usage);\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? RELATED_DEFAULT_K;\n const format = rowFormatOf(values);\n const noBuild = values['no-build'] === true;\n return withDb(ctx, values.config as string | undefined, { noBuild, requirements: new Set<BuildRequirement>(['core']) }, async (store, cfg, build) => {\n const overrides = scopeOf(values);\n if (build && resolveSearch(cfg, overrides).signals.vectors !== undefined) {\n const path = await resolveRelatedSeed(store, pathArg);\n const allowed = await scopedPaths(store, cfg, overrides);\n await prepareDocumentEmbeddings(store, cfg, new Set([...allowed, path]));\n }\n printRows(await relatedNotes(store, cfg, pathArg, { ...overrides, k }), format);\n });\n};\nexport default relatedCmd;\n"],"names":["RELATED_DEFAULT_K","relatedNotes","resolveRelatedSeed","scopedPaths","resolveSearch","printRows","prepareDocumentEmbeddings","USAGE","CONFIG","FORMAT","NO_BUILD","parse","parseK","rowFormatOf","SCOPE","scopeOf","withDb","relatedCmd","ctx","usage","name","related","values","positionals","argv","k","type","pathArg","usageError","format","noBuild","config","requirements","Set","store","cfg","build","overrides","signals","vectors","undefined","path","allowed"],"mappings":"AAAA,SAASA,iBAAiB,EAAEC,YAAY,EAAEC,kBAAkB,QAAQ,yBAAyB;AAC7F,SAASC,WAAW,QAAQ,uBAAuB;AACnD,SAASC,aAAa,QAAQ,qBAAqB;AACnD,SAASC,SAAS,QAAQ,sBAAsB;AAChD,SAAgCC,yBAAyB,QAAQ,mBAAmB;AACpF,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,MAAM,EAAEC,WAAW,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAG3G,MAAMC,aAAsB,CAACC;QAKjBN;IAJV,MAAMO,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEb,MAAMc,OAAO,EAAE;IACnD,MAAM,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGZ,MAAMO,IAAIM,IAAI,EAAEL,OAAO;QAAE,GAAGL,KAAK;QAAE,GAAGJ,QAAQ;QAAE,GAAGD,MAAM;QAAE,GAAGD,MAAM;QAAEiB,GAAG;YAAEC,MAAM;QAAS;IAAE;IAC5H,MAAM,CAACC,QAAQ,GAAGJ;IAClB,IAAI,CAACI,SAAST,IAAIU,UAAU,CAACT;IAC7B,MAAMM,KAAIb,UAAAA,OAAOU,OAAOG,CAAC,EAAwBP,IAAIU,UAAU,eAArDhB,qBAAAA,UAA0DZ;IACpE,MAAM6B,SAAShB,YAAYS;IAC3B,MAAMQ,UAAUR,MAAM,CAAC,WAAW,KAAK;IACvC,OAAON,OAAOE,KAAKI,OAAOS,MAAM,EAAwB;QAAED;QAASE,cAAc,IAAIC,IAAsB;YAAC;SAAO;IAAE,GAAG,OAAOC,OAAOC,KAAKC;QACzI,MAAMC,YAAYtB,QAAQO;QAC1B,IAAIc,SAAShC,cAAc+B,KAAKE,WAAWC,OAAO,CAACC,OAAO,KAAKC,WAAW;YACxE,MAAMC,OAAO,MAAMvC,mBAAmBgC,OAAOP;YAC7C,MAAMe,UAAU,MAAMvC,YAAY+B,OAAOC,KAAKE;YAC9C,MAAM/B,0BAA0B4B,OAAOC,KAAK,IAAIF,IAAI;mBAAIS;gBAASD;aAAK;QACxE;QACApC,UAAU,MAAMJ,aAAaiC,OAAOC,KAAKR,SAAS;YAAE,GAAGU,SAAS;YAAEZ;QAAE,IAAII;IAC1E;AACF;AACA,eAAeZ,WAAW"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
export type { TreeMap } from './map.js';
|
|
1
|
+
export type { TreeMap, TreeMapField, TreeMapHub, TreeMapRecent } from './map.js';
|
|
2
2
|
export { mapTree } from './map.js';
|
|
3
|
-
export type {
|
|
3
|
+
export type { PathOptions } from './path.js';
|
|
4
|
+
export { findPath } from './path.js';
|
|
5
|
+
export type { Peek, PeekSection } from './peek.js';
|
|
4
6
|
export { peek, resolveNote } from './peek.js';
|
|
7
|
+
export type { RelatedOptions, RelatedResult } from './related.js';
|
|
5
8
|
export { relatedNotes } from './related.js';
|
|
6
9
|
export { scopedPaths } from './scope.js';
|
|
7
|
-
export type { SearchOptions } from './search.js';
|
|
10
|
+
export type { SearchOptions, SearchResult, SearchResultVia } from './search.js';
|
|
8
11
|
export { search } from './search.js';
|
|
9
12
|
export type { PresetCoverage } from './status.js';
|
|
10
13
|
export { presetCoverage } from './status.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// The three commands: mapTree (orient), search (locate), peek (structure).
|
|
2
2
|
// Each returns data; cli.ts renders. All of them degrade when a feature is off.
|
|
3
3
|
export { mapTree } from './map.js';
|
|
4
|
+
export { findPath } from './path.js';
|
|
4
5
|
export { peek, resolveNote } from './peek.js';
|
|
5
6
|
export { relatedNotes } from './related.js';
|
|
6
7
|
export { scopedPaths } from './scope.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/index.ts"],"sourcesContent":["// The three commands: mapTree (orient), search (locate), peek (structure).\n// Each returns data; cli.ts renders. All of them degrade when a feature is off.\n\nexport type { TreeMap } from './map.ts';\nexport { mapTree } from './map.ts';\nexport type { Peek } from './peek.ts';\nexport { peek, resolveNote } from './peek.ts';\nexport { relatedNotes } from './related.ts';\nexport { scopedPaths } from './scope.ts';\nexport type { SearchOptions } from './search.ts';\nexport { search } from './search.ts';\nexport type { PresetCoverage } from './status.ts';\nexport { presetCoverage } from './status.ts';\n"],"names":["mapTree","peek","resolveNote","relatedNotes","scopedPaths","search","presetCoverage"],"mappings":"AAAA,2EAA2E;AAC3E,gFAAgF;AAGhF,SAASA,OAAO,QAAQ,WAAW;AAEnC,SAASC,IAAI,EAAEC,WAAW,QAAQ,YAAY;
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/index.ts"],"sourcesContent":["// The three commands: mapTree (orient), search (locate), peek (structure).\n// Each returns data; cli.ts renders. All of them degrade when a feature is off.\n\nexport type { TreeMap, TreeMapField, TreeMapHub, TreeMapRecent } from './map.ts';\nexport { mapTree } from './map.ts';\nexport type { PathOptions } from './path.ts';\nexport { findPath } from './path.ts';\nexport type { Peek, PeekSection } from './peek.ts';\nexport { peek, resolveNote } from './peek.ts';\nexport type { RelatedOptions, RelatedResult } from './related.ts';\nexport { relatedNotes } from './related.ts';\nexport { scopedPaths } from './scope.ts';\nexport type { SearchOptions, SearchResult, SearchResultVia } from './search.ts';\nexport { search } from './search.ts';\nexport type { PresetCoverage } from './status.ts';\nexport { presetCoverage } from './status.ts';\n"],"names":["mapTree","findPath","peek","resolveNote","relatedNotes","scopedPaths","search","presetCoverage"],"mappings":"AAAA,2EAA2E;AAC3E,gFAAgF;AAGhF,SAASA,OAAO,QAAQ,WAAW;AAEnC,SAASC,QAAQ,QAAQ,YAAY;AAErC,SAASC,IAAI,EAAEC,WAAW,QAAQ,YAAY;AAE9C,SAASC,YAAY,QAAQ,eAAe;AAC5C,SAASC,WAAW,QAAQ,aAAa;AAEzC,SAASC,MAAM,QAAQ,cAAc;AAErC,SAASC,cAAc,QAAQ,cAAc"}
|
|
@@ -1,21 +1,30 @@
|
|
|
1
1
|
import type { FeatureName, ResolvedConfig, SearchOverrides } from '../config/index.js';
|
|
2
|
-
import type {
|
|
3
|
-
import type { Store } from '../store/types.js';
|
|
2
|
+
import type { FieldStat, Store } from '../store/types.js';
|
|
4
3
|
import type { PresetCoverage } from './status.js';
|
|
5
4
|
export interface TreeMap {
|
|
6
5
|
docs: {
|
|
7
6
|
count: number;
|
|
8
7
|
bytes: number;
|
|
9
8
|
};
|
|
10
|
-
fields:
|
|
9
|
+
fields: TreeMapField[];
|
|
11
10
|
fieldsTotal: number;
|
|
12
11
|
features: {
|
|
13
12
|
on: FeatureName[];
|
|
14
13
|
off: FeatureName[];
|
|
15
14
|
};
|
|
16
15
|
presets: PresetCoverage[];
|
|
17
|
-
hubs:
|
|
18
|
-
recent:
|
|
16
|
+
hubs: TreeMapHub[];
|
|
17
|
+
recent: TreeMapRecent[];
|
|
19
18
|
recentCaveat: string | null;
|
|
20
19
|
}
|
|
20
|
+
export type TreeMapField = FieldStat;
|
|
21
|
+
export type TreeMapHub = {
|
|
22
|
+
path: string;
|
|
23
|
+
rank: number;
|
|
24
|
+
title: string;
|
|
25
|
+
};
|
|
26
|
+
export type TreeMapRecent = {
|
|
27
|
+
path: string;
|
|
28
|
+
modified: string;
|
|
29
|
+
};
|
|
21
30
|
export declare function mapTree(store: Store, cfg: ResolvedConfig, overrides?: SearchOverrides): Promise<TreeMap>;
|
package/dist/esm/commands/map.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { featureEnabled, featureStates } from '../config/index.js';
|
|
2
2
|
import { serialQuery } from '../lib/serial-query.js';
|
|
3
3
|
import { INTERNAL_COLUMNS, scopedPaths, setupMapScope } from './scope.js';
|
|
4
|
+
import { assertQuerySnapshot } from './snapshot.js';
|
|
4
5
|
import { presetCoverage } from './status.js';
|
|
5
6
|
// A result row is capped at SQLITE_MAX_COLUMN (2000, default); two aggregate expressions per
|
|
6
7
|
// field keeps a chunk's row width safely under that regardless of how many fields the tree has.
|
|
@@ -22,6 +23,7 @@ export function mapTree(store, cfg, overrides = {}) {
|
|
|
22
23
|
}
|
|
23
24
|
async function mapIndexed(store, cfg, overrides) {
|
|
24
25
|
return store.transaction(async ()=>{
|
|
26
|
+
await assertQuerySnapshot(store, cfg);
|
|
25
27
|
await setupMapScope(store, await scopedPaths(store, cfg, overrides));
|
|
26
28
|
const scopeWhere = 'WHERE "path" IN (SELECT "path" FROM _map_scope)';
|
|
27
29
|
const scopeAnd = 'AND f."path" IN (SELECT "path" FROM _map_scope)';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/map.ts"],"sourcesContent":["import type { FeatureName, ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { featureEnabled, featureStates } from '../config/index.ts';\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type {
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/map.ts"],"sourcesContent":["import type { FeatureName, ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { featureEnabled, featureStates } from '../config/index.ts';\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type { FieldStat, Store } from '../store/types.ts';\nimport { INTERNAL_COLUMNS, scopedPaths, setupMapScope } from './scope.ts';\nimport { assertQuerySnapshot } from './snapshot.ts';\nimport type { PresetCoverage } from './status.ts';\nimport { presetCoverage } from './status.ts';\n\nexport interface TreeMap {\n docs: { count: number; bytes: number };\n fields: TreeMapField[]; // top 20 by coverage; fieldsTotal carries the real count\n fieldsTotal: number;\n features: { on: FeatureName[]; off: FeatureName[] };\n presets: PresetCoverage[];\n hubs: TreeMapHub[];\n recent: TreeMapRecent[];\n recentCaveat: string | null;\n}\n\nexport type TreeMapField = FieldStat;\n\nexport type TreeMapHub = {\n path: string;\n rank: number;\n title: string;\n};\n\nexport type TreeMapRecent = {\n path: string;\n modified: string;\n};\n\n// A result row is capped at SQLITE_MAX_COLUMN (2000, default); two aggregate expressions per\n// field keeps a chunk's row width safely under that regardless of how many fields the tree has.\nconst MAP_COLUMN_CHUNK = 300;\n\n// \"YYYY-MM-DD HH:MM:SS\" UTC, the exact shape sqlite's datetime(ms / 1000, 'unixepoch') prints;\n// formatted in JS so the query stays dialect-free.\nfunction utcSecond(ms: number): string {\n return new Date(ms).toISOString().slice(0, 19).replace('T', ' ');\n}\n\nfunction chunk<T>(items: T[], size: number): T[][] {\n const out: T[][] = [];\n for (let i = 0; i < items.length; i += size) out.push(items.slice(i, i + size));\n return out;\n}\n\n// What is this scope: fixed-size output regardless of tree size. Coverage and features stay\n// global -- they describe the tree, not the current question.\nexport function mapTree(store: Store, cfg: ResolvedConfig, overrides: SearchOverrides = {}): Promise<TreeMap> {\n return serialQuery(store, () => mapIndexed(store, cfg, overrides));\n}\n\nasync function mapIndexed(store: Store, cfg: ResolvedConfig, overrides: SearchOverrides): Promise<TreeMap> {\n return store.transaction(async () => {\n await assertQuerySnapshot(store, cfg);\n await setupMapScope(store, await scopedPaths(store, cfg, overrides));\n const scopeWhere = 'WHERE \"path\" IN (SELECT \"path\" FROM _map_scope)';\n const scopeAnd = 'AND f.\"path\" IN (SELECT \"path\" FROM _map_scope)';\n\n const docs = (await (await store.prepare(`SELECT COUNT(*) AS count, COALESCE(SUM(\"_size\"), 0) AS bytes FROM frontmatter ${scopeWhere}`)).get()) as { count: number; bytes: number };\n\n const columns = (await store.docs.columns()).filter((name) => !INTERNAL_COLUMNS.has(name));\n // Observed types, not declared: a field can be text in most notes and numeric in a few, so\n // every distinct type observed across the scope is reported, not just the first.\n const allFields: FieldStat[] = [];\n for (const group of chunk(columns, MAP_COLUMN_CHUNK)) allFields.push(...(await store.docs.fieldStats(group, scopeWhere)));\n allFields.sort((a, b) => b.coverage - a.coverage);\n const fields = allFields.slice(0, 20);\n\n const hubs = featureEnabled(cfg, 'rank')\n ? ((await (await store.prepare(`SELECT f.\"path\" AS path, round(f.\"_rank\" * 100, 2) AS rank, content.title FROM frontmatter f JOIN content ON content.path = f.\"path\" WHERE f.\"_rank\" IS NOT NULL ${scopeAnd} ORDER BY f.\"_rank\" DESC, f.\"path\" ASC LIMIT 8`)).all()) as TreeMapHub[])\n : [];\n\n const recent = ((await (await store.prepare(`SELECT \"path\", \"_mtime\" AS mtime FROM frontmatter ${scopeWhere} ORDER BY \"_mtime\" DESC, \"path\" ASC LIMIT 5`)).all()) as Array<{ path: string; mtime: number }>).map((r) => ({ path: r.path, modified: utcSecond(r.mtime) }));\n\n // A fresh clone/copy stamps files with checkout time, not edit history; second granularity\n // matches the `recent` table above and is coarse enough to catch that without an exact-ms match.\n const topSecond = (await (await store.prepare(`SELECT COUNT(*) AS n FROM frontmatter ${scopeWhere} GROUP BY CAST(\"_mtime\" / 1000 AS INTEGER) ORDER BY n DESC LIMIT 1`)).get()) as { n: number } | undefined;\n const recentCaveat = topSecond && docs.count > 1 && topSecond.n > docs.count / 2 ? `${topSecond.n} of ${docs.count} files share one modified second, so recency likely reflects a checkout or copy, not edit history` : null;\n\n return { docs, fields, fieldsTotal: allFields.length, features: featureStates(cfg), presets: await presetCoverage(store, cfg), hubs, recent, recentCaveat };\n });\n}\n"],"names":["featureEnabled","featureStates","serialQuery","INTERNAL_COLUMNS","scopedPaths","setupMapScope","assertQuerySnapshot","presetCoverage","MAP_COLUMN_CHUNK","utcSecond","ms","Date","toISOString","slice","replace","chunk","items","size","out","i","length","push","mapTree","store","cfg","overrides","mapIndexed","transaction","scopeWhere","scopeAnd","docs","prepare","get","columns","filter","name","has","allFields","group","fieldStats","sort","a","b","coverage","fields","hubs","all","recent","map","r","path","modified","mtime","topSecond","recentCaveat","count","n","fieldsTotal","features","presets"],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ResolvedConfig, SearchOverrides } from '../config/index.js';
|
|
2
|
+
import type { Store } from '../store/types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Options for {@link findPath}. Scope fields constrain intermediate nodes; `maxDepth` limits the
|
|
5
|
+
* number of traversed links and must be a positive integer when supplied.
|
|
6
|
+
*/
|
|
7
|
+
export type PathOptions = Omit<SearchOverrides, 'k'> & {
|
|
8
|
+
maxDepth?: number;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Finds the shortest undirected link path between two indexed notes. Endpoints resolve across
|
|
12
|
+
* the indexed tree and remain permitted outside the scope applied to intermediate nodes.
|
|
13
|
+
*/
|
|
14
|
+
export declare function findPath(store: Store, cfg: ResolvedConfig, fromArg: string, toArg: string, options?: PathOptions): Promise<string[] | null>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { resolveSearch } from '../config/index.js';
|
|
2
|
+
import { SenseError } from '../errors.js';
|
|
3
|
+
import { findPathInSnapshot } from '../graph/traverse.js';
|
|
4
|
+
import { serialQuery } from '../lib/serial-query.js';
|
|
5
|
+
import { resolveNote } from './peek.js';
|
|
6
|
+
import { scopedPaths } from './scope.js';
|
|
7
|
+
import { assertQuerySnapshot } from './snapshot.js';
|
|
8
|
+
/**
|
|
9
|
+
* Finds the shortest undirected link path between two indexed notes. Endpoints resolve across
|
|
10
|
+
* the indexed tree and remain permitted outside the scope applied to intermediate nodes.
|
|
11
|
+
*/ export function findPath(store, cfg, fromArg, toArg, options = {}) {
|
|
12
|
+
return serialQuery(store, ()=>findScopedPath(store, cfg, fromArg, toArg, options));
|
|
13
|
+
}
|
|
14
|
+
async function findScopedPath(store, cfg, fromArg, toArg, options) {
|
|
15
|
+
if (options.maxDepth !== undefined && (!Number.isFinite(options.maxDepth) || !Number.isInteger(options.maxDepth) || options.maxDepth <= 0)) {
|
|
16
|
+
throw new SenseError('SEARCH_OPTION_INVALID', `path option "maxDepth" must be a positive finite integer, got ${String(options.maxDepth)}`);
|
|
17
|
+
}
|
|
18
|
+
// Validate the named preset before opening the snapshot; repeat it inside because preset_files
|
|
19
|
+
// and the compatibility assertion below belong to the final published generation.
|
|
20
|
+
resolveSearch(cfg, options);
|
|
21
|
+
return store.transaction(async ()=>{
|
|
22
|
+
await assertQuerySnapshot(store, cfg);
|
|
23
|
+
resolveSearch(cfg, options);
|
|
24
|
+
const paths = (await (await store.prepare('SELECT "path" FROM frontmatter')).all()).map((row)=>row.path);
|
|
25
|
+
const from = resolveNote(paths, fromArg);
|
|
26
|
+
const to = resolveNote(paths, toArg);
|
|
27
|
+
const allowed = await scopedPaths(store, cfg, options);
|
|
28
|
+
return findPathInSnapshot(store, from, to, {
|
|
29
|
+
maxDepth: options.maxDepth,
|
|
30
|
+
allowed
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/path.ts"],"sourcesContent":["import type { ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { resolveSearch } from '../config/index.ts';\nimport { SenseError } from '../errors.ts';\nimport { findPathInSnapshot } from '../graph/traverse.ts';\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type { Store } from '../store/types.ts';\nimport { resolveNote } from './peek.ts';\nimport { scopedPaths } from './scope.ts';\nimport { assertQuerySnapshot } from './snapshot.ts';\n\n/**\n * Options for {@link findPath}. Scope fields constrain intermediate nodes; `maxDepth` limits the\n * number of traversed links and must be a positive integer when supplied.\n */\nexport type PathOptions = Omit<SearchOverrides, 'k'> & {\n maxDepth?: number;\n};\n\n/**\n * Finds the shortest undirected link path between two indexed notes. Endpoints resolve across\n * the indexed tree and remain permitted outside the scope applied to intermediate nodes.\n */\nexport function findPath(store: Store, cfg: ResolvedConfig, fromArg: string, toArg: string, options: PathOptions = {}): Promise<string[] | null> {\n return serialQuery(store, () => findScopedPath(store, cfg, fromArg, toArg, options));\n}\n\nasync function findScopedPath(store: Store, cfg: ResolvedConfig, fromArg: string, toArg: string, options: PathOptions): Promise<string[] | null> {\n if (options.maxDepth !== undefined && (!Number.isFinite(options.maxDepth) || !Number.isInteger(options.maxDepth) || options.maxDepth <= 0)) {\n throw new SenseError('SEARCH_OPTION_INVALID', `path option \"maxDepth\" must be a positive finite integer, got ${String(options.maxDepth)}`);\n }\n // Validate the named preset before opening the snapshot; repeat it inside because preset_files\n // and the compatibility assertion below belong to the final published generation.\n resolveSearch(cfg, options);\n return store.transaction(async () => {\n await assertQuerySnapshot(store, cfg);\n resolveSearch(cfg, options);\n const paths = ((await (await store.prepare('SELECT \"path\" FROM frontmatter')).all()) as Array<{ path: string }>).map((row) => row.path);\n const from = resolveNote(paths, fromArg);\n const to = resolveNote(paths, toArg);\n const allowed = await scopedPaths(store, cfg, options);\n return findPathInSnapshot(store, from, to, { maxDepth: options.maxDepth, allowed });\n });\n}\n"],"names":["resolveSearch","SenseError","findPathInSnapshot","serialQuery","resolveNote","scopedPaths","assertQuerySnapshot","findPath","store","cfg","fromArg","toArg","options","findScopedPath","maxDepth","undefined","Number","isFinite","isInteger","String","transaction","paths","prepare","all","map","row","path","from","to","allowed"],"mappings":"AACA,SAASA,aAAa,QAAQ,qBAAqB;AACnD,SAASC,UAAU,QAAQ,eAAe;AAC1C,SAASC,kBAAkB,QAAQ,uBAAuB;AAC1D,SAASC,WAAW,QAAQ,yBAAyB;AAErD,SAASC,WAAW,QAAQ,YAAY;AACxC,SAASC,WAAW,QAAQ,aAAa;AACzC,SAASC,mBAAmB,QAAQ,gBAAgB;AAUpD;;;CAGC,GACD,OAAO,SAASC,SAASC,KAAY,EAAEC,GAAmB,EAAEC,OAAe,EAAEC,KAAa,EAAEC,UAAuB,CAAC,CAAC;IACnH,OAAOT,YAAYK,OAAO,IAAMK,eAAeL,OAAOC,KAAKC,SAASC,OAAOC;AAC7E;AAEA,eAAeC,eAAeL,KAAY,EAAEC,GAAmB,EAAEC,OAAe,EAAEC,KAAa,EAAEC,OAAoB;IACnH,IAAIA,QAAQE,QAAQ,KAAKC,aAAc,CAAA,CAACC,OAAOC,QAAQ,CAACL,QAAQE,QAAQ,KAAK,CAACE,OAAOE,SAAS,CAACN,QAAQE,QAAQ,KAAKF,QAAQE,QAAQ,IAAI,CAAA,GAAI;QAC1I,MAAM,IAAIb,WAAW,yBAAyB,CAAC,8DAA8D,EAAEkB,OAAOP,QAAQE,QAAQ,GAAG;IAC3I;IACA,+FAA+F;IAC/F,kFAAkF;IAClFd,cAAcS,KAAKG;IACnB,OAAOJ,MAAMY,WAAW,CAAC;QACvB,MAAMd,oBAAoBE,OAAOC;QACjCT,cAAcS,KAAKG;QACnB,MAAMS,QAAQ,AAAE,CAAA,MAAM,AAAC,CAAA,MAAMb,MAAMc,OAAO,CAAC,iCAAgC,EAAGC,GAAG,EAAC,EAA+BC,GAAG,CAAC,CAACC,MAAQA,IAAIC,IAAI;QACtI,MAAMC,OAAOvB,YAAYiB,OAAOX;QAChC,MAAMkB,KAAKxB,YAAYiB,OAAOV;QAC9B,MAAMkB,UAAU,MAAMxB,YAAYG,OAAOC,KAAKG;QAC9C,OAAOV,mBAAmBM,OAAOmB,MAAMC,IAAI;YAAEd,UAAUF,QAAQE,QAAQ;YAAEe;QAAQ;IACnF;AACF"}
|
|
@@ -2,19 +2,34 @@ import type { FeatureName, ResolvedConfig, SearchOverrides } from '../config/ind
|
|
|
2
2
|
import type { Row } from '../output/output.js';
|
|
3
3
|
import type { Store } from '../store/types.js';
|
|
4
4
|
export declare function resolveNote(paths: string[], arg: string): string;
|
|
5
|
+
/** Structured, bounded metadata returned by the root {@link peek} API. */
|
|
5
6
|
export interface Peek {
|
|
6
7
|
path: string;
|
|
7
8
|
tokens: number;
|
|
8
9
|
frontmatter: Row;
|
|
10
|
+
/** Set when frontmatter parsing failed, distinguishing that case from an empty block. */
|
|
9
11
|
parseError: string | null;
|
|
10
|
-
sections:
|
|
12
|
+
sections: PeekSection[];
|
|
11
13
|
outbound: string[];
|
|
12
14
|
backlinks: string[];
|
|
13
15
|
unresolved: string[];
|
|
16
|
+
/** Totals before each bounded list is truncated. */
|
|
14
17
|
sectionsTotal: number;
|
|
15
18
|
outboundTotal: number;
|
|
16
19
|
backlinksTotal: number;
|
|
17
20
|
unresolvedTotal: number;
|
|
21
|
+
/** Disabled features whose result blocks are omitted rather than returned empty. */
|
|
18
22
|
off: FeatureName[];
|
|
19
23
|
}
|
|
24
|
+
export interface PeekSection {
|
|
25
|
+
level: number;
|
|
26
|
+
heading: string;
|
|
27
|
+
start_line: number;
|
|
28
|
+
end_line: number;
|
|
29
|
+
tokens: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Returns indexed metadata for a note in scope. Exact excluded paths fail before scoped basename
|
|
33
|
+
* resolution; resolved neighbors stay in scope, while unresolved written targets remain visible.
|
|
34
|
+
*/
|
|
20
35
|
export declare function peek(store: Store, cfg: ResolvedConfig, pathArg: string, overrides?: SearchOverrides): Promise<Peek>;
|
|
@@ -3,7 +3,8 @@ import { estimateTokens } from '../chunk/index.js';
|
|
|
3
3
|
import { featureEnabled } from '../config/index.js';
|
|
4
4
|
import { SenseError } from '../errors.js';
|
|
5
5
|
import { serialQuery } from '../lib/serial-query.js';
|
|
6
|
-
import { INTERNAL_COLUMNS, scopedPaths } from './scope.js';
|
|
6
|
+
import { INTERNAL_COLUMNS, materializeScope, scopedPaths } from './scope.js';
|
|
7
|
+
import { assertQuerySnapshot } from './snapshot.js';
|
|
7
8
|
// Note resolution shared by peek and path: an exact path, or a unique basename (case
|
|
8
9
|
// insensitive, .md stripped).
|
|
9
10
|
export function resolveNote(paths, arg) {
|
|
@@ -16,18 +17,43 @@ export function resolveNote(paths, arg) {
|
|
|
16
17
|
throw new SenseError('NOTE_NOT_FOUND', `no note matches "${arg}"`);
|
|
17
18
|
}
|
|
18
19
|
const PEEK_LIST_LIMIT = 20;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Returns indexed metadata for a note in scope. Exact excluded paths fail before scoped basename
|
|
22
|
+
* resolution; resolved neighbors stay in scope, while unresolved written targets remain visible.
|
|
23
|
+
*/ export function peek(store, cfg, pathArg, overrides = {}) {
|
|
22
24
|
return serialQuery(store, ()=>peekIndexed(store, cfg, pathArg, overrides));
|
|
23
25
|
}
|
|
24
26
|
async function peekIndexed(store, cfg, pathArg, overrides) {
|
|
25
27
|
return store.transaction(async ()=>{
|
|
26
28
|
var _row__parse_error, _row__size;
|
|
27
29
|
var _this;
|
|
30
|
+
await assertQuerySnapshot(store, cfg);
|
|
28
31
|
const pathsStmt = await store.prepare('SELECT "path" FROM frontmatter');
|
|
29
32
|
const paths = (await pathsStmt.all()).map((r)=>r.path);
|
|
30
|
-
const
|
|
33
|
+
const allowed = await scopedPaths(store, cfg, overrides);
|
|
34
|
+
if (paths.includes(pathArg) && !allowed.has(pathArg)) {
|
|
35
|
+
throw new SenseError('NOTE_NOT_FOUND', `note "${pathArg}" exists but is outside the current scope; change the preset, include/exclude patterns, or where condition`);
|
|
36
|
+
}
|
|
37
|
+
let path;
|
|
38
|
+
try {
|
|
39
|
+
path = resolveNote([
|
|
40
|
+
...allowed
|
|
41
|
+
], pathArg);
|
|
42
|
+
} catch (err) {
|
|
43
|
+
if (err instanceof SenseError && err.code === 'NOTE_NOT_FOUND') {
|
|
44
|
+
let excludedPath;
|
|
45
|
+
try {
|
|
46
|
+
excludedPath = resolveNote(paths, pathArg);
|
|
47
|
+
} catch (unscopedErr) {
|
|
48
|
+
if (unscopedErr instanceof SenseError && unscopedErr.code === 'NOTE_AMBIGUOUS') {
|
|
49
|
+
throw new SenseError('NOTE_NOT_FOUND', `no note in the current scope matches "${pathArg}"; indexed matches exist outside the scope, so change the preset, include/exclude patterns, or where condition`);
|
|
50
|
+
}
|
|
51
|
+
throw err;
|
|
52
|
+
}
|
|
53
|
+
throw new SenseError('NOTE_NOT_FOUND', `note "${excludedPath}" exists but is outside the current scope; change the preset, include/exclude patterns, or where condition`);
|
|
54
|
+
}
|
|
55
|
+
throw err;
|
|
56
|
+
}
|
|
31
57
|
const rowStmt = await store.prepare('SELECT * FROM frontmatter WHERE "path" = ?');
|
|
32
58
|
const row = await rowStmt.get(path);
|
|
33
59
|
const parseError = (_row__parse_error = row._parse_error) !== null && _row__parse_error !== void 0 ? _row__parse_error : null;
|
|
@@ -45,15 +71,15 @@ async function peekIndexed(store, cfg, pathArg, overrides) {
|
|
|
45
71
|
let backlinks = [];
|
|
46
72
|
let unresolved = [];
|
|
47
73
|
let backlinksTotal = 0;
|
|
48
|
-
await scopedPaths(store, cfg, overrides); // validates --preset/--where/--include/--exclude even though peek's own output isn't scope-filtered
|
|
49
74
|
if (featureEnabled(cfg, 'links')) {
|
|
50
|
-
|
|
75
|
+
await materializeScope(store, '_peek_scope', allowed);
|
|
76
|
+
const out = await (await store.prepare('SELECT target, dst FROM links WHERE src = ? AND (dst IS NULL OR (dst != src AND dst IN (SELECT "path" FROM _peek_scope))) ORDER BY target')).all(path);
|
|
51
77
|
outbound = [
|
|
52
78
|
...new Set(out.filter((l)=>l.dst !== null).map((l)=>l.dst))
|
|
53
79
|
];
|
|
54
80
|
unresolved = out.filter((l)=>l.dst === null).map((l)=>l.target);
|
|
55
|
-
backlinksTotal = (await (await store.prepare('SELECT COUNT(DISTINCT src) AS n FROM links WHERE dst = ? AND src != dst')).get(path)).n;
|
|
56
|
-
backlinks = (await (await store.prepare('SELECT DISTINCT src FROM links WHERE dst = ? AND src != dst ORDER BY src LIMIT ?')).all(path, PEEK_LIST_LIMIT)).map((r)=>r.src);
|
|
81
|
+
backlinksTotal = (await (await store.prepare('SELECT COUNT(DISTINCT src) AS n FROM links WHERE dst = ? AND src != dst AND src IN (SELECT "path" FROM _peek_scope)')).get(path)).n;
|
|
82
|
+
backlinks = (await (await store.prepare('SELECT DISTINCT src FROM links WHERE dst = ? AND src != dst AND src IN (SELECT "path" FROM _peek_scope) ORDER BY src LIMIT ?')).all(path, PEEK_LIST_LIMIT)).map((r)=>r.src);
|
|
57
83
|
}
|
|
58
84
|
// content.text is the stripped body already computed at reconcile time (no extra file read),
|
|
59
85
|
// floored by the byte/4 estimate so stripped-away syntax and frontmatter can't vanish from the price.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/peek.ts"],"sourcesContent":["import posix from 'node:path/posix';\nimport { estimateTokens } from '../chunk/index.ts';\nimport type { FeatureName, ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { featureEnabled } from '../config/index.ts';\nimport { SenseError } from '../errors.ts';\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type { Row } from '../output/output.ts';\nimport type { Store } from '../store/types.ts';\nimport { INTERNAL_COLUMNS, scopedPaths } from './scope.ts';\n\n// Note resolution shared by peek and path: an exact path, or a unique basename (case\n// insensitive, .md stripped).\nexport function resolveNote(paths: string[], arg: string): string {\n const exact = paths.find((p) => p === arg);\n if (exact) return exact;\n const base = posix.basename(arg).replace(/\\.md$/i, '').toLowerCase();\n const matches = paths.filter((p) => posix.basename(p).replace(/\\.md$/i, '').toLowerCase() === base);\n if (matches.length === 1) return matches[0];\n if (matches.length > 1) throw new SenseError('NOTE_AMBIGUOUS', `\"${arg}\" is ambiguous: ${matches.join(', ')}`);\n throw new SenseError('NOTE_NOT_FOUND', `no note matches \"${arg}\"`);\n}\n\nexport interface Peek {\n path: string;\n tokens: number;\n frontmatter: Row;\n // Set when the note's frontmatter was refused, so an empty frontmatter block reads as \"did\n // not parse\" rather than \"has none\". Same reason `_parse_error` sits in the row.\n parseError: string | null;\n sections: Row[];\n outbound: string[];\n backlinks: string[];\n unresolved: string[];\n // Totals before truncation: a hub can have thousands of backlinks (or a note thousands of\n // headings), and peek's whole point is bounded output.\n sectionsTotal: number;\n outboundTotal: number;\n backlinksTotal: number;\n unresolvedTotal: number;\n // Bounded k-hop expansion beyond the immediate ring already shown by outbound/backlinks\n // (depth starts at 2).\n off: FeatureName[]; // disabled features whose blocks are omitted (not empty)\n}\n\nconst PEEK_LIST_LIMIT = 20;\n\n// peek: everything about one note except its prose -- frontmatter, outline with line\n// ranges + token estimates (so the follow-up Read is a range, not the file), links both ways.\nexport function peek(store: Store, cfg: ResolvedConfig, pathArg: string, overrides: SearchOverrides = {}): Promise<Peek> {\n return serialQuery(store, () => peekIndexed(store, cfg, pathArg, overrides));\n}\n\nasync function peekIndexed(store: Store, cfg: ResolvedConfig, pathArg: string, overrides: SearchOverrides): Promise<Peek> {\n return store.transaction(async () => {\n const pathsStmt = await store.prepare('SELECT \"path\" FROM frontmatter');\n const paths = ((await pathsStmt.all()) as Array<{ path: string }>).map((r) => r.path);\n const path = resolveNote(paths, pathArg);\n\n const rowStmt = await store.prepare('SELECT * FROM frontmatter WHERE \"path\" = ?');\n const row = (await rowStmt.get(path)) as Row;\n const parseError = (row._parse_error as string | null) ?? null;\n const frontmatter: Row = {};\n for (const [key, value] of Object.entries(row)) {\n if (!INTERNAL_COLUMNS.has(key) && value !== null) frontmatter[key] = value;\n }\n\n let sectionsTotal = 0;\n let sections: Row[] = [];\n if (featureEnabled(cfg, 'sections')) {\n sectionsTotal = ((await (await store.prepare('SELECT COUNT(*) AS n FROM sections WHERE \"path\" = ?')).get(path)) as { n: number }).n;\n sections = (await (await store.prepare('SELECT level, heading, start_line, end_line, tokens FROM sections WHERE \"path\" = ? ORDER BY idx LIMIT ?')).all(path, PEEK_LIST_LIMIT)) as Row[];\n }\n\n let outbound: string[] = [];\n let backlinks: string[] = [];\n let unresolved: string[] = [];\n let backlinksTotal = 0;\n await scopedPaths(store, cfg, overrides); // validates --preset/--where/--include/--exclude even though peek's own output isn't scope-filtered\n if (featureEnabled(cfg, 'links')) {\n const out = (await (await store.prepare('SELECT target, dst FROM links WHERE src = ? AND (dst IS NULL OR dst != src) ORDER BY target')).all(path)) as Array<{ target: string; dst: string | null }>;\n outbound = [...new Set(out.filter((l) => l.dst !== null).map((l) => l.dst as string))];\n unresolved = out.filter((l) => l.dst === null).map((l) => l.target);\n backlinksTotal = ((await (await store.prepare('SELECT COUNT(DISTINCT src) AS n FROM links WHERE dst = ? AND src != dst')).get(path)) as { n: number }).n;\n backlinks = ((await (await store.prepare('SELECT DISTINCT src FROM links WHERE dst = ? AND src != dst ORDER BY src LIMIT ?')).all(path, PEEK_LIST_LIMIT)) as Array<{ src: string }>).map((r) => r.src);\n }\n\n // content.text is the stripped body already computed at reconcile time (no extra file read),\n // floored by the byte/4 estimate so stripped-away syntax and frontmatter can't vanish from the price.\n const body = ((await (await store.prepare('SELECT text FROM content WHERE \"path\" = ?')).get(path)) as { text: string } | undefined)?.text;\n const byteTokens = Math.ceil(((row._size as number) ?? 0) / 4);\n const tokens = body !== undefined ? Math.max(Math.ceil(estimateTokens(body)), byteTokens) : byteTokens;\n\n return {\n path,\n tokens,\n frontmatter,\n parseError,\n sections,\n outbound: outbound.slice(0, PEEK_LIST_LIMIT),\n backlinks,\n unresolved: unresolved.slice(0, PEEK_LIST_LIMIT),\n sectionsTotal,\n outboundTotal: outbound.length,\n backlinksTotal,\n unresolvedTotal: unresolved.length,\n off: (['sections', 'links'] as FeatureName[]).filter((name) => !featureEnabled(cfg, name)),\n };\n });\n}\n"],"names":["posix","estimateTokens","featureEnabled","SenseError","serialQuery","INTERNAL_COLUMNS","scopedPaths","resolveNote","paths","arg","exact","find","p","base","basename","replace","toLowerCase","matches","filter","length","join","PEEK_LIST_LIMIT","peek","store","cfg","pathArg","overrides","peekIndexed","transaction","row","pathsStmt","prepare","all","map","r","path","rowStmt","get","parseError","_parse_error","frontmatter","key","value","Object","entries","has","sectionsTotal","sections","n","outbound","backlinks","unresolved","backlinksTotal","out","Set","l","dst","target","src","body","text","byteTokens","Math","ceil","_size","tokens","undefined","max","slice","outboundTotal","unresolvedTotal","off","name"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/commands/peek.ts"],"sourcesContent":["import posix from 'node:path/posix';\nimport { estimateTokens } from '../chunk/index.ts';\nimport type { FeatureName, ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { featureEnabled } from '../config/index.ts';\nimport { SenseError } from '../errors.ts';\nimport { serialQuery } from '../lib/serial-query.ts';\nimport type { Row } from '../output/output.ts';\nimport type { Store } from '../store/types.ts';\nimport { INTERNAL_COLUMNS, materializeScope, scopedPaths } from './scope.ts';\nimport { assertQuerySnapshot } from './snapshot.ts';\n\n// Note resolution shared by peek and path: an exact path, or a unique basename (case\n// insensitive, .md stripped).\nexport function resolveNote(paths: string[], arg: string): string {\n const exact = paths.find((p) => p === arg);\n if (exact) return exact;\n const base = posix.basename(arg).replace(/\\.md$/i, '').toLowerCase();\n const matches = paths.filter((p) => posix.basename(p).replace(/\\.md$/i, '').toLowerCase() === base);\n if (matches.length === 1) return matches[0];\n if (matches.length > 1) throw new SenseError('NOTE_AMBIGUOUS', `\"${arg}\" is ambiguous: ${matches.join(', ')}`);\n throw new SenseError('NOTE_NOT_FOUND', `no note matches \"${arg}\"`);\n}\n\n/** Structured, bounded metadata returned by the root {@link peek} API. */\nexport interface Peek {\n path: string;\n tokens: number;\n frontmatter: Row;\n /** Set when frontmatter parsing failed, distinguishing that case from an empty block. */\n parseError: string | null;\n sections: PeekSection[];\n outbound: string[];\n backlinks: string[];\n unresolved: string[];\n /** Totals before each bounded list is truncated. */\n sectionsTotal: number;\n outboundTotal: number;\n backlinksTotal: number;\n unresolvedTotal: number;\n /** Disabled features whose result blocks are omitted rather than returned empty. */\n off: FeatureName[];\n}\n\nexport interface PeekSection {\n level: number;\n heading: string;\n start_line: number;\n end_line: number;\n tokens: number;\n}\n\nconst PEEK_LIST_LIMIT = 20;\n\n/**\n * Returns indexed metadata for a note in scope. Exact excluded paths fail before scoped basename\n * resolution; resolved neighbors stay in scope, while unresolved written targets remain visible.\n */\nexport function peek(store: Store, cfg: ResolvedConfig, pathArg: string, overrides: SearchOverrides = {}): Promise<Peek> {\n return serialQuery(store, () => peekIndexed(store, cfg, pathArg, overrides));\n}\n\nasync function peekIndexed(store: Store, cfg: ResolvedConfig, pathArg: string, overrides: SearchOverrides): Promise<Peek> {\n return store.transaction(async () => {\n await assertQuerySnapshot(store, cfg);\n const pathsStmt = await store.prepare('SELECT \"path\" FROM frontmatter');\n const paths = ((await pathsStmt.all()) as Array<{ path: string }>).map((r) => r.path);\n const allowed = await scopedPaths(store, cfg, overrides);\n if (paths.includes(pathArg) && !allowed.has(pathArg)) {\n throw new SenseError('NOTE_NOT_FOUND', `note \"${pathArg}\" exists but is outside the current scope; change the preset, include/exclude patterns, or where condition`);\n }\n let path: string;\n try {\n path = resolveNote([...allowed], pathArg);\n } catch (err) {\n if (err instanceof SenseError && err.code === 'NOTE_NOT_FOUND') {\n let excludedPath: string;\n try {\n excludedPath = resolveNote(paths, pathArg);\n } catch (unscopedErr) {\n if (unscopedErr instanceof SenseError && unscopedErr.code === 'NOTE_AMBIGUOUS') {\n throw new SenseError('NOTE_NOT_FOUND', `no note in the current scope matches \"${pathArg}\"; indexed matches exist outside the scope, so change the preset, include/exclude patterns, or where condition`);\n }\n throw err;\n }\n throw new SenseError('NOTE_NOT_FOUND', `note \"${excludedPath}\" exists but is outside the current scope; change the preset, include/exclude patterns, or where condition`);\n }\n throw err;\n }\n\n const rowStmt = await store.prepare('SELECT * FROM frontmatter WHERE \"path\" = ?');\n const row = (await rowStmt.get(path)) as Row;\n const parseError = (row._parse_error as string | null) ?? null;\n const frontmatter: Row = {};\n for (const [key, value] of Object.entries(row)) {\n if (!INTERNAL_COLUMNS.has(key) && value !== null) frontmatter[key] = value;\n }\n\n let sectionsTotal = 0;\n let sections: PeekSection[] = [];\n if (featureEnabled(cfg, 'sections')) {\n sectionsTotal = ((await (await store.prepare('SELECT COUNT(*) AS n FROM sections WHERE \"path\" = ?')).get(path)) as { n: number }).n;\n sections = (await (await store.prepare('SELECT level, heading, start_line, end_line, tokens FROM sections WHERE \"path\" = ? ORDER BY idx LIMIT ?')).all(path, PEEK_LIST_LIMIT)) as PeekSection[];\n }\n\n let outbound: string[] = [];\n let backlinks: string[] = [];\n let unresolved: string[] = [];\n let backlinksTotal = 0;\n if (featureEnabled(cfg, 'links')) {\n await materializeScope(store, '_peek_scope', allowed);\n const out = (await (await store.prepare('SELECT target, dst FROM links WHERE src = ? AND (dst IS NULL OR (dst != src AND dst IN (SELECT \"path\" FROM _peek_scope))) ORDER BY target')).all(path)) as Array<{ target: string; dst: string | null }>;\n outbound = [...new Set(out.filter((l): l is { target: string; dst: string } => l.dst !== null).map((l) => l.dst))];\n unresolved = out.filter((l) => l.dst === null).map((l) => l.target);\n backlinksTotal = ((await (await store.prepare('SELECT COUNT(DISTINCT src) AS n FROM links WHERE dst = ? AND src != dst AND src IN (SELECT \"path\" FROM _peek_scope)')).get(path)) as { n: number }).n;\n backlinks = ((await (await store.prepare('SELECT DISTINCT src FROM links WHERE dst = ? AND src != dst AND src IN (SELECT \"path\" FROM _peek_scope) ORDER BY src LIMIT ?')).all(path, PEEK_LIST_LIMIT)) as Array<{ src: string }>).map((r) => r.src);\n }\n\n // content.text is the stripped body already computed at reconcile time (no extra file read),\n // floored by the byte/4 estimate so stripped-away syntax and frontmatter can't vanish from the price.\n const body = ((await (await store.prepare('SELECT text FROM content WHERE \"path\" = ?')).get(path)) as { text: string } | undefined)?.text;\n const byteTokens = Math.ceil(((row._size as number) ?? 0) / 4);\n const tokens = body !== undefined ? Math.max(Math.ceil(estimateTokens(body)), byteTokens) : byteTokens;\n\n return {\n path,\n tokens,\n frontmatter,\n parseError,\n sections,\n outbound: outbound.slice(0, PEEK_LIST_LIMIT),\n backlinks,\n unresolved: unresolved.slice(0, PEEK_LIST_LIMIT),\n sectionsTotal,\n outboundTotal: outbound.length,\n backlinksTotal,\n unresolvedTotal: unresolved.length,\n off: (['sections', 'links'] as FeatureName[]).filter((name) => !featureEnabled(cfg, name)),\n };\n });\n}\n"],"names":["posix","estimateTokens","featureEnabled","SenseError","serialQuery","INTERNAL_COLUMNS","materializeScope","scopedPaths","assertQuerySnapshot","resolveNote","paths","arg","exact","find","p","base","basename","replace","toLowerCase","matches","filter","length","join","PEEK_LIST_LIMIT","peek","store","cfg","pathArg","overrides","peekIndexed","transaction","row","pathsStmt","prepare","all","map","r","path","allowed","includes","has","err","code","excludedPath","unscopedErr","rowStmt","get","parseError","_parse_error","frontmatter","key","value","Object","entries","sectionsTotal","sections","n","outbound","backlinks","unresolved","backlinksTotal","out","Set","l","dst","target","src","body","text","byteTokens","Math","ceil","_size","tokens","undefined","max","slice","outboundTotal","unresolvedTotal","off","name"],"mappings":"AAAA,OAAOA,WAAW,kBAAkB;AACpC,SAASC,cAAc,QAAQ,oBAAoB;AAEnD,SAASC,cAAc,QAAQ,qBAAqB;AACpD,SAASC,UAAU,QAAQ,eAAe;AAC1C,SAASC,WAAW,QAAQ,yBAAyB;AAGrD,SAASC,gBAAgB,EAAEC,gBAAgB,EAAEC,WAAW,QAAQ,aAAa;AAC7E,SAASC,mBAAmB,QAAQ,gBAAgB;AAEpD,qFAAqF;AACrF,8BAA8B;AAC9B,OAAO,SAASC,YAAYC,KAAe,EAAEC,GAAW;IACtD,MAAMC,QAAQF,MAAMG,IAAI,CAAC,CAACC,IAAMA,MAAMH;IACtC,IAAIC,OAAO,OAAOA;IAClB,MAAMG,OAAOf,MAAMgB,QAAQ,CAACL,KAAKM,OAAO,CAAC,UAAU,IAAIC,WAAW;IAClE,MAAMC,UAAUT,MAAMU,MAAM,CAAC,CAACN,IAAMd,MAAMgB,QAAQ,CAACF,GAAGG,OAAO,CAAC,UAAU,IAAIC,WAAW,OAAOH;IAC9F,IAAII,QAAQE,MAAM,KAAK,GAAG,OAAOF,OAAO,CAAC,EAAE;IAC3C,IAAIA,QAAQE,MAAM,GAAG,GAAG,MAAM,IAAIlB,WAAW,kBAAkB,CAAC,CAAC,EAAEQ,IAAI,gBAAgB,EAAEQ,QAAQG,IAAI,CAAC,OAAO;IAC7G,MAAM,IAAInB,WAAW,kBAAkB,CAAC,iBAAiB,EAAEQ,IAAI,CAAC,CAAC;AACnE;AA8BA,MAAMY,kBAAkB;AAExB;;;CAGC,GACD,OAAO,SAASC,KAAKC,KAAY,EAAEC,GAAmB,EAAEC,OAAe,EAAEC,YAA6B,CAAC,CAAC;IACtG,OAAOxB,YAAYqB,OAAO,IAAMI,YAAYJ,OAAOC,KAAKC,SAASC;AACnE;AAEA,eAAeC,YAAYJ,KAAY,EAAEC,GAAmB,EAAEC,OAAe,EAAEC,SAA0B;IACvG,OAAOH,MAAMK,WAAW,CAAC;YA6BHC,mBA6BWA;YADhB;QAxDf,MAAMvB,oBAAoBiB,OAAOC;QACjC,MAAMM,YAAY,MAAMP,MAAMQ,OAAO,CAAC;QACtC,MAAMvB,QAAQ,AAAE,CAAA,MAAMsB,UAAUE,GAAG,EAAC,EAA+BC,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI;QACpF,MAAMC,UAAU,MAAM/B,YAAYkB,OAAOC,KAAKE;QAC9C,IAAIlB,MAAM6B,QAAQ,CAACZ,YAAY,CAACW,QAAQE,GAAG,CAACb,UAAU;YACpD,MAAM,IAAIxB,WAAW,kBAAkB,CAAC,MAAM,EAAEwB,QAAQ,0GAA0G,CAAC;QACrK;QACA,IAAIU;QACJ,IAAI;YACFA,OAAO5B,YAAY;mBAAI6B;aAAQ,EAAEX;QACnC,EAAE,OAAOc,KAAK;YACZ,IAAIA,eAAetC,cAAcsC,IAAIC,IAAI,KAAK,kBAAkB;gBAC9D,IAAIC;gBACJ,IAAI;oBACFA,eAAelC,YAAYC,OAAOiB;gBACpC,EAAE,OAAOiB,aAAa;oBACpB,IAAIA,uBAAuBzC,cAAcyC,YAAYF,IAAI,KAAK,kBAAkB;wBAC9E,MAAM,IAAIvC,WAAW,kBAAkB,CAAC,sCAAsC,EAAEwB,QAAQ,8GAA8G,CAAC;oBACzM;oBACA,MAAMc;gBACR;gBACA,MAAM,IAAItC,WAAW,kBAAkB,CAAC,MAAM,EAAEwC,aAAa,0GAA0G,CAAC;YAC1K;YACA,MAAMF;QACR;QAEA,MAAMI,UAAU,MAAMpB,MAAMQ,OAAO,CAAC;QACpC,MAAMF,MAAO,MAAMc,QAAQC,GAAG,CAACT;QAC/B,MAAMU,cAAchB,oBAAAA,IAAIiB,YAAY,cAAhBjB,+BAAAA,oBAAsC;QAC1D,MAAMkB,cAAmB,CAAC;QAC1B,KAAK,MAAM,CAACC,KAAKC,MAAM,IAAIC,OAAOC,OAAO,CAACtB,KAAM;YAC9C,IAAI,CAAC1B,iBAAiBmC,GAAG,CAACU,QAAQC,UAAU,MAAMF,WAAW,CAACC,IAAI,GAAGC;QACvE;QAEA,IAAIG,gBAAgB;QACpB,IAAIC,WAA0B,EAAE;QAChC,IAAIrD,eAAewB,KAAK,aAAa;YACnC4B,gBAAgB,AAAE,CAAA,MAAM,AAAC,CAAA,MAAM7B,MAAMQ,OAAO,CAAC,sDAAqD,EAAGa,GAAG,CAACT,KAAI,EAAqBmB,CAAC;YACnID,WAAY,MAAM,AAAC,CAAA,MAAM9B,MAAMQ,OAAO,CAAC,0GAAyG,EAAGC,GAAG,CAACG,MAAMd;QAC/J;QAEA,IAAIkC,WAAqB,EAAE;QAC3B,IAAIC,YAAsB,EAAE;QAC5B,IAAIC,aAAuB,EAAE;QAC7B,IAAIC,iBAAiB;QACrB,IAAI1D,eAAewB,KAAK,UAAU;YAChC,MAAMpB,iBAAiBmB,OAAO,eAAea;YAC7C,MAAMuB,MAAO,MAAM,AAAC,CAAA,MAAMpC,MAAMQ,OAAO,CAAC,4IAA2I,EAAGC,GAAG,CAACG;YAC1LoB,WAAW;mBAAI,IAAIK,IAAID,IAAIzC,MAAM,CAAC,CAAC2C,IAA4CA,EAAEC,GAAG,KAAK,MAAM7B,GAAG,CAAC,CAAC4B,IAAMA,EAAEC,GAAG;aAAG;YAClHL,aAAaE,IAAIzC,MAAM,CAAC,CAAC2C,IAAMA,EAAEC,GAAG,KAAK,MAAM7B,GAAG,CAAC,CAAC4B,IAAMA,EAAEE,MAAM;YAClEL,iBAAiB,AAAE,CAAA,MAAM,AAAC,CAAA,MAAMnC,MAAMQ,OAAO,CAAC,sHAAqH,EAAGa,GAAG,CAACT,KAAI,EAAqBmB,CAAC;YACpME,YAAY,AAAE,CAAA,MAAM,AAAC,CAAA,MAAMjC,MAAMQ,OAAO,CAAC,+HAA8H,EAAGC,GAAG,CAACG,MAAMd,gBAAe,EAA8BY,GAAG,CAAC,CAACC,IAAMA,EAAE8B,GAAG;QACnP;QAEA,6FAA6F;QAC7F,sGAAsG;QACtG,MAAMC,QAAS,QAAA,MAAM,AAAC,CAAA,MAAM1C,MAAMQ,OAAO,CAAC,4CAA2C,EAAGa,GAAG,CAACT,mBAA7E,4BAAF,AAAE,MAAsH+B,IAAI;QACzI,MAAMC,aAAaC,KAAKC,IAAI,CAAC,EAAExC,aAAAA,IAAIyC,KAAK,cAATzC,wBAAAA,aAAwB,KAAK;QAC5D,MAAM0C,SAASN,SAASO,YAAYJ,KAAKK,GAAG,CAACL,KAAKC,IAAI,CAACtE,eAAekE,QAAQE,cAAcA;QAE5F,OAAO;YACLhC;YACAoC;YACAxB;YACAF;YACAQ;YACAE,UAAUA,SAASmB,KAAK,CAAC,GAAGrD;YAC5BmC;YACAC,YAAYA,WAAWiB,KAAK,CAAC,GAAGrD;YAChC+B;YACAuB,eAAepB,SAASpC,MAAM;YAC9BuC;YACAkB,iBAAiBnB,WAAWtC,MAAM;YAClC0D,KAAK,AAAC;gBAAC;gBAAY;aAAQ,CAAmB3D,MAAM,CAAC,CAAC4D,OAAS,CAAC9E,eAAewB,KAAKsD;QACtF;IACF;AACF"}
|
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import type { ResolvedConfig, SearchOverrides } from '../config/index.js';
|
|
2
2
|
import type { Store } from '../store/types.js';
|
|
3
|
-
export declare
|
|
4
|
-
|
|
3
|
+
export declare const RELATED_DEFAULT_K = 5;
|
|
4
|
+
/**
|
|
5
|
+
* Options for {@link relatedNotes}. Scope fields filter result candidates, not the seed note;
|
|
6
|
+
* `k` defaults to 5, matching the CLI.
|
|
7
|
+
*/
|
|
8
|
+
export interface RelatedOptions extends SearchOverrides {
|
|
9
|
+
k?: number;
|
|
10
|
+
}
|
|
11
|
+
export type RelatedResult = {
|
|
5
12
|
path: string;
|
|
6
13
|
similarity: number;
|
|
7
|
-
}
|
|
14
|
+
};
|
|
15
|
+
export declare function resolveRelatedSeed(store: Store, pathArg: string): Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Returns the notes most similar to an indexed seed, excluding the seed and notes linked either
|
|
18
|
+
* way. The seed resolves across the indexed tree even when it is outside the candidate scope.
|
|
19
|
+
*/
|
|
20
|
+
export declare function relatedNotes(store: Store, cfg: ResolvedConfig, pathArg: string, options?: RelatedOptions): Promise<RelatedResult[]>;
|