@williambeto/ai-workflow 2.9.0 → 2.9.2
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.
|
@@ -25,6 +25,9 @@ function parseStatusLine(line) {
|
|
|
25
25
|
function isManagedChangePath(file = "") {
|
|
26
26
|
return /(^|\/)(node_modules|vendor|dist|coverage|\.cache)(\/|$)/.test(normalizePath(file));
|
|
27
27
|
}
|
|
28
|
+
function isScreenshotPath(file = "") {
|
|
29
|
+
return /\.(png|jpe?g|webp)$/i.test(normalizePath(file));
|
|
30
|
+
}
|
|
28
31
|
async function exists(target) {
|
|
29
32
|
try {
|
|
30
33
|
await fs.access(target);
|
|
@@ -163,17 +166,22 @@ var QualityGuard = class {
|
|
|
163
166
|
}
|
|
164
167
|
async verifyUiEvidence() {
|
|
165
168
|
if (!this.isUiTask()) return { status: "NOT_RUN", reason: "Non-UI task." };
|
|
166
|
-
const candidates = ["docs", "screenshots", "evidence"];
|
|
167
|
-
const found =
|
|
169
|
+
const candidates = ["docs", "screenshots", "evidence", ".evidence"];
|
|
170
|
+
const found = /* @__PURE__ */ new Set();
|
|
171
|
+
for (const file of this.getScopedChangedFiles()) {
|
|
172
|
+
const normalized = normalizePath(file);
|
|
173
|
+
if (!isScreenshotPath(normalized) || path.isAbsolute(normalized) || normalized.startsWith("../")) continue;
|
|
174
|
+
if (await exists(path.join(this.cwd, normalized))) found.add(normalized);
|
|
175
|
+
}
|
|
168
176
|
for (const dir of candidates) {
|
|
169
177
|
const root = path.join(this.cwd, dir);
|
|
170
178
|
if (!await exists(root)) continue;
|
|
171
179
|
const entries = await fs.readdir(root, { recursive: true }).catch(() => []);
|
|
172
180
|
for (const entry of entries) {
|
|
173
|
-
if (
|
|
181
|
+
if (isScreenshotPath(String(entry))) found.add(normalizePath(path.join(dir, String(entry))));
|
|
174
182
|
}
|
|
175
183
|
}
|
|
176
|
-
if (found.
|
|
184
|
+
if (found.size) return { status: "PASS", screenshots: [...found].sort().slice(0, 20) };
|
|
177
185
|
if (this.evidencePolicy === "required") {
|
|
178
186
|
return { status: "FAIL_QUALITY_GATE", reason: "Required evidence for a high-risk or release UI change does not include a persisted screenshot." };
|
|
179
187
|
}
|
|
@@ -673,6 +681,26 @@ var EvidenceCollector = class {
|
|
|
673
681
|
const implementationFilesPresent = qualityGuard.isImplementationTask();
|
|
674
682
|
const executableBehavior = await qualityGuard.hasExecutableBehaviorChanges(this.deliveryChangedFiles || void 0);
|
|
675
683
|
const results = tasks.map((task) => this.runTask(task));
|
|
684
|
+
let visualEvidence = null;
|
|
685
|
+
if (this.visualDist) {
|
|
686
|
+
console.log(`
|
|
687
|
+
--- Capturing Visual Evidence ---`);
|
|
688
|
+
console.log(`Serving ${this.visualDist} on port ${this.port}...`);
|
|
689
|
+
try {
|
|
690
|
+
const verifier = new VisualVerifier({ cwd: this.cwd, visualDist: this.visualDist, port: this.port });
|
|
691
|
+
const screenshots = await verifier.captureScreenshots();
|
|
692
|
+
visualEvidence = {
|
|
693
|
+
desktop: path3.relative(this.cwd, screenshots[0]),
|
|
694
|
+
mobile: path3.relative(this.cwd, screenshots[1])
|
|
695
|
+
};
|
|
696
|
+
console.log(`Visual evidence captured successfully:`);
|
|
697
|
+
console.log(`- Desktop: ${visualEvidence.desktop}`);
|
|
698
|
+
console.log(`- Mobile: ${visualEvidence.mobile}`);
|
|
699
|
+
} catch (err) {
|
|
700
|
+
console.error(`Error capturing visual evidence: ${err.message}`);
|
|
701
|
+
throw err;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
676
704
|
const policyValidation = await qualityGuard.verify();
|
|
677
705
|
const behaviorTests = results.filter((result) => result.kind === "test");
|
|
678
706
|
const passingBehaviorTest = behaviorTests.some((result) => result.status === "PASS");
|
|
@@ -745,7 +773,8 @@ var EvidenceCollector = class {
|
|
|
745
773
|
deliveryDecision: deliveryDecision.decision,
|
|
746
774
|
claimedOutcome: this.claimedOutcome
|
|
747
775
|
});
|
|
748
|
-
|
|
776
|
+
const deliveryOutcomeBlocks = ["NEEDS_CLARIFICATION", "NOT_DELIVERED"].includes(deliveryOutcome) && ["PASS", "PASS_WITH_NOTES"].includes(overallStatus);
|
|
777
|
+
if (deliveryOutcomeBlocks) {
|
|
749
778
|
overallStatus = "BLOCKED";
|
|
750
779
|
}
|
|
751
780
|
const limitations = [];
|
|
@@ -811,7 +840,7 @@ var EvidenceCollector = class {
|
|
|
811
840
|
"satisfy the stated decision requirement before finalizing"
|
|
812
841
|
));
|
|
813
842
|
}
|
|
814
|
-
if (
|
|
843
|
+
if (deliveryOutcomeBlocks) {
|
|
815
844
|
limitations.push(blockingDiagnostic(
|
|
816
845
|
"delivery-outcome",
|
|
817
846
|
`the resolved outcome is ${deliveryOutcome}`,
|
|
@@ -820,26 +849,6 @@ var EvidenceCollector = class {
|
|
|
820
849
|
));
|
|
821
850
|
}
|
|
822
851
|
const uniqueLimitations = [...new Set(limitations)];
|
|
823
|
-
let visualEvidence = null;
|
|
824
|
-
if (this.visualDist) {
|
|
825
|
-
console.log(`
|
|
826
|
-
--- Capturing Visual Evidence ---`);
|
|
827
|
-
console.log(`Serving ${this.visualDist} on port ${this.port}...`);
|
|
828
|
-
try {
|
|
829
|
-
const verifier = new VisualVerifier({ cwd: this.cwd, visualDist: this.visualDist, port: this.port });
|
|
830
|
-
const screenshots = await verifier.captureScreenshots();
|
|
831
|
-
visualEvidence = {
|
|
832
|
-
desktop: path3.relative(this.cwd, screenshots[0]),
|
|
833
|
-
mobile: path3.relative(this.cwd, screenshots[1])
|
|
834
|
-
};
|
|
835
|
-
console.log(`Visual evidence captured successfully:`);
|
|
836
|
-
console.log(`- Desktop: ${visualEvidence.desktop}`);
|
|
837
|
-
console.log(`- Mobile: ${visualEvidence.mobile}`);
|
|
838
|
-
} catch (err) {
|
|
839
|
-
console.error(`Error capturing visual evidence: ${err.message}`);
|
|
840
|
-
throw err;
|
|
841
|
-
}
|
|
842
|
-
}
|
|
843
852
|
const evidence = {
|
|
844
853
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
845
854
|
taskSlug: this.taskSlug,
|
|
@@ -1053,4 +1062,4 @@ export {
|
|
|
1053
1062
|
EvidenceCollector,
|
|
1054
1063
|
ValidationPlanner
|
|
1055
1064
|
};
|
|
1056
|
-
//# sourceMappingURL=chunk-
|
|
1065
|
+
//# sourceMappingURL=chunk-PP42PB7M.js.map
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
QualityGuard,
|
|
4
4
|
ValidationPlanner,
|
|
5
5
|
VisualVerifier
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-PP42PB7M.js";
|
|
7
7
|
import "./chunk-H7GIKXFO.js";
|
|
8
8
|
import "./chunk-5WRI5ZAA.js";
|
|
9
9
|
|
|
@@ -86,4 +86,4 @@ async function runValidate({
|
|
|
86
86
|
export {
|
|
87
87
|
runValidate
|
|
88
88
|
};
|
|
89
|
-
//# sourceMappingURL=validate-
|
|
89
|
+
//# sourceMappingURL=validate-7G3HBE2K.js.map
|