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,164 @@
1
+ "use strict";
2
+ /**
3
+ * GitHub MCP Integration
4
+ * Generates MCP prompts and validates MCP evidence in verification docs
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
18
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
19
+ }) : function(o, v) {
20
+ o["default"] = v;
21
+ });
22
+ var __importStar = (this && this.__importStar) || (function () {
23
+ var ownKeys = function(o) {
24
+ ownKeys = Object.getOwnPropertyNames || function (o) {
25
+ var ar = [];
26
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
27
+ return ar;
28
+ };
29
+ return ownKeys(o);
30
+ };
31
+ return function (mod) {
32
+ if (mod && mod.__esModule) return mod;
33
+ var result = {};
34
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
35
+ __setModuleDefault(result, mod);
36
+ return result;
37
+ };
38
+ })();
39
+ Object.defineProperty(exports, "__esModule", { value: true });
40
+ exports.GitHubMcpIntegrator = void 0;
41
+ const fs = __importStar(require("fs"));
42
+ class GitHubMcpIntegrator {
43
+ /**
44
+ * Generate MCP prompt section for agent instructions
45
+ */
46
+ static generateMcpPromptSection() {
47
+ return `
48
+ GitHub Context (MCP) Requirements:
49
+ - Before making decisions, consult GitHub context using available MCP tools
50
+ - Check for: related issues, existing PRs, recent commits, CI workflows
51
+ - In your verification section, include an "MCP Evidence" section with:
52
+ * What GitHub context you consulted
53
+ * Specific evidence quoted (issue numbers, PR titles, workflow names, etc.)
54
+ * How it influenced your decisions
55
+ - Example MCP Evidence format:
56
+
57
+ ## MCP Evidence
58
+ - Consulted open issues: Found issue #42 "Add user authentication"
59
+ - Checked existing PRs: No conflicting PRs for auth feature
60
+ - Reviewed CI workflow: .github/workflows/ci.yml runs tests on push
61
+ - Decision: Implemented auth to resolve #42, added tests for CI compatibility
62
+
63
+ Without MCP evidence in your verification, this step will be flagged.
64
+ `.trim();
65
+ }
66
+ /**
67
+ * Generate /delegate prompt section for agent instructions
68
+ */
69
+ static generateDelegatePromptSection() {
70
+ return `
71
+ Pull Request Creation (via /delegate):
72
+ - When your changes are ready, create a PR using the /delegate command
73
+ - The /delegate command will guide you through PR creation
74
+ - Include the resulting PR URL in your verification section
75
+ - Format: "Created PR: https://github.com/owner/repo/pull/123"
76
+ - If /delegate is not available or fails, note this in verification
77
+
78
+ Example verification with PR:
79
+ ## Verification
80
+ - Changed files: src/api.ts, test/api.test.ts
81
+ - Tests run: npm test (14 passing)
82
+ - Created PR: https://github.com/owner/repo/pull/123
83
+ `.trim();
84
+ }
85
+ /**
86
+ * Validate MCP evidence in verification.md
87
+ */
88
+ static validateMcpEvidence(verificationPath) {
89
+ const warnings = [];
90
+ if (!fs.existsSync(verificationPath)) {
91
+ return {
92
+ found: false,
93
+ warnings: ['verification.md not found']
94
+ };
95
+ }
96
+ const content = fs.readFileSync(verificationPath, 'utf-8');
97
+ // look for MCP evidence section
98
+ const mcpSectionMatch = content.match(/##\s+MCP\s+Evidence(.*?)(?=\n##|\n$)/is);
99
+ if (!mcpSectionMatch || !mcpSectionMatch[1]) {
100
+ warnings.push('No "## MCP Evidence" section found in verification.md');
101
+ return { found: false, warnings };
102
+ }
103
+ const mcpSection = mcpSectionMatch[1].trim();
104
+ if (mcpSection.length < 50) {
105
+ warnings.push('MCP Evidence section is too short (< 50 chars)');
106
+ }
107
+ // check for specific evidence markers
108
+ const hasIssueReference = /issue\s+#?\d+|issues:/i.test(mcpSection);
109
+ const hasPrReference = /PR\s+#?\d+|pull request/i.test(mcpSection);
110
+ const hasWorkflowReference = /workflow|\.github\/workflows|CI/i.test(mcpSection);
111
+ const hasCommitReference = /commit|sha/i.test(mcpSection);
112
+ const hasDecisionStatement = /decision|influenced|based on|considering/i.test(mcpSection);
113
+ const evidenceCount = [
114
+ hasIssueReference,
115
+ hasPrReference,
116
+ hasWorkflowReference,
117
+ hasCommitReference
118
+ ].filter(Boolean).length;
119
+ if (evidenceCount === 0) {
120
+ warnings.push('MCP Evidence has no specific GitHub references (issues, PRs, workflows, commits)');
121
+ }
122
+ if (!hasDecisionStatement) {
123
+ warnings.push('MCP Evidence should explain how context influenced decisions');
124
+ }
125
+ return {
126
+ found: true,
127
+ section: mcpSection,
128
+ warnings
129
+ };
130
+ }
131
+ /**
132
+ * Extract PR URLs from verification.md
133
+ */
134
+ static extractPrUrls(verificationPath) {
135
+ if (!fs.existsSync(verificationPath)) {
136
+ return [];
137
+ }
138
+ const content = fs.readFileSync(verificationPath, 'utf-8');
139
+ // github PR URLs
140
+ const urlMatches = content.match(/https:\/\/github\.com\/[^\/]+\/[^\/]+\/pull\/\d+/g) || [];
141
+ // PR references like "PR: #123" or "Created PR #42"
142
+ const refMatches = content.match(/(?:PR|pull request)\s*:?\s*#(\d+)/gi) || [];
143
+ const prNumbers = refMatches.map(m => m.match(/#(\d+)/)?.[1]).filter(Boolean);
144
+ return [...new Set([...urlMatches, ...prNumbers.map(n => `#${n}`)])];
145
+ }
146
+ /**
147
+ * Format MCP evidence for display
148
+ */
149
+ static formatMcpEvidenceDisplay(evidence) {
150
+ if (!evidence.found) {
151
+ return `⚠ MCP Evidence: NOT FOUND\n${evidence.warnings.map(w => ` - ${w}`).join('\n')}`;
152
+ }
153
+ let output = '✓ MCP Evidence: FOUND\n';
154
+ if (evidence.section) {
155
+ output += `\n${evidence.section}\n`;
156
+ }
157
+ if (evidence.warnings.length > 0) {
158
+ output += '\n⚠ Warnings:\n';
159
+ output += evidence.warnings.map(w => ` - ${w}`).join('\n');
160
+ }
161
+ return output;
162
+ }
163
+ }
164
+ exports.GitHubMcpIntegrator = GitHubMcpIntegrator;
@@ -0,0 +1,229 @@
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.HookGenerator = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ /**
40
+ * Generates per-step Copilot CLI hook files that enforce scope boundaries
41
+ * during execution and capture structured evidence in real-time.
42
+ *
43
+ * Hooks are written to <workingDir>/.github/hooks/ which the Copilot CLI
44
+ * SDK auto-loads on session start. Context (toolName, toolArgs, toolResult)
45
+ * is piped to hook commands via stdin as JSON.
46
+ */
47
+ class HookGenerator {
48
+ /**
49
+ * Generate hooks for a single step execution.
50
+ * Writes a hook config to <workingDir>/.github/hooks/ and returns
51
+ * paths needed for evidence parsing after execution.
52
+ */
53
+ generateStepHooks(input) {
54
+ const hooksDir = path.join(input.workingDir, '.github', 'hooks');
55
+ fs.mkdirSync(hooksDir, { recursive: true });
56
+ const evidenceDir = path.join(input.runDir, 'evidence');
57
+ if (!fs.existsSync(evidenceDir)) {
58
+ fs.mkdirSync(evidenceDir, { recursive: true });
59
+ }
60
+ const evidenceLogPath = path.join(evidenceDir, `step-${input.step.stepNumber}.jsonl`);
61
+ const scopeRules = this.deriveScopeRules(input.agent, input.existingTestFiles);
62
+ const hookConfig = this.buildHookConfig(scopeRules, evidenceLogPath, input);
63
+ const hooksFilePath = path.join(hooksDir, `swarm-step-${input.step.stepNumber}.json`);
64
+ fs.writeFileSync(hooksFilePath, JSON.stringify(hookConfig, null, 2));
65
+ return { hooksDir, hooksFilePath, evidenceLogPath, scopeRules };
66
+ }
67
+ /**
68
+ * Remove the generated hooks file after step execution.
69
+ * The evidence log is NOT removed (it lives in the run directory).
70
+ */
71
+ cleanupHooks(hooksFileOrDir) {
72
+ try {
73
+ const stat = fs.statSync(hooksFileOrDir);
74
+ if (stat.isDirectory()) {
75
+ // Legacy path: remove temp directory from old approach
76
+ fs.rmSync(hooksFileOrDir, { recursive: true, force: true });
77
+ }
78
+ else {
79
+ // Remove the single hooks JSON file we created
80
+ fs.unlinkSync(hooksFileOrDir);
81
+ }
82
+ }
83
+ catch {
84
+ // Best-effort cleanup
85
+ }
86
+ }
87
+ /**
88
+ * Parse an evidence JSONL file into structured entries.
89
+ */
90
+ parseEvidenceLog(evidenceLogPath) {
91
+ if (!fs.existsSync(evidenceLogPath))
92
+ return [];
93
+ const content = fs.readFileSync(evidenceLogPath, 'utf8').trim();
94
+ if (!content)
95
+ return [];
96
+ const entries = [];
97
+ for (const line of content.split('\n')) {
98
+ const trimmed = line.trim();
99
+ if (!trimmed)
100
+ continue;
101
+ try {
102
+ entries.push(JSON.parse(trimmed));
103
+ }
104
+ catch {
105
+ // Skip malformed lines; hooks may produce partial output on kill
106
+ }
107
+ }
108
+ return entries;
109
+ }
110
+ /**
111
+ * Derive scope rules from agent boundaries.
112
+ * Agent boundaries contain natural-language rules like
113
+ * "Do not modify frontend components or UI code". These are mapped
114
+ * to file path patterns for hook enforcement.
115
+ */
116
+ deriveScopeRules(agent, existingTestFiles) {
117
+ const allow = [];
118
+ const deny = [];
119
+ for (const scope of agent.scope) {
120
+ const lower = scope.toLowerCase();
121
+ if (lower.includes('frontend') || lower.includes('ui') || lower.includes('component')) {
122
+ allow.push('src/components', 'src/pages', 'src/views', 'public', 'styles', '.css', '.scss', '.html');
123
+ }
124
+ if (lower.includes('backend') || lower.includes('server') || lower.includes('api')) {
125
+ allow.push('src/api', 'src/server', 'src/routes', 'src/middleware', 'server', 'api');
126
+ }
127
+ if (lower.includes('test') || lower.includes('quality')) {
128
+ allow.push('test', 'tests', '__tests__', 'spec', '.test.', '.spec.');
129
+ }
130
+ if (lower.includes('ci/cd') || lower.includes('docker') || lower.includes('deployment')) {
131
+ allow.push('.github', 'Dockerfile', 'docker-compose', '.env', 'deploy');
132
+ }
133
+ if (lower.includes('security')) {
134
+ allow.push('src', 'config', 'package.json');
135
+ }
136
+ }
137
+ for (const boundary of agent.boundaries) {
138
+ const lower = boundary.toLowerCase();
139
+ if (lower.includes('frontend') || lower.includes('ui')) {
140
+ deny.push('src/components', 'src/pages', 'src/views', '.css', '.scss');
141
+ }
142
+ if (lower.includes('backend') || lower.includes('server')) {
143
+ deny.push('src/api', 'src/server', 'src/routes', 'server');
144
+ }
145
+ if (lower.includes('database') || lower.includes('schema') || lower.includes('migration')) {
146
+ deny.push('migrations', 'prisma/schema', 'db/schema');
147
+ }
148
+ if (lower.includes('ci/cd') || lower.includes('pipeline') || lower.includes('infrastructure')) {
149
+ deny.push('.github/workflows', 'Dockerfile');
150
+ }
151
+ if (lower.includes('test framework')) {
152
+ deny.push('jest.config', 'mocha', '.mocharc');
153
+ }
154
+ }
155
+ // Protect pre-existing test files from modification by default.
156
+ // Reviewer steps are read-only and do not write to any files.
157
+ // Worker steps must not modify existing tests unless the goal explicitly requires it.
158
+ const canModifyTests = agent.name === 'reviewer';
159
+ if (!canModifyTests && existingTestFiles && existingTestFiles.length > 0) {
160
+ for (const testFile of existingTestFiles) {
161
+ deny.push(testFile);
162
+ }
163
+ }
164
+ return {
165
+ allow: [...new Set(allow)],
166
+ deny: [...new Set(deny)]
167
+ };
168
+ }
169
+ // Scope enforcement via preToolUse hooks. The SDK reads the
170
+ // permissionDecision field from the hook's JSON stdout. When a file path
171
+ // matches a deny rule and no allow rule overrides it, the hook outputs
172
+ // "deny" with a reason. The SDK blocks the tool call and injects the
173
+ // reason into the agent's context. Violations are also logged to the
174
+ // evidence file so the verification layer can flag them independently.
175
+ /**
176
+ * Build a bash script that reads context JSON from stdin, checks the
177
+ * file path against deny/allow rules, and either denies the tool call
178
+ * (via permissionDecision) or approves it. Violations are logged to
179
+ * the evidence file regardless for verification-layer enforcement.
180
+ */
181
+ buildPreToolUseScript(scopeRules, evidenceLogPath, agentName) {
182
+ const rulesJson = JSON.stringify({ allow: scopeRules.allow, deny: scopeRules.deny });
183
+ const escapedPath = evidenceLogPath.replace(/'/g, "'\\'");
184
+ const safeAgent = agentName.replace(/'/g, '');
185
+ // Node reads context from stdin, checks scope rules, denies out-of-scope tool calls, logs violations
186
+ return `node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const ctx=JSON.parse(d);const rules=${rulesJson.replace(/"/g, '\\"')};const p=(ctx.toolArgs||{}).path||(ctx.toolArgs||{}).filePath||'';if(p&&rules.deny.length>0){const denied=rules.deny.some(r=>p.includes(r));if(denied){const allowed=rules.allow.some(r=>p.includes(r));if(!allowed){const rule=rules.deny.find(r=>p.includes(r));const entry={timestamp:new Date().toISOString(),event:'scope_violation',tool:ctx.toolName||'unknown',filePath:p,agentName:'${safeAgent}',boundaryRule:rule};require('fs').appendFileSync('${escapedPath}',JSON.stringify(entry)+'\\n');process.stdout.write(JSON.stringify({permissionDecision:'deny',permissionDecisionReason:'Scope violation: '+p+' is outside agent boundary ('+rule+')'}));return}}}process.stdout.write(JSON.stringify({permissionDecision:'approve'}))}catch(e){process.stdout.write(JSON.stringify({permissionDecision:'approve'}))}})"`;
187
+ }
188
+ /**
189
+ * Build a bash script that reads context JSON from stdin and appends
190
+ * a structured evidence entry to the JSONL log file.
191
+ */
192
+ buildPostToolUseScript(evidenceLogPath) {
193
+ const escapedPath = evidenceLogPath.replace(/'/g, "'\\''");
194
+ return `node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const ctx=JSON.parse(d);const entry={timestamp:new Date().toISOString(),event:'postToolUse',tool:ctx.toolName||'unknown',filePath:(ctx.toolArgs||{}).path||(ctx.toolArgs||{}).filePath,exitCode:ctx.toolResult?ctx.toolResult.exitCode:undefined};require('fs').appendFileSync('${escapedPath}',JSON.stringify(entry)+'\\n')}catch(e){}})"`;
195
+ }
196
+ // ---------------------------------------------------------------------------
197
+ // Private: build complete hook config
198
+ // ---------------------------------------------------------------------------
199
+ buildHookConfig(scopeRules, evidenceLogPath, input) {
200
+ const escapedEvidence = evidenceLogPath.replace(/'/g, "'\\''");
201
+ return {
202
+ version: 1,
203
+ hooks: {
204
+ sessionStart: [{
205
+ type: 'command',
206
+ bash: `node -e "const entry={timestamp:new Date().toISOString(),event:'sessionStart',tool:'session',filePath:'${input.stepBranch}'};try{require('fs').appendFileSync('${escapedEvidence}',JSON.stringify(entry)+'\\n')}catch(e){}"`,
207
+ timeoutSec: 10
208
+ }],
209
+ preToolUse: [{
210
+ type: 'command',
211
+ bash: this.buildPreToolUseScript(scopeRules, evidenceLogPath, input.agent.name),
212
+ timeoutSec: 10
213
+ }],
214
+ postToolUse: [{
215
+ type: 'command',
216
+ bash: this.buildPostToolUseScript(evidenceLogPath),
217
+ timeoutSec: 10
218
+ }],
219
+ errorOccurred: [{
220
+ type: 'command',
221
+ bash: `node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const ctx=JSON.parse(d);const entry={timestamp:new Date().toISOString(),event:'errorOccurred',tool:'error',exitCode:1};require('fs').appendFileSync('${escapedEvidence}',JSON.stringify(entry)+'\\n')}catch(e){}})"`,
222
+ timeoutSec: 10
223
+ }]
224
+ }
225
+ };
226
+ }
227
+ }
228
+ exports.HookGenerator = HookGenerator;
229
+ exports.default = HookGenerator;
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
+ if (k2 === undefined) k2 = k;
5
+ var desc = Object.getOwnPropertyDescriptor(m, k);
6
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
+ desc = { enumerable: true, get: function() { return m[k]; } };
8
+ }
9
+ Object.defineProperty(o, k2, desc);
10
+ }) : (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ o[k2] = m[k];
13
+ }));
14
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.validateURL = exports.StatisticsTracker = exports.URLShortener = exports.load_quality_gates_config = exports.run_quality_gates = exports.PMAgent = exports.RepairAgent = exports.DemoMode = exports.ShareParser = exports.VerifierEngine = exports.SessionExecutor = exports.ConfigLoader = exports.PlanGenerator = exports.SwarmOrchestrator = void 0;
19
+ /**
20
+ * Swarm Orchestrator - Public API
21
+ * Import these for programmatic use of the orchestrator.
22
+ */
23
+ var swarm_orchestrator_1 = require("./swarm-orchestrator");
24
+ Object.defineProperty(exports, "SwarmOrchestrator", { enumerable: true, get: function () { return swarm_orchestrator_1.SwarmOrchestrator; } });
25
+ var plan_generator_1 = require("./plan-generator");
26
+ Object.defineProperty(exports, "PlanGenerator", { enumerable: true, get: function () { return plan_generator_1.PlanGenerator; } });
27
+ var config_loader_1 = require("./config-loader");
28
+ Object.defineProperty(exports, "ConfigLoader", { enumerable: true, get: function () { return config_loader_1.ConfigLoader; } });
29
+ var session_executor_1 = require("./session-executor");
30
+ Object.defineProperty(exports, "SessionExecutor", { enumerable: true, get: function () { return session_executor_1.SessionExecutor; } });
31
+ var verifier_engine_1 = require("./verifier-engine");
32
+ Object.defineProperty(exports, "VerifierEngine", { enumerable: true, get: function () { return verifier_engine_1.VerifierEngine; } });
33
+ var share_parser_1 = require("./share-parser");
34
+ Object.defineProperty(exports, "ShareParser", { enumerable: true, get: function () { return share_parser_1.ShareParser; } });
35
+ var demo_mode_1 = require("./demo-mode");
36
+ Object.defineProperty(exports, "DemoMode", { enumerable: true, get: function () { return demo_mode_1.DemoMode; } });
37
+ var repair_agent_1 = require("./repair-agent");
38
+ Object.defineProperty(exports, "RepairAgent", { enumerable: true, get: function () { return repair_agent_1.RepairAgent; } });
39
+ var pm_agent_1 = require("./pm-agent");
40
+ Object.defineProperty(exports, "PMAgent", { enumerable: true, get: function () { return pm_agent_1.PMAgent; } });
41
+ var quality_gates_1 = require("./quality-gates");
42
+ Object.defineProperty(exports, "run_quality_gates", { enumerable: true, get: function () { return quality_gates_1.run_quality_gates; } });
43
+ Object.defineProperty(exports, "load_quality_gates_config", { enumerable: true, get: function () { return quality_gates_1.load_quality_gates_config; } });
44
+ var url_shortener_1 = require("./url-shortener");
45
+ Object.defineProperty(exports, "URLShortener", { enumerable: true, get: function () { return url_shortener_1.URLShortener; } });
46
+ Object.defineProperty(exports, "StatisticsTracker", { enumerable: true, get: function () { return url_shortener_1.StatisticsTracker; } });
47
+ Object.defineProperty(exports, "validateURL", { enumerable: true, get: function () { return url_shortener_1.validateURL; } });
48
+ __exportStar(require("./verification"), exports);