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,221 @@
|
|
|
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.SessionManager = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const share_parser_1 = require("./share-parser");
|
|
40
|
+
class SessionManager {
|
|
41
|
+
runsDir;
|
|
42
|
+
constructor(runsDir) {
|
|
43
|
+
this.runsDir = runsDir || path.join(process.cwd(), 'runs');
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* create a new run directory structure
|
|
47
|
+
*/
|
|
48
|
+
createRun(runId) {
|
|
49
|
+
const runDir = path.join(this.runsDir, runId);
|
|
50
|
+
if (!fs.existsSync(this.runsDir)) {
|
|
51
|
+
fs.mkdirSync(this.runsDir, { recursive: true });
|
|
52
|
+
}
|
|
53
|
+
if (fs.existsSync(runDir)) {
|
|
54
|
+
throw new Error(`run ${runId} already exists`);
|
|
55
|
+
}
|
|
56
|
+
fs.mkdirSync(runDir);
|
|
57
|
+
fs.mkdirSync(path.join(runDir, 'steps'));
|
|
58
|
+
return runDir;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* create a step directory within a run
|
|
62
|
+
*/
|
|
63
|
+
createStepDir(runId, stepNumber) {
|
|
64
|
+
const stepDir = path.join(this.runsDir, runId, 'steps', this.padStepNumber(stepNumber));
|
|
65
|
+
if (!fs.existsSync(stepDir)) {
|
|
66
|
+
fs.mkdirSync(stepDir, { recursive: true });
|
|
67
|
+
}
|
|
68
|
+
return stepDir;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* import a /share transcript and parse it
|
|
72
|
+
*/
|
|
73
|
+
importShare(runId, stepNumber, agentName, transcriptPathOrContent) {
|
|
74
|
+
const stepDir = this.createStepDir(runId, stepNumber);
|
|
75
|
+
// determine if input is path or content
|
|
76
|
+
let content;
|
|
77
|
+
if (fs.existsSync(transcriptPathOrContent)) {
|
|
78
|
+
// it's a file path
|
|
79
|
+
content = fs.readFileSync(transcriptPathOrContent, 'utf8');
|
|
80
|
+
}
|
|
81
|
+
else if (transcriptPathOrContent.startsWith('http')) {
|
|
82
|
+
// it's a URL - not supported yet
|
|
83
|
+
throw new Error('URL import not yet implemented');
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// treat as raw content
|
|
87
|
+
content = transcriptPathOrContent;
|
|
88
|
+
}
|
|
89
|
+
// parse the share transcript
|
|
90
|
+
const parser = new share_parser_1.ShareParser();
|
|
91
|
+
const index = parser.parse(content);
|
|
92
|
+
// save the share transcript to step directory
|
|
93
|
+
const sharePath = path.join(stepDir, 'share.md');
|
|
94
|
+
fs.writeFileSync(sharePath, content, 'utf8');
|
|
95
|
+
// save the index
|
|
96
|
+
const indexPath = path.join(stepDir, 'index.json');
|
|
97
|
+
fs.writeFileSync(indexPath, JSON.stringify(index, null, 2), 'utf8');
|
|
98
|
+
// create step share record
|
|
99
|
+
const stepShare = {
|
|
100
|
+
stepNumber,
|
|
101
|
+
agentName,
|
|
102
|
+
transcriptPath: sharePath,
|
|
103
|
+
index,
|
|
104
|
+
importedAt: new Date().toISOString()
|
|
105
|
+
};
|
|
106
|
+
// update run context
|
|
107
|
+
this.updateRunContext(runId, stepShare);
|
|
108
|
+
return stepShare;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* get prior context for a step (all previous shares)
|
|
112
|
+
*/
|
|
113
|
+
getPriorContext(runId, currentStep) {
|
|
114
|
+
const runContextPath = path.join(this.runsDir, runId, 'context.json');
|
|
115
|
+
if (!fs.existsSync(runContextPath)) {
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
const context = JSON.parse(fs.readFileSync(runContextPath, 'utf8'));
|
|
119
|
+
return context.shares
|
|
120
|
+
.filter(share => share.stepNumber < currentStep)
|
|
121
|
+
.sort((a, b) => a.stepNumber - b.stepNumber);
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* generate context summary for next step
|
|
125
|
+
*/
|
|
126
|
+
generateContextSummary(runId, currentStep) {
|
|
127
|
+
const priorShares = this.getPriorContext(runId, currentStep);
|
|
128
|
+
if (priorShares.length === 0) {
|
|
129
|
+
return 'no prior context';
|
|
130
|
+
}
|
|
131
|
+
const lines = [];
|
|
132
|
+
lines.push('context from prior steps:');
|
|
133
|
+
lines.push('');
|
|
134
|
+
for (const share of priorShares) {
|
|
135
|
+
lines.push(`step ${share.stepNumber} (${share.agentName}):`);
|
|
136
|
+
if (share.index.changedFiles.length > 0) {
|
|
137
|
+
lines.push(` changed files: ${share.index.changedFiles.join(', ')}`);
|
|
138
|
+
}
|
|
139
|
+
if (share.index.testsRun.length > 0) {
|
|
140
|
+
const verifiedTests = share.index.testsRun.filter(t => t.verified);
|
|
141
|
+
if (verifiedTests.length > 0) {
|
|
142
|
+
lines.push(` tests verified: ${verifiedTests.map(t => t.command).join(', ')}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
if (share.index.prLinks.length > 0) {
|
|
146
|
+
lines.push(` PRs created: ${share.index.prLinks.join(', ')}`);
|
|
147
|
+
}
|
|
148
|
+
// check for unverified claims
|
|
149
|
+
const unverified = share.index.claims.filter(c => !c.verified);
|
|
150
|
+
if (unverified.length > 0) {
|
|
151
|
+
lines.push(` ⚠ unverified claims: ${unverified.length}`);
|
|
152
|
+
unverified.forEach(claim => {
|
|
153
|
+
lines.push(` - ${claim.claim.substring(0, 80)}`);
|
|
154
|
+
lines.push(` reason: ${claim.evidence}`);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
lines.push('');
|
|
158
|
+
}
|
|
159
|
+
return lines.join('\n');
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* save summary for a step
|
|
163
|
+
*/
|
|
164
|
+
saveSummary(runId, stepNumber, summary) {
|
|
165
|
+
const stepDir = this.createStepDir(runId, stepNumber);
|
|
166
|
+
const summaryPath = path.join(stepDir, 'summary.md');
|
|
167
|
+
fs.writeFileSync(summaryPath, summary, 'utf8');
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* save verification notes for a step
|
|
171
|
+
*/
|
|
172
|
+
saveVerification(runId, stepNumber, verification) {
|
|
173
|
+
const stepDir = this.createStepDir(runId, stepNumber);
|
|
174
|
+
const verificationPath = path.join(stepDir, 'verification.md');
|
|
175
|
+
fs.writeFileSync(verificationPath, verification, 'utf8');
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* get unverified claims across all steps in a run
|
|
179
|
+
*/
|
|
180
|
+
getUnverifiedClaims(runId) {
|
|
181
|
+
const runContextPath = path.join(this.runsDir, runId, 'context.json');
|
|
182
|
+
if (!fs.existsSync(runContextPath)) {
|
|
183
|
+
return [];
|
|
184
|
+
}
|
|
185
|
+
const context = JSON.parse(fs.readFileSync(runContextPath, 'utf8'));
|
|
186
|
+
return context.shares
|
|
187
|
+
.map(share => ({
|
|
188
|
+
step: share.stepNumber,
|
|
189
|
+
agent: share.agentName,
|
|
190
|
+
claims: share.index.claims.filter(c => !c.verified)
|
|
191
|
+
}))
|
|
192
|
+
.filter(item => item.claims.length > 0);
|
|
193
|
+
}
|
|
194
|
+
updateRunContext(runId, stepShare) {
|
|
195
|
+
const runContextPath = path.join(this.runsDir, runId, 'context.json');
|
|
196
|
+
let context;
|
|
197
|
+
if (fs.existsSync(runContextPath)) {
|
|
198
|
+
context = JSON.parse(fs.readFileSync(runContextPath, 'utf8'));
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
context = {
|
|
202
|
+
runId,
|
|
203
|
+
runDir: path.join(this.runsDir, runId),
|
|
204
|
+
shares: []
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
// remove any existing share for this step (replace)
|
|
208
|
+
context.shares = context.shares.filter(s => s.stepNumber !== stepShare.stepNumber);
|
|
209
|
+
// add new share
|
|
210
|
+
context.shares.push(stepShare);
|
|
211
|
+
// sort by step number
|
|
212
|
+
context.shares.sort((a, b) => a.stepNumber - b.stepNumber);
|
|
213
|
+
// save
|
|
214
|
+
fs.writeFileSync(runContextPath, JSON.stringify(context, null, 2), 'utf8');
|
|
215
|
+
}
|
|
216
|
+
padStepNumber(stepNumber) {
|
|
217
|
+
return stepNumber.toString().padStart(2, '0');
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
exports.SessionManager = SessionManager;
|
|
221
|
+
exports.default = SessionManager;
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractClaims = extractClaims;
|
|
4
|
+
/**
|
|
5
|
+
* Probabilistic claim-verification pass: scan transcript lines for natural-language
|
|
6
|
+
* claims (tests passing, build successful, commit made) and cross-reference each
|
|
7
|
+
* claim against the deterministic extraction results already produced by the
|
|
8
|
+
* transcript-extraction pass.
|
|
9
|
+
*
|
|
10
|
+
* This is heuristic — line patterns are matched case-insensitively and lines
|
|
11
|
+
* that look like agent-prompt instructions are skipped. Returns a claims[] with
|
|
12
|
+
* verified=true when supporting evidence exists in the index, verified=false
|
|
13
|
+
* otherwise (with a reason).
|
|
14
|
+
*/
|
|
15
|
+
function extractClaims(lines, index) {
|
|
16
|
+
const claims = [];
|
|
17
|
+
const instructionPrefixes = [
|
|
18
|
+
'scope:',
|
|
19
|
+
'done when:',
|
|
20
|
+
'role:',
|
|
21
|
+
'rules:',
|
|
22
|
+
'rule:',
|
|
23
|
+
'context:',
|
|
24
|
+
'you are ',
|
|
25
|
+
'your task',
|
|
26
|
+
'your job',
|
|
27
|
+
'your goal',
|
|
28
|
+
'important:',
|
|
29
|
+
'note:',
|
|
30
|
+
'constraints:',
|
|
31
|
+
'requirements:',
|
|
32
|
+
];
|
|
33
|
+
for (const line of lines) {
|
|
34
|
+
const lowerLine = line.toLowerCase();
|
|
35
|
+
const trimmedLower = lowerLine.trim().toLowerCase();
|
|
36
|
+
if (instructionPrefixes.some((prefix) => trimmedLower.startsWith(prefix))) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
if (trimmedLower.match(/^[-*]\s+(ensure|make sure|verify|confirm|must|should)\b/)) {
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
// tests passing
|
|
43
|
+
if ((lowerLine.match(/\btests?\b/) && lowerLine.match(/\b(pass|passed|passing)\b/)) ||
|
|
44
|
+
lowerLine.includes('all tests passed') ||
|
|
45
|
+
lowerLine.includes('tests are passing')) {
|
|
46
|
+
const hasVerifiedTests = index.testsRun.some((t) => t.verified);
|
|
47
|
+
claims.push({
|
|
48
|
+
claim: line.trim(),
|
|
49
|
+
verified: hasVerifiedTests,
|
|
50
|
+
evidence: hasVerifiedTests
|
|
51
|
+
? `verified test command: ${index.testsRun.find((t) => t.verified)?.command}`
|
|
52
|
+
: 'no test execution found in transcript',
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
// build succeeded
|
|
56
|
+
if (lowerLine.match(/\b(build|builds)\s+(succeed|succeeded|passed|successful)/i) ||
|
|
57
|
+
lowerLine.includes('compiled successfully')) {
|
|
58
|
+
const hasBuildCommand = index.buildOperations.some((b) => b.verified);
|
|
59
|
+
claims.push({
|
|
60
|
+
claim: line.trim(),
|
|
61
|
+
verified: hasBuildCommand,
|
|
62
|
+
evidence: hasBuildCommand
|
|
63
|
+
? `verified build with: ${index.buildOperations.find((b) => b.verified)?.tool}`
|
|
64
|
+
: 'no build command found in transcript',
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
// lint passing
|
|
68
|
+
if (lowerLine.match(/\b(lint|linting)\s+(pass|passed|succeeded)/i) ||
|
|
69
|
+
lowerLine.match(/no\s+lint\s+errors?/i)) {
|
|
70
|
+
const hasLintCommand = index.lintOperations.some((l) => l.verified);
|
|
71
|
+
claims.push({
|
|
72
|
+
claim: line.trim(),
|
|
73
|
+
verified: hasLintCommand,
|
|
74
|
+
evidence: hasLintCommand
|
|
75
|
+
? `verified lint with: ${index.lintOperations.find((l) => l.verified)?.tool}`
|
|
76
|
+
: 'no lint command found in transcript',
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// deployment
|
|
80
|
+
if (lowerLine.match(/\b(deploy|deployed|deployment)\s+(succeed|succeeded|successful)/i)) {
|
|
81
|
+
const hasDeployCommand = index.commandsExecuted.some((cmd) => cmd.includes('deploy') || cmd.includes('publish'));
|
|
82
|
+
claims.push({
|
|
83
|
+
claim: line.trim(),
|
|
84
|
+
verified: hasDeployCommand,
|
|
85
|
+
evidence: hasDeployCommand
|
|
86
|
+
? 'verified deployment command found'
|
|
87
|
+
: 'no deployment command found in transcript',
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
// package install
|
|
91
|
+
if (lowerLine.match(/\b(installed|added)\s+package/i) || lowerLine.match(/\bnpm\s+install/i)) {
|
|
92
|
+
const hasPackageOp = index.packageOperations.some((op) => op.operation === 'install');
|
|
93
|
+
claims.push({
|
|
94
|
+
claim: line.trim(),
|
|
95
|
+
verified: hasPackageOp,
|
|
96
|
+
evidence: hasPackageOp
|
|
97
|
+
? `verified package install: ${index.packageOperations.find((op) => op.operation === 'install')?.packages.join(', ')}`
|
|
98
|
+
: 'no package install command found',
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
// git commit
|
|
102
|
+
if (lowerLine.match(/\bcommitted\s+(the\s+)?changes?/i) || lowerLine.match(/\bgit\s+commit/i)) {
|
|
103
|
+
const hasCommit = index.gitCommits.length > 0;
|
|
104
|
+
claims.push({
|
|
105
|
+
claim: line.trim(),
|
|
106
|
+
verified: hasCommit,
|
|
107
|
+
evidence: hasCommit
|
|
108
|
+
? `verified commit: ${index.gitCommits[0]?.message}`
|
|
109
|
+
: 'no git commit found in transcript',
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
// MCP consultation
|
|
113
|
+
if (lowerLine.match(/\b(consulted|checked|reviewed)\s+(mcp|github|issues?)/i) &&
|
|
114
|
+
(lowerLine.includes('mcp') ||
|
|
115
|
+
lowerLine.includes('github') ||
|
|
116
|
+
lowerLine.includes('context'))) {
|
|
117
|
+
const hasMcp = index.mcpSections.some((m) => m.verified);
|
|
118
|
+
claims.push({
|
|
119
|
+
claim: line.trim(),
|
|
120
|
+
verified: hasMcp,
|
|
121
|
+
evidence: hasMcp
|
|
122
|
+
? 'verified MCP Evidence section found'
|
|
123
|
+
: 'no MCP Evidence section or insufficient evidence',
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return claims;
|
|
128
|
+
}
|