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.
Files changed (174) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +199 -0
  3. package/agents/reviewer.agent.md +50 -0
  4. package/agents/worker.agent.md +41 -0
  5. package/config/default-agents.yaml +56 -0
  6. package/config/pm-agent.yaml +36 -0
  7. package/config/quality-gates.yaml +88 -0
  8. package/config/repair-agent.yaml +34 -0
  9. package/config/semgrep-rules/complexity-mismatch.yaml +6 -0
  10. package/config/semgrep-rules/exception-swallowing.yaml +13 -0
  11. package/config/semgrep-rules/hardcoded-answer.yaml +6 -0
  12. package/config/semgrep-rules/mock-mutation.yaml +6 -0
  13. package/config/semgrep-rules/test-modification.yaml +6 -0
  14. package/config/user-agents.yaml +23 -0
  15. package/dist/src/adapters/adapter-factory.js +29 -0
  16. package/dist/src/adapters/agent-adapter.js +32 -0
  17. package/dist/src/adapters/claude-code-adapter.js +126 -0
  18. package/dist/src/adapters/claude-code-teams.js +119 -0
  19. package/dist/src/adapters/codex-adapter.js +118 -0
  20. package/dist/src/adapters/copilot-adapter.js +224 -0
  21. package/dist/src/adapters/fatal-error-classifier.js +88 -0
  22. package/dist/src/adapters/index.js +44 -0
  23. package/dist/src/adapters/persistent-session.js +204 -0
  24. package/dist/src/adapters/process-supervisor.js +199 -0
  25. package/dist/src/agents-exporter.js +398 -0
  26. package/dist/src/analytics-log.js +161 -0
  27. package/dist/src/baseline-scanner.js +65 -0
  28. package/dist/src/bootstrap-evidence.js +88 -0
  29. package/dist/src/bootstrap-orchestrator.js +205 -0
  30. package/dist/src/bootstrap-types.js +5 -0
  31. package/dist/src/branch-merger.js +427 -0
  32. package/dist/src/cli/attest-handlers.js +44 -0
  33. package/dist/src/cli/cost-prompt.js +51 -0
  34. package/dist/src/cli/demo-handlers.js +274 -0
  35. package/dist/src/cli/flags.js +152 -0
  36. package/dist/src/cli/index.js +57 -0
  37. package/dist/src/cli/live-status.js +186 -0
  38. package/dist/src/cli/misc-handlers.js +242 -0
  39. package/dist/src/cli/plan-handlers.js +350 -0
  40. package/dist/src/cli/share-handlers.js +163 -0
  41. package/dist/src/cli/status-handlers.js +457 -0
  42. package/dist/src/cli/swarm-handlers.js +638 -0
  43. package/dist/src/cli/usage.js +72 -0
  44. package/dist/src/cli.js +217 -0
  45. package/dist/src/commit-pattern-detector.js +143 -0
  46. package/dist/src/commit-quality-analyzer.js +38 -0
  47. package/dist/src/config-loader.js +339 -0
  48. package/dist/src/context-broker.js +358 -0
  49. package/dist/src/copilot-cli-wrapper.js +258 -0
  50. package/dist/src/cost-estimator.js +241 -0
  51. package/dist/src/defaults.js +18 -0
  52. package/dist/src/demo-mode.js +180 -0
  53. package/dist/src/deployment-handler.js +78 -0
  54. package/dist/src/deployment-manager.js +228 -0
  55. package/dist/src/execution-queue.js +196 -0
  56. package/dist/src/external-tool-manager.js +184 -0
  57. package/dist/src/gate-prompt-builder.js +117 -0
  58. package/dist/src/gate-remediation.js +173 -0
  59. package/dist/src/github-issues-ingester.js +152 -0
  60. package/dist/src/github-mcp-integrator.js +164 -0
  61. package/dist/src/hook-generator.js +229 -0
  62. package/dist/src/index.js +48 -0
  63. package/dist/src/knowledge-base.js +300 -0
  64. package/dist/src/logger.js +111 -0
  65. package/dist/src/meta-analyzer.js +208 -0
  66. package/dist/src/metrics-collector.js +209 -0
  67. package/dist/src/metrics-types.js +5 -0
  68. package/dist/src/multi-repo-coordinator.js +179 -0
  69. package/dist/src/orchestrator/async-meta-analysis.js +84 -0
  70. package/dist/src/orchestrator/fatal-run-error.js +43 -0
  71. package/dist/src/orchestrator/final-gates-remediation.js +258 -0
  72. package/dist/src/orchestrator/git-state-utils.js +119 -0
  73. package/dist/src/orchestrator/pause-controller.js +55 -0
  74. package/dist/src/orchestrator/replan-runner.js +258 -0
  75. package/dist/src/orchestrator/step-executor.js +391 -0
  76. package/dist/src/orchestrator/wave-scheduler-loop.js +204 -0
  77. package/dist/src/owasp-mapper.js +153 -0
  78. package/dist/src/owasp-report-renderer.js +39 -0
  79. package/dist/src/plan-files.js +142 -0
  80. package/dist/src/plan-generator.js +1207 -0
  81. package/dist/src/pm-agent.js +296 -0
  82. package/dist/src/post-run-reporter.js +203 -0
  83. package/dist/src/pr-automation.js +103 -0
  84. package/dist/src/pr-manager.js +318 -0
  85. package/dist/src/presenter/index.js +209 -0
  86. package/dist/src/prompt-builder.js +173 -0
  87. package/dist/src/quality-gates/config-loader.js +196 -0
  88. package/dist/src/quality-gates/default-config.js +243 -0
  89. package/dist/src/quality-gates/file-utils.js +152 -0
  90. package/dist/src/quality-gates/gate-runner.js +171 -0
  91. package/dist/src/quality-gates/gates/accessibility.js +355 -0
  92. package/dist/src/quality-gates/gates/duplicate-blocks.js +144 -0
  93. package/dist/src/quality-gates/gates/hardcoded-config.js +52 -0
  94. package/dist/src/quality-gates/gates/readme-claims.js +62 -0
  95. package/dist/src/quality-gates/gates/runtime-checks.js +265 -0
  96. package/dist/src/quality-gates/gates/scaffold-defaults.js +108 -0
  97. package/dist/src/quality-gates/gates/test-coverage.js +240 -0
  98. package/dist/src/quality-gates/gates/test-file-protection.js +85 -0
  99. package/dist/src/quality-gates/gates/test-isolation.js +74 -0
  100. package/dist/src/quality-gates/index.js +17 -0
  101. package/dist/src/quality-gates/registry.js +205 -0
  102. package/dist/src/quality-gates/types.js +2 -0
  103. package/dist/src/quick-fix-mode.js +302 -0
  104. package/dist/src/recipe-loader.js +122 -0
  105. package/dist/src/repair-agent.js +396 -0
  106. package/dist/src/repo-analyzer.js +342 -0
  107. package/dist/src/report-generator.js +146 -0
  108. package/dist/src/report-renderer.js +90 -0
  109. package/dist/src/requirement-filter.js +52 -0
  110. package/dist/src/sarif-formatter.js +140 -0
  111. package/dist/src/scheduling/dependency-analyzer.js +178 -0
  112. package/dist/src/scheduling/work-stealing-queue.js +123 -0
  113. package/dist/src/secret-redactor.js +90 -0
  114. package/dist/src/session-executor.js +587 -0
  115. package/dist/src/session-manager.js +221 -0
  116. package/dist/src/share/transcript-verification.js +128 -0
  117. package/dist/src/share-parser.js +477 -0
  118. package/dist/src/spinner.js +146 -0
  119. package/dist/src/step-runner.js +365 -0
  120. package/dist/src/swarm-orchestrator.js +686 -0
  121. package/dist/src/task-classifier.js +134 -0
  122. package/dist/src/test-command-discovery.js +123 -0
  123. package/dist/src/text-similarity.js +24 -0
  124. package/dist/src/tier-maps.js +158 -0
  125. package/dist/src/types.js +5 -0
  126. package/dist/src/url-shortener.js +135 -0
  127. package/dist/src/verification/attestation.js +166 -0
  128. package/dist/src/verification/cheat-detector.js +240 -0
  129. package/dist/src/verification/command-runner.js +70 -0
  130. package/dist/src/verification/composite-score.js +157 -0
  131. package/dist/src/verification/cosign-attestation.js +137 -0
  132. package/dist/src/verification/diff-analysis.js +89 -0
  133. package/dist/src/verification/differential-gate.js +173 -0
  134. package/dist/src/verification/index.js +41 -0
  135. package/dist/src/verification/mutation-gate.js +242 -0
  136. package/dist/src/verification/property-gate.js +201 -0
  137. package/dist/src/verification/test-synthesizer.js +243 -0
  138. package/dist/src/verifier/outcome-checks.js +396 -0
  139. package/dist/src/verifier/transcript-checks.js +207 -0
  140. package/dist/src/verifier/verification-reporters.js +148 -0
  141. package/dist/src/verifier-engine.js +491 -0
  142. package/dist/src/wave-resizer.js +131 -0
  143. package/dist/src/wave-scheduler.js +44 -0
  144. package/dist/src/worktree-manager.js +368 -0
  145. package/dist/src/worktree-reserved-paths.js +97 -0
  146. package/package.json +80 -0
  147. package/plugin/agents/.gitkeep +0 -0
  148. package/plugin/agents/backend_master.agent.md +72 -0
  149. package/plugin/agents/devops_pro.agent.md +45 -0
  150. package/plugin/agents/frontend_expert.agent.md +59 -0
  151. package/plugin/agents/integrator_finalizer.agent.md +44 -0
  152. package/plugin/agents/meta_reviewer.agent.md +44 -0
  153. package/plugin/agents/security_auditor.agent.md +43 -0
  154. package/plugin/agents/tester_elite.agent.md +43 -0
  155. package/plugin/hooks/hooks.json +19 -0
  156. package/plugin/hooks/post-tool-use.json +9 -0
  157. package/plugin/hooks/pre-tool-use.json +9 -0
  158. package/plugin/plugin.json +47 -0
  159. package/plugin/skills/swarm-gates/SKILL.md +53 -0
  160. package/plugin/skills/swarm-orchestrate/SKILL.md +34 -0
  161. package/plugin/skills/swarm-verify/SKILL.md +44 -0
  162. package/templates/README.md +35 -0
  163. package/templates/cli-tool.json +31 -0
  164. package/templates/fullstack.json +52 -0
  165. package/templates/library.json +38 -0
  166. package/templates/react-app.json +45 -0
  167. package/templates/recipes/add-api-docs.json +35 -0
  168. package/templates/recipes/add-auth.json +47 -0
  169. package/templates/recipes/add-ci.json +39 -0
  170. package/templates/recipes/add-tests.json +39 -0
  171. package/templates/recipes/migrate-to-ts.json +42 -0
  172. package/templates/recipes/refactor-modularize.json +44 -0
  173. package/templates/recipes/security-audit.json +35 -0
  174. package/templates/rest-api.json +38 -0
@@ -0,0 +1,300 @@
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.KnowledgeBaseManager = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const text_similarity_1 = require("./text-similarity");
40
+ const logger_1 = require("./logger");
41
+ const logger = (0, logger_1.getLogger)('knowledge-base');
42
+ // Auto-prune triggers when pattern count exceeds this threshold
43
+ const MAX_PATTERNS = 500;
44
+ /**
45
+ * knowledge base for learning from execution patterns
46
+ * stores insights from reviewer-role analysis
47
+ */
48
+ class KnowledgeBaseManager {
49
+ knowledgeBasePath;
50
+ knowledgeBase;
51
+ constructor(workingDir) {
52
+ const baseDir = workingDir || process.cwd();
53
+ this.knowledgeBasePath = path.join(baseDir, 'knowledge-base.json');
54
+ this.knowledgeBase = this.loadKnowledgeBase();
55
+ }
56
+ /**
57
+ * load knowledge base from disk or create new
58
+ */
59
+ loadKnowledgeBase() {
60
+ if (fs.existsSync(this.knowledgeBasePath)) {
61
+ try {
62
+ const content = fs.readFileSync(this.knowledgeBasePath, 'utf8');
63
+ return JSON.parse(content);
64
+ }
65
+ catch (error) {
66
+ logger.warn(`Failed to load knowledge base, creating new: ${error}`);
67
+ }
68
+ }
69
+ return {
70
+ version: 1,
71
+ lastUpdated: new Date().toISOString(),
72
+ patterns: [],
73
+ statistics: {
74
+ totalRuns: 0,
75
+ totalPatterns: 0,
76
+ avgPatternsPerRun: 0
77
+ }
78
+ };
79
+ }
80
+ /**
81
+ * save knowledge base to disk
82
+ */
83
+ saveKnowledgeBase() {
84
+ try {
85
+ fs.writeFileSync(this.knowledgeBasePath, JSON.stringify(this.knowledgeBase, null, 2), 'utf8');
86
+ }
87
+ catch (error) {
88
+ logger.error(`Failed to save knowledge base: ${error}`);
89
+ }
90
+ }
91
+ /**
92
+ * add or update pattern in knowledge base.
93
+ * Auto-prunes when pattern count exceeds MAX_PATTERNS to bound
94
+ * Levenshtein search cost and disk footprint.
95
+ */
96
+ addOrUpdatePattern(pattern) {
97
+ const now = new Date().toISOString();
98
+ // check if similar pattern exists
99
+ const existing = this.knowledgeBase.patterns.find(p => p.category === pattern.category &&
100
+ this.isSimilarInsight(p.insight, pattern.insight));
101
+ if (existing) {
102
+ // update existing pattern
103
+ existing.occurrences++;
104
+ existing.lastSeen = now;
105
+ existing.confidence = pattern.confidence;
106
+ existing.evidence.push(...pattern.evidence);
107
+ existing.impact = pattern.impact;
108
+ }
109
+ else {
110
+ // create new pattern
111
+ const newPattern = {
112
+ id: this.generatePatternId(pattern.category),
113
+ category: pattern.category,
114
+ insight: pattern.insight,
115
+ confidence: pattern.confidence,
116
+ evidence: pattern.evidence,
117
+ occurrences: 1,
118
+ firstSeen: now,
119
+ lastSeen: now,
120
+ impact: pattern.impact,
121
+ examples: []
122
+ };
123
+ this.knowledgeBase.patterns.push(newPattern);
124
+ }
125
+ // Prevent unbounded growth: prune stale and low-value entries
126
+ if (this.knowledgeBase.patterns.length > MAX_PATTERNS) {
127
+ this.prunePatterns({ removeOlderThan: 90, removeLowConfidence: true });
128
+ }
129
+ this.knowledgeBase.lastUpdated = now;
130
+ this.knowledgeBase.statistics.totalPatterns = this.knowledgeBase.patterns.length;
131
+ this.saveKnowledgeBase();
132
+ }
133
+ /**
134
+ * Record a recipe execution for historical tracking.
135
+ * Stores structured run data so future recipe invocations can reference
136
+ * success rates and typical durations.
137
+ */
138
+ recordRecipeRun(data) {
139
+ const status = data.passed ? 'passed' : 'failed';
140
+ const completionRatio = `${data.stepsCompleted}/${data.totalSteps}`;
141
+ this.addOrUpdatePattern({
142
+ category: 'recipe_run',
143
+ insight: `recipe:${data.recipe} tool:${data.tool} ${status} (${completionRatio} steps, ${data.duration}ms)`,
144
+ confidence: 'high',
145
+ evidence: [
146
+ `recipe:${data.recipe}`,
147
+ `tool:${data.tool}`,
148
+ `passed:${data.passed}`,
149
+ `duration:${data.duration}`,
150
+ `completed:${completionRatio}`,
151
+ `params:${JSON.stringify(data.parameters)}`,
152
+ ],
153
+ impact: data.passed ? 'low' : 'medium',
154
+ });
155
+ }
156
+ /**
157
+ * get patterns by category
158
+ */
159
+ getPatternsByCategory(category) {
160
+ return this.knowledgeBase.patterns.filter(p => p.category === category);
161
+ }
162
+ /**
163
+ * get high-confidence patterns
164
+ */
165
+ getHighConfidencePatterns() {
166
+ return this.knowledgeBase.patterns.filter(p => p.confidence === 'high');
167
+ }
168
+ /**
169
+ * get patterns that should influence planning
170
+ */
171
+ getPlanningRelevantPatterns() {
172
+ return this.knowledgeBase.patterns.filter(p => (p.category === 'dependency_order' || p.category === 'best_practice') &&
173
+ p.confidence !== 'low' &&
174
+ p.occurrences >= 2);
175
+ }
176
+ /**
177
+ * get anti-patterns to warn about
178
+ */
179
+ getAntiPatterns() {
180
+ return this.knowledgeBase.patterns.filter(p => p.category === 'anti_pattern' && p.impact !== 'low');
181
+ }
182
+ /**
183
+ * record execution run
184
+ */
185
+ recordRun(_patternsDetected) {
186
+ this.knowledgeBase.statistics.totalRuns++;
187
+ const { totalRuns, totalPatterns } = this.knowledgeBase.statistics;
188
+ this.knowledgeBase.statistics.avgPatternsPerRun = totalPatterns / totalRuns;
189
+ this.knowledgeBase.lastUpdated = new Date().toISOString();
190
+ this.saveKnowledgeBase();
191
+ }
192
+ /**
193
+ * get summary statistics
194
+ */
195
+ getStatistics() {
196
+ return { ...this.knowledgeBase.statistics };
197
+ }
198
+ /**
199
+ * export knowledge base for review
200
+ */
201
+ export() {
202
+ return JSON.parse(JSON.stringify(this.knowledgeBase));
203
+ }
204
+ /**
205
+ * clear old or low-value patterns
206
+ */
207
+ prunePatterns(options) {
208
+ const now = new Date();
209
+ let removed = 0;
210
+ this.knowledgeBase.patterns = this.knowledgeBase.patterns.filter(pattern => {
211
+ if (options?.removeOlderThan) {
212
+ const lastSeenDate = new Date(pattern.lastSeen);
213
+ const daysSinceLastSeen = (now.getTime() - lastSeenDate.getTime()) / (1000 * 60 * 60 * 24);
214
+ if (daysSinceLastSeen > options.removeOlderThan) {
215
+ removed++;
216
+ return false;
217
+ }
218
+ }
219
+ if (options?.removeLowConfidence && pattern.confidence === 'low') {
220
+ removed++;
221
+ return false;
222
+ }
223
+ if (options?.removeRare && pattern.occurrences < 2) {
224
+ removed++;
225
+ return false;
226
+ }
227
+ return true;
228
+ });
229
+ if (removed > 0) {
230
+ this.knowledgeBase.statistics.totalPatterns = this.knowledgeBase.patterns.length;
231
+ this.saveKnowledgeBase();
232
+ }
233
+ return removed;
234
+ }
235
+ /**
236
+ * check if two insights are similar (simple string similarity)
237
+ */
238
+ isSimilarInsight(insight1, insight2) {
239
+ const normalize = (s) => s.toLowerCase().replace(/[^\w\s]/g, '').trim();
240
+ const n1 = normalize(insight1);
241
+ const n2 = normalize(insight2);
242
+ // exact match
243
+ if (n1 === n2)
244
+ return true;
245
+ // high overlap (simple check)
246
+ const words1 = new Set(n1.split(/\s+/));
247
+ const words2 = new Set(n2.split(/\s+/));
248
+ const intersection = new Set([...words1].filter(w => words2.has(w)));
249
+ const union = new Set([...words1, ...words2]);
250
+ const similarity = intersection.size / union.size;
251
+ return similarity > 0.7;
252
+ }
253
+ /**
254
+ * generate unique pattern ID
255
+ */
256
+ generatePatternId(category) {
257
+ const timestamp = Date.now();
258
+ const random = Math.random().toString(36).substring(2, 8);
259
+ return `${category}-${timestamp}-${random}`;
260
+ }
261
+ /**
262
+ * Delegates to the shared levenshtein from text-similarity.ts.
263
+ * Kept as a public method for backward compatibility with tests.
264
+ */
265
+ levenshtein(a, b) {
266
+ return (0, text_similarity_1.levenshtein)(a, b);
267
+ }
268
+ /**
269
+ * Find stored patterns similar to a task description.
270
+ * Uses keyword overlap + normalized Levenshtein similarity.
271
+ * Skips patterns where length difference exceeds 2x (Levenshtein
272
+ * similarity cannot reach the threshold in those cases).
273
+ */
274
+ findSimilarTasks(description, threshold = 0.7) {
275
+ const descLower = description.toLowerCase();
276
+ const descWords = new Set(descLower.split(/\s+/));
277
+ const descLen = descLower.length;
278
+ return this.knowledgeBase.patterns.filter(p => {
279
+ const insightLower = p.insight.toLowerCase();
280
+ // Length pre-filter: when one string is more than 2x the other,
281
+ // the normalized Levenshtein similarity is at most 0.5, so the
282
+ // combined score (keyword + lev) / 2 cannot reach 0.7 threshold
283
+ // unless keyword overlap is near-perfect. Skip the O(n*m) call.
284
+ const insightLen = insightLower.length;
285
+ const shorter = Math.min(descLen, insightLen);
286
+ const longer = Math.max(descLen, insightLen);
287
+ if (shorter > 0 && longer / shorter > 2)
288
+ return false;
289
+ const insightWords = new Set(insightLower.split(/\s+/));
290
+ const overlap = [...descWords].filter(w => insightWords.has(w)).length;
291
+ const union = new Set([...descWords, ...insightWords]).size;
292
+ const keywordSim = union > 0 ? overlap / union : 0;
293
+ const maxLen = longer || 1;
294
+ const levSim = 1 - (0, text_similarity_1.levenshtein)(descLower, insightLower) / maxLen;
295
+ const combined = (keywordSim + levSim) / 2;
296
+ return combined >= threshold;
297
+ });
298
+ }
299
+ }
300
+ exports.KnowledgeBaseManager = KnowledgeBaseManager;
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configureLogger = configureLogger;
4
+ exports.setPrettyMode = setPrettyMode;
5
+ exports.isPrettyMode = isPrettyMode;
6
+ exports.getLogger = getLogger;
7
+ exports.getLoggerConfig = getLoggerConfig;
8
+ exports.isJsonOutput = isJsonOutput;
9
+ exports.writeStructuredOutput = writeStructuredOutput;
10
+ const LEVEL_RANK = {
11
+ error: 0,
12
+ warn: 1,
13
+ info: 2,
14
+ debug: 3,
15
+ trace: 4,
16
+ };
17
+ const state = {
18
+ level: 'info',
19
+ outputFormat: 'text',
20
+ diagnosticsToStderr: false,
21
+ // Pretty mode: hide `[scope]` prefixes for a cleaner CLI UX.
22
+ // Auto-enabled by user-facing commands. Scope still shown in JSON output.
23
+ prettyMode: false,
24
+ };
25
+ function normalizeArgs(args) {
26
+ return args.map((arg) => {
27
+ if (typeof arg === 'string')
28
+ return arg;
29
+ if (arg instanceof Error)
30
+ return arg.stack || arg.message;
31
+ try {
32
+ return JSON.stringify(arg);
33
+ }
34
+ catch {
35
+ return String(arg);
36
+ }
37
+ }).join(' ');
38
+ }
39
+ function shouldLog(level) {
40
+ if (state.level === 'silent')
41
+ return false;
42
+ return LEVEL_RANK[level] <= LEVEL_RANK[state.level];
43
+ }
44
+ function writeLine(stream, line) {
45
+ stream.write(line + '\n');
46
+ }
47
+ function emit(level, scope, args) {
48
+ if (!shouldLog(level))
49
+ return;
50
+ const message = normalizeArgs(args);
51
+ if (state.outputFormat === 'json') {
52
+ writeLine(process.stderr, JSON.stringify({
53
+ timestamp: new Date().toISOString(),
54
+ level,
55
+ ...(scope ? { scope } : {}),
56
+ message,
57
+ }));
58
+ return;
59
+ }
60
+ const prefix = (!state.prettyMode && scope) ? `[${scope}] ` : '';
61
+ // Diagnostic levels (info/debug/trace) go to stderr when explicitly routed there
62
+ // so the presenter owns stdout cleanly. Error/warn always to stderr.
63
+ const isDiagnostic = level === 'info' || level === 'debug' || level === 'trace';
64
+ const stream = level === 'error' || level === 'warn'
65
+ ? process.stderr
66
+ : (state.diagnosticsToStderr && isDiagnostic ? process.stderr : process.stdout);
67
+ writeLine(stream, `${prefix}${message}`);
68
+ }
69
+ function createLogger(scope) {
70
+ return {
71
+ error: (...args) => emit('error', scope, args),
72
+ warn: (...args) => emit('warn', scope, args),
73
+ info: (...args) => emit('info', scope, args),
74
+ debug: (...args) => emit('debug', scope, args),
75
+ trace: (...args) => emit('trace', scope, args),
76
+ child: (childScope) => createLogger(scope ? `${scope}:${childScope}` : childScope),
77
+ };
78
+ }
79
+ function configureLogger(config) {
80
+ if (config.level)
81
+ state.level = config.level;
82
+ if (config.outputFormat)
83
+ state.outputFormat = config.outputFormat;
84
+ if (config.diagnosticsToStderr !== undefined)
85
+ state.diagnosticsToStderr = config.diagnosticsToStderr;
86
+ }
87
+ /**
88
+ * Hide `[scope]` prefixes for a cleaner user-facing CLI UX.
89
+ * Auto-enabled by user-facing commands; structured JSON output is unaffected.
90
+ */
91
+ function setPrettyMode(pretty) {
92
+ state.prettyMode = pretty;
93
+ }
94
+ function isPrettyMode() {
95
+ return state.prettyMode;
96
+ }
97
+ function getLogger(scope) {
98
+ return createLogger(scope);
99
+ }
100
+ function getLoggerConfig() {
101
+ return { ...state };
102
+ }
103
+ function isJsonOutput() {
104
+ return state.outputFormat === 'json';
105
+ }
106
+ function writeStructuredOutput(payload) {
107
+ const content = typeof payload === 'string'
108
+ ? payload
109
+ : JSON.stringify(payload, null, 2);
110
+ process.stdout.write(content + '\n');
111
+ }
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MetaAnalyzer = void 0;
4
+ /**
5
+ * meta-analysis engine - reviews execution quality and decides on replanning
6
+ */
7
+ class MetaAnalyzer {
8
+ /**
9
+ * analyze wave results and determine if replanning needed
10
+ */
11
+ analyzeWave(waveIndex, waveSteps, results, plan, executionId) {
12
+ const waveResults = results.filter(r => waveSteps.includes(r.stepNumber));
13
+ const stepReviews = waveResults.map(result => {
14
+ return this.reviewStep(result);
15
+ });
16
+ const detectedPatterns = this.detectPatterns(waveResults);
17
+ const failureRate = stepReviews.filter(r => !r.verificationPassed).length / stepReviews.length;
18
+ let overallHealth = 'healthy';
19
+ if (failureRate > 0.5) {
20
+ overallHealth = 'critical';
21
+ }
22
+ else if (failureRate > 0.2) {
23
+ overallHealth = 'degraded';
24
+ }
25
+ const replanNeeded = failureRate > 0.5;
26
+ const replanReason = replanNeeded
27
+ ? `Wave ${waveIndex + 1} failed: ${Math.round(failureRate * 100)}% of steps did not pass verification`
28
+ : null;
29
+ const suggestedChanges = this.generateSuggestedChanges(stepReviews, plan);
30
+ const knowledgeUpdates = this.extractKnowledge(stepReviews, detectedPatterns);
31
+ const nextActions = this.determineNextActions(overallHealth, replanNeeded, suggestedChanges);
32
+ return {
33
+ analysisTimestamp: new Date().toISOString(),
34
+ executionId,
35
+ waveAnalyzed: waveIndex + 1,
36
+ overallHealth,
37
+ stepReviews,
38
+ detectedPatterns,
39
+ replanNeeded,
40
+ replanReason,
41
+ suggestedChanges,
42
+ knowledgeUpdates,
43
+ nextActions
44
+ };
45
+ }
46
+ /**
47
+ * review individual step result
48
+ */
49
+ reviewStep(result) {
50
+ const verificationPassed = result.verificationResult?.passed ?? false;
51
+ const issues = [];
52
+ let rootCause = 'Unknown';
53
+ let recommendation = 'Continue';
54
+ if (!verificationPassed && result.verificationResult) {
55
+ // analyze verification failures
56
+ result.verificationResult.checks.forEach(check => {
57
+ if (!check.passed && check.required) {
58
+ issues.push(`${check.type}: ${check.description} - ${check.reason || 'failed'}`);
59
+ }
60
+ });
61
+ if (result.verificationResult.unverifiedClaims.length > 0) {
62
+ issues.push(`Unverified claims: ${result.verificationResult.unverifiedClaims.length} detected`);
63
+ }
64
+ // determine root cause
65
+ if (issues.some(i => i.includes('test'))) {
66
+ rootCause = 'Tests not executed or failed';
67
+ recommendation = 'Re-execute with explicit test requirement';
68
+ }
69
+ else if (issues.some(i => i.includes('build'))) {
70
+ rootCause = 'Build not executed or failed';
71
+ recommendation = 'Re-execute with build verification';
72
+ }
73
+ else if (issues.some(i => i.includes('commit'))) {
74
+ rootCause = 'No commits made';
75
+ recommendation = 'Re-execute with commit requirement';
76
+ }
77
+ else {
78
+ rootCause = 'Verification checks failed';
79
+ recommendation = 'Review transcript and re-execute';
80
+ }
81
+ }
82
+ return {
83
+ stepNumber: result.stepNumber,
84
+ agentName: result.agentName,
85
+ verificationPassed,
86
+ issues,
87
+ rootCause,
88
+ recommendation
89
+ };
90
+ }
91
+ /**
92
+ * detect patterns across multiple steps
93
+ */
94
+ detectPatterns(results) {
95
+ const patterns = [];
96
+ // check for generic commit messages (anti-pattern)
97
+ const genericCommitAgents = results.filter(r => {
98
+ const commits = r.verificationResult?.checks.find(c => c.type === 'commit');
99
+ if (!commits?.evidence)
100
+ return false;
101
+ return /update|fix|change/i.test(commits.evidence) && commits.evidence.length < 30;
102
+ });
103
+ if (genericCommitAgents.length >= 2) {
104
+ patterns.push({
105
+ type: 'anti-pattern',
106
+ pattern: 'generic_commit_messages',
107
+ occurrences: genericCommitAgents.length,
108
+ affectedAgents: genericCommitAgents.map(r => r.agentName),
109
+ example: 'Commits like "update files" or "fix issues"',
110
+ severity: 'medium'
111
+ });
112
+ }
113
+ // check for unverified claims (drift)
114
+ const driftingAgents = results.filter(r => {
115
+ return (r.verificationResult?.unverifiedClaims.length || 0) > 2;
116
+ });
117
+ if (driftingAgents.length >= 1) {
118
+ patterns.push({
119
+ type: 'context-gap',
120
+ pattern: 'unverified_claims',
121
+ occurrences: driftingAgents.length,
122
+ affectedAgents: driftingAgents.map(r => r.agentName),
123
+ example: 'Agent claims work done without evidence in transcript',
124
+ severity: 'high'
125
+ });
126
+ }
127
+ return patterns;
128
+ }
129
+ /**
130
+ * generate suggested changes based on review
131
+ */
132
+ generateSuggestedChanges(stepReviews, _plan) {
133
+ const changes = [];
134
+ stepReviews.forEach(review => {
135
+ if (!review.verificationPassed) {
136
+ changes.push({
137
+ type: 're-execute',
138
+ targetStep: review.stepNumber,
139
+ reason: review.rootCause,
140
+ details: review.recommendation
141
+ });
142
+ }
143
+ });
144
+ return changes;
145
+ }
146
+ /**
147
+ * extract knowledge from analysis
148
+ */
149
+ extractKnowledge(stepReviews, patterns) {
150
+ const updates = [];
151
+ // extract from patterns
152
+ patterns.forEach(pattern => {
153
+ if (pattern.severity === 'high') {
154
+ updates.push({
155
+ category: pattern.type === 'anti-pattern' ? 'anti_pattern' : 'agent_behavior',
156
+ insight: `Pattern detected: ${pattern.pattern} in ${pattern.occurrences} step(s)`,
157
+ confidence: 'high',
158
+ evidence: pattern.example
159
+ });
160
+ }
161
+ });
162
+ return updates;
163
+ }
164
+ /**
165
+ * determine next actions
166
+ */
167
+ determineNextActions(health, replanNeeded, changes) {
168
+ const actions = [];
169
+ if (replanNeeded) {
170
+ actions.push('Trigger full replan');
171
+ actions.push('Preserve git history from completed steps');
172
+ }
173
+ else if (health === 'degraded') {
174
+ if (changes.length > 0) {
175
+ actions.push(`Re-execute ${changes.length} failed step(s)`);
176
+ }
177
+ actions.push('Monitor next wave closely');
178
+ }
179
+ else {
180
+ actions.push('Continue to next wave');
181
+ }
182
+ return actions;
183
+ }
184
+ /**
185
+ * make replan decision based on analysis
186
+ */
187
+ makeReplanDecision(analysis, _plan, _completedSteps) {
188
+ if (!analysis.replanNeeded) {
189
+ return {
190
+ shouldReplan: false,
191
+ reason: 'Execution healthy, continue as planned',
192
+ preserveHistory: true
193
+ };
194
+ }
195
+ // identify which steps to retry
196
+ const stepsToRetry = analysis.suggestedChanges
197
+ .filter(c => c.type === 're-execute')
198
+ .map(c => c.targetStep)
199
+ .filter(s => s !== undefined);
200
+ return {
201
+ shouldReplan: true,
202
+ reason: analysis.replanReason || 'Critical issues detected',
203
+ stepsToRetry,
204
+ preserveHistory: true
205
+ };
206
+ }
207
+ }
208
+ exports.MetaAnalyzer = MetaAnalyzer;