opencode-cc10x 6.0.21
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 +283 -0
- package/bun.lock +20 -0
- package/dist/agents.d.ts +3 -0
- package/dist/agents.d.ts.map +1 -0
- package/dist/agents.js +483 -0
- package/dist/agents.js.map +1 -0
- package/dist/compatibility-layer.d.ts +18 -0
- package/dist/compatibility-layer.d.ts.map +1 -0
- package/dist/compatibility-layer.js +150 -0
- package/dist/compatibility-layer.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1459 -0
- package/dist/index.js.map +1 -0
- package/dist/intent-detection.d.ts +14 -0
- package/dist/intent-detection.d.ts.map +1 -0
- package/dist/intent-detection.js +121 -0
- package/dist/intent-detection.js.map +1 -0
- package/dist/memory.d.ts +41 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +330 -0
- package/dist/memory.js.map +1 -0
- package/dist/router.d.ts +15 -0
- package/dist/router.d.ts.map +1 -0
- package/dist/router.js +208 -0
- package/dist/router.js.map +1 -0
- package/dist/skills.d.ts +3 -0
- package/dist/skills.d.ts.map +1 -0
- package/dist/skills.js +2790 -0
- package/dist/skills.js.map +1 -0
- package/dist/task-orchestrator.d.ts +46 -0
- package/dist/task-orchestrator.d.ts.map +1 -0
- package/dist/task-orchestrator.js +262 -0
- package/dist/task-orchestrator.js.map +1 -0
- package/dist/workflow-executor.d.ts +29 -0
- package/dist/workflow-executor.d.ts.map +1 -0
- package/dist/workflow-executor.js +414 -0
- package/dist/workflow-executor.js.map +1 -0
- package/install-from-github.mjs +152 -0
- package/install-from-github.sh +106 -0
- package/install.sh +295 -0
- package/opencode.json +118 -0
- package/package.json +41 -0
- package/tsconfig.json +23 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1459 @@
|
|
|
1
|
+
// src/intent-detection.ts
|
|
2
|
+
var INTENT_PRIORITY = ["DEBUG", "PLAN", "REVIEW", "BUILD"];
|
|
3
|
+
var INTENT_KEYWORDS = {
|
|
4
|
+
"DEBUG": [
|
|
5
|
+
"error",
|
|
6
|
+
"bug",
|
|
7
|
+
"fix",
|
|
8
|
+
"broken",
|
|
9
|
+
"crash",
|
|
10
|
+
"fail",
|
|
11
|
+
"debug",
|
|
12
|
+
"troubleshoot",
|
|
13
|
+
"issue",
|
|
14
|
+
"problem",
|
|
15
|
+
"doesn't work",
|
|
16
|
+
"not working",
|
|
17
|
+
"exception",
|
|
18
|
+
"traceback",
|
|
19
|
+
"stack trace",
|
|
20
|
+
"panic",
|
|
21
|
+
"segfault",
|
|
22
|
+
"syntax error",
|
|
23
|
+
"runtime error"
|
|
24
|
+
],
|
|
25
|
+
"PLAN": [
|
|
26
|
+
"plan",
|
|
27
|
+
"design",
|
|
28
|
+
"architect",
|
|
29
|
+
"roadmap",
|
|
30
|
+
"strategy",
|
|
31
|
+
"spec",
|
|
32
|
+
"before we build",
|
|
33
|
+
"how should we",
|
|
34
|
+
"what's the approach",
|
|
35
|
+
"proposal",
|
|
36
|
+
"recommendation",
|
|
37
|
+
"should we use",
|
|
38
|
+
"options",
|
|
39
|
+
"alternatives",
|
|
40
|
+
"research",
|
|
41
|
+
"investigate"
|
|
42
|
+
],
|
|
43
|
+
"REVIEW": [
|
|
44
|
+
"review",
|
|
45
|
+
"audit",
|
|
46
|
+
"check",
|
|
47
|
+
"analyze",
|
|
48
|
+
"assess",
|
|
49
|
+
"what do you think",
|
|
50
|
+
"is this good",
|
|
51
|
+
"evaluate",
|
|
52
|
+
"inspect",
|
|
53
|
+
"examine",
|
|
54
|
+
"critique",
|
|
55
|
+
"feedback",
|
|
56
|
+
"suggestions",
|
|
57
|
+
"improve",
|
|
58
|
+
"optimize"
|
|
59
|
+
],
|
|
60
|
+
"BUILD": [
|
|
61
|
+
"build",
|
|
62
|
+
"implement",
|
|
63
|
+
"create",
|
|
64
|
+
"make",
|
|
65
|
+
"write",
|
|
66
|
+
"add",
|
|
67
|
+
"develop",
|
|
68
|
+
"code",
|
|
69
|
+
"feature",
|
|
70
|
+
"component",
|
|
71
|
+
"app",
|
|
72
|
+
"application",
|
|
73
|
+
"module",
|
|
74
|
+
"class",
|
|
75
|
+
"function",
|
|
76
|
+
"endpoint",
|
|
77
|
+
"api",
|
|
78
|
+
"interface",
|
|
79
|
+
"service",
|
|
80
|
+
"generate",
|
|
81
|
+
"scaffold"
|
|
82
|
+
]
|
|
83
|
+
};
|
|
84
|
+
function detectIntent(message, memory) {
|
|
85
|
+
const lowerMessage = message.toLowerCase();
|
|
86
|
+
const detectedKeywords = [];
|
|
87
|
+
const intentScores = {
|
|
88
|
+
"BUILD": 0,
|
|
89
|
+
"DEBUG": 0,
|
|
90
|
+
"REVIEW": 0,
|
|
91
|
+
"PLAN": 0
|
|
92
|
+
};
|
|
93
|
+
for (const [intent, keywords] of Object.entries(INTENT_KEYWORDS)) {
|
|
94
|
+
for (const keyword of keywords) {
|
|
95
|
+
if (lowerMessage.includes(keyword)) {
|
|
96
|
+
intentScores[intent]++;
|
|
97
|
+
detectedKeywords.push(keyword);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
let selectedIntent = "BUILD";
|
|
102
|
+
let maxScore = intentScores["BUILD"];
|
|
103
|
+
if (intentScores["DEBUG"] > 0) {
|
|
104
|
+
selectedIntent = "DEBUG";
|
|
105
|
+
maxScore = intentScores["DEBUG"];
|
|
106
|
+
} else {
|
|
107
|
+
for (const intent of INTENT_PRIORITY) {
|
|
108
|
+
if (intent === "DEBUG") continue;
|
|
109
|
+
const score = intentScores[intent];
|
|
110
|
+
if (score > maxScore || score === maxScore && INTENT_PRIORITY.indexOf(intent) < INTENT_PRIORITY.indexOf(selectedIntent)) {
|
|
111
|
+
selectedIntent = intent;
|
|
112
|
+
maxScore = score;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const totalPossibleKeywords = INTENT_KEYWORDS[selectedIntent].length;
|
|
117
|
+
const confidence = Math.min(100, Math.round(intentScores[selectedIntent] / Math.max(1, totalPossibleKeywords) * 100));
|
|
118
|
+
const memoryContext = analyzeMemoryContext(memory, selectedIntent);
|
|
119
|
+
if (memoryContext.suggestedIntent && memoryContext.suggestedIntent !== selectedIntent) {
|
|
120
|
+
if (memoryContext.confidence > confidence) {
|
|
121
|
+
selectedIntent = memoryContext.suggestedIntent;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return {
|
|
125
|
+
intent: selectedIntent,
|
|
126
|
+
confidence,
|
|
127
|
+
reasoning: generateReasoning(selectedIntent, detectedKeywords, memoryContext),
|
|
128
|
+
keywords: detectedKeywords
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function analyzeMemoryContext(memory, currentIntent) {
|
|
132
|
+
if (!memory) return { confidence: 0 };
|
|
133
|
+
const activeContext = memory.activeContext || "";
|
|
134
|
+
const patterns = memory.patterns || "";
|
|
135
|
+
const progress = memory.progress || "";
|
|
136
|
+
const combinedContext = `${activeContext} ${patterns} ${progress}`.toLowerCase();
|
|
137
|
+
if (combinedContext.includes("debugging") || combinedContext.includes("investigating")) {
|
|
138
|
+
return { suggestedIntent: "DEBUG", confidence: 70 };
|
|
139
|
+
}
|
|
140
|
+
if (combinedContext.includes("planning") || combinedContext.includes("design")) {
|
|
141
|
+
return { suggestedIntent: "PLAN", confidence: 70 };
|
|
142
|
+
}
|
|
143
|
+
if (combinedContext.includes("reviewing") || combinedContext.includes("audit")) {
|
|
144
|
+
return { suggestedIntent: "REVIEW", confidence: 70 };
|
|
145
|
+
}
|
|
146
|
+
if (combinedContext.includes("building") || combinedContext.includes("implementing")) {
|
|
147
|
+
return { suggestedIntent: "BUILD", confidence: 70 };
|
|
148
|
+
}
|
|
149
|
+
return { confidence: 0 };
|
|
150
|
+
}
|
|
151
|
+
function generateReasoning(intent, keywords, memoryContext) {
|
|
152
|
+
const reasoningParts = [];
|
|
153
|
+
if (keywords.length > 0) {
|
|
154
|
+
reasoningParts.push(`Detected keywords: ${keywords.slice(0, 3).join(", ")}`);
|
|
155
|
+
}
|
|
156
|
+
if (memoryContext.suggestedIntent) {
|
|
157
|
+
reasoningParts.push(`Memory context suggests ${memoryContext.suggestedIntent} workflow`);
|
|
158
|
+
}
|
|
159
|
+
reasoningParts.push(`Selected ${intent} workflow based on priority rules`);
|
|
160
|
+
return reasoningParts.join(". ");
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// src/compatibility-layer.ts
|
|
164
|
+
async function readFile(input, path) {
|
|
165
|
+
try {
|
|
166
|
+
if (typeof input?.readFile === "function") {
|
|
167
|
+
return await input.readFile(path);
|
|
168
|
+
}
|
|
169
|
+
const result = await input.client?.app?.fs?.read(path);
|
|
170
|
+
return result;
|
|
171
|
+
} catch (error) {
|
|
172
|
+
if (error.code === "ENOENT" || error.message?.includes("not found")) {
|
|
173
|
+
throw new Error(`File not found: ${path}`);
|
|
174
|
+
}
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
async function writeFile(input, path, content) {
|
|
179
|
+
try {
|
|
180
|
+
if (typeof input?.writeFile === "function") {
|
|
181
|
+
await input.writeFile(path, content);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
await input.client?.app?.fs?.write(path, content);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
console.error(`Failed to write file ${path}:`, error);
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async function editFile(input, path, options) {
|
|
191
|
+
try {
|
|
192
|
+
if (typeof input?.editFile === "function") {
|
|
193
|
+
await input.editFile(path, options);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
await input.client?.app?.fs?.edit(path, options);
|
|
197
|
+
} catch (error) {
|
|
198
|
+
console.error(`Failed to edit file ${path}:`, error);
|
|
199
|
+
throw error;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// src/memory.ts
|
|
204
|
+
var MEMORY_DIR = ".claude/cc10x";
|
|
205
|
+
var MEMORY_FILES = {
|
|
206
|
+
activeContext: `${MEMORY_DIR}/activeContext.md`,
|
|
207
|
+
patterns: `${MEMORY_DIR}/patterns.md`,
|
|
208
|
+
progress: `${MEMORY_DIR}/progress.md`
|
|
209
|
+
};
|
|
210
|
+
var DEFAULT_ACTIVE_CONTEXT = `# Active Context
|
|
211
|
+
|
|
212
|
+
<!-- CC10X: Do not rename headings. Used as Edit anchors. -->
|
|
213
|
+
|
|
214
|
+
## Current Focus
|
|
215
|
+
- [None yet - first workflow]
|
|
216
|
+
|
|
217
|
+
## Recent Changes
|
|
218
|
+
- [Initial cc10x setup]
|
|
219
|
+
|
|
220
|
+
## Next Steps
|
|
221
|
+
- [Awaiting first task]
|
|
222
|
+
|
|
223
|
+
## Decisions
|
|
224
|
+
- [No decisions recorded yet]
|
|
225
|
+
|
|
226
|
+
## Learnings
|
|
227
|
+
- [No learnings yet]
|
|
228
|
+
|
|
229
|
+
## References
|
|
230
|
+
- Plan: N/A
|
|
231
|
+
- Design: N/A
|
|
232
|
+
- Research: N/A
|
|
233
|
+
|
|
234
|
+
## Blockers
|
|
235
|
+
- [None]
|
|
236
|
+
|
|
237
|
+
## Last Updated
|
|
238
|
+
${(/* @__PURE__ */ new Date()).toISOString()}
|
|
239
|
+
`;
|
|
240
|
+
var DEFAULT_PATTERNS = `# Project Patterns
|
|
241
|
+
|
|
242
|
+
<!-- CC10X: Do not rename headings. Used as Edit anchors. -->
|
|
243
|
+
|
|
244
|
+
## Common Gotchas
|
|
245
|
+
- [List project-specific issues and solutions here]
|
|
246
|
+
|
|
247
|
+
## Code Conventions
|
|
248
|
+
- [Document coding patterns and standards]
|
|
249
|
+
|
|
250
|
+
## Architecture Decisions
|
|
251
|
+
- [Record important architectural choices]
|
|
252
|
+
|
|
253
|
+
## Last Updated
|
|
254
|
+
${(/* @__PURE__ */ new Date()).toISOString()}
|
|
255
|
+
`;
|
|
256
|
+
var DEFAULT_PROGRESS = `# Progress Tracking
|
|
257
|
+
|
|
258
|
+
<!-- CC10X: Do not rename headings. Used as Edit anchors. -->
|
|
259
|
+
|
|
260
|
+
## Current Workflow
|
|
261
|
+
- [None active]
|
|
262
|
+
|
|
263
|
+
## Tasks
|
|
264
|
+
- [ ] [No tasks yet]
|
|
265
|
+
|
|
266
|
+
## Completed
|
|
267
|
+
- [ ] [No completions yet]
|
|
268
|
+
|
|
269
|
+
## Verification
|
|
270
|
+
- [None yet]
|
|
271
|
+
|
|
272
|
+
## Last Updated
|
|
273
|
+
${(/* @__PURE__ */ new Date()).toISOString()}
|
|
274
|
+
`;
|
|
275
|
+
var MemoryManager = class {
|
|
276
|
+
ctx = null;
|
|
277
|
+
memoryCache = null;
|
|
278
|
+
pendingNotes = [];
|
|
279
|
+
async initialize(input) {
|
|
280
|
+
this.ctx = input;
|
|
281
|
+
await this.ensureDirectory(input);
|
|
282
|
+
}
|
|
283
|
+
async ensureDirectory(input) {
|
|
284
|
+
try {
|
|
285
|
+
const $ = input.$;
|
|
286
|
+
if (typeof $ !== "function") {
|
|
287
|
+
throw new Error("Shell not available");
|
|
288
|
+
}
|
|
289
|
+
const result = await $`mkdir -p ${MEMORY_DIR}`;
|
|
290
|
+
if (result.exitCode !== 0) {
|
|
291
|
+
throw new Error(`mkdir failed: ${result.stderr.toString()}`);
|
|
292
|
+
}
|
|
293
|
+
} catch (error) {
|
|
294
|
+
console.warn("Could not create memory directory:", error);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
async load(input) {
|
|
298
|
+
if (this.memoryCache) {
|
|
299
|
+
return this.memoryCache;
|
|
300
|
+
}
|
|
301
|
+
let memory = {
|
|
302
|
+
activeContext: "",
|
|
303
|
+
patterns: "",
|
|
304
|
+
progress: "",
|
|
305
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString()
|
|
306
|
+
};
|
|
307
|
+
try {
|
|
308
|
+
for (const [key, path] of Object.entries(MEMORY_FILES)) {
|
|
309
|
+
try {
|
|
310
|
+
const content = await readFile(input, path);
|
|
311
|
+
memory[key] = content;
|
|
312
|
+
} catch (error) {
|
|
313
|
+
console.log(`Memory file ${path} not found, will create template`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
} catch (error) {
|
|
317
|
+
console.warn("Error loading memory:", error);
|
|
318
|
+
}
|
|
319
|
+
memory = this.autoHealMemory(memory);
|
|
320
|
+
this.memoryCache = memory;
|
|
321
|
+
return memory;
|
|
322
|
+
}
|
|
323
|
+
autoHealMemory(memory) {
|
|
324
|
+
const ensureSection = (content, sections) => {
|
|
325
|
+
for (const section of sections) {
|
|
326
|
+
if (!content.includes(section)) {
|
|
327
|
+
const lastUpdatedIndex = content.lastIndexOf("## Last Updated");
|
|
328
|
+
if (lastUpdatedIndex !== -1) {
|
|
329
|
+
content = content.slice(0, lastUpdatedIndex) + `## ${section}
|
|
330
|
+
- [N/A]
|
|
331
|
+
|
|
332
|
+
` + content.slice(lastUpdatedIndex);
|
|
333
|
+
} else {
|
|
334
|
+
content += `
|
|
335
|
+
## ${section}
|
|
336
|
+
- [N/A]
|
|
337
|
+
`;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return content;
|
|
342
|
+
};
|
|
343
|
+
if (!memory.activeContext || memory.activeContext.trim() === "") {
|
|
344
|
+
memory.activeContext = DEFAULT_ACTIVE_CONTEXT;
|
|
345
|
+
} else {
|
|
346
|
+
memory.activeContext = ensureSection(memory.activeContext, [
|
|
347
|
+
"References",
|
|
348
|
+
"Decisions",
|
|
349
|
+
"Learnings"
|
|
350
|
+
]);
|
|
351
|
+
}
|
|
352
|
+
if (!memory.patterns || memory.patterns.trim() === "") {
|
|
353
|
+
memory.patterns = DEFAULT_PATTERNS;
|
|
354
|
+
}
|
|
355
|
+
if (!memory.progress || memory.progress.trim() === "") {
|
|
356
|
+
memory.progress = DEFAULT_PROGRESS;
|
|
357
|
+
}
|
|
358
|
+
return memory;
|
|
359
|
+
}
|
|
360
|
+
async updateActiveContext(input, updates) {
|
|
361
|
+
const memory = await this.load(input);
|
|
362
|
+
let content = memory.activeContext;
|
|
363
|
+
if (updates.recentChanges && updates.recentChanges.length > 0) {
|
|
364
|
+
content = this.appendToSection(content, "## Recent Changes", updates.recentChanges);
|
|
365
|
+
}
|
|
366
|
+
if (updates.decisions && updates.decisions.length > 0) {
|
|
367
|
+
content = this.appendToSection(content, "## Decisions", updates.decisions);
|
|
368
|
+
}
|
|
369
|
+
if (updates.learnings && updates.learnings.length > 0) {
|
|
370
|
+
content = this.appendToSection(content, "## Learnings", updates.learnings);
|
|
371
|
+
}
|
|
372
|
+
if (updates.nextSteps && updates.nextSteps.length > 0) {
|
|
373
|
+
content = this.appendToSection(content, "## Next Steps", updates.nextSteps);
|
|
374
|
+
}
|
|
375
|
+
content = content.replace(
|
|
376
|
+
/## Last Updated\s*\n/,
|
|
377
|
+
`## Last Updated
|
|
378
|
+
${(/* @__PURE__ */ new Date()).toISOString()}
|
|
379
|
+
`
|
|
380
|
+
);
|
|
381
|
+
await this.writeMemoryFile(input, MEMORY_FILES.activeContext, content);
|
|
382
|
+
}
|
|
383
|
+
async updateProgress(input, updates) {
|
|
384
|
+
const memory = await this.load(input);
|
|
385
|
+
let content = memory.progress;
|
|
386
|
+
if (updates.currentWorkflow) {
|
|
387
|
+
content = this.replaceOrAppendToSection(content, "## Current Workflow", [updates.currentWorkflow]);
|
|
388
|
+
}
|
|
389
|
+
if (updates.tasks && updates.tasks.length > 0) {
|
|
390
|
+
content = this.appendToSection(content, "## Tasks", updates.tasks);
|
|
391
|
+
}
|
|
392
|
+
if (updates.completed && updates.completed.length > 0) {
|
|
393
|
+
content = this.appendToSection(content, "## Completed", updates.completed);
|
|
394
|
+
}
|
|
395
|
+
if (updates.verification && updates.verification.length > 0) {
|
|
396
|
+
content = this.appendToSection(content, "## Verification", updates.verification);
|
|
397
|
+
}
|
|
398
|
+
content = content.replace(
|
|
399
|
+
/## Last Updated\s*\n/,
|
|
400
|
+
`## Last Updated
|
|
401
|
+
${(/* @__PURE__ */ new Date()).toISOString()}
|
|
402
|
+
`
|
|
403
|
+
);
|
|
404
|
+
await this.writeMemoryFile(input, MEMORY_FILES.progress, content);
|
|
405
|
+
}
|
|
406
|
+
async updatePatterns(input, updates) {
|
|
407
|
+
const memory = await this.load(input);
|
|
408
|
+
let content = memory.patterns;
|
|
409
|
+
if (updates.commonGotchas && updates.commonGotchas.length > 0) {
|
|
410
|
+
content = this.appendToSection(content, "## Common Gotchas", updates.commonGotchas);
|
|
411
|
+
}
|
|
412
|
+
if (updates.codeConventions && updates.codeConventions.length > 0) {
|
|
413
|
+
content = this.appendToSection(content, "## Code Conventions", updates.codeConventions);
|
|
414
|
+
}
|
|
415
|
+
if (updates.architectureDecisions && updates.architectureDecisions.length > 0) {
|
|
416
|
+
content = this.appendToSection(content, "## Architecture Decisions", updates.architectureDecisions);
|
|
417
|
+
}
|
|
418
|
+
content = content.replace(
|
|
419
|
+
/## Last Updated\s*\n/,
|
|
420
|
+
`## Last Updated
|
|
421
|
+
${(/* @__PURE__ */ new Date()).toISOString()}
|
|
422
|
+
`
|
|
423
|
+
);
|
|
424
|
+
await this.writeMemoryFile(input, MEMORY_FILES.patterns, content);
|
|
425
|
+
}
|
|
426
|
+
async accumulateNotes(_ctx, notes) {
|
|
427
|
+
this.pendingNotes.push(...notes);
|
|
428
|
+
}
|
|
429
|
+
async persistAccumulatedNotes(input) {
|
|
430
|
+
if (this.pendingNotes.length === 0) return;
|
|
431
|
+
const learnings = [];
|
|
432
|
+
const patterns = [];
|
|
433
|
+
const verification = [];
|
|
434
|
+
for (const note of this.pendingNotes) {
|
|
435
|
+
if (note.toLowerCase().includes("verification") || note.includes("exit code")) {
|
|
436
|
+
verification.push(note);
|
|
437
|
+
} else if (note.toLowerCase().includes("pattern") || note.toLowerCase().includes("gotcha")) {
|
|
438
|
+
patterns.push(note);
|
|
439
|
+
} else {
|
|
440
|
+
learnings.push(note);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
if (learnings.length > 0) {
|
|
444
|
+
await this.updateActiveContext(input, { learnings });
|
|
445
|
+
}
|
|
446
|
+
if (patterns.length > 0) {
|
|
447
|
+
await this.updatePatterns(input, { commonGotchas: patterns });
|
|
448
|
+
}
|
|
449
|
+
if (verification.length > 0) {
|
|
450
|
+
await this.updateProgress(input, { verification });
|
|
451
|
+
}
|
|
452
|
+
this.pendingNotes = [];
|
|
453
|
+
}
|
|
454
|
+
async saveCompactionCheckpoint(input) {
|
|
455
|
+
await this.persistAccumulatedNotes(input);
|
|
456
|
+
}
|
|
457
|
+
async writeMemoryFile(input, path, content) {
|
|
458
|
+
try {
|
|
459
|
+
try {
|
|
460
|
+
await readFile(input, path);
|
|
461
|
+
const currentContent = await readFile(input, path);
|
|
462
|
+
await editFile(input, {
|
|
463
|
+
oldString: currentContent,
|
|
464
|
+
newString: content
|
|
465
|
+
});
|
|
466
|
+
} catch {
|
|
467
|
+
await writeFile(input, path, content);
|
|
468
|
+
}
|
|
469
|
+
if (path.includes("activeContext")) {
|
|
470
|
+
this.memoryCache.activeContext = content;
|
|
471
|
+
} else if (path.includes("patterns")) {
|
|
472
|
+
this.memoryCache.patterns = content;
|
|
473
|
+
} else if (path.includes("progress")) {
|
|
474
|
+
this.memoryCache.progress = content;
|
|
475
|
+
}
|
|
476
|
+
} catch (error) {
|
|
477
|
+
console.error("Failed to write memory file:", path, error);
|
|
478
|
+
throw error;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
appendToSection(content, sectionHeader, newItems) {
|
|
482
|
+
const sectionIndex = content.indexOf(sectionHeader);
|
|
483
|
+
if (sectionIndex === -1) {
|
|
484
|
+
const lastUpdatedIndex = content.lastIndexOf("## Last Updated");
|
|
485
|
+
if (lastUpdatedIndex !== -1) {
|
|
486
|
+
const items = newItems.map((item) => `- [${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}] ${item}`).join("\n");
|
|
487
|
+
return content.slice(0, lastUpdatedIndex) + `${sectionHeader}
|
|
488
|
+
${items}
|
|
489
|
+
|
|
490
|
+
` + content.slice(lastUpdatedIndex);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
const lines = content.split("\n");
|
|
494
|
+
const sectionLineIndex = lines.findIndex((line) => line.includes(sectionHeader));
|
|
495
|
+
if (sectionLineIndex !== -1) {
|
|
496
|
+
let insertIndex = sectionLineIndex + 1;
|
|
497
|
+
while (insertIndex < lines.length && !lines[insertIndex].startsWith("##")) {
|
|
498
|
+
insertIndex++;
|
|
499
|
+
}
|
|
500
|
+
const items = newItems.map((item) => `- [${(/* @__PURE__ */ new Date()).toISOString().split("T")[0]}] ${item}`);
|
|
501
|
+
lines.splice(insertIndex, 0, ...items);
|
|
502
|
+
return lines.join("\n");
|
|
503
|
+
}
|
|
504
|
+
return content;
|
|
505
|
+
}
|
|
506
|
+
replaceOrAppendToSection(content, sectionHeader, newItems) {
|
|
507
|
+
return this.appendToSection(content, sectionHeader, newItems);
|
|
508
|
+
}
|
|
509
|
+
clearCache() {
|
|
510
|
+
this.memoryCache = null;
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
var memoryManager = new MemoryManager();
|
|
514
|
+
|
|
515
|
+
// src/task-orchestrator.ts
|
|
516
|
+
var TaskOrchestrator = class _TaskOrchestrator {
|
|
517
|
+
activeWorkflows = /* @__PURE__ */ new Map();
|
|
518
|
+
async createWorkflowTask(input, options) {
|
|
519
|
+
if (this.getActiveWorkflows !== _TaskOrchestrator.prototype.getActiveWorkflows) {
|
|
520
|
+
this.getActiveWorkflows = _TaskOrchestrator.prototype.getActiveWorkflows.bind(this);
|
|
521
|
+
}
|
|
522
|
+
const workflowId = `CC10X-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
523
|
+
const workflow = {
|
|
524
|
+
id: workflowId,
|
|
525
|
+
type: options.intent,
|
|
526
|
+
userRequest: options.userRequest,
|
|
527
|
+
memory: options.memory,
|
|
528
|
+
tasks: [],
|
|
529
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
530
|
+
status: "active"
|
|
531
|
+
};
|
|
532
|
+
const tasks = this.createTaskHierarchy(workflowId, options.intent, options.userRequest, options.memory);
|
|
533
|
+
workflow.tasks = tasks;
|
|
534
|
+
this.activeWorkflows.set(workflowId, workflow);
|
|
535
|
+
const parentTask = await this.createOpenCodeTask(input, {
|
|
536
|
+
subject: `CC10X ${options.intent}: ${options.userRequest.substring(0, 50)}`,
|
|
537
|
+
description: this.buildWorkflowDescription(workflow),
|
|
538
|
+
activeForm: `Starting ${options.intent} workflow`
|
|
539
|
+
});
|
|
540
|
+
workflow.tasks[0].id = parentTask.id;
|
|
541
|
+
console.log(`\u{1F4CB} Created workflow ${workflowId} with ${tasks.length} tasks`);
|
|
542
|
+
return workflow.tasks[0];
|
|
543
|
+
}
|
|
544
|
+
createTaskHierarchy(workflowId, intent, userRequest, memory) {
|
|
545
|
+
const tasks = [];
|
|
546
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
547
|
+
switch (intent) {
|
|
548
|
+
case "BUILD":
|
|
549
|
+
tasks.push(
|
|
550
|
+
{
|
|
551
|
+
id: `${workflowId}-builder`,
|
|
552
|
+
subject: "CC10X component-builder: Implement feature",
|
|
553
|
+
description: `Build feature with TDD: ${userRequest}
|
|
554
|
+
|
|
555
|
+
Plan: ${this.extractPlanFile(memory) || "N/A"}`,
|
|
556
|
+
status: "pending",
|
|
557
|
+
agentType: "component-builder",
|
|
558
|
+
activeForm: "Building components with TDD"
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
id: `${workflowId}-reviewer`,
|
|
562
|
+
subject: "CC10X code-reviewer: Review implementation",
|
|
563
|
+
description: "Review code quality, patterns, security",
|
|
564
|
+
status: "pending",
|
|
565
|
+
agentType: "code-reviewer",
|
|
566
|
+
blockedBy: [`${workflowId}-builder`],
|
|
567
|
+
activeForm: "Reviewing code quality"
|
|
568
|
+
},
|
|
569
|
+
{
|
|
570
|
+
id: `${workflowId}-hunter`,
|
|
571
|
+
subject: "CC10X silent-failure-hunter: Hunt edge cases",
|
|
572
|
+
description: "Find silent failures and edge cases",
|
|
573
|
+
status: "pending",
|
|
574
|
+
agentType: "silent-failure-hunter",
|
|
575
|
+
blockedBy: [`${workflowId}-builder`],
|
|
576
|
+
activeForm: "Hunting for failures"
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
id: `${workflowId}-verifier`,
|
|
580
|
+
subject: "CC10X integration-verifier: Verify implementation",
|
|
581
|
+
description: "End-to-end validation of the implementation",
|
|
582
|
+
status: "pending",
|
|
583
|
+
agentType: "integration-verifier",
|
|
584
|
+
blockedBy: [`${workflowId}-reviewer`, `${workflowId}-hunter`],
|
|
585
|
+
activeForm: "Verifying integration"
|
|
586
|
+
}
|
|
587
|
+
);
|
|
588
|
+
break;
|
|
589
|
+
case "DEBUG":
|
|
590
|
+
tasks.push(
|
|
591
|
+
{
|
|
592
|
+
id: `${workflowId}-investigator`,
|
|
593
|
+
subject: "CC10X bug-investigator: Investigate issue",
|
|
594
|
+
description: `Debug issue with log-first approach: ${userRequest}`,
|
|
595
|
+
status: "pending",
|
|
596
|
+
agentType: "bug-investigator",
|
|
597
|
+
activeForm: "Investigating bug"
|
|
598
|
+
},
|
|
599
|
+
{
|
|
600
|
+
id: `${workflowId}-reviewer`,
|
|
601
|
+
subject: "CC10X code-reviewer: Validate fix",
|
|
602
|
+
description: "Review fix for correctness and quality",
|
|
603
|
+
status: "pending",
|
|
604
|
+
agentType: "code-reviewer",
|
|
605
|
+
blockedBy: [`${workflowId}-investigator`],
|
|
606
|
+
activeForm: "Reviewing fix"
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
id: `${workflowId}-verifier`,
|
|
610
|
+
subject: "CC10X integration-verifier: Verify fix",
|
|
611
|
+
description: "Verify the fix resolves the issue",
|
|
612
|
+
status: "pending",
|
|
613
|
+
agentType: "integration-verifier",
|
|
614
|
+
blockedBy: [`${workflowId}-reviewer`],
|
|
615
|
+
activeForm: "Verifying fix"
|
|
616
|
+
}
|
|
617
|
+
);
|
|
618
|
+
break;
|
|
619
|
+
case "REVIEW":
|
|
620
|
+
tasks.push(
|
|
621
|
+
{
|
|
622
|
+
id: `${workflowId}-reviewer`,
|
|
623
|
+
subject: "CC10X code-reviewer: Comprehensive review",
|
|
624
|
+
description: `Review code with 80%+ confidence: ${userRequest}`,
|
|
625
|
+
status: "pending",
|
|
626
|
+
agentType: "code-reviewer",
|
|
627
|
+
activeForm: "Reviewing code"
|
|
628
|
+
}
|
|
629
|
+
);
|
|
630
|
+
break;
|
|
631
|
+
case "PLAN":
|
|
632
|
+
tasks.push(
|
|
633
|
+
{
|
|
634
|
+
id: `${workflowId}-planner`,
|
|
635
|
+
subject: "CC10X planner: Create comprehensive plan",
|
|
636
|
+
description: `Create detailed plan: ${userRequest}`,
|
|
637
|
+
status: "pending",
|
|
638
|
+
agentType: "planner",
|
|
639
|
+
activeForm: "Creating plan"
|
|
640
|
+
}
|
|
641
|
+
);
|
|
642
|
+
break;
|
|
643
|
+
}
|
|
644
|
+
tasks.push({
|
|
645
|
+
id: `${workflowId}-memory-update`,
|
|
646
|
+
subject: "CC10X Memory Update",
|
|
647
|
+
description: "Persist workflow learnings to memory bank",
|
|
648
|
+
status: "pending",
|
|
649
|
+
agentType: "router",
|
|
650
|
+
// Main assistant does this
|
|
651
|
+
blockedBy: tasks.map((t) => t.id),
|
|
652
|
+
activeForm: "Updating memory"
|
|
653
|
+
});
|
|
654
|
+
return tasks;
|
|
655
|
+
}
|
|
656
|
+
buildWorkflowDescription(workflow) {
|
|
657
|
+
const taskList = workflow.tasks.map(
|
|
658
|
+
(t) => `- ${t.subject} (${t.status})${t.blockedBy ? ` [blocked by: ${t.blockedBy.join(", ")}]` : ""}`
|
|
659
|
+
).join("\n");
|
|
660
|
+
return `
|
|
661
|
+
User Request: ${workflow.userRequest}
|
|
662
|
+
Workflow Type: ${workflow.type}
|
|
663
|
+
Created: ${workflow.createdAt}
|
|
664
|
+
|
|
665
|
+
Task Hierarchy:
|
|
666
|
+
${taskList}
|
|
667
|
+
|
|
668
|
+
Memory Context:
|
|
669
|
+
- Active Context: ${workflow.memory.activeContext ? "Loaded" : "Empty"}
|
|
670
|
+
- Patterns: ${workflow.memory.patterns ? "Loaded" : "Empty"}
|
|
671
|
+
- Progress: ${workflow.memory.progress ? "Loaded" : "Empty"}
|
|
672
|
+
|
|
673
|
+
Follow the cc10x workflow strictly. Check blockedBy dependencies before proceeding.
|
|
674
|
+
Parallel execution: code-reviewer and silent-failure-hunter can run simultaneously.
|
|
675
|
+
`.trim();
|
|
676
|
+
}
|
|
677
|
+
extractPlanFile(memory) {
|
|
678
|
+
const activeContext = memory.activeContext || "";
|
|
679
|
+
const referencesMatch = activeContext.match(/## References\n([\s\S]*?)(?=\n##|\n$)/);
|
|
680
|
+
if (referencesMatch) {
|
|
681
|
+
const references = referencesMatch[1];
|
|
682
|
+
const planMatch = references.match(/- Plan:\s*`([^`]+)`/);
|
|
683
|
+
if (planMatch) {
|
|
684
|
+
return planMatch[1];
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
return null;
|
|
688
|
+
}
|
|
689
|
+
async createOpenCodeTask(input, options) {
|
|
690
|
+
try {
|
|
691
|
+
let taskId = `local-${Date.now()}`;
|
|
692
|
+
if (typeof input?.taskCreate === "function") {
|
|
693
|
+
const result = await input.taskCreate({
|
|
694
|
+
subject: options.subject,
|
|
695
|
+
description: options.description,
|
|
696
|
+
activeForm: options.activeForm
|
|
697
|
+
});
|
|
698
|
+
taskId = result?.taskId ?? taskId;
|
|
699
|
+
} else if (input?.client?.app?.task?.create) {
|
|
700
|
+
const result = await input.client.app.task.create({
|
|
701
|
+
subject: options.subject,
|
|
702
|
+
description: options.description,
|
|
703
|
+
activeForm: options.activeForm
|
|
704
|
+
});
|
|
705
|
+
taskId = result?.taskId ?? taskId;
|
|
706
|
+
}
|
|
707
|
+
return {
|
|
708
|
+
id: taskId,
|
|
709
|
+
subject: options.subject,
|
|
710
|
+
description: options.description,
|
|
711
|
+
status: "pending",
|
|
712
|
+
agentType: "workflow",
|
|
713
|
+
activeForm: options.activeForm
|
|
714
|
+
};
|
|
715
|
+
} catch (error) {
|
|
716
|
+
console.error("Failed to create OpenCode task:", error);
|
|
717
|
+
return {
|
|
718
|
+
id: `local-${Date.now()}`,
|
|
719
|
+
subject: options.subject,
|
|
720
|
+
description: options.description,
|
|
721
|
+
status: "pending",
|
|
722
|
+
agentType: "workflow",
|
|
723
|
+
activeForm: options.activeForm
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
async updateTaskStatus(input, taskId, status, result) {
|
|
728
|
+
for (const workflow of this.activeWorkflows.values()) {
|
|
729
|
+
const task = workflow.tasks.find((t) => t.id === taskId);
|
|
730
|
+
if (task) {
|
|
731
|
+
task.status = status;
|
|
732
|
+
task.result = result;
|
|
733
|
+
break;
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
try {
|
|
737
|
+
if (typeof input?.taskUpdate === "function") {
|
|
738
|
+
await input.taskUpdate({
|
|
739
|
+
taskId,
|
|
740
|
+
status
|
|
741
|
+
});
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
if (input?.client?.app?.task?.update && (taskId.startsWith("task_") || taskId.length > 20)) {
|
|
745
|
+
await input.client.app.task.update({
|
|
746
|
+
taskId,
|
|
747
|
+
status
|
|
748
|
+
});
|
|
749
|
+
}
|
|
750
|
+
} catch (error) {
|
|
751
|
+
console.warn("Could not update OpenCode task status:", error);
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
async recordExecutionResult(input, result) {
|
|
755
|
+
console.log(`\u{1F4CA} Recorded execution: ${result.tool} ${result.command} \u2192 exit ${result.exitCode}`);
|
|
756
|
+
}
|
|
757
|
+
async getRunnableTasks(input) {
|
|
758
|
+
const runnableTasks = [];
|
|
759
|
+
for (const workflow of this.activeWorkflows.values()) {
|
|
760
|
+
if (workflow.status !== "active") continue;
|
|
761
|
+
for (const task of workflow.tasks) {
|
|
762
|
+
if (task.status !== "pending") continue;
|
|
763
|
+
if (task.blockedBy) {
|
|
764
|
+
const allUnblocked = task.blockedBy.every((blockedId) => {
|
|
765
|
+
const blockedTask = workflow.tasks.find((t) => t.id === blockedId);
|
|
766
|
+
return blockedTask?.status === "completed";
|
|
767
|
+
});
|
|
768
|
+
if (!allUnblocked) continue;
|
|
769
|
+
}
|
|
770
|
+
runnableTasks.push(task);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
return runnableTasks;
|
|
774
|
+
}
|
|
775
|
+
async checkForActiveWorkflows(_ctx) {
|
|
776
|
+
for (const workflow of this.activeWorkflows.values()) {
|
|
777
|
+
if (workflow.status === "active") {
|
|
778
|
+
const hasPendingTasks = workflow.tasks.some((t) => t.status === "pending");
|
|
779
|
+
if (hasPendingTasks) {
|
|
780
|
+
return workflow;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
return null;
|
|
785
|
+
}
|
|
786
|
+
async completeWorkflow(workflowId) {
|
|
787
|
+
const workflow = this.activeWorkflows.get(workflowId);
|
|
788
|
+
if (workflow) {
|
|
789
|
+
workflow.status = "completed";
|
|
790
|
+
console.log(`\u2705 Workflow ${workflowId} completed`);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
getActiveWorkflows() {
|
|
794
|
+
return Array.from(this.activeWorkflows.values()).filter((w) => w.status === "active");
|
|
795
|
+
}
|
|
796
|
+
};
|
|
797
|
+
var taskOrchestrator = new TaskOrchestrator();
|
|
798
|
+
|
|
799
|
+
// src/workflow-executor.ts
|
|
800
|
+
var WorkflowExecutor = class {
|
|
801
|
+
async executeWorkflow(input, options) {
|
|
802
|
+
const { intent, userRequest, memory, workflowTaskId, activeForm } = options;
|
|
803
|
+
console.log(`\u{1F680} Executing ${intent} workflow for: "${userRequest}"`);
|
|
804
|
+
try {
|
|
805
|
+
switch (intent) {
|
|
806
|
+
case "BUILD":
|
|
807
|
+
await this.executeBuildWorkflow(input, { userRequest, memory, workflowTaskId });
|
|
808
|
+
break;
|
|
809
|
+
case "DEBUG":
|
|
810
|
+
await this.executeDebugWorkflow(input, { userRequest, memory, workflowTaskId });
|
|
811
|
+
break;
|
|
812
|
+
case "REVIEW":
|
|
813
|
+
await this.executeReviewWorkflow(input, { userRequest, memory, workflowTaskId });
|
|
814
|
+
break;
|
|
815
|
+
case "PLAN":
|
|
816
|
+
await this.executePlanWorkflow(input, { userRequest, memory, workflowTaskId });
|
|
817
|
+
break;
|
|
818
|
+
}
|
|
819
|
+
await this.executeMemoryUpdate(input, workflowTaskId);
|
|
820
|
+
await taskOrchestrator.completeWorkflow(workflowTaskId);
|
|
821
|
+
console.log(`\u2705 ${intent} workflow completed successfully`);
|
|
822
|
+
} catch (error) {
|
|
823
|
+
console.error(`\u274C ${intent} workflow failed:`, error);
|
|
824
|
+
await this.handleWorkflowFailure(input, workflowTaskId, error);
|
|
825
|
+
}
|
|
826
|
+
}
|
|
827
|
+
async executeBuildWorkflow(input, options) {
|
|
828
|
+
const { userRequest, memory, workflowTaskId } = options;
|
|
829
|
+
await this.invokeAgent(input, {
|
|
830
|
+
agentName: "cc10x-component-builder",
|
|
831
|
+
taskId: `${workflowTaskId}-builder`,
|
|
832
|
+
prompt: this.buildBuilderPrompt(userRequest, memory),
|
|
833
|
+
waitForCompletion: true
|
|
834
|
+
});
|
|
835
|
+
await this.invokeParallelAgents(input, {
|
|
836
|
+
agentNames: ["cc10x-code-reviewer", "cc10x-silent-failure-hunter"],
|
|
837
|
+
baseTaskId: workflowTaskId,
|
|
838
|
+
sharedPrompt: this.buildReviewAndHuntPrompt(userRequest, memory),
|
|
839
|
+
waitForCompletion: true
|
|
840
|
+
});
|
|
841
|
+
await this.invokeAgent(input, {
|
|
842
|
+
agentName: "cc10x-integration-verifier",
|
|
843
|
+
taskId: `${workflowTaskId}-verifier`,
|
|
844
|
+
prompt: await this.buildVerifierPrompt(input, workflowTaskId),
|
|
845
|
+
waitForCompletion: true
|
|
846
|
+
});
|
|
847
|
+
}
|
|
848
|
+
async executeDebugWorkflow(input, options) {
|
|
849
|
+
const { userRequest, memory, workflowTaskId } = options;
|
|
850
|
+
await this.invokeAgent(input, {
|
|
851
|
+
agentName: "cc10x-bug-investigator",
|
|
852
|
+
taskId: `${workflowTaskId}-investigator`,
|
|
853
|
+
prompt: this.buildDebugPrompt(userRequest, memory),
|
|
854
|
+
waitForCompletion: true
|
|
855
|
+
});
|
|
856
|
+
await this.invokeAgent(input, {
|
|
857
|
+
agentName: "cc10x-code-reviewer",
|
|
858
|
+
taskId: `${workflowTaskId}-reviewer`,
|
|
859
|
+
prompt: this.buildReviewFixPrompt(userRequest, memory),
|
|
860
|
+
waitForCompletion: true
|
|
861
|
+
});
|
|
862
|
+
await this.invokeAgent(input, {
|
|
863
|
+
agentName: "cc10x-integration-verifier",
|
|
864
|
+
taskId: `${workflowTaskId}-verifier`,
|
|
865
|
+
prompt: await this.buildVerifierPrompt(input, workflowTaskId),
|
|
866
|
+
waitForCompletion: true
|
|
867
|
+
});
|
|
868
|
+
}
|
|
869
|
+
async executeReviewWorkflow(input, options) {
|
|
870
|
+
const { userRequest, memory, workflowTaskId } = options;
|
|
871
|
+
await this.invokeAgent(input, {
|
|
872
|
+
agentName: "cc10x-code-reviewer",
|
|
873
|
+
taskId: `${workflowTaskId}-reviewer`,
|
|
874
|
+
prompt: this.buildReviewPrompt(userRequest, memory),
|
|
875
|
+
waitForCompletion: true
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
async executePlanWorkflow(input, options) {
|
|
879
|
+
const { userRequest, memory, workflowTaskId } = options;
|
|
880
|
+
await this.invokeAgent(input, {
|
|
881
|
+
agentName: "cc10x-planner",
|
|
882
|
+
taskId: `${workflowTaskId}-planner`,
|
|
883
|
+
prompt: this.buildPlanPrompt(userRequest, memory),
|
|
884
|
+
waitForCompletion: true
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
async executeMemoryUpdate(input, workflowTaskId) {
|
|
888
|
+
console.log("\u{1F4BE} Executing workflow-final memory update");
|
|
889
|
+
await memoryManager.persistAccumulatedNotes(input);
|
|
890
|
+
await memoryManager.updateProgress(input, {
|
|
891
|
+
completed: [`Workflow ${workflowTaskId} completed with verification`]
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
async invokeAgent(input, options) {
|
|
895
|
+
const { agentName, taskId, prompt, waitForCompletion } = options;
|
|
896
|
+
console.log(`\u{1F916} Invoking agent: ${agentName} (task: ${taskId})`);
|
|
897
|
+
try {
|
|
898
|
+
await taskOrchestrator.updateTaskStatus(input, taskId, "in_progress");
|
|
899
|
+
let result;
|
|
900
|
+
if (typeof input?.invokeAgent === "function") {
|
|
901
|
+
result = await input.invokeAgent(agentName, {
|
|
902
|
+
prompt,
|
|
903
|
+
taskId
|
|
904
|
+
});
|
|
905
|
+
} else {
|
|
906
|
+
result = await input.client.app.agent.invoke(agentName, {
|
|
907
|
+
prompt,
|
|
908
|
+
taskId
|
|
909
|
+
});
|
|
910
|
+
}
|
|
911
|
+
await taskOrchestrator.updateTaskStatus(input, taskId, "completed", result);
|
|
912
|
+
console.log(`\u2705 Agent ${agentName} completed`);
|
|
913
|
+
} catch (error) {
|
|
914
|
+
console.error(`\u274C Agent ${agentName} failed:`, error);
|
|
915
|
+
await taskOrchestrator.updateTaskStatus(input, taskId, "blocked");
|
|
916
|
+
throw error;
|
|
917
|
+
}
|
|
918
|
+
}
|
|
919
|
+
async invokeParallelAgents(input, options) {
|
|
920
|
+
const { agentNames, baseTaskId, sharedPrompt, waitForCompletion } = options;
|
|
921
|
+
console.log(`\u26A1 Invoking parallel agents: ${agentNames.join(", ")}`);
|
|
922
|
+
const agentPromises = agentNames.map(
|
|
923
|
+
(agentName) => this.invokeAgent(input, {
|
|
924
|
+
agentName,
|
|
925
|
+
taskId: `${baseTaskId}-${agentName.split("-").pop()}`,
|
|
926
|
+
prompt: sharedPrompt,
|
|
927
|
+
waitForCompletion: true
|
|
928
|
+
// Each agent waits for its own completion
|
|
929
|
+
})
|
|
930
|
+
);
|
|
931
|
+
await Promise.all(agentPromises);
|
|
932
|
+
}
|
|
933
|
+
buildBuilderPrompt(userRequest, memory) {
|
|
934
|
+
return `
|
|
935
|
+
# Component Builder (TDD)
|
|
936
|
+
|
|
937
|
+
## User Request
|
|
938
|
+
${userRequest}
|
|
939
|
+
|
|
940
|
+
## Memory Context
|
|
941
|
+
${this.formatMemoryContext(memory)}
|
|
942
|
+
|
|
943
|
+
## Instructions
|
|
944
|
+
Follow the TDD cycle strictly:
|
|
945
|
+
1. RED: Write a failing test first (must exit with code 1)
|
|
946
|
+
2. GREEN: Write minimal code to pass (must exit with code 0)
|
|
947
|
+
3. REFACTOR: Clean up while keeping tests green
|
|
948
|
+
4. VERIFY: All tests must pass
|
|
949
|
+
|
|
950
|
+
## Pre-Implementation Checklist
|
|
951
|
+
- API: CORS? Auth middleware? Input validation? Rate limiting?
|
|
952
|
+
- UI: Loading states? Error boundaries? Accessibility?
|
|
953
|
+
- DB: Migrations? N+1 queries? Transactions?
|
|
954
|
+
- All: Edge cases listed? Error handling planned?
|
|
955
|
+
|
|
956
|
+
## Output Requirements
|
|
957
|
+
- Provide TDD evidence with exact commands and exit codes
|
|
958
|
+
- Include Dev Journal with decisions and assumptions
|
|
959
|
+
- Follow the Router Contract format exactly
|
|
960
|
+
- Update memory via Edit tool (permission-free)
|
|
961
|
+
`.trim();
|
|
962
|
+
}
|
|
963
|
+
buildReviewAndHuntPrompt(userRequest, memory) {
|
|
964
|
+
return `
|
|
965
|
+
# Code Review & Silent Failure Hunt
|
|
966
|
+
|
|
967
|
+
## User Request
|
|
968
|
+
${userRequest}
|
|
969
|
+
|
|
970
|
+
## Memory Context
|
|
971
|
+
${this.formatMemoryContext(memory)}
|
|
972
|
+
|
|
973
|
+
## Instructions
|
|
974
|
+
Analyze the implementation from the component-builder. Focus on:
|
|
975
|
+
|
|
976
|
+
### Code Reviewer Focus
|
|
977
|
+
- Code quality and best practices
|
|
978
|
+
- Security vulnerabilities (OWASP top 10)
|
|
979
|
+
- Performance implications (N+1 queries, etc.)
|
|
980
|
+
- Maintainability and readability
|
|
981
|
+
- API design and contracts
|
|
982
|
+
|
|
983
|
+
### Silent Failure Hunter Focus
|
|
984
|
+
- Empty catch blocks
|
|
985
|
+
- Missing error handling
|
|
986
|
+
- Unvalidated inputs
|
|
987
|
+
- Resource leaks
|
|
988
|
+
- Race conditions
|
|
989
|
+
- Edge cases not covered by tests
|
|
990
|
+
|
|
991
|
+
## Confidence Scoring
|
|
992
|
+
Only report issues with \u226580% confidence. Provide file:line citations.
|
|
993
|
+
|
|
994
|
+
## Output Requirements
|
|
995
|
+
- Critical Issues section with confidence scores
|
|
996
|
+
- Verdict: APPROVED or CHANGES REQUESTED
|
|
997
|
+
- Include "### Memory Notes" section for workflow persistence
|
|
998
|
+
`.trim();
|
|
999
|
+
}
|
|
1000
|
+
async buildVerifierPrompt(input, workflowTaskId) {
|
|
1001
|
+
const reviewerTaskId = `${workflowTaskId}-reviewer`;
|
|
1002
|
+
const hunterTaskId = `${workflowTaskId}-hunter`;
|
|
1003
|
+
return `
|
|
1004
|
+
# Integration Verifier
|
|
1005
|
+
|
|
1006
|
+
## Task Context
|
|
1007
|
+
- Workflow: ${workflowTaskId}
|
|
1008
|
+
- Previous agents: code-reviewer, silent-failure-hunter
|
|
1009
|
+
|
|
1010
|
+
## Instructions
|
|
1011
|
+
Verify the implementation considering ALL findings from previous agents.
|
|
1012
|
+
|
|
1013
|
+
### Verification Checklist
|
|
1014
|
+
- [ ] All tests pass (exit code 0)
|
|
1015
|
+
- [ ] No critical security issues
|
|
1016
|
+
- [ ] No silent failures detected
|
|
1017
|
+
- [ ] Error handling is comprehensive
|
|
1018
|
+
- [ ] Performance is acceptable
|
|
1019
|
+
- [ ] Code follows project patterns
|
|
1020
|
+
|
|
1021
|
+
### Critical Issues
|
|
1022
|
+
Any CRITICAL issues should block PASS verdict.
|
|
1023
|
+
|
|
1024
|
+
## Output Requirements
|
|
1025
|
+
- Verdict: PASS or FAIL with reasoning
|
|
1026
|
+
- Include verification evidence (commands + exit codes)
|
|
1027
|
+
- Provide "### Memory Notes" section
|
|
1028
|
+
`.trim();
|
|
1029
|
+
}
|
|
1030
|
+
buildDebugPrompt(userRequest, memory) {
|
|
1031
|
+
return `
|
|
1032
|
+
# Bug Investigator (LOG FIRST)
|
|
1033
|
+
|
|
1034
|
+
## User Request
|
|
1035
|
+
${userRequest}
|
|
1036
|
+
|
|
1037
|
+
## Memory Context
|
|
1038
|
+
${this.formatMemoryContext(memory)}
|
|
1039
|
+
|
|
1040
|
+
## Iron Law: LOG FIRST
|
|
1041
|
+
Never fix without evidence. Follow this process:
|
|
1042
|
+
|
|
1043
|
+
1. **Reproduce** - Get exact error conditions
|
|
1044
|
+
2. **Log** - Gather all relevant logs, stack traces, system state
|
|
1045
|
+
3. **Analyze** - Root cause analysis using debugging patterns
|
|
1046
|
+
4. **Fix** - Minimal change to resolve
|
|
1047
|
+
5. **Verify** - Confirm fix works and doesn't break other things
|
|
1048
|
+
|
|
1049
|
+
## Common Debugging Patterns
|
|
1050
|
+
- Check recent changes (git diff)
|
|
1051
|
+
- Examine error logs and stack traces
|
|
1052
|
+
- Validate assumptions with print statements
|
|
1053
|
+
- Isolate the failing component
|
|
1054
|
+
- Check for null/undefined values
|
|
1055
|
+
- Verify data types and formats
|
|
1056
|
+
|
|
1057
|
+
## Output Requirements
|
|
1058
|
+
- Evidence before any fix proposal
|
|
1059
|
+
- Root cause analysis with confidence
|
|
1060
|
+
- Minimal fix with verification
|
|
1061
|
+
- Update memory with common gotchas if discovered
|
|
1062
|
+
`.trim();
|
|
1063
|
+
}
|
|
1064
|
+
buildReviewFixPrompt(userRequest, memory) {
|
|
1065
|
+
return `
|
|
1066
|
+
# Code Reviewer (Fix Validation)
|
|
1067
|
+
|
|
1068
|
+
## User Request
|
|
1069
|
+
${userRequest}
|
|
1070
|
+
|
|
1071
|
+
## Memory Context
|
|
1072
|
+
${this.formatMemoryContext(memory)}
|
|
1073
|
+
|
|
1074
|
+
## Instructions
|
|
1075
|
+
Review the bug fix from bug-investigator. Focus on:
|
|
1076
|
+
|
|
1077
|
+
- Fix correctness: Does it actually solve the problem?
|
|
1078
|
+
- Side effects: Does it introduce new issues?
|
|
1079
|
+
- Code quality: Is the fix clean and maintainable?
|
|
1080
|
+
- Testing: Are there tests for the fix?
|
|
1081
|
+
- Security: Does the fix introduce vulnerabilities?
|
|
1082
|
+
|
|
1083
|
+
## Confidence Scoring
|
|
1084
|
+
Only report issues with \u226580% confidence.
|
|
1085
|
+
|
|
1086
|
+
## Output Requirements
|
|
1087
|
+
- Verdict: APPROVED or CHANGES REQUESTED
|
|
1088
|
+
- Critical Issues with file:line citations
|
|
1089
|
+
- Include "### Memory Notes" section
|
|
1090
|
+
`.trim();
|
|
1091
|
+
}
|
|
1092
|
+
buildReviewPrompt(userRequest, memory) {
|
|
1093
|
+
return `
|
|
1094
|
+
# Code Reviewer (Comprehensive Review)
|
|
1095
|
+
|
|
1096
|
+
## User Request
|
|
1097
|
+
${userRequest}
|
|
1098
|
+
|
|
1099
|
+
## Memory Context
|
|
1100
|
+
${this.formatMemoryContext(memory)}
|
|
1101
|
+
|
|
1102
|
+
## Instructions
|
|
1103
|
+
Perform comprehensive code review with 80%+ confidence threshold.
|
|
1104
|
+
|
|
1105
|
+
### Review Dimensions
|
|
1106
|
+
- **Security**: OWASP top 10, input validation, authentication/authorization
|
|
1107
|
+
- **Performance**: Algorithm efficiency, database queries, memory usage
|
|
1108
|
+
- **Maintainability**: Code structure, naming, documentation
|
|
1109
|
+
- **Reliability**: Error handling, edge cases, resource management
|
|
1110
|
+
- **Testing**: Test coverage, test quality, edge case coverage
|
|
1111
|
+
|
|
1112
|
+
## Output Requirements
|
|
1113
|
+
- Only report issues with \u226580% confidence
|
|
1114
|
+
- File:line citations for every finding
|
|
1115
|
+
- Verdict: APPROVED or CHANGES REQUESTED
|
|
1116
|
+
- Include "### Memory Notes" section
|
|
1117
|
+
`.trim();
|
|
1118
|
+
}
|
|
1119
|
+
buildPlanPrompt(userRequest, memory) {
|
|
1120
|
+
return `
|
|
1121
|
+
# Planner (Comprehensive Planning)
|
|
1122
|
+
|
|
1123
|
+
## User Request
|
|
1124
|
+
${userRequest}
|
|
1125
|
+
|
|
1126
|
+
## Memory Context
|
|
1127
|
+
${this.formatMemoryContext(memory)}
|
|
1128
|
+
|
|
1129
|
+
## Planning Requirements
|
|
1130
|
+
Create a comprehensive plan that includes:
|
|
1131
|
+
|
|
1132
|
+
### 1. Analysis
|
|
1133
|
+
- Current state assessment
|
|
1134
|
+
- Requirements clarification
|
|
1135
|
+
- Constraints and dependencies
|
|
1136
|
+
- Risk assessment
|
|
1137
|
+
|
|
1138
|
+
### 2. Architecture
|
|
1139
|
+
- System design decisions
|
|
1140
|
+
- Technology choices with rationale
|
|
1141
|
+
- API design (if applicable)
|
|
1142
|
+
- Data model (if applicable)
|
|
1143
|
+
|
|
1144
|
+
### 3. Implementation Plan
|
|
1145
|
+
- Phased approach with milestones
|
|
1146
|
+
- Specific files to create/modify
|
|
1147
|
+
- Testing strategy
|
|
1148
|
+
- Rollback plan
|
|
1149
|
+
|
|
1150
|
+
### 4. Research Needs
|
|
1151
|
+
- External packages to investigate
|
|
1152
|
+
- Best practices to research
|
|
1153
|
+
- Alternatives to evaluate
|
|
1154
|
+
|
|
1155
|
+
## Output Requirements
|
|
1156
|
+
- Save plan to docs/plans/YYYY-MM-DD-<topic>-plan.md
|
|
1157
|
+
- Update activeContext.md with plan reference
|
|
1158
|
+
- Include research phase if needed (github-research skill)
|
|
1159
|
+
- Provide clear next steps
|
|
1160
|
+
`.trim();
|
|
1161
|
+
}
|
|
1162
|
+
formatMemoryContext(memory) {
|
|
1163
|
+
if (!memory) return "No memory available";
|
|
1164
|
+
const parts = [];
|
|
1165
|
+
if (memory.activeContext) {
|
|
1166
|
+
const focusMatch = memory.activeContext.match(/## Current Focus\n([\s\S]*?)(?=\n##|\n$)/);
|
|
1167
|
+
if (focusMatch) {
|
|
1168
|
+
parts.push(`Current Focus: ${focusMatch[1].trim()}`);
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
if (memory.patterns) {
|
|
1172
|
+
const gotchasMatch = memory.patterns.match(/## Common Gotchas\n([\s\S]*?)(?=\n##|\n$)/);
|
|
1173
|
+
if (gotchasMatch) {
|
|
1174
|
+
parts.push(`Common Gotchas: ${gotchasMatch[1].trim().substring(0, 200)}...`);
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
if (memory.progress) {
|
|
1178
|
+
const completedMatch = memory.progress.match(/## Completed\n([\s\S]*?)(?=\n##|\n$)/);
|
|
1179
|
+
if (completedMatch) {
|
|
1180
|
+
parts.push(`Recent Completions: ${completedMatch[1].trim().substring(0, 200)}...`);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
return parts.length > 0 ? parts.join("\n") : "Memory files empty or not loaded";
|
|
1184
|
+
}
|
|
1185
|
+
async handleWorkflowFailure(input, workflowTaskId, error) {
|
|
1186
|
+
console.error(`Workflow ${workflowTaskId} failed:`, error);
|
|
1187
|
+
await memoryManager.updateActiveContext(input, {
|
|
1188
|
+
recentChanges: [`Workflow ${workflowTaskId} failed: ${error.message}`],
|
|
1189
|
+
nextSteps: [`Investigate workflow failure: ${error.message}`]
|
|
1190
|
+
});
|
|
1191
|
+
}
|
|
1192
|
+
};
|
|
1193
|
+
var workflowExecutor = new WorkflowExecutor();
|
|
1194
|
+
|
|
1195
|
+
// src/router.ts
|
|
1196
|
+
async function cc10xRouter(input) {
|
|
1197
|
+
await memoryManager.initialize(input);
|
|
1198
|
+
const activeWorkflows = /* @__PURE__ */ new Map();
|
|
1199
|
+
const routerHooks = {
|
|
1200
|
+
// Main message interceptor - this is where cc10x magic happens
|
|
1201
|
+
messageReceived: async (input2, output) => {
|
|
1202
|
+
try {
|
|
1203
|
+
const userMessage = input2.args?.message || input2.args?.text || "";
|
|
1204
|
+
if (!isDevelopmentIntent(userMessage)) {
|
|
1205
|
+
return;
|
|
1206
|
+
}
|
|
1207
|
+
const activeWorkflow = await checkForActiveWorkflow(input2);
|
|
1208
|
+
if (activeWorkflow) {
|
|
1209
|
+
await resumeWorkflow(activeWorkflow, userMessage, input2);
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
const memory = await memoryManager.load(input2);
|
|
1213
|
+
const intent = detectIntent(userMessage, memory);
|
|
1214
|
+
const workflowTask = await taskOrchestrator.createWorkflowTask(input2, {
|
|
1215
|
+
userRequest: userMessage,
|
|
1216
|
+
intent,
|
|
1217
|
+
memory
|
|
1218
|
+
});
|
|
1219
|
+
await workflowExecutor.executeWorkflow(input2, {
|
|
1220
|
+
intent,
|
|
1221
|
+
userRequest: userMessage,
|
|
1222
|
+
memory,
|
|
1223
|
+
workflowTaskId: workflowTask.id,
|
|
1224
|
+
activeForm: getActiveFormForIntent(intent, userMessage)
|
|
1225
|
+
});
|
|
1226
|
+
} catch (error) {
|
|
1227
|
+
console.error("cc10x router error:", error);
|
|
1228
|
+
}
|
|
1229
|
+
},
|
|
1230
|
+
sessionCreated: async (input2, output) => {
|
|
1231
|
+
await memoryManager.ensureDirectory(input2);
|
|
1232
|
+
},
|
|
1233
|
+
sessionCompacted: async (input2, output) => {
|
|
1234
|
+
await memoryManager.saveCompactionCheckpoint(input2);
|
|
1235
|
+
},
|
|
1236
|
+
toolExecuteBefore: async (input2, output) => {
|
|
1237
|
+
if (input2.tool === "bash" && isTestCommand(input2.args?.command)) {
|
|
1238
|
+
await enforceTDDRequirements(input2, input2);
|
|
1239
|
+
}
|
|
1240
|
+
if (isMemoryOperation(input2)) {
|
|
1241
|
+
await validateMemoryOperation(input2, input2);
|
|
1242
|
+
}
|
|
1243
|
+
},
|
|
1244
|
+
toolExecuteAfter: async (input2, output) => {
|
|
1245
|
+
if (output.exitCode !== void 0) {
|
|
1246
|
+
await taskOrchestrator.recordExecutionResult(input2, {
|
|
1247
|
+
tool: input2.tool,
|
|
1248
|
+
command: input2.args?.command,
|
|
1249
|
+
exitCode: output.exitCode,
|
|
1250
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1251
|
+
});
|
|
1252
|
+
}
|
|
1253
|
+
},
|
|
1254
|
+
agentStarted: async (input2, output) => {
|
|
1255
|
+
const agentName = input2.agentName || input2.agent;
|
|
1256
|
+
const taskId = input2.taskId;
|
|
1257
|
+
if (taskId) {
|
|
1258
|
+
await taskOrchestrator.updateTaskStatus(input2, taskId, "in_progress");
|
|
1259
|
+
}
|
|
1260
|
+
console.log(`\u{1F916} cc10x agent started: ${agentName}`);
|
|
1261
|
+
},
|
|
1262
|
+
agentCompleted: async (input2, output) => {
|
|
1263
|
+
const agentName = input2.agentName || input2.agent;
|
|
1264
|
+
const taskId = input2.taskId;
|
|
1265
|
+
const result = input2.result || input2.output;
|
|
1266
|
+
if (taskId) {
|
|
1267
|
+
await taskOrchestrator.updateTaskStatus(input2, taskId, "completed", result);
|
|
1268
|
+
}
|
|
1269
|
+
const memoryNotes = extractMemoryNotes(result);
|
|
1270
|
+
if (memoryNotes && memoryNotes.length > 0) {
|
|
1271
|
+
await memoryManager.accumulateNotes(input2, memoryNotes);
|
|
1272
|
+
}
|
|
1273
|
+
console.log(`\u2705 cc10x agent completed: ${agentName}`);
|
|
1274
|
+
},
|
|
1275
|
+
manualInvoke: async (args, context) => {
|
|
1276
|
+
const request = args.request || args.task || args.prompt || "";
|
|
1277
|
+
if (!request.trim()) {
|
|
1278
|
+
return "Please provide a task description.";
|
|
1279
|
+
}
|
|
1280
|
+
console.log(`\u{1F680} Manual cc10x invocation: ${request}`);
|
|
1281
|
+
const syntheticMessage = {
|
|
1282
|
+
id: `manual-${Date.now()}`,
|
|
1283
|
+
content: request,
|
|
1284
|
+
role: "user",
|
|
1285
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
1286
|
+
};
|
|
1287
|
+
try {
|
|
1288
|
+
await routerHooks.messageReceived(context, syntheticMessage);
|
|
1289
|
+
return `\u2705 cc10x orchestration started for: ${request}`;
|
|
1290
|
+
} catch (error) {
|
|
1291
|
+
console.error("Manual invocation failed:", error);
|
|
1292
|
+
return `\u274C cc10x orchestration failed: ${error.message}`;
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
};
|
|
1296
|
+
return { routerHooks };
|
|
1297
|
+
}
|
|
1298
|
+
function isDevelopmentIntent(message) {
|
|
1299
|
+
const devKeywords = [
|
|
1300
|
+
"build",
|
|
1301
|
+
"implement",
|
|
1302
|
+
"create",
|
|
1303
|
+
"make",
|
|
1304
|
+
"write",
|
|
1305
|
+
"add",
|
|
1306
|
+
"develop",
|
|
1307
|
+
"code",
|
|
1308
|
+
"feature",
|
|
1309
|
+
"component",
|
|
1310
|
+
"app",
|
|
1311
|
+
"application",
|
|
1312
|
+
"debug",
|
|
1313
|
+
"fix",
|
|
1314
|
+
"error",
|
|
1315
|
+
"bug",
|
|
1316
|
+
"broken",
|
|
1317
|
+
"troubleshoot",
|
|
1318
|
+
"review",
|
|
1319
|
+
"audit",
|
|
1320
|
+
"check",
|
|
1321
|
+
"analyze",
|
|
1322
|
+
"plan",
|
|
1323
|
+
"design",
|
|
1324
|
+
"architect",
|
|
1325
|
+
"roadmap",
|
|
1326
|
+
"strategy",
|
|
1327
|
+
"test",
|
|
1328
|
+
"tdd"
|
|
1329
|
+
];
|
|
1330
|
+
const lowerMessage = message.toLowerCase();
|
|
1331
|
+
return devKeywords.some((keyword) => lowerMessage.includes(keyword));
|
|
1332
|
+
}
|
|
1333
|
+
function getActiveFormForIntent(intent, userMessage) {
|
|
1334
|
+
const intentDescriptions = {
|
|
1335
|
+
"BUILD": `Building: ${userMessage.substring(0, 50)}...`,
|
|
1336
|
+
"DEBUG": `Debugging: ${userMessage.substring(0, 50)}...`,
|
|
1337
|
+
"REVIEW": `Reviewing: ${userMessage.substring(0, 50)}...`,
|
|
1338
|
+
"PLAN": `Planning: ${userMessage.substring(0, 50)}...`
|
|
1339
|
+
};
|
|
1340
|
+
return intentDescriptions[intent] || "Processing development task...";
|
|
1341
|
+
}
|
|
1342
|
+
function isTestCommand(command) {
|
|
1343
|
+
if (!command) return false;
|
|
1344
|
+
const testPatterns = [
|
|
1345
|
+
/test/i,
|
|
1346
|
+
/spec/i,
|
|
1347
|
+
/\.test\./,
|
|
1348
|
+
/\.spec\./,
|
|
1349
|
+
/jest/i,
|
|
1350
|
+
/mocha/i,
|
|
1351
|
+
/pytest/i,
|
|
1352
|
+
/tox/i,
|
|
1353
|
+
/npm test/i,
|
|
1354
|
+
/yarn test/i,
|
|
1355
|
+
/bun test/i
|
|
1356
|
+
];
|
|
1357
|
+
return testPatterns.some((pattern) => pattern.test(command));
|
|
1358
|
+
}
|
|
1359
|
+
function isMemoryOperation(input) {
|
|
1360
|
+
const filePath = input.args?.filePath || "";
|
|
1361
|
+
const memoryPaths = [
|
|
1362
|
+
".claude/cc10x/activeContext.md",
|
|
1363
|
+
".claude/cc10x/patterns.md",
|
|
1364
|
+
".claude/cc10x/progress.md"
|
|
1365
|
+
];
|
|
1366
|
+
return memoryPaths.some((path) => filePath.includes(path));
|
|
1367
|
+
}
|
|
1368
|
+
async function enforceTDDRequirements(ctx, input) {
|
|
1369
|
+
}
|
|
1370
|
+
async function validateMemoryOperation(ctx, input) {
|
|
1371
|
+
}
|
|
1372
|
+
async function checkForActiveWorkflow(ctx) {
|
|
1373
|
+
return null;
|
|
1374
|
+
}
|
|
1375
|
+
async function resumeWorkflow(workflow, userMessage, ctx) {
|
|
1376
|
+
}
|
|
1377
|
+
function extractMemoryNotes(result) {
|
|
1378
|
+
if (typeof result === "string") {
|
|
1379
|
+
const notes = [];
|
|
1380
|
+
const lines = result.split("\n");
|
|
1381
|
+
let inMemorySection = false;
|
|
1382
|
+
for (const line of lines) {
|
|
1383
|
+
if (line.includes("### Memory Notes")) {
|
|
1384
|
+
inMemorySection = true;
|
|
1385
|
+
continue;
|
|
1386
|
+
}
|
|
1387
|
+
if (inMemorySection) {
|
|
1388
|
+
if (line.startsWith("###") && !line.includes("Memory Notes")) {
|
|
1389
|
+
break;
|
|
1390
|
+
}
|
|
1391
|
+
if (line.trim() && !line.startsWith("#")) {
|
|
1392
|
+
notes.push(line.trim());
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
return notes;
|
|
1397
|
+
}
|
|
1398
|
+
return [];
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
// src/index.ts
|
|
1402
|
+
var OpenCodeCC10xPlugin = async (input) => {
|
|
1403
|
+
console.log("\u{1F50C} OpenCode cc10x Plugin v6.0.18 initializing...");
|
|
1404
|
+
const { $ } = input;
|
|
1405
|
+
const routerHook = await cc10xRouter({ ...input, $ });
|
|
1406
|
+
return {
|
|
1407
|
+
name: "opencode-cc10x",
|
|
1408
|
+
description: "Intelligent orchestration system for OpenCode - port of cc10x from Claude Code",
|
|
1409
|
+
version: "6.0.18",
|
|
1410
|
+
hooks: {
|
|
1411
|
+
// Router hook that intercepts user requests and orchestrates workflows
|
|
1412
|
+
"message.received": routerHook.messageReceived,
|
|
1413
|
+
// Session management hooks
|
|
1414
|
+
"session.created": routerHook.sessionCreated,
|
|
1415
|
+
"session.compacted": routerHook.sessionCompacted,
|
|
1416
|
+
// Tool execution hooks for TDD enforcement
|
|
1417
|
+
"tool.execute.before": routerHook.toolExecuteBefore,
|
|
1418
|
+
"tool.execute.after": routerHook.toolExecuteAfter,
|
|
1419
|
+
// Agent lifecycle hooks
|
|
1420
|
+
"agent.started": routerHook.agentStarted,
|
|
1421
|
+
"agent.completed": routerHook.agentCompleted
|
|
1422
|
+
},
|
|
1423
|
+
// Provide the cc10x router as a tool
|
|
1424
|
+
tools: {
|
|
1425
|
+
"cc10x-router": {
|
|
1426
|
+
description: "Main cc10x orchestration router - automatically invoked for development tasks",
|
|
1427
|
+
execute: async (args, context) => {
|
|
1428
|
+
return await routerHook.manualInvoke(args, context);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
},
|
|
1432
|
+
// Add command to appear in /commands menu
|
|
1433
|
+
commands: [
|
|
1434
|
+
{
|
|
1435
|
+
name: "cc10x-orchestrate",
|
|
1436
|
+
description: "Run cc10x intelligent orchestration for a development task",
|
|
1437
|
+
execute: async (args, context) => {
|
|
1438
|
+
const request = args.request || args.task || args.prompt || "";
|
|
1439
|
+
if (!request.trim()) {
|
|
1440
|
+
return "Please provide a task description. Usage: /cc10x-orchestrate <task description>";
|
|
1441
|
+
}
|
|
1442
|
+
console.log(`\u{1F680} cc10x orchestration triggered for: ${request}`);
|
|
1443
|
+
const workflowTaskId = `cc10x-manual-${Date.now()}`;
|
|
1444
|
+
await routerHook.manualInvoke({
|
|
1445
|
+
request,
|
|
1446
|
+
taskId: workflowTaskId,
|
|
1447
|
+
forceWorkflow: true
|
|
1448
|
+
}, context);
|
|
1449
|
+
return `\u2705 cc10x orchestration started for task: ${request}`;
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
]
|
|
1453
|
+
};
|
|
1454
|
+
};
|
|
1455
|
+
var index_default = OpenCodeCC10xPlugin;
|
|
1456
|
+
export {
|
|
1457
|
+
OpenCodeCC10xPlugin,
|
|
1458
|
+
index_default as default
|
|
1459
|
+
};
|