sensemaking 0.23.1 → 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 +15 -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/named.js +6 -2
- package/dist/cjs/cli/named.js.map +1 -1
- package/dist/cjs/cli/search.js +6 -2
- package/dist/cjs/cli/search.js.map +1 -1
- package/dist/cjs/cli/shared.d.cts +2 -0
- package/dist/cjs/cli/shared.d.ts +2 -0
- package/dist/cjs/cli/shared.js +24 -0
- package/dist/cjs/cli/shared.js.map +1 -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/map.js +2 -2
- package/dist/cjs/commands/map.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.d.cts +10 -0
- package/dist/cjs/commands/search.d.ts +10 -0
- package/dist/cjs/commands/search.js +489 -180
- 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/output/output.js +45 -8
- package/dist/cjs/output/output.js.map +1 -1
- package/dist/cjs/output/search-error.d.cts +1 -0
- package/dist/cjs/output/search-error.d.ts +1 -0
- package/dist/cjs/output/search-error.js +28 -4
- package/dist/cjs/output/search-error.js.map +1 -1
- package/dist/cjs/scan/frontmatter.js +1 -1
- package/dist/cjs/scan/frontmatter.js.map +1 -1
- package/dist/cjs/scan/index.js +1 -0
- package/dist/cjs/scan/index.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/duckdb/fieldStats.js +4 -7
- package/dist/cjs/store/duckdb/fieldStats.js.map +1 -1
- package/dist/cjs/store/duckdb/lexical.d.cts +2 -2
- package/dist/cjs/store/duckdb/lexical.d.ts +2 -2
- package/dist/cjs/store/duckdb/lexical.js +215 -64
- package/dist/cjs/store/duckdb/lexical.js.map +1 -1
- package/dist/cjs/store/duckdb/reconcile.js +7 -2
- package/dist/cjs/store/duckdb/reconcile.js.map +1 -1
- package/dist/cjs/store/duckdb/store.js +1 -3
- package/dist/cjs/store/duckdb/store.js.map +1 -1
- package/dist/cjs/store/duckdb/vectors.js +13 -8
- package/dist/cjs/store/duckdb/vectors.js.map +1 -1
- package/dist/cjs/store/native.js +5 -4
- package/dist/cjs/store/native.js.map +1 -1
- package/dist/cjs/store/open.js +20 -6
- package/dist/cjs/store/open.js.map +1 -1
- package/dist/cjs/store/shared.js.map +1 -1
- package/dist/cjs/store/sqlite/lexical.js +1 -4
- package/dist/cjs/store/sqlite/lexical.js.map +1 -1
- package/dist/cjs/store/sqlite/store.js +1 -4
- package/dist/cjs/store/sqlite/store.js.map +1 -1
- package/dist/cjs/store/sqlite/vectors.js +78 -24
- package/dist/cjs/store/sqlite/vectors.js.map +1 -1
- package/dist/cjs/store/turso/connection.js +2 -1
- package/dist/cjs/store/turso/connection.js.map +1 -1
- package/dist/cjs/store/turso/lexical-text.d.cts +1 -0
- package/dist/cjs/store/turso/lexical-text.d.ts +1 -0
- package/dist/cjs/store/turso/lexical-text.js +40 -0
- package/dist/cjs/store/turso/lexical-text.js.map +1 -0
- package/dist/cjs/store/turso/lexical.js +89 -16
- package/dist/cjs/store/turso/lexical.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 +2 -2
- package/dist/cjs/store/turso/open.js.map +1 -1
- package/dist/cjs/store/turso/reconcile.d.cts +1 -1
- package/dist/cjs/store/turso/reconcile.d.ts +1 -1
- package/dist/cjs/store/turso/reconcile.js +6 -2
- package/dist/cjs/store/turso/reconcile.js.map +1 -1
- package/dist/cjs/store/turso/sql-functions.d.cts +1 -0
- package/dist/cjs/store/turso/sql-functions.d.ts +1 -0
- package/dist/cjs/store/turso/sql-functions.js +174 -0
- package/dist/cjs/store/turso/sql-functions.js.map +1 -0
- package/dist/cjs/store/turso/store.js +2 -3
- package/dist/cjs/store/turso/store.js.map +1 -1
- package/dist/cjs/store/turso/vectors.js +50 -14
- package/dist/cjs/store/turso/vectors.js.map +1 -1
- package/dist/cjs/store/types.d.cts +1 -2
- package/dist/cjs/store/types.d.ts +1 -2
- package/dist/cjs/store/types.js +1 -4
- package/dist/cjs/store/types.js.map +1 -1
- package/dist/cjs/store/vectors.d.cts +7 -0
- package/dist/cjs/store/vectors.d.ts +7 -0
- package/dist/cjs/store/vectors.js +8 -0
- package/dist/cjs/store/vectors.js.map +1 -1
- package/dist/cjs/text/segment.d.cts +13 -0
- package/dist/cjs/text/segment.d.ts +13 -0
- package/dist/cjs/text/segment.js +109 -4
- package/dist/cjs/text/segment.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/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/named.js +6 -2
- package/dist/esm/cli/named.js.map +1 -1
- package/dist/esm/cli/search.js +5 -1
- package/dist/esm/cli/search.js.map +1 -1
- package/dist/esm/cli/shared.d.ts +2 -0
- package/dist/esm/cli/shared.js +19 -0
- package/dist/esm/cli/shared.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/map.js +2 -2
- package/dist/esm/commands/map.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.d.ts +10 -0
- package/dist/esm/commands/search.js +272 -91
- 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/output/output.js +27 -4
- package/dist/esm/output/output.js.map +1 -1
- package/dist/esm/output/search-error.d.ts +1 -0
- package/dist/esm/output/search-error.js +17 -1
- package/dist/esm/output/search-error.js.map +1 -1
- package/dist/esm/scan/frontmatter.js +1 -1
- package/dist/esm/scan/frontmatter.js.map +1 -1
- package/dist/esm/scan/index.js +1 -0
- package/dist/esm/scan/index.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/duckdb/fieldStats.js +4 -7
- package/dist/esm/store/duckdb/fieldStats.js.map +1 -1
- package/dist/esm/store/duckdb/lexical.d.ts +2 -2
- package/dist/esm/store/duckdb/lexical.js +94 -40
- package/dist/esm/store/duckdb/lexical.js.map +1 -1
- package/dist/esm/store/duckdb/reconcile.js +2 -2
- package/dist/esm/store/duckdb/reconcile.js.map +1 -1
- package/dist/esm/store/duckdb/store.js +2 -4
- package/dist/esm/store/duckdb/store.js.map +1 -1
- package/dist/esm/store/duckdb/vectors.js +26 -13
- package/dist/esm/store/duckdb/vectors.js.map +1 -1
- package/dist/esm/store/native.js +5 -4
- package/dist/esm/store/native.js.map +1 -1
- package/dist/esm/store/open.js +21 -4
- package/dist/esm/store/open.js.map +1 -1
- package/dist/esm/store/shared.js +1 -2
- package/dist/esm/store/shared.js.map +1 -1
- package/dist/esm/store/sqlite/lexical.js +2 -5
- package/dist/esm/store/sqlite/lexical.js.map +1 -1
- package/dist/esm/store/sqlite/store.js +1 -4
- package/dist/esm/store/sqlite/store.js.map +1 -1
- package/dist/esm/store/sqlite/vectors.js +48 -19
- package/dist/esm/store/sqlite/vectors.js.map +1 -1
- package/dist/esm/store/turso/connection.js +3 -2
- package/dist/esm/store/turso/connection.js.map +1 -1
- package/dist/esm/store/turso/lexical-text.d.ts +1 -0
- package/dist/esm/store/turso/lexical-text.js +12 -0
- package/dist/esm/store/turso/lexical-text.js.map +1 -0
- package/dist/esm/store/turso/lexical.js +56 -21
- package/dist/esm/store/turso/lexical.js.map +1 -1
- package/dist/esm/store/turso/open.d.ts +1 -1
- package/dist/esm/store/turso/open.js +2 -2
- package/dist/esm/store/turso/open.js.map +1 -1
- package/dist/esm/store/turso/reconcile.d.ts +1 -1
- package/dist/esm/store/turso/reconcile.js +6 -2
- package/dist/esm/store/turso/reconcile.js.map +1 -1
- package/dist/esm/store/turso/sql-functions.d.ts +1 -0
- package/dist/esm/store/turso/sql-functions.js +179 -0
- package/dist/esm/store/turso/sql-functions.js.map +1 -0
- package/dist/esm/store/turso/store.js +3 -5
- package/dist/esm/store/turso/store.js.map +1 -1
- package/dist/esm/store/turso/vectors.js +19 -10
- package/dist/esm/store/turso/vectors.js.map +1 -1
- package/dist/esm/store/types.d.ts +1 -2
- package/dist/esm/store/types.js +6 -8
- package/dist/esm/store/types.js.map +1 -1
- package/dist/esm/store/vectors.d.ts +7 -0
- package/dist/esm/store/vectors.js +8 -2
- package/dist/esm/store/vectors.js.map +1 -1
- package/dist/esm/text/segment.d.ts +13 -0
- package/dist/esm/text/segment.js +70 -0
- package/dist/esm/text/segment.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 +4 -3
- package/schema.json +7 -2
- package/skills/sense/EXAMPLES.md +3 -3
- package/skills/sense/SKILL.md +6 -6
- package/skills/sense-setup/EXAMPLES.md +21 -0
- package/skills/sense-setup/SKILL.md +3 -3
package/README.md
CHANGED
|
@@ -38,13 +38,13 @@ Every file becomes rows in these tables, plus whatever an enabled feature adds o
|
|
|
38
38
|
| `sections` | heading, `level`, `start_line`, `end_line`, `tokens` estimate | structure |
|
|
39
39
|
| `preset_files` | `path`, `preset` | which presets cover which files; `sql --preset` binds these as a `scope` table to join, since `sql` is otherwise index-wide |
|
|
40
40
|
|
|
41
|
-
Results are references (path, title, summary,
|
|
41
|
+
Results are references (path, title, summary, snippets), never file contents. Reading happens afterward through the filesystem, scoped to the line ranges `peek` returns. This is the [just-in-time context pattern](https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents): the agent holds lightweight identifiers and loads payloads only when needed.
|
|
42
42
|
|
|
43
43
|
Output size is a contract, measured per release ([BENCHMARKING.md](BENCHMARKING.md)): `map` is fixed-size, a `search` row is tens of tokens, and a `peek` stays flat however large the note is. What it saves over reading grows with the file; a small note is cheaper to read whole.
|
|
44
44
|
|
|
45
45
|
```sql
|
|
46
46
|
-- filter and search compose in one query
|
|
47
|
-
SELECT f.path, content.title, snippet(content, -1, '«', '»', '…', 10) AS
|
|
47
|
+
SELECT f.path, content.title, snippet(content, -1, '«', '»', '…', 10) AS snippet
|
|
48
48
|
FROM frontmatter f JOIN content ON content.path = f.path
|
|
49
49
|
WHERE f.status = 'active' AND content MATCH 'revenue'
|
|
50
50
|
ORDER BY bm25(content, 10.0, 5.0, 1.0) LIMIT 10
|
|
@@ -54,8 +54,8 @@ ORDER BY bm25(content, 10.0, 5.0, 1.0) LIMIT 10
|
|
|
54
54
|
|
|
55
55
|
| command | does |
|
|
56
56
|
|---|---|
|
|
57
|
-
| `map` | doc count, frontmatter field coverage, top hubs by link rank, recent changes |
|
|
58
|
-
| `search "<text>" [--preset name] [--include glob] [--exclude glob] [--no-exclude] [--where "<sql>"] [--k n]` | words + links + vectors, one fused ranked list; `via` labels each row's evidence |
|
|
57
|
+
| `map` | doc count, frontmatter field coverage, top hubs by link rank, recent changes; hub/recent limits use bytewise path order on ties |
|
|
58
|
+
| `search "<text>" [--preset name] [--include glob] [--exclude glob] [--no-exclude] [--where "<sql>"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n]` | words + links + vectors, one fused ranked list; `via` labels each row's evidence. `--k` bounds notes returned, `--snippet-char-limit` (default 80) each passage, `--snippet-count-limit` (default 1) passages per note |
|
|
59
59
|
| `peek <path> [--preset name] [--where "<sql>"]` | frontmatter + heading outline (`[L143-162, ~380t]`) + links both ways (first 20 per list, each with its total) |
|
|
60
60
|
| `path <a> <b> [--max-depth n] [--preset name] [--where "<sql>"]` | shortest link chain between two notes, or none within the bound |
|
|
61
61
|
| `related <note> [--k n] [--preset name] [--where "<sql>"]` | notes similar in meaning that `<note>` does not yet link to; reads vectors, so semantic-search cost |
|
|
@@ -64,13 +64,17 @@ ORDER BY bm25(content, 10.0, 5.0, 1.0) LIMIT 10
|
|
|
64
64
|
| `init` | write a starter `sense.config.json` |
|
|
65
65
|
| `status` | index location, doc count, per-preset coverage, watcher heartbeat |
|
|
66
66
|
| `download` | fetch the embedding model named in the config (once per machine; the first vector search fetches it otherwise) |
|
|
67
|
-
| `watch` | keep the index warm in the background (optional; see [
|
|
67
|
+
| `watch` | keep the index warm in the background (optional; see [DESIGN.md](DESIGN.md#watch-coordination)) |
|
|
68
68
|
|
|
69
|
-
`search` runs one text through every engine its scope has: FTS5 word match (BM25-ranked, bare words AND-join, operators are yours on `sqlite`; on `duckdb` and `turso` the FTS5 operators are a named error, see Config), a personalized-PageRank walk over the link graph, and vector similarity, fused into one list. `via` labels each row's evidence (`match`, `link`, `vector`, combinations);
|
|
69
|
+
`search` runs one text through every engine its scope has: FTS5 word match (BM25-ranked, bare words AND-join, operators are yours on `sqlite`; on `duckdb` and `turso` the FTS5 operators are a named error, see Config), a personalized-PageRank walk over the link graph, and vector similarity, fused into one list. `via` labels each row's evidence (`match`, `link`, `vector`, combinations); results rank by the true cosine against the best-matching canonical chunk before `similarity` is rounded to three decimals for display; a zero-direction vector has similarity `0`, exact cosine ties use bytewise path order, and equal-scoring chunks choose the earliest authored chunk. `lines` points at the section that earned the row (a direct read range). A `vector`-only row means the search words don't appear in that note; it showed up because the model judged it semantically related. `--preset` picks a named settings bundle from the config, `--where` filters on frontmatter. `--format json` on any reporting command returns structured output, and `--format csv` writes the row-returning commands one row per line, for redirecting a large result to a file instead of into context; `--version` and `--help` do what they say.
|
|
70
|
+
|
|
71
|
+
Search rows carry `snippets: string[]`. Each passage is generated around the matched words, marked with `«»`, and limited to 80 characters by default. `--snippet-count-limit` returns more non-overlapping passages from a note, in document order. Link- and vector-only rows have `snippets: []`.
|
|
72
|
+
|
|
73
|
+
Lexical words are case- and accent-insensitive. SQLite and DuckDB use their native English stem tokenizers; Turso's native Tantivy index has no stem tokenizer in the supported release, so it applies the shared Porter normalization to a derived field before native indexing. In every store, `run`, `running`, and `runs` match the same authored notes, while authored bytes are never rewritten. Quoted phrases require adjacent words, with punctuation treated as a separator, and punctuation-only input returns no lexical rows.
|
|
70
74
|
|
|
71
75
|
## Config
|
|
72
76
|
|
|
73
|
-
`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.
|
|
74
78
|
|
|
75
79
|
```json
|
|
76
80
|
{
|
|
@@ -91,9 +95,10 @@ ORDER BY bm25(content, 10.0, 5.0, 1.0) LIMIT 10
|
|
|
91
95
|
|
|
92
96
|
| key | holds |
|
|
93
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. |
|
|
94
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. |
|
|
95
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. |
|
|
96
|
-
| `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 `has`/`basename
|
|
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). |
|
|
97
102
|
| `queries` | entries runnable as `sense <name>`, each naming the verb it runs: `{ sql }` for SQL (`?` binds positional args) or `{ search }` for a ranked search with its settings baked in, so `sense hot` needs no flags. Running an entry validates it: a typo'd column errors and exits nonzero, and a parameterised entry validates with any argument, since preparing precedes binding. |
|
|
98
103
|
| `version` | schema version; older configs auto-migrate on load, noted on stderr. |
|
|
99
104
|
|
|
@@ -137,9 +142,9 @@ Every query starts with a freshness check against the cache in `.sense/`; only c
|
|
|
137
142
|
|
|
138
143
|
- **Work is linear in note count.** Crawl, reconcile, and the freshness check are what every invocation pays; that check is the floor cost of a query and the first thing to watch on a large tree.
|
|
139
144
|
- **Output is flat.** `map`, `peek`, and a search row cost the same on a small tree as a large one: context cost is bounded by what you ask for, not by how much there is.
|
|
140
|
-
- **Bulk changes are paid by whoever queries next.** `sense watch` moves that re-parse into the background ([
|
|
145
|
+
- **Bulk changes are paid by whoever queries next.** `sense watch` moves that re-parse into the background ([DESIGN.md](DESIGN.md#watch-coordination)): it changes latency, never answers, since every query reconciles for itself. To start the cache over, delete the directory `sense status` prints.
|
|
141
146
|
|
|
142
|
-
These are release gates rather than hopes: every release regenerates the numbers on pinned corpora spanning a 4x range in note count plus a stress tree that packs the worst measured shapes into one place: a megabyte-scale note, heading-dense outlines, dense link graphs, hundreds of frontmatter fields.
|
|
147
|
+
These are release gates rather than hopes: every release regenerates the numbers on pinned corpora spanning a 4x range in note count plus a stress tree that packs the worst measured shapes into one place: a megabyte-scale note, heading-dense outlines, dense link graphs, hundreds of frontmatter fields. Configured performance and output-size bands remain release gates. Report-only total rows are exempt from performance thresholds only; invocation failures and invalid artifacts block independently. Current figures: [BENCHMARKING.md](BENCHMARKING.md).
|
|
143
148
|
|
|
144
149
|
## For AI agents
|
|
145
150
|
|
package/dist/cjs/cli/index.d.cts
CHANGED
|
@@ -5,7 +5,7 @@ export declare const USAGE: {
|
|
|
5
5
|
readonly status: "status [--format table|json] [--config path]";
|
|
6
6
|
readonly download: "download [--config path]";
|
|
7
7
|
readonly sql: "sql \"<statement>\" [params...] [--preset name] [--format table|json|csv] [--config path]";
|
|
8
|
-
readonly search: "search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--format table|json|csv] [--config path]";
|
|
8
|
+
readonly search: "search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--format table|json|csv] [--config path]";
|
|
9
9
|
readonly map: "map [--format table|json] [--config path]";
|
|
10
10
|
readonly peek: "peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--format table|json] [--config path]";
|
|
11
11
|
readonly path: "path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--format table|json] [--config path]";
|
package/dist/cjs/cli/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export declare const USAGE: {
|
|
|
5
5
|
readonly status: "status [--format table|json] [--config path]";
|
|
6
6
|
readonly download: "download [--config path]";
|
|
7
7
|
readonly sql: "sql \"<statement>\" [params...] [--preset name] [--format table|json|csv] [--config path]";
|
|
8
|
-
readonly search: "search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--format table|json|csv] [--config path]";
|
|
8
|
+
readonly search: "search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--format table|json|csv] [--config path]";
|
|
9
9
|
readonly map: "map [--format table|json] [--config path]";
|
|
10
10
|
readonly peek: "peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--format table|json] [--config path]";
|
|
11
11
|
readonly path: "path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--format table|json] [--config path]";
|
package/dist/cjs/cli/index.js
CHANGED
|
@@ -52,7 +52,7 @@ var USAGE = {
|
|
|
52
52
|
status: 'status [--format table|json] [--config path]',
|
|
53
53
|
download: 'download [--config path]',
|
|
54
54
|
sql: 'sql "<statement>" [params...] [--preset name] [--format table|json|csv] [--config path]',
|
|
55
|
-
search: 'search "<terms>" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--k n] [--format table|json|csv] [--config path]',
|
|
55
|
+
search: 'search "<terms>" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--format table|json|csv] [--config path]',
|
|
56
56
|
map: 'map [--format table|json] [--config path]',
|
|
57
57
|
peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--format table|json] [--config path]',
|
|
58
58
|
path: 'path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where "<sql>"] [--max-depth n] [--format table|json] [--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 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] [--format table|json|csv] [--config path]',\n search: 'search \"<terms>\" [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--format table|json|csv] [--config path]',\n map: 'map [--format table|json] [--config path]',\n peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--format table|json] [--config path]',\n path: 'path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--format table|json] [--config path]',\n related: 'related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--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 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":["COMMANDS","USAGE","init","watch","status","download","sql","search","map","peek","path","related"],"mappings":";;;;;;;;;;;QAmBaA;eAAAA;;QAfAC;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAN,IAAMA,QAAQ;IACnBC,MAAM;IACNC,OAAO;IACPC,QAAQ;IACRC,UAAU;IACVC,KAAK;IACLC,QAAQ;IACRC,KAAK;IACLC,MAAM;IACNC,MAAM;IACNC,SAAS;AACX;AAIO,IAAMX,WAAgE;IAC3EE,MAAM,SAANA;eAAY;2DAAA,QAAO;;;IACnBC,OAAO,SAAPA;eAAa;2DAAA,QAAO;;;IACpBC,QAAQ,SAARA;eAAc;2DAAA,QAAO;;;IACrBC,UAAU,SAAVA;eAAgB;2DAAA,QAAO;;;IACvBC,KAAK,SAALA;eAAW;2DAAA,QAAO;;;IAClBC,QAAQ,SAARA;eAAc;2DAAA,QAAO;;;IACrBC,KAAK,SAALA;eAAW;2DAAA,QAAO;;;IAClBC,MAAM,SAANA;eAAY;2DAAA,QAAO;;;IACnBC,MAAM,SAANA;eAAY;2DAAA,QAAO;;;IACnBC,SAAS,SAATA;eAAe;2DAAA,QAAO;;;AACxB"}
|
|
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 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] [--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] [--format table|json|csv] [--config path]',\n map: 'map [--format table|json] [--config path]',\n peek: 'peek <path> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--format table|json] [--config path]',\n path: 'path <a> <b> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--max-depth n] [--format table|json] [--config path]',\n related: 'related <note> [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude] [--where \"<sql>\"] [--k n] [--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 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":["COMMANDS","USAGE","init","watch","status","download","sql","search","map","peek","path","related"],"mappings":";;;;;;;;;;;QAmBaA;eAAAA;;QAfAC;eAAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAN,IAAMA,QAAQ;IACnBC,MAAM;IACNC,OAAO;IACPC,QAAQ;IACRC,UAAU;IACVC,KAAK;IACLC,QAAQ;IACRC,KAAK;IACLC,MAAM;IACNC,MAAM;IACNC,SAAS;AACX;AAIO,IAAMX,WAAgE;IAC3EE,MAAM,SAANA;eAAY;2DAAA,QAAO;;;IACnBC,OAAO,SAAPA;eAAa;2DAAA,QAAO;;;IACpBC,QAAQ,SAARA;eAAc;2DAAA,QAAO;;;IACrBC,UAAU,SAAVA;eAAgB;2DAAA,QAAO;;;IACvBC,KAAK,SAALA;eAAW;2DAAA,QAAO;;;IAClBC,QAAQ,SAARA;eAAc;2DAAA,QAAO;;;IACrBC,KAAK,SAALA;eAAW;2DAAA,QAAO;;;IAClBC,MAAM,SAANA;eAAY;2DAAA,QAAO;;;IACnBC,MAAM,SAANA;eAAY;2DAAA,QAAO;;;IACnBC,SAAS,SAATA;eAAe;2DAAA,QAAO;;;AACxB"}
|
package/dist/cjs/cli/named.js
CHANGED
|
@@ -166,11 +166,11 @@ function _ts_generator(thisArg, body) {
|
|
|
166
166
|
}
|
|
167
167
|
function named(ctx, queryName) {
|
|
168
168
|
return _async_to_generator(function() {
|
|
169
|
-
var _parseK, _values_where, _values_preset, _values_include, _values_exclude, usage, _parse, values, params, format, configPath, cfg, entry, k, where, preset, include, exclude, noExclude;
|
|
169
|
+
var _parseK, _values_where, _values_preset, _values_include, _values_exclude, usage, _parse, values, params, format, configPath, cfg, entry, k, snippetCharLimit, snippetCountLimit, where, preset, include, exclude, noExclude;
|
|
170
170
|
return _ts_generator(this, function(_state) {
|
|
171
171
|
switch(_state.label){
|
|
172
172
|
case 0:
|
|
173
|
-
usage = "usage: ".concat(ctx.name, " ").concat(queryName, ' [params...] [--format table|json|csv] [--config path] [--where "<sql>"] [--k n] [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude]');
|
|
173
|
+
usage = "usage: ".concat(ctx.name, " ").concat(queryName, ' [params...] [--format table|json|csv] [--config path] [--where "<sql>"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude]');
|
|
174
174
|
_parse = (0, _sharedts.parse)(ctx.argv, usage, _object_spread({}, _sharedts.SEARCH_FLAGS, _sharedts.FORMAT, _sharedts.CONFIG)), values = _parse.values, params = _parse.positionals;
|
|
175
175
|
format = (0, _sharedts.rowFormatOf)(values);
|
|
176
176
|
configPath = values.config;
|
|
@@ -202,6 +202,8 @@ function named(ctx, queryName) {
|
|
|
202
202
|
ctx.usageError('"'.concat(queryName, '" is a saved search and takes no positional parameters; edit its "search" in sense.config.json, or use "').concat(ctx.name, ' search" directly'));
|
|
203
203
|
}
|
|
204
204
|
k = (_parseK = (0, _sharedts.parseK)(values.k, ctx.usageError)) !== null && _parseK !== void 0 ? _parseK : entry.k;
|
|
205
|
+
snippetCharLimit = (0, _sharedts.parseSnippetCharLimit)(values['snippet-char-limit'], ctx.usageError);
|
|
206
|
+
snippetCountLimit = (0, _sharedts.parseSnippetCountLimit)(values['snippet-count-limit'], ctx.usageError);
|
|
205
207
|
where = (_values_where = values.where) !== null && _values_where !== void 0 ? _values_where : entry.where;
|
|
206
208
|
preset = (_values_preset = values.preset) !== null && _values_preset !== void 0 ? _values_preset : entry.preset;
|
|
207
209
|
include = (_values_include = values.include) !== null && _values_include !== void 0 ? _values_include : entry.include;
|
|
@@ -218,6 +220,8 @@ function named(ctx, queryName) {
|
|
|
218
220
|
4,
|
|
219
221
|
(0, _searchts.search)(store, resolvedCfg, entry.search, {
|
|
220
222
|
k: k,
|
|
223
|
+
snippetCharLimit: snippetCharLimit,
|
|
224
|
+
snippetCountLimit: snippetCountLimit,
|
|
221
225
|
where: where,
|
|
222
226
|
preset: preset,
|
|
223
227
|
include: include,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/named.ts"],"sourcesContent":["import { search } from '../commands/search.ts';\nimport { printRows } from '../output/output.ts';\nimport { CONFIG, FORMAT, parse, parseK, rowFormatOf, runSql, SEARCH_FLAGS, withDb } from './shared.ts';\nimport type { Ctx } from './types.ts';\n\n// Fallback when the first positional is not a command: a saved query, { sql } or { search }.\n// SEARCH_FLAGS override a saved search's fields the same way they override a preset's.\nexport default async function named(ctx: Ctx, queryName: string): Promise<void> {\n const usage = `usage: ${ctx.name} ${queryName} [params...] [--format table|json|csv] [--config path] [--where \"<sql>\"] [--k n] [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude]`;\n const { values, positionals: params } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...FORMAT, ...CONFIG });\n const format = rowFormatOf(values);\n const configPath = values.config as string | undefined;\n\n const cfg = ctx.resolveConfig(configPath);\n const entry = cfg.queries[queryName];\n if (entry === undefined) {\n console.error(`unknown command or saved entry: \"${queryName}\"`);\n console.error(`saved queries: ${Object.keys(cfg.queries).sort().join(', ')}`);\n process.exit(2);\n }\n\n if ('sql' in entry) {\n // A saved statement written against `scope` is preset-agnostic, so the same entry can be\n // re-pointed at another layer from the command line instead of being copied per preset.\n await runSql(cfg, entry.sql, params, format, `query \"${queryName}\"`, values.preset as string | undefined);\n return;\n }\n\n // A saved search's text is fixed in config; there is nowhere for a positional to bind.\n if (params.length > 0) {\n ctx.usageError(`\"${queryName}\" is a saved search and takes no positional parameters; edit its \"search\" in sense.config.json, or use \"${ctx.name} search\" directly`);\n }\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? entry.k;\n const where = (values.where as string | undefined) ?? entry.where;\n const preset = (values.preset as string | undefined) ?? entry.preset;\n const include = (values.include as string[] | undefined) ?? entry.include;\n const exclude = (values.exclude as string[] | undefined) ?? entry.exclude;\n const noExclude = values['no-exclude'] === true;\n await withDb(ctx, configPath, async (store, resolvedCfg) => printRows(await search(store, resolvedCfg, entry.search, { k, where, preset, include, exclude, noExclude }), format));\n}\n"],"names":["named","ctx","queryName","parseK","values","usage","parse","params","format","configPath","cfg","entry","k","where","preset","include","exclude","noExclude","name","argv","SEARCH_FLAGS","FORMAT","CONFIG","positionals","rowFormatOf","config","resolveConfig","queries","undefined","console","error","Object","keys","sort","join","process","exit","runSql","sql","length","usageError","withDb","store","resolvedCfg","search","printRows"],"mappings":";;;;+BAKA,6FAA6F;AAC7F,uFAAuF;AACvF;;;eAA8BA;;;wBAPP;wBACG;
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/named.ts"],"sourcesContent":["import { search } from '../commands/search.ts';\nimport { printRows } from '../output/output.ts';\nimport { CONFIG, FORMAT, parse, parseK, parseSnippetCharLimit, parseSnippetCountLimit, rowFormatOf, runSql, SEARCH_FLAGS, withDb } from './shared.ts';\nimport type { Ctx } from './types.ts';\n\n// Fallback when the first positional is not a command: a saved query, { sql } or { search }.\n// SEARCH_FLAGS override a saved search's fields the same way they override a preset's.\nexport default async function named(ctx: Ctx, queryName: string): Promise<void> {\n const usage = `usage: ${ctx.name} ${queryName} [params...] [--format table|json|csv] [--config path] [--where \"<sql>\"] [--k n] [--snippet-char-limit n] [--snippet-count-limit n] [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude]`;\n const { values, positionals: params } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...FORMAT, ...CONFIG });\n const format = rowFormatOf(values);\n const configPath = values.config as string | undefined;\n\n const cfg = ctx.resolveConfig(configPath);\n const entry = cfg.queries[queryName];\n if (entry === undefined) {\n console.error(`unknown command or saved entry: \"${queryName}\"`);\n console.error(`saved queries: ${Object.keys(cfg.queries).sort().join(', ')}`);\n process.exit(2);\n }\n\n if ('sql' in entry) {\n // A saved statement written against `scope` is preset-agnostic, so the same entry can be\n // re-pointed at another layer from the command line instead of being copied per preset.\n await runSql(cfg, entry.sql, params, format, `query \"${queryName}\"`, values.preset as string | undefined);\n return;\n }\n\n // A saved search's text is fixed in config; there is nowhere for a positional to bind.\n if (params.length > 0) {\n ctx.usageError(`\"${queryName}\" is a saved search and takes no positional parameters; edit its \"search\" in sense.config.json, or use \"${ctx.name} search\" directly`);\n }\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? entry.k;\n const snippetCharLimit = parseSnippetCharLimit(values['snippet-char-limit'] as string | undefined, ctx.usageError);\n const snippetCountLimit = parseSnippetCountLimit(values['snippet-count-limit'] as string | undefined, ctx.usageError);\n const where = (values.where as string | undefined) ?? entry.where;\n const preset = (values.preset as string | undefined) ?? entry.preset;\n const include = (values.include as string[] | undefined) ?? entry.include;\n const exclude = (values.exclude as string[] | undefined) ?? entry.exclude;\n const noExclude = values['no-exclude'] === true;\n await withDb(ctx, configPath, async (store, resolvedCfg) => printRows(await search(store, resolvedCfg, entry.search, { k, snippetCharLimit, snippetCountLimit, where, preset, include, exclude, noExclude }), format));\n}\n"],"names":["named","ctx","queryName","parseK","values","usage","parse","params","format","configPath","cfg","entry","k","snippetCharLimit","snippetCountLimit","where","preset","include","exclude","noExclude","name","argv","SEARCH_FLAGS","FORMAT","CONFIG","positionals","rowFormatOf","config","resolveConfig","queries","undefined","console","error","Object","keys","sort","join","process","exit","runSql","sql","length","usageError","parseSnippetCharLimit","parseSnippetCountLimit","withDb","store","resolvedCfg","search","printRows"],"mappings":"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"}
|
package/dist/cjs/cli/search.js
CHANGED
|
@@ -211,7 +211,7 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
211
211
|
}
|
|
212
212
|
var searchCmd = function searchCmd(ctx) {
|
|
213
213
|
return _async_to_generator(function() {
|
|
214
|
-
var usage, _parse, values, positionals, _positionals, terms, k, format;
|
|
214
|
+
var usage, _parse, values, positionals, _positionals, terms, k, snippetCharLimit, snippetCountLimit, format;
|
|
215
215
|
return _ts_generator(this, function(_state) {
|
|
216
216
|
switch(_state.label){
|
|
217
217
|
case 0:
|
|
@@ -220,6 +220,8 @@ var searchCmd = function searchCmd(ctx) {
|
|
|
220
220
|
_positionals = _sliced_to_array(positionals, 1), terms = _positionals[0];
|
|
221
221
|
if (!terms) ctx.usageError(usage);
|
|
222
222
|
k = (0, _sharedts.parseK)(values.k, ctx.usageError);
|
|
223
|
+
snippetCharLimit = (0, _sharedts.parseSnippetCharLimit)(values['snippet-char-limit'], ctx.usageError);
|
|
224
|
+
snippetCountLimit = (0, _sharedts.parseSnippetCountLimit)(values['snippet-count-limit'], ctx.usageError);
|
|
223
225
|
format = (0, _sharedts.rowFormatOf)(values);
|
|
224
226
|
return [
|
|
225
227
|
4,
|
|
@@ -231,7 +233,9 @@ var searchCmd = function searchCmd(ctx) {
|
|
|
231
233
|
return [
|
|
232
234
|
4,
|
|
233
235
|
(0, _searchts.search)(store, cfg, terms, _object_spread({
|
|
234
|
-
k: k
|
|
236
|
+
k: k,
|
|
237
|
+
snippetCharLimit: snippetCharLimit,
|
|
238
|
+
snippetCountLimit: snippetCountLimit
|
|
235
239
|
}, (0, _sharedts.scopeOf)(values)))
|
|
236
240
|
];
|
|
237
241
|
case 1:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/search.ts"],"sourcesContent":["import { search } from '../commands/search.ts';\nimport { printRows } from '../output/output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, parse, parseK, rowFormatOf, SEARCH_FLAGS, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst searchCmd: Command = async (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.search}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...FORMAT, ...CONFIG });\n const [terms] = positionals;\n if (!terms) ctx.usageError(usage);\n const k = parseK(values.k as string | undefined, ctx.usageError);\n const format = rowFormatOf(values);\n await withDb(ctx, values.config as string | undefined, async (store, cfg) => printRows(await search(store, cfg, terms, { k, ...scopeOf(values) }), format));\n};\nexport default searchCmd;\n"],"names":["searchCmd","ctx","usage","parse","values","positionals","terms","k","format","USAGE","name","search","argv","SEARCH_FLAGS","FORMAT","CONFIG","usageError","parseK","rowFormatOf","withDb","config","store","cfg","scopeOf","printRows"],"mappings":";;;;+
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/search.ts"],"sourcesContent":["import { search } from '../commands/search.ts';\nimport { printRows } from '../output/output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, parse, parseK, parseSnippetCharLimit, parseSnippetCountLimit, rowFormatOf, SEARCH_FLAGS, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst searchCmd: Command = async (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.search}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...FORMAT, ...CONFIG });\n const [terms] = positionals;\n if (!terms) ctx.usageError(usage);\n const k = parseK(values.k as string | undefined, ctx.usageError);\n const snippetCharLimit = parseSnippetCharLimit(values['snippet-char-limit'] as string | undefined, ctx.usageError);\n const snippetCountLimit = parseSnippetCountLimit(values['snippet-count-limit'] as string | undefined, ctx.usageError);\n const format = rowFormatOf(values);\n await withDb(ctx, values.config as string | undefined, async (store, cfg) => printRows(await search(store, cfg, terms, { k, snippetCharLimit, snippetCountLimit, ...scopeOf(values) }), format));\n};\nexport default searchCmd;\n"],"names":["searchCmd","ctx","usage","parse","values","positionals","terms","k","snippetCharLimit","snippetCountLimit","format","USAGE","name","search","argv","SEARCH_FLAGS","FORMAT","CONFIG","usageError","parseK","parseSnippetCharLimit","parseSnippetCountLimit","rowFormatOf","withDb","config","store","cfg","scopeOf","printRows"],"mappings":";;;;+BAiBA;;;eAAA;;;wBAjBuB;wBACG;uBACJ;wBACmH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGzI,IAAMA,YAAqB,mBAAOC;;YAC1BC,OAC0BC,QAAxBC,QAAQC,aACAA,cAATC,OAEDC,GACAC,kBACAC,mBACAC;;;;oBAPAR,QAAQ,AAAC,UAAqBS,OAAZV,IAAIW,IAAI,EAAC,KAAgB,OAAbD,cAAK,CAACE,MAAM;oBAChBV,SAAAA,IAAAA,eAAK,EAACF,IAAIa,IAAI,EAAEZ,OAAO,mBAAKa,sBAAY,EAAKC,gBAAM,EAAKC,gBAAM,IAAtFb,SAAwBD,OAAxBC,QAAQC,cAAgBF,OAAhBE;oBACAA,gCAAAA,iBAATC,QAASD;oBAChB,IAAI,CAACC,OAAOL,IAAIiB,UAAU,CAAChB;oBACrBK,IAAIY,IAAAA,gBAAM,EAACf,OAAOG,CAAC,EAAwBN,IAAIiB,UAAU;oBACzDV,mBAAmBY,IAAAA,+BAAqB,EAAChB,MAAM,CAAC,qBAAqB,EAAwBH,IAAIiB,UAAU;oBAC3GT,oBAAoBY,IAAAA,gCAAsB,EAACjB,MAAM,CAAC,sBAAsB,EAAwBH,IAAIiB,UAAU;oBAC9GR,SAASY,IAAAA,qBAAW,EAAClB;oBAC3B;;wBAAMmB,IAAAA,gBAAM,EAACtB,KAAKG,OAAOoB,MAAM,EAAwB,SAAOC,OAAOC;;;;;4CAAkB;;gDAAMb,IAAAA,gBAAM,EAACY,OAAOC,KAAKpB,OAAO;oDAAEC,GAAAA;oDAAGC,kBAAAA;oDAAkBC,mBAAAA;mDAAsBkB,IAAAA,iBAAO,EAACvB;;;;;gDAA/FwB,mBAAS;oDAAC;oDAAiGlB;;;;;;;;;oBAAxL;;;;;;IACF;;IACA,WAAeV"}
|
|
@@ -16,6 +16,8 @@ export declare function parse(argv: string[], usage: string, options: ParseArgsO
|
|
|
16
16
|
positionals: string[];
|
|
17
17
|
};
|
|
18
18
|
export declare function parseK(k: string | undefined, usageError: (message: string) => never): number | undefined;
|
|
19
|
+
export declare function parseSnippetCharLimit(value: string | undefined, usageError: (message: string) => never): number | undefined;
|
|
20
|
+
export declare function parseSnippetCountLimit(value: string | undefined, usageError: (message: string) => never): number | undefined;
|
|
19
21
|
export declare function printWarnings(warnings: string[]): void;
|
|
20
22
|
export declare function withDb(ctx: Ctx, configPath: string | undefined, fn: (store: OpenResult['store'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void>;
|
|
21
23
|
export declare function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: RowFormat, label: string, preset?: string): Promise<void>;
|
package/dist/cjs/cli/shared.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export declare function parse(argv: string[], usage: string, options: ParseArgsO
|
|
|
16
16
|
positionals: string[];
|
|
17
17
|
};
|
|
18
18
|
export declare function parseK(k: string | undefined, usageError: (message: string) => never): number | undefined;
|
|
19
|
+
export declare function parseSnippetCharLimit(value: string | undefined, usageError: (message: string) => never): number | undefined;
|
|
20
|
+
export declare function parseSnippetCountLimit(value: string | undefined, usageError: (message: string) => never): number | undefined;
|
|
19
21
|
export declare function printWarnings(warnings: string[]): void;
|
|
20
22
|
export declare function withDb(ctx: Ctx, configPath: string | undefined, fn: (store: OpenResult['store'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void>;
|
|
21
23
|
export declare function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: RowFormat, label: string, preset?: string): Promise<void>;
|
package/dist/cjs/cli/shared.js
CHANGED
|
@@ -30,6 +30,12 @@ _export(exports, {
|
|
|
30
30
|
get parseK () {
|
|
31
31
|
return parseK;
|
|
32
32
|
},
|
|
33
|
+
get parseSnippetCharLimit () {
|
|
34
|
+
return parseSnippetCharLimit;
|
|
35
|
+
},
|
|
36
|
+
get parseSnippetCountLimit () {
|
|
37
|
+
return parseSnippetCountLimit;
|
|
38
|
+
},
|
|
33
39
|
get printWarnings () {
|
|
34
40
|
return printWarnings;
|
|
35
41
|
},
|
|
@@ -289,6 +295,12 @@ var SCOPE = {
|
|
|
289
295
|
var SEARCH_FLAGS = _object_spread_props(_object_spread({}, SCOPE), {
|
|
290
296
|
k: {
|
|
291
297
|
type: 'string'
|
|
298
|
+
},
|
|
299
|
+
'snippet-char-limit': {
|
|
300
|
+
type: 'string'
|
|
301
|
+
},
|
|
302
|
+
'snippet-count-limit': {
|
|
303
|
+
type: 'string'
|
|
292
304
|
}
|
|
293
305
|
});
|
|
294
306
|
function scopeOf(values) {
|
|
@@ -358,6 +370,18 @@ function parseK(k, usageError) {
|
|
|
358
370
|
if (!Number.isInteger(parsed) || parsed <= 0) usageError('--k expects a positive integer, got "'.concat(k, '"'));
|
|
359
371
|
return parsed;
|
|
360
372
|
}
|
|
373
|
+
function parseSnippetCharLimit(value, usageError) {
|
|
374
|
+
if (value === undefined) return undefined;
|
|
375
|
+
var parsed = Number(value);
|
|
376
|
+
if (!Number.isInteger(parsed) || parsed <= 0) usageError('--snippet-char-limit expects a positive integer, got "'.concat(value, '"'));
|
|
377
|
+
return parsed;
|
|
378
|
+
}
|
|
379
|
+
function parseSnippetCountLimit(value, usageError) {
|
|
380
|
+
if (value === undefined) return undefined;
|
|
381
|
+
var parsed = Number(value);
|
|
382
|
+
if (!Number.isInteger(parsed) || parsed <= 0) usageError('--snippet-count-limit expects a positive integer, got "'.concat(value, '"'));
|
|
383
|
+
return parsed;
|
|
384
|
+
}
|
|
361
385
|
function printWarnings(warnings) {
|
|
362
386
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
363
387
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/shared.ts"],"sourcesContent":["import type { ParseArgsOptionsConfig } from 'node:util';\nimport { parseArgs } from 'node:util';\nimport type { ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { resolvePreset } from '../config/index.ts';\nimport { columnHint } from '../output/column-hint.ts';\nimport type { Row, RowFormat } from '../output/output.ts';\nimport { printRowStream } from '../output/output.ts';\nimport { searchError } from '../output/search-error.ts';\nimport type { OpenResult } from '../store/index.ts';\nimport { openStore } from '../store/index.ts';\nimport type { Store } from '../store/types.ts';\nimport type { Ctx } from './types.ts';\n\n// Spreadable option fragments -- one flag name keeps one meaning across every command's table.\nexport const FORMAT: ParseArgsOptionsConfig = { format: { type: 'string', default: 'table' } };\nexport const CONFIG: ParseArgsOptionsConfig = { config: { type: 'string' } };\n// The scope vocabulary every scoped command shares: named preset, ad hoc include/exclude\n// globs, a where SQL condition. search adds k on top.\nexport const SCOPE: ParseArgsOptionsConfig = {\n where: { type: 'string' },\n preset: { type: 'string' },\n include: { type: 'string', multiple: true },\n exclude: { type: 'string', multiple: true },\n // Widening, which no other flag can express: --include and --exclude each override their\n // own side of the preset, so neither can drop an exclusion the preset declares.\n 'no-exclude': { type: 'boolean', default: false },\n};\nexport const SEARCH_FLAGS: ParseArgsOptionsConfig = { ...SCOPE, k: { type: 'string' } };\n\ntype Values = Record<string, string | boolean | string[] | undefined>;\n\n// The SCOPE fragment's parsed values as the overrides every scoped command passes down.\n// One place to read them: a new scope field is added to the fragment and here, not per-command.\nexport function scopeOf(values: Values): SearchOverrides {\n return {\n preset: values.preset as string | undefined,\n include: values.include as string[] | undefined,\n exclude: values.exclude as string[] | undefined,\n where: values.where as string | undefined,\n noExclude: values['no-exclude'] === true,\n };\n}\n\n// parseArgs is strict about flag names; this applies the same strictness to the value.\n// An unrecognised --format is a usage error, not a silent fallback to `table`.\nfunction pickFormat<T extends string>(values: Values, allowed: readonly T[]): T {\n const format = String(values.format);\n if ((allowed as readonly string[]).includes(format)) return format as T;\n console.error(`unknown --format \"${format}\"; expected ${allowed.join(', ')}`);\n process.exit(2);\n}\n\nexport function formatOf(values: Values): 'table' | 'json' {\n return pickFormat(values, ['table', 'json'] as const);\n}\n\n// csv is a row set rendered as rows; map, peek, status, and path render structures instead,\n// and take formatOf.\nexport function rowFormatOf(values: Values): RowFormat {\n return pickFormat(values, ['table', 'json', 'csv'] as const);\n}\n\n// Per-command parseArgs: strict (a foreign flag exits 2), and every table gets --help for free.\nexport function parse(argv: string[], usage: string, options: ParseArgsOptionsConfig): { values: Values; positionals: string[] } {\n let values: Values;\n let positionals: string[];\n try {\n ({ values, positionals } = parseArgs({\n args: argv,\n options: { ...options, help: { type: 'boolean', default: false, short: 'h' } },\n strict: true,\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage);\n process.exit(2);\n }\n if (values.help) {\n console.log(usage);\n process.exit(0);\n }\n return { values, positionals };\n}\n\n// --k must be a positive integer: SQLite reads a bound LIMIT of -1 as \"unlimited\" and 0 as \"nothing\", and parseInt would silently truncate \"5.9\".\n// All three are caller mistakes worth a usage error, matching the config-level SavedSearch validation.\nexport function parseK(k: string | undefined, usageError: (message: string) => never): number | undefined {\n if (k === undefined) return undefined;\n const parsed = Number(k);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--k expects a positive integer, got \"${k}\"`);\n return parsed;\n}\n\n// Shared open-query-close envelope for commands that touch the tree.\n\nexport function printWarnings(warnings: string[]): void {\n for (const w of warnings) console.warn(w);\n}\n\nexport async function withDb(ctx: Ctx, configPath: string | undefined, fn: (store: OpenResult['store'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void> {\n const cfg = ctx.resolveConfig(configPath);\n const { store, warnings } = await openStore(cfg);\n printWarnings(warnings);\n try {\n await fn(store, cfg);\n } finally {\n await store.close();\n }\n}\n\n// `--preset` on SQL binds a temp `scope` table rather than transparently filtering: temp views shadowing the base tables can't cover `content`, since FTS5 MATCH treats the table name as a hidden column.\n// A flag that silently scoped three tables of four would look scoped and not be.\nasync function bindScope(store: Store, cfg: ResolvedConfig, preset: string): Promise<void> {\n const { name } = resolvePreset(cfg, preset); // unknown names throw, listing what is declared\n await store.exec('DROP TABLE IF EXISTS temp.scope');\n await store.exec('CREATE TEMP TABLE scope (\"path\" TEXT PRIMARY KEY)');\n const insert = await store.prepare('INSERT INTO temp.scope (\"path\") SELECT \"path\" FROM preset_files WHERE preset = ?');\n await insert.run(name);\n}\n\n// An unbound `?` silently binds NULL, so mismatched param counts fail loudly instead.\nexport async function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: RowFormat, label: string, preset?: string): Promise<void> {\n const placeholderCount = (sql.match(/\\?/g) ?? []).length;\n if (params.length !== placeholderCount) {\n console.error(`${label} expects ${placeholderCount} parameter(s), got ${params.length}`);\n process.exit(2);\n }\n // Naming a preset and never joining it would return the whole index while reading as scoped,\n // which is the one hazard of binding rather than applying. Refuse instead.\n if (preset !== undefined && !/\\bscope\\b/i.test(sql)) {\n console.error(`--preset binds a temporary \"scope\" table of the preset's paths, and ${label} never joins it, so the preset would have no effect`);\n console.error(`add: JOIN scope ON scope.\"path\" = <table>.\"path\"`);\n process.exit(2);\n }\n const { store, warnings } = await openStore(cfg);\n printWarnings(warnings);\n if (preset !== undefined) await bindScope(store, cfg, preset);\n // Streamed, not collected: `sql`'s result size is the caller's business, not ours. columns() reads the statement's own metadata, so a 0-row csv gets a header too.\n // A mid-stream SQLite error (e.g. SQLITE_BUSY outlasting busy_timeout) may leave partial output; the nonzero exit code is the failure signal, not a completeness guarantee.\n try {\n const statement = await store.raw.prepare(sql);\n const columns = statement.columns().map((c) => c.name);\n await printRowStream(statement.iterate(...params) as AsyncIterable<Row>, format, columns);\n } catch (err) {\n const hinted = columnHint(await store.docs.columns(), err as Error); // columns read while the store is still open\n await store.close();\n // A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5 punctuation trap applies to its bound parameters.\n // SQL without MATCH gets its error verbatim; search advice on a plain typo would mislead.\n if (/\\bMATCH\\b/i.test(sql)) throw searchError(hinted, params.join(' '));\n throw hinted;\n }\n await store.close();\n}\n"],"names":["CONFIG","FORMAT","SCOPE","SEARCH_FLAGS","formatOf","parse","parseK","printWarnings","rowFormatOf","runSql","scopeOf","withDb","format","type","default","config","where","preset","include","multiple","exclude","k","values","noExclude","pickFormat","allowed","String","includes","console","error","join","process","exit","argv","usage","options","positionals","parseArgs","args","help","short","strict","allowPositionals","err","message","log","usageError","undefined","parsed","Number","isInteger","warnings","w","warn","ctx","configPath","fn","cfg","store","resolveConfig","openStore","close","bindScope","name","insert","resolvePreset","exec","prepare","run","sql","params","label","placeholderCount","statement","columns","hinted","match","length","test","raw","map","c","printRowStream","iterate","docs","columnHint","searchError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/shared.ts"],"sourcesContent":["import type { ParseArgsOptionsConfig } from 'node:util';\nimport { parseArgs } from 'node:util';\nimport type { ResolvedConfig, SearchOverrides } from '../config/index.ts';\nimport { resolvePreset } from '../config/index.ts';\nimport { columnHint } from '../output/column-hint.ts';\nimport type { Row, RowFormat } from '../output/output.ts';\nimport { printRowStream } from '../output/output.ts';\nimport { searchError } from '../output/search-error.ts';\nimport type { OpenResult } from '../store/index.ts';\nimport { openStore } from '../store/index.ts';\nimport type { Store } from '../store/types.ts';\nimport type { Ctx } from './types.ts';\n\n// Spreadable option fragments -- one flag name keeps one meaning across every command's table.\nexport const FORMAT: ParseArgsOptionsConfig = { format: { type: 'string', default: 'table' } };\nexport const CONFIG: ParseArgsOptionsConfig = { config: { type: 'string' } };\n// The scope vocabulary every scoped command shares: named preset, ad hoc include/exclude\n// globs, a where SQL condition. search adds k on top.\nexport const SCOPE: ParseArgsOptionsConfig = {\n where: { type: 'string' },\n preset: { type: 'string' },\n include: { type: 'string', multiple: true },\n exclude: { type: 'string', multiple: true },\n // Widening, which no other flag can express: --include and --exclude each override their\n // own side of the preset, so neither can drop an exclusion the preset declares.\n 'no-exclude': { type: 'boolean', default: false },\n};\nexport const SEARCH_FLAGS: ParseArgsOptionsConfig = { ...SCOPE, k: { type: 'string' }, 'snippet-char-limit': { type: 'string' }, 'snippet-count-limit': { type: 'string' } };\n\ntype Values = Record<string, string | boolean | string[] | undefined>;\n\n// The SCOPE fragment's parsed values as the overrides every scoped command passes down.\n// One place to read them: a new scope field is added to the fragment and here, not per-command.\nexport function scopeOf(values: Values): SearchOverrides {\n return {\n preset: values.preset as string | undefined,\n include: values.include as string[] | undefined,\n exclude: values.exclude as string[] | undefined,\n where: values.where as string | undefined,\n noExclude: values['no-exclude'] === true,\n };\n}\n\n// parseArgs is strict about flag names; this applies the same strictness to the value.\n// An unrecognised --format is a usage error, not a silent fallback to `table`.\nfunction pickFormat<T extends string>(values: Values, allowed: readonly T[]): T {\n const format = String(values.format);\n if ((allowed as readonly string[]).includes(format)) return format as T;\n console.error(`unknown --format \"${format}\"; expected ${allowed.join(', ')}`);\n process.exit(2);\n}\n\nexport function formatOf(values: Values): 'table' | 'json' {\n return pickFormat(values, ['table', 'json'] as const);\n}\n\n// csv is a row set rendered as rows; map, peek, status, and path render structures instead,\n// and take formatOf.\nexport function rowFormatOf(values: Values): RowFormat {\n return pickFormat(values, ['table', 'json', 'csv'] as const);\n}\n\n// Per-command parseArgs: strict (a foreign flag exits 2), and every table gets --help for free.\nexport function parse(argv: string[], usage: string, options: ParseArgsOptionsConfig): { values: Values; positionals: string[] } {\n let values: Values;\n let positionals: string[];\n try {\n ({ values, positionals } = parseArgs({\n args: argv,\n options: { ...options, help: { type: 'boolean', default: false, short: 'h' } },\n strict: true,\n allowPositionals: true,\n }));\n } catch (err) {\n console.error((err as Error).message);\n console.error(usage);\n process.exit(2);\n }\n if (values.help) {\n console.log(usage);\n process.exit(0);\n }\n return { values, positionals };\n}\n\n// --k must be a positive integer: SQLite reads a bound LIMIT of -1 as \"unlimited\" and 0 as \"nothing\", and parseInt would silently truncate \"5.9\".\n// All three are caller mistakes worth a usage error, matching the config-level SavedSearch validation.\nexport function parseK(k: string | undefined, usageError: (message: string) => never): number | undefined {\n if (k === undefined) return undefined;\n const parsed = Number(k);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--k expects a positive integer, got \"${k}\"`);\n return parsed;\n}\n\n// Same positive-integer rule as --k, beside it since both flags come from SEARCH_FLAGS.\nexport function parseSnippetCharLimit(value: string | undefined, usageError: (message: string) => never): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--snippet-char-limit expects a positive integer, got \"${value}\"`);\n return parsed;\n}\n\nexport function parseSnippetCountLimit(value: string | undefined, usageError: (message: string) => never): number | undefined {\n if (value === undefined) return undefined;\n const parsed = Number(value);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--snippet-count-limit expects a positive integer, got \"${value}\"`);\n return parsed;\n}\n\n// Shared open-query-close envelope for commands that touch the tree.\n\nexport function printWarnings(warnings: string[]): void {\n for (const w of warnings) console.warn(w);\n}\n\nexport async function withDb(ctx: Ctx, configPath: string | undefined, fn: (store: OpenResult['store'], cfg: ResolvedConfig) => void | Promise<void>): Promise<void> {\n const cfg = ctx.resolveConfig(configPath);\n const { store, warnings } = await openStore(cfg);\n printWarnings(warnings);\n try {\n await fn(store, cfg);\n } finally {\n await store.close();\n }\n}\n\n// `--preset` on SQL binds a temp `scope` table rather than transparently filtering: temp views shadowing the base tables can't cover `content`, since FTS5 MATCH treats the table name as a hidden column.\n// A flag that silently scoped three tables of four would look scoped and not be.\nasync function bindScope(store: Store, cfg: ResolvedConfig, preset: string): Promise<void> {\n const { name } = resolvePreset(cfg, preset); // unknown names throw, listing what is declared\n await store.exec('DROP TABLE IF EXISTS temp.scope');\n await store.exec('CREATE TEMP TABLE scope (\"path\" TEXT PRIMARY KEY)');\n const insert = await store.prepare('INSERT INTO temp.scope (\"path\") SELECT \"path\" FROM preset_files WHERE preset = ?');\n await insert.run(name);\n}\n\n// An unbound `?` silently binds NULL, so mismatched param counts fail loudly instead.\nexport async function runSql(cfg: ResolvedConfig, sql: string, params: string[], format: RowFormat, label: string, preset?: string): Promise<void> {\n const placeholderCount = (sql.match(/\\?/g) ?? []).length;\n if (params.length !== placeholderCount) {\n console.error(`${label} expects ${placeholderCount} parameter(s), got ${params.length}`);\n process.exit(2);\n }\n // Naming a preset and never joining it would return the whole index while reading as scoped,\n // which is the one hazard of binding rather than applying. Refuse instead.\n if (preset !== undefined && !/\\bscope\\b/i.test(sql)) {\n console.error(`--preset binds a temporary \"scope\" table of the preset's paths, and ${label} never joins it, so the preset would have no effect`);\n console.error(`add: JOIN scope ON scope.\"path\" = <table>.\"path\"`);\n process.exit(2);\n }\n const { store, warnings } = await openStore(cfg);\n printWarnings(warnings);\n if (preset !== undefined) await bindScope(store, cfg, preset);\n // Streamed, not collected: `sql`'s result size is the caller's business, not ours. columns() reads the statement's own metadata, so a 0-row csv gets a header too.\n // A mid-stream SQLite error (e.g. SQLITE_BUSY outlasting busy_timeout) may leave partial output; the nonzero exit code is the failure signal, not a completeness guarantee.\n try {\n const statement = await store.raw.prepare(sql);\n const columns = statement.columns().map((c) => c.name);\n await printRowStream(statement.iterate(...params) as AsyncIterable<Row>, format, columns);\n } catch (err) {\n const hinted = columnHint(await store.docs.columns(), err as Error); // columns read while the store is still open\n await store.close();\n // A saved query or ad-hoc SQL can carry `content MATCH ?` too, so the same FTS5 punctuation trap applies to its bound parameters.\n // SQL without MATCH gets its error verbatim; search advice on a plain typo would mislead.\n if (/\\bMATCH\\b/i.test(sql)) throw searchError(hinted, params.join(' '));\n throw hinted;\n }\n await store.close();\n}\n"],"names":["CONFIG","FORMAT","SCOPE","SEARCH_FLAGS","formatOf","parse","parseK","parseSnippetCharLimit","parseSnippetCountLimit","printWarnings","rowFormatOf","runSql","scopeOf","withDb","format","type","default","config","where","preset","include","multiple","exclude","k","values","noExclude","pickFormat","allowed","String","includes","console","error","join","process","exit","argv","usage","options","positionals","parseArgs","args","help","short","strict","allowPositionals","err","message","log","usageError","undefined","parsed","Number","isInteger","value","warnings","w","warn","ctx","configPath","fn","cfg","store","resolveConfig","openStore","close","bindScope","name","insert","resolvePreset","exec","prepare","run","sql","params","label","placeholderCount","statement","columns","hinted","match","length","test","raw","map","c","printRowStream","iterate","docs","columnHint","searchError"],"mappings":"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"}
|
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"}
|
package/dist/cjs/commands/map.js
CHANGED
|
@@ -305,7 +305,7 @@ function mapTree(_0, _1) {
|
|
|
305
305
|
];
|
|
306
306
|
return [
|
|
307
307
|
4,
|
|
308
|
-
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 '.concat(scopeAnd, ' ORDER BY f."_rank" DESC LIMIT 8'))
|
|
308
|
+
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 '.concat(scopeAnd, ' ORDER BY f."_rank" DESC, f."path" ASC LIMIT 8'))
|
|
309
309
|
];
|
|
310
310
|
case 14:
|
|
311
311
|
return [
|
|
@@ -325,7 +325,7 @@ function mapTree(_0, _1) {
|
|
|
325
325
|
hubs = _tmp2;
|
|
326
326
|
return [
|
|
327
327
|
4,
|
|
328
|
-
store.prepare('SELECT "path", "_mtime" AS mtime FROM frontmatter '.concat(scopeWhere, ' ORDER BY "_mtime" DESC LIMIT 5'))
|
|
328
|
+
store.prepare('SELECT "path", "_mtime" AS mtime FROM frontmatter '.concat(scopeWhere, ' ORDER BY "_mtime" DESC, "path" ASC LIMIT 5'))
|
|
329
329
|
];
|
|
330
330
|
case 18:
|
|
331
331
|
return [
|