twining-mcp 1.16.0 → 1.17.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/dist/engine/housekeeping.d.ts +60 -0
- package/dist/engine/housekeeping.d.ts.map +1 -0
- package/dist/engine/housekeeping.js +180 -0
- package/dist/engine/housekeeping.js.map +1 -0
- package/dist/engine/record-parser.d.ts +16 -0
- package/dist/engine/record-parser.d.ts.map +1 -0
- package/dist/engine/record-parser.js +53 -0
- package/dist/engine/record-parser.js.map +1 -0
- package/dist/instructions.d.ts +1 -1
- package/dist/instructions.d.ts.map +1 -1
- package/dist/instructions.js +9 -18
- package/dist/instructions.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +7 -0
- package/dist/server.js.map +1 -1
- package/dist/tools/housekeeping-tools.d.ts +4 -0
- package/dist/tools/housekeeping-tools.d.ts.map +1 -0
- package/dist/tools/housekeeping-tools.js +46 -0
- package/dist/tools/housekeeping-tools.js.map +1 -0
- package/dist/tools/record-tools.d.ts +5 -0
- package/dist/tools/record-tools.d.ts.map +1 -0
- package/dist/tools/record-tools.js +219 -0
- package/dist/tools/record-tools.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { BlackboardStore } from "../storage/blackboard-store.js";
|
|
2
|
+
import type { DecisionStore } from "../storage/decision-store.js";
|
|
3
|
+
import type { Archiver } from "./archiver.js";
|
|
4
|
+
import type { GraphEngine } from "./graph.js";
|
|
5
|
+
export interface StaleProvisional {
|
|
6
|
+
id: string;
|
|
7
|
+
summary: string;
|
|
8
|
+
scope: string;
|
|
9
|
+
age_days: number;
|
|
10
|
+
}
|
|
11
|
+
export interface DanglingWarning {
|
|
12
|
+
id: string;
|
|
13
|
+
summary: string;
|
|
14
|
+
scope: string;
|
|
15
|
+
age_days: number;
|
|
16
|
+
}
|
|
17
|
+
export interface HousekeepingResult {
|
|
18
|
+
archived: {
|
|
19
|
+
count: number;
|
|
20
|
+
file: string;
|
|
21
|
+
};
|
|
22
|
+
deduplicated: {
|
|
23
|
+
removed: number;
|
|
24
|
+
};
|
|
25
|
+
stale_provisionals: {
|
|
26
|
+
count: number;
|
|
27
|
+
items: StaleProvisional[];
|
|
28
|
+
};
|
|
29
|
+
promoted_provisionals: {
|
|
30
|
+
count: number;
|
|
31
|
+
ids: string[];
|
|
32
|
+
};
|
|
33
|
+
dangling_warnings: {
|
|
34
|
+
count: number;
|
|
35
|
+
items: DanglingWarning[];
|
|
36
|
+
};
|
|
37
|
+
graph_pruned: {
|
|
38
|
+
removed: number;
|
|
39
|
+
};
|
|
40
|
+
metrics_rotated: {
|
|
41
|
+
removed: number;
|
|
42
|
+
};
|
|
43
|
+
dry_run: boolean;
|
|
44
|
+
summary: string;
|
|
45
|
+
}
|
|
46
|
+
export declare class HousekeepingEngine {
|
|
47
|
+
private readonly twiningDir;
|
|
48
|
+
private readonly blackboardStore;
|
|
49
|
+
private readonly decisionStore;
|
|
50
|
+
private readonly archiver;
|
|
51
|
+
private readonly graphEngine;
|
|
52
|
+
constructor(twiningDir: string, blackboardStore: BlackboardStore, decisionStore: DecisionStore, archiver: Archiver, graphEngine: GraphEngine | null);
|
|
53
|
+
run(options?: {
|
|
54
|
+
stale_days?: number;
|
|
55
|
+
metrics_retention_days?: number;
|
|
56
|
+
execute?: boolean;
|
|
57
|
+
promote_provisionals?: boolean;
|
|
58
|
+
}): Promise<HousekeepingResult>;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=housekeeping.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"housekeeping.d.ts","sourceRoot":"","sources":["../../src/engine/housekeeping.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACtE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAS9C,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,YAAY,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,kBAAkB,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,gBAAgB,EAAE,CAAA;KAAE,CAAC;IACjE,qBAAqB,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IACxD,iBAAiB,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,eAAe,EAAE,CAAA;KAAE,CAAC;IAC/D,YAAY,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAClC,eAAe,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACrC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,kBAAkB;IAE3B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAJX,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,eAAe,EAChC,aAAa,EAAE,aAAa,EAC5B,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,WAAW,GAAG,IAAI;IAG5C,GAAG,CAAC,OAAO,CAAC,EAAE;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,sBAAsB,CAAC,EAAE,MAAM,CAAC;QAChC,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAChC,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAiKhC"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Housekeeping engine — periodic maintenance for Twining stores.
|
|
3
|
+
* Orchestrates archival, deduplication, stale decision surfacing,
|
|
4
|
+
* dangling warning detection, graph pruning, and metrics rotation.
|
|
5
|
+
*
|
|
6
|
+
* Dry-run by default — preview before executing.
|
|
7
|
+
*/
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
/** Default: flag provisionals older than 7 days. */
|
|
11
|
+
const STALE_PROVISIONAL_DAYS = 7;
|
|
12
|
+
/** Default: keep metrics for 30 days. */
|
|
13
|
+
const METRICS_RETENTION_DAYS = 30;
|
|
14
|
+
export class HousekeepingEngine {
|
|
15
|
+
twiningDir;
|
|
16
|
+
blackboardStore;
|
|
17
|
+
decisionStore;
|
|
18
|
+
archiver;
|
|
19
|
+
graphEngine;
|
|
20
|
+
constructor(twiningDir, blackboardStore, decisionStore, archiver, graphEngine) {
|
|
21
|
+
this.twiningDir = twiningDir;
|
|
22
|
+
this.blackboardStore = blackboardStore;
|
|
23
|
+
this.decisionStore = decisionStore;
|
|
24
|
+
this.archiver = archiver;
|
|
25
|
+
this.graphEngine = graphEngine;
|
|
26
|
+
}
|
|
27
|
+
async run(options) {
|
|
28
|
+
const staleDays = options?.stale_days ?? STALE_PROVISIONAL_DAYS;
|
|
29
|
+
const metricsRetentionDays = options?.metrics_retention_days ?? METRICS_RETENTION_DAYS;
|
|
30
|
+
const execute = options?.execute ?? false;
|
|
31
|
+
const promoteProvisionals = options?.promote_provisionals ?? false;
|
|
32
|
+
const result = {
|
|
33
|
+
archived: { count: 0, file: "" },
|
|
34
|
+
deduplicated: { removed: 0 },
|
|
35
|
+
stale_provisionals: { count: 0, items: [] },
|
|
36
|
+
promoted_provisionals: { count: 0, ids: [] },
|
|
37
|
+
dangling_warnings: { count: 0, items: [] },
|
|
38
|
+
graph_pruned: { removed: 0 },
|
|
39
|
+
metrics_rotated: { removed: 0 },
|
|
40
|
+
dry_run: !execute,
|
|
41
|
+
summary: "",
|
|
42
|
+
};
|
|
43
|
+
const now = Date.now();
|
|
44
|
+
// 1. Archive old blackboard entries
|
|
45
|
+
if (execute) {
|
|
46
|
+
try {
|
|
47
|
+
const archiveResult = await this.archiver.archive({ summarize: false });
|
|
48
|
+
result.archived.count = archiveResult.archived_count;
|
|
49
|
+
result.archived.file = archiveResult.archive_file;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Non-fatal
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// 2. Deduplicate blackboard entries (same entry_type + summary + scope → keep newest)
|
|
56
|
+
try {
|
|
57
|
+
const { entries } = await this.blackboardStore.read();
|
|
58
|
+
const seen = new Map();
|
|
59
|
+
const duplicateIds = [];
|
|
60
|
+
// Walk newest-first so we keep the latest
|
|
61
|
+
const sorted = [...entries].sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
62
|
+
for (const entry of sorted) {
|
|
63
|
+
const key = `${entry.entry_type}|${entry.summary}|${entry.scope}`;
|
|
64
|
+
if (seen.has(key)) {
|
|
65
|
+
duplicateIds.push(entry.id);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
seen.set(key, entry);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
if (duplicateIds.length > 0 && execute) {
|
|
72
|
+
await this.blackboardStore.dismiss(duplicateIds);
|
|
73
|
+
}
|
|
74
|
+
result.deduplicated.removed = duplicateIds.length;
|
|
75
|
+
// 6. Surface dangling warnings (never auto-removed, just reported)
|
|
76
|
+
const warnings = entries.filter((e) => e.entry_type === "warning");
|
|
77
|
+
result.dangling_warnings.items = warnings.map((w) => ({
|
|
78
|
+
id: w.id,
|
|
79
|
+
summary: w.summary,
|
|
80
|
+
scope: w.scope,
|
|
81
|
+
age_days: Math.floor((now - new Date(w.timestamp).getTime()) / (24 * 60 * 60 * 1000)),
|
|
82
|
+
}));
|
|
83
|
+
result.dangling_warnings.items.sort((a, b) => b.age_days - a.age_days);
|
|
84
|
+
result.dangling_warnings.count = result.dangling_warnings.items.length;
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// Non-fatal
|
|
88
|
+
}
|
|
89
|
+
// 3. Surface stale provisional decisions (report always, promote only if opted in)
|
|
90
|
+
try {
|
|
91
|
+
const cutoff = new Date(now - staleDays * 24 * 60 * 60 * 1000).toISOString();
|
|
92
|
+
const index = await this.decisionStore.getIndex();
|
|
93
|
+
const staleProvisionals = index.filter((e) => e.status === "provisional" && e.timestamp < cutoff);
|
|
94
|
+
result.stale_provisionals.items = staleProvisionals.map((e) => ({
|
|
95
|
+
id: e.id,
|
|
96
|
+
summary: e.summary,
|
|
97
|
+
scope: e.scope,
|
|
98
|
+
age_days: Math.floor((now - new Date(e.timestamp).getTime()) / (24 * 60 * 60 * 1000)),
|
|
99
|
+
}));
|
|
100
|
+
result.stale_provisionals.items.sort((a, b) => b.age_days - a.age_days);
|
|
101
|
+
result.stale_provisionals.count = staleProvisionals.length;
|
|
102
|
+
// Only promote if explicitly requested
|
|
103
|
+
if (promoteProvisionals && execute && staleProvisionals.length > 0) {
|
|
104
|
+
for (const entry of staleProvisionals) {
|
|
105
|
+
await this.decisionStore.updateStatus(entry.id, "active");
|
|
106
|
+
}
|
|
107
|
+
result.promoted_provisionals.count = staleProvisionals.length;
|
|
108
|
+
result.promoted_provisionals.ids = staleProvisionals.map((e) => e.id);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Non-fatal
|
|
113
|
+
}
|
|
114
|
+
// 4. Prune orphaned graph entities
|
|
115
|
+
if (this.graphEngine) {
|
|
116
|
+
try {
|
|
117
|
+
const pruneResult = await this.graphEngine.prune(undefined, !execute);
|
|
118
|
+
result.graph_pruned.removed = execute ? pruneResult.total_removed : pruneResult.total_orphans_found;
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Non-fatal
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// 5. Rotate metrics — remove entries older than retention period
|
|
125
|
+
try {
|
|
126
|
+
const metricsPath = path.join(this.twiningDir, "metrics.jsonl");
|
|
127
|
+
if (fs.existsSync(metricsPath)) {
|
|
128
|
+
const cutoff = new Date(now - metricsRetentionDays * 24 * 60 * 60 * 1000).toISOString();
|
|
129
|
+
const content = fs.readFileSync(metricsPath, "utf-8");
|
|
130
|
+
const lines = content.split("\n").filter((l) => l.trim());
|
|
131
|
+
const kept = [];
|
|
132
|
+
let removed = 0;
|
|
133
|
+
for (const line of lines) {
|
|
134
|
+
try {
|
|
135
|
+
const entry = JSON.parse(line);
|
|
136
|
+
if (entry.timestamp && entry.timestamp < cutoff) {
|
|
137
|
+
removed++;
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
kept.push(line);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
kept.push(line); // Keep unparseable lines
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (removed > 0 && execute) {
|
|
148
|
+
fs.writeFileSync(metricsPath, kept.join("\n") + (kept.length > 0 ? "\n" : ""));
|
|
149
|
+
}
|
|
150
|
+
result.metrics_rotated.removed = removed;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
// Non-fatal
|
|
155
|
+
}
|
|
156
|
+
// Build summary
|
|
157
|
+
const prefix = execute ? "" : "[preview] ";
|
|
158
|
+
const verb = execute ? "" : "would ";
|
|
159
|
+
const parts = [];
|
|
160
|
+
if (result.archived.count > 0)
|
|
161
|
+
parts.push(`${verb}archive ${result.archived.count} entries`);
|
|
162
|
+
if (result.deduplicated.removed > 0)
|
|
163
|
+
parts.push(`${verb}remove ${result.deduplicated.removed} duplicates`);
|
|
164
|
+
if (result.stale_provisionals.count > 0)
|
|
165
|
+
parts.push(`${result.stale_provisionals.count} stale provisionals need review`);
|
|
166
|
+
if (result.dangling_warnings.count > 0)
|
|
167
|
+
parts.push(`${result.dangling_warnings.count} unresolved warnings`);
|
|
168
|
+
if (result.promoted_provisionals.count > 0)
|
|
169
|
+
parts.push(`promoted ${result.promoted_provisionals.count} provisionals`);
|
|
170
|
+
if (result.graph_pruned.removed > 0)
|
|
171
|
+
parts.push(`${verb}prune ${result.graph_pruned.removed} orphaned entities`);
|
|
172
|
+
if (result.metrics_rotated.removed > 0)
|
|
173
|
+
parts.push(`${verb}rotate ${result.metrics_rotated.removed} old metrics`);
|
|
174
|
+
result.summary = parts.length > 0
|
|
175
|
+
? prefix + parts.join(", ")
|
|
176
|
+
: "Nothing to clean up";
|
|
177
|
+
return result;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=housekeeping.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"housekeeping.js","sourceRoot":"","sources":["../../src/engine/housekeeping.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses natural language decision strings into structured decision input.
|
|
3
|
+
*
|
|
4
|
+
* Examples:
|
|
5
|
+
* "Chose Redis over Memcached — need persistence across restarts"
|
|
6
|
+
* "Used event-driven pattern instead of callbacks for notifications"
|
|
7
|
+
* "Reverted the workaround — root cause was fixed upstream"
|
|
8
|
+
*/
|
|
9
|
+
export interface ParsedDecision {
|
|
10
|
+
summary: string;
|
|
11
|
+
rationale: string;
|
|
12
|
+
rejected_alternatives: string[];
|
|
13
|
+
domain: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function parseDecision(text: string): ParsedDecision;
|
|
16
|
+
//# sourceMappingURL=record-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-parser.d.ts","sourceRoot":"","sources":["../../src/engine/record-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AAyBD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CA0B1D"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parses natural language decision strings into structured decision input.
|
|
3
|
+
*
|
|
4
|
+
* Examples:
|
|
5
|
+
* "Chose Redis over Memcached — need persistence across restarts"
|
|
6
|
+
* "Used event-driven pattern instead of callbacks for notifications"
|
|
7
|
+
* "Reverted the workaround — root cause was fixed upstream"
|
|
8
|
+
*/
|
|
9
|
+
/** Separators between summary and rationale. */
|
|
10
|
+
const RATIONALE_SEPARATORS = /\s+(?:—|--|because|since|due to|as|so that)\s+/i;
|
|
11
|
+
/** Patterns that indicate a rejected alternative. */
|
|
12
|
+
const REJECTION_PATTERNS = [
|
|
13
|
+
/\bover\s+(.+?)(?:\s+(?:—|--|because|since|due to|$))/i,
|
|
14
|
+
/\binstead of\s+(.+?)(?:\s+(?:—|--|because|since|due to|$))/i,
|
|
15
|
+
/\brather than\s+(.+?)(?:\s+(?:—|--|because|since|due to|$))/i,
|
|
16
|
+
/\bnot\s+(.+?)(?:\s+(?:—|--|because|since|due to|$))/i,
|
|
17
|
+
];
|
|
18
|
+
/** Keywords that hint at a domain. */
|
|
19
|
+
const DOMAIN_HINTS = {
|
|
20
|
+
architecture: ["pattern", "architecture", "event-driven", "microservice", "monolith", "layer", "decouple"],
|
|
21
|
+
security: ["auth", "jwt", "oauth", "token", "encrypt", "permission", "rbac"],
|
|
22
|
+
performance: ["cache", "redis", "memcached", "index", "optimize", "latency", "batch"],
|
|
23
|
+
"data-model": ["schema", "migration", "table", "column", "relation", "model", "entity"],
|
|
24
|
+
"api-design": ["endpoint", "rest", "graphql", "grpc", "route", "api"],
|
|
25
|
+
testing: ["test", "mock", "stub", "fixture", "coverage", "spec"],
|
|
26
|
+
deployment: ["deploy", "docker", "k8s", "ci", "cd", "pipeline", "terraform"],
|
|
27
|
+
implementation: [], // default fallback
|
|
28
|
+
};
|
|
29
|
+
export function parseDecision(text) {
|
|
30
|
+
// Split on rationale separator
|
|
31
|
+
const parts = text.split(RATIONALE_SEPARATORS, 2);
|
|
32
|
+
const summary = (parts[0] ?? text).trim();
|
|
33
|
+
const rationale = parts.length > 1 ? (parts[1] ?? "").trim() : summary;
|
|
34
|
+
// Extract rejected alternatives
|
|
35
|
+
const rejected = [];
|
|
36
|
+
for (const pattern of REJECTION_PATTERNS) {
|
|
37
|
+
const match = text.match(pattern);
|
|
38
|
+
if (match?.[1]) {
|
|
39
|
+
rejected.push(match[1].trim());
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
// Infer domain from keywords
|
|
43
|
+
const lower = text.toLowerCase();
|
|
44
|
+
let domain = "implementation";
|
|
45
|
+
for (const [d, keywords] of Object.entries(DOMAIN_HINTS)) {
|
|
46
|
+
if (keywords.some((k) => lower.includes(k))) {
|
|
47
|
+
domain = d;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return { summary, rationale, rejected_alternatives: rejected, domain };
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=record-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-parser.js","sourceRoot":"","sources":["../../src/engine/record-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,gDAAgD;AAChD,MAAM,oBAAoB,GAAG,iDAAiD,CAAC;AAE/E,qDAAqD;AACrD,MAAM,kBAAkB,GAAG;IACzB,uDAAuD;IACvD,6DAA6D;IAC7D,8DAA8D;IAC9D,sDAAsD;CACvD,CAAC;AAEF,sCAAsC;AACtC,MAAM,YAAY,GAA6B;IAC7C,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC;IAC1G,QAAQ,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,CAAC;IAC5E,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC;IACrF,YAAY,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC;IACvF,YAAY,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;IACrE,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,CAAC;IAChE,UAAU,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,CAAC;IAC5E,cAAc,EAAE,EAAE,EAAE,mBAAmB;CACxC,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,+BAA+B;IAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,EAAE,CAAC,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;IAEvE,gCAAgC;IAChC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,OAAO,IAAI,kBAAkB,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAClC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACf,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,6BAA6B;IAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,IAAI,MAAM,GAAG,gBAAgB,CAAC;IAC9B,KAAK,MAAM,CAAC,CAAC,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;QACzD,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,MAAM,GAAG,CAAC,CAAC;YACX,MAAM;QACR,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AACzE,CAAC"}
|
package/dist/instructions.d.ts
CHANGED
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
* Condensed version of the 3 mandatory gates from docs/CLAUDE_TEMPLATE.md.
|
|
4
4
|
* Sent in the MCP initialize response so any MCP client gets workflow guidance.
|
|
5
5
|
*/
|
|
6
|
-
export declare const TWINING_INSTRUCTIONS = "# Twining \u2014 Agent Coordination\n\nTwining provides persistent project memory: decisions survive context resets, new sessions start informed, and multi-agent work stays coordinated. State lives in `.twining/` as plain files.\n\n##
|
|
6
|
+
export declare const TWINING_INSTRUCTIONS = "# Twining \u2014 Agent Coordination\n\nTwining provides persistent project memory: decisions survive context resets, new sessions start informed, and multi-agent work stays coordinated. State lives in `.twining/` as plain files.\n\n## 2 Mandatory Gates\n\n### Gate 1: Context Assembly (BEFORE working)\nYour FIRST tool call MUST be `twining_assemble` with your task description and scope. Do not read files or make changes until assemble returns. Also call `twining_why` on files you plan to modify.\n\n### Gate 2: Record (BEFORE committing or ending)\nCall `twining_record` with a summary and any decisions before every `git commit` or session end. Write decisions as natural sentences: \"Chose X over Y \u2014 reason\". The server handles routing to the decision store and blackboard.\n\n## Key Conventions\n- **Scopes** use path-prefix semantics: `\"src/auth/\"` not `\"project\"` \u2014 use the narrowest scope that fits\n- Never skip `twining_assemble` before work or `twining_record` before committing\n\n## Core Tools\n- **twining_assemble** \u2014 orient before working (Gate 1)\n- **twining_record** \u2014 record what you did before committing/ending (Gate 2)\n- **twining_post** \u2014 share findings, warnings, or needs during work\n- **twining_why** \u2014 check what decisions constrain a file before modifying it\n";
|
|
7
7
|
//# sourceMappingURL=instructions.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../src/instructions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,oBAAoB
|
|
1
|
+
{"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../src/instructions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,eAAO,MAAM,oBAAoB,szCAqBhC,CAAC"}
|
package/dist/instructions.js
CHANGED
|
@@ -7,31 +7,22 @@ export const TWINING_INSTRUCTIONS = `# Twining — Agent Coordination
|
|
|
7
7
|
|
|
8
8
|
Twining provides persistent project memory: decisions survive context resets, new sessions start informed, and multi-agent work stays coordinated. State lives in \`.twining/\` as plain files.
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## 2 Mandatory Gates
|
|
11
11
|
|
|
12
12
|
### Gate 1: Context Assembly (BEFORE working)
|
|
13
13
|
Your FIRST tool call MUST be \`twining_assemble\` with your task description and scope. Do not read files or make changes until assemble returns. Also call \`twining_why\` on files you plan to modify.
|
|
14
14
|
|
|
15
|
-
### Gate 2:
|
|
16
|
-
Call \`
|
|
17
|
-
|
|
18
|
-
### Gate 3: Status & Handoff (BEFORE completing)
|
|
19
|
-
Post a \`status\` entry via \`twining_post\` summarizing what you did. Link commits via \`twining_link_commit\`. On complex tasks, call \`twining_verify\` to check decision hygiene.
|
|
15
|
+
### Gate 2: Record (BEFORE committing or ending)
|
|
16
|
+
Call \`twining_record\` with a summary and any decisions before every \`git commit\` or session end. Write decisions as natural sentences: "Chose X over Y — reason". The server handles routing to the decision store and blackboard.
|
|
20
17
|
|
|
21
18
|
## Key Conventions
|
|
22
19
|
- **Scopes** use path-prefix semantics: \`"src/auth/"\` not \`"project"\` — use the narrowest scope that fits
|
|
23
|
-
-
|
|
24
|
-
- **Domains**: architecture, implementation, testing, deployment, security, performance, api-design, data-model
|
|
25
|
-
- Never use \`twining_post\` with entry_type "decision" — always use \`twining_decide\`
|
|
26
|
-
- Never skip \`twining_assemble\` before work or \`twining_post\` status before handoff
|
|
20
|
+
- Never skip \`twining_assemble\` before work or \`twining_record\` before committing
|
|
27
21
|
|
|
28
|
-
##
|
|
29
|
-
- **
|
|
30
|
-
- **
|
|
31
|
-
- **
|
|
32
|
-
- **
|
|
33
|
-
- **Verification**: twining_verify
|
|
34
|
-
- **Lifecycle**: twining_status, twining_archive, twining_export
|
|
35
|
-
- **Coordination**: twining_agents, twining_register, twining_discover, twining_delegate, twining_handoff, twining_acknowledge
|
|
22
|
+
## Core Tools
|
|
23
|
+
- **twining_assemble** — orient before working (Gate 1)
|
|
24
|
+
- **twining_record** — record what you did before committing/ending (Gate 2)
|
|
25
|
+
- **twining_post** — share findings, warnings, or needs during work
|
|
26
|
+
- **twining_why** — check what decisions constrain a file before modifying it
|
|
36
27
|
`;
|
|
37
28
|
//# sourceMappingURL=instructions.js.map
|
package/dist/instructions.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instructions.js","sourceRoot":"","sources":["../src/instructions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG
|
|
1
|
+
{"version":3,"file":"instructions.js","sourceRoot":"","sources":["../src/instructions.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,CAAC,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;CAqBnC,CAAC"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAmCpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAKpE;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,SAAS,CAAC;IAClB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,kBAAkB,EAAE,aAAa,CAAC;CAClD;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CA6K/D"}
|
package/dist/server.js
CHANGED
|
@@ -26,6 +26,7 @@ import { SearchEngine } from "./embeddings/search.js";
|
|
|
26
26
|
import { registerBlackboardTools } from "./tools/blackboard-tools.js";
|
|
27
27
|
import { registerDecisionTools } from "./tools/decision-tools.js";
|
|
28
28
|
import { registerContextTools } from "./tools/context-tools.js";
|
|
29
|
+
import { registerRecordTools } from "./tools/record-tools.js";
|
|
29
30
|
import { registerLifecycleTools } from "./tools/lifecycle-tools.js";
|
|
30
31
|
import { registerGraphTools } from "./tools/graph-tools.js";
|
|
31
32
|
import { registerVerifyTools } from "./tools/verify-tools.js";
|
|
@@ -35,6 +36,8 @@ import { AgentStore } from "./storage/agent-store.js";
|
|
|
35
36
|
import { HandoffStore } from "./storage/handoff-store.js";
|
|
36
37
|
import { CoordinationEngine } from "./engine/coordination.js";
|
|
37
38
|
import { registerCoordinationTools } from "./tools/coordination-tools.js";
|
|
39
|
+
import { HousekeepingEngine } from "./engine/housekeeping.js";
|
|
40
|
+
import { registerHousekeepingTools } from "./tools/housekeeping-tools.js";
|
|
38
41
|
import { MetricsCollector } from "./analytics/metrics-collector.js";
|
|
39
42
|
import { createInstrumentedServer } from "./analytics/instrumented-server.js";
|
|
40
43
|
import { TWINING_INSTRUCTIONS } from "./instructions.js";
|
|
@@ -79,6 +82,8 @@ export function createServer(projectRoot) {
|
|
|
79
82
|
// Create verify engine
|
|
80
83
|
const verifyEngine = new VerifyEngine(decisionStore, blackboardStore, blackboardEngine, graphEngine, projectRoot);
|
|
81
84
|
verifyEngine.setAssemblyChecker((agentId) => contextAssembler.hasRecentAssembly(agentId));
|
|
85
|
+
// Create housekeeping engine
|
|
86
|
+
const housekeepingEngine = new HousekeepingEngine(twiningDir, blackboardStore, decisionStore, archiver, graphEngine);
|
|
82
87
|
// Create exporter
|
|
83
88
|
const exporter = new Exporter(blackboardStore, decisionStore, graphStore);
|
|
84
89
|
// Process pending posts and actions (fire-and-forget, non-fatal)
|
|
@@ -105,6 +110,8 @@ export function createServer(projectRoot) {
|
|
|
105
110
|
const toolMode = config.tools?.mode ?? "full";
|
|
106
111
|
const fullSurface = config.tools?.full_surface ?? false;
|
|
107
112
|
// Core tools (always registered in both full and lite modes)
|
|
113
|
+
registerRecordTools(server, blackboardEngine, decisionEngine, projectRoot);
|
|
114
|
+
registerHousekeepingTools(server, housekeepingEngine);
|
|
108
115
|
registerBlackboardTools(server, blackboardEngine, { fullSurface });
|
|
109
116
|
registerDecisionTools(server, decisionEngine, { fullSurface });
|
|
110
117
|
registerContextTools(server, contextAssembler, { fullSurface });
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { HousekeepingEngine } from "../engine/housekeeping.js";
|
|
3
|
+
export declare function registerHousekeepingTools(server: McpServer, housekeepingEngine: HousekeepingEngine): void;
|
|
4
|
+
//# sourceMappingURL=housekeeping-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"housekeeping-tools.d.ts","sourceRoot":"","sources":["../../src/tools/housekeeping-tools.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAGpE,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,SAAS,EACjB,kBAAkB,EAAE,kBAAkB,GACrC,IAAI,CA6CN"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool handler for twining_housekeeping — periodic store maintenance.
|
|
3
|
+
* Dry-run by default. Pass execute: true to apply changes.
|
|
4
|
+
*/
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
import { toolResult, toolError } from "../utils/errors.js";
|
|
7
|
+
export function registerHousekeepingTools(server, housekeepingEngine) {
|
|
8
|
+
server.registerTool("twining_housekeeping", {
|
|
9
|
+
description: "Run periodic maintenance on Twining stores. Preview by default (dry run). " +
|
|
10
|
+
"Archives old entries, removes duplicates, surfaces stale decisions and dangling warnings, " +
|
|
11
|
+
"prunes orphaned graph entities, and rotates old metrics. " +
|
|
12
|
+
"Pass execute: true to apply changes.",
|
|
13
|
+
inputSchema: {
|
|
14
|
+
execute: z
|
|
15
|
+
.boolean()
|
|
16
|
+
.optional()
|
|
17
|
+
.describe("Set to true to apply changes. Default is false (preview only)."),
|
|
18
|
+
promote_provisionals: z
|
|
19
|
+
.boolean()
|
|
20
|
+
.optional()
|
|
21
|
+
.describe("Set to true to auto-promote stale provisional decisions to active. Default is false (report only)."),
|
|
22
|
+
stale_days: z
|
|
23
|
+
.number()
|
|
24
|
+
.optional()
|
|
25
|
+
.describe("Flag provisional decisions older than this many days (default: 7)"),
|
|
26
|
+
metrics_retention_days: z
|
|
27
|
+
.number()
|
|
28
|
+
.optional()
|
|
29
|
+
.describe("Remove metrics older than this many days (default: 30)"),
|
|
30
|
+
},
|
|
31
|
+
}, async (args) => {
|
|
32
|
+
try {
|
|
33
|
+
const result = await housekeepingEngine.run({
|
|
34
|
+
execute: args.execute,
|
|
35
|
+
promote_provisionals: args.promote_provisionals,
|
|
36
|
+
stale_days: args.stale_days,
|
|
37
|
+
metrics_retention_days: args.metrics_retention_days,
|
|
38
|
+
});
|
|
39
|
+
return toolResult(result);
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
return toolError(e instanceof Error ? e.message : "Unknown error", "INTERNAL_ERROR");
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=housekeeping-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"housekeeping-tools.js","sourceRoot":"","sources":["../../src/tools/housekeeping-tools.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,UAAU,yBAAyB,CACvC,MAAiB,EACjB,kBAAsC;IAEtC,MAAM,CAAC,YAAY,CACjB,sBAAsB,EACtB;QACE,WAAW,EACT,4EAA4E;YAC5E,4FAA4F;YAC5F,2DAA2D;YAC3D,sCAAsC;QACxC,WAAW,EAAE;YACX,OAAO,EAAE,CAAC;iBACP,OAAO,EAAE;iBACT,QAAQ,EAAE;iBACV,QAAQ,CAAC,gEAAgE,CAAC;YAC7E,oBAAoB,EAAE,CAAC;iBACpB,OAAO,EAAE;iBACT,QAAQ,EAAE;iBACV,QAAQ,CAAC,oGAAoG,CAAC;YACjH,UAAU,EAAE,CAAC;iBACV,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,mEAAmE,CAAC;YAChF,sBAAsB,EAAE,CAAC;iBACtB,MAAM,EAAE;iBACR,QAAQ,EAAE;iBACV,QAAQ,CAAC,wDAAwD,CAAC;SACtE;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,GAAG,CAAC;gBAC1C,OAAO,EAAE,IAAI,CAAC,OAAO;gBACrB,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;gBAC/C,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;aACpD,CAAC,CAAC;YACH,OAAO,UAAU,CAAC,MAAM,CAAC,CAAC;QAC5B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,SAAS,CACd,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAChD,gBAAgB,CACjB,CAAC;QACJ,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import type { BlackboardEngine } from "../engine/blackboard.js";
|
|
3
|
+
import type { DecisionEngine } from "../engine/decisions.js";
|
|
4
|
+
export declare function registerRecordTools(server: McpServer, blackboardEngine: BlackboardEngine, decisionEngine: DecisionEngine, projectRoot: string): void;
|
|
5
|
+
//# sourceMappingURL=record-tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-tools.d.ts","sourceRoot":"","sources":["../../src/tools/record-tools.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAkD7D,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,gBAAgB,EAAE,gBAAgB,EAClC,cAAc,EAAE,cAAc,EAC9B,WAAW,EAAE,MAAM,GAClB,IAAI,CAuLN"}
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool handler for twining_record — the unified recording tool.
|
|
3
|
+
* Collapses twining_decide + twining_post(status) into one natural-language call.
|
|
4
|
+
* Always creates a status post; optionally creates decision records and findings.
|
|
5
|
+
*/
|
|
6
|
+
import { execFileSync } from "node:child_process";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { parseDecision } from "../engine/record-parser.js";
|
|
9
|
+
import { toolResult, toolError, TwiningError } from "../utils/errors.js";
|
|
10
|
+
/**
|
|
11
|
+
* Infer scope from git diff when not explicitly provided.
|
|
12
|
+
* Finds the common path prefix of changed files.
|
|
13
|
+
*/
|
|
14
|
+
function inferScopeFromGit(projectRoot) {
|
|
15
|
+
try {
|
|
16
|
+
const output = execFileSync("git", ["diff", "--name-only", "HEAD"], {
|
|
17
|
+
cwd: projectRoot,
|
|
18
|
+
encoding: "utf-8",
|
|
19
|
+
timeout: 5000,
|
|
20
|
+
}).trim();
|
|
21
|
+
if (!output)
|
|
22
|
+
return null;
|
|
23
|
+
const files = output.split("\n").filter(Boolean);
|
|
24
|
+
if (files.length === 0)
|
|
25
|
+
return null;
|
|
26
|
+
// Find common path prefix
|
|
27
|
+
const parts = files[0].split("/");
|
|
28
|
+
let prefix = "";
|
|
29
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
30
|
+
const candidate = parts.slice(0, i + 1).join("/") + "/";
|
|
31
|
+
if (files.every((f) => f.startsWith(candidate))) {
|
|
32
|
+
prefix = candidate;
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return prefix || null;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Parse a finding string, detecting "warning:" or "need:" prefixes for entry_type.
|
|
46
|
+
* Default entry_type is "finding".
|
|
47
|
+
*/
|
|
48
|
+
function parseFinding(text) {
|
|
49
|
+
const lower = text.toLowerCase();
|
|
50
|
+
if (lower.startsWith("warning:")) {
|
|
51
|
+
return { entry_type: "warning", summary: text.slice("warning:".length).trim() };
|
|
52
|
+
}
|
|
53
|
+
if (lower.startsWith("need:")) {
|
|
54
|
+
return { entry_type: "need", summary: text.slice("need:".length).trim() };
|
|
55
|
+
}
|
|
56
|
+
return { entry_type: "finding", summary: text };
|
|
57
|
+
}
|
|
58
|
+
export function registerRecordTools(server, blackboardEngine, decisionEngine, projectRoot) {
|
|
59
|
+
server.registerTool("twining_record", {
|
|
60
|
+
description: "Record what you did, any choices you made, and anything you discovered. Call before committing or ending a session. " +
|
|
61
|
+
"The summary becomes a status post. Decisions become tracked records with rationale. " +
|
|
62
|
+
"Findings become blackboard entries visible to future agents. Scope is auto-inferred from git diff if omitted.",
|
|
63
|
+
inputSchema: {
|
|
64
|
+
summary: z
|
|
65
|
+
.string()
|
|
66
|
+
.describe("What you did this session — one or two sentences"),
|
|
67
|
+
decisions: z
|
|
68
|
+
.array(z.string())
|
|
69
|
+
.optional()
|
|
70
|
+
.describe('Choices you made, as natural sentences. E.g. ["Chose X over Y — reason", "Used pattern Z because..."]'),
|
|
71
|
+
findings: z
|
|
72
|
+
.array(z.string())
|
|
73
|
+
.optional()
|
|
74
|
+
.describe('Discoveries, warnings, or needs. Prefix with "warning:" or "need:" for severity. ' +
|
|
75
|
+
'E.g. ["Auth tokens stored in localStorage — fails SOC2", "warning: No token rotation exists", "need: Add rate limiting before launch"]'),
|
|
76
|
+
assumptions: z
|
|
77
|
+
.array(z.string())
|
|
78
|
+
.optional()
|
|
79
|
+
.describe('Conditions your decisions depend on. E.g. ["Data is relational", "No strict ordering required"]'),
|
|
80
|
+
constraints: z
|
|
81
|
+
.array(z.string())
|
|
82
|
+
.optional()
|
|
83
|
+
.describe('What limited your options. E.g. ["Must support Node 18+", "Cannot add new dependencies"]'),
|
|
84
|
+
affected_files: z
|
|
85
|
+
.array(z.string())
|
|
86
|
+
.optional()
|
|
87
|
+
.describe("File paths you changed or that are affected by your decisions"),
|
|
88
|
+
affected_symbols: z
|
|
89
|
+
.array(z.string())
|
|
90
|
+
.optional()
|
|
91
|
+
.describe("Function/class/method names affected by your decisions"),
|
|
92
|
+
depends_on: z
|
|
93
|
+
.array(z.string())
|
|
94
|
+
.optional()
|
|
95
|
+
.describe("IDs of prior decisions that your decisions depend on (from twining_assemble or twining_why output)"),
|
|
96
|
+
supersedes: z
|
|
97
|
+
.string()
|
|
98
|
+
.optional()
|
|
99
|
+
.describe("ID of a prior decision that your work replaces or invalidates"),
|
|
100
|
+
reversible: z
|
|
101
|
+
.boolean()
|
|
102
|
+
.optional()
|
|
103
|
+
.describe("Whether your decisions are easily reversible (default: true)"),
|
|
104
|
+
commit_hash: z
|
|
105
|
+
.string()
|
|
106
|
+
.optional()
|
|
107
|
+
.describe("Git commit hash to associate with these decisions"),
|
|
108
|
+
scope: z
|
|
109
|
+
.string()
|
|
110
|
+
.optional()
|
|
111
|
+
.describe('Area of codebase affected. Auto-inferred from git diff if omitted.'),
|
|
112
|
+
agent_id: z
|
|
113
|
+
.string()
|
|
114
|
+
.optional()
|
|
115
|
+
.describe("Agent identifier (default: main)"),
|
|
116
|
+
},
|
|
117
|
+
}, async (args) => {
|
|
118
|
+
try {
|
|
119
|
+
// Auto-infer scope from git diff if not provided
|
|
120
|
+
const scope = args.scope ?? inferScopeFromGit(projectRoot) ?? "project";
|
|
121
|
+
const agentId = args.agent_id ?? "main";
|
|
122
|
+
const createdDecisions = [];
|
|
123
|
+
const createdFindings = [];
|
|
124
|
+
// 1. Always create a status post
|
|
125
|
+
const detailParts = [];
|
|
126
|
+
if (args.decisions?.length)
|
|
127
|
+
detailParts.push(`Decisions: ${args.decisions.join("; ")}`);
|
|
128
|
+
if (args.findings?.length)
|
|
129
|
+
detailParts.push(`Findings: ${args.findings.join("; ")}`);
|
|
130
|
+
const statusEntry = await blackboardEngine.post({
|
|
131
|
+
entry_type: "status",
|
|
132
|
+
summary: args.summary,
|
|
133
|
+
detail: detailParts.join("\n"),
|
|
134
|
+
tags: ["session-record"],
|
|
135
|
+
scope,
|
|
136
|
+
agent_id: agentId,
|
|
137
|
+
});
|
|
138
|
+
// 2. Create decision records from natural language
|
|
139
|
+
if (args.decisions?.length) {
|
|
140
|
+
for (const text of args.decisions) {
|
|
141
|
+
const parsed = parseDecision(text);
|
|
142
|
+
try {
|
|
143
|
+
const decision = await decisionEngine.decide({
|
|
144
|
+
domain: parsed.domain,
|
|
145
|
+
scope,
|
|
146
|
+
summary: parsed.summary,
|
|
147
|
+
context: args.summary,
|
|
148
|
+
rationale: parsed.rationale,
|
|
149
|
+
alternatives: parsed.rejected_alternatives.map((alt) => ({
|
|
150
|
+
option: alt,
|
|
151
|
+
reason_rejected: "Not chosen",
|
|
152
|
+
})),
|
|
153
|
+
assumptions: args.assumptions,
|
|
154
|
+
constraints: args.constraints,
|
|
155
|
+
depends_on: args.depends_on,
|
|
156
|
+
supersedes: args.supersedes,
|
|
157
|
+
reversible: args.reversible,
|
|
158
|
+
confidence: "medium",
|
|
159
|
+
affected_files: args.affected_files ?? [],
|
|
160
|
+
affected_symbols: args.affected_symbols ?? [],
|
|
161
|
+
commit_hash: args.commit_hash,
|
|
162
|
+
agent_id: agentId,
|
|
163
|
+
});
|
|
164
|
+
createdDecisions.push({
|
|
165
|
+
id: decision.id,
|
|
166
|
+
summary: parsed.summary,
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
// Decision creation failure is non-fatal — status post is the minimum
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
// 3. Create finding/warning/need entries
|
|
175
|
+
if (args.findings?.length) {
|
|
176
|
+
for (const text of args.findings) {
|
|
177
|
+
const parsed = parseFinding(text);
|
|
178
|
+
try {
|
|
179
|
+
const entry = await blackboardEngine.post({
|
|
180
|
+
entry_type: parsed.entry_type,
|
|
181
|
+
summary: parsed.summary,
|
|
182
|
+
detail: "",
|
|
183
|
+
tags: ["session-record"],
|
|
184
|
+
scope,
|
|
185
|
+
agent_id: agentId,
|
|
186
|
+
});
|
|
187
|
+
createdFindings.push({
|
|
188
|
+
id: entry.id,
|
|
189
|
+
entry_type: parsed.entry_type,
|
|
190
|
+
summary: parsed.summary,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
catch {
|
|
194
|
+
// Non-fatal
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const parts = ["Recorded status"];
|
|
199
|
+
if (createdDecisions.length > 0)
|
|
200
|
+
parts.push(`${createdDecisions.length} decision(s)`);
|
|
201
|
+
if (createdFindings.length > 0)
|
|
202
|
+
parts.push(`${createdFindings.length} finding(s)`);
|
|
203
|
+
return toolResult({
|
|
204
|
+
status_entry_id: statusEntry.id,
|
|
205
|
+
decisions_created: createdDecisions,
|
|
206
|
+
findings_created: createdFindings,
|
|
207
|
+
scope,
|
|
208
|
+
message: parts.join(" + "),
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
catch (e) {
|
|
212
|
+
if (e instanceof TwiningError) {
|
|
213
|
+
return toolError(e.message, e.code);
|
|
214
|
+
}
|
|
215
|
+
return toolError(e instanceof Error ? e.message : "Unknown error", "INTERNAL_ERROR");
|
|
216
|
+
}
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
//# sourceMappingURL=record-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record-tools.js","sourceRoot":"","sources":["../../src/tools/record-tools.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED