trellis 2.1.9 → 3.0.2
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 +65 -796
- package/dist/cli/index.d.ts +3 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2948 -182
- package/dist/client/index.js +4 -4
- package/dist/context/heat-map-manager.d.ts +100 -0
- package/dist/context/heat-map-manager.d.ts.map +1 -0
- package/dist/context/manager.d.ts +16 -0
- package/dist/context/manager.d.ts.map +1 -0
- package/dist/context/types.d.ts +20 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/core/agents/harness.d.ts +10 -1
- package/dist/core/agents/harness.d.ts.map +1 -1
- package/dist/core/agents/types.d.ts +18 -2
- package/dist/core/agents/types.d.ts.map +1 -1
- package/dist/core/computation/expr-evaluator.d.ts +52 -0
- package/dist/core/computation/expr-evaluator.d.ts.map +1 -0
- package/dist/core/index.js +93 -5
- package/dist/core/kernel/logic-middleware.d.ts +19 -0
- package/dist/core/kernel/logic-middleware.d.ts.map +1 -0
- package/dist/core/kernel/schema-middleware.d.ts +15 -0
- package/dist/core/kernel/schema-middleware.d.ts.map +1 -0
- package/dist/core/kernel/security-middleware.d.ts +24 -0
- package/dist/core/kernel/security-middleware.d.ts.map +1 -0
- package/dist/core/kernel/sync-provider.d.ts +59 -0
- package/dist/core/kernel/sync-provider.d.ts.map +1 -0
- package/dist/core/kernel/trellis-kernel.d.ts +55 -0
- package/dist/core/kernel/trellis-kernel.d.ts.map +1 -1
- package/dist/core/ontology/builtins.d.ts.map +1 -1
- package/dist/core/ontology/core-ontology.d.ts +20 -0
- package/dist/core/ontology/core-ontology.d.ts.map +1 -0
- package/dist/core/ontology/index.d.ts +3 -1
- package/dist/core/ontology/index.d.ts.map +1 -1
- package/dist/core/ontology/types.d.ts +138 -34
- package/dist/core/ontology/types.d.ts.map +1 -1
- package/dist/core/persist/backend.d.ts +2 -0
- package/dist/core/persist/backend.d.ts.map +1 -1
- package/dist/core/persist/better-sqlite-backend.d.ts +33 -0
- package/dist/core/persist/better-sqlite-backend.d.ts.map +1 -0
- package/dist/core/persist/sqlite-backend.d.ts +2 -0
- package/dist/core/persist/sqlite-backend.d.ts.map +1 -1
- package/dist/core/store/eav-store.d.ts +4 -0
- package/dist/core/store/eav-store.d.ts.map +1 -1
- package/dist/db/index.js +10 -8
- package/dist/{deploy-99j5dc9c.js → deploy-999q207z.js} +2 -1
- package/dist/engine.d.ts +3 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/evals/types.d.ts +29 -0
- package/dist/evals/types.d.ts.map +1 -0
- package/dist/{import-fyg5sgq4.js → import-s2b8e0ft.js} +2 -2
- package/dist/{index-3ejh8k6v.js → index-0q7wbasy.js} +18 -4
- package/dist/{index-7t92ej34.js → index-0zk3fx2s.js} +467 -7
- package/dist/{index-xr7rx360.js → index-6n5dcebj.js} +33 -0
- package/dist/{index-4beszbgg.js → index-7e27kvvj.js} +1 -1
- package/dist/index-bmyt7k8n.js +90 -0
- package/dist/{index-k5kf7sd0.js → index-hmdbnd4n.js} +1 -1
- package/dist/{index-czecrvvn.js → index-q31hfjja.js} +858 -48
- package/dist/{index-8fjwnztt.js → index-skhn0agf.js} +1 -1
- package/dist/{index-04sq3h27.js → index-w7ng765c.js} +3 -1
- package/dist/{index-hgd30epa.js → index-wt8rz4gn.js} +4 -21
- package/dist/{index-5p6zgspx.js → index-y3d71wzd.js} +1 -1
- package/dist/index-y6a4kj0p.js +43 -0
- package/dist/{index-5bhe57y9.js → index-yhwjgfvj.js} +16 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -6
- package/dist/llm/provider.d.ts +11 -0
- package/dist/llm/provider.d.ts.map +1 -0
- package/dist/llm/types.d.ts +74 -0
- package/dist/llm/types.d.ts.map +1 -0
- package/dist/mcp/index.d.ts +7 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/orchestration/types.d.ts +22 -0
- package/dist/orchestration/types.d.ts.map +1 -0
- package/dist/plugins/agent-memory/graph-context-manager.d.ts +75 -0
- package/dist/plugins/agent-memory/graph-context-manager.d.ts.map +1 -0
- package/dist/plugins/agent-memory/index.d.ts +30 -0
- package/dist/plugins/agent-memory/index.d.ts.map +1 -0
- package/dist/plugins/agent-memory/ontology.d.ts +13 -0
- package/dist/plugins/agent-memory/ontology.d.ts.map +1 -0
- package/dist/plugins/agent-memory/plugin.d.ts +17 -0
- package/dist/plugins/agent-memory/plugin.d.ts.map +1 -0
- package/dist/plugins/brand/cache.d.ts +18 -0
- package/dist/plugins/brand/cache.d.ts.map +1 -0
- package/dist/plugins/brand/catalog-generator.d.ts +89 -0
- package/dist/plugins/brand/catalog-generator.d.ts.map +1 -0
- package/dist/plugins/brand/constraints.d.ts +55 -0
- package/dist/plugins/brand/constraints.d.ts.map +1 -0
- package/dist/plugins/brand/index.d.ts +44 -0
- package/dist/plugins/brand/index.d.ts.map +1 -0
- package/dist/plugins/brand/mcp-tools.d.ts +101 -0
- package/dist/plugins/brand/mcp-tools.d.ts.map +1 -0
- package/dist/plugins/brand/ontology.d.ts +13 -0
- package/dist/plugins/brand/ontology.d.ts.map +1 -0
- package/dist/plugins/brand/plugin.d.ts +21 -0
- package/dist/plugins/brand/plugin.d.ts.map +1 -0
- package/dist/plugins/brand/voice-tone.d.ts +24 -0
- package/dist/plugins/brand/voice-tone.d.ts.map +1 -0
- package/dist/plugins/idea-garden/api.d.ts +26 -0
- package/dist/plugins/idea-garden/api.d.ts.map +1 -0
- package/dist/plugins/idea-garden/index.d.ts +12 -0
- package/dist/plugins/idea-garden/index.d.ts.map +1 -0
- package/dist/plugins/idea-garden/plugin.d.ts +16 -0
- package/dist/plugins/idea-garden/plugin.d.ts.map +1 -0
- package/dist/plugins/idea-garden/types.d.ts +22 -0
- package/dist/plugins/idea-garden/types.d.ts.map +1 -0
- package/dist/plugins/plan-approval/index.d.ts +36 -0
- package/dist/plugins/plan-approval/index.d.ts.map +1 -0
- package/dist/plugins/plan-approval/ontology.d.ts +11 -0
- package/dist/plugins/plan-approval/ontology.d.ts.map +1 -0
- package/dist/plugins/plan-approval/plan-manager.d.ts +104 -0
- package/dist/plugins/plan-approval/plan-manager.d.ts.map +1 -0
- package/dist/plugins/plan-approval/plugin.d.ts +110 -0
- package/dist/plugins/plan-approval/plugin.d.ts.map +1 -0
- package/dist/plugins/proactive-watcher/index.d.ts +28 -0
- package/dist/plugins/proactive-watcher/index.d.ts.map +1 -0
- package/dist/plugins/proactive-watcher/ontology.d.ts +8 -0
- package/dist/plugins/proactive-watcher/ontology.d.ts.map +1 -0
- package/dist/plugins/proactive-watcher/plugin.d.ts +20 -0
- package/dist/plugins/proactive-watcher/plugin.d.ts.map +1 -0
- package/dist/plugins/proactive-watcher/watcher-manager.d.ts +36 -0
- package/dist/plugins/proactive-watcher/watcher-manager.d.ts.map +1 -0
- package/dist/plugins/sprite-tools/checkpoint-middleware.d.ts +43 -0
- package/dist/plugins/sprite-tools/checkpoint-middleware.d.ts.map +1 -0
- package/dist/plugins/sprite-tools/index.d.ts +40 -0
- package/dist/plugins/sprite-tools/index.d.ts.map +1 -0
- package/dist/plugins/sprite-tools/plugin.d.ts +69 -0
- package/dist/plugins/sprite-tools/plugin.d.ts.map +1 -0
- package/dist/react/index.js +4 -4
- package/dist/scaffold/index.d.ts +13 -0
- package/dist/scaffold/index.d.ts.map +1 -0
- package/dist/scaffold/infer.d.ts +42 -0
- package/dist/scaffold/infer.d.ts.map +1 -0
- package/dist/scaffold/profile.d.ts +51 -0
- package/dist/scaffold/profile.d.ts.map +1 -0
- package/dist/scaffold/seed.d.ts +27 -0
- package/dist/scaffold/seed.d.ts.map +1 -0
- package/dist/scaffold/write.d.ts +53 -0
- package/dist/scaffold/write.d.ts.map +1 -0
- package/dist/{sdk-sj8rp0m7.js → sdk-snn5gad3.js} +4 -4
- package/dist/server/deploy.d.ts.map +1 -1
- package/dist/server/index.d.ts +5 -3
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +37 -7
- package/dist/server/sprites.d.ts +26 -0
- package/dist/server/sprites.d.ts.map +1 -0
- package/dist/server/vm-config.d.ts +60 -0
- package/dist/server/vm-config.d.ts.map +1 -0
- package/dist/{server-3vkpnpbz.js → server-mrctdwzr.js} +2 -2
- package/dist/sprites-vc4qbrp1.js +16 -0
- package/dist/streaming/types.d.ts +43 -0
- package/dist/streaming/types.d.ts.map +1 -0
- package/dist/{tenancy-tjr7kk2v.js → tenancy-7d1g4ayp.js} +3 -3
- package/dist/ui/client.html +460 -664
- package/dist/ui/server.d.ts +6 -2
- package/dist/ui/server.d.ts.map +1 -1
- package/dist/vcs/decompose.d.ts.map +1 -1
- package/dist/vcs/index.js +2 -2
- package/dist/vcs/issue.d.ts.map +1 -1
- package/dist/vcs/types.d.ts +1 -0
- package/dist/vcs/types.d.ts.map +1 -1
- package/dist/vm-config-6xhsj6b3.js +22 -0
- package/package.json +14 -4
- /package/dist/{index-kbnht9p8.js → index-c9h37r6h.js} +0 -0
|
@@ -26,6 +26,13 @@ function decompose(op) {
|
|
|
26
26
|
const vcs = op.vcs;
|
|
27
27
|
if (!vcs)
|
|
28
28
|
return result;
|
|
29
|
+
if (vcs.issueId && vcs.oldIssueStatus) {
|
|
30
|
+
result.deleteFacts.push({
|
|
31
|
+
e: issueEntityId(vcs.issueId),
|
|
32
|
+
a: "status",
|
|
33
|
+
v: vcs.oldIssueStatus
|
|
34
|
+
});
|
|
35
|
+
}
|
|
29
36
|
switch (op.kind) {
|
|
30
37
|
case "vcs:fileAdd": {
|
|
31
38
|
if (!vcs.filePath)
|
|
@@ -1268,6 +1275,7 @@ async function updateIssue(ctx, id, updates) {
|
|
|
1268
1275
|
issueId: id,
|
|
1269
1276
|
issueTitle: updates.title,
|
|
1270
1277
|
issueDescription: updates.description,
|
|
1278
|
+
oldIssueStatus: updates.status ? getIssueFact(ctx, issueEntityId(id), "status") : undefined,
|
|
1271
1279
|
issueStatus: updates.status,
|
|
1272
1280
|
issuePriority: updates.priority,
|
|
1273
1281
|
issueLabels: updates.labels,
|
|
@@ -1291,6 +1299,7 @@ async function startIssue(ctx, id, branchName) {
|
|
|
1291
1299
|
previousHash: ctx.getLastOp()?.hash,
|
|
1292
1300
|
vcs: {
|
|
1293
1301
|
issueId: id,
|
|
1302
|
+
oldIssueStatus: status,
|
|
1294
1303
|
issueAssignee: ctx.agentId,
|
|
1295
1304
|
branchName
|
|
1296
1305
|
}
|
|
@@ -1310,7 +1319,11 @@ async function pauseIssue(ctx, id, note) {
|
|
|
1310
1319
|
const op = await createVcsOp("vcs:issuePause", {
|
|
1311
1320
|
agentId: ctx.agentId,
|
|
1312
1321
|
previousHash: ctx.getLastOp()?.hash,
|
|
1313
|
-
vcs: {
|
|
1322
|
+
vcs: {
|
|
1323
|
+
issueId: id,
|
|
1324
|
+
oldIssueStatus: status,
|
|
1325
|
+
pauseNote: note.trim()
|
|
1326
|
+
}
|
|
1314
1327
|
});
|
|
1315
1328
|
ctx.applyOp(op);
|
|
1316
1329
|
return op;
|
|
@@ -1324,7 +1337,7 @@ async function resumeIssue(ctx, id) {
|
|
|
1324
1337
|
const op = await createVcsOp("vcs:issueResume", {
|
|
1325
1338
|
agentId: ctx.agentId,
|
|
1326
1339
|
previousHash: ctx.getLastOp()?.hash,
|
|
1327
|
-
vcs: { issueId: id }
|
|
1340
|
+
vcs: { issueId: id, oldIssueStatus: status }
|
|
1328
1341
|
});
|
|
1329
1342
|
ctx.applyOp(op);
|
|
1330
1343
|
return op;
|
|
@@ -1356,7 +1369,7 @@ async function closeIssue(ctx, id, opts) {
|
|
|
1356
1369
|
const op = await createVcsOp("vcs:issueClose", {
|
|
1357
1370
|
agentId: ctx.agentId,
|
|
1358
1371
|
previousHash: ctx.getLastOp()?.hash,
|
|
1359
|
-
vcs: { issueId: id }
|
|
1372
|
+
vcs: { issueId: id, oldIssueStatus: status }
|
|
1360
1373
|
});
|
|
1361
1374
|
ctx.applyOp(op);
|
|
1362
1375
|
if (startedAt) {
|
|
@@ -1376,6 +1389,7 @@ async function triageIssue(ctx, id) {
|
|
|
1376
1389
|
previousHash: ctx.getLastOp()?.hash,
|
|
1377
1390
|
vcs: {
|
|
1378
1391
|
issueId: id,
|
|
1392
|
+
oldIssueStatus: status,
|
|
1379
1393
|
issueStatus: "queue"
|
|
1380
1394
|
}
|
|
1381
1395
|
});
|
|
@@ -1391,7 +1405,7 @@ async function reopenIssue(ctx, id) {
|
|
|
1391
1405
|
const op = await createVcsOp("vcs:issueReopen", {
|
|
1392
1406
|
agentId: ctx.agentId,
|
|
1393
1407
|
previousHash: ctx.getLastOp()?.hash,
|
|
1394
|
-
vcs: { issueId: id }
|
|
1408
|
+
vcs: { issueId: id, oldIssueStatus: status }
|
|
1395
1409
|
});
|
|
1396
1410
|
ctx.applyOp(op);
|
|
1397
1411
|
return op;
|
|
@@ -2,13 +2,299 @@
|
|
|
2
2
|
import {
|
|
3
3
|
EAVStore,
|
|
4
4
|
init_eav_store
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-yhwjgfvj.js";
|
|
6
6
|
import {
|
|
7
7
|
QueryEngine
|
|
8
8
|
} from "./index-yp88he8n.js";
|
|
9
9
|
|
|
10
10
|
// src/core/kernel/trellis-kernel.ts
|
|
11
11
|
init_eav_store();
|
|
12
|
+
|
|
13
|
+
// src/core/ontology/core-ontology.ts
|
|
14
|
+
var VERSION = "1.0.0";
|
|
15
|
+
function f(name, valueType, opts) {
|
|
16
|
+
return { name, valueType, ...opts };
|
|
17
|
+
}
|
|
18
|
+
var thing = {
|
|
19
|
+
"@id": "core:Thing",
|
|
20
|
+
"@type": "trellis:Schema",
|
|
21
|
+
version: VERSION,
|
|
22
|
+
tier: "core",
|
|
23
|
+
label: "Thing",
|
|
24
|
+
icon: "lucide:box",
|
|
25
|
+
fields: [
|
|
26
|
+
f("id", "title", { required: true }),
|
|
27
|
+
f("createdAt", "date"),
|
|
28
|
+
f("updatedAt", "date"),
|
|
29
|
+
f("createdBy", "relation", {
|
|
30
|
+
relation: { targetSchema: "core:Member", cardinality: "one" }
|
|
31
|
+
}),
|
|
32
|
+
f("tags", "multi_select")
|
|
33
|
+
]
|
|
34
|
+
};
|
|
35
|
+
var record = {
|
|
36
|
+
"@id": "core:Record",
|
|
37
|
+
"@type": "trellis:Schema",
|
|
38
|
+
version: VERSION,
|
|
39
|
+
tier: "core",
|
|
40
|
+
subClassOf: "core:Thing",
|
|
41
|
+
label: "Record",
|
|
42
|
+
icon: "lucide:file",
|
|
43
|
+
fields: [
|
|
44
|
+
f("title", "title", { required: true }),
|
|
45
|
+
f("description", "rich_text"),
|
|
46
|
+
f("status", "select"),
|
|
47
|
+
f("tags", "multi_select")
|
|
48
|
+
]
|
|
49
|
+
};
|
|
50
|
+
var document = {
|
|
51
|
+
"@id": "core:Document",
|
|
52
|
+
"@type": "trellis:Schema",
|
|
53
|
+
version: VERSION,
|
|
54
|
+
tier: "core",
|
|
55
|
+
subClassOf: "core:Record",
|
|
56
|
+
label: "Document",
|
|
57
|
+
icon: "lucide:file-text",
|
|
58
|
+
fields: [
|
|
59
|
+
f("content", "rich_text"),
|
|
60
|
+
f("mimeType", "rich_text"),
|
|
61
|
+
f("fileUrl", "url")
|
|
62
|
+
]
|
|
63
|
+
};
|
|
64
|
+
var event = {
|
|
65
|
+
"@id": "core:Event",
|
|
66
|
+
"@type": "trellis:Schema",
|
|
67
|
+
version: VERSION,
|
|
68
|
+
tier: "core",
|
|
69
|
+
subClassOf: "core:Record",
|
|
70
|
+
label: "Event",
|
|
71
|
+
icon: "lucide:calendar",
|
|
72
|
+
fields: [
|
|
73
|
+
f("startDate", "date"),
|
|
74
|
+
f("endDate", "date"),
|
|
75
|
+
f("location", "rich_text"),
|
|
76
|
+
f("allDay", "checkbox")
|
|
77
|
+
]
|
|
78
|
+
};
|
|
79
|
+
var collection = {
|
|
80
|
+
"@id": "core:Collection",
|
|
81
|
+
"@type": "trellis:Schema",
|
|
82
|
+
version: VERSION,
|
|
83
|
+
tier: "core",
|
|
84
|
+
subClassOf: "core:Thing",
|
|
85
|
+
label: "Collection",
|
|
86
|
+
icon: "lucide:database",
|
|
87
|
+
fields: [
|
|
88
|
+
f("title", "title", { required: true }),
|
|
89
|
+
f("description", "rich_text"),
|
|
90
|
+
f("icon", "rich_text"),
|
|
91
|
+
f("schema", "rich_text"),
|
|
92
|
+
f("recordType", "relation", {
|
|
93
|
+
relation: { targetSchema: "core:Record", cardinality: "one" }
|
|
94
|
+
})
|
|
95
|
+
]
|
|
96
|
+
};
|
|
97
|
+
var tag = {
|
|
98
|
+
"@id": "core:Tag",
|
|
99
|
+
"@type": "trellis:Schema",
|
|
100
|
+
version: VERSION,
|
|
101
|
+
tier: "core",
|
|
102
|
+
subClassOf: "core:Thing",
|
|
103
|
+
label: "Tag",
|
|
104
|
+
icon: "lucide:tag",
|
|
105
|
+
fields: [
|
|
106
|
+
f("name", "title", { required: true }),
|
|
107
|
+
f("slug", "rich_text"),
|
|
108
|
+
f("color", "rich_text"),
|
|
109
|
+
f("icon", "rich_text"),
|
|
110
|
+
f("parentTag", "relation", {
|
|
111
|
+
relation: { targetSchema: "core:Tag", cardinality: "one" }
|
|
112
|
+
})
|
|
113
|
+
]
|
|
114
|
+
};
|
|
115
|
+
var workspace = {
|
|
116
|
+
"@id": "core:Workspace",
|
|
117
|
+
"@type": "trellis:Schema",
|
|
118
|
+
version: VERSION,
|
|
119
|
+
tier: "core",
|
|
120
|
+
subClassOf: "core:Thing",
|
|
121
|
+
label: "Workspace",
|
|
122
|
+
icon: "lucide:building-2",
|
|
123
|
+
fields: [
|
|
124
|
+
f("name", "title", { required: true }),
|
|
125
|
+
f("slug", "rich_text"),
|
|
126
|
+
f("avatar", "files"),
|
|
127
|
+
f("plan", "select")
|
|
128
|
+
]
|
|
129
|
+
};
|
|
130
|
+
var app = {
|
|
131
|
+
"@id": "core:App",
|
|
132
|
+
"@type": "trellis:Schema",
|
|
133
|
+
version: VERSION,
|
|
134
|
+
tier: "core",
|
|
135
|
+
subClassOf: "core:Thing",
|
|
136
|
+
label: "App",
|
|
137
|
+
icon: "lucide:layout-grid",
|
|
138
|
+
fields: [
|
|
139
|
+
f("name", "title", { required: true }),
|
|
140
|
+
f("slug", "rich_text"),
|
|
141
|
+
f("icon", "rich_text"),
|
|
142
|
+
f("color", "rich_text"),
|
|
143
|
+
f("description", "rich_text"),
|
|
144
|
+
f("ontologies", "multi_select")
|
|
145
|
+
]
|
|
146
|
+
};
|
|
147
|
+
var member = {
|
|
148
|
+
"@id": "core:Member",
|
|
149
|
+
"@type": "trellis:Schema",
|
|
150
|
+
version: VERSION,
|
|
151
|
+
tier: "core",
|
|
152
|
+
subClassOf: "core:Thing",
|
|
153
|
+
label: "Member",
|
|
154
|
+
icon: "lucide:user",
|
|
155
|
+
fields: [
|
|
156
|
+
f("name", "title", { required: true }),
|
|
157
|
+
f("email", "email"),
|
|
158
|
+
f("avatar", "files"),
|
|
159
|
+
f("role", "select", {
|
|
160
|
+
required: true,
|
|
161
|
+
selectOptions: ["owner", "admin", "member", "guest"],
|
|
162
|
+
defaultValue: "member"
|
|
163
|
+
}),
|
|
164
|
+
f("status", "select", {
|
|
165
|
+
required: true,
|
|
166
|
+
selectOptions: ["pending", "active", "suspended"],
|
|
167
|
+
defaultValue: "pending"
|
|
168
|
+
}),
|
|
169
|
+
f("orgId", "relation", {
|
|
170
|
+
required: true,
|
|
171
|
+
relation: { targetSchema: "core:Workspace", cardinality: "one" }
|
|
172
|
+
}),
|
|
173
|
+
f("userId", "relation", {
|
|
174
|
+
relation: { targetSchema: "core:Person", cardinality: "one" }
|
|
175
|
+
}),
|
|
176
|
+
f("invitedAt", "date"),
|
|
177
|
+
f("joinedAt", "date")
|
|
178
|
+
]
|
|
179
|
+
};
|
|
180
|
+
var notification = {
|
|
181
|
+
"@id": "core:Notification",
|
|
182
|
+
"@type": "trellis:Schema",
|
|
183
|
+
version: VERSION,
|
|
184
|
+
tier: "core",
|
|
185
|
+
subClassOf: "core:Thing",
|
|
186
|
+
label: "Notification",
|
|
187
|
+
icon: "lucide:bell",
|
|
188
|
+
fields: [
|
|
189
|
+
f("recipientId", "relation", {
|
|
190
|
+
required: true,
|
|
191
|
+
relation: { targetSchema: "core:Person", cardinality: "one" }
|
|
192
|
+
}),
|
|
193
|
+
f("orgId", "relation", {
|
|
194
|
+
relation: { targetSchema: "core:Workspace", cardinality: "one" }
|
|
195
|
+
}),
|
|
196
|
+
f("orgName", "rich_text"),
|
|
197
|
+
f("type", "select", {
|
|
198
|
+
required: true,
|
|
199
|
+
selectOptions: [
|
|
200
|
+
"invite_accepted",
|
|
201
|
+
"invite_sent",
|
|
202
|
+
"member_joined",
|
|
203
|
+
"member_removed",
|
|
204
|
+
"role_changed",
|
|
205
|
+
"mention",
|
|
206
|
+
"comment",
|
|
207
|
+
"entity_updated",
|
|
208
|
+
"system"
|
|
209
|
+
]
|
|
210
|
+
}),
|
|
211
|
+
f("title", "title", { required: true }),
|
|
212
|
+
f("message", "rich_text", { required: true }),
|
|
213
|
+
f("actionUrl", "url"),
|
|
214
|
+
f("icon", "rich_text"),
|
|
215
|
+
f("variant", "select", {
|
|
216
|
+
selectOptions: ["default", "success", "warning", "destructive", "info"]
|
|
217
|
+
}),
|
|
218
|
+
f("isRead", "checkbox", { defaultValue: false }),
|
|
219
|
+
f("actorId", "relation", {
|
|
220
|
+
relation: { targetSchema: "core:Person", cardinality: "one" }
|
|
221
|
+
}),
|
|
222
|
+
f("actorName", "rich_text"),
|
|
223
|
+
f("metadata", "rich_text"),
|
|
224
|
+
f("createdAt", "date", { required: true })
|
|
225
|
+
]
|
|
226
|
+
};
|
|
227
|
+
var share = {
|
|
228
|
+
"@id": "core:Share",
|
|
229
|
+
"@type": "trellis:Schema",
|
|
230
|
+
version: VERSION,
|
|
231
|
+
tier: "core",
|
|
232
|
+
subClassOf: "core:Thing",
|
|
233
|
+
label: "Share",
|
|
234
|
+
icon: "lucide:share-2",
|
|
235
|
+
fields: [
|
|
236
|
+
f("entityId", "relation", { required: true }),
|
|
237
|
+
f("entityType", "select", { selectOptions: ["entity", "collection"] }),
|
|
238
|
+
f("userId", "relation", {
|
|
239
|
+
required: true,
|
|
240
|
+
relation: { targetSchema: "core:Person", cardinality: "one" }
|
|
241
|
+
}),
|
|
242
|
+
f("orgId", "relation", {
|
|
243
|
+
relation: { targetSchema: "core:Workspace", cardinality: "one" }
|
|
244
|
+
}),
|
|
245
|
+
f("permission", "select", {
|
|
246
|
+
required: true,
|
|
247
|
+
selectOptions: ["view", "comment", "edit"],
|
|
248
|
+
defaultValue: "view"
|
|
249
|
+
}),
|
|
250
|
+
f("sharedBy", "relation", {
|
|
251
|
+
relation: { targetSchema: "core:Person", cardinality: "one" }
|
|
252
|
+
}),
|
|
253
|
+
f("createdAt", "date", { required: true })
|
|
254
|
+
]
|
|
255
|
+
};
|
|
256
|
+
var person = {
|
|
257
|
+
"@id": "core:Person",
|
|
258
|
+
"@type": "trellis:Schema",
|
|
259
|
+
version: VERSION,
|
|
260
|
+
tier: "core",
|
|
261
|
+
subClassOf: "core:Thing",
|
|
262
|
+
label: "Person",
|
|
263
|
+
icon: "lucide:user",
|
|
264
|
+
fields: [f("name", "title", { required: true })]
|
|
265
|
+
};
|
|
266
|
+
var workflow = {
|
|
267
|
+
"@id": "core:Workflow",
|
|
268
|
+
"@type": "trellis:Schema",
|
|
269
|
+
version: VERSION,
|
|
270
|
+
tier: "core",
|
|
271
|
+
subClassOf: "core:Thing",
|
|
272
|
+
label: "Workflow",
|
|
273
|
+
icon: "lucide:git-branch",
|
|
274
|
+
fields: [
|
|
275
|
+
f("name", "title", { required: true }),
|
|
276
|
+
f("trigger", "rich_text"),
|
|
277
|
+
f("steps", "multi_select"),
|
|
278
|
+
f("active", "checkbox")
|
|
279
|
+
]
|
|
280
|
+
};
|
|
281
|
+
var CORE_ONTOLOGY = [
|
|
282
|
+
thing,
|
|
283
|
+
record,
|
|
284
|
+
document,
|
|
285
|
+
event,
|
|
286
|
+
collection,
|
|
287
|
+
tag,
|
|
288
|
+
workspace,
|
|
289
|
+
app,
|
|
290
|
+
member,
|
|
291
|
+
notification,
|
|
292
|
+
share,
|
|
293
|
+
person,
|
|
294
|
+
workflow
|
|
295
|
+
];
|
|
296
|
+
|
|
297
|
+
// src/core/kernel/trellis-kernel.ts
|
|
12
298
|
async function hashOp(kind, timestamp, agentId, previousHash, payload) {
|
|
13
299
|
const data = `${kind}|${timestamp}|${agentId}|${previousHash ?? ""}|${payload}`;
|
|
14
300
|
const buf = new TextEncoder().encode(data);
|
|
@@ -25,15 +311,26 @@ class TrellisKernel {
|
|
|
25
311
|
snapshotThreshold;
|
|
26
312
|
opsSinceSnapshot = 0;
|
|
27
313
|
_booted = false;
|
|
314
|
+
ontologies = new Map;
|
|
315
|
+
workspaceConfig = null;
|
|
316
|
+
autoReplay = true;
|
|
28
317
|
constructor(config) {
|
|
29
318
|
this.store = new EAVStore;
|
|
30
319
|
this.backend = config.backend;
|
|
31
320
|
this.agentId = config.agentId;
|
|
32
321
|
this.middleware = config.middleware ?? [];
|
|
33
322
|
this.snapshotThreshold = config.snapshotThreshold ?? 0;
|
|
323
|
+
this.autoReplay = config.autoReplay ?? true;
|
|
324
|
+
for (const schema of CORE_ONTOLOGY) {
|
|
325
|
+
this.ontologies.set(schema["@id"], schema);
|
|
326
|
+
}
|
|
34
327
|
}
|
|
35
328
|
boot() {
|
|
36
329
|
this.backend.init();
|
|
330
|
+
if (!this.autoReplay) {
|
|
331
|
+
this._booted = true;
|
|
332
|
+
return { opsReplayed: 0, fromSnapshot: false };
|
|
333
|
+
}
|
|
37
334
|
let opsReplayed = 0;
|
|
38
335
|
let fromSnapshot = false;
|
|
39
336
|
const snapshot = this.backend.loadLatestSnapshot();
|
|
@@ -204,7 +501,7 @@ class TrellisKernel {
|
|
|
204
501
|
const facts = this.store.getFactsByEntity(entityId);
|
|
205
502
|
if (facts.length === 0)
|
|
206
503
|
return null;
|
|
207
|
-
const typeFact = facts.find((
|
|
504
|
+
const typeFact = facts.find((f2) => f2.a === "type");
|
|
208
505
|
return {
|
|
209
506
|
id: entityId,
|
|
210
507
|
type: typeFact?.v ?? "unknown",
|
|
@@ -217,11 +514,11 @@ class TrellisKernel {
|
|
|
217
514
|
const deleteFacts = [];
|
|
218
515
|
const addFacts = [];
|
|
219
516
|
for (const [attr, newValue] of Object.entries(updates)) {
|
|
220
|
-
const existing = existingFacts.filter((
|
|
517
|
+
const existing = existingFacts.filter((f2) => f2.a === attr);
|
|
221
518
|
deleteFacts.push(...existing);
|
|
222
519
|
addFacts.push({ e: entityId, a: attr, v: newValue });
|
|
223
520
|
}
|
|
224
|
-
const updatedAtFacts = existingFacts.filter((
|
|
521
|
+
const updatedAtFacts = existingFacts.filter((f2) => f2.a === "updatedAt");
|
|
225
522
|
deleteFacts.push(...updatedAtFacts);
|
|
226
523
|
addFacts.push({ e: entityId, a: "updatedAt", v: new Date().toISOString() });
|
|
227
524
|
return this.mutate("addFacts", {
|
|
@@ -241,15 +538,15 @@ class TrellisKernel {
|
|
|
241
538
|
let entityIds;
|
|
242
539
|
if (type) {
|
|
243
540
|
const typeFacts = this.store.getFactsByValue("type", type);
|
|
244
|
-
entityIds = new Set(typeFacts.map((
|
|
541
|
+
entityIds = new Set(typeFacts.map((f2) => f2.e));
|
|
245
542
|
} else {
|
|
246
543
|
const allTypeFacts = this.store.getFactsByAttribute("type");
|
|
247
|
-
entityIds = new Set(allTypeFacts.map((
|
|
544
|
+
entityIds = new Set(allTypeFacts.map((f2) => f2.e));
|
|
248
545
|
}
|
|
249
546
|
if (filters) {
|
|
250
547
|
for (const [attr, value] of Object.entries(filters)) {
|
|
251
548
|
const matchingFacts = this.store.getFactsByValue(attr, value);
|
|
252
|
-
const matchingEntities = new Set(matchingFacts.map((
|
|
549
|
+
const matchingEntities = new Set(matchingFacts.map((f2) => f2.e));
|
|
253
550
|
for (const id of entityIds) {
|
|
254
551
|
if (!matchingEntities.has(id)) {
|
|
255
552
|
entityIds.delete(id);
|
|
@@ -279,6 +576,163 @@ class TrellisKernel {
|
|
|
279
576
|
deleteFacts: [{ e: entityId, a: attribute, v: value }]
|
|
280
577
|
});
|
|
281
578
|
}
|
|
579
|
+
getOntology(id) {
|
|
580
|
+
return this.ontologies.get(id);
|
|
581
|
+
}
|
|
582
|
+
listOntologies() {
|
|
583
|
+
return Array.from(this.ontologies.values());
|
|
584
|
+
}
|
|
585
|
+
createOntology(schema) {
|
|
586
|
+
const tier = schema.tier ?? "user";
|
|
587
|
+
if (tier === "core") {
|
|
588
|
+
throw new Error("Cannot modify core ontologies");
|
|
589
|
+
}
|
|
590
|
+
if (this.ontologies.has(schema["@id"])) {
|
|
591
|
+
throw new Error(`Ontology ${schema["@id"]} already exists`);
|
|
592
|
+
}
|
|
593
|
+
this.ontologies.set(schema["@id"], schema);
|
|
594
|
+
const fact = {
|
|
595
|
+
e: schema["@id"],
|
|
596
|
+
a: "schema",
|
|
597
|
+
v: JSON.stringify(schema)
|
|
598
|
+
};
|
|
599
|
+
this.store.addFacts([fact]);
|
|
600
|
+
}
|
|
601
|
+
updateOntology(id, updates) {
|
|
602
|
+
const existing = this.ontologies.get(id);
|
|
603
|
+
if (!existing) {
|
|
604
|
+
throw new Error(`Ontology ${id} not found`);
|
|
605
|
+
}
|
|
606
|
+
const tier = existing.tier ?? "user";
|
|
607
|
+
if (tier === "core") {
|
|
608
|
+
throw new Error("Cannot modify core ontologies");
|
|
609
|
+
}
|
|
610
|
+
const updated = { ...existing, ...updates };
|
|
611
|
+
this.ontologies.set(id, updated);
|
|
612
|
+
const existingFacts = this.store.getFactsByEntity(id);
|
|
613
|
+
const schemaFacts = existingFacts.filter((f2) => f2.a === "schema");
|
|
614
|
+
const deleteFacts = [...schemaFacts];
|
|
615
|
+
const addFacts = [
|
|
616
|
+
{
|
|
617
|
+
e: id,
|
|
618
|
+
a: "schema",
|
|
619
|
+
v: JSON.stringify(updated)
|
|
620
|
+
}
|
|
621
|
+
];
|
|
622
|
+
this.store.deleteFacts(deleteFacts);
|
|
623
|
+
this.store.addFacts(addFacts);
|
|
624
|
+
}
|
|
625
|
+
deleteOntology(id) {
|
|
626
|
+
const existing = this.ontologies.get(id);
|
|
627
|
+
if (!existing) {
|
|
628
|
+
throw new Error(`Ontology ${id} not found`);
|
|
629
|
+
}
|
|
630
|
+
const tier = existing.tier ?? "user";
|
|
631
|
+
if (tier === "core") {
|
|
632
|
+
throw new Error("Cannot delete core ontologies");
|
|
633
|
+
}
|
|
634
|
+
this.ontologies.delete(id);
|
|
635
|
+
const facts = this.store.getFactsByEntity(id);
|
|
636
|
+
this.store.deleteFacts(facts);
|
|
637
|
+
}
|
|
638
|
+
bootWorkspace(config) {
|
|
639
|
+
this.workspaceConfig = config;
|
|
640
|
+
if (config.workspace.ontologies) {
|
|
641
|
+
for (const [id, schema] of Object.entries(config.workspace.ontologies)) {
|
|
642
|
+
if (!this.ontologies.has(id)) {
|
|
643
|
+
this.ontologies.set(id, schema);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
if (config.workspace.graph?.nodes) {
|
|
648
|
+
for (const node of config.workspace.graph.nodes) {
|
|
649
|
+
const n = node;
|
|
650
|
+
if (n.id && n.type) {
|
|
651
|
+
const facts = [
|
|
652
|
+
{ e: String(n.id), a: "type", v: String(n.type) }
|
|
653
|
+
];
|
|
654
|
+
for (const [key, value] of Object.entries(n)) {
|
|
655
|
+
if (key !== "id" && key !== "type") {
|
|
656
|
+
facts.push({ e: String(n.id), a: key, v: value });
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
this.store.addFacts(facts);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
if (config.workspace.graph?.edges) {
|
|
664
|
+
for (const edge of config.workspace.graph.edges) {
|
|
665
|
+
const e = edge;
|
|
666
|
+
if (e.source && e.target && e.relation) {
|
|
667
|
+
this.store.addLinks([
|
|
668
|
+
{
|
|
669
|
+
e1: String(e.source),
|
|
670
|
+
a: String(e.relation),
|
|
671
|
+
e2: String(e.target)
|
|
672
|
+
}
|
|
673
|
+
]);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
this.boot();
|
|
678
|
+
}
|
|
679
|
+
exportWorkspace() {
|
|
680
|
+
const ontologies = {};
|
|
681
|
+
for (const [id, schema] of this.ontologies) {
|
|
682
|
+
if (schema.tier !== "core") {
|
|
683
|
+
ontologies[id] = schema;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
const allFacts = this.store.getAllFacts();
|
|
687
|
+
const nodes = [];
|
|
688
|
+
const entityIds = new Set(allFacts.map((f2) => f2.e));
|
|
689
|
+
for (const id of entityIds) {
|
|
690
|
+
const facts = this.store.getFactsByEntity(id);
|
|
691
|
+
const typeFact = facts.find((f2) => f2.a === "type");
|
|
692
|
+
const node = { id };
|
|
693
|
+
if (typeFact) {
|
|
694
|
+
node.type = typeFact.v;
|
|
695
|
+
}
|
|
696
|
+
for (const fact of facts) {
|
|
697
|
+
if (fact.a !== "type") {
|
|
698
|
+
node[fact.a] = fact.v;
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
nodes.push(node);
|
|
702
|
+
}
|
|
703
|
+
const allLinks = this.store.getAllLinks();
|
|
704
|
+
const edges = allLinks.map((l) => ({
|
|
705
|
+
source: l.e1,
|
|
706
|
+
relation: l.a,
|
|
707
|
+
target: l.e2
|
|
708
|
+
}));
|
|
709
|
+
return {
|
|
710
|
+
workspace: {
|
|
711
|
+
name: this.workspaceConfig?.workspace.name,
|
|
712
|
+
description: this.workspaceConfig?.workspace.description,
|
|
713
|
+
ontologies: Object.keys(ontologies).length > 0 ? ontologies : undefined,
|
|
714
|
+
graph: { nodes, edges },
|
|
715
|
+
projections: this.workspaceConfig?.workspace.projections,
|
|
716
|
+
routes: this.workspaceConfig?.workspace.routes,
|
|
717
|
+
app: this.workspaceConfig?.workspace.app
|
|
718
|
+
}
|
|
719
|
+
};
|
|
720
|
+
}
|
|
721
|
+
async createNode(id, data, type, _ctx) {
|
|
722
|
+
return this.createEntity(id, type, data);
|
|
723
|
+
}
|
|
724
|
+
async updateNode(id, data, type, _ctx) {
|
|
725
|
+
return this.updateEntity(id, data);
|
|
726
|
+
}
|
|
727
|
+
async deleteNode(id, _ctx) {
|
|
728
|
+
return this.deleteEntity(id);
|
|
729
|
+
}
|
|
730
|
+
async link(e1, a, e2, _ctx) {
|
|
731
|
+
return this.addLink(e1, a, e2);
|
|
732
|
+
}
|
|
733
|
+
async unlink(e1, a, e2, _ctx) {
|
|
734
|
+
return this.removeLink(e1, a, e2);
|
|
735
|
+
}
|
|
282
736
|
addMiddleware(mw) {
|
|
283
737
|
this.middleware.push(mw);
|
|
284
738
|
}
|
|
@@ -456,6 +910,12 @@ class SqliteKernelBackend {
|
|
|
456
910
|
const row = this._stmts.getLast.get();
|
|
457
911
|
return row ? rowToOp(row) : undefined;
|
|
458
912
|
}
|
|
913
|
+
getByHash(hash) {
|
|
914
|
+
return this.getOpByHash(hash);
|
|
915
|
+
}
|
|
916
|
+
getOpCount() {
|
|
917
|
+
return this.count();
|
|
918
|
+
}
|
|
459
919
|
getOpByHash(hash) {
|
|
460
920
|
const row = this._stmts.getByHash.get({ $hash: hash });
|
|
461
921
|
return row ? rowToOp(row) : undefined;
|
|
@@ -496,6 +496,39 @@ async function route(req, url, path, auth, tenantId, ctx) {
|
|
|
496
496
|
headers: { "Content-Type": "application/javascript" }
|
|
497
497
|
});
|
|
498
498
|
}
|
|
499
|
+
if (method === "GET" && path === "/__trellis/trellis.css") {
|
|
500
|
+
const candidates = [
|
|
501
|
+
join(import.meta.dir, "db", "trellis.css"),
|
|
502
|
+
join(import.meta.dir, "trellis.css")
|
|
503
|
+
];
|
|
504
|
+
for (const p of candidates) {
|
|
505
|
+
if (existsSync(p)) {
|
|
506
|
+
return new Response(readFileSync(p, "utf-8"), {
|
|
507
|
+
headers: { "Content-Type": "text/css; charset=utf-8" }
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
return new Response("/* Trellis CSS not found */", {
|
|
512
|
+
headers: { "Content-Type": "text/css" }
|
|
513
|
+
});
|
|
514
|
+
}
|
|
515
|
+
if (method === "GET" && (path === "/" || path === "/inspector")) {
|
|
516
|
+
const html = `<!DOCTYPE html>
|
|
517
|
+
<html lang="en">
|
|
518
|
+
<head>
|
|
519
|
+
<meta charset="UTF-8">
|
|
520
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
521
|
+
<title>Trellis DB Inspector</title>
|
|
522
|
+
<link rel="stylesheet" href="/__trellis/trellis.css">
|
|
523
|
+
</head>
|
|
524
|
+
<body>
|
|
525
|
+
<script src="/__trellis/inspector.js"></script>
|
|
526
|
+
</body>
|
|
527
|
+
</html>`;
|
|
528
|
+
return new Response(html, {
|
|
529
|
+
headers: { "Content-Type": "text/html; charset=utf-8" }
|
|
530
|
+
});
|
|
531
|
+
}
|
|
499
532
|
if (method === "GET" && path === "/health") {
|
|
500
533
|
const kernel = ctx.pool.get(tenantId);
|
|
501
534
|
const ops = kernel.readAllOps().length;
|