trellis 1.0.8 → 2.0.5
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/LICENSE +21 -0
- package/README.md +533 -82
- package/bin/trellis.mjs +2 -0
- package/dist/cli/index.js +4718 -0
- package/dist/core/index.js +12 -0
- package/dist/decisions/index.js +19 -0
- package/dist/embeddings/index.js +43 -0
- package/dist/index-1j1anhmr.js +4038 -0
- package/dist/index-3s0eak0p.js +1556 -0
- package/dist/index-8pce39mh.js +272 -0
- package/dist/index-a76rekgs.js +67 -0
- package/dist/index-cy9k1g6v.js +684 -0
- package/dist/index-fd4e26s4.js +69 -0
- package/dist/{store/eav-store.js → index-gkvhzm9f.js} +4 -6
- package/dist/index-gnw8d7d6.js +51 -0
- package/dist/index-vkpkfwhq.js +817 -0
- package/dist/index.js +118 -2876
- package/dist/links/index.js +55 -0
- package/dist/transformers-m9je15kg.js +32491 -0
- package/dist/vcs/index.js +110 -0
- package/logo.png +0 -0
- package/logo.svg +9 -0
- package/package.json +79 -76
- package/src/cli/index.ts +2340 -0
- package/src/core/index.ts +35 -0
- package/src/core/kernel/middleware.ts +44 -0
- package/src/core/persist/backend.ts +64 -0
- package/src/core/store/eav-store.ts +467 -0
- package/src/decisions/auto-capture.ts +136 -0
- package/src/decisions/hooks.ts +163 -0
- package/src/decisions/index.ts +261 -0
- package/src/decisions/types.ts +103 -0
- package/src/embeddings/chunker.ts +327 -0
- package/src/embeddings/index.ts +41 -0
- package/src/embeddings/model.ts +95 -0
- package/src/embeddings/search.ts +305 -0
- package/src/embeddings/store.ts +313 -0
- package/src/embeddings/types.ts +85 -0
- package/src/engine.ts +1083 -0
- package/src/garden/cluster.ts +330 -0
- package/src/garden/garden.ts +306 -0
- package/src/garden/index.ts +29 -0
- package/src/git/git-exporter.ts +286 -0
- package/src/git/git-importer.ts +329 -0
- package/src/git/git-reader.ts +189 -0
- package/src/git/index.ts +22 -0
- package/src/identity/governance.ts +211 -0
- package/src/identity/identity.ts +224 -0
- package/src/identity/index.ts +30 -0
- package/src/identity/signing-middleware.ts +97 -0
- package/src/index.ts +20 -0
- package/src/links/index.ts +49 -0
- package/src/links/lifecycle.ts +400 -0
- package/src/links/parser.ts +484 -0
- package/src/links/ref-index.ts +186 -0
- package/src/links/resolver.ts +314 -0
- package/src/links/types.ts +108 -0
- package/src/mcp/index.ts +22 -0
- package/src/mcp/server.ts +1278 -0
- package/src/semantic/csharp-parser.ts +493 -0
- package/src/semantic/go-parser.ts +585 -0
- package/src/semantic/index.ts +34 -0
- package/src/semantic/java-parser.ts +456 -0
- package/src/semantic/python-parser.ts +659 -0
- package/src/semantic/ruby-parser.ts +446 -0
- package/src/semantic/rust-parser.ts +784 -0
- package/src/semantic/semantic-merge.ts +210 -0
- package/src/semantic/ts-parser.ts +681 -0
- package/src/semantic/types.ts +175 -0
- package/src/sync/index.ts +32 -0
- package/src/sync/memory-transport.ts +66 -0
- package/src/sync/reconciler.ts +237 -0
- package/src/sync/sync-engine.ts +258 -0
- package/src/sync/types.ts +104 -0
- package/src/vcs/blob-store.ts +124 -0
- package/src/vcs/branch.ts +150 -0
- package/src/vcs/checkpoint.ts +64 -0
- package/src/vcs/decompose.ts +469 -0
- package/src/vcs/diff.ts +409 -0
- package/src/vcs/engine-context.ts +26 -0
- package/src/vcs/index.ts +23 -0
- package/src/vcs/issue.ts +800 -0
- package/src/vcs/merge.ts +425 -0
- package/src/vcs/milestone.ts +124 -0
- package/src/vcs/ops.ts +59 -0
- package/src/vcs/types.ts +213 -0
- package/src/vcs/vcs-middleware.ts +81 -0
- package/src/watcher/fs-watcher.ts +217 -0
- package/src/watcher/index.ts +9 -0
- package/src/watcher/ingestion.ts +116 -0
- package/dist/ai/index.js +0 -688
- package/dist/cli/server.js +0 -3321
- package/dist/cli/tql.js +0 -5282
- package/dist/client/tql-client.js +0 -108
- package/dist/graph/index.js +0 -2248
- package/dist/kernel/logic-middleware.js +0 -179
- package/dist/kernel/middleware.js +0 -0
- package/dist/kernel/operations.js +0 -32
- package/dist/kernel/schema-middleware.js +0 -34
- package/dist/kernel/security-middleware.js +0 -53
- package/dist/kernel/trellis-kernel.js +0 -2239
- package/dist/kernel/workspace.js +0 -91
- package/dist/persist/backend.js +0 -0
- package/dist/persist/sqlite-backend.js +0 -123
- package/dist/query/index.js +0 -1643
- package/dist/server/index.js +0 -3309
- package/dist/workflows/index.js +0 -3160
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
// src/kernel/logic-middleware.ts
|
|
2
|
-
class LogicMiddleware {
|
|
3
|
-
provider;
|
|
4
|
-
store;
|
|
5
|
-
aiProvider;
|
|
6
|
-
name = "logic-layer";
|
|
7
|
-
constructor(provider, store, aiProvider) {
|
|
8
|
-
this.provider = provider;
|
|
9
|
-
this.store = store;
|
|
10
|
-
this.aiProvider = aiProvider;
|
|
11
|
-
}
|
|
12
|
-
async handleQuery(query, ctx, next) {
|
|
13
|
-
const result = await next(query, ctx);
|
|
14
|
-
if (typeof query !== "string" || !result.rows || result.rows.length === 0) {
|
|
15
|
-
return result;
|
|
16
|
-
}
|
|
17
|
-
const enrichedRows = [...result.rows];
|
|
18
|
-
let changed = false;
|
|
19
|
-
for (let i = 0;i < enrichedRows.length; i++) {
|
|
20
|
-
const row = enrichedRows[i];
|
|
21
|
-
const entityType = this.extractEntityType(row);
|
|
22
|
-
if (!entityType)
|
|
23
|
-
continue;
|
|
24
|
-
const schema = this.provider.getOntology(`trellis:schema/${entityType.toLowerCase()}`);
|
|
25
|
-
if (!schema)
|
|
26
|
-
continue;
|
|
27
|
-
const virtualAttrs = schema.fields.filter((f) => f.valueType === "formula" || f.valueType === "rollup" || f.valueType === "ai_generated");
|
|
28
|
-
if (virtualAttrs.length > 0) {
|
|
29
|
-
const enrichedRow = { ...row };
|
|
30
|
-
for (const attr of virtualAttrs) {
|
|
31
|
-
if (attr.valueType === "formula" && attr.formula) {
|
|
32
|
-
const val = this.evaluateFormula(attr.formula, enrichedRow);
|
|
33
|
-
if (val !== undefined) {
|
|
34
|
-
const prefix = this.getVarPrefix(row);
|
|
35
|
-
if (prefix) {
|
|
36
|
-
enrichedRow[`${prefix}.${attr.name}`] = val;
|
|
37
|
-
}
|
|
38
|
-
enrichedRow[attr.name] = val;
|
|
39
|
-
changed = true;
|
|
40
|
-
}
|
|
41
|
-
} else if (attr.valueType === "rollup" && attr.rollup) {
|
|
42
|
-
const val = this.evaluateRollup(attr.rollup, enrichedRow);
|
|
43
|
-
if (val !== undefined) {
|
|
44
|
-
const prefix = this.getVarPrefix(row);
|
|
45
|
-
if (prefix) {
|
|
46
|
-
enrichedRow[`${prefix}.${attr.name}`] = val;
|
|
47
|
-
}
|
|
48
|
-
enrichedRow[attr.name] = val;
|
|
49
|
-
changed = true;
|
|
50
|
-
}
|
|
51
|
-
} else if (attr.valueType === "ai_generated" && attr.aiGenerated && this.aiProvider) {
|
|
52
|
-
const val = await this.evaluateAIGenerated(attr.aiGenerated, enrichedRow);
|
|
53
|
-
if (val !== undefined) {
|
|
54
|
-
const prefix = this.getVarPrefix(row);
|
|
55
|
-
if (prefix) {
|
|
56
|
-
enrichedRow[`${prefix}.${attr.name}`] = val;
|
|
57
|
-
}
|
|
58
|
-
enrichedRow[attr.name] = val;
|
|
59
|
-
changed = true;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
enrichedRows[i] = enrichedRow;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
return changed ? { ...result, rows: enrichedRows } : result;
|
|
67
|
-
}
|
|
68
|
-
async evaluateAIGenerated(aiConfig, row) {
|
|
69
|
-
if (!this.aiProvider)
|
|
70
|
-
return;
|
|
71
|
-
const cleanRow = this.getCleanRow(row);
|
|
72
|
-
return this.aiProvider.generate(aiConfig.prompt, cleanRow);
|
|
73
|
-
}
|
|
74
|
-
extractEntityType(row) {
|
|
75
|
-
for (const key of Object.keys(row)) {
|
|
76
|
-
if (key === "type" || key.endsWith(".type")) {
|
|
77
|
-
return row[key];
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
getVarPrefix(row) {
|
|
83
|
-
for (const key of Object.keys(row)) {
|
|
84
|
-
if (key.startsWith("?") && key.includes(".")) {
|
|
85
|
-
return key.split(".")[0];
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
getCleanRow(row) {
|
|
91
|
-
const cleanRow = {};
|
|
92
|
-
for (const [k, v] of Object.entries(row)) {
|
|
93
|
-
const cleanKey = k.includes(".") ? k.split(".").pop() : k;
|
|
94
|
-
cleanRow[cleanKey] = v;
|
|
95
|
-
}
|
|
96
|
-
return cleanRow;
|
|
97
|
-
}
|
|
98
|
-
evaluateRollup(rollup, row) {
|
|
99
|
-
const entityId = row["@id"] || row["id"] || row[this.getVarPrefix(row) + ".@id"];
|
|
100
|
-
if (!entityId)
|
|
101
|
-
return;
|
|
102
|
-
const links = this.store.getLinksByEntityAndAttribute(entityId, rollup.relationProperty);
|
|
103
|
-
const targetEntities = links.map((l) => l.e2);
|
|
104
|
-
if (rollup.aggregation === "count") {
|
|
105
|
-
return targetEntities.length;
|
|
106
|
-
}
|
|
107
|
-
const values = [];
|
|
108
|
-
for (const targetId of targetEntities) {
|
|
109
|
-
const facts = this.store.getFactsByEntity(targetId);
|
|
110
|
-
const targetFact = facts.find((f) => f.a === rollup.targetProperty);
|
|
111
|
-
if (targetFact) {
|
|
112
|
-
values.push(targetFact.v);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
if (values.length === 0)
|
|
116
|
-
return 0;
|
|
117
|
-
switch (rollup.aggregation) {
|
|
118
|
-
case "sum":
|
|
119
|
-
return values.reduce((a, b) => typeof b === "number" ? a + b : a, 0);
|
|
120
|
-
case "avg":
|
|
121
|
-
const sum = values.reduce((a, b) => typeof b === "number" ? a + b : a, 0);
|
|
122
|
-
return sum / values.length;
|
|
123
|
-
case "min":
|
|
124
|
-
return Math.min(...values.filter((v) => typeof v === "number"));
|
|
125
|
-
case "max":
|
|
126
|
-
return Math.max(...values.filter((v) => typeof v === "number"));
|
|
127
|
-
case "median":
|
|
128
|
-
const nums = values.filter((v) => typeof v === "number").sort((a, b) => a - b);
|
|
129
|
-
if (nums.length === 0)
|
|
130
|
-
return 0;
|
|
131
|
-
const mid = Math.floor(nums.length / 2);
|
|
132
|
-
return nums.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
|
|
133
|
-
case "mode":
|
|
134
|
-
if (values.length === 0)
|
|
135
|
-
return;
|
|
136
|
-
const counts = new Map;
|
|
137
|
-
let maxCount = 0;
|
|
138
|
-
let mode = values[0];
|
|
139
|
-
for (const v of values) {
|
|
140
|
-
const count = (counts.get(v) || 0) + 1;
|
|
141
|
-
counts.set(v, count);
|
|
142
|
-
if (count > maxCount) {
|
|
143
|
-
maxCount = count;
|
|
144
|
-
mode = v;
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
return mode;
|
|
148
|
-
default:
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
evaluateFormula(formula, row) {
|
|
153
|
-
try {
|
|
154
|
-
const cleanRow = this.getCleanRow(row);
|
|
155
|
-
let expr = formula;
|
|
156
|
-
expr = expr.replace(/\$if\((.*?), (.*?), (.*?)\)/g, "($1 ? $2 : $3)");
|
|
157
|
-
expr = expr.replace(/\$concat\((.*?)\)/g, (match, args) => {
|
|
158
|
-
return args.split(",").map((a) => a.trim()).join(" + ");
|
|
159
|
-
});
|
|
160
|
-
const tokens = expr.split(/([-+*/()<>!=&|?, ]+)/).filter((t) => t.trim().length > 0);
|
|
161
|
-
for (const token of tokens) {
|
|
162
|
-
if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(token) && !["true", "false", "null", "undefined"].includes(token)) {
|
|
163
|
-
const val = cleanRow[token];
|
|
164
|
-
if (val !== undefined) {
|
|
165
|
-
const stringified = typeof val === "string" ? `"${val.replace(/"/g, "\\\"")}"` : String(val);
|
|
166
|
-
expr = expr.replace(new RegExp(`\\b${token}\\b`, "g"), stringified);
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
return new Function(`return (${expr})`)();
|
|
171
|
-
} catch (e) {
|
|
172
|
-
console.warn(`[logic] Formula evaluation failed: ${formula}`, e);
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
export {
|
|
178
|
-
LogicMiddleware
|
|
179
|
-
};
|
|
File without changes
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
// src/kernel/operations.ts
|
|
2
|
-
async function hashOp(op) {
|
|
3
|
-
const content = JSON.stringify({
|
|
4
|
-
kind: op.kind,
|
|
5
|
-
timestamp: op.timestamp,
|
|
6
|
-
agentId: op.agentId,
|
|
7
|
-
previousHash: op.previousHash,
|
|
8
|
-
facts: op.facts,
|
|
9
|
-
links: op.links
|
|
10
|
-
});
|
|
11
|
-
const msgUint8 = new TextEncoder().encode(content);
|
|
12
|
-
const hashBuffer = await crypto.subtle.digest("SHA-256", msgUint8);
|
|
13
|
-
const hashArray = Array.from(new Uint8Array(hashBuffer));
|
|
14
|
-
const hashHex = hashArray.map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
15
|
-
return `trellis:op:${hashHex}`;
|
|
16
|
-
}
|
|
17
|
-
async function createOp(kind, params) {
|
|
18
|
-
const opBase = {
|
|
19
|
-
kind,
|
|
20
|
-
timestamp: new Date().toISOString(),
|
|
21
|
-
agentId: params.agentId,
|
|
22
|
-
previousHash: params.previousHash,
|
|
23
|
-
facts: params.facts,
|
|
24
|
-
links: params.links
|
|
25
|
-
};
|
|
26
|
-
const hash = await hashOp(opBase);
|
|
27
|
-
return { ...opBase, hash };
|
|
28
|
-
}
|
|
29
|
-
export {
|
|
30
|
-
hashOp,
|
|
31
|
-
createOp
|
|
32
|
-
};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
// src/kernel/schema-middleware.ts
|
|
2
|
-
class SchemaMiddleware {
|
|
3
|
-
provider;
|
|
4
|
-
name = "schema-enforcement";
|
|
5
|
-
constructor(provider) {
|
|
6
|
-
this.provider = provider;
|
|
7
|
-
}
|
|
8
|
-
async handleOp(op, ctx, next) {
|
|
9
|
-
if (ctx.system || ctx.remote) {
|
|
10
|
-
return next(op, ctx);
|
|
11
|
-
}
|
|
12
|
-
if (op.kind === "addFacts" && op.facts) {
|
|
13
|
-
const typeFact = op.facts.find((f) => f.a === "type");
|
|
14
|
-
if (typeFact && typeof typeFact.v === "string") {
|
|
15
|
-
const type = typeFact.v;
|
|
16
|
-
const schema = this.provider.getOntology(`trellis:schema/${type.toLowerCase()}`);
|
|
17
|
-
if (schema) {
|
|
18
|
-
const allowedFields = new Set(schema.fields.map((f) => f.name));
|
|
19
|
-
allowedFields.add("type");
|
|
20
|
-
allowedFields.add("@id");
|
|
21
|
-
for (const fact of op.facts) {
|
|
22
|
-
if (!allowedFields.has(fact.a)) {
|
|
23
|
-
throw new Error(`Schema violation: attribute "${fact.a}" is not allowed for entity type "${type}".`);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return next(op, ctx);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
export {
|
|
33
|
-
SchemaMiddleware
|
|
34
|
-
};
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
// src/kernel/security-middleware.ts
|
|
2
|
-
class SecurityMiddleware {
|
|
3
|
-
provider;
|
|
4
|
-
name = "security";
|
|
5
|
-
constructor(provider) {
|
|
6
|
-
this.provider = provider;
|
|
7
|
-
}
|
|
8
|
-
async handleOp(op, ctx, next) {
|
|
9
|
-
const agentId = ctx.agentId || "anonymous";
|
|
10
|
-
if (ctx.system) {
|
|
11
|
-
return next(op, ctx);
|
|
12
|
-
}
|
|
13
|
-
let targetEntityId;
|
|
14
|
-
let targetEntityType;
|
|
15
|
-
if (op.facts && op.facts.length > 0) {
|
|
16
|
-
const firstFact = op.facts[0];
|
|
17
|
-
targetEntityId = firstFact.e;
|
|
18
|
-
const typeFact = op.facts.find((f) => f.a === "type");
|
|
19
|
-
if (typeFact && typeof typeFact.v === "string") {
|
|
20
|
-
targetEntityType = typeFact.v;
|
|
21
|
-
}
|
|
22
|
-
} else if (op.links && op.links.length > 0) {
|
|
23
|
-
targetEntityId = op.links[0].e1;
|
|
24
|
-
}
|
|
25
|
-
const allowed = await this.provider.can({
|
|
26
|
-
agentId,
|
|
27
|
-
action: "mutate",
|
|
28
|
-
targetEntityId,
|
|
29
|
-
targetEntityType
|
|
30
|
-
});
|
|
31
|
-
if (!allowed) {
|
|
32
|
-
throw new Error(`Security violation: agent ${agentId} is not authorized to mutate kernel state${targetEntityId ? ` for entity ${targetEntityId}` : ""}.`);
|
|
33
|
-
}
|
|
34
|
-
return next(op, ctx);
|
|
35
|
-
}
|
|
36
|
-
async handleQuery(query, ctx, next) {
|
|
37
|
-
const agentId = ctx.agentId || "anonymous";
|
|
38
|
-
if (ctx.system) {
|
|
39
|
-
return next(query, ctx);
|
|
40
|
-
}
|
|
41
|
-
const allowed = await this.provider.can({
|
|
42
|
-
agentId,
|
|
43
|
-
action: "query"
|
|
44
|
-
});
|
|
45
|
-
if (!allowed) {
|
|
46
|
-
throw new Error(`Security violation: agent ${agentId} is not authorized to query the kernel.`);
|
|
47
|
-
}
|
|
48
|
-
return next(query, ctx);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
export {
|
|
52
|
-
SecurityMiddleware
|
|
53
|
-
};
|