closed-loop-cli 1.0.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.

Potentially problematic release.


This version of closed-loop-cli might be problematic. Click here for more details.

Files changed (86) hide show
  1. package/dist/dashboard/server.js +237 -0
  2. package/dist/index.js +272 -0
  3. package/dist/orchestrator/agent-prompts.js +42 -0
  4. package/dist/orchestrator/autogenesis.js +973 -0
  5. package/dist/orchestrator/dgm-archive.js +223 -0
  6. package/dist/orchestrator/event-stream.js +103 -0
  7. package/dist/orchestrator/fitness-evaluator.js +99 -0
  8. package/dist/orchestrator/meta-agent.js +421 -0
  9. package/dist/orchestrator/microagent-registry.js +134 -0
  10. package/dist/orchestrator/mutation-strategies.js +174 -0
  11. package/dist/orchestrator/prompt-benchmark.js +102 -0
  12. package/dist/orchestrator/prompt-optimizer.js +169 -0
  13. package/dist/orchestrator/refactor-scanner.js +222 -0
  14. package/dist/orchestrator/research-manager.js +104 -0
  15. package/dist/orchestrator/rulez.js +135 -0
  16. package/dist/orchestrator/sahoo-gateway.js +261 -0
  17. package/dist/orchestrator/state-manager.js +121 -0
  18. package/dist/orchestrator/task-agent.js +444 -0
  19. package/dist/orchestrator/telegram-bot.js +374 -0
  20. package/dist/orchestrator/types.js +2 -0
  21. package/dist/tests/dynamic/dependencies.test.js +37 -0
  22. package/dist/tests/dynamic/dummy.test.js +7 -0
  23. package/dist/tests/dynamic/fuzzy-patch.test.js +68 -0
  24. package/dist/tests/dynamic/indexer.test.js +60 -0
  25. package/dist/tests/dynamic/openhands.test.js +83 -0
  26. package/dist/tests/dynamic/skills.test.js +88 -0
  27. package/dist/tests/run-tests.js +294 -0
  28. package/dist/tools/diff-tools.js +24 -0
  29. package/dist/tools/file-tools.js +191 -0
  30. package/dist/tools/indexer.js +301 -0
  31. package/dist/tools/math-helper.js +6 -0
  32. package/dist/tools/repo-map.js +122 -0
  33. package/dist/tools/search-tools.js +271 -0
  34. package/dist/tools/shell-tools.js +75 -0
  35. package/dist/tools/skills.js +122 -0
  36. package/dist/tools/tui-tools.js +82 -0
  37. package/docs/AI_Arch_Opt_Anti_Gaming.md +227 -0
  38. package/docs/AI_Self_Improvement_Safety.md +457 -0
  39. package/docs/Anthropic AI Agents_ Capabilities and Concerns.md +134 -0
  40. package/docs/Auto_ClosedLoop_AI_Agent.md +415 -0
  41. package/docs/Autonomous AI Agents_ Closing the Loop.docx +0 -0
  42. package/docs/Secure_AI_Sandbox_Framework.md +358 -0
  43. package/docs/skills/add-file-existence-check-utility.json +9 -0
  44. package/docs/skills/add-utility-function-for-file-existence-check.json +9 -0
  45. package/docs/skills/add-utility-function-to-module.json +9 -0
  46. package/docs/skills/extract-command-runner-utility.json +9 -0
  47. package/docs/skills/file-existence-check-utility.json +9 -0
  48. package/package.json +36 -0
  49. package/src/dashboard/public/index.css +1334 -0
  50. package/src/dashboard/public/index.html +385 -0
  51. package/src/dashboard/public/index.js +1059 -0
  52. package/src/dashboard/server.ts +209 -0
  53. package/src/index.ts +256 -0
  54. package/src/orchestrator/agent-prompts.ts +43 -0
  55. package/src/orchestrator/autogenesis.ts +1078 -0
  56. package/src/orchestrator/dgm-archive.ts +257 -0
  57. package/src/orchestrator/event-stream.ts +90 -0
  58. package/src/orchestrator/fitness-evaluator.ts +154 -0
  59. package/src/orchestrator/meta-agent.ts +434 -0
  60. package/src/orchestrator/microagent-registry.ts +115 -0
  61. package/src/orchestrator/microagents/git-helper.md +11 -0
  62. package/src/orchestrator/microagents/test-fixer.md +10 -0
  63. package/src/orchestrator/microagents/typescript-expert.md +11 -0
  64. package/src/orchestrator/mutation-strategies.ts +214 -0
  65. package/src/orchestrator/research-manager.ts +88 -0
  66. package/src/orchestrator/rulez.ts +118 -0
  67. package/src/orchestrator/sahoo-gateway.ts +300 -0
  68. package/src/orchestrator/state-manager.ts +161 -0
  69. package/src/orchestrator/system-prompt.txt +1 -0
  70. package/src/orchestrator/task-agent.ts +461 -0
  71. package/src/orchestrator/telegram-bot.ts +358 -0
  72. package/src/tests/dynamic/dependencies.test.ts +48 -0
  73. package/src/tests/dynamic/dummy.test.ts +4 -0
  74. package/src/tests/dynamic/fuzzy-patch.test.ts +42 -0
  75. package/src/tests/dynamic/indexer.test.ts +31 -0
  76. package/src/tests/dynamic/openhands.test.ts +59 -0
  77. package/src/tests/dynamic/skills.test.ts +63 -0
  78. package/src/tests/run-tests.ts +296 -0
  79. package/src/tools/diff-tools.ts +27 -0
  80. package/src/tools/file-tools.ts +187 -0
  81. package/src/tools/indexer.ts +325 -0
  82. package/src/tools/repo-map.ts +96 -0
  83. package/src/tools/search-tools.ts +258 -0
  84. package/src/tools/shell-tools.ts +90 -0
  85. package/src/tools/skills.ts +101 -0
  86. package/src/tools/tui-tools.ts +87 -0
@@ -0,0 +1,421 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.runSelfImprovingTask = runSelfImprovingTask;
40
+ const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const dotenv = __importStar(require("dotenv"));
44
+ const task_agent_1 = require("./task-agent");
45
+ const shell_tools_1 = require("../tools/shell-tools");
46
+ const sahoo_gateway_1 = require("./sahoo-gateway");
47
+ const diff_tools_1 = require("../tools/diff-tools");
48
+ const repo_map_1 = require("../tools/repo-map");
49
+ const agent_prompts_1 = require("./agent-prompts");
50
+ const state_manager_1 = require("./state-manager");
51
+ const tui_tools_1 = require("../tools/tui-tools");
52
+ const research_manager_1 = require("./research-manager");
53
+ const microagent_registry_1 = require("./microagent-registry");
54
+ const event_stream_1 = require("./event-stream");
55
+ // Load environment variables
56
+ dotenv.config();
57
+ const apiKey = process.env.ANTHROPIC_API_KEY || process.env.ANTHROPIC_AUTH_TOKEN || '';
58
+ const baseURL = process.env.ANTHROPIC_BASE_URL || undefined;
59
+ const defaultModel = process.env.ANTHROPIC_MODEL || 'mimo-v2.5-pro[1m]';
60
+ const anthropic = new sdk_1.default({
61
+ apiKey: apiKey,
62
+ baseURL: baseURL,
63
+ });
64
+ /**
65
+ * Runs a task inside the closed-loop system:
66
+ * 1. Reads current codebase rules (CLAUDE.md) and past experiences (Learnings.md).
67
+ * 2. Prepends memory context to the prompt.
68
+ * 3. Executes Task Agent.
69
+ * 4. Extracts learnings from the session logs and writes them back to Learnings.md.
70
+ */
71
+ function getRoleSystemPrompt(role, claudeContext, learningsContext, repoMapContext, osContext, microagentsContext) {
72
+ let rolePrompt = '';
73
+ switch (role) {
74
+ case 'architect':
75
+ rolePrompt = agent_prompts_1.ARCHITECT_PROMPT;
76
+ break;
77
+ case 'coder':
78
+ rolePrompt = agent_prompts_1.CODER_PROMPT;
79
+ break;
80
+ case 'coder_codeact':
81
+ rolePrompt = agent_prompts_1.CODEACT_CODER_PROMPT;
82
+ break;
83
+ case 'debugger':
84
+ rolePrompt = agent_prompts_1.DEBUGGER_PROMPT;
85
+ break;
86
+ case 'gatekeeper':
87
+ rolePrompt = agent_prompts_1.GATEKEEPER_PROMPT;
88
+ break;
89
+ }
90
+ // Load custom playbooks from the Skill Registry
91
+ let skillsSummary = 'No custom development skills recorded yet.';
92
+ try {
93
+ const { getSkillsSummary } = require('../tools/skills');
94
+ skillsSummary = getSkillsSummary();
95
+ }
96
+ catch (e) { }
97
+ return `You are operating inside a self-improving workspace. You have specialized responsibilities.
98
+ ROLE SPECIFICATION:
99
+ ${rolePrompt}
100
+
101
+ ---
102
+ CRITICAL WORKSPACE GUIDELINES (CLAUDE.md):
103
+ ${claudeContext}
104
+
105
+ ---
106
+ REUSABLE DEVELOPMENT SKILLS (Playbooks derived from past successful evolutions):
107
+ ${skillsSummary}
108
+
109
+ ---
110
+ PAST EXPERIENCE & LEARNINGS (Learnings.md):
111
+ ${learningsContext}
112
+
113
+ ---
114
+ DYNAMICS & INSTRUCTIONS FROM MICROAGENTS:
115
+ ${microagentsContext || 'No microagents active for this context.'}
116
+
117
+ ---
118
+ CODEBASE REPOSITORY MAP (Overview of files and structural signatures):
119
+ ${repoMapContext}
120
+ ---
121
+ ` + osContext;
122
+ }
123
+ async function runSelfImprovingTask(task, effort = 'standard', codeactMode = false) {
124
+ const workspaceRoot = process.cwd();
125
+ const claudePath = path.join(workspaceRoot, 'CLAUDE.md');
126
+ const learningsPath = path.join(workspaceRoot, 'Learnings.md');
127
+ // 1. Read CLAUDE.md and Learnings.md context
128
+ let claudeContext = '';
129
+ let learningsContext = '';
130
+ if (fs.existsSync(claudePath)) {
131
+ claudeContext = fs.readFileSync(claudePath, 'utf-8');
132
+ }
133
+ if (fs.existsSync(learningsPath)) {
134
+ learningsContext = fs.readFileSync(learningsPath, 'utf-8');
135
+ }
136
+ // Generate AST Code Index
137
+ try {
138
+ const { generateCodeIndex } = require('../tools/indexer');
139
+ console.log(`\x1b[34m[MetaAgent]\x1b[0m Generating AST code index (code-index.json)...`);
140
+ generateCodeIndex(workspaceRoot);
141
+ }
142
+ catch (err) {
143
+ console.error(`\x1b[31m[MetaAgent] Failed to generate code index: ${err.message}\x1b[0m`);
144
+ }
145
+ // Generate Repository Map
146
+ let repoMapContext = '';
147
+ try {
148
+ repoMapContext = (0, repo_map_1.generateRepoMap)(workspaceRoot);
149
+ }
150
+ catch (err) {
151
+ console.error(`\x1b[31m[MetaAgent] Failed to generate codebase map: ${err.message}\x1b[0m`);
152
+ }
153
+ console.log(`\x1b[34m[MetaAgent]\x1b[0m Ingesting memory context and codebase map...`);
154
+ // Inject OS environment awareness to guide command execution safely
155
+ const osType = process.platform === 'win32' ? 'Windows (win32)' : process.platform;
156
+ const shellType = process.platform === 'win32' ? 'PowerShell or Command Prompt (cmd.exe)' : 'Bash or Sh';
157
+ const osContext = `\n\n---
158
+ CURRENT ENVIRONMENT & OS SAFETY GUIDELINES:
159
+ - Operating System: ${osType}
160
+ - Active Terminal Shell: ${shellType}
161
+ ${process.platform === 'win32' ? `
162
+ IMPORTANT: You are running on Windows. Unix terminal commands such as 'cat', 'ls', 'grep', 'rm -rf', and pipes like '| head' or '| grep' are NOT supported natively.
163
+ - Use Windows/PowerShell equivalent commands (e.g., 'Get-Content' instead of 'cat', 'dir' or 'Get-ChildItem' instead of 'ls', and Node scripts or PowerShell commands for string filtering).
164
+ - Keep commands compatible with Windows environment syntax.` : `
165
+ - Use Unix terminal commands natively compatible with the active shell.`}
166
+ ---`;
167
+ let targetFile = '';
168
+ let dependencyWarning = '';
169
+ if (task.includes('Refactor the file "')) {
170
+ targetFile = task.split('"')[1];
171
+ }
172
+ else if (task.includes('file "')) {
173
+ targetFile = task.split('"')[1];
174
+ }
175
+ if (targetFile) {
176
+ try {
177
+ const { getDependents } = require('../tools/indexer');
178
+ const dependents = getDependents(targetFile, workspaceRoot);
179
+ if (dependents.length > 0) {
180
+ dependencyWarning = `\n\n---
181
+ DEPENDENCY WARNING:
182
+ The file you are modifying ("${targetFile}") is imported by the following files in this project:
183
+ ${dependents.map((f) => `- ${f}`).join('\n')}
184
+
185
+ IMPORTANT: Make sure that any changes to function signatures, classes, or exported variables do not break these importing files. If you change exports, you must also update the files importing them.
186
+ ---`;
187
+ console.log(`\x1b[33m[Dependency Guard] Target file "${targetFile}" is imported by: ${JSON.stringify(dependents)}\x1b[0m\n`);
188
+ }
189
+ }
190
+ catch (e) {
191
+ console.error('[Dependency Guard] Failed to resolve dependents:', e);
192
+ }
193
+ }
194
+ // Load Microagents context
195
+ const registry = microagent_registry_1.MicroagentRegistry.getInstance();
196
+ registry.loadMicroagents(); // reload to get latest updates
197
+ const matchingAgents = registry.findMatchingMicroagents(task);
198
+ let microagentsContext = '';
199
+ if (matchingAgents.length > 0) {
200
+ microagentsContext = matchingAgents.map(a => `[Microagent: ${a.name}]\nInstructions:\n${a.instructions}`).join('\n\n');
201
+ console.log(`\x1b[32m[MicroagentRegistry]\x1b[0m Triggered Microagents: ${matchingAgents.map(a => a.name).join(', ')}`);
202
+ event_stream_1.EventStream.getInstance().publish('system', 'log', 'MicroagentsTriggered', `Triggered microagents: ${matchingAgents.map(a => a.name).join(', ')}`);
203
+ }
204
+ let result = '';
205
+ let errorMsg = '';
206
+ const startTime = new Date();
207
+ try {
208
+ // Phase 1: Architect / Planner Agent
209
+ (0, tui_tools_1.printAgentHeader)('architect');
210
+ research_manager_1.ResearchManager.logDecision('Architect (Planner)', 'Spawning Planner Agent to generate implementation plan', 'info');
211
+ const architectPrompt = getRoleSystemPrompt('architect', claudeContext, learningsContext, repoMapContext, osContext, microagentsContext);
212
+ const architectReport = await (0, task_agent_1.runTaskAgent)(task + dependencyWarning, {
213
+ systemPrompt: architectPrompt,
214
+ role: 'architect',
215
+ effort
216
+ });
217
+ const plan = architectReport.result;
218
+ console.log(`\x1b[32m[MetaAgent]\x1b[0m Plan generated successfully:\n${plan}\n`);
219
+ research_manager_1.ResearchManager.logDecision('Architect (Planner)', 'Plan generated successfully', 'success', plan);
220
+ // Phase 2: Coder Agent
221
+ (0, tui_tools_1.printAgentHeader)('coder');
222
+ research_manager_1.ResearchManager.logDecision('Coder (Worker)', `Spawning Coder Agent to apply mutations (CodeAct=${codeactMode})`, 'info');
223
+ const coderPrompt = getRoleSystemPrompt(codeactMode ? 'coder_codeact' : 'coder', claudeContext, learningsContext, repoMapContext, osContext, microagentsContext);
224
+ const coderReport = await (0, task_agent_1.runTaskAgent)(`Here is the task you must implement:\n"${task}"\n\nHere is the approved design plan/blueprint to guide your implementation:\n"""\n${plan}\n"""\n\nPlease implement the code changes as planned. Use editFile or writeFile to execute the plan.`, {
225
+ systemPrompt: coderPrompt,
226
+ role: codeactMode ? 'coder_codeact' : 'coder',
227
+ effort
228
+ });
229
+ result = coderReport.result;
230
+ console.log(`\x1b[32m[MetaAgent]\x1b[0m Code mutations applied.`);
231
+ research_manager_1.ResearchManager.logDecision('Coder (Worker)', 'Coder mutated files successfully based on design plan', 'success', result);
232
+ // Phase 3: Inner Self-Healing Loop (Debugger <-> Coder)
233
+ const healCycles = 3;
234
+ let buildSuccess = false;
235
+ let testSuccess = false;
236
+ for (let cycle = 1; cycle <= healCycles; cycle++) {
237
+ console.log(`\n\x1b[34m[MetaAgent]\x1b[0m Verification Loop - Cycle ${cycle}/${healCycles}: Running compilation check...`);
238
+ research_manager_1.ResearchManager.logDecision('Verification', `Running compilation check (Cycle ${cycle}/${healCycles})`, 'info');
239
+ const compileRes = await (0, shell_tools_1.runCommand)('npm run build');
240
+ buildSuccess = compileRes.exitCode === 0;
241
+ console.log(`\x1b[34m[MetaAgent]\x1b[0m Verification Loop - Cycle ${cycle}/${healCycles}: Running tests check...`);
242
+ research_manager_1.ResearchManager.logDecision('Verification', `Running unit tests (Cycle ${cycle}/${healCycles})`, 'info');
243
+ const testRes = await (0, shell_tools_1.runCommand)('npm test');
244
+ testSuccess = testRes.exitCode === 0;
245
+ if (buildSuccess && testSuccess) {
246
+ console.log(`\x1b[32m[MetaAgent]\x1b[0m Codebase compile & test execution passed! Code is healthy.\x1b[0m`);
247
+ research_manager_1.ResearchManager.logDecision('Verification', 'Compilation & unit tests passed successfully', 'success');
248
+ break;
249
+ }
250
+ const errorLog = `Compilation Output:\nExit Code: ${compileRes.exitCode}\nStdout:\n${compileRes.stdout}\nStderr:\n${compileRes.stderr}\n\nTest Suite Output:\nExit Code: ${testRes.exitCode}\nStdout:\n${testRes.stdout}\nStderr:\n${testRes.stderr}`;
251
+ research_manager_1.ResearchManager.logDecision('Verification', `Build/tests failed (Cycle ${cycle}/${healCycles})`, 'failure', errorLog);
252
+ if (cycle < healCycles) {
253
+ (0, tui_tools_1.printAgentHeader)('debugger');
254
+ console.log(`\x1b[33m[MetaAgent] Build/tests failed. Invoking Diagnostics & Debugger Agent to analyze errors...\x1b[0m`);
255
+ research_manager_1.ResearchManager.logDecision('Debugger', 'Spawning Debugger Agent to analyze compilation/test errors', 'info');
256
+ const debuggerPrompt = getRoleSystemPrompt('debugger', claudeContext, learningsContext, repoMapContext, osContext, microagentsContext);
257
+ const debuggerReport = await (0, task_agent_1.runTaskAgent)(`The code modification failed verification. Here is the compile/test execution log:\n\n${errorLog}\n\nPlease inspect the error trace, identify the exact lines and files of code that caused the issue, and output a specific, actionable instruction for the Coder agent to fix it. Do NOT make file changes yourself.`, {
258
+ systemPrompt: debuggerPrompt,
259
+ role: 'debugger',
260
+ effort
261
+ });
262
+ console.log(`\x1b[33m[MetaAgent] Diagnostic feedback received. Re-running Coder Agent to apply the fix...\x1b[0m`);
263
+ research_manager_1.ResearchManager.logDecision('Debugger', 'Diagnostic advice generated', 'success', debuggerReport.result);
264
+ research_manager_1.ResearchManager.logDecision('Coder (Worker)', `Applying corrections based on diagnostic instructions (Cycle ${cycle}/${healCycles})`, 'info');
265
+ const correctionTask = `The previous implementation caused build/test failures.
266
+ Here is the error trace:
267
+ ${errorLog}
268
+
269
+ Here is the diagnostic instruction from the Debugger agent:
270
+ "${debuggerReport.result}"
271
+
272
+ Please make the necessary file edits (using editFile or writeFile) to correct the codebase.`;
273
+ const recoderReport = await (0, task_agent_1.runTaskAgent)(correctionTask, {
274
+ systemPrompt: coderPrompt,
275
+ role: 'coder',
276
+ effort
277
+ });
278
+ result = recoderReport.result;
279
+ research_manager_1.ResearchManager.logDecision('Coder (Worker)', `Applied corrections (Cycle ${cycle}/${healCycles})`, 'success');
280
+ }
281
+ else {
282
+ console.log(`\x1b[31m[MetaAgent] Build/tests failed after maximum self-healing cycles.\x1b[0m`);
283
+ research_manager_1.ResearchManager.logDecision('Verification', `Self-healing failed to stabilize build and tests after ${healCycles} attempts`, 'failure');
284
+ throw new Error(`Self-healing failed to stabilize build and tests after ${healCycles} attempts.\n${errorLog}`);
285
+ }
286
+ }
287
+ // Phase 4: Gatekeeper & Reviewer Agent
288
+ (0, tui_tools_1.printAgentHeader)('gatekeeper');
289
+ research_manager_1.ResearchManager.logDecision('Gatekeeper', 'Spawning Gatekeeper Agent to perform safety and quality review', 'info');
290
+ const gatekeeperPrompt = getRoleSystemPrompt('gatekeeper', claudeContext, learningsContext, repoMapContext, osContext, microagentsContext);
291
+ // Find modified files via git status
292
+ const gitStatus = await (0, shell_tools_1.runCommand)('git status --porcelain');
293
+ const modifiedFiles = [];
294
+ if (gitStatus.exitCode === 0 && gitStatus.stdout.trim()) {
295
+ const lines = gitStatus.stdout.split('\n');
296
+ for (const line of lines) {
297
+ const trimmed = line.trim();
298
+ if (trimmed.startsWith('M ') || trimmed.startsWith('A ') || trimmed.startsWith('?? ')) {
299
+ const filePath = trimmed.substring(2).trim();
300
+ if (filePath && !filePath.includes('Learnings.md') && !filePath.includes('.env') && !filePath.includes('code-index.json')) {
301
+ modifiedFiles.push(filePath);
302
+ }
303
+ }
304
+ }
305
+ }
306
+ console.log(`\x1b[34m[MetaAgent]\x1b[0m Modified files detected: ${JSON.stringify(modifiedFiles)}`);
307
+ if (modifiedFiles.length > 0) {
308
+ const diffRes = await (0, shell_tools_1.runCommand)('git diff');
309
+ const reviewerReport = await (0, task_agent_1.runTaskAgent)(`Please review the modifications in the git diff below and confirm if they compile and are safe:\n\n${diffRes.stdout}\n\nIf anything is unsafe or incorrect, raise a concern.`, {
310
+ systemPrompt: gatekeeperPrompt,
311
+ role: 'gatekeeper',
312
+ effort
313
+ });
314
+ console.log(`\x1b[32m[MetaAgent]\x1b[0m Reviewer comments:\n${reviewerReport.result}\n`);
315
+ research_manager_1.ResearchManager.logDecision('Gatekeeper', 'Safety & quality audit report complete', 'success', reviewerReport.result);
316
+ for (const filePath of modifiedFiles) {
317
+ const fullPath = path.join(workspaceRoot, filePath);
318
+ let afterContent = '';
319
+ if (fs.existsSync(fullPath)) {
320
+ afterContent = fs.readFileSync(fullPath, 'utf-8');
321
+ }
322
+ // Get beforeContent using git show HEAD:path
323
+ let beforeContent = '';
324
+ try {
325
+ const beforeRes = await (0, shell_tools_1.runCommand)(`git show HEAD:${filePath.replace(/\\/g, '/')}`);
326
+ if (beforeRes.exitCode === 0) {
327
+ beforeContent = beforeRes.stdout;
328
+ }
329
+ }
330
+ catch (e) {
331
+ // If file is new, beforeContent remains empty
332
+ }
333
+ research_manager_1.ResearchManager.logDecision('SAHOO Safety Gate', `Evaluating SAHOO policies for ${filePath}`, 'info');
334
+ const sahooRes = (0, sahoo_gateway_1.evaluateSahoo)(filePath, beforeContent, afterContent, buildSuccess, testSuccess);
335
+ if (!sahooRes.passed) {
336
+ console.log(`\x1b[31m[SAHOO HALT TRIGGERED]\x1b[0m ${sahooRes.reason}`);
337
+ console.log(`\x1b[31m[MetaAgent] SAHOO Gateway Rejected changes. Rolling back codebase...\x1b[0m`);
338
+ research_manager_1.ResearchManager.logDecision('SAHOO Safety Gate', `SAHOO rejected change in ${filePath}: ${sahooRes.reason}`, 'failure');
339
+ (0, state_manager_1.updateEvolutionState)({
340
+ lastRefactorResult: {
341
+ success: false,
342
+ targetFile: filePath,
343
+ message: `SAHOO Gateway Rejected: ${sahooRes.reason}`,
344
+ time: new Date().toISOString(),
345
+ metrics: sahooRes.metrics,
346
+ reason: sahooRes.reason
347
+ }
348
+ });
349
+ // Execute git rollback (revert all changes)
350
+ research_manager_1.ResearchManager.logDecision('Rollback', 'Reverting workspace modifications via git reset to preserve stability', 'info');
351
+ await (0, shell_tools_1.runCommand)('git reset --hard HEAD');
352
+ await (0, shell_tools_1.runCommand)('git clean -fd');
353
+ throw new Error(`SAHOO Policy Violation: ${sahooRes.reason}. Reverted all changes to preserve system stability.`);
354
+ }
355
+ else {
356
+ console.log(`\x1b[32m[SAHOO Passed]\x1b[0m File: ${filePath} | GDI: ${sahooRes.metrics.goalDriftIndex.toFixed(3)} | CPS: ${sahooRes.metrics.constraintPreservationScore}`);
357
+ console.log(await (0, diff_tools_1.getFormattedDiff)(filePath));
358
+ research_manager_1.ResearchManager.logDecision('SAHOO Safety Gate', `SAHOO passed for ${filePath}`, 'success');
359
+ (0, state_manager_1.updateEvolutionState)({
360
+ lastRefactorResult: {
361
+ success: true,
362
+ targetFile: filePath,
363
+ message: 'SAHOO Gateway passed.',
364
+ time: new Date().toISOString(),
365
+ metrics: sahooRes.metrics
366
+ }
367
+ });
368
+ }
369
+ }
370
+ }
371
+ }
372
+ catch (err) {
373
+ errorMsg = err.message;
374
+ console.error(`\x1b[31m[MetaAgent] Multi-Agent run encountered an error: ${errorMsg}\x1b[0m`);
375
+ }
376
+ const endTime = new Date();
377
+ const elapsedMinutes = ((endTime.getTime() - startTime.getTime()) / 60000).toFixed(1);
378
+ // 4. Summarize and write learnings to Learnings.md (Closing the Loop)
379
+ console.log(`\x1b[34m[MetaAgent]\x1b[0m Synthesizing learnings from session...`);
380
+ const dateStr = startTime.toISOString().split('T')[0];
381
+ const summaryPrompt = `Based on the following session logs, extract the key learnings in the strict Learnings.md format.
382
+ Include:
383
+ 1. Observation (สิ่งที่พบ): What succeeded, failed, linter errors, or quirks of the codebase.
384
+ 2. Action (การแก้ไข): The precise changes, command fixes, or prompt templates adjusted.
385
+ 3. Confidence: A decimal from 0.0 to 1.0.
386
+
387
+ Session Details:
388
+ - Task: "${task}"
389
+ - Duration: ${elapsedMinutes} minutes
390
+ - Status: ${errorMsg ? 'FAILED with error: ' + errorMsg : 'SUCCESS'}
391
+ - Agent Output: "${result}"
392
+
393
+ Return ONLY the markdown section matching:
394
+ ### YYYY-MM-DD - [Task Name]
395
+ - **Observation (สิ่งที่พบ)**: ...
396
+ - **Action (การแก้ไข)**: ...
397
+ - **Confidence (ความมั่นใจ 0-1)**: ...
398
+ `;
399
+ try {
400
+ const summaryResponse = await anthropic.messages.create({
401
+ model: defaultModel,
402
+ max_tokens: 1000,
403
+ messages: [{ role: 'user', content: summaryPrompt }],
404
+ });
405
+ const summaryBlock = summaryResponse.content.find(b => b.type === 'text');
406
+ if (summaryBlock && summaryBlock.text) {
407
+ const learningsText = summaryBlock.text.trim();
408
+ console.log(`\n\x1b[32m[New Learnings Formulated]:\x1b[0m\n${learningsText}\n`);
409
+ // Append to Learnings.md
410
+ fs.appendFileSync(learningsPath, `\n${learningsText}\n`, 'utf-8');
411
+ console.log(`\x1b[34m[MetaAgent]\x1b[0m Successfully updated Learnings.md`);
412
+ }
413
+ }
414
+ catch (summaryErr) {
415
+ console.error(`\x1b[31m[MetaAgent] Failed to write learnings to Learnings.md: ${summaryErr.message}\x1b[0m`);
416
+ }
417
+ if (errorMsg) {
418
+ throw new Error(errorMsg);
419
+ }
420
+ return result;
421
+ }
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MicroagentRegistry = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ class MicroagentRegistry {
40
+ static instance;
41
+ microagents = [];
42
+ dirPath;
43
+ constructor() {
44
+ this.dirPath = path.join(process.cwd(), 'src', 'orchestrator', 'microagents');
45
+ this.ensureDirectoryExists();
46
+ this.loadMicroagents();
47
+ }
48
+ static getInstance() {
49
+ if (!MicroagentRegistry.instance) {
50
+ MicroagentRegistry.instance = new MicroagentRegistry();
51
+ }
52
+ return MicroagentRegistry.instance;
53
+ }
54
+ ensureDirectoryExists() {
55
+ if (!fs.existsSync(this.dirPath)) {
56
+ fs.mkdirSync(this.dirPath, { recursive: true });
57
+ }
58
+ }
59
+ loadMicroagents() {
60
+ this.microagents = [];
61
+ if (!fs.existsSync(this.dirPath))
62
+ return;
63
+ try {
64
+ const files = fs.readdirSync(this.dirPath);
65
+ for (const file of files) {
66
+ if (file.endsWith('.md')) {
67
+ const filePath = path.join(this.dirPath, file);
68
+ const content = fs.readFileSync(filePath, 'utf-8');
69
+ const microagent = this.parseMicroagent(content);
70
+ if (microagent) {
71
+ this.microagents.push(microagent);
72
+ }
73
+ }
74
+ }
75
+ console.log(`[MicroagentRegistry] Loaded ${this.microagents.length} microagents.`);
76
+ }
77
+ catch (e) {
78
+ console.error('[MicroagentRegistry] Failed to load microagents:', e);
79
+ }
80
+ }
81
+ parseMicroagent(content) {
82
+ // Simple YAML frontmatter parser
83
+ const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/);
84
+ if (!match)
85
+ return null;
86
+ const frontmatter = match[1];
87
+ const instructions = match[2].trim();
88
+ const metadata = {};
89
+ const lines = frontmatter.split('\n');
90
+ for (const line of lines) {
91
+ const parts = line.split(':');
92
+ if (parts.length >= 2) {
93
+ const key = parts[0].trim();
94
+ const value = parts.slice(1).join(':').trim();
95
+ metadata[key] = value;
96
+ }
97
+ }
98
+ if (!metadata.name || !metadata.trigger) {
99
+ return null;
100
+ }
101
+ return {
102
+ name: metadata.name,
103
+ trigger: metadata.trigger,
104
+ description: metadata.description || '',
105
+ instructions
106
+ };
107
+ }
108
+ getMicroagents() {
109
+ return this.microagents;
110
+ }
111
+ /**
112
+ * Returns microagents whose triggers match the query/context string.
113
+ */
114
+ findMatchingMicroagents(query) {
115
+ const matched = [];
116
+ const lowerQuery = query.toLowerCase();
117
+ for (const agent of this.microagents) {
118
+ try {
119
+ const regex = new RegExp(agent.trigger, 'i');
120
+ if (regex.test(lowerQuery)) {
121
+ matched.push(agent);
122
+ }
123
+ }
124
+ catch (e) {
125
+ // Fallback to substring match if regex is invalid
126
+ if (lowerQuery.includes(agent.trigger.toLowerCase())) {
127
+ matched.push(agent);
128
+ }
129
+ }
130
+ }
131
+ return matched;
132
+ }
133
+ }
134
+ exports.MicroagentRegistry = MicroagentRegistry;