latticesql 4.3.7 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -69
- package/dist/cli.js +52911 -35716
- package/dist/desktop-entry.js +52495 -35437
- package/dist/gui-assets/force-graph.mjs +1 -0
- package/dist/index.cjs +41284 -24203
- package/dist/index.d.cts +2131 -509
- package/dist/index.d.ts +2131 -509
- package/dist/index.js +41170 -24101
- package/docs/api-reference.md +33 -2
- package/docs/assistant.md +28 -3
- package/docs/bugs/2026-07-05-db-source-import-then-wipe.md +71 -0
- package/docs/bugs/2026-07-06-workspace-switch-stale-settings-takeover.md +61 -0
- package/docs/bugs/2026-07-11-chat-active-context-w-routes.md +63 -0
- package/docs/bugs/2026-07-11-connector-table-unknown-table.md +55 -0
- package/docs/bugs/2026-07-12-image-vision-byo-key-auth.md +55 -0
- package/docs/bugs/2026-07-13-desktop-bulk-ingest-js-heap-oom.md +104 -0
- package/docs/computed-tables.md +200 -0
- package/docs/connectors.md +143 -147
- package/docs/desktop.md +48 -0
- package/docs/retrieval.md +41 -0
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -74,6 +74,8 @@ provenance** + a **trust/verification** workflow), reliability (**`withRetry`**
|
|
|
74
74
|
seamless **keyless cloud file-byte access** (an in-database SigV4 presigner). All
|
|
75
75
|
opt-in per table/call; absent the opt-in, behavior is byte-identical to 4.0.
|
|
76
76
|
|
|
77
|
+
**New in 5.0 (major release).** 5.0 reframes the GUI around an **Analytics view** — ask a question about your data and Lattice answers, building a **dashboard** when a picture answers best (the docked assistant is **"Ask Lattice"**). It adds **connected external data**: link a Postgres/other database or an **MCP server** and its tables mirror in as **typed, read-only** tables grouped under the source's name; **import intelligence** (`import_spreadsheet`, faithful every-row import, multi-table Excel sheets); **computed tables** (live read-only projections); and a rebuilt **chat** that acknowledges instantly and streams the answer in the background (reload never cancels an in-flight turn). **Breaking / consumer-facing changes:** the bespoke **Jira/Trello connector exports are removed** (connectors are now MCP-based); the per-user **Anthropic API-key** assistant path is retired in favor of built-in **OAuth** plus a generic **"Other AI Endpoint"** provider (base URL + key + model); and the inference-aggressiveness slider is gone (a fixed high default). Existing 3.0+/4.x configs and data silently upgrade on GUI open. Under the hood, four substrate pieces also land: (1) A **native vector search substrate**: the pgvector / sqlite-vec index now **stays in sync with writes** (inserts/updates/deletes mirror incrementally; a freshness guard falls back to an exact scan rather than ever serving a stale index), **semantic + hybrid search work for scoped cloud members** confined to the rows they may see (via a `SECURITY DEFINER` path keyed on the member's own role — an exact scan with no over-fetch inference channel), and the index is **tunable + observable** (`embeddings.index = { m, efConstruction }`, query-time `efSearch`, an internal index registry, and `lattice reindex` / `lattice index status` / `lattice doctor --fix`), and can be stored at **16-bit half precision** (`embeddings.index.quantization = 'halfvec'`, pgvector ≥ 0.7) to roughly halve its memory while the exact-scan fallback stays full precision. All opt-in; omit the knobs and the build/query is byte-identical to before. (2) A **live force-directed brain graph** across all three GUI graph surfaces (schema, per-object, and folder) — a dependency-free physics engine + live SVG renderer with drag-to-pin, zoom, neighbor highlight, and fly-in growth. (3) **Auto-update is now visible on every surface** (npm, desktop, and dev builds — previously only the npm-supervised CLI surfaced the pill), a long-open desktop window notices new releases on its own, and a `--no-auto-update` / `LATTICE_NO_AUTO_UPDATE=1` switch (default on) pins the version for testing, air-gapped, and reproducible-demo runs. (4) **Data provenance + lineage.** Every object's page now traces where its data came from across three tiers — **raw** (files / connectors), **computed** (imports / artifacts), and **observation** (AI / learning-loop edits) — via `GET /api/provenance`, shown as a force-directed graph or a grouped source table, with a per-row provenance panel; an additive internal lineage substrate (`__lattice_lineage` + an audit `source` column) records source→object edges. Relatedly, the brain graph now shows **object↔object relationships only** (`files` is a source, not a node) and the sidebar groups are collapsible. See **[docs/retrieval.md](docs/retrieval.md)** and **[docs/desktop.md](docs/desktop.md)**.
|
|
78
|
+
|
|
77
79
|
**New in 4.0 (major release — mostly drop-in):** a major version that decomposes the three largest internal modules and hardens the cloud path for many simultaneous users, while keeping the `Lattice` / GUI surface stable. **Existing 3.0+ configs and databases are migrated forward SILENTLY on open** — you usually need to do nothing. The breaking changes are auto-handled on open (or clearly documented): the per-field `ref:` shorthand is still parsed (and the GUI rewrites it to the explicit `relations:` block on disk); a legacy empty-string `deleted_at` is normalized to `NULL`; a legacy `files.path`-only row is backfilled into the reference model; the render manifest is v2-only and self-upgrades on first render. The one consumer-code change: the exported `MEMBER_GROUP` constant is replaced by **`memberGroupFor(db)`** (the member group role is now **per-cloud** — derived from the database/schema — so unrelated clouds on one Postgres cluster no longer share a group). Opening a cloud workspace is now **much faster** (one batched schema introspection instead of per-table round-trips; the owner-side RLS/grant convergence runs in the background since the owner is BYPASSRLS). See **[docs/MIGRATING-4.0.md](docs/MIGRATING-4.0.md)** for the (mostly no-op) migration and the manual steps for library/non-GUI consumers.
|
|
78
80
|
|
|
79
81
|
**New in 3.4:** the browser GUI now **updates itself** — launched from an npm install it silently installs the latest published version and keeps checking in the background, relaunching on the same port while the open tab auto-reloads onto the new build (a git checkout / `npx` copy is left untouched); **file loopback** — editing a rendered `.md` context file on disk flows back into the database through the normal write path (changelog/versioned/undoable, live in the GUI), with a public [`reverseSyncFromFiles()`](docs/api-reference.md) for embedders; on a cloud, a member's **rendered context is now scoped to their own visibility** (rendered through their RLS connection + masking view, so their assistant only ever reads rows they may see); the assistant gains a **`get_row_context`** tool (reads a record's pre-joined rendered context in one call) and **`add_column`** (add a field to an existing table on request); and the cloud gets resilience + search fixes — the open-time converge is **per-table fault-isolated** (one un-manageable table no longer breaks the whole workspace), `migrate-to-cloud` now builds the full-text index (with a public [`rebuildFtsIndexes()`](docs/api-reference.md)), and a plaintext `postgres://` URL in a config is healed into an encrypted credential reference on open. New `GET /api/version`, `GET /api/update/status`, and `POST /api/workspaces/reload` endpoints. See [docs/workspaces.md](docs/workspaces.md), [docs/cloud.md](docs/cloud.md), and [docs/assistant.md](docs/assistant.md).
|
|
@@ -122,7 +124,7 @@ opt-in per table/call; absent the opt-in, behavior is byte-identical to 4.0.
|
|
|
122
124
|
- [Pluggable backends (v1.6+)](#pluggable-backends-v16)
|
|
123
125
|
- [Architecture](#architecture)
|
|
124
126
|
- [Examples](#examples)
|
|
125
|
-
- [Connectors
|
|
127
|
+
- [MCP Connectors](#mcp-connectors)
|
|
126
128
|
- [Staying up to date](#staying-up-to-date)
|
|
127
129
|
- [Auto-update](#auto-update-v11)
|
|
128
130
|
- [Telemetry](#telemetry)
|
|
@@ -1090,6 +1092,25 @@ await db.delete('tasks', 'task-001');
|
|
|
1090
1092
|
await db.delete('event_seats', { event_id: 'e-1', seat_no: 3 });
|
|
1091
1093
|
```
|
|
1092
1094
|
|
|
1095
|
+
#### `transaction()` (v5.0+)
|
|
1096
|
+
|
|
1097
|
+
```typescript
|
|
1098
|
+
await db.transaction<T>(fn: () => Promise<T>): Promise<T>
|
|
1099
|
+
```
|
|
1100
|
+
|
|
1101
|
+
Run `fn` inside a single database transaction. Every write `fn` performs through this Lattice (`insert` / `update` / `delete` and their audit + changelog writes) commits together, or rolls back together if `fn` throws. Reads inside `fn` see its own uncommitted writes (read-your-writes). The transaction is scoped to the async context of `fn`, so two concurrent callers never accidentally share one; a nested `transaction()` reuses the outer transaction. When the adapter cannot open a transaction, `fn` runs without one.
|
|
1102
|
+
|
|
1103
|
+
```typescript
|
|
1104
|
+
// Move every row from one table to another as one atomic unit — either all
|
|
1105
|
+
// rows move, or (on any error) nothing does.
|
|
1106
|
+
await db.transaction(async () => {
|
|
1107
|
+
for (const row of rows) {
|
|
1108
|
+
await db.insert('archive', row);
|
|
1109
|
+
await db.delete('inbox', row.id);
|
|
1110
|
+
}
|
|
1111
|
+
});
|
|
1112
|
+
```
|
|
1113
|
+
|
|
1093
1114
|
#### `get()`
|
|
1094
1115
|
|
|
1095
1116
|
```typescript
|
|
@@ -2166,11 +2187,14 @@ npx lattice gui
|
|
|
2166
2187
|
npx lattice gui --config ./lattice.config.yml --output ./context --port 4317
|
|
2167
2188
|
```
|
|
2168
2189
|
|
|
2169
|
-
###
|
|
2190
|
+
### GUI layout (Analytics view + workspace)
|
|
2170
2191
|
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2192
|
+
**In 5.0 the GUI opens on the Analytics view** — a Dashboards sidebar, a tabbed
|
|
2193
|
+
dashboard canvas, and the persistent **Ask Lattice** dock. Ask a question and Lattice
|
|
2194
|
+
answers there, building a dashboard when a picture answers best; the wrench toggles the
|
|
2195
|
+
**Configure** drawer (Data Model / Inputs / Workspace). The data-browsing surface below
|
|
2196
|
+
is unchanged and reachable from the sidebar: each object's rows open as a grid of
|
|
2197
|
+
**folder tiles** rather than a spreadsheet. Click a tile to open an **item view** that
|
|
2174
2198
|
renders the row as a document built from its columns — long-form fields render as
|
|
2175
2199
|
formatted markdown — alongside that row's relationships as **sub-folders** you can
|
|
2176
2200
|
keep opening (e.g. _Authors → a person → Books → a book → Reviews_). A breadcrumb
|
|
@@ -2211,12 +2235,17 @@ across 9 tables") instead of a wall of near-identical rows. The feed is scoped t
|
|
|
2211
2235
|
the open conversation: the assistant's data changes are saved with each turn and
|
|
2212
2236
|
replayed as those cards when you reopen the chat. When the assistant references a record, it emits an inline object-link pill — a clickable chip that opens that row in the mode-aware navigator.
|
|
2213
2237
|
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
`
|
|
2238
|
+
Connect the **AI assistant** in **User Settings → Assistant** to ask questions
|
|
2239
|
+
about your data or instruct edits in natural language. The assistant calls the
|
|
2240
|
+
same operations the UI does, so its changes are audited, shown in the feed, and
|
|
2241
|
+
undoable. The built-in path is **Connect with Claude** (a subscription OAuth flow —
|
|
2242
|
+
no env setup). Or point it at **any endpoint** via **Other AI Endpoint** — an
|
|
2243
|
+
OpenAI-compatible `chat/completions` server (OpenAI, Azure, OpenRouter, a local
|
|
2244
|
+
vLLM / Ollama / LM Studio server, or your own gateway) OR a Claude-API endpoint
|
|
2245
|
+
(the Anthropic wire is auto-selected for an Anthropic host) — the first-run screen
|
|
2246
|
+
takes a base URL, API key, and model, and every assistant feature then runs on it.
|
|
2247
|
+
(A managed deployment supplies the operator's model key via `ANTHROPIC_API_KEY`
|
|
2248
|
+
env; the per-user "paste an Anthropic key" path was retired in 5.0.)
|
|
2220
2249
|
|
|
2221
2250
|
Optional extras, each enabled by its own key/binary:
|
|
2222
2251
|
|
|
@@ -2389,10 +2418,14 @@ a **Context Constructor** that turns dropped files and pasted text into linked
|
|
|
2389
2418
|
Lattice objects. It is **GUI-only and inert until you configure a credential** —
|
|
2390
2419
|
the library API is unchanged and fully backwards-compatible.
|
|
2391
2420
|
|
|
2392
|
-
- **Connect
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2421
|
+
- **Connect the assistant.** The built-in path is **Connect with Claude** — a
|
|
2422
|
+
subscription OAuth flow (PKCE) in **Settings → User → Assistant**, no env setup
|
|
2423
|
+
required. To bring your own model instead, **Other AI Endpoint** takes a base URL +
|
|
2424
|
+
API key + model (an OpenAI-compatible endpoint, or a Claude-API endpoint — the
|
|
2425
|
+
Anthropic wire is auto-selected for an Anthropic host); the credential is stored
|
|
2426
|
+
encrypted in the native `secrets` entity. (The former "paste an Anthropic API key"
|
|
2427
|
+
path was retired in 5.0 — a managed deployment supplies the operator key via
|
|
2428
|
+
`ANTHROPIC_API_KEY` env instead.)
|
|
2396
2429
|
- **Drop files / paste text / images / URLs.** Sources become native `files` rows
|
|
2397
2430
|
(referenced, not copied) and are extracted — documents (PDF / Office /
|
|
2398
2431
|
OpenDocument / EPUB / RTF) parsed **natively in-process**, **images via Claude
|
|
@@ -2411,8 +2444,9 @@ the library API is unchanged and fully backwards-compatible.
|
|
|
2411
2444
|
the optional `playwright` dependency is installed (graceful static fallback
|
|
2412
2445
|
otherwise). Tunable via the `LATTICE_URL_*` env vars — see
|
|
2413
2446
|
[`.env.example`](.env.example).
|
|
2414
|
-
- **Inference
|
|
2415
|
-
|
|
2447
|
+
- **Inference** — the assistant extrapolates (link liberality + auto-junction/auto-create
|
|
2448
|
+
gating) at a fixed high default. (The earlier user-facing "Inference Aggressiveness"
|
|
2449
|
+
slider was removed in 5.0.)
|
|
2416
2450
|
- **Context-aware.** The chat knows the record you're viewing, so "delete this
|
|
2417
2451
|
file" / "summarize this" resolve to it; and it can answer questions about Lattice
|
|
2418
2452
|
itself (e.g. "what is private mode?") via a `lattice_help` tool that searches
|
|
@@ -2805,6 +2839,8 @@ if (result.restartRequired) {
|
|
|
2805
2839
|
|
|
2806
2840
|
`autoUpdate()` is safe to call on every startup — it skips if already on the latest version. Pass `{ quiet: true }` to suppress console output.
|
|
2807
2841
|
|
|
2842
|
+
The **GUI and desktop app** auto-update on their own: `lattice gui` (when installed via npm) installs newer versions and relaunches in the background, and the desktop app applies updates on relaunch. Both show an "Update available" link next to the version chip when a newer release is published. To pin to the current version, pass `lattice gui --no-auto-update` or set `LATTICE_NO_AUTO_UPDATE=1` (the latter also covers the desktop app, which has no CLI flags).
|
|
2843
|
+
|
|
2808
2844
|
**`AutoUpdateResult`**
|
|
2809
2845
|
|
|
2810
2846
|
```typescript
|
|
@@ -2858,76 +2894,62 @@ See Scarf's own [privacy documentation](https://docs.scarf.sh) for the upstream
|
|
|
2858
2894
|
|
|
2859
2895
|
---
|
|
2860
2896
|
|
|
2861
|
-
## Connectors
|
|
2897
|
+
## MCP Connectors
|
|
2862
2898
|
|
|
2863
2899
|
Connectors sync data from external systems into Lattice as **connected data
|
|
2864
2900
|
types** — tables whose rows are ingested from a source rather than authored
|
|
2865
|
-
locally.
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2901
|
+
locally. Every connector is a standard **MCP connection**: Lattice runs as a
|
|
2902
|
+
local [Model Context Protocol](https://modelcontextprotocol.io) client and
|
|
2903
|
+
talks to the server directly from your machine — no broker, no provider-specific
|
|
2904
|
+
code. A provider is just another MCP server URL.
|
|
2905
|
+
|
|
2906
|
+
In the **GUI**, open **Configure → MCP Connectors**: paste a server URL, sign in
|
|
2907
|
+
with the provider's own OAuth in your browser (client identity via a client-ID
|
|
2908
|
+
metadata document, dynamic registration, or a pre-registered client id — the
|
|
2909
|
+
form asks only when the server requires one). Each server is **introspected at
|
|
2910
|
+
connect and modeled into typed, read-only tables — one per record kind** (scalar
|
|
2911
|
+
fields become real columns, nested data spills to a `data` JSON column),
|
|
2912
|
+
namespaced per connection and grouped under a **per-server header named for the
|
|
2913
|
+
server's brand** (e.g. an MCP server at `mcp.acme.com` → an **ACME** group with its
|
|
2914
|
+
own tables). A server that exposes nothing modelable falls back to a single flat
|
|
2915
|
+
`mcp_items` table. Connect any number of servers side by side; each row shows
|
|
2916
|
+
status, last sync, and Refresh / Disconnect / Reconnect. Tokens are stored
|
|
2917
|
+
encrypted on your machine and synced data stays local.
|
|
2918
|
+
|
|
2919
|
+
Programmatically, the same engine is exposed as a library surface:
|
|
2877
2920
|
|
|
2878
2921
|
```typescript
|
|
2879
2922
|
import {
|
|
2880
|
-
|
|
2923
|
+
genericConnector,
|
|
2881
2924
|
createConnector,
|
|
2882
2925
|
syncConnector,
|
|
2883
2926
|
syncIfStale,
|
|
2884
2927
|
disconnectConnector,
|
|
2885
2928
|
} from 'latticesql';
|
|
2886
2929
|
|
|
2887
|
-
const connector =
|
|
2888
|
-
|
|
2889
|
-
// 1. Validate + store the member's Atlassian credentials (site + email + API token):
|
|
2890
|
-
const { connectionId, displayName } = await connector.connect({
|
|
2891
|
-
site: 'https://your-domain.atlassian.net',
|
|
2892
|
-
email: 'you@example.com',
|
|
2893
|
-
apiToken: process.env.JIRA_API_TOKEN!,
|
|
2894
|
-
});
|
|
2895
|
-
|
|
2896
|
-
// 2. Register + sync (defines the six jira_* connected tables and ingests):
|
|
2930
|
+
const connector = genericConnector();
|
|
2897
2931
|
const connectorId = await createConnector(db, {
|
|
2898
|
-
connector: '
|
|
2899
|
-
toolkit: '
|
|
2900
|
-
displayName:
|
|
2901
|
-
connectionRef: connectionId,
|
|
2932
|
+
connector: 'mcp',
|
|
2933
|
+
toolkit: 'mcp',
|
|
2934
|
+
displayName: 'My MCP server',
|
|
2935
|
+
connectionRef: connectionId, // from the OAuth/stdio connect flow
|
|
2902
2936
|
connectedBy: 'user-123',
|
|
2903
2937
|
});
|
|
2904
|
-
await syncConnector(db, connector, connectorId);
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
await syncIfStale(db, connector, connectorId);
|
|
2908
|
-
|
|
2909
|
-
// 4. Disconnect — soft-deletes the ingested rows + drops the stored credentials.
|
|
2910
|
-
await disconnectConnector(db, connector, connectorId);
|
|
2938
|
+
await syncConnector(db, connector, connectorId); // ingest (idempotent upserts)
|
|
2939
|
+
await syncIfStale(db, connector, connectorId); // re-sync on load if > 1h old
|
|
2940
|
+
await disconnectConnector(db, connector, connectorId); // soft teardown
|
|
2911
2941
|
```
|
|
2912
2942
|
|
|
2913
|
-
Connected
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
vanished from the source.
|
|
2919
|
-
|
|
2920
|
-
On a cloud workspace, the owner calls `enableConnectorRls(db, connector, 'jira')`
|
|
2921
|
-
to scope connected rows per member (private by default, or shared per type).
|
|
2943
|
+
Connected rows are full Lattice rows: queryable, full-text searchable, rendered
|
|
2944
|
+
to context, per-member `private` by default on a cloud
|
|
2945
|
+
(`enableConnectorRls(db, connector, 'mcp')`), and stamped with immutable lineage
|
|
2946
|
+
(`_source_connector_id`, `_source_model`). A re-sync upserts on the natural key
|
|
2947
|
+
and soft-deletes rows that vanished from the source.
|
|
2922
2948
|
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
See [docs/connectors.md](docs/connectors.md) for the full guide and the connector
|
|
2928
|
-
SPI (to add a new connector).
|
|
2929
|
-
|
|
2930
|
-
---
|
|
2949
|
+
See [docs/connectors.md](docs/connectors.md) for the full guide — the OAuth
|
|
2950
|
+
client-identity mechanisms, the privacy model, the per-server typed-table
|
|
2951
|
+
modeling (with the `mcp_items` fallback), and the connector SPI for embedding a
|
|
2952
|
+
specific provider.
|
|
2931
2953
|
|
|
2932
2954
|
## Contributing
|
|
2933
2955
|
|