latticesql 4.3.8 → 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 +52895 -35705
- package/dist/desktop-entry.js +52510 -35457
- package/dist/gui-assets/force-graph.mjs +1 -0
- package/dist/index.cjs +41272 -24196
- package/dist/index.d.cts +2131 -509
- package/dist/index.d.ts +2131 -509
- package/dist/index.js +41207 -24143
- 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/dist/index.d.cts
CHANGED
|
@@ -54,10 +54,40 @@ interface RenderCursor {
|
|
|
54
54
|
grants: string | null;
|
|
55
55
|
owners: string | null;
|
|
56
56
|
}
|
|
57
|
+
/** A rendered file Lattice wrote outside the entity-context trees (a phase-1
|
|
58
|
+
* table rollup), tracked so it has a lifecycle: when its path changes or its
|
|
59
|
+
* table disappears, the old path moves to `retiredFiles` and is pruned by the
|
|
60
|
+
* next reconciliation — hash-guarded so a user-edited file is never deleted. */
|
|
61
|
+
interface TableFileManifestInfo {
|
|
62
|
+
/** Path relative to the output dir (the compiled def.outputFile). */
|
|
63
|
+
path: string;
|
|
64
|
+
/** SHA-256 hex digest of the last content Lattice rendered to it. */
|
|
65
|
+
hash: string;
|
|
66
|
+
}
|
|
57
67
|
interface LatticeManifest {
|
|
58
68
|
version: 1 | 2;
|
|
59
69
|
generated_at: string;
|
|
60
70
|
entityContexts: Record<string, EntityContextManifestEntry>;
|
|
71
|
+
/**
|
|
72
|
+
* Phase-1 table rollup files, keyed by table (see {@link TableFileManifestInfo}).
|
|
73
|
+
* Optional — a v3 manifest has no rollup history, and reconciliation treats the
|
|
74
|
+
* absence as "prune nothing" (never as delete-everything).
|
|
75
|
+
*/
|
|
76
|
+
tableFiles?: Record<string, TableFileManifestInfo>;
|
|
77
|
+
/**
|
|
78
|
+
* Phase-2 multi-output files, keyed by multi name: every path the multi
|
|
79
|
+
* produced on its last render, with content hashes. A key that disappears (a
|
|
80
|
+
* deleted row) retires its path into `retiredFiles` on the next render.
|
|
81
|
+
*/
|
|
82
|
+
multiFiles?: Record<string, Record<string, string>>;
|
|
83
|
+
/**
|
|
84
|
+
* Rendered files whose path is no longer produced by the current schema (an
|
|
85
|
+
* outputFile change, a dropped table). Each entry persists here until the
|
|
86
|
+
* reconciliation pass actually deletes it (only when the on-disk content still
|
|
87
|
+
* hashes to Lattice's own last write) or the file disappears — so a crash
|
|
88
|
+
* between the manifest write and the prune can never orphan a file forever.
|
|
89
|
+
*/
|
|
90
|
+
retiredFiles?: TableFileManifestInfo[];
|
|
61
91
|
/**
|
|
62
92
|
* Render-output format version the tree was produced with (see
|
|
63
93
|
* {@link TEMPLATE_VERSION}). Optional: a manifest written before this field
|
|
@@ -836,6 +866,287 @@ declare class ConnectedSourceImmutableError extends Error {
|
|
|
836
866
|
constructor(table: string, column: string);
|
|
837
867
|
}
|
|
838
868
|
|
|
869
|
+
/**
|
|
870
|
+
* Scalar types recognised in `lattice.config.yml` field definitions.
|
|
871
|
+
*
|
|
872
|
+
* | YAML type | SQLite type | TypeScript type |
|
|
873
|
+
* | ----------- | ----------- | --------------- |
|
|
874
|
+
* | `uuid` | TEXT | string |
|
|
875
|
+
* | `text` | TEXT | string |
|
|
876
|
+
* | `integer` | INTEGER | number |
|
|
877
|
+
* | `int` | INTEGER | number |
|
|
878
|
+
* | `real` | REAL | number |
|
|
879
|
+
* | `float` | REAL | number |
|
|
880
|
+
* | `boolean` | INTEGER | boolean |
|
|
881
|
+
* | `bool` | INTEGER | boolean |
|
|
882
|
+
* | `datetime` | TEXT | string |
|
|
883
|
+
* | `date` | TEXT | string |
|
|
884
|
+
* | `blob` | BLOB | Buffer |
|
|
885
|
+
*/
|
|
886
|
+
type LatticeFieldType = 'uuid' | 'text' | 'integer' | 'int' | 'real' | 'float' | 'boolean' | 'bool' | 'datetime' | 'date' | 'blob';
|
|
887
|
+
/**
|
|
888
|
+
* A single field (column) definition in a `lattice.config.yml` entity.
|
|
889
|
+
*
|
|
890
|
+
* @example
|
|
891
|
+
* ```yaml
|
|
892
|
+
* id: { type: uuid, primaryKey: true }
|
|
893
|
+
* title: { type: text, required: true }
|
|
894
|
+
* status: { type: text, default: open }
|
|
895
|
+
* assignee_id: { type: uuid }
|
|
896
|
+
* score: { type: integer, default: 0 }
|
|
897
|
+
* ```
|
|
898
|
+
*/
|
|
899
|
+
interface LatticeFieldDef {
|
|
900
|
+
/** Column data type */
|
|
901
|
+
type: LatticeFieldType;
|
|
902
|
+
/** Mark this column as the table's primary key */
|
|
903
|
+
primaryKey?: boolean;
|
|
904
|
+
/** Column is NOT NULL */
|
|
905
|
+
required?: boolean;
|
|
906
|
+
/** SQL DEFAULT value */
|
|
907
|
+
default?: string | number | boolean;
|
|
908
|
+
/**
|
|
909
|
+
* Per-column audience (Stage-0 scaffolding for the per-viewer enrichment
|
|
910
|
+
* model). Names who may see this column's value in a cloud. Omitted ⇒
|
|
911
|
+
* `row-audience` — the value is visible to exactly whoever can see the row,
|
|
912
|
+
* which is today's behavior, so leaving it unset changes nothing. Later
|
|
913
|
+
* stages parse a richer grammar (e.g. `subject+role:hr`) and generate a
|
|
914
|
+
* cell-masking view from it; Stage-0 only records the metadata.
|
|
915
|
+
*/
|
|
916
|
+
audience?: string;
|
|
917
|
+
/**
|
|
918
|
+
* DEPRECATED (3.x) per-field foreign-key shorthand: `ref: <targetTable>` declared
|
|
919
|
+
* a `belongsTo` whose relation name is the field name with a trailing `_id`
|
|
920
|
+
* stripped. Superseded by the explicit entity-level `relations:` block. 4.0 still
|
|
921
|
+
* PARSES it (converted to a `belongsTo` in-memory) so existing 3.0+ configs keep
|
|
922
|
+
* working, and the GUI silently rewrites it to `relations:` on open so configs
|
|
923
|
+
* migrate forward. A future major may drop this once configs have upgraded.
|
|
924
|
+
*/
|
|
925
|
+
ref?: string;
|
|
926
|
+
/**
|
|
927
|
+
* Marks this field as a COMPUTED column: a real, materialized column on the base
|
|
928
|
+
* table whose value is derived (not hand-entered) using one of the computed field
|
|
929
|
+
* kinds (alias / calc / ai_classify / ai_transform / aggregate — the same vocabulary
|
|
930
|
+
* the retired computed-TABLE views used). Because it is a real column it is
|
|
931
|
+
* queryable/filterable/sortable and appears in `SELECT *`. A field is computed iff it
|
|
932
|
+
* carries `computed:`; deterministic kinds recompute synchronously on write, AI kinds
|
|
933
|
+
* fill asynchronously. See src/schema/computed-field.ts.
|
|
934
|
+
*/
|
|
935
|
+
computed?: ComputedFieldDef;
|
|
936
|
+
}
|
|
937
|
+
/**
|
|
938
|
+
* Inline render spec inside YAML — a flat object alternative to `TemplateRenderSpec`.
|
|
939
|
+
*
|
|
940
|
+
* @example
|
|
941
|
+
* ```yaml
|
|
942
|
+
* render:
|
|
943
|
+
* template: default-list
|
|
944
|
+
* formatRow: "{{title}} — {{status}}"
|
|
945
|
+
* ```
|
|
946
|
+
*/
|
|
947
|
+
interface LatticeEntityRenderSpec {
|
|
948
|
+
template: string;
|
|
949
|
+
formatRow?: string;
|
|
950
|
+
}
|
|
951
|
+
/**
|
|
952
|
+
* A single entity (table) definition in `lattice.config.yml`.
|
|
953
|
+
*
|
|
954
|
+
* @example
|
|
955
|
+
* ```yaml
|
|
956
|
+
* ticket:
|
|
957
|
+
* fields:
|
|
958
|
+
* id: { type: uuid, primaryKey: true }
|
|
959
|
+
* title: { type: text, required: true }
|
|
960
|
+
* assignee_id: { type: uuid }
|
|
961
|
+
* relations:
|
|
962
|
+
* assignee:
|
|
963
|
+
* type: belongsTo
|
|
964
|
+
* table: user
|
|
965
|
+
* foreignKey: assignee_id
|
|
966
|
+
* render: default-list
|
|
967
|
+
* outputFile: context/TICKETS.md
|
|
968
|
+
* ```
|
|
969
|
+
*/
|
|
970
|
+
interface LatticeEntityDef {
|
|
971
|
+
/** Column definitions */
|
|
972
|
+
fields: Record<string, LatticeFieldDef>;
|
|
973
|
+
/**
|
|
974
|
+
* Explicit `belongsTo` relations for this entity, keyed by relation name.
|
|
975
|
+
*
|
|
976
|
+
* Each entry declares a foreign key on THIS entity pointing at another
|
|
977
|
+
* table: `{ type: belongsTo, table, foreignKey, references? }`. The
|
|
978
|
+
* `foreignKey` names a plain field on this entity; `references` is the
|
|
979
|
+
* column on the related table (defaults to its primary key). The relation
|
|
980
|
+
* name (the map key) is whatever you choose — it is not derived from the
|
|
981
|
+
* field name.
|
|
982
|
+
*
|
|
983
|
+
* @example
|
|
984
|
+
* ```yaml
|
|
985
|
+
* relations:
|
|
986
|
+
* assignee:
|
|
987
|
+
* type: belongsTo
|
|
988
|
+
* table: user
|
|
989
|
+
* foreignKey: assignee_id
|
|
990
|
+
* # references: id # optional; defaults to the target's primary key
|
|
991
|
+
* ```
|
|
992
|
+
*/
|
|
993
|
+
relations?: Record<string, BelongsToRelation>;
|
|
994
|
+
/**
|
|
995
|
+
* How to render rows into context text.
|
|
996
|
+
* Accepts the same forms as `TableDefinition.render`:
|
|
997
|
+
* - A `BuiltinTemplateName` string (e.g. `default-list`)
|
|
998
|
+
* - A `{ template, formatRow }` object for hooks
|
|
999
|
+
*/
|
|
1000
|
+
render?: string | LatticeEntityRenderSpec;
|
|
1001
|
+
/** Render output file path (relative to the config file directory) */
|
|
1002
|
+
outputFile: string;
|
|
1003
|
+
/**
|
|
1004
|
+
* Optional explicit primary key override.
|
|
1005
|
+
* If omitted, the field with `primaryKey: true` is used.
|
|
1006
|
+
* Accepts a single column name or an array for composite keys.
|
|
1007
|
+
*/
|
|
1008
|
+
primaryKey?: string | string[];
|
|
1009
|
+
}
|
|
1010
|
+
/**
|
|
1011
|
+
* A single field of a computed table. Every field has a direct computation:
|
|
1012
|
+
*
|
|
1013
|
+
* - `alias` — project a base column (`'status'`) or a dotted belongsTo path
|
|
1014
|
+
* (`'assignee.team.name'`, resolved through declared relations).
|
|
1015
|
+
* - `calc` — a sandboxed calculation expression over base columns / belongsTo
|
|
1016
|
+
* paths (see `schema/calc-expr.ts` for the grammar). `type` is the display
|
|
1017
|
+
* type; defaults to `text`.
|
|
1018
|
+
* - `ai_classify` — a model-assigned label for the field's `input` value,
|
|
1019
|
+
* constrained to `labels`. Model outputs are materialized once into the
|
|
1020
|
+
* `__lattice_ai_map` bookkeeping table and LEFT JOINed by the view — the
|
|
1021
|
+
* model is never re-run at read time.
|
|
1022
|
+
* - `ai_transform` — a model-derived free-form value over `inputs` (order is
|
|
1023
|
+
* part of the cache identity). Materialized into `__lattice_ai_cell` per
|
|
1024
|
+
* row and LEFT JOINed; a changed source row makes the join miss, so the
|
|
1025
|
+
* field reads NULL until the next fill pass — never a stale value.
|
|
1026
|
+
* - `aggregate` — fold many junction rows into one scalar per base row via a
|
|
1027
|
+
* correlated subquery. `via` is `'<junctionTable>.<remoteRelationOrTable>'`
|
|
1028
|
+
* (e.g. `'ticket_tags.tag'`); `column` names the remote column to aggregate
|
|
1029
|
+
* (required for every `fn` except `count`).
|
|
1030
|
+
*/
|
|
1031
|
+
type ComputedFieldDef = {
|
|
1032
|
+
kind: 'alias';
|
|
1033
|
+
source: string;
|
|
1034
|
+
} | {
|
|
1035
|
+
kind: 'calc';
|
|
1036
|
+
expr: string;
|
|
1037
|
+
type?: LatticeFieldType;
|
|
1038
|
+
} | {
|
|
1039
|
+
kind: 'ai_classify';
|
|
1040
|
+
input: string;
|
|
1041
|
+
prompt: string;
|
|
1042
|
+
labels: string[];
|
|
1043
|
+
model?: 'default' | 'cheapest';
|
|
1044
|
+
} | {
|
|
1045
|
+
kind: 'ai_transform';
|
|
1046
|
+
inputs: string[];
|
|
1047
|
+
prompt: string;
|
|
1048
|
+
model?: 'default' | 'cheapest';
|
|
1049
|
+
} | {
|
|
1050
|
+
kind: 'aggregate';
|
|
1051
|
+
via: string;
|
|
1052
|
+
fn: 'count' | 'sum' | 'avg' | 'min' | 'max' | 'concat';
|
|
1053
|
+
column?: string;
|
|
1054
|
+
};
|
|
1055
|
+
/**
|
|
1056
|
+
* A computed table: a live, read-only SQL VIEW defined over one base table
|
|
1057
|
+
* (a declared entity or another computed table). The view always projects the
|
|
1058
|
+
* base primary key as `id` first, then each field in declaration order.
|
|
1059
|
+
* Registered at init as a queryable, non-writable table.
|
|
1060
|
+
*
|
|
1061
|
+
* @example
|
|
1062
|
+
* ```yaml
|
|
1063
|
+
* computed:
|
|
1064
|
+
* ticket_summary:
|
|
1065
|
+
* base: ticket
|
|
1066
|
+
* fields:
|
|
1067
|
+
* title: { kind: alias, source: title }
|
|
1068
|
+
* team: { kind: alias, source: assignee.team.name }
|
|
1069
|
+
* is_urgent: { kind: calc, expr: "priority >= 3", type: boolean }
|
|
1070
|
+
* tag_count: { kind: aggregate, via: ticket_tags.tag, fn: count }
|
|
1071
|
+
* ```
|
|
1072
|
+
*/
|
|
1073
|
+
interface ComputedTableDef {
|
|
1074
|
+
/** Base table: a declared entity or another computed table. */
|
|
1075
|
+
base: string;
|
|
1076
|
+
/** Optional human description (display metadata only). */
|
|
1077
|
+
description?: string;
|
|
1078
|
+
/** Field definitions, projected in declaration order. */
|
|
1079
|
+
fields: Record<string, ComputedFieldDef>;
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* The top-level `lattice.config.yml` document.
|
|
1083
|
+
*
|
|
1084
|
+
* @example
|
|
1085
|
+
* ```yaml
|
|
1086
|
+
* db: ./data/app.db
|
|
1087
|
+
* entities:
|
|
1088
|
+
* ticket:
|
|
1089
|
+
* fields:
|
|
1090
|
+
* id: { type: uuid, primaryKey: true }
|
|
1091
|
+
* title: { type: text, required: true }
|
|
1092
|
+
* render: default-list
|
|
1093
|
+
* outputFile: context/TICKETS.md
|
|
1094
|
+
* ```
|
|
1095
|
+
*/
|
|
1096
|
+
interface LatticeConfig {
|
|
1097
|
+
/** Path to the SQLite database file (relative to the config file) */
|
|
1098
|
+
db: string;
|
|
1099
|
+
/** Entity (table) definitions */
|
|
1100
|
+
entities: Record<string, LatticeEntityDef>;
|
|
1101
|
+
/** Entity context directory definitions */
|
|
1102
|
+
entityContexts?: Record<string, LatticeEntityContextDef>;
|
|
1103
|
+
/** Computed-table (read-only SQL projection) definitions */
|
|
1104
|
+
computed?: Record<string, ComputedTableDef>;
|
|
1105
|
+
}
|
|
1106
|
+
/**
|
|
1107
|
+
* Source spec in YAML config — either the shorthand string 'self' or an object.
|
|
1108
|
+
*/
|
|
1109
|
+
type LatticeEntityContextSourceDef = 'self' | {
|
|
1110
|
+
type: 'hasMany';
|
|
1111
|
+
table: string;
|
|
1112
|
+
foreignKey: string;
|
|
1113
|
+
references?: string;
|
|
1114
|
+
} | {
|
|
1115
|
+
type: 'manyToMany';
|
|
1116
|
+
junctionTable: string;
|
|
1117
|
+
localKey: string;
|
|
1118
|
+
remoteKey: string;
|
|
1119
|
+
remoteTable: string;
|
|
1120
|
+
references?: string;
|
|
1121
|
+
} | {
|
|
1122
|
+
type: 'belongsTo';
|
|
1123
|
+
table: string;
|
|
1124
|
+
foreignKey: string;
|
|
1125
|
+
references?: string;
|
|
1126
|
+
};
|
|
1127
|
+
/** A single per-entity file spec in YAML config */
|
|
1128
|
+
interface LatticeEntityContextFileDef {
|
|
1129
|
+
source: LatticeEntityContextSourceDef;
|
|
1130
|
+
template: string;
|
|
1131
|
+
budget?: number;
|
|
1132
|
+
omitIfEmpty?: boolean;
|
|
1133
|
+
}
|
|
1134
|
+
/** Entity context definition in YAML config */
|
|
1135
|
+
interface LatticeEntityContextDef {
|
|
1136
|
+
slug: string;
|
|
1137
|
+
directoryRoot?: string;
|
|
1138
|
+
protectedFiles?: string[];
|
|
1139
|
+
index?: {
|
|
1140
|
+
outputFile: string;
|
|
1141
|
+
render: string;
|
|
1142
|
+
};
|
|
1143
|
+
files: Record<string, LatticeEntityContextFileDef>;
|
|
1144
|
+
combined?: {
|
|
1145
|
+
outputFile: string;
|
|
1146
|
+
exclude?: string[];
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
|
|
839
1150
|
/**
|
|
840
1151
|
* Declarative computed columns + materialized rollups.
|
|
841
1152
|
*
|
|
@@ -1484,6 +1795,15 @@ interface TableDefinition {
|
|
|
1484
1795
|
* `refreshMaterializedRollups`. See {@link MaterializedRollupSpec}.
|
|
1485
1796
|
*/
|
|
1486
1797
|
materializedRollups?: Record<string, MaterializedRollupSpec>;
|
|
1798
|
+
/**
|
|
1799
|
+
* Serializable computed COLUMNS (5.0+) — a real, materialized column derived by a
|
|
1800
|
+
* computed field kind (alias / calc / ai_classify / ai_transform / aggregate; the
|
|
1801
|
+
* same vocabulary the retired computed-TABLE views used). Because it is a real
|
|
1802
|
+
* column it is queryable / filterable / sortable and appears in `SELECT *`.
|
|
1803
|
+
* Deterministic kinds recompute on write (bounded, dep-gated); AI kinds fill
|
|
1804
|
+
* asynchronously. Compiled + wired by {@link file://./schema/computed-field.ts}.
|
|
1805
|
+
*/
|
|
1806
|
+
computedFields?: Record<string, ComputedFieldDef>;
|
|
1487
1807
|
/**
|
|
1488
1808
|
* Mark this table as a *connected data type* (4.3+) — its rows are ingested
|
|
1489
1809
|
* from an external system through a connector rather than authored locally.
|
|
@@ -1512,6 +1832,25 @@ interface FtsConfig {
|
|
|
1512
1832
|
/** Columns to index. Omit to auto-detect the table's text columns. */
|
|
1513
1833
|
fields?: string[];
|
|
1514
1834
|
}
|
|
1835
|
+
/**
|
|
1836
|
+
* Native ANN index build tuning (pgvector HNSW). Defaults match pgvector's own,
|
|
1837
|
+
* so omitting this builds exactly as before. Has no effect on the in-process scan
|
|
1838
|
+
* or on sqlite-vec.
|
|
1839
|
+
*/
|
|
1840
|
+
interface VectorIndexOptions {
|
|
1841
|
+
/** HNSW graph degree `m` (pgvector default 16). Higher → better recall, more memory + slower build. */
|
|
1842
|
+
m?: number;
|
|
1843
|
+
/** HNSW build candidate-list size `ef_construction` (pgvector default 64). Higher → better recall, slower build. */
|
|
1844
|
+
efConstruction?: number;
|
|
1845
|
+
/**
|
|
1846
|
+
* Index storage precision. `'halfvec'` (pgvector ≥ 0.7) stores the derived index
|
|
1847
|
+
* at 16-bit half precision — roughly halving its memory at a small recall cost —
|
|
1848
|
+
* while the embeddings store stays full precision, so the scan fallback remains
|
|
1849
|
+
* exact. Default `'none'` (full-precision `vector`). pgvector only; ignored on
|
|
1850
|
+
* sqlite-vec.
|
|
1851
|
+
*/
|
|
1852
|
+
quantization?: 'none' | 'halfvec';
|
|
1853
|
+
}
|
|
1515
1854
|
/**
|
|
1516
1855
|
* Configuration for embedding-based semantic search on a table.
|
|
1517
1856
|
*/
|
|
@@ -1554,6 +1893,12 @@ interface EmbeddingsConfig {
|
|
|
1554
1893
|
* so it fails loudly and tells you to add a pgvector index or raise the cap.
|
|
1555
1894
|
*/
|
|
1556
1895
|
maxScanChunks?: number;
|
|
1896
|
+
/**
|
|
1897
|
+
* Optional native-index build tuning (pgvector HNSW `m` / `ef_construction`),
|
|
1898
|
+
* applied by `buildVectorIndex`. Omit for pgvector's defaults. No effect on the
|
|
1899
|
+
* in-process scan or sqlite-vec. Backward compatible — omitting it builds as before.
|
|
1900
|
+
*/
|
|
1901
|
+
index?: VectorIndexOptions;
|
|
1557
1902
|
}
|
|
1558
1903
|
/**
|
|
1559
1904
|
* Options for `Lattice.search()`.
|
|
@@ -1580,6 +1925,12 @@ interface SearchOptions {
|
|
|
1580
1925
|
* to `topK`. Defaults to `max(topK * 4, 20)`. Ignored when no reranker is set.
|
|
1581
1926
|
*/
|
|
1582
1927
|
rerankPoolSize?: number;
|
|
1928
|
+
/**
|
|
1929
|
+
* Query-time HNSW search breadth (pgvector `hnsw.ef_search`) for the indexed
|
|
1930
|
+
* vector arm. Higher trades latency for recall. Omit for pgvector's default. No
|
|
1931
|
+
* effect without a native index (the in-process scan is already exact).
|
|
1932
|
+
*/
|
|
1933
|
+
efSearch?: number;
|
|
1583
1934
|
}
|
|
1584
1935
|
/**
|
|
1585
1936
|
* A single search result returned by `Lattice.search()`.
|
|
@@ -1781,6 +2132,14 @@ interface CountOptions {
|
|
|
1781
2132
|
/** Advanced filter clauses (same as QueryOptions.filters) */
|
|
1782
2133
|
filters?: FilterExpr[];
|
|
1783
2134
|
}
|
|
2135
|
+
interface BoundedCountOptions extends CountOptions {
|
|
2136
|
+
/**
|
|
2137
|
+
* Stop counting after this many matching rows (default 1000). The query scans at
|
|
2138
|
+
* most `cap + 1` rows, so it never becomes an O(table) COUNT on a huge table;
|
|
2139
|
+
* callers render a result greater than `cap` as an approximate "cap+".
|
|
2140
|
+
*/
|
|
2141
|
+
cap?: number;
|
|
2142
|
+
}
|
|
1784
2143
|
/** SQL aggregate function. */
|
|
1785
2144
|
type AggregateFunction = 'count' | 'sum' | 'avg' | 'min' | 'max';
|
|
1786
2145
|
/** One aggregate column in an {@link AggregateOptions}. */
|
|
@@ -1914,6 +2273,9 @@ interface SeedResult {
|
|
|
1914
2273
|
upserted: number;
|
|
1915
2274
|
linked: number;
|
|
1916
2275
|
softDeleted: number;
|
|
2276
|
+
/** Records skipped because they had no natural-key value to identity-match on (so they
|
|
2277
|
+
* couldn't be upserted). 0 when every record had a key. Surfaced, never silently dropped. */
|
|
2278
|
+
skipped: number;
|
|
1917
2279
|
/**
|
|
1918
2280
|
* Links whose target row did not resolve. Empty when every link
|
|
1919
2281
|
* resolved. Always present, so callers can check
|
|
@@ -2623,7 +2985,7 @@ declare class EmbeddingScanTooLargeError extends Error {
|
|
|
2623
2985
|
* chunk vectors. Either way results respect `deleted_at IS NULL` on the base
|
|
2624
2986
|
* table and are de-duplicated to the best-scoring chunk per row.
|
|
2625
2987
|
*/
|
|
2626
|
-
declare function searchByEmbedding(adapter: StorageAdapter, table: string, queryText: string, config: EmbeddingsConfig, topK: number, minScore: number, pkColumn?: string): Promise<SearchResult[]>;
|
|
2988
|
+
declare function searchByEmbedding(adapter: StorageAdapter, table: string, queryText: string, config: EmbeddingsConfig, topK: number, minScore: number, pkColumn?: string, isCloudMember?: boolean, efSearch?: number): Promise<SearchResult[]>;
|
|
2627
2989
|
interface RefreshEmbeddingsOptions {
|
|
2628
2990
|
/** Only re-embed rows whose stored model differs from `config.modelId`. */
|
|
2629
2991
|
staleModelOnly?: boolean;
|
|
@@ -2747,6 +3109,14 @@ interface HybridSearchOptions {
|
|
|
2747
3109
|
ranking?: RankingOptions;
|
|
2748
3110
|
/** Optional reranker over the fused top candidates (graceful fallback). */
|
|
2749
3111
|
reranker?: RerankerFn;
|
|
3112
|
+
/**
|
|
3113
|
+
* Caller is a scoped cloud member (no grant on the internal embeddings store /
|
|
3114
|
+
* vector index). Routes the vector arm and row materialization through the
|
|
3115
|
+
* member-safe, row-visibility-filtered paths. Default false (owner / local).
|
|
3116
|
+
*/
|
|
3117
|
+
isCloudMember?: boolean;
|
|
3118
|
+
/** Query-time HNSW search breadth (pgvector `hnsw.ef_search`) for the vector arm. */
|
|
3119
|
+
efSearch?: number;
|
|
2750
3120
|
}
|
|
2751
3121
|
/** Per-result score breakdown (the `--explain` payload). */
|
|
2752
3122
|
interface HybridScoreBreakdown {
|
|
@@ -2910,18 +3280,569 @@ declare function graphAdjacencyBoost<T extends {
|
|
|
2910
3280
|
}>(adapter: StorageAdapter, results: T[], opts: GraphBoostOptions): Promise<GraphBoostResult<T>[]>;
|
|
2911
3281
|
|
|
2912
3282
|
/**
|
|
2913
|
-
*
|
|
2914
|
-
*
|
|
2915
|
-
*
|
|
2916
|
-
*
|
|
2917
|
-
*
|
|
2918
|
-
*
|
|
2919
|
-
*
|
|
2920
|
-
*
|
|
2921
|
-
*
|
|
2922
|
-
*
|
|
2923
|
-
*
|
|
2924
|
-
*
|
|
3283
|
+
* Sandboxed calculation-expression language for computed-table `calc` fields.
|
|
3284
|
+
*
|
|
3285
|
+
* A tokenizer + recursive-descent parser produce a typed AST; SQL is emitted
|
|
3286
|
+
* by re-serializing that AST. Raw user text NEVER reaches the SQL string —
|
|
3287
|
+
* this module is the injection boundary for computed tables. Anything outside
|
|
3288
|
+
* the grammar (semicolons, comment sequences, subqueries, table names, bind
|
|
3289
|
+
* parameters, double quotes, unknown functions) has no token or production,
|
|
3290
|
+
* so it fails with a parse error instead of ever appearing in SQL.
|
|
3291
|
+
*
|
|
3292
|
+
* Supported grammar (precedence, loosest → tightest):
|
|
3293
|
+
*
|
|
3294
|
+
* OR
|
|
3295
|
+
* AND
|
|
3296
|
+
* NOT <expr>
|
|
3297
|
+
* comparison: `= != <> < <= > >=`, `IS [NOT] NULL`, `[NOT] LIKE`,
|
|
3298
|
+
* `[NOT] IN (<literal list>)`, `[NOT] BETWEEN a AND b`
|
|
3299
|
+
* `||` (string concatenation)
|
|
3300
|
+
* `+ -`
|
|
3301
|
+
* `* / %`
|
|
3302
|
+
* unary `-`
|
|
3303
|
+
* primary: literals, column refs, allowlisted functions, CAST, CASE, `( )`
|
|
3304
|
+
*
|
|
3305
|
+
* Literals: numeric (`12`, `3.5`), `'string'` (with `''` as the only escape,
|
|
3306
|
+
* re-escaped on emit), `NULL`, `TRUE`/`FALSE`. Column refs are a bare
|
|
3307
|
+
* identifier or a dotted belongsTo path, validated at parse time by a
|
|
3308
|
+
* caller-supplied resolver; at emit time the compiler maps each path to a
|
|
3309
|
+
* `"alias"."column"` pair, so identifiers in the output are always
|
|
3310
|
+
* compiler-produced. Emitted expressions are fully parenthesized, so the
|
|
3311
|
+
* grammar's precedence is explicit in the SQL and identical on both dialects.
|
|
3312
|
+
*
|
|
3313
|
+
* Pure module: no I/O, no imports beyond types.
|
|
3314
|
+
*/
|
|
3315
|
+
type CalcDialect = 'sqlite' | 'postgres';
|
|
3316
|
+
/** Target types accepted by `CAST(expr AS <type>)`. */
|
|
3317
|
+
type CalcCastType = 'TEXT' | 'INTEGER' | 'REAL';
|
|
3318
|
+
/** Binary operators preserved in the AST (comparison `!=` normalizes to `<>`). */
|
|
3319
|
+
type BinaryOp = '+' | '-' | '*' | '/' | '%' | '||' | '=' | '<>' | '<' | '<=' | '>' | '>=';
|
|
3320
|
+
/** Typed AST. Only these shapes exist — SQL is produced exclusively from them. */
|
|
3321
|
+
type CalcNode = {
|
|
3322
|
+
t: 'num';
|
|
3323
|
+
lexeme: string;
|
|
3324
|
+
} | {
|
|
3325
|
+
t: 'str';
|
|
3326
|
+
value: string;
|
|
3327
|
+
} | {
|
|
3328
|
+
t: 'null';
|
|
3329
|
+
} | {
|
|
3330
|
+
t: 'bool';
|
|
3331
|
+
value: boolean;
|
|
3332
|
+
} | {
|
|
3333
|
+
t: 'col';
|
|
3334
|
+
path: readonly string[];
|
|
3335
|
+
} | {
|
|
3336
|
+
t: 'bin';
|
|
3337
|
+
op: BinaryOp;
|
|
3338
|
+
left: CalcNode;
|
|
3339
|
+
right: CalcNode;
|
|
3340
|
+
} | {
|
|
3341
|
+
t: 'logic';
|
|
3342
|
+
op: 'AND' | 'OR';
|
|
3343
|
+
left: CalcNode;
|
|
3344
|
+
right: CalcNode;
|
|
3345
|
+
} | {
|
|
3346
|
+
t: 'not';
|
|
3347
|
+
expr: CalcNode;
|
|
3348
|
+
} | {
|
|
3349
|
+
t: 'neg';
|
|
3350
|
+
expr: CalcNode;
|
|
3351
|
+
} | {
|
|
3352
|
+
t: 'isnull';
|
|
3353
|
+
expr: CalcNode;
|
|
3354
|
+
negated: boolean;
|
|
3355
|
+
} | {
|
|
3356
|
+
t: 'like';
|
|
3357
|
+
expr: CalcNode;
|
|
3358
|
+
pattern: CalcNode;
|
|
3359
|
+
negated: boolean;
|
|
3360
|
+
} | {
|
|
3361
|
+
t: 'in';
|
|
3362
|
+
expr: CalcNode;
|
|
3363
|
+
items: readonly CalcNode[];
|
|
3364
|
+
negated: boolean;
|
|
3365
|
+
} | {
|
|
3366
|
+
t: 'between';
|
|
3367
|
+
expr: CalcNode;
|
|
3368
|
+
low: CalcNode;
|
|
3369
|
+
high: CalcNode;
|
|
3370
|
+
negated: boolean;
|
|
3371
|
+
} | {
|
|
3372
|
+
t: 'case';
|
|
3373
|
+
whens: readonly {
|
|
3374
|
+
when: CalcNode;
|
|
3375
|
+
then: CalcNode;
|
|
3376
|
+
}[];
|
|
3377
|
+
elseExpr: CalcNode | null;
|
|
3378
|
+
} | {
|
|
3379
|
+
t: 'fn';
|
|
3380
|
+
name: string;
|
|
3381
|
+
args: readonly CalcNode[];
|
|
3382
|
+
} | {
|
|
3383
|
+
t: 'cast';
|
|
3384
|
+
expr: CalcNode;
|
|
3385
|
+
to: CalcCastType;
|
|
3386
|
+
};
|
|
3387
|
+
/** A parsed expression plus the unique column paths it references. */
|
|
3388
|
+
interface CalcExpr {
|
|
3389
|
+
readonly ast: CalcNode;
|
|
3390
|
+
/** Unique referenced column paths, in first-appearance order. */
|
|
3391
|
+
readonly columnPaths: readonly (readonly string[])[];
|
|
3392
|
+
}
|
|
3393
|
+
/**
|
|
3394
|
+
* Column-reference resolver supplied by the caller. Receives the dotted path
|
|
3395
|
+
* split into segments; returns true when the path resolves (a base column, or
|
|
3396
|
+
* a belongsTo chain ending in a column). An unresolved path is a parse error.
|
|
3397
|
+
*/
|
|
3398
|
+
type CalcRefResolver = (path: readonly string[]) => boolean;
|
|
3399
|
+
/** Thrown for any lexical or syntactic violation of the expression grammar. */
|
|
3400
|
+
declare class CalcExprError extends Error {
|
|
3401
|
+
readonly position: number;
|
|
3402
|
+
constructor(message: string, position: number);
|
|
3403
|
+
}
|
|
3404
|
+
/**
|
|
3405
|
+
* Parse a calculation expression, validating every column reference against
|
|
3406
|
+
* `resolveRef`. Throws {@link CalcExprError} on any grammar violation or
|
|
3407
|
+
* unresolved reference.
|
|
3408
|
+
*/
|
|
3409
|
+
declare function parseCalcExpr(source: string, resolveRef: CalcRefResolver): CalcExpr;
|
|
3410
|
+
/** Emit-time context: the dialect and the compiler's path → SQL mapping. */
|
|
3411
|
+
interface CalcEmitContext {
|
|
3412
|
+
dialect: CalcDialect;
|
|
3413
|
+
/** Map a resolved column path to its compiled `"alias"."column"` SQL. */
|
|
3414
|
+
columnSql: (path: readonly string[]) => string;
|
|
3415
|
+
}
|
|
3416
|
+
/**
|
|
3417
|
+
* Serialize a parsed expression to SQL. Every composite node is
|
|
3418
|
+
* parenthesized, so the emitted precedence is explicit and dialect-neutral.
|
|
3419
|
+
*/
|
|
3420
|
+
declare function emitCalcExpr(expr: CalcExpr, ctx: CalcEmitContext): string;
|
|
3421
|
+
|
|
3422
|
+
/**
|
|
3423
|
+
* Compiler for serializable COMPUTED COLUMNS (#10) — the per-entity replacement for the
|
|
3424
|
+
* read-only computed-TABLE views. A computed field (`LatticeFieldDef.computed`) is a real,
|
|
3425
|
+
* materialized column whose value is derived by one of five kinds
|
|
3426
|
+
* (alias / calc / ai_classify / ai_transform / aggregate). This module compiles a
|
|
3427
|
+
* DETERMINISTIC field (alias / calc) into a bounded SQL scalar expression the runtime
|
|
3428
|
+
* recomputes on write via a single targeted `UPDATE … WHERE pk = ?` (one row).
|
|
3429
|
+
*
|
|
3430
|
+
* The SQL is emitted through the SAME `emitCalcExpr` the retired view compiler used, so
|
|
3431
|
+
* there is one source of truth for calc semantics (no JS/SQL divergence). Non-deterministic
|
|
3432
|
+
* or non-same-row kinds are returned as DEFERRED — the field is valid and registered, but
|
|
3433
|
+
* its value is produced by a later mechanism (the AI fill engine for ai_* kinds; the
|
|
3434
|
+
* aggregate/belongsTo-path recompute) rather than the synchronous write-path UPDATE.
|
|
3435
|
+
*/
|
|
3436
|
+
|
|
3437
|
+
/** Why a computed field is not recomputed by the synchronous same-row UPDATE path. */
|
|
3438
|
+
type DeferredReason = 'ai' | 'aggregate' | 'path';
|
|
3439
|
+
/** AI-fill recompute metadata, carried so the runtime never re-parses the def. */
|
|
3440
|
+
interface AiFieldPlan {
|
|
3441
|
+
kind: 'classify' | 'transform';
|
|
3442
|
+
/** Same-row columns fed to the model — a write to any of these invalidates the cell. */
|
|
3443
|
+
inputs: string[];
|
|
3444
|
+
prompt: string;
|
|
3445
|
+
/** Allowed labels (classify only). */
|
|
3446
|
+
labels?: string[];
|
|
3447
|
+
model: 'default' | 'cheapest';
|
|
3448
|
+
}
|
|
3449
|
+
/** Aggregate recompute metadata, carried so the runtime never re-parses the def. */
|
|
3450
|
+
interface AggregateFieldPlan {
|
|
3451
|
+
/** Junction/child table folded into one scalar per base row. */
|
|
3452
|
+
junction: string;
|
|
3453
|
+
/** Remote relation/column segment of `via` (`'<junction>.<remote>'`). */
|
|
3454
|
+
remote: string;
|
|
3455
|
+
fn: 'count' | 'sum' | 'avg' | 'min' | 'max' | 'concat';
|
|
3456
|
+
/** Remote column to aggregate (required for every fn except count). */
|
|
3457
|
+
column?: string;
|
|
3458
|
+
}
|
|
3459
|
+
interface CompiledComputedField {
|
|
3460
|
+
/** The physical column the value materializes into. */
|
|
3461
|
+
column: string;
|
|
3462
|
+
/** SQL scalar expression over the base row's OWN columns, for the recompute UPDATE.
|
|
3463
|
+
* Empty when {@link deferred} is set. */
|
|
3464
|
+
sql: string;
|
|
3465
|
+
/** Same-row columns this value depends on (drives dep-gated recompute). Empty for
|
|
3466
|
+
* aggregate/path; for a deferred `ai` field these ARE populated (the AI cell is
|
|
3467
|
+
* invalidated when an input column changes). */
|
|
3468
|
+
deps: string[];
|
|
3469
|
+
/** Set when the value is produced by a later mechanism, not the same-row UPDATE. */
|
|
3470
|
+
deferred?: DeferredReason;
|
|
3471
|
+
/** Present iff `deferred === 'ai'` — drives the async fill + staleness. */
|
|
3472
|
+
ai?: AiFieldPlan;
|
|
3473
|
+
/** Present iff `deferred === 'aggregate'` — drives the correlated-subquery recompute. */
|
|
3474
|
+
aggregate?: AggregateFieldPlan;
|
|
3475
|
+
}
|
|
3476
|
+
|
|
3477
|
+
/**
|
|
3478
|
+
* Computed-table compiler + registration.
|
|
3479
|
+
*
|
|
3480
|
+
* A computed table is a live, READ-ONLY SQL VIEW over one base table,
|
|
3481
|
+
* declared in the workspace config (`computed:`). This module compiles a
|
|
3482
|
+
* {@link ComputedTableDef} into dialect-specific DDL:
|
|
3483
|
+
*
|
|
3484
|
+
* - The view projects the base primary key `AS "id"` first, then each field
|
|
3485
|
+
* in declaration order.
|
|
3486
|
+
* - Soft-deleted base rows are filtered (`"b"."deleted_at" IS NULL` when the
|
|
3487
|
+
* base carries that column). Each unique belongsTo path prefix becomes ONE
|
|
3488
|
+
* LEFT JOIN with a deterministic alias (`j1`, `j2`, … assigned in
|
|
3489
|
+
* sorted-path order, so recompiles are byte-stable); a joined table's
|
|
3490
|
+
* `deleted_at IS NULL` lives in the JOIN's ON clause, so an invisible
|
|
3491
|
+
* parent nulls the field without dropping the base row.
|
|
3492
|
+
* - `aggregate` fields compile to correlated subqueries over the junction.
|
|
3493
|
+
* - AI fields LEFT JOIN the `__lattice_ai_map` / `__lattice_ai_cell`
|
|
3494
|
+
* bookkeeping tables (see `computed-fill.ts`) — reads never invoke a model.
|
|
3495
|
+
* A transform's join matches on an `input_key` computed in SQL from the
|
|
3496
|
+
* declared inputs IN ORDER, so any source change makes the join miss and
|
|
3497
|
+
* the field reads NULL until the next fill pass (never stale).
|
|
3498
|
+
* - With `cloud.rowVisible`, every relation gains the same
|
|
3499
|
+
* `lattice_row_visible(...)` predicate the cell-masking views use, so a
|
|
3500
|
+
* scoped member's reads stay row-filtered.
|
|
3501
|
+
*
|
|
3502
|
+
* Everything interpolated into SQL is either a validated bare identifier
|
|
3503
|
+
* (see `identifier.ts`), an escaped string literal produced here, or the
|
|
3504
|
+
* re-serialized output of the sandboxed expression parser (`calc-expr.ts`).
|
|
3505
|
+
* Raw config text never reaches the SQL string.
|
|
3506
|
+
*/
|
|
3507
|
+
|
|
3508
|
+
/** What the compiler needs to know about one referencable table. */
|
|
3509
|
+
interface ComputedSchemaTable {
|
|
3510
|
+
/** Column names present on the table. */
|
|
3511
|
+
columns: ReadonlySet<string>;
|
|
3512
|
+
/** Declared belongsTo relations, keyed by relation name. */
|
|
3513
|
+
relations: Readonly<Record<string, BelongsToRelation>>;
|
|
3514
|
+
/** Normalized primary-key columns. */
|
|
3515
|
+
primaryKey: readonly string[];
|
|
3516
|
+
/** Whether the table carries the soft-delete `deleted_at` column. */
|
|
3517
|
+
hasDeletedAt: boolean;
|
|
3518
|
+
/** Canonical Lattice field types, when known (display metadata only). */
|
|
3519
|
+
fieldTypes?: Readonly<Record<string, string>>;
|
|
3520
|
+
}
|
|
3521
|
+
/** table name → shape; built from the parsed config / live schema registry. */
|
|
3522
|
+
type ComputedSchema = ReadonlyMap<string, ComputedSchemaTable>;
|
|
3523
|
+
/** One compiled AI-derived field, including the SQL its fill pass runs. */
|
|
3524
|
+
interface CompiledAiField {
|
|
3525
|
+
/** Cache key: `<table>.<field>`. */
|
|
3526
|
+
key: string;
|
|
3527
|
+
/** Bare field name. */
|
|
3528
|
+
field: string;
|
|
3529
|
+
kind: 'ai_classify' | 'ai_transform';
|
|
3530
|
+
/** Declared input paths, in config order (order is part of the cache identity). */
|
|
3531
|
+
inputs: readonly string[];
|
|
3532
|
+
/** Compiled SQL expression per input, aligned with `inputs`. */
|
|
3533
|
+
inputSql: readonly string[];
|
|
3534
|
+
/** ai_transform only: the SQL `input_key` expression the view joins on. */
|
|
3535
|
+
inputKeySql?: string;
|
|
3536
|
+
/** ai_transform only: `CAST("b"."<pk>" AS TEXT)`. */
|
|
3537
|
+
rowIdSql?: string;
|
|
3538
|
+
/**
|
|
3539
|
+
* SELECT returning this field's unfilled work (no LIMIT — the fill engine
|
|
3540
|
+
* appends one). Classifier: never-seen DISTINCT input values. Transform:
|
|
3541
|
+
* join-miss rows with `row_id`, the SQL-computed `input_key`, and each
|
|
3542
|
+
* input value as `input_<i>` — the fill engine reads the key from the
|
|
3543
|
+
* database so it can never disagree with the view's join expression.
|
|
3544
|
+
*/
|
|
3545
|
+
pendingSql: string;
|
|
3546
|
+
prompt: string;
|
|
3547
|
+
labels?: readonly string[];
|
|
3548
|
+
model: 'default' | 'cheapest';
|
|
3549
|
+
}
|
|
3550
|
+
interface CompiledComputedTable {
|
|
3551
|
+
viewName: string;
|
|
3552
|
+
/** SELECT body (a preview runs it with LIMIT). */
|
|
3553
|
+
selectSql: string;
|
|
3554
|
+
/** `DROP VIEW IF EXISTS` + `CREATE VIEW`, dialect-specific. */
|
|
3555
|
+
createSql: string;
|
|
3556
|
+
/** `['id', ...fieldNames]` in declaration order. */
|
|
3557
|
+
columns: string[];
|
|
3558
|
+
/** Field → canonical Lattice display type (includes the projected `id`). */
|
|
3559
|
+
fieldTypes: Record<string, string>;
|
|
3560
|
+
/** Base + every joined / junction / remote table (bookkeeping tables excluded). */
|
|
3561
|
+
sources: string[];
|
|
3562
|
+
aiFields: CompiledAiField[];
|
|
3563
|
+
/** Stable hash of `createSql` — the idempotence guard for Postgres DDL. */
|
|
3564
|
+
contentHash: string;
|
|
3565
|
+
}
|
|
3566
|
+
/** Thrown by {@link computedTableOrder} when computed→computed bases form a cycle. */
|
|
3567
|
+
declare class ComputedTableCycleError extends Error {
|
|
3568
|
+
readonly cycle: string[];
|
|
3569
|
+
constructor(cycle: string[]);
|
|
3570
|
+
}
|
|
3571
|
+
/**
|
|
3572
|
+
* Cloud-compile options. On a secured team cloud a Postgres view executes with
|
|
3573
|
+
* its OWNER's rights, so a computed view must (a) row-filter per viewer with
|
|
3574
|
+
* `lattice_row_visible(...)` predicates and (b) read every source column THROUGH
|
|
3575
|
+
* that table's cell-masking view when one exists — otherwise the computed view
|
|
3576
|
+
* exposes the RAW value of a column the owner masked from this member's role, a
|
|
3577
|
+
* column-level cross-tenant leak that the normal `<t>_v` masked read path would
|
|
3578
|
+
* have caught.
|
|
3579
|
+
*/
|
|
3580
|
+
interface CloudCompileOptions {
|
|
3581
|
+
rowVisible: true;
|
|
3582
|
+
/**
|
|
3583
|
+
* Source tables that carry a cell-masking view (`<t>_v`, generated from
|
|
3584
|
+
* `__lattice_column_policy`; see cloud/audience.ts). A computed field reading a
|
|
3585
|
+
* column of such a table is compiled to read it through `<t>_v`, which encodes
|
|
3586
|
+
* BOTH per-column masking (a masked cell reads NULL for a member) AND row
|
|
3587
|
+
* visibility — so a table read through its masking view needs no separate
|
|
3588
|
+
* `lattice_row_visible` predicate (the view already applies it).
|
|
3589
|
+
*/
|
|
3590
|
+
maskedTables?: ReadonlySet<string>;
|
|
3591
|
+
}
|
|
3592
|
+
/**
|
|
3593
|
+
* Order computed-table definitions so every base compiles before the tables
|
|
3594
|
+
* built on it (dependencies first). Only bases that are themselves computed
|
|
3595
|
+
* tables participate; entity bases are leaves. Throws
|
|
3596
|
+
* {@link ComputedTableCycleError} on a cycle, naming it.
|
|
3597
|
+
*/
|
|
3598
|
+
declare function computedTableOrder(defs: Record<string, ComputedTableDef>): string[];
|
|
3599
|
+
/**
|
|
3600
|
+
* Compile one computed-table definition into dialect-specific view DDL plus
|
|
3601
|
+
* the metadata later slices need (columns, display types, AI fill SQL).
|
|
3602
|
+
* Pure: validates everything it touches and throws a descriptive error on
|
|
3603
|
+
* any unknown table, relation, or column. `schema` must already contain any
|
|
3604
|
+
* computed table used as `base` (compile in {@link computedTableOrder}).
|
|
3605
|
+
*/
|
|
3606
|
+
declare function compileComputedTable(name: string, def: ComputedTableDef, schema: ComputedSchema, dialect: 'sqlite' | 'postgres', cloud?: CloudCompileOptions): CompiledComputedTable;
|
|
3607
|
+
/**
|
|
3608
|
+
* The registration seam the core exposes to this module — kept structural so
|
|
3609
|
+
* `lattice.ts` can pass a closure-backed host without a runtime import cycle.
|
|
3610
|
+
*/
|
|
3611
|
+
interface ComputedTableHost {
|
|
3612
|
+
adapter: StorageAdapter;
|
|
3613
|
+
/** Apply version-guarded migrations (the Postgres DDL path). */
|
|
3614
|
+
migrate(migrations: Migration[]): Promise<void>;
|
|
3615
|
+
introspectColumns(table: string): Promise<string[]>;
|
|
3616
|
+
/**
|
|
3617
|
+
* Batch-introspect several tables' columns in ONE round-trip (table → ordered
|
|
3618
|
+
* columns). Optional: when absent, registration falls back to a per-table
|
|
3619
|
+
* {@link introspectColumns} loop. Providing it collapses the post-create
|
|
3620
|
+
* introspection of K computed views into a single `information_schema` query,
|
|
3621
|
+
* so a pooled-cloud open never pays K serial round-trips just to read columns.
|
|
3622
|
+
*/
|
|
3623
|
+
introspectAllColumns?(tables: string[]): Promise<Map<string, Set<string>>>;
|
|
3624
|
+
/** Register the already-existing view in the live schema registry. Issues NO DDL. */
|
|
3625
|
+
register(table: string, def: TableDefinition, columns: readonly string[]): void;
|
|
3626
|
+
}
|
|
3627
|
+
interface RegisterComputedTablesOptions {
|
|
3628
|
+
/** Lookup for every referencable table (entities + already-registered tables). */
|
|
3629
|
+
schema: ComputedSchema;
|
|
3630
|
+
dialect: 'sqlite' | 'postgres';
|
|
3631
|
+
/**
|
|
3632
|
+
* Scoped cloud member open: the role cannot DDL, so register purely by
|
|
3633
|
+
* introspection — no view DDL, no bookkeeping-table creation, and a view
|
|
3634
|
+
* this member cannot see is skipped rather than treated as a failure.
|
|
3635
|
+
*/
|
|
3636
|
+
introspectOnly?: boolean;
|
|
3637
|
+
/**
|
|
3638
|
+
* Cloud compile: emit per-relation `lattice_row_visible` predicates and read
|
|
3639
|
+
* masked source tables through their cell-masking `<t>_v` view (see
|
|
3640
|
+
* {@link CloudCompileOptions}).
|
|
3641
|
+
*/
|
|
3642
|
+
cloud?: CloudCompileOptions;
|
|
3643
|
+
/**
|
|
3644
|
+
* Runtime (ops-layer) registration: execute the view DDL directly (drop +
|
|
3645
|
+
* recreate) on Postgres too, instead of the content-hash migration the open
|
|
3646
|
+
* path uses. A runtime edit can be REVERTED to a prior definition whose
|
|
3647
|
+
* content hash was already applied once — a version-guarded migration would
|
|
3648
|
+
* skip that DDL and silently leave the view on the newer definition.
|
|
3649
|
+
*/
|
|
3650
|
+
directDdl?: boolean;
|
|
3651
|
+
}
|
|
3652
|
+
interface ComputedRegistrationResult {
|
|
3653
|
+
/** Successfully compiled + registered computed tables, in topo order. */
|
|
3654
|
+
registered: string[];
|
|
3655
|
+
/** Introspect-only opens where the view is not (yet) visible to this role. */
|
|
3656
|
+
skipped: string[];
|
|
3657
|
+
/** Per-table failures. A failure never aborts the open or the other tables. */
|
|
3658
|
+
errors: {
|
|
3659
|
+
table: string;
|
|
3660
|
+
error: string;
|
|
3661
|
+
}[];
|
|
3662
|
+
/** Compiled artifacts, for the fill engine / preview / ops layers. */
|
|
3663
|
+
compiled: Map<string, CompiledComputedTable>;
|
|
3664
|
+
}
|
|
3665
|
+
/**
|
|
3666
|
+
* Compile every computed-table definition in topological order, execute the
|
|
3667
|
+
* view DDL, introspect the result, and register it with the host.
|
|
3668
|
+
*
|
|
3669
|
+
* DDL is planned dependency-aware: when a table's view must be (re)created —
|
|
3670
|
+
* SQLite and the runtime `directDdl` path always recreate; Postgres recreates
|
|
3671
|
+
* when the definition's content-hash migration has not been applied — every
|
|
3672
|
+
* TRANSITIVE dependent (a computed table based on it) is dropped first in
|
|
3673
|
+
* reverse-topological order and force-recreated afterwards in topological
|
|
3674
|
+
* order. Postgres refuses `DROP VIEW` while dependents exist, so without the
|
|
3675
|
+
* plan a changed base failed to re-register AND took its dependents with it
|
|
3676
|
+
* on the next open; and a dependent whose own hash is unchanged must be
|
|
3677
|
+
* recreated DIRECTLY (its migration version is already recorded — a
|
|
3678
|
+
* version-guarded migrate would skip the CREATE and leave the view missing).
|
|
3679
|
+
* (`CREATE OR REPLACE VIEW` is deliberately not used — it fails whenever the
|
|
3680
|
+
* column list changes.)
|
|
3681
|
+
*
|
|
3682
|
+
* A definition that fails to compile (or whose DDL fails) must NOT brick the
|
|
3683
|
+
* open: it is skipped, recorded under field `'*'` in
|
|
3684
|
+
* `__lattice_computed_state`, reported in the returned result, and the
|
|
3685
|
+
* remaining tables continue. This function itself never throws for a
|
|
3686
|
+
* per-table failure.
|
|
3687
|
+
*
|
|
3688
|
+
* After registration, stored AI outputs whose `prompt_hash` no longer matches
|
|
3689
|
+
* the current definition are purged ({@link purgeStaleAiFields}), so a
|
|
3690
|
+
* definition changed through ANY path (ops layer, hand-edited YAML,
|
|
3691
|
+
* member-hydrated config) never keeps serving values derived from a prompt or
|
|
3692
|
+
* label set that no longer exists.
|
|
3693
|
+
*/
|
|
3694
|
+
declare function registerComputedTables(host: ComputedTableHost, defs: Record<string, ComputedTableDef>, opts: RegisterComputedTablesOptions): Promise<ComputedRegistrationResult>;
|
|
3695
|
+
|
|
3696
|
+
/**
|
|
3697
|
+
* AI-fill engine for computed tables.
|
|
3698
|
+
*
|
|
3699
|
+
* AI-derived fields never re-run a model at read time: model outputs are
|
|
3700
|
+
* materialized once into shared bookkeeping tables that the computed-table
|
|
3701
|
+
* view LEFT JOINs, so reads are always deterministic SQL.
|
|
3702
|
+
*
|
|
3703
|
+
* Three unregistered `__lattice_` bookkeeping tables (raw DDL, dialect-neutral,
|
|
3704
|
+
* no SQL-side defaults — every writer supplies explicit ISO timestamps, keeping
|
|
3705
|
+
* the CREATE byte-identical across dialects):
|
|
3706
|
+
*
|
|
3707
|
+
* - `__lattice_ai_map` — classifier memo: one row per (field, distinct input
|
|
3708
|
+
* value). `label` is NULLABLE: NULL records "the model declined", kept so the
|
|
3709
|
+
* same value is never re-asked. The view joins on the CAST-to-TEXT input.
|
|
3710
|
+
* - `__lattice_ai_cell` — per-row transform output, keyed (field, row). The
|
|
3711
|
+
* `input_key` column stores the SQL-computed concatenation of the field's
|
|
3712
|
+
* inputs; the view's join also matches on it, so a changed source row makes
|
|
3713
|
+
* the join miss and the field reads NULL until the next fill (never stale).
|
|
3714
|
+
* - `__lattice_computed_state` — per-(table, field) fill status for progress
|
|
3715
|
+
* and error reporting. Registration failures land here under field `'*'`.
|
|
3716
|
+
*
|
|
3717
|
+
* The LLM is INJECTED via the minimal {@link FillLlm} interface — this module
|
|
3718
|
+
* performs no model calls of its own and the schema layer stays free of any
|
|
3719
|
+
* client dependency. The `model` string passed through is the field's declared
|
|
3720
|
+
* tier (`'default'` / `'cheapest'`); the adapter maps it to a real model id.
|
|
3721
|
+
*/
|
|
3722
|
+
|
|
3723
|
+
declare const AI_MAP_TABLE = "__lattice_ai_map";
|
|
3724
|
+
declare const AI_CELL_TABLE = "__lattice_ai_cell";
|
|
3725
|
+
declare const COMPUTED_STATE_TABLE = "__lattice_computed_state";
|
|
3726
|
+
/**
|
|
3727
|
+
* Minimal LLM interface the fill engine depends on. Callers adapt their own
|
|
3728
|
+
* client: `model` arrives as the field's declared tier ('default'/'cheapest');
|
|
3729
|
+
* the implementation resolves it to a concrete model. The returned string is
|
|
3730
|
+
* the raw completion text.
|
|
3731
|
+
*/
|
|
3732
|
+
interface FillLlm {
|
|
3733
|
+
complete(opts: {
|
|
3734
|
+
system: string;
|
|
3735
|
+
user: string;
|
|
3736
|
+
model: string;
|
|
3737
|
+
}): Promise<string>;
|
|
3738
|
+
}
|
|
3739
|
+
interface ComputedFillOptions {
|
|
3740
|
+
/** Pending items fetched (and classifier values sent) per model call. Default 50. */
|
|
3741
|
+
batchSize?: number;
|
|
3742
|
+
}
|
|
3743
|
+
/** Per-field outcome of a fill run. */
|
|
3744
|
+
interface FieldFillResult {
|
|
3745
|
+
/** Bare field name. */
|
|
3746
|
+
field: string;
|
|
3747
|
+
/** Cache key: `<table>.<field>`. */
|
|
3748
|
+
key: string;
|
|
3749
|
+
kind: 'ai_classify' | 'ai_transform';
|
|
3750
|
+
/** 'idle' when the field converged; 'error' when it stopped early. */
|
|
3751
|
+
status: 'idle' | 'error';
|
|
3752
|
+
/** Rows/values materialized by THIS run. */
|
|
3753
|
+
filled: number;
|
|
3754
|
+
/** Items still unfilled after the run (0 unless the field errored). */
|
|
3755
|
+
pending: number;
|
|
3756
|
+
error?: string;
|
|
3757
|
+
}
|
|
3758
|
+
/** Report returned by {@link runComputedFill}. Errors are returned, never thrown away. */
|
|
3759
|
+
interface ComputedFillReport {
|
|
3760
|
+
table: string;
|
|
3761
|
+
fields: FieldFillResult[];
|
|
3762
|
+
}
|
|
3763
|
+
/** A row of `__lattice_computed_state`. */
|
|
3764
|
+
interface ComputedFieldState {
|
|
3765
|
+
table_name: string;
|
|
3766
|
+
field: string;
|
|
3767
|
+
status: 'idle' | 'running' | 'error';
|
|
3768
|
+
error: string | null;
|
|
3769
|
+
pending: number | null;
|
|
3770
|
+
filled: number | null;
|
|
3771
|
+
started_at: string | null;
|
|
3772
|
+
finished_at: string | null;
|
|
3773
|
+
}
|
|
3774
|
+
/**
|
|
3775
|
+
* Create the three bookkeeping tables if absent. Idempotent; safe on both
|
|
3776
|
+
* dialects (plain TEXT/INTEGER columns, composite PKs, no defaults).
|
|
3777
|
+
*/
|
|
3778
|
+
declare function ensureAiTables(adapter: StorageAdapter): Promise<void>;
|
|
3779
|
+
/** Read the fill/error state rows for one computed table. */
|
|
3780
|
+
declare function readComputedState(adapter: StorageAdapter, tableName: string): Promise<ComputedFieldState[]>;
|
|
3781
|
+
/**
|
|
3782
|
+
* Delete every materialized output + state row for one field. Called when the
|
|
3783
|
+
* field's DEFINITION changes (prompt, labels, model, inputs) — the cached
|
|
3784
|
+
* outputs no longer describe the field, so they are purged and the next fill
|
|
3785
|
+
* re-derives them. `fieldKey` is `'<table>.<field>'`.
|
|
3786
|
+
*/
|
|
3787
|
+
declare function purgeAiField(adapter: StorageAdapter, fieldKey: string): Promise<void>;
|
|
3788
|
+
/**
|
|
3789
|
+
* Run the fill pass for every AI field of a compiled computed table.
|
|
3790
|
+
*
|
|
3791
|
+
* - `ai_classify`: only never-seen DISTINCT input values reach the model, in
|
|
3792
|
+
* batches (~50 per call), as one strict-JSON request mapping each value to a
|
|
3793
|
+
* label. Every returned label is validated against the allowed set; a value
|
|
3794
|
+
* with an out-of-set (or missing) label is recorded as an error for the
|
|
3795
|
+
* field and NEVER stored as a label. A `null` label means the model
|
|
3796
|
+
* declined — stored so the value is not re-asked.
|
|
3797
|
+
* - `ai_transform`: one model call per join-miss row; the row's `input_key`
|
|
3798
|
+
* is SELECTed from the database via the same SQL expression the view joins
|
|
3799
|
+
* on, so the two can never disagree.
|
|
3800
|
+
*
|
|
3801
|
+
* An LLM/parse error records status `'error'` for that field, stops that
|
|
3802
|
+
* field's remaining batches (already-written rows stay), continues the other
|
|
3803
|
+
* fields, and is RETURNED in the report — unfilled rows keep reading NULL via
|
|
3804
|
+
* the view's join miss, never a stale value. This function only throws for
|
|
3805
|
+
* infrastructure failures (e.g. the database itself is unreachable).
|
|
3806
|
+
*/
|
|
3807
|
+
declare function runComputedFill(adapter: StorageAdapter, llm: FillLlm, compiled: CompiledComputedTable, opts?: ComputedFillOptions): Promise<ComputedFillReport>;
|
|
3808
|
+
|
|
3809
|
+
/**
|
|
3810
|
+
* AI fill for #10 computed COLUMNS (the per-entity replacement for the retired
|
|
3811
|
+
* computed-TABLE AI fields). An `ai_classify` / `ai_transform` computed field is a
|
|
3812
|
+
* real column that starts NULL and is populated asynchronously by a model. This
|
|
3813
|
+
* engine scans a bounded window of un-filled cells (`WHERE "<col>" IS NULL`), calls
|
|
3814
|
+
* the injected {@link FillLlm} per row, validates the output, and writes it back with
|
|
3815
|
+
* a single targeted `UPDATE … WHERE pk` (bounded, never a whole-table scan).
|
|
3816
|
+
*
|
|
3817
|
+
* It writes through the raw adapter (NOT `Lattice.update`) so a fill does not re-fire
|
|
3818
|
+
* the write hooks that trigger it — that would loop forever. The staleness contract
|
|
3819
|
+
* ("a changed input NULLs the cell before the refill") is enforced in the write path
|
|
3820
|
+
* (`Lattice._nullStaleAiColumns`); this engine only ever FILLS a NULL cell, so it is
|
|
3821
|
+
* safe to run repeatedly and idempotent once every cell is populated.
|
|
3822
|
+
*/
|
|
3823
|
+
|
|
3824
|
+
interface FieldFillReport {
|
|
3825
|
+
/** Cells populated this run. */
|
|
3826
|
+
filled: number;
|
|
3827
|
+
/** Cells whose model output was rejected/failed (left NULL). */
|
|
3828
|
+
failed: number;
|
|
3829
|
+
/** First few human-readable failure reasons (never secrets). */
|
|
3830
|
+
errors: string[];
|
|
3831
|
+
}
|
|
3832
|
+
|
|
3833
|
+
/**
|
|
3834
|
+
* Seamless cloud file-byte access — an in-database presigned-URL broker.
|
|
3835
|
+
*
|
|
3836
|
+
* After joining a cloud via invite, a scoped member connects directly to the
|
|
3837
|
+
* cloud's Postgres as their own least-privilege role. They can SELECT a `files`
|
|
3838
|
+
* row they're allowed to see, but they hold no S3 credential, so fetching the
|
|
3839
|
+
* bytes would otherwise fail. This installs a `SECURITY DEFINER` function that,
|
|
3840
|
+
* **inside Postgres** (the only place the owner's key lives, away from members),
|
|
3841
|
+
* gates on the member's row-visibility and computes a short-lived AWS SigV4
|
|
3842
|
+
* presigned URL for exactly that object — so the member fetches/uploads bytes
|
|
3843
|
+
* with zero config and never holds a key.
|
|
3844
|
+
*
|
|
3845
|
+
* Why sign in plpgsql: the secret must never leave the database for a member's
|
|
2925
3846
|
* process, so a Node-side presign is out — the signature is computed in-DB via
|
|
2926
3847
|
* `pgcrypto` HMAC-SHA256. Correctness of the SigV4 chain is verified against
|
|
2927
3848
|
* AWS's published test vectors (no real S3 needed).
|
|
@@ -3303,6 +4224,21 @@ type EventHandler<T> = (data: T) => void;
|
|
|
3303
4224
|
type PkLookup = string | Record<string, unknown>;
|
|
3304
4225
|
declare class Lattice {
|
|
3305
4226
|
private readonly _adapter;
|
|
4227
|
+
/**
|
|
4228
|
+
* Ambient transaction executor for {@link transaction}. When a store is set,
|
|
4229
|
+
* every write helper routes through it (via {@link _exec}) instead of the base
|
|
4230
|
+
* adapter, so the whole call chain lands on one transaction connection. Scoped
|
|
4231
|
+
* to the async context of the `transaction(fn)` callback, so concurrent callers
|
|
4232
|
+
* never share a transaction.
|
|
4233
|
+
*/
|
|
4234
|
+
private readonly _txStore;
|
|
4235
|
+
/**
|
|
4236
|
+
* Serializer for schema mutations (CREATE TABLE / ALTER … ADD COLUMN). See
|
|
4237
|
+
* {@link withSchemaLock}. The flag marks "already inside the lock" for reentrancy;
|
|
4238
|
+
* the chain is the FIFO queue that runs one locked section at a time.
|
|
4239
|
+
*/
|
|
4240
|
+
private readonly _schemaLockFlag;
|
|
4241
|
+
private _schemaLockChain;
|
|
3306
4242
|
private _changelogService?;
|
|
3307
4243
|
private _changelogWriterInstance?;
|
|
3308
4244
|
private _reportBuilder?;
|
|
@@ -3364,6 +4300,23 @@ declare class Lattice {
|
|
|
3364
4300
|
private readonly _computed;
|
|
3365
4301
|
/** table → materialized rollup specs (P-VIEW). */
|
|
3366
4302
|
private readonly _rollups;
|
|
4303
|
+
/** table → compiled DETERMINISTIC computed columns (same-row alias/calc, #10) for the
|
|
4304
|
+
* bounded write-path recompute UPDATE. Deferred kinds (aggregate/AI/belongsTo-path)
|
|
4305
|
+
* are produced by their own mechanisms and are NOT in this map. */
|
|
4306
|
+
private readonly _computedFieldSql;
|
|
4307
|
+
/** All compiled computed fields per table (incl. deferred) — for introspection + fill. */
|
|
4308
|
+
private readonly _computedFieldPlans;
|
|
4309
|
+
/** table → its AI computed fields (column + input deps + plan) — the async-fill hot path. */
|
|
4310
|
+
private readonly _aiComputedFields;
|
|
4311
|
+
/** Computed-table (read-only view) definitions from the YAML config. */
|
|
4312
|
+
private readonly _configComputedTables;
|
|
4313
|
+
/**
|
|
4314
|
+
* Names of the computed tables registered by this instance — the single
|
|
4315
|
+
* source of truth the write-refusal guard and {@link isComputedTable} share.
|
|
4316
|
+
*/
|
|
4317
|
+
private readonly _computedTables;
|
|
4318
|
+
/** Outcome of the init-time computed-table registration (see accessor). */
|
|
4319
|
+
private _computedRegistration;
|
|
3367
4320
|
/** source table → parents whose rollup it feeds (for incremental recompute). */
|
|
3368
4321
|
private readonly _rollupSources;
|
|
3369
4322
|
/**
|
|
@@ -3446,6 +4399,88 @@ declare class Lattice {
|
|
|
3446
4399
|
init(options?: InitOptions): Promise<void>;
|
|
3447
4400
|
/** Async tail of init(). See {@link init} for the sync-validation phase. */
|
|
3448
4401
|
private _initAsync;
|
|
4402
|
+
/**
|
|
4403
|
+
* Register the config-declared computed tables (read-only SQL views) in
|
|
4404
|
+
* topological order: compile, execute the view DDL (SQLite drops +
|
|
4405
|
+
* recreates unconditionally; Postgres guards the DDL behind a content-hash
|
|
4406
|
+
* migration version so a converged open issues none), introspect, and
|
|
4407
|
+
* register each view as a queryable table. A definition that fails to
|
|
4408
|
+
* compile never bricks the open — it is recorded under field `'*'` in
|
|
4409
|
+
* `__lattice_computed_state`, surfaced via {@link getComputedRegistration},
|
|
4410
|
+
* and the remaining tables continue.
|
|
4411
|
+
*/
|
|
4412
|
+
private _registerConfigComputedTables;
|
|
4413
|
+
/**
|
|
4414
|
+
* The registration host over THIS instance — shared by the init-time
|
|
4415
|
+
* registration and {@link registerComputedTablesLive} so both register
|
|
4416
|
+
* through the identical seam.
|
|
4417
|
+
*/
|
|
4418
|
+
private _computedTableHost;
|
|
4419
|
+
/**
|
|
4420
|
+
* On a secured team cloud, computed views must compile with per-relation
|
|
4421
|
+
* `lattice_row_visible(...)` predicates: a Postgres view executes with its
|
|
4422
|
+
* OWNER's rights, so without the predicates a member granted SELECT on the
|
|
4423
|
+
* view would read every base row, bypassing RLS. The predicate helper only
|
|
4424
|
+
* exists once the cloud RLS bootstrap has run — detected by its
|
|
4425
|
+
* `__lattice_owners` bookkeeping table (same tell `probeCloud` uses). A probe
|
|
4426
|
+
* failure propagates: silently compiling without the predicates on a cloud
|
|
4427
|
+
* would be a row-visibility hole, and a connection broken enough to fail this
|
|
4428
|
+
* one SELECT fails the open anyway.
|
|
4429
|
+
*/
|
|
4430
|
+
computedCloudOption(opts?: {
|
|
4431
|
+
introspectOnly?: boolean;
|
|
4432
|
+
}): Promise<CloudCompileOptions | undefined>;
|
|
4433
|
+
/**
|
|
4434
|
+
* Table lookup for the computed-table compiler: every registered table's
|
|
4435
|
+
* declared + introspected columns, belongsTo relations, and normalized
|
|
4436
|
+
* primary key. Shared by the init-time registration and the runtime ops
|
|
4437
|
+
* layer (create/preview/field pickers), so the two can never disagree about
|
|
4438
|
+
* what a definition may reference.
|
|
4439
|
+
*/
|
|
4440
|
+
computedSchemaLookup(): Map<string, ComputedSchemaTable>;
|
|
4441
|
+
/**
|
|
4442
|
+
* Register computed-table definitions at RUNTIME — the live counterpart of
|
|
4443
|
+
* the init-time registration, used by the GUI ops layer (create/update). It
|
|
4444
|
+
* runs the SAME registration path as the open (compile in topological order,
|
|
4445
|
+
* bookkeeping-table ensure, view DDL, introspect, live-register) with one
|
|
4446
|
+
* deliberate difference: the view DDL executes directly (drop + recreate)
|
|
4447
|
+
* rather than through the open path's content-hash migration, because a
|
|
4448
|
+
* runtime edit can be reverted to a PRIOR definition whose hash was already
|
|
4449
|
+
* applied once — a version-guarded migration would skip that DDL. Successful
|
|
4450
|
+
* registrations join {@link isComputedTable} / {@link getComputedTableNames}
|
|
4451
|
+
* (so the write-refusal guard covers them immediately) and their compiled
|
|
4452
|
+
* artifacts merge into {@link getComputedRegistration}. Per-definition
|
|
4453
|
+
* failures are RETURNED in `errors`, never thrown — the caller decides
|
|
4454
|
+
* whether a failure aborts its operation.
|
|
4455
|
+
*/
|
|
4456
|
+
registerComputedTablesLive(defs: Record<string, ComputedTableDef>): Promise<ComputedRegistrationResult>;
|
|
4457
|
+
/**
|
|
4458
|
+
* Remove a computed table from the live registry — the inverse of
|
|
4459
|
+
* {@link registerComputedTablesLive} for one table. Unregisters the view
|
|
4460
|
+
* from the schema registry (it stops being listed/queryable) and from the
|
|
4461
|
+
* computed-table set (the write-refusal guard no longer names it). Issues NO
|
|
4462
|
+
* DDL — the caller owns dropping the view. Throws for a name that is not a
|
|
4463
|
+
* registered computed table, so a plain entity can never be unregistered
|
|
4464
|
+
* through this path.
|
|
4465
|
+
*/
|
|
4466
|
+
unregisterComputedTable(name: string): void;
|
|
4467
|
+
/**
|
|
4468
|
+
* True when `name` is a computed table registered by this instance —
|
|
4469
|
+
* a read-only projection that refuses direct writes.
|
|
4470
|
+
*/
|
|
4471
|
+
isComputedTable(name: string): boolean;
|
|
4472
|
+
/** Names of the computed tables registered by this instance. */
|
|
4473
|
+
getComputedTableNames(): string[];
|
|
4474
|
+
/**
|
|
4475
|
+
* Outcome of the init-time computed-table registration: what registered,
|
|
4476
|
+
* what was skipped (introspect-only member opens), per-table errors, and
|
|
4477
|
+
* the compiled artifacts (view SQL + AI fill queries) for downstream
|
|
4478
|
+
* consumers such as the fill engine. Null when the config declares no
|
|
4479
|
+
* computed tables or init has not run.
|
|
4480
|
+
*/
|
|
4481
|
+
getComputedRegistration(): ComputedRegistrationResult | null;
|
|
4482
|
+
/** Refuse writes against a computed table — it is a read-only projection. */
|
|
4483
|
+
private _assertNotComputedTable;
|
|
3449
4484
|
/**
|
|
3450
4485
|
* Run additional migrations after init(). Useful for package-level schema
|
|
3451
4486
|
* changes applied at runtime (e.g. update hooks that add columns).
|
|
@@ -3469,6 +4504,51 @@ declare class Lattice {
|
|
|
3469
4504
|
* Teams schema spec → DDL translation).
|
|
3470
4505
|
*/
|
|
3471
4506
|
getDialect(): 'sqlite' | 'postgres';
|
|
4507
|
+
/**
|
|
4508
|
+
* The adapter that write/read SQL should execute against: the ambient
|
|
4509
|
+
* transaction connection when inside {@link transaction}, otherwise the base
|
|
4510
|
+
* adapter. Only the row `run`/`get` execution helpers consult this — schema,
|
|
4511
|
+
* introspection, search, and graph helpers keep the base adapter, since those
|
|
4512
|
+
* are structural and should not be scoped to a data transaction.
|
|
4513
|
+
*/
|
|
4514
|
+
private _exec;
|
|
4515
|
+
/**
|
|
4516
|
+
* Run `fn` inside a single database transaction. Every write `fn` performs
|
|
4517
|
+
* through this Lattice (insert / update / delete and their audit + changelog
|
|
4518
|
+
* writes) executes on one connection and commits together, or rolls back
|
|
4519
|
+
* together if `fn` throws. Reads inside `fn` see its own uncommitted writes.
|
|
4520
|
+
*
|
|
4521
|
+
* The transaction is scoped to the async context of `fn` (via
|
|
4522
|
+
* `AsyncLocalStorage`), so two concurrent callers on the same Lattice never
|
|
4523
|
+
* accidentally share a transaction. A nested `transaction` call reuses the
|
|
4524
|
+
* outer transaction rather than opening a second one. When the adapter cannot
|
|
4525
|
+
* open a transaction (`withClient` unavailable), `fn` runs WITHOUT one — the
|
|
4526
|
+
* caller's own validation still applies; this mirrors the hard-delete fallback.
|
|
4527
|
+
*
|
|
4528
|
+
* @since 5.0.0
|
|
4529
|
+
*/
|
|
4530
|
+
transaction<T>(fn: () => Promise<T>): Promise<T>;
|
|
4531
|
+
/**
|
|
4532
|
+
* Run `fn` with exclusive access to schema mutation. Serializes CREATE TABLE /
|
|
4533
|
+
* ALTER … ADD COLUMN so concurrent callers can't interleave a check-then-DDL
|
|
4534
|
+
* across an `await` and collide. This matters because the SQLite adapter is one
|
|
4535
|
+
* synchronous connection: when a parallel folder ingest has two files that both
|
|
4536
|
+
* extract a new "Invoices" entity, or both add an "amount" column, the un-serialized
|
|
4537
|
+
* loser hits `CREATE TABLE`/`ADD COLUMN` after the winner already ran it and throws
|
|
4538
|
+
* "table already exists" / "duplicate column name". Row INSERTs are deliberately NOT
|
|
4539
|
+
* serialized — they're atomic auto-commit statements with uuid keys and no
|
|
4540
|
+
* read-modify-write, so they stay fully concurrent.
|
|
4541
|
+
*
|
|
4542
|
+
* Reentrant via `AsyncLocalStorage`: a locked section that itself triggers more
|
|
4543
|
+
* DDL (e.g. `createUserEntity` → `addColumn` when securing a cloud table) runs the
|
|
4544
|
+
* nested call inline instead of deadlocking on the queue it already holds — the same
|
|
4545
|
+
* ambient-context pattern as {@link transaction}. A rejected `fn` never poisons the
|
|
4546
|
+
* queue: the chain advances on settle either way, and the caller still sees the
|
|
4547
|
+
* rejection through the returned promise.
|
|
4548
|
+
*
|
|
4549
|
+
* @since 5.0.0
|
|
4550
|
+
*/
|
|
4551
|
+
withSchemaLock<T>(fn: () => Promise<T>): Promise<T>;
|
|
3472
4552
|
/**
|
|
3473
4553
|
* True when a table opts into the observation/changelog substrate
|
|
3474
4554
|
* (`def.changelog`). Callers that want to bypass the high-level {@link delete}
|
|
@@ -3608,6 +4688,13 @@ declare class Lattice {
|
|
|
3608
4688
|
getConnectedSource(table: string): ConnectorSource | undefined;
|
|
3609
4689
|
/** Names of all registered connected data types (tables with a `source`). */
|
|
3610
4690
|
connectedTables(): string[];
|
|
4691
|
+
/**
|
|
4692
|
+
* Column names encrypted-at-rest for `table` (decrypted on read). Any caller that ships rows
|
|
4693
|
+
* OUTSIDE the process — an HTTP API response, a render, a log — must mask these; an unmasked
|
|
4694
|
+
* read returns cleartext credentials. Empty set when the table has no encrypted columns or the
|
|
4695
|
+
* encryption layer isn't built yet.
|
|
4696
|
+
*/
|
|
4697
|
+
getEncryptedColumns(table: string): ReadonlySet<string>;
|
|
3611
4698
|
/** Post-insert side effects (changelog, audit, write hooks, embedding sync),
|
|
3612
4699
|
* identical for the plain and force-visibility insert paths. */
|
|
3613
4700
|
private _afterInsert;
|
|
@@ -3629,6 +4716,50 @@ declare class Lattice {
|
|
|
3629
4716
|
* columns, and fold them into the update payload. No-op otherwise.
|
|
3630
4717
|
*/
|
|
3631
4718
|
private _recomputeComputedOnUpdate;
|
|
4719
|
+
/**
|
|
4720
|
+
* Recompute the DETERMINISTIC same-row computed columns (#10 alias/calc) for ONE row via
|
|
4721
|
+
* a single bounded `UPDATE … WHERE pk` (one row, no scan). Runs AFTER the row
|
|
4722
|
+
* is written, so the compiler-emitted SQL expressions read the row's own just-written
|
|
4723
|
+
* columns. `changedCols` = the update payload keys (dep-gated recompute); pass `null` for
|
|
4724
|
+
* an insert (recompute every computed column on the new row). The SET right-hand sides
|
|
4725
|
+
* are compiler-generated SQL over validated, quoted column names — never user input.
|
|
4726
|
+
*/
|
|
4727
|
+
private _recomputeComputedFieldColumns;
|
|
4728
|
+
/**
|
|
4729
|
+
* Derive computed columns after a row is written: recompute the deterministic same-row
|
|
4730
|
+
* columns and NULL any AI cells whose inputs changed. Called by every write path (insert,
|
|
4731
|
+
* update, upsert, the natural-key upsert/enrich the sync + seed engines use) so a computed
|
|
4732
|
+
* field is never left unpopulated or stale regardless of HOW the row was written.
|
|
4733
|
+
* `changedCols === null` = a full-row write (recompute all + null every AI cell).
|
|
4734
|
+
*/
|
|
4735
|
+
private _deriveComputedAfterWrite;
|
|
4736
|
+
/**
|
|
4737
|
+
* NULL the AI computed cells on ONE row whose input columns just changed (one bounded
|
|
4738
|
+
* row update, no scan). The "never serve stale" contract: a changed input clears the derived value
|
|
4739
|
+
* immediately; {@link fillComputedFields} repopulates it out-of-band. `changedCols === null`
|
|
4740
|
+
* NULLs every AI cell on the row (a full-row write, where any input may have changed).
|
|
4741
|
+
*/
|
|
4742
|
+
private _nullStaleAiColumns;
|
|
4743
|
+
/**
|
|
4744
|
+
* The compiled computed-field plans for a table (all kinds, incl. deferred AI/aggregate) —
|
|
4745
|
+
* for the GUI field editor + the fill/refresh machinery. Empty when the table has none.
|
|
4746
|
+
*/
|
|
4747
|
+
getComputedFieldPlans(table: string): CompiledComputedField[];
|
|
4748
|
+
/** Whether a table has any AI computed fields awaiting fill. */
|
|
4749
|
+
hasAiComputedFields(table: string): boolean;
|
|
4750
|
+
/**
|
|
4751
|
+
* Populate the un-filled (NULL) cells of a table's AI computed fields using the injected
|
|
4752
|
+
* {@link FillLlm}. Kept OUT of the write path (no model calls in the core DB layer) — the GUI
|
|
4753
|
+
* calls this fire-and-forget after a write and on open (backfill), a test injects a fake LLM.
|
|
4754
|
+
* Bounded (scans `WHERE col IS NULL LIMIT n`, skips tombstones). Returns a report;
|
|
4755
|
+
* never throws for a per-cell model failure (those are counted + surfaced in the report).
|
|
4756
|
+
*/
|
|
4757
|
+
fillComputedFields(table: string, llm: FillLlm, opts?: {
|
|
4758
|
+
batchSize?: number;
|
|
4759
|
+
maxRows?: number;
|
|
4760
|
+
}): Promise<FieldFillReport>;
|
|
4761
|
+
/** Every table that has AI computed fields (for open-time backfill). */
|
|
4762
|
+
aiComputedFieldTables(): string[];
|
|
3632
4763
|
/** Recompute parent rollup(s) for the FK values carried on a source row. */
|
|
3633
4764
|
private _propagateRollupsFromRow;
|
|
3634
4765
|
/** Recompute the parent rollup(s) fed by a changed source row (fetched by id). */
|
|
@@ -3653,6 +4784,21 @@ declare class Lattice {
|
|
|
3653
4784
|
* @since 0.17.0
|
|
3654
4785
|
*/
|
|
3655
4786
|
updateReturning(table: string, id: PkLookup, row: Partial<Row>): Promise<Row>;
|
|
4787
|
+
/**
|
|
4788
|
+
* Permanently delete a row via `DELETE FROM`. This is a **hard delete** —
|
|
4789
|
+
* the row is removed from the table, not soft-deleted via a `deleted_at` column.
|
|
4790
|
+
*
|
|
4791
|
+
* On tables with `changelog: true`, the full previous row is captured and
|
|
4792
|
+
* appended to the changelog before removal, making the delete auditable and
|
|
4793
|
+
* recoverable via {@link rollback}. On tables without a changelog, the row
|
|
4794
|
+
* is gone permanently.
|
|
4795
|
+
*
|
|
4796
|
+
* Side effects:
|
|
4797
|
+
* - If the table has materialized rollups fed by child rows, a deleted child
|
|
4798
|
+
* is removed from its parent's rollup aggregates.
|
|
4799
|
+
* - Write hooks and audit events are fired.
|
|
4800
|
+
* - Embeddings are synced (if the table has embedding definitions).
|
|
4801
|
+
*/
|
|
3656
4802
|
delete(table: string, id: PkLookup, provenance?: ChangeProvenance): Promise<void>;
|
|
3657
4803
|
/**
|
|
3658
4804
|
* Record a DERIVED observation about a row WITHOUT mutating the canonical row.
|
|
@@ -3750,6 +4896,21 @@ declare class Lattice {
|
|
|
3750
4896
|
* decrypt deps are wired through `_encryption`, so the query/get decryption
|
|
3751
4897
|
* asymmetry is preserved: only query/get invoke them. */
|
|
3752
4898
|
private get _queryCore();
|
|
4899
|
+
/** Optional host-supplied replacement for the pre-render reverse-sync drain. */
|
|
4900
|
+
private _autoRenderDrainOverride;
|
|
4901
|
+
/**
|
|
4902
|
+
* Route non-error render notices (e.g. an edited generated rollup being
|
|
4903
|
+
* restored) somewhere visible. Default: console.warn. The GUI wires its
|
|
4904
|
+
* activity feed here.
|
|
4905
|
+
*/
|
|
4906
|
+
setRenderNoticeHandler(handler: ((message: string) => void) | null): void;
|
|
4907
|
+
/**
|
|
4908
|
+
* Replace the pre-render manual-edit drain (see the auto-render scheduler's
|
|
4909
|
+
* drain dep). The GUI wires its file-loopback watcher here so drained edits go
|
|
4910
|
+
* through the full mutation path (changelog + activity feed + undo) instead of
|
|
4911
|
+
* the core changelog-only apply.
|
|
4912
|
+
*/
|
|
4913
|
+
setAutoRenderDrain(drain: ((outputDir: string) => Promise<void>) | null): void;
|
|
3753
4914
|
/** Lazily-constructed auto-render scheduler (see src/render/auto-render.ts). */
|
|
3754
4915
|
private get _autoRender();
|
|
3755
4916
|
/**
|
|
@@ -3828,6 +4989,12 @@ declare class Lattice {
|
|
|
3828
4989
|
*/
|
|
3829
4990
|
private _expandRelations;
|
|
3830
4991
|
count(table: string, opts?: CountOptions): Promise<number>;
|
|
4992
|
+
/**
|
|
4993
|
+
* Bounded variant of {@link count}: stops after `opts.cap + 1` matching rows
|
|
4994
|
+
* (default cap 1000) so it stays cheap on large tables. Returns the exact count
|
|
4995
|
+
* when `<= cap`, else `cap + 1` to signal "more than cap" (render as "cap+").
|
|
4996
|
+
*/
|
|
4997
|
+
boundedCount(table: string, opts?: BoundedCountOptions): Promise<number>;
|
|
3831
4998
|
/**
|
|
3832
4999
|
* SQL-side aggregation — `COUNT`/`SUM`/`AVG`/`MIN`/`MAX` with optional
|
|
3833
5000
|
* `GROUP BY` and `HAVING`, computed in the database so only the grouped result
|
|
@@ -4013,6 +5180,14 @@ declare class Lattice {
|
|
|
4013
5180
|
* `reverseSync`. Compares file hashes against the current manifest, so a
|
|
4014
5181
|
* render-written file is recognized as an echo and skipped.
|
|
4015
5182
|
*/
|
|
5183
|
+
/**
|
|
5184
|
+
* The post-render reconciliation pass: prune files the prior manifest managed
|
|
5185
|
+
* that the new render no longer produces (deleted rows, renamed roots, retired
|
|
5186
|
+
* rollups) — hash-guarded so a manually edited file is never deleted. Runs
|
|
5187
|
+
* automatically after auto/background renders and at workspace open; exposed
|
|
5188
|
+
* for callers that drive `render()` themselves.
|
|
5189
|
+
*/
|
|
5190
|
+
reconcileRenderedTree(outputDir: string, prevManifest: LatticeManifest | null, newManifest: LatticeManifest | null): Promise<CleanupResult>;
|
|
4016
5191
|
reverseSyncFromFiles(outputDir: string, opts?: ReverseSyncProcessOptions): Promise<ReverseSyncResult>;
|
|
4017
5192
|
watch(outputDir: string, opts?: WatchOptions): Promise<StopFn>;
|
|
4018
5193
|
on(event: 'audit', handler: EventHandler<AuditEvent>): this;
|
|
@@ -4087,6 +5262,17 @@ declare class Lattice {
|
|
|
4087
5262
|
private _serializePkLookup;
|
|
4088
5263
|
/** Returns a rejected Promise if not initialized; null if ready. */
|
|
4089
5264
|
private _fireWriteHooks;
|
|
5265
|
+
/**
|
|
5266
|
+
* Suspend auto-render (re-entrant) for the duration of a bulk operation — e.g.
|
|
5267
|
+
* ingesting a folder of hundreds of files. Writes still record their render
|
|
5268
|
+
* scope, but no render fires until {@link resumeAutoRender} balances every
|
|
5269
|
+
* pause, at which point ONE coalesced render covers everything. This removes
|
|
5270
|
+
* the O(N²) "render-per-file" blowup where each of N writes re-scanned the
|
|
5271
|
+
* whole (growing) file set. Always pair with resumeAutoRender in a `finally`.
|
|
5272
|
+
*/
|
|
5273
|
+
pauseAutoRender(): this;
|
|
5274
|
+
/** Balance a {@link pauseAutoRender}; the last resume arms one coalesced render. */
|
|
5275
|
+
resumeAutoRender(): this;
|
|
4090
5276
|
/**
|
|
4091
5277
|
* Turn on automatic rendering into `outputDir`. After this, every insert /
|
|
4092
5278
|
* update / delete debounce-triggers a re-render (coalesced, so a bulk seed
|
|
@@ -4152,242 +5338,44 @@ declare class Lattice {
|
|
|
4152
5338
|
recentChanges(opts?: {
|
|
4153
5339
|
table?: string;
|
|
4154
5340
|
since?: string;
|
|
4155
|
-
limit?: number;
|
|
4156
|
-
}): Promise<ChangeEntry[]>;
|
|
4157
|
-
/**
|
|
4158
|
-
* Rollback a specific change by applying the inverse operation.
|
|
4159
|
-
* The rollback itself is recorded as a new changelog entry.
|
|
4160
|
-
*/
|
|
4161
|
-
rollback(changeId: string): Promise<void>;
|
|
4162
|
-
/**
|
|
4163
|
-
* Show field-level diff between two changelog entries for the same row.
|
|
4164
|
-
*/
|
|
4165
|
-
diff(table: string, id: string, fromChangeId: string, toChangeId: string): Promise<Record<string, {
|
|
4166
|
-
old: unknown;
|
|
4167
|
-
new: unknown;
|
|
4168
|
-
}>>;
|
|
4169
|
-
/**
|
|
4170
|
-
* Reconstruct the row state at a specific changelog entry by replaying
|
|
4171
|
-
* all operations up to and including that entry.
|
|
4172
|
-
*/
|
|
4173
|
-
snapshot(table: string, id: string, changeId: string): Promise<Record<string, unknown>>;
|
|
4174
|
-
/**
|
|
4175
|
-
* Manually prune changelog entries based on the configured retention policy.
|
|
4176
|
-
* Also callable directly for on-demand cleanup.
|
|
4177
|
-
*/
|
|
4178
|
-
pruneChangelog(): Promise<void>;
|
|
4179
|
-
private _notInitError;
|
|
4180
|
-
/**
|
|
4181
|
-
* Returns a rejected Promise if any of the given column names are not present
|
|
4182
|
-
* in the table's schema; null if all columns are valid.
|
|
4183
|
-
*
|
|
4184
|
-
* Applied on the read path (query/count) to validate WHERE and filter column
|
|
4185
|
-
* names before they are interpolated into SQL. The write path strips unknown
|
|
4186
|
-
* columns via _filterToSchemaColumns; the read path rejects instead to avoid
|
|
4187
|
-
* silently discarding intended filter conditions.
|
|
4188
|
-
*
|
|
4189
|
-
* Unregistered tables (accessed via the raw `.db` handle) are passed through.
|
|
4190
|
-
*/
|
|
4191
|
-
private _invalidColumnError;
|
|
4192
|
-
private _assertNotInit;
|
|
4193
|
-
}
|
|
4194
|
-
|
|
4195
|
-
/**
|
|
4196
|
-
* Scalar types recognised in `lattice.config.yml` field definitions.
|
|
4197
|
-
*
|
|
4198
|
-
* | YAML type | SQLite type | TypeScript type |
|
|
4199
|
-
* | ----------- | ----------- | --------------- |
|
|
4200
|
-
* | `uuid` | TEXT | string |
|
|
4201
|
-
* | `text` | TEXT | string |
|
|
4202
|
-
* | `integer` | INTEGER | number |
|
|
4203
|
-
* | `int` | INTEGER | number |
|
|
4204
|
-
* | `real` | REAL | number |
|
|
4205
|
-
* | `float` | REAL | number |
|
|
4206
|
-
* | `boolean` | INTEGER | boolean |
|
|
4207
|
-
* | `bool` | INTEGER | boolean |
|
|
4208
|
-
* | `datetime` | TEXT | string |
|
|
4209
|
-
* | `date` | TEXT | string |
|
|
4210
|
-
* | `blob` | BLOB | Buffer |
|
|
4211
|
-
*/
|
|
4212
|
-
type LatticeFieldType = 'uuid' | 'text' | 'integer' | 'int' | 'real' | 'float' | 'boolean' | 'bool' | 'datetime' | 'date' | 'blob';
|
|
4213
|
-
/**
|
|
4214
|
-
* A single field (column) definition in a `lattice.config.yml` entity.
|
|
4215
|
-
*
|
|
4216
|
-
* @example
|
|
4217
|
-
* ```yaml
|
|
4218
|
-
* id: { type: uuid, primaryKey: true }
|
|
4219
|
-
* title: { type: text, required: true }
|
|
4220
|
-
* status: { type: text, default: open }
|
|
4221
|
-
* assignee_id: { type: uuid }
|
|
4222
|
-
* score: { type: integer, default: 0 }
|
|
4223
|
-
* ```
|
|
4224
|
-
*/
|
|
4225
|
-
interface LatticeFieldDef {
|
|
4226
|
-
/** Column data type */
|
|
4227
|
-
type: LatticeFieldType;
|
|
4228
|
-
/** Mark this column as the table's primary key */
|
|
4229
|
-
primaryKey?: boolean;
|
|
4230
|
-
/** Column is NOT NULL */
|
|
4231
|
-
required?: boolean;
|
|
4232
|
-
/** SQL DEFAULT value */
|
|
4233
|
-
default?: string | number | boolean;
|
|
4234
|
-
/**
|
|
4235
|
-
* Per-column audience (Stage-0 scaffolding for the per-viewer enrichment
|
|
4236
|
-
* model). Names who may see this column's value in a cloud. Omitted ⇒
|
|
4237
|
-
* `row-audience` — the value is visible to exactly whoever can see the row,
|
|
4238
|
-
* which is today's behavior, so leaving it unset changes nothing. Later
|
|
4239
|
-
* stages parse a richer grammar (e.g. `subject+role:hr`) and generate a
|
|
4240
|
-
* cell-masking view from it; Stage-0 only records the metadata.
|
|
4241
|
-
*/
|
|
4242
|
-
audience?: string;
|
|
4243
|
-
/**
|
|
4244
|
-
* DEPRECATED (3.x) per-field foreign-key shorthand: `ref: <targetTable>` declared
|
|
4245
|
-
* a `belongsTo` whose relation name is the field name with a trailing `_id`
|
|
4246
|
-
* stripped. Superseded by the explicit entity-level `relations:` block. 4.0 still
|
|
4247
|
-
* PARSES it (converted to a `belongsTo` in-memory) so existing 3.0+ configs keep
|
|
4248
|
-
* working, and the GUI silently rewrites it to `relations:` on open so configs
|
|
4249
|
-
* migrate forward. A future major may drop this once configs have upgraded.
|
|
4250
|
-
*/
|
|
4251
|
-
ref?: string;
|
|
4252
|
-
}
|
|
4253
|
-
/**
|
|
4254
|
-
* Inline render spec inside YAML — a flat object alternative to `TemplateRenderSpec`.
|
|
4255
|
-
*
|
|
4256
|
-
* @example
|
|
4257
|
-
* ```yaml
|
|
4258
|
-
* render:
|
|
4259
|
-
* template: default-list
|
|
4260
|
-
* formatRow: "{{title}} — {{status}}"
|
|
4261
|
-
* ```
|
|
4262
|
-
*/
|
|
4263
|
-
interface LatticeEntityRenderSpec {
|
|
4264
|
-
template: string;
|
|
4265
|
-
formatRow?: string;
|
|
4266
|
-
}
|
|
4267
|
-
/**
|
|
4268
|
-
* A single entity (table) definition in `lattice.config.yml`.
|
|
4269
|
-
*
|
|
4270
|
-
* @example
|
|
4271
|
-
* ```yaml
|
|
4272
|
-
* ticket:
|
|
4273
|
-
* fields:
|
|
4274
|
-
* id: { type: uuid, primaryKey: true }
|
|
4275
|
-
* title: { type: text, required: true }
|
|
4276
|
-
* assignee_id: { type: uuid }
|
|
4277
|
-
* relations:
|
|
4278
|
-
* assignee:
|
|
4279
|
-
* type: belongsTo
|
|
4280
|
-
* table: user
|
|
4281
|
-
* foreignKey: assignee_id
|
|
4282
|
-
* render: default-list
|
|
4283
|
-
* outputFile: context/TICKETS.md
|
|
4284
|
-
* ```
|
|
4285
|
-
*/
|
|
4286
|
-
interface LatticeEntityDef {
|
|
4287
|
-
/** Column definitions */
|
|
4288
|
-
fields: Record<string, LatticeFieldDef>;
|
|
4289
|
-
/**
|
|
4290
|
-
* Explicit `belongsTo` relations for this entity, keyed by relation name.
|
|
4291
|
-
*
|
|
4292
|
-
* Each entry declares a foreign key on THIS entity pointing at another
|
|
4293
|
-
* table: `{ type: belongsTo, table, foreignKey, references? }`. The
|
|
4294
|
-
* `foreignKey` names a plain field on this entity; `references` is the
|
|
4295
|
-
* column on the related table (defaults to its primary key). The relation
|
|
4296
|
-
* name (the map key) is whatever you choose — it is not derived from the
|
|
4297
|
-
* field name.
|
|
4298
|
-
*
|
|
4299
|
-
* @example
|
|
4300
|
-
* ```yaml
|
|
4301
|
-
* relations:
|
|
4302
|
-
* assignee:
|
|
4303
|
-
* type: belongsTo
|
|
4304
|
-
* table: user
|
|
4305
|
-
* foreignKey: assignee_id
|
|
4306
|
-
* # references: id # optional; defaults to the target's primary key
|
|
4307
|
-
* ```
|
|
4308
|
-
*/
|
|
4309
|
-
relations?: Record<string, BelongsToRelation>;
|
|
4310
|
-
/**
|
|
4311
|
-
* How to render rows into context text.
|
|
4312
|
-
* Accepts the same forms as `TableDefinition.render`:
|
|
4313
|
-
* - A `BuiltinTemplateName` string (e.g. `default-list`)
|
|
4314
|
-
* - A `{ template, formatRow }` object for hooks
|
|
4315
|
-
*/
|
|
4316
|
-
render?: string | LatticeEntityRenderSpec;
|
|
4317
|
-
/** Render output file path (relative to the config file directory) */
|
|
4318
|
-
outputFile: string;
|
|
4319
|
-
/**
|
|
4320
|
-
* Optional explicit primary key override.
|
|
4321
|
-
* If omitted, the field with `primaryKey: true` is used.
|
|
4322
|
-
* Accepts a single column name or an array for composite keys.
|
|
4323
|
-
*/
|
|
4324
|
-
primaryKey?: string | string[];
|
|
4325
|
-
}
|
|
4326
|
-
/**
|
|
4327
|
-
* The top-level `lattice.config.yml` document.
|
|
4328
|
-
*
|
|
4329
|
-
* @example
|
|
4330
|
-
* ```yaml
|
|
4331
|
-
* db: ./data/app.db
|
|
4332
|
-
* entities:
|
|
4333
|
-
* ticket:
|
|
4334
|
-
* fields:
|
|
4335
|
-
* id: { type: uuid, primaryKey: true }
|
|
4336
|
-
* title: { type: text, required: true }
|
|
4337
|
-
* render: default-list
|
|
4338
|
-
* outputFile: context/TICKETS.md
|
|
4339
|
-
* ```
|
|
4340
|
-
*/
|
|
4341
|
-
interface LatticeConfig {
|
|
4342
|
-
/** Path to the SQLite database file (relative to the config file) */
|
|
4343
|
-
db: string;
|
|
4344
|
-
/** Entity (table) definitions */
|
|
4345
|
-
entities: Record<string, LatticeEntityDef>;
|
|
4346
|
-
/** Entity context directory definitions */
|
|
4347
|
-
entityContexts?: Record<string, LatticeEntityContextDef>;
|
|
4348
|
-
}
|
|
4349
|
-
/**
|
|
4350
|
-
* Source spec in YAML config — either the shorthand string 'self' or an object.
|
|
4351
|
-
*/
|
|
4352
|
-
type LatticeEntityContextSourceDef = 'self' | {
|
|
4353
|
-
type: 'hasMany';
|
|
4354
|
-
table: string;
|
|
4355
|
-
foreignKey: string;
|
|
4356
|
-
references?: string;
|
|
4357
|
-
} | {
|
|
4358
|
-
type: 'manyToMany';
|
|
4359
|
-
junctionTable: string;
|
|
4360
|
-
localKey: string;
|
|
4361
|
-
remoteKey: string;
|
|
4362
|
-
remoteTable: string;
|
|
4363
|
-
references?: string;
|
|
4364
|
-
} | {
|
|
4365
|
-
type: 'belongsTo';
|
|
4366
|
-
table: string;
|
|
4367
|
-
foreignKey: string;
|
|
4368
|
-
references?: string;
|
|
4369
|
-
};
|
|
4370
|
-
/** A single per-entity file spec in YAML config */
|
|
4371
|
-
interface LatticeEntityContextFileDef {
|
|
4372
|
-
source: LatticeEntityContextSourceDef;
|
|
4373
|
-
template: string;
|
|
4374
|
-
budget?: number;
|
|
4375
|
-
omitIfEmpty?: boolean;
|
|
4376
|
-
}
|
|
4377
|
-
/** Entity context definition in YAML config */
|
|
4378
|
-
interface LatticeEntityContextDef {
|
|
4379
|
-
slug: string;
|
|
4380
|
-
directoryRoot?: string;
|
|
4381
|
-
protectedFiles?: string[];
|
|
4382
|
-
index?: {
|
|
4383
|
-
outputFile: string;
|
|
4384
|
-
render: string;
|
|
4385
|
-
};
|
|
4386
|
-
files: Record<string, LatticeEntityContextFileDef>;
|
|
4387
|
-
combined?: {
|
|
4388
|
-
outputFile: string;
|
|
4389
|
-
exclude?: string[];
|
|
4390
|
-
};
|
|
5341
|
+
limit?: number;
|
|
5342
|
+
}): Promise<ChangeEntry[]>;
|
|
5343
|
+
/**
|
|
5344
|
+
* Rollback a specific change by applying the inverse operation.
|
|
5345
|
+
* The rollback itself is recorded as a new changelog entry.
|
|
5346
|
+
*/
|
|
5347
|
+
rollback(changeId: string): Promise<void>;
|
|
5348
|
+
/**
|
|
5349
|
+
* Show field-level diff between two changelog entries for the same row.
|
|
5350
|
+
*/
|
|
5351
|
+
diff(table: string, id: string, fromChangeId: string, toChangeId: string): Promise<Record<string, {
|
|
5352
|
+
old: unknown;
|
|
5353
|
+
new: unknown;
|
|
5354
|
+
}>>;
|
|
5355
|
+
/**
|
|
5356
|
+
* Reconstruct the row state at a specific changelog entry by replaying
|
|
5357
|
+
* all operations up to and including that entry.
|
|
5358
|
+
*/
|
|
5359
|
+
snapshot(table: string, id: string, changeId: string): Promise<Record<string, unknown>>;
|
|
5360
|
+
/**
|
|
5361
|
+
* Manually prune changelog entries based on the configured retention policy.
|
|
5362
|
+
* Also callable directly for on-demand cleanup.
|
|
5363
|
+
*/
|
|
5364
|
+
pruneChangelog(): Promise<void>;
|
|
5365
|
+
private _notInitError;
|
|
5366
|
+
/**
|
|
5367
|
+
* Returns a rejected Promise if any of the given column names are not present
|
|
5368
|
+
* in the table's schema; null if all columns are valid.
|
|
5369
|
+
*
|
|
5370
|
+
* Applied on the read path (query/count) to validate WHERE and filter column
|
|
5371
|
+
* names before they are interpolated into SQL. The write path strips unknown
|
|
5372
|
+
* columns via _filterToSchemaColumns; the read path rejects instead to avoid
|
|
5373
|
+
* silently discarding intended filter conditions.
|
|
5374
|
+
*
|
|
5375
|
+
* Unregistered tables (accessed via the raw `.db` handle) are passed through.
|
|
5376
|
+
*/
|
|
5377
|
+
private _invalidColumnError;
|
|
5378
|
+
private _assertNotInit;
|
|
4391
5379
|
}
|
|
4392
5380
|
|
|
4393
5381
|
/** Output of a successful config parse — ready to hand to Lattice. */
|
|
@@ -4410,6 +5398,11 @@ interface ParsedConfig {
|
|
|
4410
5398
|
table: string;
|
|
4411
5399
|
definition: EntityContextDefinition;
|
|
4412
5400
|
}[];
|
|
5401
|
+
/** Computed-table (read-only SQL projection) definitions in declaration order */
|
|
5402
|
+
computedTables: readonly {
|
|
5403
|
+
name: string;
|
|
5404
|
+
definition: ComputedTableDef;
|
|
5405
|
+
}[];
|
|
4413
5406
|
}
|
|
4414
5407
|
/**
|
|
4415
5408
|
* Read, parse, and validate a `lattice.config.yml` file.
|
|
@@ -4498,9 +5491,9 @@ declare function fixSchemaConflicts(db: Database.Database, checks: {
|
|
|
4498
5491
|
}[]): void;
|
|
4499
5492
|
|
|
4500
5493
|
/**
|
|
4501
|
-
* Derive a 256-bit AES key from a master password using scrypt
|
|
4502
|
-
* The salt is fixed per Lattice instance — callers should use a
|
|
4503
|
-
* master key per database.
|
|
5494
|
+
* Derive a 256-bit AES key from a master password using scrypt (memoized by the
|
|
5495
|
+
* master-key value). The salt is fixed per Lattice instance — callers should use a
|
|
5496
|
+
* unique master key per database.
|
|
4504
5497
|
*/
|
|
4505
5498
|
declare function deriveKey(masterKey: string): Buffer;
|
|
4506
5499
|
/**
|
|
@@ -4569,7 +5562,7 @@ declare function markdownTable(rows: Row[], columns: MarkdownTableColumn[]): str
|
|
|
4569
5562
|
* @example `slugify('My Agent Name') // 'my-agent-name'`
|
|
4570
5563
|
* @example `slugify('José García') // 'jose-garcia'`
|
|
4571
5564
|
*/
|
|
4572
|
-
declare function slugify(name: string): string;
|
|
5565
|
+
declare function slugify$1(name: string): string;
|
|
4573
5566
|
/**
|
|
4574
5567
|
* Truncate content at a character budget.
|
|
4575
5568
|
*
|
|
@@ -4892,11 +5885,39 @@ declare class DenoSqliteAdapter implements StorageAdapter {
|
|
|
4892
5885
|
private readonly _path;
|
|
4893
5886
|
private readonly _wal;
|
|
4894
5887
|
private readonly _busyTimeout;
|
|
5888
|
+
/**
|
|
5889
|
+
* Prepared-statement cache, keyed by SQL text. This is load-bearing, not an
|
|
5890
|
+
* optimization: `node:sqlite`'s `DatabaseSync.prepare()` — unlike `better-sqlite3`,
|
|
5891
|
+
* which caches compiled statements internally — compiles a FRESH native
|
|
5892
|
+
* `sqlite3_stmt` on every call and never finalizes it eagerly. Preparing per call
|
|
5893
|
+
* (as the raw adapter surface does) therefore leaks a native statement every
|
|
5894
|
+
* `run`/`get`/`all`; under a bulk-write loop (e.g. ingesting a folder of files, or
|
|
5895
|
+
* the change-probe watch loop) these accumulate far faster than GC reclaims them and
|
|
5896
|
+
* abort the runtime with a native memory blowup. Caching by SQL text keeps the live
|
|
5897
|
+
* native-statement count flat — the same behavior `better-sqlite3` gives for free.
|
|
5898
|
+
*/
|
|
5899
|
+
private readonly _stmtCache;
|
|
5900
|
+
private _stmtCacheMisses;
|
|
4895
5901
|
constructor(path: string, options?: {
|
|
4896
5902
|
wal?: boolean;
|
|
4897
5903
|
busyTimeout?: number;
|
|
4898
5904
|
});
|
|
4899
5905
|
get db(): NodeDatabaseSync;
|
|
5906
|
+
/**
|
|
5907
|
+
* Return the compiled statement for `sql`, reusing a cached one when present. A
|
|
5908
|
+
* `node:sqlite` statement is reusable across executions (each `run`/`get`/`all`
|
|
5909
|
+
* re-binds its params), and SQLite's `prepare_v2` auto-recompiles a cached statement
|
|
5910
|
+
* across a schema change (ALTER TABLE) transparently — so reuse is safe. Bounded so a
|
|
5911
|
+
* caller that inlines values into SQL (unbounded distinct text) can't grow it without
|
|
5912
|
+
* limit; on overflow the whole cache is dropped (evicted statements finalize on GC)
|
|
5913
|
+
* and rebuilt from the next calls.
|
|
5914
|
+
*/
|
|
5915
|
+
private _prepared;
|
|
5916
|
+
/** Diagnostics: live cached-statement count + total compiles (cache misses). */
|
|
5917
|
+
stmtCacheStats(): {
|
|
5918
|
+
size: number;
|
|
5919
|
+
misses: number;
|
|
5920
|
+
};
|
|
4900
5921
|
open(): void;
|
|
4901
5922
|
close(): void;
|
|
4902
5923
|
run(sql: string, params?: unknown[]): void;
|
|
@@ -5207,8 +6228,23 @@ interface Connector {
|
|
|
5207
6228
|
* MUST page rather than load everything at once (bounded reads).
|
|
5208
6229
|
*/
|
|
5209
6230
|
listChanges(toolkit: string, model: string, ctx: ListChangesContext): AsyncIterable<ExternalRecord>;
|
|
5210
|
-
/**
|
|
6231
|
+
/**
|
|
6232
|
+
* Optional batch lifecycle. The sync engine calls `beginSyncSession` before a
|
|
6233
|
+
* connector's models are synced and `endSyncSession` after (even on error), so a
|
|
6234
|
+
* connector can open ONE shared resource (e.g. a single MCP transport) and reuse
|
|
6235
|
+
* it across every `listChanges` call instead of reconnecting per parent key.
|
|
6236
|
+
* Connectors that omit these fall back to per-call open (behavior unchanged).
|
|
6237
|
+
*/
|
|
6238
|
+
beginSyncSession?(connectionId: string): Promise<void>;
|
|
6239
|
+
endSyncSession?(connectionId: string): Promise<void>;
|
|
6240
|
+
/** Revoke a connected account (teardown). May retain non-secret reconnect state. */
|
|
5211
6241
|
disconnect(connectionId: string): Promise<void>;
|
|
6242
|
+
/**
|
|
6243
|
+
* Remove ALL local state for a connection, including anything `disconnect`
|
|
6244
|
+
* retained for reconnect (e.g. a stored server URL). Called on hard teardown,
|
|
6245
|
+
* after the registry row is deleted. Optional; omit when disconnect is total.
|
|
6246
|
+
*/
|
|
6247
|
+
purgeConnection?(connectionId: string): Promise<void>;
|
|
5212
6248
|
}
|
|
5213
6249
|
/**
|
|
5214
6250
|
* A connector that connects via direct credentials the member pastes in — an API
|
|
@@ -5239,14 +6275,109 @@ interface CredentialConnector extends Connector {
|
|
|
5239
6275
|
* layer uses this to decide whether to serve the credential connect form.
|
|
5240
6276
|
*/
|
|
5241
6277
|
declare function isCredentialConnector(c: Connector): c is CredentialConnector;
|
|
6278
|
+
/**
|
|
6279
|
+
* How Lattice reaches one MCP server's tools. Everything runs on the local
|
|
6280
|
+
* machine — Lattice IS the MCP client. A remote server is reached over Streamable
|
|
6281
|
+
* HTTP (authorized with that server's own OAuth); a local server runs as a stdio
|
|
6282
|
+
* child process (fully offline, no OAuth). No data is routed through any cloud
|
|
6283
|
+
* middleman (no Lattice-cloud, no model inference).
|
|
6284
|
+
*/
|
|
6285
|
+
interface McpServerSpec {
|
|
6286
|
+
/** Stable server name (e.g. `'atlassian'`, `'monday'`). */
|
|
6287
|
+
name: string;
|
|
6288
|
+
/** Remote Streamable-HTTP endpoint. Omit for a stdio server. */
|
|
6289
|
+
url?: string;
|
|
6290
|
+
/** Local stdio command (the server runs as a child process, fully offline). */
|
|
6291
|
+
command?: string;
|
|
6292
|
+
/** Args for the stdio command. */
|
|
6293
|
+
args?: string[];
|
|
6294
|
+
/**
|
|
6295
|
+
* Transport. Inferred when omitted: `command` → `'stdio'`, a `url` ending in
|
|
6296
|
+
* `/sse` → `'sse'` (the legacy Server-Sent-Events transport many hosted MCP
|
|
6297
|
+
* servers still use), otherwise `'http'` (Streamable HTTP).
|
|
6298
|
+
*/
|
|
6299
|
+
transport?: 'http' | 'sse' | 'stdio';
|
|
6300
|
+
/** Whether the server requires OAuth. Defaults to true for HTTP/SSE, false for stdio. */
|
|
6301
|
+
oauth?: boolean;
|
|
6302
|
+
}
|
|
6303
|
+
/** Begin-connect result: either an OAuth redirect to complete, or an immediate connection. */
|
|
6304
|
+
type McpBeginResult = {
|
|
6305
|
+
kind: 'redirect';
|
|
6306
|
+
redirectUrl: string;
|
|
6307
|
+
pendingId: string;
|
|
6308
|
+
} | {
|
|
6309
|
+
kind: 'connected';
|
|
6310
|
+
connectionId: string;
|
|
6311
|
+
displayName: string | null;
|
|
6312
|
+
};
|
|
6313
|
+
/**
|
|
6314
|
+
* A connector whose data comes from an MCP server it reads over a local transport
|
|
6315
|
+
* (mechanism 2 — Lattice is the MCP client, per-server OAuth, tokens in the
|
|
6316
|
+
* machine-local encrypted store). Connecting means authorizing that server, not a
|
|
6317
|
+
* broker or a Claude subscription. The sync engine is unchanged — `listChanges`
|
|
6318
|
+
* calls MCP read tools instead of a bespoke REST client.
|
|
6319
|
+
*/
|
|
6320
|
+
interface McpConnector extends Connector {
|
|
6321
|
+
/** The MCP server(s) this toolkit reads from. */
|
|
6322
|
+
mcpServers(toolkit: string): McpServerSpec[];
|
|
6323
|
+
/**
|
|
6324
|
+
* Begin connecting. For an OAuth server, run discovery + stash PKCE state and
|
|
6325
|
+
* return a redirect the GUI opens (system browser on desktop). For a local/open
|
|
6326
|
+
* server, validate via `tools/list` and return the connection immediately.
|
|
6327
|
+
* `redirectUri` is where the GUI receives the code; `serverUrl` overrides the
|
|
6328
|
+
* toolkit default (used by the generic bring-your-own-URL connector).
|
|
6329
|
+
* `clientInfo` is a pre-registered OAuth client (id + optional secret) for
|
|
6330
|
+
* authorization servers that support neither a client-ID metadata document nor
|
|
6331
|
+
* dynamic registration. `targetConnectorId` marks a reconnect of an existing
|
|
6332
|
+
* registry row rather than a new connection.
|
|
6333
|
+
*/
|
|
6334
|
+
beginConnect(userId: string, toolkit: string, opts?: {
|
|
6335
|
+
redirectUri?: string;
|
|
6336
|
+
serverUrl?: string;
|
|
6337
|
+
clientInfo?: {
|
|
6338
|
+
client_id: string;
|
|
6339
|
+
client_secret?: string;
|
|
6340
|
+
};
|
|
6341
|
+
targetConnectorId?: string;
|
|
6342
|
+
}): Promise<McpBeginResult>;
|
|
6343
|
+
/**
|
|
6344
|
+
* Finish an OAuth connect: exchange the `code`, store the token under
|
|
6345
|
+
* `mcp_creds:<connectionId>`, and return the connection. `serverName` is the
|
|
6346
|
+
* server's self-reported name from the MCP handshake (display-name material);
|
|
6347
|
+
* `targetConnectorId` echoes the reconnect target recorded at begin. Throws
|
|
6348
|
+
* loudly on a mismatched state or a failed exchange — never a silent default.
|
|
6349
|
+
*/
|
|
6350
|
+
completeConnect(pendingId: string, params: {
|
|
6351
|
+
code: string;
|
|
6352
|
+
state?: string;
|
|
6353
|
+
}): Promise<{
|
|
6354
|
+
connectionId: string;
|
|
6355
|
+
displayName: string | null;
|
|
6356
|
+
serverName?: string;
|
|
6357
|
+
targetConnectorId?: string;
|
|
6358
|
+
}>;
|
|
6359
|
+
/**
|
|
6360
|
+
* OPTIONAL: discover the server's record shapes and persist a typed schema descriptor for
|
|
6361
|
+
* this connection, so {@link Connector.models} emits one typed table per record kind (namespaced
|
|
6362
|
+
* by `prefix`, the server brand). Present on the introspective generic connector; absent on
|
|
6363
|
+
* fixed-schema connectors. Best-effort — resolves null when the server exposes nothing modelable.
|
|
6364
|
+
*/
|
|
6365
|
+
introspect?(connectionId: string, toolkit: string, prefix: string): Promise<unknown>;
|
|
6366
|
+
}
|
|
6367
|
+
/** True when `c` is an {@link McpConnector} (connects via an MCP server, not credentials). */
|
|
6368
|
+
declare function isMcpConnector(c: Connector): c is McpConnector;
|
|
5242
6369
|
|
|
5243
6370
|
/**
|
|
5244
6371
|
* The connector catalog — the single place every built-in connector is wired.
|
|
5245
6372
|
*
|
|
5246
6373
|
* Routes, the sidebar, the settings panel, and sync-all all iterate this list via
|
|
5247
|
-
* the data-driven API ({@link Connector.presentation} / `
|
|
5248
|
-
*
|
|
5249
|
-
*
|
|
6374
|
+
* the data-driven API ({@link Connector.presentation} / `mcpServers` / `models`).
|
|
6375
|
+
*
|
|
6376
|
+
* There is exactly ONE built-in connector: the generic MCP connector. Lattice is
|
|
6377
|
+
* a local MCP client — the user supplies any MCP server URL, authorizes it with
|
|
6378
|
+
* that server's own OAuth, and each added server is its own connection. Nothing
|
|
6379
|
+
* is routed through a cloud middleman, and no provider-specific connector code
|
|
6380
|
+
* exists; a provider is just another MCP server URL.
|
|
5250
6381
|
*
|
|
5251
6382
|
* Named `catalog.ts` (not `registry.ts`) to avoid confusion with the
|
|
5252
6383
|
* `__lattice_connectors` DB table managed in `registry.ts`: this is the in-memory
|
|
@@ -5254,8 +6385,8 @@ declare function isCredentialConnector(c: Connector): c is CredentialConnector;
|
|
|
5254
6385
|
*/
|
|
5255
6386
|
|
|
5256
6387
|
/**
|
|
5257
|
-
*
|
|
5258
|
-
* result to the connectors routes
|
|
6388
|
+
* The built-in connectors, fresh instances per call. The GUI server passes the
|
|
6389
|
+
* result to the connectors routes.
|
|
5259
6390
|
*/
|
|
5260
6391
|
declare function builtinConnectors(): Connector[];
|
|
5261
6392
|
|
|
@@ -5327,7 +6458,7 @@ declare function getConnectorByToolkit(db: Lattice, toolkit: string, connectedBy
|
|
|
5327
6458
|
*/
|
|
5328
6459
|
declare function listConnectors(db: Lattice, connectedBy?: string): Promise<ConnectorRecord[]>;
|
|
5329
6460
|
/** Update a connector's backend connection id + mark it connected (re-auth/reuse). */
|
|
5330
|
-
declare function updateConnectorConnection(db: Lattice, id: string, connectionRef: string): Promise<void>;
|
|
6461
|
+
declare function updateConnectorConnection(db: Lattice, id: string, connectionRef: string, toolkit?: string): Promise<void>;
|
|
5331
6462
|
/** Record a sync outcome: success stamps `last_sync_at` + clears the error. */
|
|
5332
6463
|
declare function recordSync(db: Lattice, id: string, outcome: {
|
|
5333
6464
|
ok: true;
|
|
@@ -5349,296 +6480,577 @@ declare function setConnectorStatus(db: Lattice, id: string, status: ConnectorSt
|
|
|
5349
6480
|
declare function deleteConnectorRecord(db: Lattice, id: string): Promise<void>;
|
|
5350
6481
|
|
|
5351
6482
|
/**
|
|
5352
|
-
*
|
|
5353
|
-
* APIs DIRECTLY via the optional `jira.js` dependency, authenticated with the
|
|
5354
|
-
* user's OWN Atlassian credentials (site URL + email + API token, HTTP Basic).
|
|
5355
|
-
* No broker, no extra API key.
|
|
6483
|
+
* Shared connector errors.
|
|
5356
6484
|
*
|
|
5357
|
-
*
|
|
5358
|
-
*
|
|
5359
|
-
* the
|
|
5360
|
-
*
|
|
5361
|
-
* `disconnect` (teardown) satisfy the SPI normally, keyed by the stored
|
|
5362
|
-
* connection. The schema (the six connected models) lives in `./models.ts`; this
|
|
5363
|
-
* file is the fetch/auth half.
|
|
6485
|
+
* Lives in its own module (not inside any one connector) so every connector and
|
|
6486
|
+
* the GUI routes reference a single {@link ConnectorUnavailableError} identity —
|
|
6487
|
+
* the route layer maps it to a 422 via `instanceof`, so a split identity would
|
|
6488
|
+
* silently break that mapping.
|
|
5364
6489
|
*/
|
|
5365
|
-
|
|
5366
|
-
/** The user's Atlassian credentials for one Jira connection. */
|
|
5367
|
-
interface JiraCreds {
|
|
5368
|
-
/** Site base URL, e.g. `https://your-domain.atlassian.net`. */
|
|
5369
|
-
site: string;
|
|
5370
|
-
/** Atlassian account email (the Basic-auth username). */
|
|
5371
|
-
email: string;
|
|
5372
|
-
/** Atlassian API token (the Basic-auth password) — a user secret. */
|
|
5373
|
-
apiToken: string;
|
|
5374
|
-
}
|
|
5375
|
-
/** Thrown when the connector is used but its prerequisites are missing. */
|
|
6490
|
+
/** Thrown when a connector is used but its prerequisites are missing. */
|
|
5376
6491
|
declare class ConnectorUnavailableError extends Error {
|
|
5377
6492
|
constructor(message: string);
|
|
5378
6493
|
}
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5387
|
-
|
|
5388
|
-
|
|
5389
|
-
|
|
5390
|
-
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
|
|
5394
|
-
|
|
5395
|
-
|
|
5396
|
-
|
|
5397
|
-
|
|
5398
|
-
|
|
5399
|
-
|
|
5400
|
-
|
|
5401
|
-
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
|
|
5406
|
-
|
|
5407
|
-
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
}): Promise<{
|
|
5412
|
-
comments: Json$1[];
|
|
5413
|
-
total?: number;
|
|
5414
|
-
}>;
|
|
5415
|
-
getAllUsers(args: {
|
|
5416
|
-
startAt: number;
|
|
5417
|
-
maxResults: number;
|
|
5418
|
-
}): Promise<Json$1[]>;
|
|
5419
|
-
getAllBoards(args: {
|
|
5420
|
-
startAt: number;
|
|
5421
|
-
maxResults: number;
|
|
5422
|
-
}): Promise<{
|
|
5423
|
-
values: Json$1[];
|
|
5424
|
-
total?: number;
|
|
5425
|
-
isLast?: boolean;
|
|
5426
|
-
}>;
|
|
5427
|
-
getAllSprints(args: {
|
|
5428
|
-
boardId: number;
|
|
5429
|
-
startAt: number;
|
|
5430
|
-
maxResults: number;
|
|
5431
|
-
}): Promise<{
|
|
5432
|
-
values: Json$1[];
|
|
5433
|
-
total?: number;
|
|
5434
|
-
isLast?: boolean;
|
|
5435
|
-
}>;
|
|
6494
|
+
|
|
6495
|
+
/**
|
|
6496
|
+
* The MCP transport seam.
|
|
6497
|
+
*
|
|
6498
|
+
* An {@link McpConnector} calls a read tool by name and gets back the tool's raw
|
|
6499
|
+
* JSON result; *how* the call reaches the server is the transport's concern. This
|
|
6500
|
+
* keeps the connector modules (schema + mappers) and the sync engine completely
|
|
6501
|
+
* decoupled from the MCP SDK — and lets tests inject a fake transport with canned
|
|
6502
|
+
* tool JSON instead of standing up a real server.
|
|
6503
|
+
*
|
|
6504
|
+
* There is exactly one production implementation ({@link './direct-transport.ts'}):
|
|
6505
|
+
* Lattice as a local MCP client over Streamable HTTP (remote servers) or stdio
|
|
6506
|
+
* (local server processes). Nothing routes through a cloud middleman.
|
|
6507
|
+
*/
|
|
6508
|
+
/** One MCP read-tool invocation. */
|
|
6509
|
+
interface McpToolCall {
|
|
6510
|
+
/** Tool name (e.g. `'search_threads'`). */
|
|
6511
|
+
tool: string;
|
|
6512
|
+
/** Tool arguments (the tool's input schema). */
|
|
6513
|
+
args: Record<string, unknown>;
|
|
6514
|
+
}
|
|
6515
|
+
/** A tool discovered on the server (name + optional description), for connect-time validation. */
|
|
6516
|
+
interface McpToolInfo {
|
|
6517
|
+
name: string;
|
|
6518
|
+
description?: string;
|
|
6519
|
+
}
|
|
6520
|
+
/** A resource advertised by the server (`resources/list`) — its "available files". */
|
|
6521
|
+
interface McpResourceInfo {
|
|
6522
|
+
name: string;
|
|
6523
|
+
uri: string;
|
|
6524
|
+
description?: string;
|
|
6525
|
+
mimeType?: string;
|
|
5436
6526
|
}
|
|
5437
6527
|
/**
|
|
5438
|
-
*
|
|
5439
|
-
*
|
|
5440
|
-
*
|
|
5441
|
-
* resolve `jira.js` — it need not be installed to compile latticesql.
|
|
6528
|
+
* A live connection to one MCP server. Implementations MUST NOT hold the
|
|
6529
|
+
* connection open across calls unless {@link close} is honored — connectors open
|
|
6530
|
+
* a transport, drain a model's pages, and close.
|
|
5442
6531
|
*/
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
/**
|
|
5449
|
-
* @param clientFactory builds a {@link JiraClient} from creds (default: the lazy
|
|
5450
|
-
* `jira.js` loader; tests inject a fake).
|
|
5451
|
-
* @param credsLoader resolves a connection id to its stored creds (default: the
|
|
5452
|
-
* machine-local store; tests inject a fake).
|
|
5453
|
-
*/
|
|
5454
|
-
constructor(clientFactory?: (creds: JiraCreds) => Promise<JiraClient>, credsLoader?: (connectionId: string) => JiraCreds | null);
|
|
5455
|
-
toolkits(): string[];
|
|
5456
|
-
models(toolkit: string): ConnectedModelDef[];
|
|
5457
|
-
presentation(toolkit: string): ToolkitPresentation;
|
|
5458
|
-
credentialFields(): CredentialField[];
|
|
5459
|
-
helpUrl(): string;
|
|
6532
|
+
interface McpTransport {
|
|
6533
|
+
/** List the callable tools on the server (connect-time validation + discovery). */
|
|
6534
|
+
listTools(): Promise<McpToolInfo[]>;
|
|
6535
|
+
/** Call one read tool; returns the parsed JSON content the tool produced. */
|
|
6536
|
+
callTool(call: McpToolCall): Promise<unknown>;
|
|
5460
6537
|
/**
|
|
5461
|
-
*
|
|
5462
|
-
*
|
|
5463
|
-
* therefore not part of the Jira flow and throw a clear, actionable error.
|
|
6538
|
+
* List the server's advertised resources (standard MCP `resources/list`).
|
|
6539
|
+
* Servers without the resources capability yield `[]`, never an error.
|
|
5464
6540
|
*/
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
6541
|
+
listResources(): Promise<McpResourceInfo[]>;
|
|
6542
|
+
/** The server's self-reported identity from the `initialize` handshake, if known. */
|
|
6543
|
+
serverInfo?(): {
|
|
6544
|
+
name?: string;
|
|
6545
|
+
title?: string;
|
|
6546
|
+
version?: string;
|
|
6547
|
+
} | undefined;
|
|
6548
|
+
/** Close the underlying client/session. */
|
|
6549
|
+
close(): Promise<void>;
|
|
6550
|
+
}
|
|
6551
|
+
/**
|
|
6552
|
+
* Builds a transport for one connected MCP server. The connector base takes this
|
|
6553
|
+
* as a constructor seam so tests inject a fake and production injects the direct
|
|
6554
|
+
* client. `connectionId` keys the stored OAuth token for the server.
|
|
6555
|
+
*/
|
|
6556
|
+
type McpTransportFactory = (server: McpServerRef) => Promise<McpTransport>;
|
|
6557
|
+
/** The resolved server + connection a transport should attach to. */
|
|
6558
|
+
interface McpServerRef {
|
|
6559
|
+
/** Server name (for diagnostics). */
|
|
6560
|
+
name: string;
|
|
6561
|
+
/** Remote endpoint, or undefined for a stdio server. */
|
|
6562
|
+
url?: string;
|
|
6563
|
+
/** Local stdio command + args, or undefined for an HTTP/SSE server. */
|
|
6564
|
+
command?: string;
|
|
6565
|
+
args?: string[];
|
|
6566
|
+
/** `'http'` (Streamable HTTP), `'sse'`, or `'stdio'` — resolved by the connector. */
|
|
6567
|
+
transport: 'http' | 'sse' | 'stdio';
|
|
6568
|
+
/** The registry connection id — keys the stored OAuth token (HTTP/SSE servers). */
|
|
6569
|
+
connectionId: string;
|
|
6570
|
+
}
|
|
6571
|
+
|
|
6572
|
+
/**
|
|
6573
|
+
* The direct MCP client transport — Lattice talks to an MCP server itself, on the
|
|
6574
|
+
* local machine, over Streamable HTTP (remote servers, per-server OAuth) or stdio
|
|
6575
|
+
* (a local server process, fully offline). This is the only production transport:
|
|
6576
|
+
* no data is routed through a cloud middleman.
|
|
6577
|
+
*
|
|
6578
|
+
* `@modelcontextprotocol/sdk` is an OPTIONAL dependency, lazy-imported with
|
|
6579
|
+
* non-literal specifiers so `latticesql` compiles + installs without it (and so
|
|
6580
|
+
* it resolves under both Node and the desktop Deno runtime). The SDK surface is
|
|
6581
|
+
* hand-typed at the seam, mirroring the Jira `jira.js` seam.
|
|
6582
|
+
*/
|
|
6583
|
+
|
|
6584
|
+
/**
|
|
6585
|
+
* The transport factory used at SYNC time — the connection is already authorized,
|
|
6586
|
+
* so the stored token is attached and no redirect is expected. Opens a client,
|
|
6587
|
+
* ready for `listChanges` to call read tools.
|
|
6588
|
+
*/
|
|
6589
|
+
declare function connectDirect(ref: McpServerRef): Promise<McpTransport>;
|
|
6590
|
+
interface BeginOAuthArgs {
|
|
6591
|
+
connectionId: string;
|
|
6592
|
+
serverUrl: string;
|
|
6593
|
+
redirectUri: string;
|
|
6594
|
+
state: string;
|
|
6595
|
+
/** `'http'` (Streamable HTTP) or `'sse'`. */
|
|
6596
|
+
transportKind: 'http' | 'sse';
|
|
6597
|
+
clientName?: string;
|
|
6598
|
+
scope?: string;
|
|
6599
|
+
}
|
|
6600
|
+
interface CompleteOAuthArgs {
|
|
6601
|
+
connectionId: string;
|
|
6602
|
+
redirectUri: string;
|
|
6603
|
+
code: string;
|
|
6604
|
+
/** `'http'` (Streamable HTTP) or `'sse'` — must match the begin call. */
|
|
6605
|
+
transportKind: 'http' | 'sse';
|
|
6606
|
+
clientName?: string;
|
|
6607
|
+
scope?: string;
|
|
6608
|
+
state?: string;
|
|
6609
|
+
}
|
|
6610
|
+
|
|
6611
|
+
/**
|
|
6612
|
+
* The base for every MCP-backed connector.
|
|
6613
|
+
*
|
|
6614
|
+
* A concrete connector (Gmail, Calendar, Jira, …) supplies only schema + mapping:
|
|
6615
|
+
* the connected {@link ConnectedModelDef}s (`models`), the MCP server(s) it reads
|
|
6616
|
+
* from (`mcpServers`), and, per model, which read tool feeds it and how to map the
|
|
6617
|
+
* tool's JSON into rows (`bindings`). Everything else — connecting (per-server
|
|
6618
|
+
* OAuth or a local stdio server), paging, and yielding {@link ExternalRecord}s to
|
|
6619
|
+
* the unchanged sync engine — lives here.
|
|
6620
|
+
*
|
|
6621
|
+
* The transport and OAuth driver are constructor seams so tests inject fakes and
|
|
6622
|
+
* never touch the network or the MCP SDK.
|
|
6623
|
+
*/
|
|
6624
|
+
|
|
6625
|
+
/** Binds one connected model to the MCP read tool that feeds it, plus its mapper. */
|
|
6626
|
+
interface McpModelBinding {
|
|
6627
|
+
/** The connected model key (matches {@link ConnectedModelDef.model}). */
|
|
6628
|
+
model: string;
|
|
6629
|
+
/** The MCP read tool that feeds this model. */
|
|
6630
|
+
tool: string;
|
|
6631
|
+
/**
|
|
6632
|
+
* Build the tool arguments for one page. `parentKey` is set for per-parent
|
|
6633
|
+
* models (e.g. an issue key when fetching its comments); `cursor` is the page
|
|
6634
|
+
* token from {@link nextCursor} on the prior page (null on the first page).
|
|
6635
|
+
*/
|
|
6636
|
+
buildArgs(ctx: {
|
|
6637
|
+
parentKey?: string;
|
|
6638
|
+
cursor?: string | null;
|
|
6639
|
+
}): Record<string, unknown>;
|
|
6640
|
+
/** Pull the array of raw items out of the tool's JSON result. */
|
|
6641
|
+
items(result: unknown): unknown[];
|
|
6642
|
+
/** Map one raw item to an {@link ExternalRecord}. Return null to skip it. */
|
|
6643
|
+
map(item: unknown, ctx: {
|
|
6644
|
+
parentKey?: string;
|
|
6645
|
+
}): ExternalRecord | null;
|
|
6646
|
+
/** Extract the next-page cursor, or a falsy value when the last page was reached. */
|
|
6647
|
+
nextCursor?(result: unknown): string | null | undefined;
|
|
6648
|
+
}
|
|
6649
|
+
/** OAuth driver seam — the real SDK-backed functions in production, fakes in tests. */
|
|
6650
|
+
interface McpOAuthDriver {
|
|
6651
|
+
begin(args: BeginOAuthArgs): Promise<{
|
|
6652
|
+
authorizationUrl: string | undefined;
|
|
6653
|
+
toolNames: string[];
|
|
6654
|
+
serverName?: string;
|
|
6655
|
+
}>;
|
|
6656
|
+
complete(args: CompleteOAuthArgs): Promise<{
|
|
6657
|
+
toolNames: string[];
|
|
6658
|
+
serverName?: string;
|
|
6659
|
+
}>;
|
|
6660
|
+
}
|
|
6661
|
+
declare abstract class McpConnectorBase implements McpConnector {
|
|
6662
|
+
private readonly transportFactory;
|
|
6663
|
+
private readonly oauth;
|
|
6664
|
+
protected constructor(transportFactory?: McpTransportFactory, oauth?: McpOAuthDriver);
|
|
6665
|
+
abstract readonly connector: string;
|
|
6666
|
+
abstract toolkits(): string[];
|
|
6667
|
+
abstract presentation(toolkit: string): ToolkitPresentation;
|
|
6668
|
+
abstract models(toolkit: string): ConnectedModelDef[];
|
|
6669
|
+
abstract mcpServers(toolkit: string): McpServerSpec[];
|
|
6670
|
+
/** The per-model tool + mapper bindings for a toolkit. */
|
|
6671
|
+
protected abstract bindings(toolkit: string): McpModelBinding[];
|
|
6672
|
+
/** Optional OAuth scope string requested for a toolkit's server. */
|
|
6673
|
+
protected scope(_toolkit: string): string | undefined;
|
|
6674
|
+
private resolveServer;
|
|
6675
|
+
private transportKind;
|
|
6676
|
+
private needsOAuth;
|
|
6677
|
+
private buildRef;
|
|
6678
|
+
/** Open a transport to this toolkit's server for an existing connection (sync time). */
|
|
6679
|
+
protected openServerTransport(toolkit: string, connectionId: string): Promise<McpTransport>;
|
|
6680
|
+
beginConnect(_userId: string, toolkit: string, opts?: {
|
|
6681
|
+
redirectUri?: string;
|
|
6682
|
+
serverUrl?: string;
|
|
6683
|
+
clientInfo?: {
|
|
6684
|
+
client_id: string;
|
|
6685
|
+
client_secret?: string;
|
|
6686
|
+
};
|
|
6687
|
+
targetConnectorId?: string;
|
|
6688
|
+
}): Promise<McpBeginResult>;
|
|
6689
|
+
completeConnect(pendingId: string, params: {
|
|
6690
|
+
code: string;
|
|
6691
|
+
state?: string;
|
|
6692
|
+
}): Promise<{
|
|
5477
6693
|
connectionId: string;
|
|
5478
6694
|
displayName: string | null;
|
|
6695
|
+
serverName?: string;
|
|
6696
|
+
targetConnectorId?: string;
|
|
5479
6697
|
}>;
|
|
5480
|
-
listChanges(toolkit: string, model: string, ctx: ListChangesContext): AsyncIterable<ExternalRecord>;
|
|
5481
6698
|
disconnect(connectionId: string): Promise<void>;
|
|
5482
|
-
|
|
5483
|
-
private
|
|
5484
|
-
|
|
5485
|
-
|
|
6699
|
+
purgeConnection(connectionId: string): Promise<void>;
|
|
6700
|
+
private readonly _activeSessions;
|
|
6701
|
+
private readonly _sessionTransports;
|
|
6702
|
+
/** Reuse ONE transport for this connection across the sync's models/parents. */
|
|
6703
|
+
beginSyncSession(connectionId: string): Promise<void>;
|
|
6704
|
+
/** Close + evict the shared transport opened during the session (idempotent). */
|
|
6705
|
+
endSyncSession(connectionId: string): Promise<void>;
|
|
6706
|
+
listChanges(toolkit: string, model: string, ctx: ListChangesContext): AsyncIterable<ExternalRecord>;
|
|
6707
|
+
authorize(_userId: string, _toolkit: string): Promise<AuthorizeResult>;
|
|
6708
|
+
completeAuth(_userId: string, _toolkit: string): Promise<ConnectionResult>;
|
|
6709
|
+
private displayNameFor;
|
|
6710
|
+
}
|
|
6711
|
+
/** A single-toolkit MCP connector defined purely by schema + bindings. */
|
|
6712
|
+
interface McpConnectorSpec {
|
|
6713
|
+
/** Connector id (also the toolkit id unless {@link toolkit} is set). */
|
|
6714
|
+
connector: string;
|
|
6715
|
+
/** Toolkit id, if it differs from the connector id. */
|
|
6716
|
+
toolkit?: string;
|
|
6717
|
+
presentation: ToolkitPresentation;
|
|
6718
|
+
servers: McpServerSpec[];
|
|
6719
|
+
models: ConnectedModelDef[];
|
|
6720
|
+
bindings: McpModelBinding[];
|
|
6721
|
+
/** OAuth scope requested for the server, if any. */
|
|
6722
|
+
scope?: string;
|
|
6723
|
+
}
|
|
6724
|
+
/** Test/DI seams for a {@link SimpleMcpConnector}. */
|
|
6725
|
+
interface McpConnectorDeps {
|
|
6726
|
+
transportFactory?: McpTransportFactory;
|
|
6727
|
+
oauth?: McpOAuthDriver;
|
|
6728
|
+
}
|
|
6729
|
+
/**
|
|
6730
|
+
* The concrete connector every built-in MCP connector module instantiates: it
|
|
6731
|
+
* wires a {@link McpConnectorSpec} into the base, so a connector module is just
|
|
6732
|
+
* its table schema + per-model tool bindings — no class boilerplate.
|
|
6733
|
+
*/
|
|
6734
|
+
declare class SimpleMcpConnector extends McpConnectorBase {
|
|
6735
|
+
private readonly spec;
|
|
6736
|
+
readonly connector: string;
|
|
6737
|
+
private readonly toolkit;
|
|
6738
|
+
constructor(spec: McpConnectorSpec, deps?: McpConnectorDeps);
|
|
6739
|
+
toolkits(): string[];
|
|
6740
|
+
presentation(_toolkit: string): ToolkitPresentation;
|
|
6741
|
+
models(_toolkit: string): ConnectedModelDef[];
|
|
6742
|
+
mcpServers(_toolkit: string): McpServerSpec[];
|
|
6743
|
+
protected bindings(_toolkit: string): McpModelBinding[];
|
|
6744
|
+
protected scope(_toolkit: string): string | undefined;
|
|
5486
6745
|
}
|
|
5487
6746
|
|
|
5488
6747
|
/**
|
|
5489
|
-
*
|
|
5490
|
-
*
|
|
5491
|
-
*
|
|
5492
|
-
*
|
|
5493
|
-
* re-syncs upsert idempotently), and the FK relations that derive graph edges.
|
|
5494
|
-
* The fetch/map logic lives in the connector ({@link JiraConnector}), which calls
|
|
5495
|
-
* the Jira REST/Agile API directly via `jira.js` — there is no broker.
|
|
6748
|
+
* Shared builder for MCP-connector connected models — the same "Jira data
|
|
6749
|
+
* conventions" every connector reuses: a Lattice {@link TableDefinition} with the
|
|
6750
|
+
* standard lifecycle columns, a `source` descriptor (per-member `private`
|
|
6751
|
+
* visibility), an `outputFile`, and optional graph edges + a per-parent binding.
|
|
5496
6752
|
*/
|
|
5497
6753
|
|
|
5498
|
-
|
|
5499
|
-
|
|
6754
|
+
interface McpModelArgs {
|
|
6755
|
+
connector: string;
|
|
6756
|
+
toolkit: string;
|
|
6757
|
+
table: string;
|
|
6758
|
+
model: string;
|
|
6759
|
+
naturalKey: string;
|
|
6760
|
+
columns: Record<string, string>;
|
|
6761
|
+
def: Partial<TableDefinition>;
|
|
6762
|
+
graphEdges?: ConnectedModelDef['graphEdges'];
|
|
6763
|
+
parent?: ConnectedModelDef['parent'];
|
|
6764
|
+
}
|
|
6765
|
+
/** Build a {@link ConnectedModelDef} for an MCP connector (mirrors `jira/models.ts`). */
|
|
6766
|
+
declare function mcpModel(args: McpModelArgs): ConnectedModelDef;
|
|
6767
|
+
|
|
5500
6768
|
/**
|
|
5501
|
-
*
|
|
5502
|
-
*
|
|
6769
|
+
* Persisted + memoized schema descriptor for one MCP connection — the MCP analogue of
|
|
6770
|
+
* `db-source/schema-cache.ts`. The connector SPI's `models()` is SYNCHRONOUS, but discovering
|
|
6771
|
+
* an MCP server's record shapes means calling its read tools (async), so introspection happens
|
|
6772
|
+
* in the async connect/refresh path, persists a descriptor in the machine-local encrypted store
|
|
6773
|
+
* (keyed `mcp_schema:<connectionId>`), and `models()` reads it back synchronously via
|
|
6774
|
+
* {@link buildMcpModelDefs}. That turns a server's flat item stream into one TYPED table per
|
|
6775
|
+
* record kind (e.g. `deduction_types`, `company`), each namespaced per connection so two servers
|
|
6776
|
+
* never collide and each auto-groups under its own GUI schema header (via `mcp:<connId>` toolkit).
|
|
5503
6777
|
*/
|
|
5504
|
-
|
|
6778
|
+
|
|
6779
|
+
/** SQL spec inferred for a modeled column. */
|
|
6780
|
+
type McpSqlSpec = 'TEXT' | 'INTEGER' | 'REAL';
|
|
6781
|
+
interface McpColumnDesc {
|
|
6782
|
+
name: string;
|
|
6783
|
+
sqlSpec: McpSqlSpec;
|
|
6784
|
+
}
|
|
6785
|
+
/** One record kind discovered on the server → one typed Lattice table. */
|
|
6786
|
+
interface McpKindDesc {
|
|
6787
|
+
/** Record kind slug (the table's identity within the connection), e.g. `deduction_types`. */
|
|
6788
|
+
kind: string;
|
|
6789
|
+
/** The server read tool whose items populate this kind (e.g. `list_deduction_types`). */
|
|
6790
|
+
tool: string;
|
|
6791
|
+
/** Modeled columns inferred from sampled items (excludes the natural key + lifecycle cols). */
|
|
6792
|
+
columns: McpColumnDesc[];
|
|
6793
|
+
/** The item field used as the natural key, or `_pk` when synthesized (no stable id field). */
|
|
6794
|
+
naturalKey: string;
|
|
6795
|
+
}
|
|
6796
|
+
interface McpSchemaDescriptor {
|
|
6797
|
+
/** Sanitized slug namespacing this connection's tables (from the server brand / display name). */
|
|
6798
|
+
prefix: string;
|
|
6799
|
+
kinds: McpKindDesc[];
|
|
6800
|
+
}
|
|
5505
6801
|
|
|
5506
6802
|
/**
|
|
5507
|
-
* The
|
|
5508
|
-
*
|
|
5509
|
-
*
|
|
5510
|
-
*
|
|
6803
|
+
* The introspective MCP connector — the always-works path.
|
|
6804
|
+
*
|
|
6805
|
+
* Point it at ANY reachable MCP server (a URL you supply, or a local stdio
|
|
6806
|
+
* command) and it pulls that server's readable items in as context without a
|
|
6807
|
+
* hand-authored schema: it introspects the server's tools (`tools/list`), calls
|
|
6808
|
+
* each no-argument read tool, and ALSO lists the server's advertised resources
|
|
6809
|
+
* (`resources/list` — its "available files"). Everything lands in one connected
|
|
6810
|
+
* `*_items` table (typed columns for kind/tool/server/title/summary + a JSON
|
|
6811
|
+
* `data` blob, FTS on title/summary, per-member `private` visibility — the same
|
|
6812
|
+
* connector-table conventions the sync engine expects).
|
|
5511
6813
|
*
|
|
5512
|
-
*
|
|
5513
|
-
*
|
|
5514
|
-
*
|
|
5515
|
-
*
|
|
5516
|
-
*
|
|
5517
|
-
*
|
|
5518
|
-
*
|
|
6814
|
+
* Two uses:
|
|
6815
|
+
* - {@link genericConnector} — the built-in bring-your-own-URL connector; every
|
|
6816
|
+
* added server is its own connection (one registry row per server).
|
|
6817
|
+
* - {@link introspectiveConnector} — the same engine pre-pointed at a fixed
|
|
6818
|
+
* endpoint with its own table name, for library consumers that embed a
|
|
6819
|
+
* specific provider.
|
|
6820
|
+
*
|
|
6821
|
+
* Only read-shaped tools are called: tools that require arguments are skipped in
|
|
6822
|
+
* introspective mode, and obvious write tools are never called.
|
|
5519
6823
|
*/
|
|
5520
6824
|
|
|
5521
|
-
/**
|
|
5522
|
-
interface
|
|
5523
|
-
/**
|
|
5524
|
-
|
|
5525
|
-
/**
|
|
5526
|
-
|
|
6825
|
+
/** Configuration for an introspective connector instance. */
|
|
6826
|
+
interface IntrospectiveSpec {
|
|
6827
|
+
/** Connector + toolkit id. */
|
|
6828
|
+
connector: string;
|
|
6829
|
+
/** Display label. */
|
|
6830
|
+
label: string;
|
|
6831
|
+
/** Badge letter + colour for the fallback icon. */
|
|
6832
|
+
iconLetter: string;
|
|
6833
|
+
iconColor: string;
|
|
6834
|
+
/** The connected table name (e.g. `'mcp_items'`, `'jira_items'`). */
|
|
6835
|
+
table: string;
|
|
6836
|
+
/** The MCP server(s). A branded connector sets a default url; generic leaves it blank. */
|
|
6837
|
+
servers: McpServerSpec[];
|
|
5527
6838
|
}
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
|
|
5531
|
-
|
|
5532
|
-
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
|
|
5536
|
-
|
|
5537
|
-
|
|
5538
|
-
limit: number;
|
|
5539
|
-
/** Return only rows older than this id (Trello returns newest-first). */
|
|
5540
|
-
before?: string;
|
|
5541
|
-
}
|
|
5542
|
-
/** The minimal Trello surface the connector depends on (all calls return raw REST shapes). */
|
|
5543
|
-
interface TrelloClient {
|
|
5544
|
-
/** Validate the credentials + return the authenticated member (`GET /members/me`). */
|
|
5545
|
-
me(): Promise<Json>;
|
|
5546
|
-
/** The authenticated member's boards (`GET /members/me/boards`). */
|
|
5547
|
-
myBoards(): Promise<Json[]>;
|
|
5548
|
-
/** A board's lists (`GET /boards/{id}/lists`). */
|
|
5549
|
-
boardLists(boardId: string): Promise<Json[]>;
|
|
5550
|
-
/** A board's members (`GET /boards/{id}/members`). */
|
|
5551
|
-
boardMembers(boardId: string): Promise<Json[]>;
|
|
5552
|
-
/** A board's labels (`GET /boards/{id}/labels`). */
|
|
5553
|
-
boardLabels(boardId: string): Promise<Json[]>;
|
|
5554
|
-
/** A board's cards, paged newest-first via `before` (`GET /boards/{id}/cards`). */
|
|
5555
|
-
boardCards(boardId: string, opts: TrelloPageOpts): Promise<Json[]>;
|
|
5556
|
-
/** A card's `commentCard` actions, paged via `before` (`GET /cards/{id}/actions`). */
|
|
5557
|
-
cardComments(cardId: string, opts: TrelloPageOpts): Promise<Json[]>;
|
|
5558
|
-
/** A card's assigned members (`GET /cards/{id}/members`). */
|
|
5559
|
-
cardMembers(cardId: string): Promise<Json[]>;
|
|
5560
|
-
/** A card's applied labels (`GET /cards/{id}/labels`). */
|
|
5561
|
-
cardLabels(cardId: string): Promise<Json[]>;
|
|
5562
|
-
/** A card's checklists (`GET /cards/{id}/checklists`). */
|
|
5563
|
-
cardChecklists(cardId: string): Promise<Json[]>;
|
|
5564
|
-
/** A checklist's items (`GET /checklists/{id}/checkItems`). */
|
|
5565
|
-
checklistItems(checklistId: string): Promise<Json[]>;
|
|
5566
|
-
}
|
|
5567
|
-
/**
|
|
5568
|
-
* Build a {@link TrelloClient} that talks to Trello over the Node global `fetch`,
|
|
5569
|
-
* authenticated with the user's API key + token. No SDK, no extra dependency.
|
|
5570
|
-
*/
|
|
5571
|
-
declare function loadTrelloClient(creds: TrelloCreds): Promise<TrelloClient>;
|
|
5572
|
-
declare class TrelloConnector implements CredentialConnector {
|
|
5573
|
-
private readonly clientFactory;
|
|
5574
|
-
private readonly credsLoader;
|
|
5575
|
-
readonly connector = "trello";
|
|
6839
|
+
declare class IntrospectiveMcpConnector extends McpConnectorBase {
|
|
6840
|
+
private readonly spec;
|
|
6841
|
+
readonly connector: string;
|
|
6842
|
+
private readonly model;
|
|
6843
|
+
constructor(spec: IntrospectiveSpec, deps?: McpConnectorDeps);
|
|
6844
|
+
toolkits(): string[];
|
|
6845
|
+
presentation(_toolkit: string): ToolkitPresentation;
|
|
6846
|
+
models(toolkit: string): ConnectedModelDef[];
|
|
6847
|
+
mcpServers(_toolkit: string): McpServerSpec[];
|
|
6848
|
+
protected bindings(_toolkit: string): McpModelBinding[];
|
|
5576
6849
|
/**
|
|
5577
|
-
*
|
|
5578
|
-
*
|
|
5579
|
-
*
|
|
5580
|
-
*
|
|
6850
|
+
* Discover the server's record shapes and persist a typed schema descriptor: call each
|
|
6851
|
+
* non-write read tool once, infer a kind + typed columns from a sample, and store it under
|
|
6852
|
+
* the connection. `models()` then emits one typed table per kind. Best-effort — returns null
|
|
6853
|
+
* when the server exposes nothing modelable (the caller keeps the flat `mcp_items` fallback).
|
|
6854
|
+
* `prefix` namespaces the tables (the server brand, e.g. `justworks`).
|
|
5581
6855
|
*/
|
|
5582
|
-
|
|
6856
|
+
introspect(connectionId: string, toolkit: string, prefix: string): Promise<McpSchemaDescriptor | null>;
|
|
6857
|
+
listChanges(toolkit: string, model: string, ctx: ListChangesContext): AsyncIterable<ExternalRecord>;
|
|
6858
|
+
}
|
|
6859
|
+
/** Build an introspective connector for a specific provider (branded, pre-pointed). */
|
|
6860
|
+
declare function introspectiveConnector(spec: IntrospectiveSpec, deps?: McpConnectorDeps): IntrospectiveMcpConnector;
|
|
6861
|
+
/** The generic MCP connector — point it at any reachable MCP server (no default url). */
|
|
6862
|
+
declare function genericConnector(deps?: McpConnectorDeps): IntrospectiveMcpConnector;
|
|
6863
|
+
|
|
6864
|
+
/**
|
|
6865
|
+
* The external-database connector — a {@link CredentialConnector} that connects to
|
|
6866
|
+
* an external Postgres-family database (AWS RDS Postgres, Supabase, generic
|
|
6867
|
+
* Postgres) the user supplies via host/user/password fields (read-only by
|
|
6868
|
+
* contract — see external-pool.ts; raw connection strings are not accepted), and
|
|
6869
|
+
* IMPORTS its tables into Lattice as connected data types (so they land in the
|
|
6870
|
+
* SOURCE·INPUTS tier and sync via the shared connector sync engine).
|
|
6871
|
+
*
|
|
6872
|
+
* Unlike single-connection connectors (Jira/Trello), each external DB is its own
|
|
6873
|
+
* connection with its own table set, so the toolkit string is per-connection
|
|
6874
|
+
* (`db_source:<connectionId>`) and the dedicated `/api/db-sources` route creates a
|
|
6875
|
+
* new registry row per connection. The credentials (connection string) + the
|
|
6876
|
+
* introspected schema descriptor are persisted in the machine-local encrypted
|
|
6877
|
+
* store — never in the registry, responses, or logs.
|
|
6878
|
+
*/
|
|
6879
|
+
|
|
6880
|
+
/** Read the stored connection string for a connection, or null. */
|
|
6881
|
+
declare function getDbSourceCreds(connectionId: string): string | null;
|
|
6882
|
+
/** Persist the connection string (machine-local, encrypted). */
|
|
6883
|
+
declare function setDbSourceCreds(connectionId: string, connectionString: string): void;
|
|
6884
|
+
/** Remove the stored connection string. */
|
|
6885
|
+
declare function clearDbSourceCreds(connectionId: string): void;
|
|
6886
|
+
/**
|
|
6887
|
+
* Assemble a Postgres connection string from host + user + database (+ optional
|
|
6888
|
+
* port/password). Raw connection strings are deliberately NOT accepted: pasting a
|
|
6889
|
+
* full URL invites reusing an owner/admin connection wholesale, and the read-only
|
|
6890
|
+
* data-source contract wants the credentials entered deliberately (ideally a
|
|
6891
|
+
* read-only database user). Throws loudly when incomplete — never a silent default.
|
|
6892
|
+
*/
|
|
6893
|
+
declare function assembleConnectionString(creds: Record<string, string>): string;
|
|
6894
|
+
declare class DatabaseConnector implements CredentialConnector {
|
|
6895
|
+
private readonly credsLoader;
|
|
6896
|
+
readonly connector = "db_source";
|
|
6897
|
+
/** @param credsLoader test seam — resolve a connection id to its connection string. */
|
|
6898
|
+
constructor(credsLoader?: (connectionId: string) => string | null);
|
|
5583
6899
|
toolkits(): string[];
|
|
5584
6900
|
models(toolkit: string): ConnectedModelDef[];
|
|
5585
|
-
presentation(
|
|
6901
|
+
presentation(_toolkit: string): ToolkitPresentation;
|
|
5586
6902
|
credentialFields(): CredentialField[];
|
|
5587
|
-
helpUrl(): string;
|
|
5588
|
-
/**
|
|
5589
|
-
* Trello authenticates with a direct API key + token, not an OAuth redirect.
|
|
5590
|
-
* The GUI collects them and calls {@link connect}; these SPI methods are
|
|
5591
|
-
* therefore not part of the Trello flow and reject with a clear error.
|
|
5592
|
-
*/
|
|
6903
|
+
helpUrl(): string | undefined;
|
|
5593
6904
|
authorize(_userId: string, _toolkit: string): Promise<AuthorizeResult>;
|
|
5594
6905
|
completeAuth(_userId: string, _toolkit: string): Promise<ConnectionResult>;
|
|
5595
6906
|
/**
|
|
5596
|
-
* Validate
|
|
5597
|
-
*
|
|
5598
|
-
*
|
|
5599
|
-
*
|
|
6907
|
+
* Validate the credentials against the external DB (`SELECT 1`), introspect its
|
|
6908
|
+
* schema, and persist both the connection string + schema descriptor encrypted
|
|
6909
|
+
* under a fresh connection id. Returns the id (recorded in the registry by the
|
|
6910
|
+
* caller) and the database name as the display name.
|
|
5600
6911
|
*/
|
|
5601
6912
|
connect(creds: Record<string, string>): Promise<{
|
|
5602
6913
|
connectionId: string;
|
|
5603
6914
|
displayName: string | null;
|
|
5604
6915
|
}>;
|
|
5605
|
-
listChanges(toolkit: string, model: string, ctx: ListChangesContext): AsyncIterable<ExternalRecord>;
|
|
5606
|
-
disconnect(connectionId: string): Promise<void>;
|
|
5607
6916
|
/**
|
|
5608
|
-
*
|
|
5609
|
-
*
|
|
5610
|
-
*
|
|
6917
|
+
* Re-authenticate an EXISTING connection with edited credentials (e.g. a rotated
|
|
6918
|
+
* password or a corrected host/port). Unlike {@link connect}, this reuses the
|
|
6919
|
+
* connection id AND the descriptor's original table prefix, so the imported
|
|
6920
|
+
* tables keep their physical names and rows upsert idempotently onto the same
|
|
6921
|
+
* objects — an edit re-points the same database, it does not fork a new table
|
|
6922
|
+
* set. Validates against the DB, re-introspects (picking up any newly-added
|
|
6923
|
+
* tables), and overwrites the stored connection string + schema descriptor.
|
|
5611
6924
|
*/
|
|
5612
|
-
|
|
6925
|
+
reconnect(connectionId: string, creds: Record<string, string>): Promise<{
|
|
6926
|
+
connectionId: string;
|
|
6927
|
+
displayName: string | null;
|
|
6928
|
+
}>;
|
|
6929
|
+
listChanges(toolkit: string, model: string, ctx: ListChangesContext): AsyncIterable<ExternalRecord>;
|
|
6930
|
+
disconnect(connectionId: string): Promise<void>;
|
|
5613
6931
|
}
|
|
5614
6932
|
|
|
5615
6933
|
/**
|
|
5616
|
-
*
|
|
5617
|
-
*
|
|
5618
|
-
*
|
|
5619
|
-
*
|
|
5620
|
-
*
|
|
5621
|
-
* fetch/map logic lives in the connector ({@link TrelloConnector}), which calls
|
|
5622
|
-
* the Trello REST API directly over the Node global `fetch` — there is no broker
|
|
5623
|
-
* and no SDK dependency.
|
|
6934
|
+
* SQL dialects for the external-database connector. A dialect knows how to (a)
|
|
6935
|
+
* introspect a schema (tables → columns → primary keys), (b) map a native column
|
|
6936
|
+
* type to a Lattice column spec, and (c) build a bounded page query. v5.0 ships
|
|
6937
|
+
* Postgres-family support only; the interface is structured so MySQL/Snowflake can
|
|
6938
|
+
* slot in later without touching the connector.
|
|
5624
6939
|
*
|
|
5625
|
-
*
|
|
5626
|
-
*
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
6940
|
+
* All introspection/page SQL is parameterized or built from identifiers this
|
|
6941
|
+
* module quotes — never string-interpolated user values.
|
|
6942
|
+
*/
|
|
6943
|
+
/** A SQL fragment plus its bound parameters (Postgres `$1` placeholders). */
|
|
6944
|
+
interface SqlQuery {
|
|
6945
|
+
sql: string;
|
|
6946
|
+
params: unknown[];
|
|
6947
|
+
}
|
|
6948
|
+
/** Options for a bounded page over one external table. */
|
|
6949
|
+
interface PageOpts {
|
|
6950
|
+
schema: string;
|
|
6951
|
+
table: string;
|
|
6952
|
+
/** Explicitly projected columns (never `SELECT *` — bounded reads). */
|
|
6953
|
+
columns: string[];
|
|
6954
|
+
/** Single-column key to keyset-paginate on, or null to offset-paginate. */
|
|
6955
|
+
keyCol: string | null;
|
|
6956
|
+
/** Last key value seen (keyset only); undefined for the first page. */
|
|
6957
|
+
afterKey?: unknown;
|
|
6958
|
+
/** Row offset (offset pagination only). */
|
|
6959
|
+
offset: number;
|
|
6960
|
+
/** Page size. */
|
|
6961
|
+
limit: number;
|
|
6962
|
+
}
|
|
6963
|
+
interface SqlDialect {
|
|
6964
|
+
readonly id: 'postgres';
|
|
6965
|
+
/** True when this dialect handles the given connection string. */
|
|
6966
|
+
detect(connectionString: string): boolean;
|
|
6967
|
+
/** Quote an identifier (table/column/schema) for this dialect. */
|
|
6968
|
+
quoteIdent(id: string): string;
|
|
6969
|
+
/** List base tables in a schema → rows `{ name }`. */
|
|
6970
|
+
tablesSql(schema: string): SqlQuery;
|
|
6971
|
+
/** All columns for a schema → rows `{ table, name, type }` (ordinal order). */
|
|
6972
|
+
columnsSql(schema: string): SqlQuery;
|
|
6973
|
+
/** Primary-key columns for a schema → rows `{ table, col }` (key order). */
|
|
6974
|
+
primaryKeysSql(schema: string): SqlQuery;
|
|
6975
|
+
/**
|
|
6976
|
+
* FOREIGN KEY columns for a schema → rows `{ cname, table, col, ref_table,
|
|
6977
|
+
* ref_col }`. May emit multiple rows per composite constraint — the caller
|
|
6978
|
+
* groups by `cname` and keeps single-column FKs only (those are the ones that
|
|
6979
|
+
* map cleanly onto graph edges).
|
|
6980
|
+
*/
|
|
6981
|
+
foreignKeysSql(schema: string): SqlQuery;
|
|
6982
|
+
/** Map a native column type to a Lattice column SQL spec (TEXT | INTEGER | REAL). */
|
|
6983
|
+
mapType(nativeType: string): 'TEXT' | 'INTEGER' | 'REAL';
|
|
6984
|
+
/** Build a bounded page query (keyset when keyCol set, else offset). */
|
|
6985
|
+
pageSql(opts: PageOpts): SqlQuery;
|
|
6986
|
+
}
|
|
6987
|
+
/** Postgres-family dialect (AWS RDS Postgres, Supabase, generic Postgres). */
|
|
6988
|
+
declare const PostgresDialect: SqlDialect;
|
|
6989
|
+
/**
|
|
6990
|
+
* Resolve the dialect for a connection string. v5.0 supports Postgres-family
|
|
6991
|
+
* only; a non-Postgres URL throws a clear, actionable error — never a silent
|
|
6992
|
+
* fallback.
|
|
6993
|
+
*/
|
|
6994
|
+
declare function dialectFor(connectionString: string): SqlDialect;
|
|
6995
|
+
|
|
6996
|
+
/**
|
|
6997
|
+
* Persisted + memoized schema descriptor for one external-DB connection. The
|
|
6998
|
+
* connector's `models()` is SYNCHRONOUS (the SPI + sync engine call it inline),
|
|
6999
|
+
* but introspecting an external DB is async — so introspection happens in the
|
|
7000
|
+
* async `connect()`/refresh paths, persists the descriptor in the machine-local
|
|
7001
|
+
* encrypted store (alongside the credentials), and `models()` reads it back
|
|
7002
|
+
* synchronously here. No schema migration: this rides the existing encrypted
|
|
7003
|
+
* credential store, not the registry table.
|
|
5632
7004
|
*/
|
|
5633
7005
|
|
|
5634
|
-
|
|
5635
|
-
|
|
7006
|
+
interface DbColumnDesc {
|
|
7007
|
+
/** External column name. */
|
|
7008
|
+
name: string;
|
|
7009
|
+
/** Mapped Lattice column spec. */
|
|
7010
|
+
sqlSpec: 'TEXT' | 'INTEGER' | 'REAL';
|
|
7011
|
+
}
|
|
7012
|
+
interface DbTableDesc {
|
|
7013
|
+
/** External table name within the source schema. */
|
|
7014
|
+
name: string;
|
|
7015
|
+
columns: DbColumnDesc[];
|
|
7016
|
+
/** Primary-key columns in key order (may be empty for a keyless table). */
|
|
7017
|
+
pk: string[];
|
|
7018
|
+
/** Whether this table is imported (table-level selection). */
|
|
7019
|
+
selected: boolean;
|
|
7020
|
+
/**
|
|
7021
|
+
* Single-column FOREIGN KEYs introspected from the remote (composite FKs are
|
|
7022
|
+
* dropped at introspection time). Materialized as graph edges between the
|
|
7023
|
+
* imported tables so a connected database's relational structure carries over.
|
|
7024
|
+
* Optional — descriptors persisted before FK introspection existed lack it.
|
|
7025
|
+
*/
|
|
7026
|
+
fks?: {
|
|
7027
|
+
column: string;
|
|
7028
|
+
refTable: string;
|
|
7029
|
+
refColumn: string;
|
|
7030
|
+
}[];
|
|
7031
|
+
}
|
|
7032
|
+
interface DbSchemaDescriptor {
|
|
7033
|
+
dialect: string;
|
|
7034
|
+
/** Source schema (e.g. `public`). */
|
|
7035
|
+
schema: string;
|
|
7036
|
+
/** Sanitized slug namespacing the imported Lattice tables (from the display name). */
|
|
7037
|
+
prefix: string;
|
|
7038
|
+
tables: DbTableDesc[];
|
|
7039
|
+
}
|
|
7040
|
+
declare function getSchemaDescriptor(connectionId: string): DbSchemaDescriptor | null;
|
|
7041
|
+
declare function setSchemaDescriptor(connectionId: string, descriptor: DbSchemaDescriptor): void;
|
|
7042
|
+
declare function clearSchemaDescriptor(connectionId: string): void;
|
|
7043
|
+
/** Lowercase, non-alphanumeric→underscore slug, bounded; never empty. */
|
|
7044
|
+
declare function slugify(name: string): string;
|
|
7045
|
+
/** The imported Lattice table name for an external table (namespaced by prefix). */
|
|
7046
|
+
declare function latticeTableName(prefix: string, externalTable: string): string;
|
|
5636
7047
|
/**
|
|
5637
|
-
*
|
|
5638
|
-
*
|
|
5639
|
-
*
|
|
7048
|
+
* Build the Lattice {@link ConnectedModelDef}s for the selected tables. Pure +
|
|
7049
|
+
* synchronous so `models()` can return immediately. Each table maps to a Lattice
|
|
7050
|
+
* table carrying the standard lifecycle/lineage columns + the external columns,
|
|
7051
|
+
* with a `source` descriptor (so the row stamps land it in the SOURCE·INPUTS tier).
|
|
5640
7052
|
*/
|
|
5641
|
-
declare function
|
|
7053
|
+
declare function buildModelDefs(connectionId: string, descriptor: DbSchemaDescriptor): ConnectedModelDef[];
|
|
5642
7054
|
|
|
5643
7055
|
/**
|
|
5644
7056
|
* Connector sync engine.
|
|
@@ -5774,6 +7186,21 @@ declare function enableConnectorRls(db: Lattice, connector: Connector, toolkit:
|
|
|
5774
7186
|
*/
|
|
5775
7187
|
declare function secureConnectorTables(db: Lattice, connector: Connector): Promise<void>;
|
|
5776
7188
|
|
|
7189
|
+
/**
|
|
7190
|
+
* A compact summary of the workspace's connected external sources for the
|
|
7191
|
+
* assistant's context, so it can answer "are you connected to X?" and knows
|
|
7192
|
+
* which table holds each source's data. Returns '' when nothing is connected.
|
|
7193
|
+
*
|
|
7194
|
+
* On a CLOUD (Postgres) workspace this is scoped by `connectedBy` so a member
|
|
7195
|
+
* never sees another member's connections. On a LOCAL (SQLite) single-user
|
|
7196
|
+
* workspace the `connected_by` stamp is meaningless and can drift when the
|
|
7197
|
+
* user's saved identity changes (a connector stamped with an old email would
|
|
7198
|
+
* then be invisible), so every connection is listed — matching how the sidebar
|
|
7199
|
+
* re-registers connector tables locally. This is the same trust boundary: a
|
|
7200
|
+
* local workspace is one user's own machine.
|
|
7201
|
+
*/
|
|
7202
|
+
declare function describeConnectedSources(db: Lattice, connectedBy: string): Promise<string>;
|
|
7203
|
+
|
|
5777
7204
|
/**
|
|
5778
7205
|
* Durable retry for transient database failures.
|
|
5779
7206
|
*
|
|
@@ -6134,6 +7561,11 @@ interface UserIdentity {
|
|
|
6134
7561
|
* Read the machine-local user identity. Returns `{display_name: '',
|
|
6135
7562
|
* email: ''}` if the file is missing or malformed — callers can treat
|
|
6136
7563
|
* empty fields as "not set yet" without a separate existence check.
|
|
7564
|
+
*
|
|
7565
|
+
* In a managed/hosted deployment there is no local identity file, so a stored
|
|
7566
|
+
* field falls back to the `LATTICE_USER_NAME` / `LATTICE_USER_EMAIL` env vars
|
|
7567
|
+
* (which the host injects per session). Env is only a fallback — a value written
|
|
7568
|
+
* to the identity file always wins, preserving the "empty = not set" contract.
|
|
6137
7569
|
*/
|
|
6138
7570
|
declare function readIdentity(): UserIdentity;
|
|
6139
7571
|
/**
|
|
@@ -6169,6 +7601,15 @@ interface UserPreferences {
|
|
|
6169
7601
|
* A user preference, machine-local (see `voice_provider`).
|
|
6170
7602
|
*/
|
|
6171
7603
|
aggressiveness: number;
|
|
7604
|
+
/**
|
|
7605
|
+
* Clarify threshold (0..1) — the single confidence bar that decides when an
|
|
7606
|
+
* automated inference asks the user instead of guessing. At or above the
|
|
7607
|
+
* threshold the system acts silently; between the floor (threshold / 2,
|
|
7608
|
+
* derived where consumed) and the threshold it asks a short multiple-choice
|
|
7609
|
+
* question; below the floor it drops the inference as noise. A user
|
|
7610
|
+
* preference, machine-local (see `voice_provider`).
|
|
7611
|
+
*/
|
|
7612
|
+
clarify_threshold: number;
|
|
6172
7613
|
}
|
|
6173
7614
|
/**
|
|
6174
7615
|
* Read machine-local user preferences. Returns defaults if the file is
|
|
@@ -6628,14 +8069,14 @@ declare function hasVectorIndex(adapter: StorageAdapter, table: string): Promise
|
|
|
6628
8069
|
* true — surfacing a misconfiguration loudly rather than silently doing
|
|
6629
8070
|
* nothing. By default it is a reported no-op (returns 0).
|
|
6630
8071
|
*/
|
|
6631
|
-
declare function buildVectorIndex(adapter: StorageAdapter, table: string, dim: number, requireExtension?: boolean): Promise<number>;
|
|
6632
|
-
/** Drop a table's native vector index. */
|
|
8072
|
+
declare function buildVectorIndex(adapter: StorageAdapter, table: string, dim: number, requireExtension?: boolean, opts?: VectorIndexOptions): Promise<number>;
|
|
8073
|
+
/** Drop a table's native vector index (and its registry row). */
|
|
6633
8074
|
declare function dropVectorIndex(adapter: StorageAdapter, table: string): Promise<void>;
|
|
6634
8075
|
/**
|
|
6635
8076
|
* Query the native vector index for the nearest chunks to `queryVector`.
|
|
6636
8077
|
* Returns up to `limit` hits with cosine similarity scores ≥ `minScore`.
|
|
6637
8078
|
*/
|
|
6638
|
-
declare function searchVectorIndex(adapter: StorageAdapter, table: string, queryVector: number[], limit: number, minScore: number): Promise<VectorHit[]>;
|
|
8079
|
+
declare function searchVectorIndex(adapter: StorageAdapter, table: string, queryVector: number[], limit: number, minScore: number, efSearch?: number): Promise<VectorHit[]>;
|
|
6639
8080
|
|
|
6640
8081
|
/**
|
|
6641
8082
|
* Reference-ingestion API — parallel to {@link attachBlob}, but records a row
|
|
@@ -6907,6 +8348,16 @@ declare function memberRoleName(label: string): string;
|
|
|
6907
8348
|
* `postgres://<role>:<password>@<host>/<db>` and sees only its permitted rows.
|
|
6908
8349
|
*/
|
|
6909
8350
|
declare function provisionMemberRole(db: Lattice, role: string, password: string): Promise<void>;
|
|
8351
|
+
/**
|
|
8352
|
+
* Idempotently grant an EXISTING scoped login role membership in the cloud's
|
|
8353
|
+
* member group. The group holds every table/schema/connect grant and RLS keys on
|
|
8354
|
+
* `session_user`, so the role gets exactly an invited member's access while
|
|
8355
|
+
* staying RLS-confined to its own rows. Use this to adopt a role created out of
|
|
8356
|
+
* band (e.g. by an external provisioner) without rotating its password or
|
|
8357
|
+
* re-running CREATE/ALTER ROLE. The member group must already exist (it is created
|
|
8358
|
+
* when the owner first opens/secures the cloud).
|
|
8359
|
+
*/
|
|
8360
|
+
declare function grantMemberAccess(db: Lattice, role: string): Promise<void>;
|
|
6910
8361
|
/**
|
|
6911
8362
|
* Change a row's sharing through the owner-only `lattice_set_row_visibility`
|
|
6912
8363
|
* SECURITY DEFINER function. Only the row's owner (Postgres raises for anyone
|
|
@@ -7254,6 +8705,9 @@ interface ClaudeAuth {
|
|
|
7254
8705
|
apiKey?: string | undefined;
|
|
7255
8706
|
authToken?: string | undefined;
|
|
7256
8707
|
betaHeader?: string | undefined;
|
|
8708
|
+
/** Override the Anthropic API host (the SDK's `baseURL`). Needed for a BYO custom-host key
|
|
8709
|
+
* or a proxy; when unset the SDK reads `process.env.ANTHROPIC_BASE_URL` or the default host. */
|
|
8710
|
+
baseURL?: string | undefined;
|
|
7257
8711
|
}
|
|
7258
8712
|
|
|
7259
8713
|
/** Generate a 1-2 sentence description of a document's text. */
|
|
@@ -7291,6 +8745,20 @@ interface ExtractedObject {
|
|
|
7291
8745
|
values: Record<string, string>;
|
|
7292
8746
|
/** Short human label for the object. */
|
|
7293
8747
|
label: string;
|
|
8748
|
+
/**
|
|
8749
|
+
* The model's 0-1 confidence in its target-entity decision (that {@link entity}
|
|
8750
|
+
* is where these records belong / that a new entity is warranted). Optional:
|
|
8751
|
+
* a model that omits it is treated by consumers as fully confident (1.0), so
|
|
8752
|
+
* pre-confidence outputs behave exactly as before.
|
|
8753
|
+
*/
|
|
8754
|
+
confidence?: number;
|
|
8755
|
+
/**
|
|
8756
|
+
* Labels of the OTHER extracted objects in the same document this object is
|
|
8757
|
+
* related to — e.g. a meeting lists its attendees' labels. Consumers materialize
|
|
8758
|
+
* these as record-to-record links (so a meeting links to its people, not just to
|
|
8759
|
+
* the source). Optional: absent/empty → no cross-object links.
|
|
8760
|
+
*/
|
|
8761
|
+
links?: string[];
|
|
7294
8762
|
}
|
|
7295
8763
|
/** Parse + sanitize the extractor's JSON. Caps at 3 objects; drops invalid ones. */
|
|
7296
8764
|
declare function parseObjects(raw: string): ExtractedObject[];
|
|
@@ -7471,6 +8939,9 @@ interface VisionOptions {
|
|
|
7471
8939
|
prompt?: string;
|
|
7472
8940
|
/** Cap on the normalized JPEG size (bytes). Default ~1.4 MB. */
|
|
7473
8941
|
maxBytes?: number;
|
|
8942
|
+
/** The image's original media type (e.g. `image/png`). Used for the sharp-free fallback when
|
|
8943
|
+
* native normalization is unavailable — we send the raw bytes with this exact media type. */
|
|
8944
|
+
mediaType?: string;
|
|
7474
8945
|
/** Injectable model call (test seam). Defaults to a real Anthropic vision call. */
|
|
7475
8946
|
sender?: (input: VisionSenderInput) => Promise<string>;
|
|
7476
8947
|
}
|
|
@@ -7495,8 +8966,14 @@ interface PdfOptions {
|
|
|
7495
8966
|
*/
|
|
7496
8967
|
declare function describePdf(auth: ClaudeAuth, path: string, opts?: PdfOptions): Promise<string>;
|
|
7497
8968
|
|
|
7498
|
-
/**
|
|
7499
|
-
|
|
8969
|
+
/**
|
|
8970
|
+
* How the running copy of the package was installed. `desktop` is the bundled
|
|
8971
|
+
* desktop app (a compiled binary, not an npm install): it is never
|
|
8972
|
+
* `installable` via npm, but it CAN update itself through its own bundled
|
|
8973
|
+
* updater, so the GUI surfaces a "restart to update" action for it rather than
|
|
8974
|
+
* the npm "upgrade in place" action.
|
|
8975
|
+
*/
|
|
8976
|
+
type InstallKind = 'global' | 'local' | 'npx' | 'linked-dev' | 'unknown' | 'desktop';
|
|
7500
8977
|
interface InstallContext {
|
|
7501
8978
|
kind: InstallKind;
|
|
7502
8979
|
/** True only when an `npm install` may safely upgrade this copy in place. */
|
|
@@ -7514,6 +8991,19 @@ interface UpdateStatus {
|
|
|
7514
8991
|
latest: string | null;
|
|
7515
8992
|
kind: InstallContext['kind'];
|
|
7516
8993
|
installable: boolean;
|
|
8994
|
+
/** Master switch — false when auto-update is disabled for this server. */
|
|
8995
|
+
autoUpdate: boolean;
|
|
8996
|
+
/**
|
|
8997
|
+
* What the user can DO about an available update on THIS surface:
|
|
8998
|
+
* - `upgrade-in-place`: an npm install can upgrade this copy now (the GUI's
|
|
8999
|
+
* manual "Upgrade" fallback to the background poll).
|
|
9000
|
+
* - `restart-to-update`: a newer version exists and the bundled desktop
|
|
9001
|
+
* updater can apply it on relaunch ("Restart to update").
|
|
9002
|
+
* - `none`: nothing to offer — already current, auto-update disabled, or a
|
|
9003
|
+
* surface that can't self-update (a dev/linked checkout, where `latest` is
|
|
9004
|
+
* still reported for information but there is no apply action).
|
|
9005
|
+
*/
|
|
9006
|
+
action: 'upgrade-in-place' | 'restart-to-update' | 'none';
|
|
7517
9007
|
checking: boolean;
|
|
7518
9008
|
installing: boolean;
|
|
7519
9009
|
lastError: string | null;
|
|
@@ -7526,6 +9016,80 @@ interface UpdateService {
|
|
|
7526
9016
|
checkNow(force?: boolean): Promise<UpdateStatus>;
|
|
7527
9017
|
}
|
|
7528
9018
|
|
|
9019
|
+
/**
|
|
9020
|
+
* Server-Sent Events protocol shared by the assistant chat stream and the
|
|
9021
|
+
* activity feed. The server writes `data: <json>\n\n` frames; the browser
|
|
9022
|
+
* reads them with a `fetch` ReadableStream reader. Both ends agree on the
|
|
9023
|
+
* event shapes defined here so neither side has to guess.
|
|
9024
|
+
*/
|
|
9025
|
+
/** Events emitted while streaming one assistant turn (with tool calls). */
|
|
9026
|
+
type ChatStreamEvent = {
|
|
9027
|
+
type: 'assistant_message_start';
|
|
9028
|
+
id: string;
|
|
9029
|
+
} | {
|
|
9030
|
+
type: 'text_delta';
|
|
9031
|
+
delta: string;
|
|
9032
|
+
} | {
|
|
9033
|
+
type: 'tool_use';
|
|
9034
|
+
id: string;
|
|
9035
|
+
name: string;
|
|
9036
|
+
} | {
|
|
9037
|
+
type: 'tool_result';
|
|
9038
|
+
toolUseId: string;
|
|
9039
|
+
isError: boolean;
|
|
9040
|
+
} | {
|
|
9041
|
+
type: 'open';
|
|
9042
|
+
table: string;
|
|
9043
|
+
id: string;
|
|
9044
|
+
} | {
|
|
9045
|
+
type: 'question';
|
|
9046
|
+
question: string;
|
|
9047
|
+
options: string[];
|
|
9048
|
+
allowOther: boolean;
|
|
9049
|
+
} | {
|
|
9050
|
+
type: 'assistant_message_end';
|
|
9051
|
+
hadTools?: boolean;
|
|
9052
|
+
} | {
|
|
9053
|
+
type: 'ack';
|
|
9054
|
+
message: string;
|
|
9055
|
+
} | {
|
|
9056
|
+
type: 'done';
|
|
9057
|
+
} | {
|
|
9058
|
+
type: 'warn';
|
|
9059
|
+
message: string;
|
|
9060
|
+
} | {
|
|
9061
|
+
type: 'limit';
|
|
9062
|
+
message: string;
|
|
9063
|
+
resetAt?: string;
|
|
9064
|
+
} | {
|
|
9065
|
+
type: 'error';
|
|
9066
|
+
message: string;
|
|
9067
|
+
};
|
|
9068
|
+
|
|
9069
|
+
/**
|
|
9070
|
+
* In-process bus that streams ONE chat turn's progress to the GUI over the
|
|
9071
|
+
* multiplexed `/api/stream` WebSocket — the async replacement for the held-open
|
|
9072
|
+
* `POST /api/chat` SSE response. Modeled on {@link RenderProgressBus} / `FeedBus`,
|
|
9073
|
+
* but deliberately with NO `latest()` / replay buffer: a reconnecting client recovers
|
|
9074
|
+
* from the server-authoritative persisted `chat_messages` (checkpointed as the turn
|
|
9075
|
+
* streams), so replaying stale ticks to a fresh socket would only cause double-render.
|
|
9076
|
+
*
|
|
9077
|
+
* Every envelope carries the turn's `ownerUserId` so the `/api/stream` forwarder can
|
|
9078
|
+
* gate delivery PER USER — on a cloud workspace a chat is private to its author, and
|
|
9079
|
+
* this bus is per-process (shared across every connected socket), so the gate is
|
|
9080
|
+
* load-bearing, not decorative (see `chat-identity` / Stage 5).
|
|
9081
|
+
*/
|
|
9082
|
+
interface ChatProgressEnvelope {
|
|
9083
|
+
/** The thread the turn belongs to. */
|
|
9084
|
+
threadId: string;
|
|
9085
|
+
/** The pending assistant message id — the client filters live events by (thread, message). */
|
|
9086
|
+
messageId: string;
|
|
9087
|
+
/** Cloud user id of the turn's owner; null on a local (single-user) workspace. */
|
|
9088
|
+
ownerUserId: string | null;
|
|
9089
|
+
/** The streamed chat event (same union the old SSE response wrote). */
|
|
9090
|
+
event: ChatStreamEvent;
|
|
9091
|
+
}
|
|
9092
|
+
|
|
7529
9093
|
interface StartGuiServerOptions {
|
|
7530
9094
|
/**
|
|
7531
9095
|
* Active workspace config to open. NULL/empty ⇒ boot into the zero-workspace
|
|
@@ -7584,12 +9148,23 @@ interface StartGuiServerOptions {
|
|
|
7584
9148
|
*/
|
|
7585
9149
|
realtimeWatchdogMs?: number;
|
|
7586
9150
|
/**
|
|
7587
|
-
*
|
|
9151
|
+
* Master switch for ALL auto-update behavior (default true). When false: the
|
|
9152
|
+
* in-process poll never runs (no registry/manifest fetch, no install, no
|
|
9153
|
+
* relaunch), `/api/update/status` reports `autoUpdate:false` / `action:'none'`,
|
|
9154
|
+
* and the desktop/CLI callers skip their own updaters too. Provided so the GUI
|
|
9155
|
+
* can be run pinned to its current version (testing, air-gapped, reproducible
|
|
9156
|
+
* demos). `GET /api/version` + `GET /api/update/status` still answer.
|
|
9157
|
+
*/
|
|
9158
|
+
autoUpdate?: boolean;
|
|
9159
|
+
/**
|
|
9160
|
+
* Run the in-process auto-update poll: while the GUI is open, check for a
|
|
7588
9161
|
* newer version and, when one lands on an installable copy, install it and
|
|
7589
9162
|
* exit with the supervisor's restart code so it relaunches on the new version.
|
|
7590
9163
|
* Set ONLY for a supervised child (`LATTICE_GUI_SUPERVISED=1`) — exiting to
|
|
7591
|
-
* apply an update is safe only when a supervisor is there to respawn it.
|
|
7592
|
-
*
|
|
9164
|
+
* apply an update is safe only when a supervisor is there to respawn it. This
|
|
9165
|
+
* is the npm install-and-relaunch SUB-behavior; it is forced off when
|
|
9166
|
+
* `autoUpdate` is false. `GET /api/version` + `GET /api/update/status` are
|
|
9167
|
+
* served regardless.
|
|
7593
9168
|
*/
|
|
7594
9169
|
selfUpdate?: boolean;
|
|
7595
9170
|
/**
|
|
@@ -7599,6 +9174,29 @@ interface StartGuiServerOptions {
|
|
|
7599
9174
|
* it overrides `selfUpdate`'s default factory.
|
|
7600
9175
|
*/
|
|
7601
9176
|
updateServiceFactory?: (emit: (type: string, data: unknown) => void) => UpdateService;
|
|
9177
|
+
/**
|
|
9178
|
+
* Override the "is a newer version available?" probe. The desktop shell passes
|
|
9179
|
+
* a function that reads its release manifest (latest.json) — the same source
|
|
9180
|
+
* its bundled updater applies from — so the GUI surfaces a "restart to update"
|
|
9181
|
+
* hint without coupling the desktop to the npm registry. Omitted ⇒ the default
|
|
9182
|
+
* npm-registry check (web/CLI).
|
|
9183
|
+
*/
|
|
9184
|
+
updateCheck?: (force: boolean) => Promise<string | null>;
|
|
9185
|
+
/**
|
|
9186
|
+
* Override the detected install context for the update service. The desktop
|
|
9187
|
+
* shell passes `{ kind:'desktop', installable:false, … }` so the status route
|
|
9188
|
+
* reports the desktop surface (→ `action:'restart-to-update'`) rather than
|
|
9189
|
+
* "unknown / not installable".
|
|
9190
|
+
*/
|
|
9191
|
+
updateContext?: InstallContext;
|
|
9192
|
+
/**
|
|
9193
|
+
* Desktop shell only: apply a pending update via the bundled binary updater
|
|
9194
|
+
* (download + relaunch). Wired to `POST /api/update/apply` when the surface is
|
|
9195
|
+
* the desktop app, so the "Restart to update" pill triggers the real updater
|
|
9196
|
+
* instead of the npm install path (which the desktop can't use). Omitted ⇒ the
|
|
9197
|
+
* apply route uses the npm path / reports "not available".
|
|
9198
|
+
*/
|
|
9199
|
+
desktopApplyUpdate?: () => void;
|
|
7602
9200
|
/**
|
|
7603
9201
|
* Desktop shell only: open an external URL in the OS default browser. The
|
|
7604
9202
|
* embedded desktop webview has no tabs, so `target="_blank"` links are routed
|
|
@@ -7622,6 +9220,12 @@ interface GuiServerHandle {
|
|
|
7622
9220
|
* resolves immediately for a non-cloud / virgin workspace.
|
|
7623
9221
|
*/
|
|
7624
9222
|
whenConverged: () => Promise<void>;
|
|
9223
|
+
/**
|
|
9224
|
+
* TEST-ONLY: publish a chat-progress envelope directly into the active workspace's bus so
|
|
9225
|
+
* the per-user `/api/stream` delivery gate can be exercised without a live model turn.
|
|
9226
|
+
* Never invoked in production.
|
|
9227
|
+
*/
|
|
9228
|
+
publishChatProgressForTest: (env: ChatProgressEnvelope) => void;
|
|
7625
9229
|
}
|
|
7626
9230
|
declare function startGuiServer(options: StartGuiServerOptions): Promise<GuiServerHandle>;
|
|
7627
9231
|
|
|
@@ -7760,6 +9364,14 @@ interface ProposedSchema {
|
|
|
7760
9364
|
entities: InferredEntity[];
|
|
7761
9365
|
dimensions: InferredDimension[];
|
|
7762
9366
|
linkages: InferredLinkage[];
|
|
9367
|
+
/**
|
|
9368
|
+
* Link candidates in the marginal confidence band — at or above the "drop as
|
|
9369
|
+
* noise" floor but below the creation threshold (see `InferOptions.
|
|
9370
|
+
* minLinkConfidence`). NOT materialized: the referencing column survives as a
|
|
9371
|
+
* plain scalar column, and the importer asks the user whether to connect it
|
|
9372
|
+
* instead of guessing. Same shape as {@link linkages}, confidence included.
|
|
9373
|
+
*/
|
|
9374
|
+
marginalLinks: InferredLinkage[];
|
|
7763
9375
|
/** Top-level keys not imported (derived rollups, meta, scalars, column dictionaries). */
|
|
7764
9376
|
skipped: {
|
|
7765
9377
|
key: string;
|
|
@@ -7801,6 +9413,16 @@ declare function inferFieldType(values: unknown[]): InferredType;
|
|
|
7801
9413
|
interface InferOptions {
|
|
7802
9414
|
/** Override the inferred entity → table name (sourceKey → name). */
|
|
7803
9415
|
rename?: Record<string, string>;
|
|
9416
|
+
/**
|
|
9417
|
+
* Confidence bar for creating a linkage (0..1, clamped). At or above it a
|
|
9418
|
+
* link is inferred as usual; in `[minLinkConfidence / 2, minLinkConfidence)`
|
|
9419
|
+
* the candidate is returned on {@link ProposedSchema.marginalLinks} instead
|
|
9420
|
+
* of being created (the referencing column stays a plain scalar column so a
|
|
9421
|
+
* later confirmation can still connect it); below the floor it is dropped as
|
|
9422
|
+
* noise. Dimension links (confidence 1) are unaffected. Defaults to
|
|
9423
|
+
* {@link DEFAULT_LINK_CONFIDENCE}.
|
|
9424
|
+
*/
|
|
9425
|
+
minLinkConfidence?: number;
|
|
7804
9426
|
}
|
|
7805
9427
|
declare function inferSchema(data: Record<string, unknown>, opts?: InferOptions): ProposedSchema;
|
|
7806
9428
|
|
|
@@ -8016,4 +9638,4 @@ declare function dedupeAndDetectViews(plan: ProposedSchema, data: Record<string,
|
|
|
8016
9638
|
views: DetectedView[];
|
|
8017
9639
|
};
|
|
8018
9640
|
|
|
8019
|
-
export { ALL_PROVENANCE_FIELDS, type AddWorkspaceOptions, type AdoptNativeOptions, type AdoptResult, type AggregateFunction, type AggregateHaving, type AggregateOptions, type AggregateResult, type AggregateSpec, type ApplyWriteResult, type AsOfCandidate, type AsOfColumnCandidate, type AsOfInputs, type AudienceRowCtx, type AuditEvent, type AuthorizeResult, type AutoUpdateResult, type BacklinkSignal, type BelongsToRelation, type BelongsToSource, type BenchmarkOptions, type BenchmarkReport, type BenchmarkScale, type BlobMetadata, BoundedReadError, type BuiltinTemplateName, CLOUD_SETTING_SYSTEM_PROMPT, CLOUD_SETTING_WORKSPACE_LOGO, CLOUD_SETTING_WORKSPACE_LOGO_ETAG, CONFIG_SUBDIR, CONNECTED_COLUMNS, CONNECTORS_TABLE, type CatalogEntity, type CatalogRecord, type ChangeEntry, type ChangelogOptions, type ChunkedMigrationOptions, type ChunkedMigrationResult, type ChunkerFn, type ClassifyMatch, type CleanupOptions, type CleanupResult, type CloudProbeResult, type CloudS3Secret, ComputedColumnCycleError, type ComputedColumnSpec, type ConnectedEdgeSpec, type ConnectedModelDef, ConnectedSourceImmutableError, type ConnectedVisibility, type ConnectionResult, type Connector, type ConnectorRecord, type ConnectorSource, type ConnectorStatus, ConnectorUnavailableError, type CountOptions, type CrawlOptions, type CrawlResult, type CreateConnectorInput, type CredentialConnector, type CredentialField, type CustomSignal, type CustomSource, DEFAULT_ENTRY_TYPES, DEFAULT_MAX_NODES, DEFAULT_STALE_MS, DEFAULT_TYPE_ALIASES, DenoSqliteAdapter, type DetectedView, type DiagnoseOptions, type DisconnectOptions, type DisconnectResult, type DiscoveredTable, EMBEDDINGS_TABLE, EmbeddingDimensionMismatchError, type EmbeddingRefreshResult, EmbeddingScanTooLargeError, type EmbeddingsConfig, type EnrichOptions, type EnrichResult, type EnrichedSource, type EnrichmentLookup, type EntityContextDefinition, type EntityContextManifestEntry, type EntityFileManifestInfo, type EntityFileSource, type EntityFileSpec, type EntityMatch, type EntityProfileField, type EntityProfileSection, type EntityProfileTemplate, type EntityRenderSpec, type EntityRenderTemplate, type EntitySectionPerRow, type EntitySectionsTemplate, type EntityTableColumn, type EntityTableTemplate, type EvalQuery, type EvalRegression, type ExistingTable, type ExtensionAvailability, type ExternalRecord, type ExtractEdgesSpec, type ExtractedObject, FileSourceKeyStore, type FileSourceKeyStoreOptions, type FilesRow, type Filter, type FilterAnd, type FilterExpr, type FilterOp, type FilterOr, FoldCache, type FtsConfig, type FtsGroup, type FtsHit, type FtsOptions, type FtsResult, type GraphBoostOptions, type GraphBoostResult, type GraphEdge, type GraphNode, type GraphTraversalResult, type GuiServerHandle, type HasManyRelation, type HasManySource, type HealthIssueKind, type HealthSeverity, type HybridScoreBreakdown, type HybridSearchOptions, type HybridSearchResult, IMMUTABLE_CONNECTED_FIELDS, type ImportMode, type ImportProgress, InMemorySourceKeyStore, InMemoryStateStore, type InferredColumn, type InferredDimension, type InferredEntity, type InferredLinkage, type InferredType, type InitOptions, JIRA_MODELS, type JiraClient, JiraConnector, type JiraCreds, LEGACY_MEMBER_GROUP, LOCAL_DB_RELPATH, type LatencyStats, Lattice, type LatticeConfig, type LatticeConfigInput, type LatticeEntityDef, type LatticeEntityRenderSpec, type LatticeFieldDef, type LatticeFieldType, type LatticeManifest, type LatticeOptions, type LinkOptions, type ListChangesContext, type LlmClient, type LlmMessage, MAX_TRAVERSAL_DEPTH, type ManyToManySource, type MarkdownTableColumn, type MaterializeCtx, type MaterializeOptions, type MaterializeResult, type MaterializedRollupSpec, type MigrateResult, type Migration, type MigrationCheckpoint, type MigrationOptions, type MigrationProgress, type MigrationResult, type MigrationStatus, type MultiTableDefinition, NATIVE_ENTITY_DEFS, NATIVE_ENTITY_NAMES, NATIVE_REGISTRY_TABLE, type Observation, type OrderBySpec, type OrganizeOptions, type OrganizeResult, type OrganizedCreation, type OrganizedLink, type ParseError, type ParseResult, type ParsedConfig, type PdfOptions, type PdfSenderInput, type PerQueryEval, type PkLookup, PostgresAdapter, type PostgresAdapterOptions, type PreparedStatement, type PrimaryKey, ProgressThrottle, type ProposedSchema, type ProvenanceConfig, type ProvenanceField, ProvenanceImmutableError, type QueryOptions, type QueryPageOptions, type QueryPageResult, type QueryProjection, READ_ONLY_HEADER, ROOT_DIRNAME, type RankingOptions, type ReadOnlyHeaderOptions, type RecencySignal, type ReconcileOptions, type ReconcileResult, type RefKind, type RefProvider, type ReferenceMetadata, ReferenceUnavailableError, type RefreshEmbeddingsOptions, type Relation, type RelevanceLabel, type RemoteBlobStore, type RenderHooks, type RenderOptions, type RenderProgress, type RenderProgressCallback, type RenderProgressKind, type RenderResult, type RenderSpec, type ReportConfig, type ReportResult, type ReportSection, type ReportSectionResult, type RerankCandidate, type RerankScore, type RerankerFn, type ResolveOptions, type RetrievalEvalOptions, type RetrievalEvalSummary, type RetrievalHealthIssue, type RetrievalHealthReport, type RetrievalHealthSpec, type RetrievalSlo, type Retriever, type RetryOptions, type ReverseSeedDetection, type ReverseSeedResult, type ReverseSeedTableResult, type ReverseSyncError, type ReverseSyncResult, type ReverseSyncUpdate, type RewardScores, type RewardSignal, type RollupFunction, type Row, type RowVisibilityDefault, type S3Config, type S3StoreConfig, S3UnavailableError, S3_SECRET_TABLE, SQLiteAdapter, type SchemaEntity, type SchemaMatch, type SearchOptions, type SearchResult, type SecurityOptions, type SeedConfig, type SeedLinkSpec, SeedReconciliationError, type SeedResult, type SelfSource, type SemanticChunkerOptions, type SessionEntry, type SessionParseOptions, type SessionWriteEntry, type SessionWriteOp, type SessionWriteParseResult, type SloViolation, type SourceHandle, type SourceKeyStore, type SourceMetadata, type SourceQueryOptions, SourceShreddedError, type StartGuiServerOptions, type StopFn, type StorageAdapter, type SyncConnectorOptions, type SyncConnectorResult, type SyncResult, TRELLO_MODELS, TRUST_COLUMNS, type TableDefinition, type TableHealth, type TablePolicy, type TemplateRenderSpec, type TextChunk, type ToolkitPresentation, type TraversalDirection, type TraversalNode, type TraversalOptions, type TrelloClient, TrelloConnector, type TrelloCreds, type TrelloPageOpts, type TrustConfig, type TrustState, type TurnParams, type TurnResult, type UnresolvedLink, type UpsertByNaturalKeyOptions, type UserIdentity, type UserPreferences, type VectorHit, type Viewer, type VisionOptions, type VisionSenderInput, WORKSPACES_SUBDIR, type WatchOptions, type WorkspacePaths, type WorkspaceRecord, type WorkspaceRegistry, type WriteHook, type WriteHookContext, type WritebackDefinition, type WritebackStateStore, type WritebackValidationResult, activeWorkspaceLabel, addEdge, addEdges, addWorkspace, adoptNativeEntities, allComputedDeps, analyticsEnabled, applyChunkedMigration, applyReranker, applyTokenBudget, applyWriteEntry, archiveLocalSqlite, assertSafeUrl, attachBlob, audiencePredicate, audienceViewSql, autoFtsColumns, autoUpdate, backfillOwnership, backlinkBoost, benchmarkRetrieval, buildVectorIndex, builtinConnectors, canManageRoles, checkSlos, chunkText, classifyLinks, clearJiraCreds, clearTrelloCreds, cloudRlsInstalled, collectConnectorKeys, computeColumns, computedColumnDdl, computedColumnOrder, concatRowText, configDir, connectedColumns, contentHash, cosineSimilarity, crawlUrl, createConnector, createReadOnlyHeader, createS3Store, createSQLiteStateStore, decrypt, dedupeAndDetectViews, defaultWorkspaceYaml, defineJiraTables, defineTrelloTables, deleteConnectorRecord, deleteDbCredential, deleteToken, deriveCanonicalContexts, deriveKey, describeImage, describePdf, detectAsOf, detectAsOfCandidates, detectAsOfColumns, detectRetrievalRegressions, diagnoseRetrieval, disconnectConnector, discoverCloudTables, dropVectorIndex, enableAudienceView, enableChangelogRls, enableConnectorRls, enableRlsForTable, encrypt, enrichKnowledge, ensureCheckpointTable, ensureConnectorRegistry, ensureEdgesTable, ensureEmbeddingsTable, ensureFtsIndex, ensureLatticeRoot, entityFileNames, estimateTokens, evaluateRetrieval, excelToRecords, extractEdgesFromColumn, extractObjects, filePresignSql, findLatticeRoot, fixSchemaConflicts, foldEntity, formatHealthReport, frontmatter, ftsTableName, fullTextSearch, generateEntryId, generateMemberPassword, generateWriteEntryId, getActiveWorkspace, getCloudSetting, getConnector, getConnectorByToolkit, getDbCredential, getJiraCreds, getMigrationCheckpoint, getOrCreateMasterKey, getTablePolicy, getTrelloCreds, getWorkspace, grantPresignerToMemberGroup, graphAdjacencyBoost, hasFilePresigner, hasFtsIndex, hasVectorIndex, hashFile, hybridSearch, importLegacyUserConfig, inferFieldType, inferSchema, installCloudRls, installCloudSettings, installFilePresigner, isCredentialConnector, isEncrypted, isNativeEntity, isPostgresUrl, isPrivateIp, isRetryableDbError, isRowAudience, latencyStats, listConnectors, listDbCredentials, listMigrationCheckpoints, listNativeBindings, listTokens, listWorkspaces, loadColumnPolicy, loadJiraClient, loadTrelloClient, manifestPath, markdownTable, matchSchemaToExisting, materializeImport, memberGroupFor, memberRoleName, migrateLatticeData, neighbors, normalizeName, observationVisible, observationsFromChange, openTargetLatticeForMigration, openUnderSource, organizeSource, parseCellDate, parseConfigFile, parseConfigString, parseMarkdownEntries, parseMatches, parseObjects, parseSessionMD, parseSessionWrites, percentile, probeCloud, provenanceColumns, providerForUrl, provisionMemberRole, rankingBoost, readIdentity, readManifest, readPreferences, readRegistry, readToken, recencyBoost, recordSync, referenceLocalFile, referenceUrl, refreshEmbeddings, regenerateAudienceViewFromDb, registerNativeEntities, registryPath, removeEdge, removeEmbedding, renameEntities, resolveActiveS3Config, resolveConnectorIdentity, resolveLatticeRoot, resolveProvenanceFields, resolveSource, resolveTrustDefault, resolveWorkspacePaths, resumeMigration, revertMigration, revokeMemberRole, rewardBoost, rollupColumnDdl, rootConfigDir, s3Key, saveDbCredential, saveDbCredentialForTeam, sealUnderSource, searchByEmbedding, searchVectorIndex, secureCloud, secureConnectorTables, seedColumnPolicyFromYaml, semanticChunker, setActiveWorkspace, setCloudS3Secret, setCloudSetting, setColumnAudience, setConnectorStatus, setJiraCreds, setRowVisibility, setTableDefaultVisibility, setTableNeverShare, setTrelloCreds, shredSource, slugify, sourceRecords, startGuiServer, storeEmbedding, summarizeText, syncConnector, syncIfStale, syncStaleConnectors, tableNeedsAudienceView, toSafeDirName, traverse, truncate, updateConnectorConnection, validateEntryId, vectorIndexAvailable, vectorIndexName, withRetry, workspaceBlobsDir, workspaceConfigPath, workspaceContextDir, workspaceDataDir, workspaceDbPath, workspaceDir, workspacesDir, writeIdentity, writeManifest, writePreferences, writeRegistry, writeToken };
|
|
9641
|
+
export { AI_CELL_TABLE, AI_MAP_TABLE, ALL_PROVENANCE_FIELDS, type AddWorkspaceOptions, type AdoptNativeOptions, type AdoptResult, type AggregateFunction, type AggregateHaving, type AggregateOptions, type AggregateResult, type AggregateSpec, type ApplyWriteResult, type AsOfCandidate, type AsOfColumnCandidate, type AsOfInputs, type AudienceRowCtx, type AuditEvent, type AuthorizeResult, type AutoUpdateResult, type BacklinkSignal, type BelongsToRelation, type BelongsToSource, type BenchmarkOptions, type BenchmarkReport, type BenchmarkScale, type BlobMetadata, type BoundedCountOptions, BoundedReadError, type BuiltinTemplateName, CLOUD_SETTING_SYSTEM_PROMPT, CLOUD_SETTING_WORKSPACE_LOGO, CLOUD_SETTING_WORKSPACE_LOGO_ETAG, COMPUTED_STATE_TABLE, CONFIG_SUBDIR, CONNECTED_COLUMNS, CONNECTORS_TABLE, type CalcEmitContext, type CalcExpr, CalcExprError, type CalcNode, type CalcRefResolver, type CatalogEntity, type CatalogRecord, type ChangeEntry, type ChangelogOptions, type ChunkedMigrationOptions, type ChunkedMigrationResult, type ChunkerFn, type ClassifyMatch, type CleanupOptions, type CleanupResult, type CloudProbeResult, type CloudS3Secret, type CompiledAiField, type CompiledComputedTable, ComputedColumnCycleError, type ComputedColumnSpec, type ComputedFieldDef, type ComputedFieldState, type ComputedFillOptions, type ComputedFillReport, type ComputedRegistrationResult, type ComputedSchema, type ComputedSchemaTable, ComputedTableCycleError, type ComputedTableDef, type ComputedTableHost, type ConnectedEdgeSpec, type ConnectedModelDef, ConnectedSourceImmutableError, type ConnectedVisibility, type ConnectionResult, type Connector, type ConnectorRecord, type ConnectorSource, type ConnectorStatus, ConnectorUnavailableError, type CountOptions, type CrawlOptions, type CrawlResult, type CreateConnectorInput, type CredentialConnector, type CredentialField, type CustomSignal, type CustomSource, DEFAULT_ENTRY_TYPES, DEFAULT_MAX_NODES, DEFAULT_STALE_MS, DEFAULT_TYPE_ALIASES, DatabaseConnector, type DbColumnDesc, type DbSchemaDescriptor, type DbTableDesc, DenoSqliteAdapter, type DetectedView, type DiagnoseOptions, type DisconnectOptions, type DisconnectResult, type DiscoveredTable, EMBEDDINGS_TABLE, EmbeddingDimensionMismatchError, type EmbeddingRefreshResult, EmbeddingScanTooLargeError, type EmbeddingsConfig, type EnrichOptions, type EnrichResult, type EnrichedSource, type EnrichmentLookup, type EntityContextDefinition, type EntityContextManifestEntry, type EntityFileManifestInfo, type EntityFileSource, type EntityFileSpec, type EntityMatch, type EntityProfileField, type EntityProfileSection, type EntityProfileTemplate, type EntityRenderSpec, type EntityRenderTemplate, type EntitySectionPerRow, type EntitySectionsTemplate, type EntityTableColumn, type EntityTableTemplate, type EvalQuery, type EvalRegression, type ExistingTable, type ExtensionAvailability, type ExternalRecord, type ExtractEdgesSpec, type ExtractedObject, type FieldFillResult, FileSourceKeyStore, type FileSourceKeyStoreOptions, type FilesRow, type FillLlm, type Filter, type FilterAnd, type FilterExpr, type FilterOp, type FilterOr, FoldCache, type FtsConfig, type FtsGroup, type FtsHit, type FtsOptions, type FtsResult, type GraphBoostOptions, type GraphBoostResult, type GraphEdge, type GraphNode, type GraphTraversalResult, type GuiServerHandle, type HasManyRelation, type HasManySource, type HealthIssueKind, type HealthSeverity, type HybridScoreBreakdown, type HybridSearchOptions, type HybridSearchResult, IMMUTABLE_CONNECTED_FIELDS, type ImportMode, type ImportProgress, InMemorySourceKeyStore, InMemoryStateStore, type InferredColumn, type InferredDimension, type InferredEntity, type InferredLinkage, type InferredType, type InitOptions, type IntrospectiveSpec, LEGACY_MEMBER_GROUP, LOCAL_DB_RELPATH, type LatencyStats, Lattice, type LatticeConfig, type LatticeConfigInput, type LatticeEntityDef, type LatticeEntityRenderSpec, type LatticeFieldDef, type LatticeFieldType, type LatticeManifest, type LatticeOptions, type LinkOptions, type ListChangesContext, type LlmClient, type LlmMessage, MAX_TRAVERSAL_DEPTH, type ManyToManySource, type MarkdownTableColumn, type MaterializeCtx, type MaterializeOptions, type MaterializeResult, type MaterializedRollupSpec, type McpBeginResult, type McpConnector, McpConnectorBase, type McpConnectorDeps, type McpConnectorSpec, type McpModelBinding, type McpOAuthDriver, type McpServerRef, type McpServerSpec, type McpToolCall, type McpToolInfo, type McpTransport, type McpTransportFactory, type MigrateResult, type Migration, type MigrationCheckpoint, type MigrationOptions, type MigrationProgress, type MigrationResult, type MigrationStatus, type MultiTableDefinition, NATIVE_ENTITY_DEFS, NATIVE_ENTITY_NAMES, NATIVE_REGISTRY_TABLE, type Observation, type OrderBySpec, type OrganizeOptions, type OrganizeResult, type OrganizedCreation, type OrganizedLink, type PageOpts, type ParseError, type ParseResult, type ParsedConfig, type PdfOptions, type PdfSenderInput, type PerQueryEval, type PkLookup, PostgresAdapter, type PostgresAdapterOptions, PostgresDialect, type PreparedStatement, type PrimaryKey, ProgressThrottle, type ProposedSchema, type ProvenanceConfig, type ProvenanceField, ProvenanceImmutableError, type QueryOptions, type QueryPageOptions, type QueryPageResult, type QueryProjection, READ_ONLY_HEADER, ROOT_DIRNAME, type RankingOptions, type ReadOnlyHeaderOptions, type RecencySignal, type ReconcileOptions, type ReconcileResult, type RefKind, type RefProvider, type ReferenceMetadata, ReferenceUnavailableError, type RefreshEmbeddingsOptions, type RegisterComputedTablesOptions, type Relation, type RelevanceLabel, type RemoteBlobStore, type RenderHooks, type RenderOptions, type RenderProgress, type RenderProgressCallback, type RenderProgressKind, type RenderResult, type RenderSpec, type ReportConfig, type ReportResult, type ReportSection, type ReportSectionResult, type RerankCandidate, type RerankScore, type RerankerFn, type ResolveOptions, type RetrievalEvalOptions, type RetrievalEvalSummary, type RetrievalHealthIssue, type RetrievalHealthReport, type RetrievalHealthSpec, type RetrievalSlo, type Retriever, type RetryOptions, type ReverseSeedDetection, type ReverseSeedResult, type ReverseSeedTableResult, type ReverseSyncError, type ReverseSyncResult, type ReverseSyncUpdate, type RewardScores, type RewardSignal, type RollupFunction, type Row, type RowVisibilityDefault, type S3Config, type S3StoreConfig, S3UnavailableError, S3_SECRET_TABLE, SQLiteAdapter, type SchemaEntity, type SchemaMatch, type SearchOptions, type SearchResult, type SecurityOptions, type SeedConfig, type SeedLinkSpec, SeedReconciliationError, type SeedResult, type SelfSource, type SemanticChunkerOptions, type SessionEntry, type SessionParseOptions, type SessionWriteEntry, type SessionWriteOp, type SessionWriteParseResult, SimpleMcpConnector, type SloViolation, type SourceHandle, type SourceKeyStore, type SourceMetadata, type SourceQueryOptions, SourceShreddedError, type SqlDialect, type SqlQuery, type StartGuiServerOptions, type StopFn, type StorageAdapter, type SyncConnectorOptions, type SyncConnectorResult, type SyncResult, TRUST_COLUMNS, type TableDefinition, type TableHealth, type TablePolicy, type TemplateRenderSpec, type TextChunk, type ToolkitPresentation, type TraversalDirection, type TraversalNode, type TraversalOptions, type TrustConfig, type TrustState, type TurnParams, type TurnResult, type UnresolvedLink, type UpsertByNaturalKeyOptions, type UserIdentity, type UserPreferences, type VectorHit, type VectorIndexOptions, type Viewer, type VisionOptions, type VisionSenderInput, WORKSPACES_SUBDIR, type WatchOptions, type WorkspacePaths, type WorkspaceRecord, type WorkspaceRegistry, type WriteHook, type WriteHookContext, type WritebackDefinition, type WritebackStateStore, type WritebackValidationResult, activeWorkspaceLabel, addEdge, addEdges, addWorkspace, adoptNativeEntities, allComputedDeps, analyticsEnabled, applyChunkedMigration, applyReranker, applyTokenBudget, applyWriteEntry, archiveLocalSqlite, assembleConnectionString, assertSafeUrl, attachBlob, audiencePredicate, audienceViewSql, autoFtsColumns, autoUpdate, backfillOwnership, backlinkBoost, benchmarkRetrieval, buildModelDefs, buildVectorIndex, builtinConnectors, canManageRoles, checkSlos, chunkText, classifyLinks, clearDbSourceCreds, clearSchemaDescriptor, cloudRlsInstalled, collectConnectorKeys, compileComputedTable, computeColumns, computedColumnDdl, computedColumnOrder, computedTableOrder, concatRowText, configDir, connectDirect, connectedColumns, contentHash, cosineSimilarity, crawlUrl, createConnector, createReadOnlyHeader, createS3Store, createSQLiteStateStore, decrypt, dedupeAndDetectViews, defaultWorkspaceYaml, deleteConnectorRecord, deleteDbCredential, deleteToken, deriveCanonicalContexts, deriveKey, describeConnectedSources, describeImage, describePdf, detectAsOf, detectAsOfCandidates, detectAsOfColumns, detectRetrievalRegressions, diagnoseRetrieval, dialectFor, disconnectConnector, discoverCloudTables, dropVectorIndex, emitCalcExpr, enableAudienceView, enableChangelogRls, enableConnectorRls, enableRlsForTable, encrypt, enrichKnowledge, ensureAiTables, ensureCheckpointTable, ensureConnectorRegistry, ensureEdgesTable, ensureEmbeddingsTable, ensureFtsIndex, ensureLatticeRoot, entityFileNames, estimateTokens, evaluateRetrieval, excelToRecords, extractEdgesFromColumn, extractObjects, filePresignSql, findLatticeRoot, fixSchemaConflicts, foldEntity, formatHealthReport, frontmatter, ftsTableName, fullTextSearch, generateEntryId, generateMemberPassword, generateWriteEntryId, genericConnector, getActiveWorkspace, getCloudSetting, getConnector, getConnectorByToolkit, getDbCredential, getDbSourceCreds, getMigrationCheckpoint, getOrCreateMasterKey, getSchemaDescriptor, getTablePolicy, getWorkspace, grantMemberAccess, grantPresignerToMemberGroup, graphAdjacencyBoost, hasFilePresigner, hasFtsIndex, hasVectorIndex, hashFile, hybridSearch, importLegacyUserConfig, inferFieldType, inferSchema, installCloudRls, installCloudSettings, installFilePresigner, introspectiveConnector, isCredentialConnector, isEncrypted, isMcpConnector, isNativeEntity, isPostgresUrl, isPrivateIp, isRetryableDbError, isRowAudience, latencyStats, latticeTableName, listConnectors, listDbCredentials, listMigrationCheckpoints, listNativeBindings, listTokens, listWorkspaces, loadColumnPolicy, manifestPath, markdownTable, matchSchemaToExisting, materializeImport, mcpModel, memberGroupFor, memberRoleName, migrateLatticeData, neighbors, normalizeName, observationVisible, observationsFromChange, openTargetLatticeForMigration, openUnderSource, organizeSource, parseCalcExpr, parseCellDate, parseConfigFile, parseConfigString, parseMarkdownEntries, parseMatches, parseObjects, parseSessionMD, parseSessionWrites, percentile, probeCloud, provenanceColumns, providerForUrl, provisionMemberRole, purgeAiField, rankingBoost, readComputedState, readIdentity, readManifest, readPreferences, readRegistry, readToken, recencyBoost, recordSync, referenceLocalFile, referenceUrl, refreshEmbeddings, regenerateAudienceViewFromDb, registerComputedTables, registerNativeEntities, registryPath, removeEdge, removeEmbedding, renameEntities, resolveActiveS3Config, resolveConnectorIdentity, resolveLatticeRoot, resolveProvenanceFields, resolveSource, resolveTrustDefault, resolveWorkspacePaths, resumeMigration, revertMigration, revokeMemberRole, rewardBoost, rollupColumnDdl, rootConfigDir, runComputedFill, s3Key, saveDbCredential, saveDbCredentialForTeam, sealUnderSource, searchByEmbedding, searchVectorIndex, secureCloud, secureConnectorTables, seedColumnPolicyFromYaml, semanticChunker, setActiveWorkspace, setCloudS3Secret, setCloudSetting, setColumnAudience, setConnectorStatus, setDbSourceCreds, setRowVisibility, setSchemaDescriptor, setTableDefaultVisibility, setTableNeverShare, shredSource, slugify$1 as slugify, slugify as slugifyDbName, sourceRecords, startGuiServer, storeEmbedding, summarizeText, syncConnector, syncIfStale, syncStaleConnectors, tableNeedsAudienceView, toSafeDirName, traverse, truncate, updateConnectorConnection, validateEntryId, vectorIndexAvailable, vectorIndexName, withRetry, workspaceBlobsDir, workspaceConfigPath, workspaceContextDir, workspaceDataDir, workspaceDbPath, workspaceDir, workspacesDir, writeIdentity, writeManifest, writePreferences, writeRegistry, writeToken };
|