ridgeline 0.6.0 → 0.7.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.
- package/README.md +8 -5
- package/dist/agents/core/designer.md +131 -0
- package/dist/agents/core/refiner.md +28 -1
- package/dist/agents/core/researcher.md +30 -11
- package/dist/agents/core/specifier.md +16 -0
- package/dist/agents/researchers/gaps.md +67 -0
- package/dist/agents/specifiers/visual-coherence.md +55 -0
- package/dist/cli.js +39 -8
- package/dist/cli.js.map +1 -1
- package/dist/commands/create.js +16 -1
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/design.d.ts +8 -0
- package/dist/commands/design.js +130 -0
- package/dist/commands/design.js.map +1 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.js +3 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/plan.js +3 -3
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/qa-workflow.d.ts +33 -0
- package/dist/commands/qa-workflow.js +139 -0
- package/dist/commands/qa-workflow.js.map +1 -0
- package/dist/commands/refine.d.ts +1 -0
- package/dist/commands/refine.js +17 -4
- package/dist/commands/refine.js.map +1 -1
- package/dist/commands/research.js +22 -8
- package/dist/commands/research.js.map +1 -1
- package/dist/commands/rewind.js +2 -2
- package/dist/commands/rewind.js.map +1 -1
- package/dist/commands/shape.js +36 -121
- package/dist/commands/shape.js.map +1 -1
- package/dist/commands/spec.js +1 -0
- package/dist/commands/spec.js.map +1 -1
- package/dist/engine/claude/stream.display.js +0 -1
- package/dist/engine/claude/stream.display.js.map +1 -1
- package/dist/engine/claude/stream.parse.d.ts +1 -15
- package/dist/engine/claude/stream.parse.js +3 -21
- package/dist/engine/claude/stream.parse.js.map +1 -1
- package/dist/engine/claude/stream.result.js +2 -2
- package/dist/engine/claude/stream.types.d.ts +15 -0
- package/dist/engine/claude/stream.types.js +23 -0
- package/dist/engine/claude/stream.types.js.map +1 -0
- package/dist/engine/discovery/agent.registry.d.ts +4 -0
- package/dist/engine/discovery/agent.registry.js +46 -18
- package/dist/engine/discovery/agent.registry.js.map +1 -1
- package/dist/engine/discovery/flavour.config.d.ts +9 -0
- package/dist/engine/discovery/flavour.config.js +61 -0
- package/dist/engine/discovery/flavour.config.js.map +1 -0
- package/dist/engine/discovery/plugin.scan.d.ts +1 -0
- package/dist/engine/discovery/plugin.scan.js +29 -1
- package/dist/engine/discovery/plugin.scan.js.map +1 -1
- package/dist/engine/discovery/skill.check.d.ts +19 -0
- package/dist/engine/discovery/skill.check.js +145 -0
- package/dist/engine/discovery/skill.check.js.map +1 -0
- package/dist/engine/pipeline/build.exec.js +1 -0
- package/dist/engine/pipeline/build.exec.js.map +1 -1
- package/dist/engine/pipeline/phase.sequence.js +10 -10
- package/dist/engine/pipeline/phase.sequence.js.map +1 -1
- package/dist/engine/pipeline/pipeline.shared.d.ts +6 -0
- package/dist/engine/pipeline/pipeline.shared.js +24 -1
- package/dist/engine/pipeline/pipeline.shared.js.map +1 -1
- package/dist/engine/pipeline/plan.exec.js +1 -0
- package/dist/engine/pipeline/plan.exec.js.map +1 -1
- package/dist/engine/pipeline/refine.exec.d.ts +2 -0
- package/dist/engine/pipeline/refine.exec.js +13 -2
- package/dist/engine/pipeline/refine.exec.js.map +1 -1
- package/dist/engine/pipeline/research.exec.d.ts +3 -0
- package/dist/engine/pipeline/research.exec.js +74 -5
- package/dist/engine/pipeline/research.exec.js.map +1 -1
- package/dist/engine/pipeline/review.exec.js +23 -0
- package/dist/engine/pipeline/review.exec.js.map +1 -1
- package/dist/engine/pipeline/specify.exec.d.ts +1 -0
- package/dist/engine/pipeline/specify.exec.js +114 -44
- package/dist/engine/pipeline/specify.exec.js.map +1 -1
- package/dist/flavours/data-analysis/core/refiner.md +28 -1
- package/dist/flavours/data-analysis/core/researcher.md +30 -11
- package/dist/flavours/data-analysis/researchers/gaps.md +59 -0
- package/dist/flavours/game-dev/core/refiner.md +28 -1
- package/dist/flavours/game-dev/core/researcher.md +30 -11
- package/dist/flavours/game-dev/researchers/gaps.md +59 -0
- package/dist/flavours/legal-drafting/core/refiner.md +28 -1
- package/dist/flavours/legal-drafting/core/researcher.md +30 -11
- package/dist/flavours/legal-drafting/researchers/gaps.md +59 -0
- package/dist/flavours/machine-learning/core/refiner.md +28 -1
- package/dist/flavours/machine-learning/core/researcher.md +30 -11
- package/dist/flavours/machine-learning/researchers/gaps.md +59 -0
- package/dist/flavours/mobile-app/core/refiner.md +28 -1
- package/dist/flavours/mobile-app/core/researcher.md +30 -11
- package/dist/flavours/mobile-app/researchers/gaps.md +59 -0
- package/dist/flavours/music-composition/core/refiner.md +28 -1
- package/dist/flavours/music-composition/core/researcher.md +30 -11
- package/dist/flavours/music-composition/researchers/gaps.md +59 -0
- package/dist/flavours/novel-writing/core/refiner.md +28 -1
- package/dist/flavours/novel-writing/core/researcher.md +30 -11
- package/dist/flavours/novel-writing/researchers/gaps.md +59 -0
- package/dist/flavours/screenwriting/core/refiner.md +28 -1
- package/dist/flavours/screenwriting/core/researcher.md +30 -11
- package/dist/flavours/screenwriting/researchers/gaps.md +59 -0
- package/dist/flavours/security-audit/core/refiner.md +28 -1
- package/dist/flavours/security-audit/core/researcher.md +30 -11
- package/dist/flavours/security-audit/researchers/gaps.md +59 -0
- package/dist/flavours/software-engineering/core/builder.md +2 -0
- package/dist/flavours/software-engineering/core/refiner.md +28 -1
- package/dist/flavours/software-engineering/core/researcher.md +30 -11
- package/dist/flavours/software-engineering/core/reviewer.md +2 -0
- package/dist/flavours/software-engineering/flavour.json +7 -0
- package/dist/flavours/software-engineering/researchers/gaps.md +59 -0
- package/dist/flavours/technical-writing/core/refiner.md +28 -1
- package/dist/flavours/technical-writing/core/researcher.md +30 -11
- package/dist/flavours/technical-writing/researchers/gaps.md +59 -0
- package/dist/flavours/test-suite/core/refiner.md +28 -1
- package/dist/flavours/test-suite/core/researcher.md +30 -11
- package/dist/flavours/test-suite/researchers/gaps.md +59 -0
- package/dist/flavours/translation/core/refiner.md +28 -1
- package/dist/flavours/translation/core/researcher.md +30 -11
- package/dist/flavours/translation/researchers/gaps.md +59 -0
- package/dist/flavours/web-game/core/builder.md +123 -0
- package/dist/flavours/web-game/core/reviewer.md +159 -0
- package/dist/flavours/web-game/flavour.json +9 -0
- package/dist/flavours/web-ui/core/builder.md +117 -0
- package/dist/flavours/web-ui/core/reviewer.md +155 -0
- package/dist/flavours/web-ui/flavour.json +10 -0
- package/dist/plugin/visual-tools/plugin.json +4 -0
- package/dist/plugin/visual-tools/skills/a11y-audit/SKILL.md +57 -0
- package/dist/plugin/visual-tools/skills/agent-browser/SKILL.md +56 -0
- package/dist/plugin/visual-tools/skills/agent-browser/references/viewports.md +17 -0
- package/dist/plugin/visual-tools/skills/canvas-screenshot/SKILL.md +84 -0
- package/dist/plugin/visual-tools/skills/css-audit/SKILL.md +50 -0
- package/dist/plugin/visual-tools/skills/lighthouse/SKILL.md +58 -0
- package/dist/plugin/visual-tools/skills/shader-validate/SKILL.md +77 -0
- package/dist/plugin/visual-tools/skills/visual-diff/SKILL.md +68 -0
- package/dist/shapes/detect.d.ts +8 -0
- package/dist/shapes/detect.js +87 -0
- package/dist/shapes/detect.js.map +1 -0
- package/dist/shapes/game-visual.json +8 -0
- package/dist/shapes/print-layout.json +8 -0
- package/dist/shapes/web-visual.json +9 -0
- package/dist/stores/budget.js +2 -1
- package/dist/stores/budget.js.map +1 -1
- package/dist/stores/feedback.format.d.ts +3 -0
- package/dist/stores/feedback.format.js +62 -0
- package/dist/stores/feedback.format.js.map +1 -0
- package/dist/stores/feedback.parse.d.ts +2 -0
- package/dist/stores/feedback.parse.js +121 -0
- package/dist/stores/feedback.parse.js.map +1 -0
- package/dist/stores/feedback.verdict.d.ts +2 -4
- package/dist/stores/feedback.verdict.js +7 -175
- package/dist/stores/feedback.verdict.js.map +1 -1
- package/dist/stores/index.d.ts +1 -1
- package/dist/stores/index.js +1 -2
- package/dist/stores/index.js.map +1 -1
- package/dist/stores/state.d.ts +4 -0
- package/dist/stores/state.js +37 -5
- package/dist/stores/state.js.map +1 -1
- package/dist/stores/trajectory.d.ts +2 -3
- package/dist/stores/trajectory.js +6 -7
- package/dist/stores/trajectory.js.map +1 -1
- package/dist/types.d.ts +11 -1
- package/dist/utils/atomic-write.d.ts +6 -0
- package/dist/utils/atomic-write.js +62 -0
- package/dist/utils/atomic-write.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: shader-validate
|
|
3
|
+
description: Validate and cross-compile GLSL, WGSL, and SPIR-V shaders using naga. Use when writing shaders, checking shader compilation, debugging shader errors, converting between shader languages, or verifying WebGL/WebGPU shader code.
|
|
4
|
+
compatibility: Requires naga-cli (cargo install naga-cli)
|
|
5
|
+
metadata:
|
|
6
|
+
author: ridgeline
|
|
7
|
+
version: "1.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Shader Validation
|
|
11
|
+
|
|
12
|
+
Validate and cross-compile shaders using naga — a fast Rust-based shader translator supporting WGSL, GLSL, SPIR-V, MSL, and HLSL.
|
|
13
|
+
|
|
14
|
+
## Validating a shader
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
naga my_shader.wgsl
|
|
18
|
+
naga my_shader.frag
|
|
19
|
+
naga my_shader.vert
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Exit code 0 means the shader is valid. Non-zero prints error details with line numbers.
|
|
23
|
+
|
|
24
|
+
## Cross-compiling shaders
|
|
25
|
+
|
|
26
|
+
Convert between shader languages by specifying input and output files:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# WGSL to SPIR-V
|
|
30
|
+
naga shader.wgsl shader.spv
|
|
31
|
+
|
|
32
|
+
# GLSL to WGSL
|
|
33
|
+
naga shader.frag shader.wgsl
|
|
34
|
+
|
|
35
|
+
# SPIR-V to Metal
|
|
36
|
+
naga shader.spv shader.metal
|
|
37
|
+
|
|
38
|
+
# WGSL to GLSL (with profile)
|
|
39
|
+
naga shader.wgsl shader.frag --profile es310
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The output format is determined by file extension.
|
|
43
|
+
|
|
44
|
+
## Common GLSL validation
|
|
45
|
+
|
|
46
|
+
For WebGL fragment shaders:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
naga my_effect.frag
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
For vertex shaders:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
naga my_mesh.vert
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Batch validation
|
|
59
|
+
|
|
60
|
+
Validate all shaders in a directory:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
find src/shaders -name '*.frag' -o -name '*.vert' -o -name '*.wgsl' | xargs -I {} naga {}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Common errors
|
|
67
|
+
|
|
68
|
+
- **"unknown type"**: Missing uniform/varying declaration or typo in type name
|
|
69
|
+
- **"expected ';'"**: Missing semicolon (GLSL) or syntax mismatch
|
|
70
|
+
- **"binding collision"**: Two resources share the same binding index
|
|
71
|
+
- **"entry point not found"**: Missing `main` function (GLSL) or `@vertex`/`@fragment` annotation (WGSL)
|
|
72
|
+
|
|
73
|
+
## Gotchas
|
|
74
|
+
|
|
75
|
+
- naga's GLSL support requires the shader stage to be inferred from the file extension (`.vert`, `.frag`, `.comp`). Use the correct extension.
|
|
76
|
+
- WGSL is the native format — validation is most thorough for WGSL input.
|
|
77
|
+
- naga does not execute shaders. It checks syntax, types, and resource bindings — not runtime behavior.
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: visual-diff
|
|
3
|
+
description: Compare screenshots pixel-by-pixel against reference images to detect visual regressions. Use when checking for unintended visual changes, comparing before/after screenshots, or validating that UI changes match expectations.
|
|
4
|
+
compatibility: Requires pixelmatch (npm i -g pixelmatch) and pngjs (npm i -g pngjs)
|
|
5
|
+
metadata:
|
|
6
|
+
author: ridgeline
|
|
7
|
+
version: "1.0"
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Visual Diff
|
|
11
|
+
|
|
12
|
+
Pixel-level screenshot comparison using pixelmatch. Compares two PNG images and produces a diff image highlighting changed pixels.
|
|
13
|
+
|
|
14
|
+
## Comparing two screenshots
|
|
15
|
+
|
|
16
|
+
Write and run a Node.js script:
|
|
17
|
+
|
|
18
|
+
```javascript
|
|
19
|
+
const fs = require('fs');
|
|
20
|
+
const { PNG } = require('pngjs');
|
|
21
|
+
const pixelmatch = require('pixelmatch');
|
|
22
|
+
|
|
23
|
+
const img1 = PNG.sync.read(fs.readFileSync('reference.png'));
|
|
24
|
+
const img2 = PNG.sync.read(fs.readFileSync('current.png'));
|
|
25
|
+
const { width, height } = img1;
|
|
26
|
+
const diff = new PNG({ width, height });
|
|
27
|
+
|
|
28
|
+
const mismatchedPixels = pixelmatch(
|
|
29
|
+
img1.data, img2.data, diff.data, width, height,
|
|
30
|
+
{ threshold: 0.1 }
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
fs.writeFileSync('diff.png', PNG.sync.write(diff));
|
|
34
|
+
|
|
35
|
+
const totalPixels = width * height;
|
|
36
|
+
const mismatchPercent = ((mismatchedPixels / totalPixels) * 100).toFixed(2);
|
|
37
|
+
console.log(`Mismatched pixels: ${mismatchedPixels} (${mismatchPercent}%)`);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Interpreting results
|
|
41
|
+
|
|
42
|
+
- **< 1% mismatch**: Pass — sub-pixel rendering differences, antialiasing
|
|
43
|
+
|
|
44
|
+
- **1–5% mismatch**: Review — may be intentional changes or minor regressions
|
|
45
|
+
- **> 5% mismatch**: Likely regression — investigate the diff image
|
|
46
|
+
|
|
47
|
+
## Creating reference images
|
|
48
|
+
|
|
49
|
+
Save a known-good screenshot as the reference. Store references alongside the test:
|
|
50
|
+
|
|
51
|
+
```text
|
|
52
|
+
tests/visual/
|
|
53
|
+
reference/
|
|
54
|
+
homepage-mobile.png
|
|
55
|
+
homepage-desktop.png
|
|
56
|
+
current/
|
|
57
|
+
homepage-mobile.png
|
|
58
|
+
homepage-desktop.png
|
|
59
|
+
diff/
|
|
60
|
+
homepage-mobile.png
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Gotchas
|
|
64
|
+
|
|
65
|
+
- Images must be the same dimensions. Resize first if viewports differ.
|
|
66
|
+
|
|
67
|
+
- Font rendering varies across OS — set threshold to 0.1 or higher to account for antialiasing.
|
|
68
|
+
- Dynamic content (timestamps, avatars) causes false positives. Mock or hide dynamic elements before capture.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type ShapeDefinition = {
|
|
2
|
+
name: string;
|
|
3
|
+
keywords: string[];
|
|
4
|
+
reviewerContext: string;
|
|
5
|
+
};
|
|
6
|
+
export declare function loadShapeDefinitions(): ShapeDefinition[];
|
|
7
|
+
export declare function detectShapes(text: string, definitions: ShapeDefinition[]): ShapeDefinition[];
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,87 @@
|
|
|
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.loadShapeDefinitions = loadShapeDefinitions;
|
|
37
|
+
exports.detectShapes = detectShapes;
|
|
38
|
+
const fs = __importStar(require("node:fs"));
|
|
39
|
+
const path = __importStar(require("node:path"));
|
|
40
|
+
function resolveShapesDir() {
|
|
41
|
+
const candidates = [
|
|
42
|
+
path.join(__dirname),
|
|
43
|
+
path.join(__dirname, "..", "shapes"),
|
|
44
|
+
path.join(__dirname, "..", "..", "src", "shapes"),
|
|
45
|
+
];
|
|
46
|
+
for (const candidate of candidates) {
|
|
47
|
+
try {
|
|
48
|
+
const entries = fs.readdirSync(candidate);
|
|
49
|
+
const hasJson = entries.some(f => f.endsWith(".json"));
|
|
50
|
+
if (hasJson)
|
|
51
|
+
return candidate;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
// directory doesn't exist or can't be read — try next
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
function loadShapeDefinitions() {
|
|
60
|
+
const dir = resolveShapesDir();
|
|
61
|
+
if (dir === null)
|
|
62
|
+
return [];
|
|
63
|
+
const entries = fs.readdirSync(dir);
|
|
64
|
+
const jsonFiles = entries.filter(f => f.endsWith(".json"));
|
|
65
|
+
const definitions = [];
|
|
66
|
+
for (const file of jsonFiles) {
|
|
67
|
+
try {
|
|
68
|
+
const raw = fs.readFileSync(path.join(dir, file), "utf-8");
|
|
69
|
+
const parsed = JSON.parse(raw);
|
|
70
|
+
if (typeof parsed.name === "string" &&
|
|
71
|
+
Array.isArray(parsed.keywords)) {
|
|
72
|
+
definitions.push(parsed);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// malformed JSON or unreadable file — skip
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return definitions;
|
|
80
|
+
}
|
|
81
|
+
function detectShapes(text, definitions) {
|
|
82
|
+
if (!text || definitions.length === 0)
|
|
83
|
+
return [];
|
|
84
|
+
const lower = text.toLowerCase();
|
|
85
|
+
return definitions.filter(def => def.keywords.some(keyword => lower.includes(keyword.toLowerCase())));
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/shapes/detect.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,oDAyBC;AAED,oCAQC;AAhED,4CAA6B;AAC7B,gDAAiC;AAQjC,SAAS,gBAAgB;IACvB,MAAM,UAAU,GAAG;QACjB,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,CAAC;KAClD,CAAA;IAED,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,CAAa,CAAA;YACrD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;YACtD,IAAI,OAAO;gBAAE,OAAO,SAAS,CAAA;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,sDAAsD;QACxD,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,SAAgB,oBAAoB;IAClC,MAAM,GAAG,GAAG,gBAAgB,EAAE,CAAA;IAC9B,IAAI,GAAG,KAAK,IAAI;QAAE,OAAO,EAAE,CAAA;IAE3B,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAa,CAAA;IAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;IAE1D,MAAM,WAAW,GAAsB,EAAE,CAAA;IAEzC,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,OAAO,CAAW,CAAA;YACpE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC9B,IACE,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ;gBAC/B,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAC9B,CAAC;gBACD,WAAW,CAAC,IAAI,CAAC,MAAyB,CAAC,CAAA;YAC7C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,2CAA2C;QAC7C,CAAC;IACH,CAAC;IAED,OAAO,WAAW,CAAA;AACpB,CAAC;AAED,SAAgB,YAAY,CAAC,IAAY,EAAE,WAA8B;IACvE,IAAI,CAAC,IAAI,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IAEhD,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAA;IAEhC,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAC9B,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CACpE,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "game-visual",
|
|
3
|
+
"keywords": [
|
|
4
|
+
"game", "sprite", "texture", "3D", "scene", "canvas",
|
|
5
|
+
"WebGL", "Godot", "Unity", "Phaser"
|
|
6
|
+
],
|
|
7
|
+
"reviewerContext": "Verify asset dimensions match specification. Check color palette consistency. Validate sprite sheet layouts. Evaluate UI overlay legibility against game backgrounds."
|
|
8
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "print-layout",
|
|
3
|
+
"keywords": [
|
|
4
|
+
"print", "PDF", "document", "brochure", "typography",
|
|
5
|
+
"poster", "flyer", "report"
|
|
6
|
+
],
|
|
7
|
+
"reviewerContext": "Verify bleed and trim areas. Check font embedding. Validate resolution meets print DPI requirements. Evaluate typographic hierarchy and spacing consistency."
|
|
8
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "web-visual",
|
|
3
|
+
"keywords": [
|
|
4
|
+
"UI", "frontend", "CSS", "responsive", "web app", "dashboard",
|
|
5
|
+
"website", "landing page", "SPA", "component library", "design system",
|
|
6
|
+
"Tailwind", "React", "Vue", "Svelte"
|
|
7
|
+
],
|
|
8
|
+
"reviewerContext": "Check responsive behavior at mobile/tablet/desktop viewports. Verify interactive states. Evaluate whitespace and visual breathing room. Check color contrast ratios."
|
|
9
|
+
}
|
package/dist/stores/budget.js
CHANGED
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.getTotalCost = exports.recordCost = exports.saveBudget = exports.loadBudget = void 0;
|
|
37
37
|
const fs = __importStar(require("node:fs"));
|
|
38
38
|
const path = __importStar(require("node:path"));
|
|
39
|
+
const atomic_write_1 = require("../utils/atomic-write");
|
|
39
40
|
const budgetPath = (buildDir) => path.join(buildDir, "budget.json");
|
|
40
41
|
const loadBudget = (buildDir) => {
|
|
41
42
|
const fp = budgetPath(buildDir);
|
|
@@ -46,7 +47,7 @@ const loadBudget = (buildDir) => {
|
|
|
46
47
|
};
|
|
47
48
|
exports.loadBudget = loadBudget;
|
|
48
49
|
const saveBudget = (buildDir, budget) => {
|
|
49
|
-
|
|
50
|
+
(0, atomic_write_1.atomicWriteSync)(budgetPath(buildDir), JSON.stringify(budget, null, 2) + "\n");
|
|
50
51
|
};
|
|
51
52
|
exports.saveBudget = saveBudget;
|
|
52
53
|
const recordCost = (buildDir, phase, role, attempt, result) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/stores/budget.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA6B;AAC7B,gDAAiC;
|
|
1
|
+
{"version":3,"file":"budget.js","sourceRoot":"","sources":["../../src/stores/budget.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA6B;AAC7B,gDAAiC;AAEjC,wDAAuD;AAEvD,MAAM,UAAU,GAAG,CAAC,QAAgB,EAAU,EAAE,CAC9C,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAA;AAE7B,MAAM,UAAU,GAAG,CAAC,QAAgB,EAAe,EAAE;IAC1D,MAAM,EAAE,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAA;IAC/B,IAAI,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAA;IACjD,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC,EAAE,CAAA;AACzC,CAAC,CAAA;AANY,QAAA,UAAU,cAMtB;AAEM,MAAM,UAAU,GAAG,CAAC,QAAgB,EAAE,MAAmB,EAAQ,EAAE;IACxE,IAAA,8BAAe,EAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;AAC/E,CAAC,CAAA;AAFY,QAAA,UAAU,cAEtB;AAEM,MAAM,UAAU,GAAG,CACxB,QAAgB,EAChB,KAAa,EACb,IAAyB,EACzB,OAAe,EACf,MAAoB,EACP,EAAE;IACf,MAAM,MAAM,GAAG,IAAA,kBAAU,EAAC,QAAQ,CAAC,CAAA;IACnC,MAAM,KAAK,GAAgB;QACzB,KAAK;QACL,IAAI;QACJ,OAAO;QACP,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,WAAW,EAAE,MAAM,CAAC,KAAK,CAAC,WAAW;QACrC,YAAY,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY;QACvC,oBAAoB,EAAE,MAAM,CAAC,KAAK,CAAC,oBAAoB;QACvD,wBAAwB,EAAE,MAAM,CAAC,KAAK,CAAC,wBAAwB;QAC/D,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAA;IACD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC1B,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IAC3E,IAAA,kBAAU,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;IAC5B,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAxBY,QAAA,UAAU,cAwBtB;AAEM,MAAM,YAAY,GAAG,CAAC,QAAgB,EAAU,EAAE,CACvD,IAAA,kBAAU,EAAC,QAAQ,CAAC,CAAC,YAAY,CAAA;AADtB,QAAA,YAAY,gBACU"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateFeedback = exports.formatIssue = void 0;
|
|
4
|
+
// Format a ReviewIssue for display
|
|
5
|
+
const formatIssue = (issue) => {
|
|
6
|
+
const parts = [];
|
|
7
|
+
if (issue.file)
|
|
8
|
+
parts.push(issue.file);
|
|
9
|
+
parts.push(issue.description);
|
|
10
|
+
return parts.join(": ");
|
|
11
|
+
};
|
|
12
|
+
exports.formatIssue = formatIssue;
|
|
13
|
+
// Generate feedback markdown from a structured verdict
|
|
14
|
+
const generateFeedback = (phaseId, verdict) => {
|
|
15
|
+
const lines = [];
|
|
16
|
+
lines.push(`# Reviewer Feedback: Phase ${phaseId}`);
|
|
17
|
+
lines.push("");
|
|
18
|
+
// Failed criteria
|
|
19
|
+
const failed = verdict.criteriaResults.filter((cr) => !cr.passed);
|
|
20
|
+
if (failed.length > 0) {
|
|
21
|
+
lines.push("## Failed Criteria");
|
|
22
|
+
lines.push("");
|
|
23
|
+
for (const cr of failed) {
|
|
24
|
+
lines.push(`### Criterion ${cr.criterion}`);
|
|
25
|
+
lines.push(`**Status:** FAIL`);
|
|
26
|
+
lines.push(`**Evidence:** ${cr.notes}`);
|
|
27
|
+
// Find matching issue with requiredState
|
|
28
|
+
const matchingIssue = verdict.issues.find((i) => i.criterion === cr.criterion);
|
|
29
|
+
if (matchingIssue?.requiredState) {
|
|
30
|
+
lines.push(`**Required state:** ${matchingIssue.requiredState}`);
|
|
31
|
+
}
|
|
32
|
+
lines.push("");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
// Blocking issues
|
|
36
|
+
const blocking = verdict.issues.filter((i) => i.severity === "blocking");
|
|
37
|
+
if (blocking.length > 0) {
|
|
38
|
+
lines.push("## Issues");
|
|
39
|
+
lines.push("");
|
|
40
|
+
for (const issue of blocking) {
|
|
41
|
+
const filePart = issue.file ? ` (${issue.file})` : "";
|
|
42
|
+
lines.push(`- ${issue.description}${filePart}`);
|
|
43
|
+
if (issue.requiredState) {
|
|
44
|
+
lines.push(` - **Required:** ${issue.requiredState}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
lines.push("");
|
|
48
|
+
}
|
|
49
|
+
// What passed
|
|
50
|
+
const passed = verdict.criteriaResults.filter((cr) => cr.passed);
|
|
51
|
+
if (passed.length > 0) {
|
|
52
|
+
lines.push("## What Passed");
|
|
53
|
+
lines.push("");
|
|
54
|
+
for (const cr of passed) {
|
|
55
|
+
lines.push(`- Criterion ${cr.criterion}: ${cr.notes}`);
|
|
56
|
+
}
|
|
57
|
+
lines.push("");
|
|
58
|
+
}
|
|
59
|
+
return lines.join("\n");
|
|
60
|
+
};
|
|
61
|
+
exports.generateFeedback = generateFeedback;
|
|
62
|
+
//# sourceMappingURL=feedback.format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.format.js","sourceRoot":"","sources":["../../src/stores/feedback.format.ts"],"names":[],"mappings":";;;AAEA,mCAAmC;AAC5B,MAAM,WAAW,GAAG,CAAC,KAAkB,EAAU,EAAE;IACxD,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,IAAI,KAAK,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACtC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;IAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC,CAAA;AALY,QAAA,WAAW,eAKvB;AAED,uDAAuD;AAChD,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAE,OAAsB,EAAU,EAAE;IAClF,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,KAAK,CAAC,IAAI,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAA;IACnD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAEd,kBAAkB;IAClB,MAAM,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAA;IACjE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAA;QAChC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,SAAS,EAAE,CAAC,CAAA;YAC3C,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;YAC9B,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,KAAK,EAAE,CAAC,CAAA;YACvC,yCAAyC;YACzC,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,EAAE,CAAC,SAAS,CAAC,CAAA;YAC9E,IAAI,aAAa,EAAE,aAAa,EAAE,CAAC;gBACjC,KAAK,CAAC,IAAI,CAAC,uBAAuB,aAAa,CAAC,aAAa,EAAE,CAAC,CAAA;YAClE,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QAChB,CAAC;IACH,CAAC;IAED,kBAAkB;IAClB,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAA;IACxE,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QACvB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;YACrD,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,WAAW,GAAG,QAAQ,EAAE,CAAC,CAAA;YAC/C,IAAI,KAAK,CAAC,aAAa,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC,qBAAqB,KAAK,CAAC,aAAa,EAAE,CAAC,CAAA;YACxD,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAChB,CAAC;IAED,cAAc;IACd,MAAM,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,CAAA;IAChE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAA;QAC5B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACd,KAAK,MAAM,EAAE,IAAI,MAAM,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,SAAS,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,CAAA;QACxD,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IAChB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC,CAAA;AAnDY,QAAA,gBAAgB,oBAmD5B"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseVerdict = void 0;
|
|
4
|
+
// Normalize an issue entry — accept both string and object forms
|
|
5
|
+
const normalizeIssue = (item, severity) => {
|
|
6
|
+
if (typeof item === "string") {
|
|
7
|
+
return { description: item, severity };
|
|
8
|
+
}
|
|
9
|
+
if (typeof item === "object" && item !== null) {
|
|
10
|
+
const obj = item;
|
|
11
|
+
return {
|
|
12
|
+
criterion: typeof obj.criterion === "number" ? obj.criterion : undefined,
|
|
13
|
+
description: typeof obj.description === "string" ? obj.description : String(obj.description ?? ""),
|
|
14
|
+
file: typeof obj.file === "string" ? obj.file : undefined,
|
|
15
|
+
severity,
|
|
16
|
+
requiredState: typeof obj.requiredState === "string" ? obj.requiredState : undefined,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return { description: String(item), severity };
|
|
20
|
+
};
|
|
21
|
+
// Try to parse a raw object as a ReviewVerdict
|
|
22
|
+
const tryParseVerdict = (raw) => {
|
|
23
|
+
if (typeof raw !== "object" || raw === null)
|
|
24
|
+
return null;
|
|
25
|
+
const obj = raw;
|
|
26
|
+
if (typeof obj.passed !== "boolean")
|
|
27
|
+
return null;
|
|
28
|
+
return {
|
|
29
|
+
passed: obj.passed,
|
|
30
|
+
summary: typeof obj.summary === "string" ? obj.summary : "",
|
|
31
|
+
criteriaResults: Array.isArray(obj.criteriaResults)
|
|
32
|
+
? obj.criteriaResults.map((cr) => ({
|
|
33
|
+
criterion: typeof cr.criterion === "number" ? cr.criterion : 0,
|
|
34
|
+
passed: typeof cr.passed === "boolean" ? cr.passed : false,
|
|
35
|
+
notes: typeof cr.notes === "string" ? cr.notes : "",
|
|
36
|
+
}))
|
|
37
|
+
: [],
|
|
38
|
+
issues: Array.isArray(obj.issues)
|
|
39
|
+
? obj.issues.map((i) => normalizeIssue(i, "blocking"))
|
|
40
|
+
: [],
|
|
41
|
+
suggestions: Array.isArray(obj.suggestions)
|
|
42
|
+
? obj.suggestions.map((s) => normalizeIssue(s, "suggestion"))
|
|
43
|
+
: [],
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
// Find the end index of a balanced JSON object starting at position 0 in `text`.
|
|
47
|
+
// Returns the index of the closing brace, or -1 if no balanced pair is found.
|
|
48
|
+
const findBalancedBrace = (text) => {
|
|
49
|
+
let depth = 0;
|
|
50
|
+
let inString = false;
|
|
51
|
+
let escape = false;
|
|
52
|
+
for (let j = 0; j < text.length; j++) {
|
|
53
|
+
const ch = text[j];
|
|
54
|
+
if (escape) {
|
|
55
|
+
escape = false;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (ch === "\\") {
|
|
59
|
+
escape = true;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (ch === '"') {
|
|
63
|
+
inString = !inString;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (inString)
|
|
67
|
+
continue;
|
|
68
|
+
if (ch === "{")
|
|
69
|
+
depth++;
|
|
70
|
+
if (ch === "}") {
|
|
71
|
+
depth--;
|
|
72
|
+
if (depth === 0)
|
|
73
|
+
return j;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return -1;
|
|
77
|
+
};
|
|
78
|
+
// Try to parse a JSON object starting at `text` as a ReviewVerdict.
|
|
79
|
+
// First tries the full slice, then tries balanced brace extraction.
|
|
80
|
+
const tryExtractVerdictAt = (text) => {
|
|
81
|
+
try {
|
|
82
|
+
return tryParseVerdict(JSON.parse(text));
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
const end = findBalancedBrace(text);
|
|
86
|
+
if (end === -1)
|
|
87
|
+
return null;
|
|
88
|
+
try {
|
|
89
|
+
return tryParseVerdict(JSON.parse(text.slice(0, end + 1)));
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const UNPARSEABLE_VERDICT = {
|
|
97
|
+
passed: false,
|
|
98
|
+
summary: "Could not parse reviewer verdict from output",
|
|
99
|
+
criteriaResults: [],
|
|
100
|
+
issues: [{ description: "Reviewer output did not contain a valid JSON verdict", severity: "blocking" }],
|
|
101
|
+
suggestions: [],
|
|
102
|
+
};
|
|
103
|
+
// Extract the JSON verdict block from reviewer's text output
|
|
104
|
+
const parseVerdict = (text) => {
|
|
105
|
+
// Try extracting from fenced code block first
|
|
106
|
+
const fencedMatch = text.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
|
|
107
|
+
if (fencedMatch) {
|
|
108
|
+
const result = tryExtractVerdictAt(fencedMatch[1]);
|
|
109
|
+
if (result)
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
// Scan every { and try to parse a verdict from that position
|
|
113
|
+
for (let i = text.indexOf("{"); i !== -1; i = text.indexOf("{", i + 1)) {
|
|
114
|
+
const result = tryExtractVerdictAt(text.slice(i));
|
|
115
|
+
if (result)
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
return UNPARSEABLE_VERDICT;
|
|
119
|
+
};
|
|
120
|
+
exports.parseVerdict = parseVerdict;
|
|
121
|
+
//# sourceMappingURL=feedback.parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.parse.js","sourceRoot":"","sources":["../../src/stores/feedback.parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export declare const formatIssue: (issue: ReviewIssue) => string;
|
|
4
|
-
export declare const generateFeedback: (phaseId: string, verdict: ReviewVerdict) => string;
|
|
1
|
+
export { parseVerdict } from "./feedback.parse";
|
|
2
|
+
export { formatIssue, generateFeedback } from "./feedback.format";
|