codekin 0.4.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -15
- package/bin/codekin.mjs +52 -32
- package/dist/assets/index-B8opKRtJ.js +186 -0
- package/dist/assets/index-wajPH8o6.css +1 -0
- package/dist/index.html +2 -2
- package/package.json +2 -7
- package/server/dist/approval-manager.d.ts +9 -2
- package/server/dist/approval-manager.js +47 -78
- package/server/dist/approval-manager.js.map +1 -1
- package/server/dist/claude-process.d.ts +20 -4
- package/server/dist/claude-process.js +79 -50
- package/server/dist/claude-process.js.map +1 -1
- package/server/dist/commit-event-handler.js.map +1 -1
- package/server/dist/config.d.ts +4 -0
- package/server/dist/config.js +17 -0
- package/server/dist/config.js.map +1 -1
- package/server/dist/diff-manager.d.ts +41 -0
- package/server/dist/diff-manager.js +303 -0
- package/server/dist/diff-manager.js.map +1 -0
- package/server/dist/error-page.d.ts +5 -0
- package/server/dist/error-page.js +144 -0
- package/server/dist/error-page.js.map +1 -0
- package/server/dist/native-permissions.d.ts +44 -0
- package/server/dist/native-permissions.js +163 -0
- package/server/dist/native-permissions.js.map +1 -0
- package/server/dist/orchestrator-children.d.ts +74 -0
- package/server/dist/orchestrator-children.js +287 -0
- package/server/dist/orchestrator-children.js.map +1 -0
- package/server/dist/orchestrator-learning.d.ts +134 -0
- package/server/dist/orchestrator-learning.js +567 -0
- package/server/dist/orchestrator-learning.js.map +1 -0
- package/server/dist/orchestrator-manager.d.ts +25 -0
- package/server/dist/orchestrator-manager.js +353 -0
- package/server/dist/orchestrator-manager.js.map +1 -0
- package/server/dist/orchestrator-memory.d.ts +77 -0
- package/server/dist/orchestrator-memory.js +288 -0
- package/server/dist/orchestrator-memory.js.map +1 -0
- package/server/dist/orchestrator-monitor.d.ts +59 -0
- package/server/dist/orchestrator-monitor.js +238 -0
- package/server/dist/orchestrator-monitor.js.map +1 -0
- package/server/dist/orchestrator-reports.d.ts +45 -0
- package/server/dist/orchestrator-reports.js +124 -0
- package/server/dist/orchestrator-reports.js.map +1 -0
- package/server/dist/orchestrator-routes.d.ts +17 -0
- package/server/dist/orchestrator-routes.js +526 -0
- package/server/dist/orchestrator-routes.js.map +1 -0
- package/server/dist/plan-manager.d.ts +74 -0
- package/server/dist/plan-manager.js +121 -0
- package/server/dist/plan-manager.js.map +1 -0
- package/server/dist/session-archive.js +9 -2
- package/server/dist/session-archive.js.map +1 -1
- package/server/dist/session-manager.d.ts +117 -42
- package/server/dist/session-manager.js +728 -433
- package/server/dist/session-manager.js.map +1 -1
- package/server/dist/session-naming.d.ts +6 -10
- package/server/dist/session-naming.js +60 -62
- package/server/dist/session-naming.js.map +1 -1
- package/server/dist/session-persistence.d.ts +6 -1
- package/server/dist/session-persistence.js +8 -1
- package/server/dist/session-persistence.js.map +1 -1
- package/server/dist/session-restart-scheduler.d.ts +30 -0
- package/server/dist/session-restart-scheduler.js +41 -0
- package/server/dist/session-restart-scheduler.js.map +1 -0
- package/server/dist/session-routes.js +122 -61
- package/server/dist/session-routes.js.map +1 -1
- package/server/dist/stepflow-types.d.ts +1 -1
- package/server/dist/tsconfig.tsbuildinfo +1 -1
- package/server/dist/types.d.ts +40 -5
- package/server/dist/types.js +8 -1
- package/server/dist/types.js.map +1 -1
- package/server/dist/upload-routes.js +7 -1
- package/server/dist/upload-routes.js.map +1 -1
- package/server/dist/version-check.d.ts +17 -0
- package/server/dist/version-check.js +89 -0
- package/server/dist/version-check.js.map +1 -0
- package/server/dist/workflow-engine.d.ts +74 -1
- package/server/dist/workflow-engine.js +20 -1
- package/server/dist/workflow-engine.js.map +1 -1
- package/server/dist/ws-message-handler.js +115 -9
- package/server/dist/ws-message-handler.js.map +1 -1
- package/server/dist/ws-server.js +90 -15
- package/server/dist/ws-server.js.map +1 -1
- package/dist/assets/index-BAdQqYEY.js +0 -182
- package/dist/assets/index-CeZYNLWt.css +0 -1
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrator self-improving memory — extraction, deduplication, aging,
|
|
3
|
+
* pattern learning, and user skill modeling.
|
|
4
|
+
*
|
|
5
|
+
* This module adds the intelligence layer on top of OrchestratorMemory:
|
|
6
|
+
* - Extracts memory candidates from session interactions
|
|
7
|
+
* - Deduplicates against existing memories using FTS similarity
|
|
8
|
+
* - Ages and decays stale items on a schedule
|
|
9
|
+
* - Tracks finding outcomes to improve future triage
|
|
10
|
+
* - Maintains a user skill model that adapts guidance
|
|
11
|
+
* - Records decisions with outcome tracking
|
|
12
|
+
*/
|
|
13
|
+
import { readFileSync, writeFileSync, existsSync, readdirSync } from 'fs';
|
|
14
|
+
import { join } from 'path';
|
|
15
|
+
import { ORCHESTRATOR_DIR } from './orchestrator-manager.js';
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Default TTLs (in days)
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
const TTL_DAYS = {
|
|
20
|
+
user_preference: null, // permanent (pinned)
|
|
21
|
+
repo_context: null, // permanent until repo removed
|
|
22
|
+
decision: 90,
|
|
23
|
+
finding_outcome: 180,
|
|
24
|
+
session_summary: 60,
|
|
25
|
+
journal: 30,
|
|
26
|
+
};
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
// Memory Extraction
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
/**
|
|
31
|
+
* Extract memory candidates from an interaction transcript.
|
|
32
|
+
*
|
|
33
|
+
* This is a rule-based extractor that looks for patterns indicating
|
|
34
|
+
* durable information worth remembering. In future, this could be
|
|
35
|
+
* enhanced with an LLM call for richer extraction.
|
|
36
|
+
*/
|
|
37
|
+
export function extractMemoryCandidates(userMessage, assistantResponse, currentRepo) {
|
|
38
|
+
const candidates = [];
|
|
39
|
+
// Pattern 1: User states a preference ("I prefer...", "always use...", "don't...")
|
|
40
|
+
const prefPatterns = [
|
|
41
|
+
/\bi\s+prefer\b/i,
|
|
42
|
+
/\balways\s+(use|do|run|make)\b/i,
|
|
43
|
+
/\bdon'?t\s+(ever|always)\b/i,
|
|
44
|
+
/\bnever\s+(do|use|run|make)\b/i,
|
|
45
|
+
/\bplease\s+always\b/i,
|
|
46
|
+
/\bmy\s+preference\s+is\b/i,
|
|
47
|
+
];
|
|
48
|
+
for (const pat of prefPatterns) {
|
|
49
|
+
if (pat.test(userMessage)) {
|
|
50
|
+
candidates.push({
|
|
51
|
+
memoryType: 'user_preference',
|
|
52
|
+
title: 'User preference',
|
|
53
|
+
content: userMessage.slice(0, 500),
|
|
54
|
+
scope: null,
|
|
55
|
+
tags: ['preference', 'user-stated'],
|
|
56
|
+
confidence: 0.9,
|
|
57
|
+
});
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Pattern 2: User describes their role or expertise
|
|
62
|
+
const rolePatterns = [
|
|
63
|
+
/\bi(?:'m| am)\s+a\s+(senior|junior|lead|staff|principal|intern)?\s*\w*/i,
|
|
64
|
+
/\bmy\s+role\s+is\b/i,
|
|
65
|
+
/\bi\s+work\s+(?:as|on|in|with)\b/i,
|
|
66
|
+
/\bi(?:'ve| have)\s+been\s+(?:doing|working|coding|programming)\b/i,
|
|
67
|
+
/\bfirst\s+time\s+(?:using|working|touching|doing)\b/i,
|
|
68
|
+
/\bnew\s+to\s+(?:this|react|go|python|typescript|rust|devops)\b/i,
|
|
69
|
+
];
|
|
70
|
+
for (const pat of rolePatterns) {
|
|
71
|
+
if (pat.test(userMessage)) {
|
|
72
|
+
candidates.push({
|
|
73
|
+
memoryType: 'user_preference',
|
|
74
|
+
title: 'User background',
|
|
75
|
+
content: userMessage.slice(0, 500),
|
|
76
|
+
scope: null,
|
|
77
|
+
tags: ['background', 'skill-signal'],
|
|
78
|
+
confidence: 0.7,
|
|
79
|
+
});
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Pattern 3: Explicit "remember" requests
|
|
84
|
+
if (/\bremember\s+(?:that|this|to)\b/i.test(userMessage)) {
|
|
85
|
+
candidates.push({
|
|
86
|
+
memoryType: 'user_preference',
|
|
87
|
+
title: 'User asked to remember',
|
|
88
|
+
content: userMessage.slice(0, 500),
|
|
89
|
+
scope: currentRepo,
|
|
90
|
+
tags: ['explicit-remember'],
|
|
91
|
+
confidence: 1.0,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
// Pattern 4: Decision made ("let's go with...", "decided to...")
|
|
95
|
+
const decisionPatterns = [
|
|
96
|
+
/\blet'?s?\s+(?:go\s+with|use|do|pick|choose)\b/i,
|
|
97
|
+
/\bdecided?\s+(?:to|on|that)\b/i,
|
|
98
|
+
/\bwe(?:'ll| will)\s+(?:go|use|do)\b/i,
|
|
99
|
+
/\bsounds?\s+good\b/i,
|
|
100
|
+
/\byes,?\s+(?:go\s+ahead|do\s+it|proceed|let's)\b/i,
|
|
101
|
+
];
|
|
102
|
+
for (const pat of decisionPatterns) {
|
|
103
|
+
if (pat.test(userMessage)) {
|
|
104
|
+
candidates.push({
|
|
105
|
+
memoryType: 'decision',
|
|
106
|
+
title: 'Decision',
|
|
107
|
+
content: `User: ${userMessage.slice(0, 250)}\nContext: ${assistantResponse.slice(0, 250)}`,
|
|
108
|
+
scope: currentRepo,
|
|
109
|
+
tags: ['decision'],
|
|
110
|
+
confidence: 0.7,
|
|
111
|
+
});
|
|
112
|
+
break;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Pattern 5: Repo-specific context from assistant responses
|
|
116
|
+
if (currentRepo && assistantResponse.length > 200) {
|
|
117
|
+
const repoSignals = [
|
|
118
|
+
/\bthis\s+(?:repo|repository|project|codebase)\s+(?:is|uses|has|was)\b/i,
|
|
119
|
+
/\bthe\s+(?:main|primary)\s+(?:stack|framework|language)\b/i,
|
|
120
|
+
/\barchitecture\s+(?:is|uses|follows)\b/i,
|
|
121
|
+
];
|
|
122
|
+
for (const pat of repoSignals) {
|
|
123
|
+
if (pat.test(assistantResponse)) {
|
|
124
|
+
candidates.push({
|
|
125
|
+
memoryType: 'repo_context',
|
|
126
|
+
title: `Repo context: ${currentRepo.split('/').pop()}`,
|
|
127
|
+
content: assistantResponse.slice(0, 500),
|
|
128
|
+
scope: currentRepo,
|
|
129
|
+
tags: ['repo-context', 'auto-extracted'],
|
|
130
|
+
confidence: 0.6,
|
|
131
|
+
});
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return candidates;
|
|
137
|
+
}
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
// Deduplication
|
|
140
|
+
// ---------------------------------------------------------------------------
|
|
141
|
+
/**
|
|
142
|
+
* Check if a candidate is a duplicate of an existing memory item.
|
|
143
|
+
* Uses FTS search to find similar items, then compares content overlap.
|
|
144
|
+
*/
|
|
145
|
+
export function findDuplicate(memory, candidate, threshold = 0.85) {
|
|
146
|
+
// Search for similar items by title/content keywords
|
|
147
|
+
const searchTerms = (candidate.title + ' ' + candidate.content)
|
|
148
|
+
.replace(/[^\w\s]/g, ' ')
|
|
149
|
+
.split(/\s+/)
|
|
150
|
+
.filter(w => w.length > 3)
|
|
151
|
+
.slice(0, 5)
|
|
152
|
+
.join(' ');
|
|
153
|
+
if (!searchTerms)
|
|
154
|
+
return null;
|
|
155
|
+
try {
|
|
156
|
+
const similar = memory.search(searchTerms, 5);
|
|
157
|
+
for (const item of similar) {
|
|
158
|
+
// Same type and scope
|
|
159
|
+
if (item.memoryType !== candidate.memoryType)
|
|
160
|
+
continue;
|
|
161
|
+
if (item.scope !== candidate.scope)
|
|
162
|
+
continue;
|
|
163
|
+
// Simple content overlap check
|
|
164
|
+
const similarity = computeOverlap(item.content, candidate.content);
|
|
165
|
+
if (similarity >= threshold)
|
|
166
|
+
return item;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
// FTS query may fail on unusual input — not a problem
|
|
171
|
+
}
|
|
172
|
+
return null;
|
|
173
|
+
}
|
|
174
|
+
/** Compute word-level Jaccard similarity between two texts. */
|
|
175
|
+
function computeOverlap(a, b) {
|
|
176
|
+
const wordsA = new Set(a.toLowerCase().split(/\s+/).filter(w => w.length > 2));
|
|
177
|
+
const wordsB = new Set(b.toLowerCase().split(/\s+/).filter(w => w.length > 2));
|
|
178
|
+
if (wordsA.size === 0 || wordsB.size === 0)
|
|
179
|
+
return 0;
|
|
180
|
+
let intersection = 0;
|
|
181
|
+
for (const w of wordsA) {
|
|
182
|
+
if (wordsB.has(w))
|
|
183
|
+
intersection++;
|
|
184
|
+
}
|
|
185
|
+
return intersection / (wordsA.size + wordsB.size - intersection);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Smart upsert: insert candidate if no duplicate exists, update if similar.
|
|
189
|
+
* Returns the memory item ID and whether it was new or updated.
|
|
190
|
+
*/
|
|
191
|
+
export function smartUpsert(memory, candidate, sourceRef = null) {
|
|
192
|
+
const duplicate = findDuplicate(memory, candidate);
|
|
193
|
+
if (duplicate) {
|
|
194
|
+
// If the new candidate has higher confidence, update
|
|
195
|
+
if (candidate.confidence > duplicate.confidence) {
|
|
196
|
+
const id = memory.upsert({
|
|
197
|
+
id: duplicate.id,
|
|
198
|
+
...candidate,
|
|
199
|
+
sourceRef,
|
|
200
|
+
isPinned: duplicate.isPinned,
|
|
201
|
+
expiresAt: duplicate.expiresAt,
|
|
202
|
+
});
|
|
203
|
+
return { id, action: 'updated' };
|
|
204
|
+
}
|
|
205
|
+
return { id: duplicate.id, action: 'skipped' };
|
|
206
|
+
}
|
|
207
|
+
// Compute expiry based on type
|
|
208
|
+
const ttlDays = TTL_DAYS[candidate.memoryType];
|
|
209
|
+
const expiresAt = ttlDays
|
|
210
|
+
? new Date(Date.now() + ttlDays * 24 * 60 * 60 * 1000).toISOString()
|
|
211
|
+
: null;
|
|
212
|
+
const id = memory.upsert({
|
|
213
|
+
...candidate,
|
|
214
|
+
sourceRef,
|
|
215
|
+
isPinned: candidate.memoryType === 'user_preference',
|
|
216
|
+
expiresAt,
|
|
217
|
+
});
|
|
218
|
+
return { id, action: 'inserted' };
|
|
219
|
+
}
|
|
220
|
+
// ---------------------------------------------------------------------------
|
|
221
|
+
// Aging & Decay
|
|
222
|
+
// ---------------------------------------------------------------------------
|
|
223
|
+
/**
|
|
224
|
+
* Run the aging/decay cycle:
|
|
225
|
+
* 1. Expire items past their TTL
|
|
226
|
+
* 2. Compact old journal entries into monthly summaries
|
|
227
|
+
* 3. Decay confidence of items that haven't been accessed recently
|
|
228
|
+
*/
|
|
229
|
+
export function runAgingCycle(memory) {
|
|
230
|
+
// 1. Expire stale items
|
|
231
|
+
const expired = memory.expireStale();
|
|
232
|
+
// 2. Compact old journal entries (older than 30 days) into monthly summaries
|
|
233
|
+
const compacted = compactOldJournals();
|
|
234
|
+
// 3. Decay confidence of old, non-pinned items that haven't been updated
|
|
235
|
+
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString();
|
|
236
|
+
const oldItems = memory.list({ limit: 100 })
|
|
237
|
+
.filter(item => !item.isPinned &&
|
|
238
|
+
item.updatedAt < thirtyDaysAgo &&
|
|
239
|
+
item.confidence > 0.3);
|
|
240
|
+
let decayed = 0;
|
|
241
|
+
for (const item of oldItems) {
|
|
242
|
+
const newConfidence = Math.max(0.3, item.confidence * 0.95); // 5% decay
|
|
243
|
+
if (newConfidence < item.confidence) {
|
|
244
|
+
memory.upsert({
|
|
245
|
+
id: item.id,
|
|
246
|
+
memoryType: item.memoryType,
|
|
247
|
+
scope: item.scope,
|
|
248
|
+
title: item.title,
|
|
249
|
+
content: item.content,
|
|
250
|
+
sourceRef: item.sourceRef,
|
|
251
|
+
confidence: newConfidence,
|
|
252
|
+
expiresAt: item.expiresAt,
|
|
253
|
+
isPinned: item.isPinned,
|
|
254
|
+
tags: item.tags,
|
|
255
|
+
});
|
|
256
|
+
decayed++;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return { expired, compacted, decayed };
|
|
260
|
+
}
|
|
261
|
+
/** Compact journal entries older than 30 days into monthly summary files. */
|
|
262
|
+
function compactOldJournals() {
|
|
263
|
+
const journalDir = join(ORCHESTRATOR_DIR, 'journal');
|
|
264
|
+
if (!existsSync(journalDir))
|
|
265
|
+
return 0;
|
|
266
|
+
const thirtyDaysAgo = new Date(Date.now() - 30 * 24 * 60 * 60 * 1000);
|
|
267
|
+
const cutoffDate = thirtyDaysAgo.toISOString().slice(0, 10);
|
|
268
|
+
let files;
|
|
269
|
+
try {
|
|
270
|
+
files = readdirSync(journalDir).filter(f => f.endsWith('.md'));
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
return 0;
|
|
274
|
+
}
|
|
275
|
+
// Group old files by month
|
|
276
|
+
const monthGroups = new Map();
|
|
277
|
+
for (const file of files) {
|
|
278
|
+
const dateMatch = file.match(/^(\d{4}-\d{2})-\d{2}\.md$/);
|
|
279
|
+
if (!dateMatch)
|
|
280
|
+
continue;
|
|
281
|
+
const fileDate = file.replace('.md', '');
|
|
282
|
+
if (fileDate >= cutoffDate)
|
|
283
|
+
continue; // not old enough
|
|
284
|
+
const month = dateMatch[1];
|
|
285
|
+
const group = monthGroups.get(month) ?? [];
|
|
286
|
+
group.push(file);
|
|
287
|
+
monthGroups.set(month, group);
|
|
288
|
+
}
|
|
289
|
+
// Compact each month into a summary file
|
|
290
|
+
let compacted = 0;
|
|
291
|
+
for (const [month, monthFiles] of monthGroups) {
|
|
292
|
+
const summaryFile = join(journalDir, `${month}-summary.md`);
|
|
293
|
+
if (existsSync(summaryFile))
|
|
294
|
+
continue; // already compacted
|
|
295
|
+
const contents = [`# Journal Summary: ${month}\n`];
|
|
296
|
+
for (const file of monthFiles.sort()) {
|
|
297
|
+
const filePath = join(journalDir, file);
|
|
298
|
+
try {
|
|
299
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
300
|
+
contents.push(`## ${file.replace('.md', '')}\n${content}\n`);
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
writeFileSync(summaryFile, contents.join('\n'), 'utf-8');
|
|
307
|
+
compacted += monthFiles.length;
|
|
308
|
+
// Note: we don't delete originals — the orchestrator can do that if it wants
|
|
309
|
+
}
|
|
310
|
+
return compacted;
|
|
311
|
+
}
|
|
312
|
+
// ---------------------------------------------------------------------------
|
|
313
|
+
// Pattern Learning — Finding Outcomes
|
|
314
|
+
// ---------------------------------------------------------------------------
|
|
315
|
+
/**
|
|
316
|
+
* Record the outcome of a finding triage decision.
|
|
317
|
+
*/
|
|
318
|
+
export function recordFindingOutcome(memory, outcome) {
|
|
319
|
+
return memory.upsert({
|
|
320
|
+
memoryType: 'finding_outcome',
|
|
321
|
+
title: `${outcome.action}: ${outcome.category} finding in ${outcome.repo.split('/').pop()}`,
|
|
322
|
+
content: JSON.stringify(outcome),
|
|
323
|
+
scope: outcome.repo,
|
|
324
|
+
sourceRef: outcome.sessionId,
|
|
325
|
+
confidence: 0.9,
|
|
326
|
+
isPinned: false,
|
|
327
|
+
expiresAt: new Date(Date.now() + 180 * 24 * 60 * 60 * 1000).toISOString(),
|
|
328
|
+
tags: [outcome.category, outcome.severity, outcome.action],
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Analyze past finding outcomes to compute a triage recommendation.
|
|
333
|
+
* Returns the likely action and confidence based on historical patterns.
|
|
334
|
+
*/
|
|
335
|
+
export function getTriageRecommendation(memory, category, severity, repo) {
|
|
336
|
+
// Get all finding outcomes for this category, prefer repo-specific matches
|
|
337
|
+
const allOutcomes = memory.list({ memoryType: 'finding_outcome', limit: 50 })
|
|
338
|
+
.map(item => {
|
|
339
|
+
try {
|
|
340
|
+
return JSON.parse(item.content);
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
return null;
|
|
344
|
+
}
|
|
345
|
+
})
|
|
346
|
+
.filter((o) => o !== null)
|
|
347
|
+
.filter(o => o.category === category);
|
|
348
|
+
// Prefer repo-specific outcomes if available
|
|
349
|
+
const repoSpecific = repo ? allOutcomes.filter(o => o.repo === repo) : [];
|
|
350
|
+
const outcomes = repoSpecific.length >= 2 ? repoSpecific : allOutcomes;
|
|
351
|
+
if (outcomes.length < 3) {
|
|
352
|
+
return { action: 'unknown', confidence: 0, reason: 'Not enough historical data' };
|
|
353
|
+
}
|
|
354
|
+
// Filter to matching severity
|
|
355
|
+
const bySeverity = outcomes.filter(o => o.severity === severity);
|
|
356
|
+
const pool = bySeverity.length >= 2 ? bySeverity : outcomes;
|
|
357
|
+
// Count actions
|
|
358
|
+
const counts = { implemented: 0, skipped: 0, deferred: 0 };
|
|
359
|
+
for (const o of pool) {
|
|
360
|
+
counts[o.action]++;
|
|
361
|
+
}
|
|
362
|
+
const total = pool.length;
|
|
363
|
+
const implementRate = counts.implemented / total;
|
|
364
|
+
const skipRate = counts.skipped / total;
|
|
365
|
+
// Also factor in success rate of implementations
|
|
366
|
+
const implementations = pool.filter(o => o.action === 'implemented');
|
|
367
|
+
const successRate = implementations.length > 0
|
|
368
|
+
? implementations.filter(o => o.outcome === 'success').length / implementations.length
|
|
369
|
+
: 0;
|
|
370
|
+
if (implementRate > 0.6 && successRate > 0.5) {
|
|
371
|
+
return {
|
|
372
|
+
action: 'implement',
|
|
373
|
+
confidence: Math.min(0.9, implementRate * successRate),
|
|
374
|
+
reason: `${Math.round(implementRate * 100)}% of similar findings were implemented (${Math.round(successRate * 100)}% success rate)`,
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
if (skipRate > 0.6) {
|
|
378
|
+
return {
|
|
379
|
+
action: 'skip',
|
|
380
|
+
confidence: Math.min(0.85, skipRate),
|
|
381
|
+
reason: `${Math.round(skipRate * 100)}% of similar findings were skipped`,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
return {
|
|
385
|
+
action: 'unknown',
|
|
386
|
+
confidence: 0.3,
|
|
387
|
+
reason: `Mixed history: ${counts.implemented} implemented, ${counts.skipped} skipped, ${counts.deferred} deferred`,
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
// ---------------------------------------------------------------------------
|
|
391
|
+
// User Skill Model
|
|
392
|
+
// ---------------------------------------------------------------------------
|
|
393
|
+
const SKILL_PROFILE_FILE = join(ORCHESTRATOR_DIR, 'skill-profile.json');
|
|
394
|
+
/** Load the user's skill profile from disk. */
|
|
395
|
+
export function loadSkillProfile() {
|
|
396
|
+
if (!existsSync(SKILL_PROFILE_FILE))
|
|
397
|
+
return [];
|
|
398
|
+
try {
|
|
399
|
+
return JSON.parse(readFileSync(SKILL_PROFILE_FILE, 'utf-8'));
|
|
400
|
+
}
|
|
401
|
+
catch {
|
|
402
|
+
return [];
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
/** Save the skill profile to disk. */
|
|
406
|
+
export function saveSkillProfile(profile) {
|
|
407
|
+
writeFileSync(SKILL_PROFILE_FILE, JSON.stringify(profile, null, 2), 'utf-8');
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Update the user's skill level for a domain based on observed signals.
|
|
411
|
+
* Signals are things like: "used advanced git rebase", "asked basic TypeScript question",
|
|
412
|
+
* "configured CI pipeline without help".
|
|
413
|
+
*/
|
|
414
|
+
export function updateSkillLevel(domain, signal, indicatedLevel) {
|
|
415
|
+
const profile = loadSkillProfile();
|
|
416
|
+
const existing = profile.find(s => s.domain === domain);
|
|
417
|
+
const now = new Date().toISOString();
|
|
418
|
+
if (existing) {
|
|
419
|
+
// Add signal
|
|
420
|
+
existing.signals.push(signal);
|
|
421
|
+
if (existing.signals.length > 20)
|
|
422
|
+
existing.signals = existing.signals.slice(-20);
|
|
423
|
+
existing.lastUpdated = now;
|
|
424
|
+
// Adjust level — only move up, or down if strong evidence
|
|
425
|
+
const levels = ['beginner', 'intermediate', 'advanced', 'expert'];
|
|
426
|
+
const currentIdx = levels.indexOf(existing.level);
|
|
427
|
+
const newIdx = levels.indexOf(indicatedLevel);
|
|
428
|
+
if (newIdx > currentIdx) {
|
|
429
|
+
// Level up — require confidence
|
|
430
|
+
existing.confidence = Math.min(1, existing.confidence + 0.15);
|
|
431
|
+
if (existing.confidence >= 0.7) {
|
|
432
|
+
existing.level = indicatedLevel;
|
|
433
|
+
existing.confidence = 0.6; // reset after level change
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
else if (newIdx < currentIdx) {
|
|
437
|
+
// Level down — be cautious
|
|
438
|
+
existing.confidence = Math.max(0, existing.confidence - 0.1);
|
|
439
|
+
if (existing.confidence < 0.3) {
|
|
440
|
+
existing.level = indicatedLevel;
|
|
441
|
+
existing.confidence = 0.5;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
// Same level — increase confidence
|
|
446
|
+
existing.confidence = Math.min(1, existing.confidence + 0.1);
|
|
447
|
+
}
|
|
448
|
+
saveSkillProfile(profile);
|
|
449
|
+
return existing;
|
|
450
|
+
}
|
|
451
|
+
// New domain
|
|
452
|
+
const newSkill = {
|
|
453
|
+
domain,
|
|
454
|
+
level: indicatedLevel,
|
|
455
|
+
confidence: 0.5,
|
|
456
|
+
signals: [signal],
|
|
457
|
+
lastUpdated: now,
|
|
458
|
+
};
|
|
459
|
+
profile.push(newSkill);
|
|
460
|
+
saveSkillProfile(profile);
|
|
461
|
+
return newSkill;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Get the user's assessed skill level for a domain.
|
|
465
|
+
* Returns null if we have no data for this domain.
|
|
466
|
+
*/
|
|
467
|
+
export function getSkillLevel(domain) {
|
|
468
|
+
const profile = loadSkillProfile();
|
|
469
|
+
return profile.find(s => s.domain === domain) ?? null;
|
|
470
|
+
}
|
|
471
|
+
/**
|
|
472
|
+
* Get a guidance style recommendation based on the user's overall skill profile.
|
|
473
|
+
*/
|
|
474
|
+
export function getGuidanceStyle() {
|
|
475
|
+
const profile = loadSkillProfile();
|
|
476
|
+
if (profile.length === 0) {
|
|
477
|
+
return { tone: 'collaborative', explainLevel: 'moderate', domains: {} };
|
|
478
|
+
}
|
|
479
|
+
// Compute average skill level
|
|
480
|
+
const levels = { beginner: 0, intermediate: 1, advanced: 2, expert: 3 };
|
|
481
|
+
const avg = profile.reduce((sum, s) => sum + levels[s.level], 0) / profile.length;
|
|
482
|
+
const domains = {};
|
|
483
|
+
for (const s of profile)
|
|
484
|
+
domains[s.domain] = s.level;
|
|
485
|
+
if (avg < 0.8) {
|
|
486
|
+
return { tone: 'tutorial', explainLevel: 'detailed', domains };
|
|
487
|
+
}
|
|
488
|
+
if (avg < 2.0) {
|
|
489
|
+
return { tone: 'collaborative', explainLevel: 'moderate', domains };
|
|
490
|
+
}
|
|
491
|
+
return { tone: 'concise', explainLevel: 'minimal', domains };
|
|
492
|
+
}
|
|
493
|
+
// ---------------------------------------------------------------------------
|
|
494
|
+
// Decision History
|
|
495
|
+
// ---------------------------------------------------------------------------
|
|
496
|
+
/**
|
|
497
|
+
* Record a decision with expected outcome.
|
|
498
|
+
*/
|
|
499
|
+
export function recordDecision(memory, decision) {
|
|
500
|
+
const record = {
|
|
501
|
+
...decision,
|
|
502
|
+
id: `decision-${Date.now()}`,
|
|
503
|
+
timestamp: new Date().toISOString(),
|
|
504
|
+
actualOutcome: null,
|
|
505
|
+
outcomeAssessedAt: null,
|
|
506
|
+
};
|
|
507
|
+
return memory.upsert({
|
|
508
|
+
memoryType: 'decision',
|
|
509
|
+
title: `Decision: ${decision.decision.slice(0, 100)}`,
|
|
510
|
+
content: JSON.stringify(record),
|
|
511
|
+
scope: decision.repo,
|
|
512
|
+
sourceRef: decision.relatedFinding,
|
|
513
|
+
confidence: 0.8,
|
|
514
|
+
isPinned: false,
|
|
515
|
+
expiresAt: new Date(Date.now() + 90 * 24 * 60 * 60 * 1000).toISOString(),
|
|
516
|
+
tags: ['decision'],
|
|
517
|
+
});
|
|
518
|
+
}
|
|
519
|
+
/**
|
|
520
|
+
* Update a decision's actual outcome.
|
|
521
|
+
*/
|
|
522
|
+
export function assessDecisionOutcome(memory, decisionId, actualOutcome) {
|
|
523
|
+
const item = memory.get(decisionId);
|
|
524
|
+
if (!item || item.memoryType !== 'decision')
|
|
525
|
+
return false;
|
|
526
|
+
try {
|
|
527
|
+
const record = JSON.parse(item.content);
|
|
528
|
+
record.actualOutcome = actualOutcome;
|
|
529
|
+
record.outcomeAssessedAt = new Date().toISOString();
|
|
530
|
+
memory.upsert({
|
|
531
|
+
id: item.id,
|
|
532
|
+
memoryType: 'decision',
|
|
533
|
+
title: item.title,
|
|
534
|
+
content: JSON.stringify(record),
|
|
535
|
+
scope: item.scope,
|
|
536
|
+
sourceRef: item.sourceRef,
|
|
537
|
+
confidence: item.confidence,
|
|
538
|
+
isPinned: item.isPinned,
|
|
539
|
+
expiresAt: item.expiresAt,
|
|
540
|
+
tags: item.tags,
|
|
541
|
+
});
|
|
542
|
+
return true;
|
|
543
|
+
}
|
|
544
|
+
catch {
|
|
545
|
+
return false;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* Get decisions that need outcome assessment (older than 7 days, no outcome yet).
|
|
550
|
+
*/
|
|
551
|
+
export function getPendingOutcomeAssessments(memory) {
|
|
552
|
+
const sevenDaysAgo = new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString();
|
|
553
|
+
const decisions = memory.list({ memoryType: 'decision', limit: 50 });
|
|
554
|
+
return decisions
|
|
555
|
+
.map(item => {
|
|
556
|
+
try {
|
|
557
|
+
return JSON.parse(item.content);
|
|
558
|
+
}
|
|
559
|
+
catch {
|
|
560
|
+
return null;
|
|
561
|
+
}
|
|
562
|
+
})
|
|
563
|
+
.filter((d) => d !== null &&
|
|
564
|
+
d.actualOutcome === null &&
|
|
565
|
+
d.timestamp < sevenDaysAgo);
|
|
566
|
+
}
|
|
567
|
+
//# sourceMappingURL=orchestrator-learning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator-learning.js","sourceRoot":"","sources":["../orchestrator-learning.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orchestrator lifecycle manager.
|
|
3
|
+
*
|
|
4
|
+
* Manages the always-on orchestrator session: directory setup, stable ID
|
|
5
|
+
* persistence, and auto-start on server boot. The orchestrator is a standard
|
|
6
|
+
* Claude session with source='orchestrator' that runs in ~/.codekin/orchestrator/.
|
|
7
|
+
*/
|
|
8
|
+
import type { SessionManager } from './session-manager.js';
|
|
9
|
+
export declare const ORCHESTRATOR_DIR: string;
|
|
10
|
+
/** Ensure the orchestrator workspace directory exists with starter files. */
|
|
11
|
+
export declare function ensureOrchestratorDir(): void;
|
|
12
|
+
/** Get or create a stable session UUID that persists across restarts. */
|
|
13
|
+
export declare function getOrCreateOrchestratorId(): string;
|
|
14
|
+
/** Check if a session is the orchestrator session. */
|
|
15
|
+
export declare function isOrchestratorSession(source: string | undefined): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Ensure the orchestrator session exists and is running.
|
|
18
|
+
* Creates it if missing, starts Claude if not alive.
|
|
19
|
+
* Returns the orchestrator session ID.
|
|
20
|
+
*/
|
|
21
|
+
export declare function ensureOrchestratorRunning(sessions: SessionManager): string;
|
|
22
|
+
/**
|
|
23
|
+
* Get the orchestrator session ID if it exists, or null.
|
|
24
|
+
*/
|
|
25
|
+
export declare function getOrchestratorSessionId(sessions: SessionManager): string | null;
|