swarm-orchestrator 7.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +15 -0
- package/README.md +199 -0
- package/agents/reviewer.agent.md +50 -0
- package/agents/worker.agent.md +41 -0
- package/config/default-agents.yaml +56 -0
- package/config/pm-agent.yaml +36 -0
- package/config/quality-gates.yaml +88 -0
- package/config/repair-agent.yaml +34 -0
- package/config/semgrep-rules/complexity-mismatch.yaml +6 -0
- package/config/semgrep-rules/exception-swallowing.yaml +13 -0
- package/config/semgrep-rules/hardcoded-answer.yaml +6 -0
- package/config/semgrep-rules/mock-mutation.yaml +6 -0
- package/config/semgrep-rules/test-modification.yaml +6 -0
- package/config/user-agents.yaml +23 -0
- package/dist/src/adapters/adapter-factory.js +29 -0
- package/dist/src/adapters/agent-adapter.js +32 -0
- package/dist/src/adapters/claude-code-adapter.js +126 -0
- package/dist/src/adapters/claude-code-teams.js +119 -0
- package/dist/src/adapters/codex-adapter.js +118 -0
- package/dist/src/adapters/copilot-adapter.js +224 -0
- package/dist/src/adapters/fatal-error-classifier.js +88 -0
- package/dist/src/adapters/index.js +44 -0
- package/dist/src/adapters/persistent-session.js +204 -0
- package/dist/src/adapters/process-supervisor.js +199 -0
- package/dist/src/agents-exporter.js +398 -0
- package/dist/src/analytics-log.js +161 -0
- package/dist/src/baseline-scanner.js +65 -0
- package/dist/src/bootstrap-evidence.js +88 -0
- package/dist/src/bootstrap-orchestrator.js +205 -0
- package/dist/src/bootstrap-types.js +5 -0
- package/dist/src/branch-merger.js +427 -0
- package/dist/src/cli/attest-handlers.js +44 -0
- package/dist/src/cli/cost-prompt.js +51 -0
- package/dist/src/cli/demo-handlers.js +274 -0
- package/dist/src/cli/flags.js +152 -0
- package/dist/src/cli/index.js +57 -0
- package/dist/src/cli/live-status.js +186 -0
- package/dist/src/cli/misc-handlers.js +242 -0
- package/dist/src/cli/plan-handlers.js +350 -0
- package/dist/src/cli/share-handlers.js +163 -0
- package/dist/src/cli/status-handlers.js +457 -0
- package/dist/src/cli/swarm-handlers.js +638 -0
- package/dist/src/cli/usage.js +72 -0
- package/dist/src/cli.js +217 -0
- package/dist/src/commit-pattern-detector.js +143 -0
- package/dist/src/commit-quality-analyzer.js +38 -0
- package/dist/src/config-loader.js +339 -0
- package/dist/src/context-broker.js +358 -0
- package/dist/src/copilot-cli-wrapper.js +258 -0
- package/dist/src/cost-estimator.js +241 -0
- package/dist/src/defaults.js +18 -0
- package/dist/src/demo-mode.js +180 -0
- package/dist/src/deployment-handler.js +78 -0
- package/dist/src/deployment-manager.js +228 -0
- package/dist/src/execution-queue.js +196 -0
- package/dist/src/external-tool-manager.js +184 -0
- package/dist/src/gate-prompt-builder.js +117 -0
- package/dist/src/gate-remediation.js +173 -0
- package/dist/src/github-issues-ingester.js +152 -0
- package/dist/src/github-mcp-integrator.js +164 -0
- package/dist/src/hook-generator.js +229 -0
- package/dist/src/index.js +48 -0
- package/dist/src/knowledge-base.js +300 -0
- package/dist/src/logger.js +111 -0
- package/dist/src/meta-analyzer.js +208 -0
- package/dist/src/metrics-collector.js +209 -0
- package/dist/src/metrics-types.js +5 -0
- package/dist/src/multi-repo-coordinator.js +179 -0
- package/dist/src/orchestrator/async-meta-analysis.js +84 -0
- package/dist/src/orchestrator/fatal-run-error.js +43 -0
- package/dist/src/orchestrator/final-gates-remediation.js +258 -0
- package/dist/src/orchestrator/git-state-utils.js +119 -0
- package/dist/src/orchestrator/pause-controller.js +55 -0
- package/dist/src/orchestrator/replan-runner.js +258 -0
- package/dist/src/orchestrator/step-executor.js +391 -0
- package/dist/src/orchestrator/wave-scheduler-loop.js +204 -0
- package/dist/src/owasp-mapper.js +153 -0
- package/dist/src/owasp-report-renderer.js +39 -0
- package/dist/src/plan-files.js +142 -0
- package/dist/src/plan-generator.js +1207 -0
- package/dist/src/pm-agent.js +296 -0
- package/dist/src/post-run-reporter.js +203 -0
- package/dist/src/pr-automation.js +103 -0
- package/dist/src/pr-manager.js +318 -0
- package/dist/src/presenter/index.js +209 -0
- package/dist/src/prompt-builder.js +173 -0
- package/dist/src/quality-gates/config-loader.js +196 -0
- package/dist/src/quality-gates/default-config.js +243 -0
- package/dist/src/quality-gates/file-utils.js +152 -0
- package/dist/src/quality-gates/gate-runner.js +171 -0
- package/dist/src/quality-gates/gates/accessibility.js +355 -0
- package/dist/src/quality-gates/gates/duplicate-blocks.js +144 -0
- package/dist/src/quality-gates/gates/hardcoded-config.js +52 -0
- package/dist/src/quality-gates/gates/readme-claims.js +62 -0
- package/dist/src/quality-gates/gates/runtime-checks.js +265 -0
- package/dist/src/quality-gates/gates/scaffold-defaults.js +108 -0
- package/dist/src/quality-gates/gates/test-coverage.js +240 -0
- package/dist/src/quality-gates/gates/test-file-protection.js +85 -0
- package/dist/src/quality-gates/gates/test-isolation.js +74 -0
- package/dist/src/quality-gates/index.js +17 -0
- package/dist/src/quality-gates/registry.js +205 -0
- package/dist/src/quality-gates/types.js +2 -0
- package/dist/src/quick-fix-mode.js +302 -0
- package/dist/src/recipe-loader.js +122 -0
- package/dist/src/repair-agent.js +396 -0
- package/dist/src/repo-analyzer.js +342 -0
- package/dist/src/report-generator.js +146 -0
- package/dist/src/report-renderer.js +90 -0
- package/dist/src/requirement-filter.js +52 -0
- package/dist/src/sarif-formatter.js +140 -0
- package/dist/src/scheduling/dependency-analyzer.js +178 -0
- package/dist/src/scheduling/work-stealing-queue.js +123 -0
- package/dist/src/secret-redactor.js +90 -0
- package/dist/src/session-executor.js +587 -0
- package/dist/src/session-manager.js +221 -0
- package/dist/src/share/transcript-verification.js +128 -0
- package/dist/src/share-parser.js +477 -0
- package/dist/src/spinner.js +146 -0
- package/dist/src/step-runner.js +365 -0
- package/dist/src/swarm-orchestrator.js +686 -0
- package/dist/src/task-classifier.js +134 -0
- package/dist/src/test-command-discovery.js +123 -0
- package/dist/src/text-similarity.js +24 -0
- package/dist/src/tier-maps.js +158 -0
- package/dist/src/types.js +5 -0
- package/dist/src/url-shortener.js +135 -0
- package/dist/src/verification/attestation.js +166 -0
- package/dist/src/verification/cheat-detector.js +240 -0
- package/dist/src/verification/command-runner.js +70 -0
- package/dist/src/verification/composite-score.js +157 -0
- package/dist/src/verification/cosign-attestation.js +137 -0
- package/dist/src/verification/diff-analysis.js +89 -0
- package/dist/src/verification/differential-gate.js +173 -0
- package/dist/src/verification/index.js +41 -0
- package/dist/src/verification/mutation-gate.js +242 -0
- package/dist/src/verification/property-gate.js +201 -0
- package/dist/src/verification/test-synthesizer.js +243 -0
- package/dist/src/verifier/outcome-checks.js +396 -0
- package/dist/src/verifier/transcript-checks.js +207 -0
- package/dist/src/verifier/verification-reporters.js +148 -0
- package/dist/src/verifier-engine.js +491 -0
- package/dist/src/wave-resizer.js +131 -0
- package/dist/src/wave-scheduler.js +44 -0
- package/dist/src/worktree-manager.js +368 -0
- package/dist/src/worktree-reserved-paths.js +97 -0
- package/package.json +80 -0
- package/plugin/agents/.gitkeep +0 -0
- package/plugin/agents/backend_master.agent.md +72 -0
- package/plugin/agents/devops_pro.agent.md +45 -0
- package/plugin/agents/frontend_expert.agent.md +59 -0
- package/plugin/agents/integrator_finalizer.agent.md +44 -0
- package/plugin/agents/meta_reviewer.agent.md +44 -0
- package/plugin/agents/security_auditor.agent.md +43 -0
- package/plugin/agents/tester_elite.agent.md +43 -0
- package/plugin/hooks/hooks.json +19 -0
- package/plugin/hooks/post-tool-use.json +9 -0
- package/plugin/hooks/pre-tool-use.json +9 -0
- package/plugin/plugin.json +47 -0
- package/plugin/skills/swarm-gates/SKILL.md +53 -0
- package/plugin/skills/swarm-orchestrate/SKILL.md +34 -0
- package/plugin/skills/swarm-verify/SKILL.md +44 -0
- package/templates/README.md +35 -0
- package/templates/cli-tool.json +31 -0
- package/templates/fullstack.json +52 -0
- package/templates/library.json +38 -0
- package/templates/react-app.json +45 -0
- package/templates/recipes/add-api-docs.json +35 -0
- package/templates/recipes/add-auth.json +47 -0
- package/templates/recipes/add-ci.json +39 -0
- package/templates/recipes/add-tests.json +39 -0
- package/templates/recipes/migrate-to-ts.json +42 -0
- package/templates/recipes/refactor-modularize.json +44 -0
- package/templates/recipes/security-audit.json +35 -0
- package/templates/rest-api.json +38 -0
|
@@ -0,0 +1,209 @@
|
|
|
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
|
+
const fs = __importStar(require("fs"));
|
|
37
|
+
const path = __importStar(require("path"));
|
|
38
|
+
const logger_1 = require("./logger");
|
|
39
|
+
const logger = (0, logger_1.getLogger)('metrics-collector');
|
|
40
|
+
/**
|
|
41
|
+
* Collects metrics during orchestrator execution
|
|
42
|
+
* Tracks time, commits, verifications, and recovery events
|
|
43
|
+
*/
|
|
44
|
+
class MetricsCollector {
|
|
45
|
+
executionId;
|
|
46
|
+
goal;
|
|
47
|
+
startTime;
|
|
48
|
+
endTime;
|
|
49
|
+
waveCount = 0;
|
|
50
|
+
stepCount = 0;
|
|
51
|
+
commitCount = 0;
|
|
52
|
+
verificationsPassed = 0;
|
|
53
|
+
verificationsFailed = 0;
|
|
54
|
+
recoveryEvents = [];
|
|
55
|
+
agentsUsed = new Set();
|
|
56
|
+
constructor(executionId, goal) {
|
|
57
|
+
this.executionId = executionId;
|
|
58
|
+
this.goal = goal;
|
|
59
|
+
this.startTime = new Date();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Mark start of new wave
|
|
63
|
+
*/
|
|
64
|
+
startWave(waveNumber) {
|
|
65
|
+
this.waveCount = Math.max(this.waveCount, waveNumber);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Track step execution
|
|
69
|
+
*/
|
|
70
|
+
trackStep(stepNumber, agentName) {
|
|
71
|
+
this.stepCount = Math.max(this.stepCount, stepNumber);
|
|
72
|
+
this.agentsUsed.add(agentName);
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Track commit produced
|
|
76
|
+
*/
|
|
77
|
+
trackCommit(agentName) {
|
|
78
|
+
this.commitCount++;
|
|
79
|
+
if (agentName) {
|
|
80
|
+
this.agentsUsed.add(agentName);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Track verification result
|
|
85
|
+
*/
|
|
86
|
+
trackVerification(passed) {
|
|
87
|
+
if (passed) {
|
|
88
|
+
this.verificationsPassed++;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this.verificationsFailed++;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Track recovery event
|
|
96
|
+
*/
|
|
97
|
+
trackRecovery(event) {
|
|
98
|
+
this.recoveryEvents.push(event);
|
|
99
|
+
this.agentsUsed.add(event.agentName);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Mark execution end and finalize metrics
|
|
103
|
+
*/
|
|
104
|
+
finalize() {
|
|
105
|
+
this.endTime = new Date();
|
|
106
|
+
return {
|
|
107
|
+
executionId: this.executionId,
|
|
108
|
+
goal: this.goal,
|
|
109
|
+
startTime: this.startTime.toISOString(),
|
|
110
|
+
endTime: this.endTime.toISOString(),
|
|
111
|
+
totalTimeMs: this.endTime.getTime() - this.startTime.getTime(),
|
|
112
|
+
waveCount: this.waveCount,
|
|
113
|
+
stepCount: this.stepCount,
|
|
114
|
+
commitCount: this.commitCount,
|
|
115
|
+
verificationsPassed: this.verificationsPassed,
|
|
116
|
+
verificationsFailed: this.verificationsFailed,
|
|
117
|
+
recoveryEvents: this.recoveryEvents,
|
|
118
|
+
agentsUsed: Array.from(this.agentsUsed).sort()
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get current metrics snapshot (without finalizing)
|
|
123
|
+
*/
|
|
124
|
+
getSnapshot() {
|
|
125
|
+
const now = new Date();
|
|
126
|
+
return {
|
|
127
|
+
executionId: this.executionId,
|
|
128
|
+
goal: this.goal,
|
|
129
|
+
startTime: this.startTime.toISOString(),
|
|
130
|
+
totalTimeMs: now.getTime() - this.startTime.getTime(),
|
|
131
|
+
waveCount: this.waveCount,
|
|
132
|
+
stepCount: this.stepCount,
|
|
133
|
+
commitCount: this.commitCount,
|
|
134
|
+
verificationsPassed: this.verificationsPassed,
|
|
135
|
+
verificationsFailed: this.verificationsFailed,
|
|
136
|
+
recoveryEvents: this.recoveryEvents,
|
|
137
|
+
agentsUsed: Array.from(this.agentsUsed).sort()
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Persist full session state to runs/<id>/session-state.json.
|
|
142
|
+
* Creates the directory if missing.
|
|
143
|
+
*/
|
|
144
|
+
saveSession(id, state) {
|
|
145
|
+
const dir = path.join(process.cwd(), 'runs', id);
|
|
146
|
+
if (!fs.existsSync(dir)) {
|
|
147
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
148
|
+
}
|
|
149
|
+
fs.writeFileSync(path.join(dir, 'session-state.json'), JSON.stringify(state, null, 2), 'utf8');
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Load a previously saved session. Returns null if not found.
|
|
153
|
+
*/
|
|
154
|
+
loadSession(id) {
|
|
155
|
+
const filePath = path.join(process.cwd(), 'runs', id, 'session-state.json');
|
|
156
|
+
if (!fs.existsSync(filePath))
|
|
157
|
+
return null;
|
|
158
|
+
try {
|
|
159
|
+
return JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
160
|
+
}
|
|
161
|
+
catch (err) {
|
|
162
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
163
|
+
logger.warn(`[metrics] Failed to load session ${id}: ${msg}`);
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Generate a Markdown audit report from session state.
|
|
169
|
+
*/
|
|
170
|
+
generateAuditReport(state) {
|
|
171
|
+
const lines = [
|
|
172
|
+
`# Audit Report: ${state.sessionId}`,
|
|
173
|
+
'',
|
|
174
|
+
'## Timeline',
|
|
175
|
+
`- Status: ${state.status}`,
|
|
176
|
+
`- Last completed step: ${state.lastCompletedStep}`,
|
|
177
|
+
`- Total steps: ${state.graph.steps.length}`,
|
|
178
|
+
'',
|
|
179
|
+
'## Cost Breakdown',
|
|
180
|
+
`- Steps executed: ${state.lastCompletedStep}`,
|
|
181
|
+
`- Branches: ${Object.keys(state.branchMap).length}`,
|
|
182
|
+
`- Transcripts: ${Object.keys(state.transcripts).length}`,
|
|
183
|
+
'',
|
|
184
|
+
'## Diffs Summary',
|
|
185
|
+
...state.graph.steps.map(s => {
|
|
186
|
+
const branch = state.branchMap[String(s.stepNumber)] || 'no branch';
|
|
187
|
+
return `- Step ${s.stepNumber} (${s.agent}): branch \`${branch}\``;
|
|
188
|
+
}),
|
|
189
|
+
'',
|
|
190
|
+
'## Gates',
|
|
191
|
+
...state.gateResults.map(g => `- ${g.title}: ${g.status} (${g.issues.length} issue(s))`),
|
|
192
|
+
'',
|
|
193
|
+
'## Evidence',
|
|
194
|
+
...state.graph.steps.map(s => {
|
|
195
|
+
const transcript = state.transcripts[String(s.stepNumber)];
|
|
196
|
+
if (transcript) {
|
|
197
|
+
const lineCount = transcript.split('\n').length;
|
|
198
|
+
return `- Step ${s.stepNumber} (${s.agent}): transcript present (${lineCount} lines)`;
|
|
199
|
+
}
|
|
200
|
+
return `- Step ${s.stepNumber} (${s.agent}): no transcript`;
|
|
201
|
+
}),
|
|
202
|
+
'',
|
|
203
|
+
'## Steps',
|
|
204
|
+
...state.graph.steps.map(s => `- Step ${s.stepNumber}: ${s.task} (${s.agent})`),
|
|
205
|
+
];
|
|
206
|
+
return lines.join('\n');
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
exports.default = MetricsCollector;
|
|
@@ -0,0 +1,179 @@
|
|
|
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.MultiRepoCoordinator = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
/**
|
|
40
|
+
* Multi-Repo Coordinator - identify cross-repo relationships
|
|
41
|
+
* Analysis only, no execution
|
|
42
|
+
*/
|
|
43
|
+
class MultiRepoCoordinator {
|
|
44
|
+
/**
|
|
45
|
+
* Identify relationships between multiple repositories
|
|
46
|
+
*/
|
|
47
|
+
identifyRelationships(repos) {
|
|
48
|
+
if (repos.length < 2) {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
const relationships = [];
|
|
52
|
+
// Check for API dependencies (import statements referencing other repos)
|
|
53
|
+
for (let i = 0; i < repos.length; i++) {
|
|
54
|
+
for (let j = i + 1; j < repos.length; j++) {
|
|
55
|
+
const apiDeps = this.findApiDependencies(repos[i], repos[j]);
|
|
56
|
+
relationships.push(...apiDeps);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Check for shared schemas (TypeScript types exported/imported)
|
|
60
|
+
for (let i = 0; i < repos.length; i++) {
|
|
61
|
+
for (let j = i + 1; j < repos.length; j++) {
|
|
62
|
+
const schemas = this.findSharedSchemas(repos[i], repos[j]);
|
|
63
|
+
relationships.push(...schemas);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Check for build coupling (one repo's build depends on another)
|
|
67
|
+
for (let i = 0; i < repos.length; i++) {
|
|
68
|
+
for (let j = i + 1; j < repos.length; j++) {
|
|
69
|
+
const buildCoupling = this.findBuildCoupling(repos[i], repos[j]);
|
|
70
|
+
relationships.push(...buildCoupling);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return relationships;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Find API dependencies between repos
|
|
77
|
+
*/
|
|
78
|
+
findApiDependencies(repo1, repo2) {
|
|
79
|
+
const relationships = [];
|
|
80
|
+
// Check if repo1 has repo2 as a dependency
|
|
81
|
+
const repo1DepOnRepo2 = repo1.dependencies.some(d => d.name === repo2.repoName || d.name.includes(repo2.repoName));
|
|
82
|
+
if (repo1DepOnRepo2) {
|
|
83
|
+
relationships.push({
|
|
84
|
+
sourceRepo: repo1.repoName,
|
|
85
|
+
targetRepo: repo2.repoName,
|
|
86
|
+
type: 'api_dependency',
|
|
87
|
+
evidence: [
|
|
88
|
+
repo1.dependencies.find(d => d.name === repo2.repoName || d.name.includes(repo2.repoName)).source
|
|
89
|
+
],
|
|
90
|
+
details: `${repo1.repoName} depends on ${repo2.repoName}`
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
// Check reverse
|
|
94
|
+
const repo2DepOnRepo1 = repo2.dependencies.some(d => d.name === repo1.repoName || d.name.includes(repo1.repoName));
|
|
95
|
+
if (repo2DepOnRepo1) {
|
|
96
|
+
relationships.push({
|
|
97
|
+
sourceRepo: repo2.repoName,
|
|
98
|
+
targetRepo: repo1.repoName,
|
|
99
|
+
type: 'api_dependency',
|
|
100
|
+
evidence: [
|
|
101
|
+
repo2.dependencies.find(d => d.name === repo1.repoName || d.name.includes(repo1.repoName)).source
|
|
102
|
+
],
|
|
103
|
+
details: `${repo2.repoName} depends on ${repo1.repoName}`
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
return relationships;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Find shared schemas (look for types/ or schema/ directories)
|
|
110
|
+
*/
|
|
111
|
+
findSharedSchemas(repo1, repo2) {
|
|
112
|
+
const relationships = [];
|
|
113
|
+
// Check if both have schema directories
|
|
114
|
+
const repo1SchemaDir = path.join(repo1.repoPath, 'src', 'types');
|
|
115
|
+
const repo2SchemaDir = path.join(repo2.repoPath, 'src', 'types');
|
|
116
|
+
const repo1HasTypes = fs.existsSync(repo1SchemaDir);
|
|
117
|
+
const repo2HasTypes = fs.existsSync(repo2SchemaDir);
|
|
118
|
+
if (repo1HasTypes && repo2HasTypes) {
|
|
119
|
+
// Look for similarly named type files
|
|
120
|
+
const repo1Types = this.getTypeFiles(repo1SchemaDir);
|
|
121
|
+
const repo2Types = this.getTypeFiles(repo2SchemaDir);
|
|
122
|
+
const commonTypes = repo1Types.filter(t => repo2Types.includes(t));
|
|
123
|
+
if (commonTypes.length > 0) {
|
|
124
|
+
relationships.push({
|
|
125
|
+
sourceRepo: repo1.repoName,
|
|
126
|
+
targetRepo: repo2.repoName,
|
|
127
|
+
type: 'schema_sharing',
|
|
128
|
+
evidence: commonTypes.map(t => `Both repos have: ${t}`),
|
|
129
|
+
details: `Shared type files: ${commonTypes.join(', ')}`
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return relationships;
|
|
134
|
+
}
|
|
135
|
+
getTypeFiles(dir) {
|
|
136
|
+
try {
|
|
137
|
+
return fs.readdirSync(dir)
|
|
138
|
+
.filter(f => f.endsWith('.ts') || f.endsWith('.d.ts'))
|
|
139
|
+
.map(f => path.basename(f));
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
// Directory unreadable (missing, permissions); return empty list
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Find build coupling (build scripts reference other repos)
|
|
148
|
+
*/
|
|
149
|
+
findBuildCoupling(repo1, repo2) {
|
|
150
|
+
const relationships = [];
|
|
151
|
+
// Check if build scripts reference other repo
|
|
152
|
+
for (const script of repo1.buildScripts) {
|
|
153
|
+
if (script.command.includes(repo2.repoName) || script.command.includes(path.basename(repo2.repoPath))) {
|
|
154
|
+
relationships.push({
|
|
155
|
+
sourceRepo: repo1.repoName,
|
|
156
|
+
targetRepo: repo2.repoName,
|
|
157
|
+
type: 'build_coupling',
|
|
158
|
+
evidence: [script.source, `Command: ${script.command}`],
|
|
159
|
+
details: `${repo1.repoName} build depends on ${repo2.repoName}`
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Check reverse
|
|
164
|
+
for (const script of repo2.buildScripts) {
|
|
165
|
+
if (script.command.includes(repo1.repoName) || script.command.includes(path.basename(repo1.repoPath))) {
|
|
166
|
+
relationships.push({
|
|
167
|
+
sourceRepo: repo2.repoName,
|
|
168
|
+
targetRepo: repo1.repoName,
|
|
169
|
+
type: 'build_coupling',
|
|
170
|
+
evidence: [script.source, `Command: ${script.command}`],
|
|
171
|
+
details: `${repo2.repoName} build depends on ${repo1.repoName}`
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return relationships;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
exports.MultiRepoCoordinator = MultiRepoCoordinator;
|
|
179
|
+
exports.default = MultiRepoCoordinator;
|
|
@@ -0,0 +1,84 @@
|
|
|
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.runAsyncMetaAnalysis = runAsyncMetaAnalysis;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const logger_1 = require("../logger");
|
|
40
|
+
const logger = (0, logger_1.getLogger)('orchestrator');
|
|
41
|
+
/**
|
|
42
|
+
* Run meta-analysis off the critical path. Fires asynchronously via setImmediate
|
|
43
|
+
* from the scheduler so the next step can launch without waiting for KB updates.
|
|
44
|
+
*
|
|
45
|
+
* Writes `analysis-batch-<waveIndex>.json` to `runDir` and feeds detected
|
|
46
|
+
* knowledge updates into the KnowledgeBase on the context. Swallows errors
|
|
47
|
+
* with a warning so analytics failures never block execution.
|
|
48
|
+
*
|
|
49
|
+
* No-ops when `context.metaAnalyzer` or `context.knowledgeBase` is undefined.
|
|
50
|
+
*
|
|
51
|
+
* @param context - subset of the swarm execution context carrying metaAnalyzer, knowledgeBase, results, waveAnalyses
|
|
52
|
+
* @param plan - the current execution plan
|
|
53
|
+
* @param runDir - directory where the analysis snapshot is persisted
|
|
54
|
+
* @param completedSteps - step numbers that have completed so far (defines the "wave" analyzed)
|
|
55
|
+
*/
|
|
56
|
+
function runAsyncMetaAnalysis(context, plan, runDir, completedSteps) {
|
|
57
|
+
if (!context.metaAnalyzer || !context.knowledgeBase)
|
|
58
|
+
return;
|
|
59
|
+
// Use the most recent completed step as the "wave" we are analyzing
|
|
60
|
+
const waveIndex = completedSteps.length;
|
|
61
|
+
try {
|
|
62
|
+
const waveAnalysis = context.metaAnalyzer.analyzeWave(waveIndex, completedSteps, context.results, plan, context.executionId);
|
|
63
|
+
context.waveAnalyses?.push(waveAnalysis);
|
|
64
|
+
// Persist analysis snapshot
|
|
65
|
+
const analysisPath = path.join(runDir, `analysis-batch-${waveIndex}.json`);
|
|
66
|
+
fs.writeFileSync(analysisPath, JSON.stringify(waveAnalysis, null, 2), 'utf8');
|
|
67
|
+
// Feed insights back into the knowledge base
|
|
68
|
+
if (waveAnalysis.knowledgeUpdates.length > 0) {
|
|
69
|
+
waveAnalysis.knowledgeUpdates.forEach(update => {
|
|
70
|
+
context.knowledgeBase.addOrUpdatePattern({
|
|
71
|
+
category: update.category,
|
|
72
|
+
insight: update.insight,
|
|
73
|
+
confidence: update.confidence,
|
|
74
|
+
evidence: [update.evidence],
|
|
75
|
+
impact: update.confidence === 'high' ? 'high' : 'medium'
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
82
|
+
logger.warn(`[analytics] Wave analysis failed (non-fatal): ${msg}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FatalRunError = void 0;
|
|
4
|
+
exports.isFatalRunError = isFatalRunError;
|
|
5
|
+
/**
|
|
6
|
+
* Thrown when an agent CLI reports an unrecoverable, account-level failure
|
|
7
|
+
* (usage-limit, auth, extended rate-limit). The orchestrator catches this
|
|
8
|
+
* and aborts the run instead of replanning into the same wall.
|
|
9
|
+
*
|
|
10
|
+
* Distinct from a verification failure: those are step-level signals that
|
|
11
|
+
* the agent produced a wrong patch, and the replan/repair loop can usefully
|
|
12
|
+
* try again. A FatalRunError signals that *no* further agent invocations
|
|
13
|
+
* will succeed for this run, so retrying would only burn more wall-clock
|
|
14
|
+
* for the same outcome.
|
|
15
|
+
*
|
|
16
|
+
* The contained `cause` carries the classifier verdict (kind + evidence)
|
|
17
|
+
* so postmortem reports and the SWE-bench harness can attribute the abort
|
|
18
|
+
* to the specific account-level wall that triggered it.
|
|
19
|
+
*/
|
|
20
|
+
class FatalRunError extends Error {
|
|
21
|
+
fatalKind;
|
|
22
|
+
evidence;
|
|
23
|
+
stepNumber;
|
|
24
|
+
agentName;
|
|
25
|
+
constructor(fatal, context = {}) {
|
|
26
|
+
const where = context.stepNumber !== undefined
|
|
27
|
+
? ` (step ${context.stepNumber}${context.agentName ? `, ${context.agentName}` : ''})`
|
|
28
|
+
: '';
|
|
29
|
+
super(`agent CLI reported unrecoverable ${fatal.kind} error${where}: ${fatal.message}. ` +
|
|
30
|
+
`Aborting run; replanning cannot recover from an account-level wall. ` +
|
|
31
|
+
`Resolve the upstream issue (upgrade plan, refresh credentials, wait through the rate-limit window) and rerun.`);
|
|
32
|
+
this.name = 'FatalRunError';
|
|
33
|
+
this.fatalKind = fatal.kind;
|
|
34
|
+
this.evidence = fatal.evidence;
|
|
35
|
+
this.stepNumber = context.stepNumber;
|
|
36
|
+
this.agentName = context.agentName;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.FatalRunError = FatalRunError;
|
|
40
|
+
function isFatalRunError(err) {
|
|
41
|
+
return err instanceof FatalRunError
|
|
42
|
+
|| (typeof err === 'object' && err !== null && err.name === 'FatalRunError');
|
|
43
|
+
}
|