twining-mcp 1.3.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/LICENSE +21 -0
- package/README.md +165 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +78 -0
- package/dist/config.js.map +1 -0
- package/dist/dashboard/api-routes.d.ts +21 -0
- package/dist/dashboard/api-routes.d.ts.map +1 -0
- package/dist/dashboard/api-routes.js +516 -0
- package/dist/dashboard/api-routes.js.map +1 -0
- package/dist/dashboard/dashboard-config.d.ts +19 -0
- package/dist/dashboard/dashboard-config.d.ts.map +1 -0
- package/dist/dashboard/dashboard-config.js +17 -0
- package/dist/dashboard/dashboard-config.js.map +1 -0
- package/dist/dashboard/http-server.d.ts +29 -0
- package/dist/dashboard/http-server.d.ts.map +1 -0
- package/dist/dashboard/http-server.js +177 -0
- package/dist/dashboard/http-server.js.map +1 -0
- package/dist/dashboard/public/app.js +2396 -0
- package/dist/dashboard/public/assets/favicon.svg +44 -0
- package/dist/dashboard/public/assets/icon-512.png +0 -0
- package/dist/dashboard/public/assets/logo.svg +45 -0
- package/dist/dashboard/public/favicon.ico +0 -0
- package/dist/dashboard/public/index.html +338 -0
- package/dist/dashboard/public/style.css +858 -0
- package/dist/dashboard/public/vendor/cytoscape.min.js +1 -0
- package/dist/dashboard/public/vendor/vis-timeline-graph2d.min.css +2 -0
- package/dist/dashboard/public/vendor/vis-timeline-graph2d.min.js +48 -0
- package/dist/embeddings/embedder.d.ts +24 -0
- package/dist/embeddings/embedder.d.ts.map +1 -0
- package/dist/embeddings/embedder.js +109 -0
- package/dist/embeddings/embedder.js.map +1 -0
- package/dist/embeddings/index-manager.d.ts +27 -0
- package/dist/embeddings/index-manager.d.ts.map +1 -0
- package/dist/embeddings/index-manager.js +115 -0
- package/dist/embeddings/index-manager.js.map +1 -0
- package/dist/embeddings/search.d.ts +52 -0
- package/dist/embeddings/search.d.ts.map +1 -0
- package/dist/embeddings/search.js +170 -0
- package/dist/embeddings/search.js.map +1 -0
- package/dist/engine/archiver.d.ts +28 -0
- package/dist/engine/archiver.d.ts.map +1 -0
- package/dist/engine/archiver.js +153 -0
- package/dist/engine/archiver.js.map +1 -0
- package/dist/engine/blackboard.d.ts +55 -0
- package/dist/engine/blackboard.d.ts.map +1 -0
- package/dist/engine/blackboard.js +90 -0
- package/dist/engine/blackboard.js.map +1 -0
- package/dist/engine/context-assembler.d.ts +50 -0
- package/dist/engine/context-assembler.d.ts.map +1 -0
- package/dist/engine/context-assembler.js +483 -0
- package/dist/engine/context-assembler.js.map +1 -0
- package/dist/engine/coordination.d.ts +53 -0
- package/dist/engine/coordination.d.ts.map +1 -0
- package/dist/engine/coordination.js +239 -0
- package/dist/engine/coordination.js.map +1 -0
- package/dist/engine/decisions.d.ts +147 -0
- package/dist/engine/decisions.d.ts.map +1 -0
- package/dist/engine/decisions.js +540 -0
- package/dist/engine/decisions.js.map +1 -0
- package/dist/engine/exporter.d.ts +30 -0
- package/dist/engine/exporter.d.ts.map +1 -0
- package/dist/engine/exporter.js +192 -0
- package/dist/engine/exporter.js.map +1 -0
- package/dist/engine/graph.d.ts +55 -0
- package/dist/engine/graph.d.ts.map +1 -0
- package/dist/engine/graph.js +119 -0
- package/dist/engine/graph.js.map +1 -0
- package/dist/engine/planning-bridge.d.ts +53 -0
- package/dist/engine/planning-bridge.d.ts.map +1 -0
- package/dist/engine/planning-bridge.js +170 -0
- package/dist/engine/planning-bridge.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +7 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +82 -0
- package/dist/server.js.map +1 -0
- package/dist/storage/agent-store.d.ts +36 -0
- package/dist/storage/agent-store.d.ts.map +1 -0
- package/dist/storage/agent-store.js +119 -0
- package/dist/storage/agent-store.js.map +1 -0
- package/dist/storage/blackboard-store.d.ts +21 -0
- package/dist/storage/blackboard-store.d.ts.map +1 -0
- package/dist/storage/blackboard-store.js +56 -0
- package/dist/storage/blackboard-store.js.map +1 -0
- package/dist/storage/decision-store.d.ts +23 -0
- package/dist/storage/decision-store.d.ts.map +1 -0
- package/dist/storage/decision-store.js +179 -0
- package/dist/storage/decision-store.js.map +1 -0
- package/dist/storage/file-store.d.ts +20 -0
- package/dist/storage/file-store.d.ts.map +1 -0
- package/dist/storage/file-store.js +108 -0
- package/dist/storage/file-store.js.map +1 -0
- package/dist/storage/graph-store.d.ts +39 -0
- package/dist/storage/graph-store.d.ts.map +1 -0
- package/dist/storage/graph-store.js +143 -0
- package/dist/storage/graph-store.js.map +1 -0
- package/dist/storage/handoff-store.d.ts +44 -0
- package/dist/storage/handoff-store.d.ts.map +1 -0
- package/dist/storage/handoff-store.js +136 -0
- package/dist/storage/handoff-store.js.map +1 -0
- package/dist/storage/init.d.ts +10 -0
- package/dist/storage/init.d.ts.map +1 -0
- package/dist/storage/init.js +48 -0
- package/dist/storage/init.js.map +1 -0
- package/dist/tools/blackboard-tools.d.ts +4 -0
- package/dist/tools/blackboard-tools.d.ts.map +1 -0
- package/dist/tools/blackboard-tools.js +131 -0
- package/dist/tools/blackboard-tools.js.map +1 -0
- package/dist/tools/context-tools.d.ts +4 -0
- package/dist/tools/context-tools.d.ts.map +1 -0
- package/dist/tools/context-tools.js +76 -0
- package/dist/tools/context-tools.js.map +1 -0
- package/dist/tools/coordination-tools.d.ts +6 -0
- package/dist/tools/coordination-tools.d.ts.map +1 -0
- package/dist/tools/coordination-tools.js +220 -0
- package/dist/tools/coordination-tools.js.map +1 -0
- package/dist/tools/decision-tools.d.ts +4 -0
- package/dist/tools/decision-tools.d.ts.map +1 -0
- package/dist/tools/decision-tools.js +265 -0
- package/dist/tools/decision-tools.js.map +1 -0
- package/dist/tools/export-tools.d.ts +4 -0
- package/dist/tools/export-tools.d.ts.map +1 -0
- package/dist/tools/export-tools.js +30 -0
- package/dist/tools/export-tools.js.map +1 -0
- package/dist/tools/graph-tools.d.ts +4 -0
- package/dist/tools/graph-tools.d.ts.map +1 -0
- package/dist/tools/graph-tools.js +127 -0
- package/dist/tools/graph-tools.js.map +1 -0
- package/dist/tools/lifecycle-tools.d.ts +9 -0
- package/dist/tools/lifecycle-tools.d.ts.map +1 -0
- package/dist/tools/lifecycle-tools.js +142 -0
- package/dist/tools/lifecycle-tools.js.map +1 -0
- package/dist/utils/errors.d.ts +24 -0
- package/dist/utils/errors.d.ts.map +1 -0
- package/dist/utils/errors.js +31 -0
- package/dist/utils/errors.js.map +1 -0
- package/dist/utils/ids.d.ts +2 -0
- package/dist/utils/ids.d.ts.map +1 -0
- package/dist/utils/ids.js +10 -0
- package/dist/utils/ids.js.map +1 -0
- package/dist/utils/liveness.d.ts +14 -0
- package/dist/utils/liveness.d.ts.map +1 -0
- package/dist/utils/liveness.js +19 -0
- package/dist/utils/liveness.js.map +1 -0
- package/dist/utils/tags.d.ts +9 -0
- package/dist/utils/tags.d.ts.map +1 -0
- package/dist/utils/tags.js +12 -0
- package/dist/utils/tags.js.map +1 -0
- package/dist/utils/tokens.d.ts +6 -0
- package/dist/utils/tokens.d.ts.map +1 -0
- package/dist/utils/tokens.js +8 -0
- package/dist/utils/tokens.js.map +1 -0
- package/dist/utils/types.d.ts +308 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +18 -0
- package/dist/utils/types.js.map +1 -0
- package/package.json +60 -0
- package/src/dashboard/public/app.js +2396 -0
- package/src/dashboard/public/assets/favicon.svg +44 -0
- package/src/dashboard/public/assets/icon-512.png +0 -0
- package/src/dashboard/public/assets/logo.svg +45 -0
- package/src/dashboard/public/favicon.ico +0 -0
- package/src/dashboard/public/index.html +338 -0
- package/src/dashboard/public/style.css +858 -0
- package/src/dashboard/public/vendor/cytoscape.min.js +1 -0
- package/src/dashboard/public/vendor/vis-timeline-graph2d.min.css +2 -0
- package/src/dashboard/public/vendor/vis-timeline-graph2d.min.js +48 -0
|
@@ -0,0 +1,540 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Decision business logic.
|
|
3
|
+
* Validates input, applies defaults, delegates to DecisionStore,
|
|
4
|
+
* and cross-posts to blackboard.
|
|
5
|
+
* Phase 3: Adds trace, reconsider, override, and conflict detection.
|
|
6
|
+
* Generates embeddings on decide (Phase 2) with graceful fallback.
|
|
7
|
+
* Phase 5: Syncs decision summaries to .planning/STATE.md for GSD bridge.
|
|
8
|
+
*/
|
|
9
|
+
import fs from "node:fs";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { DecisionStore } from "../storage/decision-store.js";
|
|
12
|
+
import { BlackboardEngine } from "./blackboard.js";
|
|
13
|
+
import { TwiningError } from "../utils/errors.js";
|
|
14
|
+
export class DecisionEngine {
|
|
15
|
+
decisionStore;
|
|
16
|
+
blackboardEngine;
|
|
17
|
+
embedder;
|
|
18
|
+
indexManager;
|
|
19
|
+
projectRoot;
|
|
20
|
+
searchEngine;
|
|
21
|
+
graphEngine;
|
|
22
|
+
constructor(decisionStore, blackboardEngine, embedder, indexManager, projectRoot, searchEngine, graphEngine) {
|
|
23
|
+
this.decisionStore = decisionStore;
|
|
24
|
+
this.blackboardEngine = blackboardEngine;
|
|
25
|
+
this.embedder = embedder ?? null;
|
|
26
|
+
this.indexManager = indexManager ?? null;
|
|
27
|
+
this.projectRoot = projectRoot ?? null;
|
|
28
|
+
this.searchEngine = searchEngine ?? null;
|
|
29
|
+
this.graphEngine = graphEngine ?? null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Sync a decision summary to .planning/STATE.md.
|
|
33
|
+
* Appends to the "### Decisions" section under "## Accumulated Context".
|
|
34
|
+
* Never throws — planning sync failure must not prevent decide().
|
|
35
|
+
* Uses direct fs calls because STATE.md is a GSD planning file, not Twining data.
|
|
36
|
+
*/
|
|
37
|
+
syncToPlanning(summary) {
|
|
38
|
+
if (!this.projectRoot)
|
|
39
|
+
return;
|
|
40
|
+
try {
|
|
41
|
+
const statePath = path.join(this.projectRoot, ".planning", "STATE.md");
|
|
42
|
+
if (!fs.existsSync(statePath))
|
|
43
|
+
return;
|
|
44
|
+
const content = fs.readFileSync(statePath, "utf-8");
|
|
45
|
+
const lines = content.split("\n");
|
|
46
|
+
// Find the "### Decisions" section
|
|
47
|
+
let decisionsLineIndex = -1;
|
|
48
|
+
for (let i = 0; i < lines.length; i++) {
|
|
49
|
+
if (lines[i].trim() === "### Decisions") {
|
|
50
|
+
decisionsLineIndex = i;
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
if (decisionsLineIndex === -1)
|
|
55
|
+
return; // No Decisions section found
|
|
56
|
+
// Find the end of the Decisions section (next ### or ## header)
|
|
57
|
+
let insertIndex = lines.length; // Default: end of file
|
|
58
|
+
for (let i = decisionsLineIndex + 1; i < lines.length; i++) {
|
|
59
|
+
if (/^#{2,3}\s/.test(lines[i])) {
|
|
60
|
+
insertIndex = i;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// Insert the decision summary before the next header
|
|
65
|
+
// Walk back over any trailing blank lines to insert after content
|
|
66
|
+
let insertAt = insertIndex;
|
|
67
|
+
while (insertAt > decisionsLineIndex + 1 && lines[insertAt - 1].trim() === "") {
|
|
68
|
+
insertAt--;
|
|
69
|
+
}
|
|
70
|
+
const newLine = `- ${summary}`;
|
|
71
|
+
lines.splice(insertAt, 0, newLine);
|
|
72
|
+
fs.writeFileSync(statePath, lines.join("\n"), "utf-8");
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
// Never let planning sync failure prevent the decide operation
|
|
76
|
+
console.error("[twining] STATE.md sync failed (non-fatal):", error);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/** Record a decision with full rationale and conflict detection. */
|
|
80
|
+
async decide(input) {
|
|
81
|
+
// Validate required fields
|
|
82
|
+
if (!input.domain) {
|
|
83
|
+
throw new TwiningError("domain is required", "INVALID_INPUT");
|
|
84
|
+
}
|
|
85
|
+
if (!input.scope) {
|
|
86
|
+
throw new TwiningError("scope is required", "INVALID_INPUT");
|
|
87
|
+
}
|
|
88
|
+
if (!input.summary) {
|
|
89
|
+
throw new TwiningError("summary is required", "INVALID_INPUT");
|
|
90
|
+
}
|
|
91
|
+
if (!input.context) {
|
|
92
|
+
throw new TwiningError("context is required", "INVALID_INPUT");
|
|
93
|
+
}
|
|
94
|
+
if (!input.rationale) {
|
|
95
|
+
throw new TwiningError("rationale is required", "INVALID_INPUT");
|
|
96
|
+
}
|
|
97
|
+
// If supersedes, mark old decision
|
|
98
|
+
if (input.supersedes) {
|
|
99
|
+
await this.decisionStore.updateStatus(input.supersedes, "superseded");
|
|
100
|
+
}
|
|
101
|
+
// Conflict detection: scan for active decisions in same domain with overlapping scope
|
|
102
|
+
const index = await this.decisionStore.getIndex();
|
|
103
|
+
const conflicts = index.filter((entry) => entry.domain === input.domain &&
|
|
104
|
+
(entry.scope.startsWith(input.scope) ||
|
|
105
|
+
input.scope.startsWith(entry.scope)) &&
|
|
106
|
+
entry.status === "active" &&
|
|
107
|
+
entry.summary !== input.summary);
|
|
108
|
+
// Normalize alternatives: ensure pros/cons arrays exist
|
|
109
|
+
const alternatives = (input.alternatives ?? []).map((alt) => ({
|
|
110
|
+
option: alt.option,
|
|
111
|
+
pros: alt.pros ?? [],
|
|
112
|
+
cons: alt.cons ?? [],
|
|
113
|
+
reason_rejected: alt.reason_rejected,
|
|
114
|
+
}));
|
|
115
|
+
// Create decision with defaults — provisional if conflicts found
|
|
116
|
+
const decision = await this.decisionStore.create({
|
|
117
|
+
agent_id: input.agent_id ?? "main",
|
|
118
|
+
domain: input.domain,
|
|
119
|
+
scope: input.scope,
|
|
120
|
+
summary: input.summary,
|
|
121
|
+
context: input.context,
|
|
122
|
+
rationale: input.rationale,
|
|
123
|
+
constraints: input.constraints ?? [],
|
|
124
|
+
alternatives,
|
|
125
|
+
depends_on: input.depends_on ?? [],
|
|
126
|
+
supersedes: input.supersedes,
|
|
127
|
+
confidence: (input.confidence ?? "medium"),
|
|
128
|
+
reversible: input.reversible ?? true,
|
|
129
|
+
affected_files: input.affected_files ?? [],
|
|
130
|
+
affected_symbols: input.affected_symbols ?? [],
|
|
131
|
+
commit_hashes: input.commit_hash ? [input.commit_hash] : [],
|
|
132
|
+
});
|
|
133
|
+
// If conflicts exist, mark new decision as provisional and post warning
|
|
134
|
+
if (conflicts.length > 0) {
|
|
135
|
+
await this.decisionStore.updateStatus(decision.id, "provisional");
|
|
136
|
+
const conflictDetails = conflicts
|
|
137
|
+
.map((c) => `- ${c.id}: "${c.summary}"`)
|
|
138
|
+
.join("\n");
|
|
139
|
+
await this.blackboardEngine.post({
|
|
140
|
+
entry_type: "warning",
|
|
141
|
+
summary: `Potential conflict: new decision may conflict with ${conflicts.length} existing decision(s)`,
|
|
142
|
+
detail: `New decision "${decision.summary}" conflicts with:\n${conflictDetails}`,
|
|
143
|
+
tags: [input.domain],
|
|
144
|
+
scope: input.scope,
|
|
145
|
+
agent_id: decision.agent_id,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
// Cross-post to blackboard (internal — bypasses decision rejection)
|
|
149
|
+
await this.blackboardEngine.post({
|
|
150
|
+
entry_type: "decision",
|
|
151
|
+
summary: decision.summary,
|
|
152
|
+
detail: decision.rationale,
|
|
153
|
+
tags: [decision.domain],
|
|
154
|
+
scope: decision.scope,
|
|
155
|
+
agent_id: decision.agent_id,
|
|
156
|
+
_internal: true,
|
|
157
|
+
});
|
|
158
|
+
// Generate embedding (Phase 2) — never let embedding failure prevent the decide
|
|
159
|
+
if (this.embedder && this.indexManager) {
|
|
160
|
+
try {
|
|
161
|
+
const text = decision.summary + " " + decision.rationale + " " + decision.context;
|
|
162
|
+
const vector = await this.embedder.embed(text);
|
|
163
|
+
if (vector) {
|
|
164
|
+
await this.indexManager.addEntry("decisions", decision.id, vector);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
// Silent failure — embedding is best-effort
|
|
169
|
+
console.error("[twining] Decision embedding generation failed (non-fatal):", error);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// Sync decision summary to .planning/STATE.md (Phase 5 GSD bridge)
|
|
173
|
+
this.syncToPlanning(decision.summary);
|
|
174
|
+
// Auto-populate knowledge graph with affected files/symbols (spec §4.2)
|
|
175
|
+
if (this.graphEngine) {
|
|
176
|
+
try {
|
|
177
|
+
for (const filePath of decision.affected_files) {
|
|
178
|
+
const entity = await this.graphEngine.addEntity({
|
|
179
|
+
name: filePath,
|
|
180
|
+
type: "file",
|
|
181
|
+
properties: { scope: decision.scope },
|
|
182
|
+
});
|
|
183
|
+
await this.graphEngine.addRelation({
|
|
184
|
+
source: entity.name,
|
|
185
|
+
target: decision.id,
|
|
186
|
+
type: "decided_by",
|
|
187
|
+
properties: { decision_summary: decision.summary },
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
for (const symbol of decision.affected_symbols) {
|
|
191
|
+
const entity = await this.graphEngine.addEntity({
|
|
192
|
+
name: symbol,
|
|
193
|
+
type: "function",
|
|
194
|
+
properties: { scope: decision.scope },
|
|
195
|
+
});
|
|
196
|
+
await this.graphEngine.addRelation({
|
|
197
|
+
source: entity.name,
|
|
198
|
+
target: decision.id,
|
|
199
|
+
type: "decided_by",
|
|
200
|
+
properties: { decision_summary: decision.summary },
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
// Non-fatal — graph enrichment is best-effort
|
|
206
|
+
console.error("[twining] Graph auto-population failed (non-fatal):", error);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const result = { id: decision.id, timestamp: decision.timestamp };
|
|
210
|
+
if (conflicts.length > 0) {
|
|
211
|
+
result.conflicts = conflicts.map((c) => ({
|
|
212
|
+
id: c.id,
|
|
213
|
+
summary: c.summary,
|
|
214
|
+
}));
|
|
215
|
+
}
|
|
216
|
+
return result;
|
|
217
|
+
}
|
|
218
|
+
/** Retrieve decision chain for a scope or file. */
|
|
219
|
+
async why(scope) {
|
|
220
|
+
const decisions = await this.decisionStore.getByScope(scope);
|
|
221
|
+
const mapped = decisions.map((d) => ({
|
|
222
|
+
id: d.id,
|
|
223
|
+
summary: d.summary,
|
|
224
|
+
rationale: d.rationale,
|
|
225
|
+
confidence: d.confidence,
|
|
226
|
+
status: d.status,
|
|
227
|
+
timestamp: d.timestamp,
|
|
228
|
+
alternatives_count: d.alternatives.length,
|
|
229
|
+
commit_hashes: d.commit_hashes ?? [],
|
|
230
|
+
}));
|
|
231
|
+
const active_count = decisions.filter((d) => d.status === "active").length;
|
|
232
|
+
const provisional_count = decisions.filter((d) => d.status === "provisional").length;
|
|
233
|
+
return { decisions: mapped, active_count, provisional_count };
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Link a commit hash to an existing decision.
|
|
237
|
+
* Posts a status entry to the blackboard for traceability.
|
|
238
|
+
*/
|
|
239
|
+
async linkCommit(decisionId, commitHash, agentId) {
|
|
240
|
+
const decision = await this.decisionStore.get(decisionId);
|
|
241
|
+
if (!decision) {
|
|
242
|
+
throw new TwiningError(`Decision not found: ${decisionId}`, "NOT_FOUND");
|
|
243
|
+
}
|
|
244
|
+
await this.decisionStore.linkCommit(decisionId, commitHash);
|
|
245
|
+
// Post status entry to blackboard
|
|
246
|
+
const summary = `Commit ${commitHash.slice(0, 7)} linked to decision: ${decision.summary}`.slice(0, 200);
|
|
247
|
+
await this.blackboardEngine.post({
|
|
248
|
+
entry_type: "status",
|
|
249
|
+
summary,
|
|
250
|
+
detail: `Linked commit ${commitHash} to decision ${decisionId}`,
|
|
251
|
+
tags: [decision.domain],
|
|
252
|
+
scope: decision.scope,
|
|
253
|
+
agent_id: agentId ?? "main",
|
|
254
|
+
});
|
|
255
|
+
return { linked: true, decision_summary: decision.summary };
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Get decisions linked to a specific commit hash.
|
|
259
|
+
*/
|
|
260
|
+
async getByCommitHash(commitHash) {
|
|
261
|
+
const decisions = await this.decisionStore.getByCommitHash(commitHash);
|
|
262
|
+
return {
|
|
263
|
+
decisions: decisions.map((d) => ({
|
|
264
|
+
id: d.id,
|
|
265
|
+
summary: d.summary,
|
|
266
|
+
domain: d.domain,
|
|
267
|
+
scope: d.scope,
|
|
268
|
+
confidence: d.confidence,
|
|
269
|
+
timestamp: d.timestamp,
|
|
270
|
+
commit_hashes: d.commit_hashes,
|
|
271
|
+
})),
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Trace a decision's dependency chain upstream and/or downstream.
|
|
276
|
+
* Uses BFS with a visited set to prevent infinite loops from circular dependencies.
|
|
277
|
+
*/
|
|
278
|
+
async trace(decisionId, direction = "both") {
|
|
279
|
+
// Verify root decision exists
|
|
280
|
+
const rootDecision = await this.decisionStore.get(decisionId);
|
|
281
|
+
if (!rootDecision) {
|
|
282
|
+
throw new TwiningError(`Decision not found: ${decisionId}`, "NOT_FOUND");
|
|
283
|
+
}
|
|
284
|
+
// Load all decisions to build the dependency maps
|
|
285
|
+
const index = await this.decisionStore.getIndex();
|
|
286
|
+
const decisions = new Map();
|
|
287
|
+
for (const entry of index) {
|
|
288
|
+
const d = await this.decisionStore.get(entry.id);
|
|
289
|
+
if (d)
|
|
290
|
+
decisions.set(d.id, d);
|
|
291
|
+
}
|
|
292
|
+
// Build reverse dependency map: parentId -> [childIds that depend on parent]
|
|
293
|
+
const reverseMap = new Map();
|
|
294
|
+
for (const [id, d] of decisions) {
|
|
295
|
+
for (const dep of d.depends_on) {
|
|
296
|
+
if (!reverseMap.has(dep))
|
|
297
|
+
reverseMap.set(dep, []);
|
|
298
|
+
reverseMap.get(dep).push(id);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
const visited = new Set();
|
|
302
|
+
visited.add(decisionId);
|
|
303
|
+
const chain = [];
|
|
304
|
+
// BFS upstream: follow depends_on
|
|
305
|
+
if (direction === "upstream" || direction === "both") {
|
|
306
|
+
const queue = [...(rootDecision.depends_on ?? [])];
|
|
307
|
+
while (queue.length > 0) {
|
|
308
|
+
const current = queue.shift();
|
|
309
|
+
if (visited.has(current))
|
|
310
|
+
continue;
|
|
311
|
+
visited.add(current);
|
|
312
|
+
const d = decisions.get(current);
|
|
313
|
+
if (d) {
|
|
314
|
+
chain.push({
|
|
315
|
+
id: d.id,
|
|
316
|
+
summary: d.summary,
|
|
317
|
+
depends_on: d.depends_on,
|
|
318
|
+
dependents: reverseMap.get(d.id) ?? [],
|
|
319
|
+
status: d.status,
|
|
320
|
+
});
|
|
321
|
+
for (const dep of d.depends_on) {
|
|
322
|
+
if (!visited.has(dep))
|
|
323
|
+
queue.push(dep);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
// BFS downstream: follow reverse map (dependents)
|
|
329
|
+
if (direction === "downstream" || direction === "both") {
|
|
330
|
+
const queue = [...(reverseMap.get(decisionId) ?? [])];
|
|
331
|
+
while (queue.length > 0) {
|
|
332
|
+
const current = queue.shift();
|
|
333
|
+
if (visited.has(current))
|
|
334
|
+
continue;
|
|
335
|
+
visited.add(current);
|
|
336
|
+
const d = decisions.get(current);
|
|
337
|
+
if (d) {
|
|
338
|
+
chain.push({
|
|
339
|
+
id: d.id,
|
|
340
|
+
summary: d.summary,
|
|
341
|
+
depends_on: d.depends_on,
|
|
342
|
+
dependents: reverseMap.get(d.id) ?? [],
|
|
343
|
+
status: d.status,
|
|
344
|
+
});
|
|
345
|
+
const downstream = reverseMap.get(d.id) ?? [];
|
|
346
|
+
for (const dep of downstream) {
|
|
347
|
+
if (!visited.has(dep))
|
|
348
|
+
queue.push(dep);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return { chain };
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Flag a decision for reconsideration.
|
|
357
|
+
* Sets active decisions to provisional and posts a warning.
|
|
358
|
+
*/
|
|
359
|
+
async reconsider(decisionId, newContext, agentId) {
|
|
360
|
+
const decision = await this.decisionStore.get(decisionId);
|
|
361
|
+
if (!decision) {
|
|
362
|
+
throw new TwiningError(`Decision not found: ${decisionId}`, "NOT_FOUND");
|
|
363
|
+
}
|
|
364
|
+
let flagged = false;
|
|
365
|
+
if (decision.status === "active") {
|
|
366
|
+
await this.decisionStore.updateStatus(decisionId, "provisional");
|
|
367
|
+
flagged = true;
|
|
368
|
+
}
|
|
369
|
+
// Check for downstream dependents
|
|
370
|
+
const index = await this.decisionStore.getIndex();
|
|
371
|
+
const downstreamIds = [];
|
|
372
|
+
for (const entry of index) {
|
|
373
|
+
const d = await this.decisionStore.get(entry.id);
|
|
374
|
+
if (d && d.depends_on.includes(decisionId)) {
|
|
375
|
+
downstreamIds.push(d.id);
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
let detail = newContext;
|
|
379
|
+
if (downstreamIds.length > 0) {
|
|
380
|
+
detail += `\nNote: ${downstreamIds.length} downstream decisions may be affected: ${downstreamIds.join(", ")}`;
|
|
381
|
+
}
|
|
382
|
+
// Post warning to blackboard
|
|
383
|
+
await this.blackboardEngine.post({
|
|
384
|
+
entry_type: "warning",
|
|
385
|
+
summary: `Reconsideration flagged: ${decision.summary}`.slice(0, 200),
|
|
386
|
+
detail,
|
|
387
|
+
tags: [decision.domain],
|
|
388
|
+
scope: decision.scope,
|
|
389
|
+
agent_id: agentId ?? "main",
|
|
390
|
+
});
|
|
391
|
+
return { flagged, decision_summary: decision.summary };
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Override a decision with a reason, optionally creating a replacement.
|
|
395
|
+
*/
|
|
396
|
+
async override(decisionId, reason, newDecision, overriddenBy) {
|
|
397
|
+
const decision = await this.decisionStore.get(decisionId);
|
|
398
|
+
if (!decision) {
|
|
399
|
+
throw new TwiningError(`Decision not found: ${decisionId}`, "NOT_FOUND");
|
|
400
|
+
}
|
|
401
|
+
// Set status to overridden with extra fields
|
|
402
|
+
await this.decisionStore.updateStatus(decisionId, "overridden", {
|
|
403
|
+
overridden_by: overriddenBy ?? "human",
|
|
404
|
+
override_reason: reason,
|
|
405
|
+
});
|
|
406
|
+
// Post override entry to blackboard (internal — bypasses decision rejection)
|
|
407
|
+
const overrider = overriddenBy ?? "human";
|
|
408
|
+
await this.blackboardEngine.post({
|
|
409
|
+
entry_type: "decision",
|
|
410
|
+
summary: `Override: ${decision.summary} -- overridden by ${overrider}`.slice(0, 200),
|
|
411
|
+
detail: reason,
|
|
412
|
+
tags: [decision.domain],
|
|
413
|
+
scope: decision.scope,
|
|
414
|
+
agent_id: overrider,
|
|
415
|
+
_internal: true,
|
|
416
|
+
});
|
|
417
|
+
const result = {
|
|
418
|
+
overridden: true,
|
|
419
|
+
old_summary: decision.summary,
|
|
420
|
+
};
|
|
421
|
+
// If a replacement decision is provided, create it via decide()
|
|
422
|
+
if (newDecision) {
|
|
423
|
+
const newResult = await this.decide({
|
|
424
|
+
domain: decision.domain,
|
|
425
|
+
scope: decision.scope,
|
|
426
|
+
summary: newDecision,
|
|
427
|
+
context: reason,
|
|
428
|
+
rationale: reason,
|
|
429
|
+
supersedes: decisionId,
|
|
430
|
+
agent_id: overriddenBy ?? "human",
|
|
431
|
+
});
|
|
432
|
+
result.new_decision_id = newResult.id;
|
|
433
|
+
}
|
|
434
|
+
return result;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Search decisions across all scopes by keyword or semantic similarity.
|
|
438
|
+
* Supports filtering by domain, status, and confidence.
|
|
439
|
+
* Never throws — returns empty results on error.
|
|
440
|
+
*/
|
|
441
|
+
async searchDecisions(query, filters, limit) {
|
|
442
|
+
const maxResults = limit ?? 20;
|
|
443
|
+
try {
|
|
444
|
+
if (!query || query.trim().length === 0) {
|
|
445
|
+
return { results: [], total_matched: 0, fallback_mode: true };
|
|
446
|
+
}
|
|
447
|
+
// Load index and apply filters before loading full decision files
|
|
448
|
+
const index = await this.decisionStore.getIndex();
|
|
449
|
+
let filtered = index;
|
|
450
|
+
if (filters?.domain) {
|
|
451
|
+
filtered = filtered.filter((entry) => entry.domain === filters.domain);
|
|
452
|
+
}
|
|
453
|
+
if (filters?.status) {
|
|
454
|
+
filtered = filtered.filter((entry) => entry.status === filters.status);
|
|
455
|
+
}
|
|
456
|
+
if (filters?.confidence) {
|
|
457
|
+
filtered = filtered.filter((entry) => entry.confidence === filters.confidence);
|
|
458
|
+
}
|
|
459
|
+
if (filtered.length === 0) {
|
|
460
|
+
return { results: [], total_matched: 0, fallback_mode: true };
|
|
461
|
+
}
|
|
462
|
+
// Load full Decision objects for filtered entries
|
|
463
|
+
const decisions = [];
|
|
464
|
+
for (const entry of filtered) {
|
|
465
|
+
const d = await this.decisionStore.get(entry.id);
|
|
466
|
+
if (d)
|
|
467
|
+
decisions.push(d);
|
|
468
|
+
}
|
|
469
|
+
// Delegate to SearchEngine if available
|
|
470
|
+
if (this.searchEngine) {
|
|
471
|
+
const searchResults = await this.searchEngine.searchDecisions(query, decisions, { limit: maxResults });
|
|
472
|
+
return {
|
|
473
|
+
results: searchResults.results.map((r) => ({
|
|
474
|
+
id: r.decision.id,
|
|
475
|
+
summary: r.decision.summary,
|
|
476
|
+
domain: r.decision.domain,
|
|
477
|
+
scope: r.decision.scope,
|
|
478
|
+
confidence: r.decision.confidence,
|
|
479
|
+
status: r.decision.status,
|
|
480
|
+
timestamp: r.decision.timestamp,
|
|
481
|
+
relevance: r.relevance,
|
|
482
|
+
commit_hashes: r.decision.commit_hashes ?? [],
|
|
483
|
+
})),
|
|
484
|
+
total_matched: searchResults.results.length,
|
|
485
|
+
fallback_mode: searchResults.fallback_mode,
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
// Keyword fallback: manual keyword matching
|
|
489
|
+
const queryTerms = query
|
|
490
|
+
.toLowerCase()
|
|
491
|
+
.split(/\s+/)
|
|
492
|
+
.filter((t) => t.length > 0);
|
|
493
|
+
if (queryTerms.length === 0) {
|
|
494
|
+
return { results: [], total_matched: 0, fallback_mode: true };
|
|
495
|
+
}
|
|
496
|
+
const scored = [];
|
|
497
|
+
for (const decision of decisions) {
|
|
498
|
+
const text = (decision.summary +
|
|
499
|
+
" " +
|
|
500
|
+
decision.rationale +
|
|
501
|
+
" " +
|
|
502
|
+
decision.context).toLowerCase();
|
|
503
|
+
let score = 0;
|
|
504
|
+
for (const term of queryTerms) {
|
|
505
|
+
if (text.includes(term)) {
|
|
506
|
+
const parts = text.split(term);
|
|
507
|
+
const matches = parts.length - 1;
|
|
508
|
+
score += Math.log(1 + matches);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
const normalizedScore = score / queryTerms.length;
|
|
512
|
+
if (normalizedScore > 0) {
|
|
513
|
+
scored.push({ decision, relevance: normalizedScore });
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
scored.sort((a, b) => b.relevance - a.relevance);
|
|
517
|
+
const topResults = scored.slice(0, maxResults);
|
|
518
|
+
return {
|
|
519
|
+
results: topResults.map((r) => ({
|
|
520
|
+
id: r.decision.id,
|
|
521
|
+
summary: r.decision.summary,
|
|
522
|
+
domain: r.decision.domain,
|
|
523
|
+
scope: r.decision.scope,
|
|
524
|
+
confidence: r.decision.confidence,
|
|
525
|
+
status: r.decision.status,
|
|
526
|
+
timestamp: r.decision.timestamp,
|
|
527
|
+
relevance: r.relevance,
|
|
528
|
+
commit_hashes: r.decision.commit_hashes ?? [],
|
|
529
|
+
})),
|
|
530
|
+
total_matched: topResults.length,
|
|
531
|
+
fallback_mode: true,
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
catch (error) {
|
|
535
|
+
console.error("[twining] searchDecisions failed (non-fatal):", error);
|
|
536
|
+
return { results: [], total_matched: 0, fallback_mode: true };
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
//# sourceMappingURL=decisions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"decisions.js","sourceRoot":"","sources":["../../src/engine/decisions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exporter engine — generates a single markdown snapshot of all Twining state.
|
|
3
|
+
* Reads blackboard, decisions, and knowledge graph stores.
|
|
4
|
+
* Supports optional scope filtering for targeted exports.
|
|
5
|
+
*/
|
|
6
|
+
import type { BlackboardStore } from "../storage/blackboard-store.js";
|
|
7
|
+
import type { DecisionStore } from "../storage/decision-store.js";
|
|
8
|
+
import type { GraphStore } from "../storage/graph-store.js";
|
|
9
|
+
export interface ExportStats {
|
|
10
|
+
blackboard_entries: number;
|
|
11
|
+
decisions: number;
|
|
12
|
+
graph_entities: number;
|
|
13
|
+
graph_relations: number;
|
|
14
|
+
scope: string;
|
|
15
|
+
}
|
|
16
|
+
export declare class Exporter {
|
|
17
|
+
private readonly blackboardStore;
|
|
18
|
+
private readonly decisionStore;
|
|
19
|
+
private readonly graphStore;
|
|
20
|
+
constructor(blackboardStore: BlackboardStore, decisionStore: DecisionStore, graphStore: GraphStore);
|
|
21
|
+
/**
|
|
22
|
+
* Export full Twining state as a single markdown document.
|
|
23
|
+
* If scope is provided, filters all data to that scope.
|
|
24
|
+
*/
|
|
25
|
+
exportMarkdown(scope?: string): Promise<{
|
|
26
|
+
markdown: string;
|
|
27
|
+
stats: ExportStats;
|
|
28
|
+
}>;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=exporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exporter.d.ts","sourceRoot":"","sources":["../../src/engine/exporter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAS5D,MAAM,WAAW,WAAW;IAC1B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,QAAQ;IAEjB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,UAAU;gBAFV,eAAe,EAAE,eAAe,EAChC,aAAa,EAAE,aAAa,EAC5B,UAAU,EAAE,UAAU;IAGzC;;;OAGG;IACG,cAAc,CAClB,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,WAAW,CAAA;KAAE,CAAC;CAmNrD"}
|