trellis 2.0.8 → 2.0.13

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.
Files changed (42) hide show
  1. package/README.md +279 -116
  2. package/dist/cli/index.js +655 -4
  3. package/dist/core/index.js +471 -2
  4. package/dist/embeddings/index.js +5 -1
  5. package/dist/{index-s603ev6w.js → index-5b01h414.js} +1 -1
  6. package/dist/index-5m0g9r0y.js +1100 -0
  7. package/dist/{index-zf6htvnm.js → index-7gvjxt27.js} +166 -2
  8. package/dist/index-hybgxe40.js +1174 -0
  9. package/dist/index.js +7 -2
  10. package/dist/transformers.node-bx3q9d7k.js +33130 -0
  11. package/package.json +9 -4
  12. package/src/cli/index.ts +939 -0
  13. package/src/core/agents/harness.ts +380 -0
  14. package/src/core/agents/index.ts +18 -0
  15. package/src/core/agents/types.ts +90 -0
  16. package/src/core/index.ts +85 -2
  17. package/src/core/kernel/trellis-kernel.ts +593 -0
  18. package/src/core/ontology/builtins.ts +248 -0
  19. package/src/core/ontology/index.ts +34 -0
  20. package/src/core/ontology/registry.ts +209 -0
  21. package/src/core/ontology/types.ts +124 -0
  22. package/src/core/ontology/validator.ts +382 -0
  23. package/src/core/persist/backend.ts +10 -0
  24. package/src/core/persist/sqlite-backend.ts +298 -0
  25. package/src/core/plugins/index.ts +17 -0
  26. package/src/core/plugins/registry.ts +322 -0
  27. package/src/core/plugins/types.ts +126 -0
  28. package/src/core/query/datalog.ts +188 -0
  29. package/src/core/query/engine.ts +370 -0
  30. package/src/core/query/index.ts +34 -0
  31. package/src/core/query/parser.ts +481 -0
  32. package/src/core/query/types.ts +200 -0
  33. package/src/embeddings/auto-embed.ts +248 -0
  34. package/src/embeddings/index.ts +7 -0
  35. package/src/embeddings/model.ts +21 -4
  36. package/src/embeddings/types.ts +8 -1
  37. package/src/index.ts +9 -0
  38. package/src/sync/http-transport.ts +144 -0
  39. package/src/sync/index.ts +11 -0
  40. package/src/sync/multi-repo.ts +200 -0
  41. package/src/sync/ws-transport.ts +145 -0
  42. package/dist/index-5bhe57y9.js +0 -326
@@ -0,0 +1,145 @@
1
+ /**
2
+ * WebSocket Sync Transport
3
+ *
4
+ * Implements SyncTransport over WebSocket for real-time peer sync.
5
+ * Uses Bun's native WebSocket support for both server and client.
6
+ *
7
+ * @module trellis/sync
8
+ */
9
+
10
+ import type { SyncTransport, SyncMessage, PeerId } from './types.js';
11
+
12
+ // ---------------------------------------------------------------------------
13
+ // WebSocket Transport
14
+ // ---------------------------------------------------------------------------
15
+
16
+ export class WebSocketSyncTransport implements SyncTransport {
17
+ private localPeerId: string;
18
+ private connections: Map<string, WebSocket> = new Map();
19
+ private knownPeers: Map<string, PeerId> = new Map();
20
+ private messageHandler: ((msg: SyncMessage) => void) | null = null;
21
+
22
+ constructor(localPeerId: string) {
23
+ this.localPeerId = localPeerId;
24
+ }
25
+
26
+ /**
27
+ * Connect to a remote peer's WebSocket endpoint.
28
+ */
29
+ async connect(peerId: string, url: string, name?: string): Promise<void> {
30
+ return new Promise((resolve, reject) => {
31
+ const ws = new WebSocket(url);
32
+
33
+ ws.onopen = () => {
34
+ this.connections.set(peerId, ws);
35
+ this.knownPeers.set(peerId, {
36
+ id: peerId,
37
+ name: name ?? peerId,
38
+ lastSeen: new Date().toISOString(),
39
+ });
40
+ resolve();
41
+ };
42
+
43
+ ws.onmessage = (event) => {
44
+ try {
45
+ const msg = JSON.parse(String(event.data)) as SyncMessage;
46
+ this.knownPeers.set(msg.peerId, {
47
+ id: msg.peerId,
48
+ name: msg.peerId,
49
+ lastSeen: new Date().toISOString(),
50
+ });
51
+ if (this.messageHandler) {
52
+ this.messageHandler(msg);
53
+ }
54
+ } catch {}
55
+ };
56
+
57
+ ws.onclose = () => {
58
+ this.connections.delete(peerId);
59
+ };
60
+
61
+ ws.onerror = (err) => {
62
+ reject(new Error(`WebSocket connection to ${peerId} failed`));
63
+ };
64
+ });
65
+ }
66
+
67
+ /**
68
+ * Accept an incoming WebSocket connection (server side).
69
+ */
70
+ acceptConnection(peerId: string, ws: WebSocket): void {
71
+ this.connections.set(peerId, ws);
72
+ this.knownPeers.set(peerId, {
73
+ id: peerId,
74
+ name: peerId,
75
+ lastSeen: new Date().toISOString(),
76
+ });
77
+
78
+ ws.onmessage = (event) => {
79
+ try {
80
+ const msg = JSON.parse(String(event.data)) as SyncMessage;
81
+ this.knownPeers.set(msg.peerId, {
82
+ id: msg.peerId,
83
+ name: msg.peerId,
84
+ lastSeen: new Date().toISOString(),
85
+ });
86
+ if (this.messageHandler) {
87
+ this.messageHandler(msg);
88
+ }
89
+ } catch {}
90
+ };
91
+
92
+ ws.onclose = () => {
93
+ this.connections.delete(peerId);
94
+ };
95
+ }
96
+
97
+ async send(peerId: string, message: SyncMessage): Promise<void> {
98
+ const ws = this.connections.get(peerId);
99
+ if (!ws || ws.readyState !== WebSocket.OPEN) {
100
+ throw new Error(`No open connection to peer "${peerId}".`);
101
+ }
102
+ ws.send(JSON.stringify(message));
103
+ }
104
+
105
+ onMessage(handler: (message: SyncMessage) => void): void {
106
+ this.messageHandler = handler;
107
+ }
108
+
109
+ peers(): PeerId[] {
110
+ return [...this.knownPeers.values()];
111
+ }
112
+
113
+ /**
114
+ * Disconnect from a peer.
115
+ */
116
+ disconnect(peerId: string): void {
117
+ const ws = this.connections.get(peerId);
118
+ if (ws) {
119
+ ws.close();
120
+ this.connections.delete(peerId);
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Disconnect from all peers.
126
+ */
127
+ disconnectAll(): void {
128
+ for (const [id, ws] of this.connections) {
129
+ ws.close();
130
+ }
131
+ this.connections.clear();
132
+ }
133
+
134
+ /**
135
+ * Check if connected to a specific peer.
136
+ */
137
+ isConnected(peerId: string): boolean {
138
+ const ws = this.connections.get(peerId);
139
+ return ws !== undefined && ws.readyState === WebSocket.OPEN;
140
+ }
141
+
142
+ getLocalPeerId(): string {
143
+ return this.localPeerId;
144
+ }
145
+ }
@@ -1,326 +0,0 @@
1
- // @bun
2
- import {
3
- __esm
4
- } from "./index-a76rekgs.js";
5
-
6
- // src/core/store/eav-store.ts
7
- function* flatten(obj, base = "") {
8
- if (Array.isArray(obj)) {
9
- for (const v of obj) {
10
- yield* flatten(v, base);
11
- }
12
- } else if (obj && typeof obj === "object") {
13
- for (const [k, v] of Object.entries(obj)) {
14
- yield* flatten(v, base ? `${base}.${k}` : k);
15
- }
16
- } else {
17
- yield [base, obj];
18
- }
19
- }
20
- function jsonEntityFacts(entityId, root, type) {
21
- const facts = [{ e: entityId, a: "type", v: type }];
22
- for (const [a, v] of flatten(root)) {
23
- if (v === undefined || v === null)
24
- continue;
25
- if (Array.isArray(v)) {
26
- for (const el of v) {
27
- facts.push({ e: entityId, a, v: el });
28
- }
29
- } else if (typeof v === "object") {} else {
30
- facts.push({ e: entityId, a, v });
31
- }
32
- }
33
- return facts;
34
- }
35
-
36
- class EAVStore {
37
- facts = [];
38
- links = [];
39
- catalog = new Map;
40
- eavIndex = new Map;
41
- aevIndex = new Map;
42
- aveIndex = new Map;
43
- linkIndex = new Map;
44
- linkReverseIndex = new Map;
45
- linkAttrIndex = new Map;
46
- distinct = new Map;
47
- addFacts(facts) {
48
- for (let i = 0;i < facts.length; i++) {
49
- const fact = facts[i];
50
- if (fact) {
51
- this.facts.push(fact);
52
- this.updateIndexes(fact, this.facts.length - 1);
53
- this.updateCatalog(fact);
54
- }
55
- }
56
- }
57
- addLinks(links) {
58
- for (const link of links) {
59
- this.links.push(link);
60
- this.updateLinkIndexes(link);
61
- }
62
- }
63
- deleteFacts(factsToDelete) {
64
- for (const fact of factsToDelete) {
65
- const valueKey = this.valueKey(fact.v);
66
- const indices = this.aveIndex.get(fact.a)?.get(valueKey);
67
- if (!indices)
68
- continue;
69
- let foundIdx = -1;
70
- for (const idx of indices) {
71
- const storedFact = this.facts[idx];
72
- if (storedFact && storedFact.e === fact.e && storedFact.a === fact.a) {
73
- foundIdx = idx;
74
- break;
75
- }
76
- }
77
- if (foundIdx !== -1) {
78
- this.facts[foundIdx] = undefined;
79
- this.eavIndex.get(fact.e)?.get(fact.a)?.delete(foundIdx);
80
- this.aevIndex.get(fact.a)?.get(fact.e)?.delete(foundIdx);
81
- this.aveIndex.get(fact.a)?.get(valueKey)?.delete(foundIdx);
82
- const entry = this.catalog.get(fact.a);
83
- if (entry) {}
84
- }
85
- }
86
- }
87
- deleteLinks(linksToDelete) {
88
- for (const link of linksToDelete) {
89
- const initialLen = this.links.length;
90
- this.links = this.links.filter((l) => !(l.e1 === link.e1 && l.a === link.a && l.e2 === link.e2));
91
- if (this.links.length < initialLen) {
92
- this.linkIndex.get(link.e1)?.get(link.a)?.delete(link.e2);
93
- this.linkReverseIndex.get(link.e2)?.get(link.a)?.delete(link.e1);
94
- const attrPairs = this.linkAttrIndex.get(link.a);
95
- if (attrPairs) {
96
- for (const pair of attrPairs) {
97
- if (pair[0] === link.e1 && pair[1] === link.e2) {
98
- attrPairs.delete(pair);
99
- break;
100
- }
101
- }
102
- }
103
- }
104
- }
105
- }
106
- updateIndexes(fact, index) {
107
- if (!this.eavIndex.has(fact.e)) {
108
- this.eavIndex.set(fact.e, new Map);
109
- }
110
- if (!this.eavIndex.get(fact.e).has(fact.a)) {
111
- this.eavIndex.get(fact.e).set(fact.a, new Set);
112
- }
113
- this.eavIndex.get(fact.e).get(fact.a).add(index);
114
- if (!this.aevIndex.has(fact.a)) {
115
- this.aevIndex.set(fact.a, new Map);
116
- }
117
- if (!this.aevIndex.get(fact.a).has(fact.e)) {
118
- this.aevIndex.get(fact.a).set(fact.e, new Set);
119
- }
120
- this.aevIndex.get(fact.a).get(fact.e).add(index);
121
- if (!this.aveIndex.has(fact.a)) {
122
- this.aveIndex.set(fact.a, new Map);
123
- }
124
- const valueKey = this.valueKey(fact.v);
125
- if (!this.aveIndex.get(fact.a).has(valueKey)) {
126
- this.aveIndex.get(fact.a).set(valueKey, new Set);
127
- }
128
- this.aveIndex.get(fact.a).get(valueKey).add(index);
129
- }
130
- updateLinkIndexes(link) {
131
- if (!this.linkIndex.has(link.e1)) {
132
- this.linkIndex.set(link.e1, new Map);
133
- }
134
- const e1Attrs = this.linkIndex.get(link.e1);
135
- if (!e1Attrs.has(link.a)) {
136
- e1Attrs.set(link.a, new Set);
137
- }
138
- e1Attrs.get(link.a).add(link.e2);
139
- if (!this.linkReverseIndex.has(link.e2)) {
140
- this.linkReverseIndex.set(link.e2, new Map);
141
- }
142
- const e2Attrs = this.linkReverseIndex.get(link.e2);
143
- if (!e2Attrs.has(link.a)) {
144
- e2Attrs.set(link.a, new Set);
145
- }
146
- e2Attrs.get(link.a).add(link.e1);
147
- if (!this.linkAttrIndex.has(link.a)) {
148
- this.linkAttrIndex.set(link.a, new Set);
149
- }
150
- this.linkAttrIndex.get(link.a).add([link.e1, link.e2]);
151
- }
152
- valueKey(v) {
153
- if (v instanceof Date)
154
- return `date:${v.toISOString()}`;
155
- return `${typeof v}:${v}`;
156
- }
157
- updateCatalog(fact) {
158
- const entry = this.catalog.get(fact.a) || {
159
- attribute: fact.a,
160
- type: this.inferType(fact.v),
161
- cardinality: "one",
162
- distinctCount: 0,
163
- examples: []
164
- };
165
- const factType = this.inferType(fact.v);
166
- if (entry.type !== factType && entry.type !== "mixed") {
167
- entry.type = "mixed";
168
- }
169
- const entityAttrs = this.eavIndex.get(fact.e)?.get(fact.a);
170
- if (entityAttrs && entityAttrs.size > 1) {
171
- entry.cardinality = "many";
172
- }
173
- const k = this.valueKey(fact.v);
174
- const s = this.distinct.get(fact.a) || (this.distinct.set(fact.a, new Set), this.distinct.get(fact.a));
175
- s.add(k);
176
- entry.distinctCount = s.size;
177
- if (entry.examples.length < 5 && !entry.examples.includes(fact.v)) {
178
- entry.examples.push(fact.v);
179
- }
180
- if (typeof fact.v === "number") {
181
- entry.min = Math.min(entry.min ?? fact.v, fact.v);
182
- entry.max = Math.max(entry.max ?? fact.v, fact.v);
183
- }
184
- this.catalog.set(fact.a, entry);
185
- }
186
- inferType(v) {
187
- if (typeof v === "string")
188
- return "string";
189
- if (typeof v === "number")
190
- return "number";
191
- if (typeof v === "boolean")
192
- return "boolean";
193
- if (v instanceof Date)
194
- return "date";
195
- return "mixed";
196
- }
197
- getFactsByEntity(entity) {
198
- const indices = this.eavIndex.get(entity);
199
- if (!indices)
200
- return [];
201
- const result = [];
202
- for (const attrIndices of indices.values()) {
203
- for (const idx of attrIndices) {
204
- const fact = this.facts[idx];
205
- if (fact) {
206
- result.push(fact);
207
- }
208
- }
209
- }
210
- return result;
211
- }
212
- getFactsByAttribute(attribute) {
213
- const indices = this.aevIndex.get(attribute);
214
- if (!indices)
215
- return [];
216
- const result = [];
217
- for (const entityIndices of indices.values()) {
218
- for (const idx of entityIndices) {
219
- const fact = this.facts[idx];
220
- if (fact) {
221
- result.push(fact);
222
- }
223
- }
224
- }
225
- return result;
226
- }
227
- getFactsByValue(attribute, value) {
228
- const indices = this.aveIndex.get(attribute)?.get(this.valueKey(value));
229
- if (!indices)
230
- return [];
231
- return Array.from(indices).map((idx) => this.facts[idx]).filter((fact) => fact !== undefined);
232
- }
233
- getCatalog() {
234
- return Array.from(this.catalog.values());
235
- }
236
- getCatalogEntry(attribute) {
237
- return this.catalog.get(attribute);
238
- }
239
- getAllFacts() {
240
- return this.facts.filter((f) => f !== undefined);
241
- }
242
- getAllLinks() {
243
- return [...this.links];
244
- }
245
- getLinksByEntity(entity) {
246
- const results = [];
247
- const forwardLinks = this.linkIndex.get(entity);
248
- if (forwardLinks) {
249
- for (const [attr, targets] of forwardLinks) {
250
- for (const target of targets) {
251
- results.push({ e1: entity, a: attr, e2: target });
252
- }
253
- }
254
- }
255
- const reverseLinks = this.linkReverseIndex.get(entity);
256
- if (reverseLinks) {
257
- for (const [attr, sources] of reverseLinks) {
258
- for (const source of sources) {
259
- results.push({ e1: source, a: attr, e2: entity });
260
- }
261
- }
262
- }
263
- return results;
264
- }
265
- getLinksByAttribute(attribute) {
266
- const results = [];
267
- const links = this.linkAttrIndex.get(attribute);
268
- if (links) {
269
- for (const [e1, e2] of links) {
270
- results.push({ e1, a: attribute, e2 });
271
- }
272
- }
273
- return results;
274
- }
275
- getLinksByEntityAndAttribute(entity, attribute) {
276
- const results = [];
277
- const attrs = this.linkIndex.get(entity);
278
- if (attrs) {
279
- const targets = attrs.get(attribute);
280
- if (targets) {
281
- for (const target of targets) {
282
- results.push({ e1: entity, a: attribute, e2: target });
283
- }
284
- }
285
- }
286
- return results;
287
- }
288
- getStats() {
289
- return {
290
- totalFacts: this.facts.length,
291
- totalLinks: this.links.length,
292
- uniqueEntities: this.eavIndex.size,
293
- uniqueAttributes: this.aevIndex.size,
294
- catalogEntries: this.catalog.size
295
- };
296
- }
297
- snapshot() {
298
- return {
299
- facts: this.facts.filter((f) => f !== undefined),
300
- links: [...this.links],
301
- catalog: this.getCatalog()
302
- };
303
- }
304
- restore(snapshot) {
305
- this.facts = [];
306
- this.links = [];
307
- this.catalog.clear();
308
- this.eavIndex.clear();
309
- this.aevIndex.clear();
310
- this.aveIndex.clear();
311
- this.linkIndex.clear();
312
- this.linkReverseIndex.clear();
313
- this.linkAttrIndex.clear();
314
- this.distinct.clear();
315
- this.addFacts(snapshot.facts);
316
- this.addLinks(snapshot.links);
317
- if (snapshot.catalog) {
318
- for (const entry of snapshot.catalog) {
319
- this.catalog.set(entry.attribute, entry);
320
- }
321
- }
322
- }
323
- }
324
- var init_eav_store = () => {};
325
-
326
- export { flatten, jsonEntityFacts, EAVStore, init_eav_store };