howone 0.1.50 → 0.1.52
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/package.json +1 -1
- package/templates/vite/.howone/skills/howone/03-ai-capabilities/01-ai-capability-architecture.md +16 -2
- package/templates/vite/.howone/skills/howone/03-ai-capabilities/02-workflow-contract-rules.md +107 -0
- package/templates/vite/.howone/skills/howone/03-ai-capabilities/03-service-capability-catalog.md +98 -22
- package/templates/vite/.howone/skills/howone/03-ai-capabilities/04-workflow-operations.md +8 -0
- package/templates/vite/.howone/skills/howone/03-ai-capabilities/05-ai-feature-playbooks.md +66 -1
- package/templates/vite/.howone/skills/web-clone/LICENSE +0 -21
- package/templates/vite/.howone/skills/web-clone/README.md +0 -179
- package/templates/vite/.howone/skills/web-clone/SKILL.md +0 -243
- package/templates/vite/.howone/skills/web-clone/references/assessment.md +0 -77
- package/templates/vite/.howone/skills/web-clone/references/complex-playbooks.md +0 -46
- package/templates/vite/.howone/skills/web-clone/references/deliverables.md +0 -144
- package/templates/vite/.howone/skills/web-clone/references/design-dna.md +0 -125
- package/templates/vite/.howone/skills/web-clone/references/effect-extraction.md +0 -73
- package/templates/vite/.howone/skills/web-clone/references/marbles-case.md +0 -31
- package/templates/vite/.howone/skills/web-clone/references/reverse-engineering.md +0 -34
- package/templates/vite/.howone/skills/web-clone/references/static-mirror.md +0 -72
- package/templates/vite/.howone/skills/web-clone/scripts/asset-harvest.mjs +0 -101
- package/templates/vite/.howone/skills/web-clone/scripts/audit-clone.mjs +0 -151
- package/templates/vite/.howone/skills/web-clone/scripts/compare-recon.mjs +0 -265
- package/templates/vite/.howone/skills/web-clone/scripts/dna-scaffold.mjs +0 -214
- package/templates/vite/.howone/skills/web-clone/scripts/init-clone.mjs +0 -136
- package/templates/vite/.howone/skills/web-clone/scripts/interaction-probe.mjs +0 -314
- package/templates/vite/.howone/skills/web-clone/scripts/lib/playwright-loader.mjs +0 -39
- package/templates/vite/.howone/skills/web-clone/scripts/mirror-site.mjs +0 -121
- package/templates/vite/.howone/skills/web-clone/scripts/network-capture.mjs +0 -127
- package/templates/vite/.howone/skills/web-clone/scripts/recon-site.mjs +0 -235
- package/templates/vite/.howone/skills/web-clone/scripts/route-crawl.mjs +0 -228
- package/templates/vite/.howone/skills/web-clone/scripts/sourcemap-hunt.mjs +0 -112
- package/templates/vite/.howone/skills/web-clone/scripts/visual-diff.mjs +0 -161
- package/templates/vite/.howone/skills/web-shader-extractor/SKILL.md +0 -123
- package/templates/vite/.howone/skills/web-shader-extractor/references/capture-backends.md +0 -201
- package/templates/vite/.howone/skills/web-shader-extractor/references/evidence-policy.md +0 -93
- package/templates/vite/.howone/skills/web-shader-extractor/references/operating-contract.md +0 -82
- package/templates/vite/.howone/skills/web-shader-extractor/references/qa-failure-policy.md +0 -100
- package/templates/vite/.howone/skills/web-shader-extractor/references/recon-kernel.md +0 -206
- package/templates/vite/.howone/skills/web-shader-extractor/references/replay-policy.md +0 -145
- package/templates/vite/.howone/skills/web-shader-extractor/references/shaders-com.md +0 -212
- package/templates/vite/.howone/skills/web-shader-extractor/references/source-analysis.md +0 -112
- package/templates/vite/.howone/skills/web-shader-extractor/references/surface-discovery.md +0 -113
- package/templates/vite/.howone/skills/web-shader-extractor/references/target-lock.md +0 -205
- package/templates/vite/.howone/skills/web-shader-extractor/references/three-shader-reconstruction.md +0 -155
- package/templates/vite/.howone/skills/web-shader-extractor/references/tool-capability-matrix.md +0 -57
- package/templates/vite/.howone/skills/web-shader-extractor/references/unicorn-studio.md +0 -387
- package/templates/vite/.howone/skills/web-shader-extractor/scripts/fetch-rendered-dom.mjs +0 -178
- package/templates/vite/.howone/skills/web-shader-extractor/scripts/scan-bundle.sh +0 -80
- package/templates/vite/.howone/skills/web-shader-extractor/templates/extraction-report.md +0 -41
- package/templates/vite/.howone/skills/web-shader-extractor/templates/known-gaps.md +0 -14
- package/templates/vite/.howone/skills/web-shader-extractor/templates/qa-report.md +0 -74
- package/templates/vite/.howone/skills/web-shader-extractor/templates/replay-manifest.json +0 -147
- package/templates/vite/.howone/skills/web-shader-extractor/templates/run-state.json +0 -75
- package/templates/vite/.howone/skills/web-shader-extractor/templates/scout-card.json +0 -106
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { loadPlaywright, launchChromium } from "./lib/playwright-loader.mjs";
|
|
5
|
-
|
|
6
|
-
function usage() {
|
|
7
|
-
console.log(`Usage:
|
|
8
|
-
node scripts/visual-diff.mjs --original <png> --clone <png> --out visual-diff.json [--diff visual-diff.png] [--threshold 0.08]
|
|
9
|
-
|
|
10
|
-
Compares screenshots in a real browser canvas and outputs numeric visual-diff metrics.
|
|
11
|
-
`);
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function parseArgs(argv) {
|
|
15
|
-
const out = { original: "", clone: "", out: "visual-diff.json", diff: "", threshold: 0.08 };
|
|
16
|
-
for (let i = 0; i < argv.length; i += 1) {
|
|
17
|
-
const arg = argv[i];
|
|
18
|
-
if (arg === "--help" || arg === "-h") out.help = true;
|
|
19
|
-
else if (arg === "--original") out.original = argv[++i] || "";
|
|
20
|
-
else if (arg === "--clone") out.clone = argv[++i] || "";
|
|
21
|
-
else if (arg === "--out") out.out = argv[++i] || "visual-diff.json";
|
|
22
|
-
else if (arg === "--diff") out.diff = argv[++i] || "";
|
|
23
|
-
else if (arg === "--threshold") out.threshold = Number(argv[++i] || "0.08");
|
|
24
|
-
else throw new Error(`Unexpected argument: ${arg}`);
|
|
25
|
-
}
|
|
26
|
-
return out;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function imageDataUrl(file) {
|
|
30
|
-
const ext = path.extname(file).slice(1).toLowerCase() || "png";
|
|
31
|
-
const mime = ext === "jpg" || ext === "jpeg" ? "image/jpeg" : "image/png";
|
|
32
|
-
return `data:${mime};base64,${fs.readFileSync(file).toString("base64")}`;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function scoreFromDiff(diffRatio, meanAbsDiff) {
|
|
36
|
-
if (diffRatio <= 0.01 && meanAbsDiff <= 0.01) return 5;
|
|
37
|
-
if (diffRatio <= 0.04 && meanAbsDiff <= 0.025) return 4.5;
|
|
38
|
-
if (diffRatio <= 0.08 && meanAbsDiff <= 0.05) return 4;
|
|
39
|
-
if (diffRatio <= 0.16 && meanAbsDiff <= 0.08) return 3;
|
|
40
|
-
if (diffRatio <= 0.3 && meanAbsDiff <= 0.14) return 2;
|
|
41
|
-
return 1;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async function compareInBrowser(page, original, clone, threshold) {
|
|
45
|
-
return page.evaluate(async ({ original, clone, threshold }) => {
|
|
46
|
-
const loadImage = (src) => new Promise((resolve, reject) => {
|
|
47
|
-
const image = new Image();
|
|
48
|
-
image.onload = () => resolve(image);
|
|
49
|
-
image.onerror = () => reject(new Error(`Failed to load image: ${src.slice(0, 80)}`));
|
|
50
|
-
image.src = src;
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
const [left, right] = await Promise.all([loadImage(original), loadImage(clone)]);
|
|
54
|
-
const width = Math.max(left.naturalWidth, right.naturalWidth);
|
|
55
|
-
const height = Math.max(left.naturalHeight, right.naturalHeight);
|
|
56
|
-
|
|
57
|
-
const canvasA = document.createElement("canvas");
|
|
58
|
-
const canvasB = document.createElement("canvas");
|
|
59
|
-
const canvasD = document.createElement("canvas");
|
|
60
|
-
for (const canvas of [canvasA, canvasB, canvasD]) {
|
|
61
|
-
canvas.width = width;
|
|
62
|
-
canvas.height = height;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const ctxA = canvasA.getContext("2d");
|
|
66
|
-
const ctxB = canvasB.getContext("2d");
|
|
67
|
-
const ctxD = canvasD.getContext("2d");
|
|
68
|
-
ctxA.fillStyle = "white";
|
|
69
|
-
ctxB.fillStyle = "white";
|
|
70
|
-
ctxA.fillRect(0, 0, width, height);
|
|
71
|
-
ctxB.fillRect(0, 0, width, height);
|
|
72
|
-
ctxA.drawImage(left, 0, 0);
|
|
73
|
-
ctxB.drawImage(right, 0, 0);
|
|
74
|
-
|
|
75
|
-
const a = ctxA.getImageData(0, 0, width, height);
|
|
76
|
-
const b = ctxB.getImageData(0, 0, width, height);
|
|
77
|
-
const d = ctxD.createImageData(width, height);
|
|
78
|
-
let changed = 0;
|
|
79
|
-
let sumAbs = 0;
|
|
80
|
-
let sumSq = 0;
|
|
81
|
-
|
|
82
|
-
for (let i = 0; i < a.data.length; i += 4) {
|
|
83
|
-
const dr = Math.abs(a.data[i] - b.data[i]);
|
|
84
|
-
const dg = Math.abs(a.data[i + 1] - b.data[i + 1]);
|
|
85
|
-
const db = Math.abs(a.data[i + 2] - b.data[i + 2]);
|
|
86
|
-
const da = Math.abs(a.data[i + 3] - b.data[i + 3]);
|
|
87
|
-
const delta = (dr + dg + db + da) / 1020;
|
|
88
|
-
sumAbs += delta;
|
|
89
|
-
sumSq += delta * delta;
|
|
90
|
-
if (delta > threshold) changed += 1;
|
|
91
|
-
|
|
92
|
-
if (delta > threshold) {
|
|
93
|
-
d.data[i] = 255;
|
|
94
|
-
d.data[i + 1] = Math.max(0, 80 - delta * 80);
|
|
95
|
-
d.data[i + 2] = Math.max(0, 80 - delta * 80);
|
|
96
|
-
d.data[i + 3] = 255;
|
|
97
|
-
} else {
|
|
98
|
-
d.data[i] = Math.round(a.data[i] * 0.25 + 245 * 0.75);
|
|
99
|
-
d.data[i + 1] = Math.round(a.data[i + 1] * 0.25 + 245 * 0.75);
|
|
100
|
-
d.data[i + 2] = Math.round(a.data[i + 2] * 0.25 + 245 * 0.75);
|
|
101
|
-
d.data[i + 3] = 255;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
ctxD.putImageData(d, 0, 0);
|
|
106
|
-
const pixels = width * height;
|
|
107
|
-
const diffPixelRatio = changed / pixels;
|
|
108
|
-
const meanAbsDiff = sumAbs / pixels;
|
|
109
|
-
const rmse = Math.sqrt(sumSq / pixels);
|
|
110
|
-
|
|
111
|
-
return {
|
|
112
|
-
original: { width: left.naturalWidth, height: left.naturalHeight },
|
|
113
|
-
clone: { width: right.naturalWidth, height: right.naturalHeight },
|
|
114
|
-
comparedCanvas: { width, height },
|
|
115
|
-
threshold,
|
|
116
|
-
changedPixels: changed,
|
|
117
|
-
totalPixels: pixels,
|
|
118
|
-
diffPixelRatio,
|
|
119
|
-
meanAbsDiff,
|
|
120
|
-
rmse,
|
|
121
|
-
diffPngDataUrl: canvasD.toDataURL("image/png"),
|
|
122
|
-
};
|
|
123
|
-
}, { original, clone, threshold });
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
try {
|
|
127
|
-
const args = parseArgs(process.argv.slice(2));
|
|
128
|
-
if (args.help || !args.original || !args.clone) {
|
|
129
|
-
usage();
|
|
130
|
-
process.exit(args.help ? 0 : 1);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const { chromium } = loadPlaywright();
|
|
134
|
-
const browser = await launchChromium(chromium);
|
|
135
|
-
const page = await browser.newPage();
|
|
136
|
-
const result = await compareInBrowser(page, imageDataUrl(args.original), imageDataUrl(args.clone), args.threshold);
|
|
137
|
-
await browser.close();
|
|
138
|
-
|
|
139
|
-
const diffDataUrl = result.diffPngDataUrl;
|
|
140
|
-
delete result.diffPngDataUrl;
|
|
141
|
-
result.visualScore = scoreFromDiff(result.diffPixelRatio, result.meanAbsDiff);
|
|
142
|
-
result.files = {
|
|
143
|
-
original: path.resolve(args.original),
|
|
144
|
-
clone: path.resolve(args.clone),
|
|
145
|
-
diff: args.diff ? path.resolve(args.diff) : "",
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
fs.mkdirSync(path.dirname(path.resolve(args.out)), { recursive: true });
|
|
149
|
-
fs.writeFileSync(args.out, `${JSON.stringify(result, null, 2)}\n`);
|
|
150
|
-
|
|
151
|
-
if (args.diff) {
|
|
152
|
-
const base64 = diffDataUrl.replace(/^data:image\/png;base64,/, "");
|
|
153
|
-
fs.mkdirSync(path.dirname(path.resolve(args.diff)), { recursive: true });
|
|
154
|
-
fs.writeFileSync(args.diff, Buffer.from(base64, "base64"));
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
console.log(path.resolve(args.out));
|
|
158
|
-
} catch (error) {
|
|
159
|
-
console.error(`visual-diff failed: ${error.message}`);
|
|
160
|
-
process.exit(1);
|
|
161
|
-
}
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: web-shader-extractor
|
|
3
|
-
description: >
|
|
4
|
-
Use when a user gives or references a webpage URL and wants to extract,
|
|
5
|
-
reproduce, port, or locally replay a WebGL, WebGPU, Canvas, shader-like,
|
|
6
|
-
animated background, interactive 3D, or web visual effect. Locks the target
|
|
7
|
-
rendering surface group, records shader/resource/render graph/timing/input
|
|
8
|
-
evidence, builds an evidence-matched local baseline, then projectizes it.
|
|
9
|
-
Do not use for ordinary DOM/CSS page cloning.
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# Web Shader Extractor
|
|
13
|
-
|
|
14
|
-
Index for WebGL / WebGPU / Canvas rendering investigation and local replay.
|
|
15
|
-
Start from the target visual. Lock the surface group. Trace source or runtime facts. Build a runnable baseline. Then projectize.
|
|
16
|
-
|
|
17
|
-
## Router Contract
|
|
18
|
-
|
|
19
|
-
This file is the index. Do not treat it as the full operating manual. Before task action, read:
|
|
20
|
-
|
|
21
|
-
- `references/operating-contract.md`
|
|
22
|
-
- `references/recon-kernel.md`
|
|
23
|
-
|
|
24
|
-
Then load only the focused references needed by the current state.
|
|
25
|
-
Keep large evidence, captures, and generated outputs out of the conversation.
|
|
26
|
-
Store them in the user's output directory.
|
|
27
|
-
|
|
28
|
-
## Use This For
|
|
29
|
-
|
|
30
|
-
- Extracting a webpage WebGL, WebGPU, Canvas2D, OffscreenCanvas, shader, or animated canvas effect.
|
|
31
|
-
- Replaying an animated background, product shader, interactive WebGL scene, or Canvas visual locally.
|
|
32
|
-
- Building an evidence-matched baseline first, then an editable project.
|
|
33
|
-
- Investigating target-bound shader/render graph/timing/resource/input facts.
|
|
34
|
-
|
|
35
|
-
Do not use this for ordinary DOM/CSS cloning, static screenshots, generic website copying, unrelated JavaScript deobfuscation, or product UI redesign.
|
|
36
|
-
Use it only when the task has a shader/canvas target.
|
|
37
|
-
|
|
38
|
-
## Core Rules
|
|
39
|
-
|
|
40
|
-
- Target-bound before framework-bound: a global Three.js, platform, or shader signature is only a hypothesis until tied to the target surface group.
|
|
41
|
-
- Evidence before implementation: source, runtime objects, frame captures, source maps, and public structured definitions outrank visual fitting.
|
|
42
|
-
- Baseline before projectization: never overwrite a verified baseline for cleanup, simplification, or native conversion.
|
|
43
|
-
- Honest labels: implementation-critical facts are `SOURCE`, `PARTIAL`, or `GUESS`; unlabeled values are treated as `GUESS`.
|
|
44
|
-
- No compensation tuning: do not adjust brightness, time, color, offsets, or noise to mask missing pipeline evidence.
|
|
45
|
-
- Gate artifacts are transition guards: if the required artifact is missing, incomplete, or has placeholders in gate-critical fields, the state has not advanced.
|
|
46
|
-
- Ask only for product scope changes or external access/permission blockers.
|
|
47
|
-
- Use plain records: state the fact, evidence path, current unknown, and next action. Avoid metaphor, broad claims, and unsupported conclusions.
|
|
48
|
-
|
|
49
|
-
## State Router
|
|
50
|
-
|
|
51
|
-
Use the Recon Kernel state flow:
|
|
52
|
-
|
|
53
|
-
```text
|
|
54
|
-
INTAKE -> CAPABILITY_SNAPSHOT -> QUICK_SCOUT -> SURFACE_ATTRIBUTION
|
|
55
|
-
-> TARGET_LOCK_GATE
|
|
56
|
-
- provisional/failed -> REFINE_SCOUT
|
|
57
|
-
- attributed -> targeted owner/backend/source probe -> TARGET_LOCK_GATE
|
|
58
|
-
- locked -> SCOPE_CHECK
|
|
59
|
-
-> TRACE_ROUTE_SELECT -> SOURCE_TRACE -> CAPTURE_MINIMUM_TRUTH
|
|
60
|
-
-> REPLAY_READY_GATE
|
|
61
|
-
- not ready -> SOURCE_TRACE / CAPTURE_MINIMUM_TRUTH
|
|
62
|
-
- ready -> RAW_REPLAY
|
|
63
|
-
-> BASELINE_RUN -> BASELINE_VERIFY
|
|
64
|
-
-> BASELINE_VERIFIED -> PROJECTIZE -> PROJECT_VERIFY -> PACKAGE
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
`TARGET_LOCKED` must precede deep source/bundle work.
|
|
68
|
-
Before lock, only narrow source probes tied to `nextProbe` are allowed.
|
|
69
|
-
`REPLAY_READY` must precede implementation.
|
|
70
|
-
`BASELINE_VERIFIED` must precede projectization.
|
|
71
|
-
|
|
72
|
-
## Reference Router
|
|
73
|
-
|
|
74
|
-
Load only what the current state needs:
|
|
75
|
-
|
|
76
|
-
| Need | Read |
|
|
77
|
-
|---|---|
|
|
78
|
-
| Global contract, fact labels, completion states | `references/operating-contract.md` |
|
|
79
|
-
| Kernel, initial protocol, state flow, autonomy, budgets | `references/recon-kernel.md` |
|
|
80
|
-
| Surface discovery and visual attribution | `references/surface-discovery.md` |
|
|
81
|
-
| Lock criteria, target-bound evidence, scope, Three.js binding | `references/target-lock.md` |
|
|
82
|
-
| Evidence labels, ledgers, unknown classes, sensitive data | `references/evidence-policy.md` |
|
|
83
|
-
| Tool capability selection | `references/tool-capability-matrix.md` |
|
|
84
|
-
| WebGL, WebGPU, and Canvas2D capture facts | `references/capture-backends.md` |
|
|
85
|
-
| Source maps, bundle slices, config, encoded definitions | `references/source-analysis.md` |
|
|
86
|
-
| Replay readiness, routes, baseline, stack choice, projectization | `references/replay-policy.md` |
|
|
87
|
-
| QA, failure routing, severity, mismatch signatures | `references/qa-failure-policy.md` |
|
|
88
|
-
| Three.js shader injection or TSL reconstruction | `references/three-shader-reconstruction.md` |
|
|
89
|
-
| Unicorn Studio target | `references/unicorn-studio.md` |
|
|
90
|
-
| shaders.com / TSL target | `references/shaders-com.md` |
|
|
91
|
-
|
|
92
|
-
## Tool And Artifact Policy
|
|
93
|
-
|
|
94
|
-
Tools are replaceable capabilities, not prerequisites. First record the available capability profile:
|
|
95
|
-
|
|
96
|
-
```text
|
|
97
|
-
navigate, runtime-eval, preload-script, network-metadata, network-body,
|
|
98
|
-
source-map, canvas-screenshot, interaction, frame-capture-webgl,
|
|
99
|
-
frame-capture-webgpu, local-run, multi-frame-compare
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Use `scripts/fetch-rendered-dom.mjs` only as an optional inventory helper when Playwright is already available.
|
|
103
|
-
Use `scripts/scan-bundle.sh` only on target-bound bundle slices or a precise `nextProbe`.
|
|
104
|
-
Script output is hypothesis evidence. It never satisfies Surface Attribution, Target Lock, Replay Ready, or QA gates by itself.
|
|
105
|
-
|
|
106
|
-
Use bundled templates as schemas, not free-form notes:
|
|
107
|
-
|
|
108
|
-
- `templates/scout-card.json`
|
|
109
|
-
- `templates/replay-manifest.json`
|
|
110
|
-
- `templates/run-state.json`
|
|
111
|
-
- `templates/qa-report.md`
|
|
112
|
-
- `templates/known-gaps.md`
|
|
113
|
-
- `templates/extraction-report.md`
|
|
114
|
-
|
|
115
|
-
## Platform Adapters
|
|
116
|
-
|
|
117
|
-
Load platform references only after target-bound evidence points there:
|
|
118
|
-
|
|
119
|
-
- Unicorn Studio: `references/unicorn-studio.md`
|
|
120
|
-
- shaders.com / TSL: `references/shaders-com.md`
|
|
121
|
-
- Three.js shader injection or TSL: `references/three-shader-reconstruction.md`
|
|
122
|
-
|
|
123
|
-
If no adapter fits, follow generic WebGL, WebGPU, or Canvas2D capture in `references/capture-backends.md`.
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
# Capture Backends
|
|
2
|
-
|
|
3
|
-
Use after `TARGET_LOCKED`, or as a selected tactical probe while moving from `attributed` to `locked`. Capture only facts bound to the target surface group.
|
|
4
|
-
|
|
5
|
-
## Common Rules
|
|
6
|
-
|
|
7
|
-
- Prefer public source/config or runtime objects when they are target-bound.
|
|
8
|
-
- Use preload hooks or frame capture when source does not expose the render graph.
|
|
9
|
-
- Use bundle slices only when they resolve a named unknown.
|
|
10
|
-
- Keep backend facts separate from replay implementation choices.
|
|
11
|
-
- Record every hook result as evidence. Hook hits prove only that an API was used; they do not prove the target uses that API until tied to the target surface group, owner, frame, or call path.
|
|
12
|
-
|
|
13
|
-
## WebGL / WebGL2
|
|
14
|
-
|
|
15
|
-
Capture:
|
|
16
|
-
|
|
17
|
-
- surface CSS size, backing size, DPR, and context attributes
|
|
18
|
-
- vertex/fragment source or trusted source representation
|
|
19
|
-
- attributes, buffers, indices, instancing, or fullscreen primitive
|
|
20
|
-
- textures, samplers, formats, dimensions, and asset paths
|
|
21
|
-
- pass order, FBOs, attachments, inputs, and outputs
|
|
22
|
-
- viewport, scissor, clear, blend, depth, stencil, cull, alpha
|
|
23
|
-
- time origin/unit/delta, random, uniform updates, pointer, scroll, resize
|
|
24
|
-
- color space, tone mapping, premultiplied alpha, and DOM composite
|
|
25
|
-
|
|
26
|
-
Common failure cases:
|
|
27
|
-
|
|
28
|
-
- WebGL1 vs WebGL2 shader syntax
|
|
29
|
-
- framebuffer orientation and texture coordinate flips
|
|
30
|
-
- premultiplied alpha mismatch
|
|
31
|
-
- renderer output color space vs shader internal color space
|
|
32
|
-
- time measured in seconds, frames, or platform-specific increments
|
|
33
|
-
- hidden parent DOM transforms changing canvas coordinates
|
|
34
|
-
|
|
35
|
-
### WebGL Preload Hook Map
|
|
36
|
-
|
|
37
|
-
Use this map when source or runtime objects do not expose enough facts. Hook only the minimum API set needed for the current unknown.
|
|
38
|
-
|
|
39
|
-
Surface and owner:
|
|
40
|
-
|
|
41
|
-
- `HTMLCanvasElement.prototype.getContext`
|
|
42
|
-
- `OffscreenCanvas.prototype.getContext`
|
|
43
|
-
- `HTMLCanvasElement.prototype.transferControlToOffscreen`
|
|
44
|
-
|
|
45
|
-
Program and shader:
|
|
46
|
-
|
|
47
|
-
- `createShader`
|
|
48
|
-
- `shaderSource`
|
|
49
|
-
- `compileShader`
|
|
50
|
-
- `getShaderInfoLog`
|
|
51
|
-
- `createProgram`
|
|
52
|
-
- `attachShader`
|
|
53
|
-
- `linkProgram`
|
|
54
|
-
- `getProgramInfoLog`
|
|
55
|
-
- `useProgram`
|
|
56
|
-
|
|
57
|
-
Uniforms:
|
|
58
|
-
|
|
59
|
-
- `getUniformLocation`
|
|
60
|
-
- `uniform1f` / `uniform2f` / `uniform3f` / `uniform4f`
|
|
61
|
-
- `uniform1i` / `uniform2i` / `uniform3i` / `uniform4i`
|
|
62
|
-
- `uniformMatrix*`
|
|
63
|
-
|
|
64
|
-
Geometry:
|
|
65
|
-
|
|
66
|
-
- `createBuffer`
|
|
67
|
-
- `bindBuffer`
|
|
68
|
-
- `bufferData`
|
|
69
|
-
- `bufferSubData`
|
|
70
|
-
- `vertexAttribPointer`
|
|
71
|
-
- `enableVertexAttribArray`
|
|
72
|
-
- `bindVertexArray`
|
|
73
|
-
|
|
74
|
-
Textures:
|
|
75
|
-
|
|
76
|
-
- `createTexture`
|
|
77
|
-
- `bindTexture`
|
|
78
|
-
- `texImage2D`
|
|
79
|
-
- `texSubImage2D`
|
|
80
|
-
- `texParameteri`
|
|
81
|
-
- `activeTexture`
|
|
82
|
-
- `pixelStorei`
|
|
83
|
-
|
|
84
|
-
Framebuffers:
|
|
85
|
-
|
|
86
|
-
- `createFramebuffer`
|
|
87
|
-
- `bindFramebuffer`
|
|
88
|
-
- `framebufferTexture2D`
|
|
89
|
-
- `createRenderbuffer`
|
|
90
|
-
- `bindRenderbuffer`
|
|
91
|
-
- `framebufferRenderbuffer`
|
|
92
|
-
|
|
93
|
-
State:
|
|
94
|
-
|
|
95
|
-
- `viewport`
|
|
96
|
-
- `scissor`
|
|
97
|
-
- `clearColor`
|
|
98
|
-
- `clear`
|
|
99
|
-
- `enable` / `disable`
|
|
100
|
-
- `blendFunc` / `blendFuncSeparate`
|
|
101
|
-
- `blendEquation`
|
|
102
|
-
- `depthFunc`
|
|
103
|
-
- `cullFace`
|
|
104
|
-
- `colorMask`
|
|
105
|
-
- `depthMask`
|
|
106
|
-
|
|
107
|
-
Draw:
|
|
108
|
-
|
|
109
|
-
- `drawArrays`
|
|
110
|
-
- `drawElements`
|
|
111
|
-
- `drawArraysInstanced`
|
|
112
|
-
- `drawElementsInstanced`
|
|
113
|
-
|
|
114
|
-
## WebGPU
|
|
115
|
-
|
|
116
|
-
WebGPU targets do not pass through `gl.shaderSource()`. Treat them as a separate backend.
|
|
117
|
-
|
|
118
|
-
Capture:
|
|
119
|
-
|
|
120
|
-
- canvas configuration and preferred format
|
|
121
|
-
- shader modules or trusted node/source definitions
|
|
122
|
-
- render and compute pipeline descriptors
|
|
123
|
-
- bind group layouts and bind groups
|
|
124
|
-
- buffers, textures, samplers, and update cadence
|
|
125
|
-
- render pass and compute pass order
|
|
126
|
-
- command submission sequence
|
|
127
|
-
- time, pointer, scroll, resize, random
|
|
128
|
-
- output color, alpha, and canvas/DOM composite
|
|
129
|
-
|
|
130
|
-
Prefer platform/source definitions, readable WGSL, or WebGPU capture tools.
|
|
131
|
-
If the site uses Three.js TSL or another node system that targets WebGPU, capture the node definition and renderer route before translating to GLSL or WGSL.
|
|
132
|
-
|
|
133
|
-
Do not declare WebGPU replay ready because a WebGL shader capture succeeded elsewhere on the page. Evidence must bind to the WebGPU target surface.
|
|
134
|
-
|
|
135
|
-
### WebGPU Preload Hook Map
|
|
136
|
-
|
|
137
|
-
- `navigator.gpu.requestAdapter`
|
|
138
|
-
- `GPUAdapter.requestDevice`
|
|
139
|
-
- `GPUCanvasContext.configure`
|
|
140
|
-
- `GPUDevice.createShaderModule`
|
|
141
|
-
- `GPUDevice.createRenderPipeline`
|
|
142
|
-
- `GPUDevice.createComputePipeline`
|
|
143
|
-
- `GPUDevice.createBindGroupLayout`
|
|
144
|
-
- `GPUDevice.createBindGroup`
|
|
145
|
-
- `GPUDevice.createBuffer`
|
|
146
|
-
- `GPUDevice.createTexture`
|
|
147
|
-
- `GPUCommandEncoder.beginRenderPass`
|
|
148
|
-
- `GPUCommandEncoder.beginComputePass`
|
|
149
|
-
- `GPURenderPassEncoder.setPipeline`
|
|
150
|
-
- `GPURenderPassEncoder.setBindGroup`
|
|
151
|
-
- `GPURenderPassEncoder.draw`
|
|
152
|
-
- `GPURenderPassEncoder.drawIndexed`
|
|
153
|
-
- `GPUQueue.writeBuffer`
|
|
154
|
-
- `GPUQueue.writeTexture`
|
|
155
|
-
- `GPUQueue.submit`
|
|
156
|
-
|
|
157
|
-
## Canvas2D
|
|
158
|
-
|
|
159
|
-
Canvas2D targets need command, asset, font, and timing facts rather than shader facts.
|
|
160
|
-
|
|
161
|
-
Capture:
|
|
162
|
-
|
|
163
|
-
- command stream or readable source
|
|
164
|
-
- transforms and clipping
|
|
165
|
-
- paths, text, image draws
|
|
166
|
-
- gradients, patterns, filters
|
|
167
|
-
- `globalCompositeOperation`
|
|
168
|
-
- assets and fonts
|
|
169
|
-
- timing, random, pointer, scroll, resize
|
|
170
|
-
- canvas size, DPR, and DOM composite
|
|
171
|
-
|
|
172
|
-
Use Vanilla JS for simple Canvas2D baselines. Keep static offscreen buffers when the source uses them. Match font loading and text metrics before tuning positions.
|
|
173
|
-
|
|
174
|
-
Common failure cases:
|
|
175
|
-
|
|
176
|
-
- font fallback changes glyph metrics
|
|
177
|
-
- DPR scaling applied twice or not at all
|
|
178
|
-
- filter/composite order differs from source
|
|
179
|
-
- image smoothing settings change texture quality
|
|
180
|
-
- random state is re-created every frame in the replay
|
|
181
|
-
|
|
182
|
-
### Canvas2D Command Capture Map
|
|
183
|
-
|
|
184
|
-
- `drawImage`
|
|
185
|
-
- `fillRect` / `strokeRect` / `clearRect`
|
|
186
|
-
- `beginPath` / `moveTo` / `lineTo` / `bezierCurveTo` / `arc` / `fill` / `stroke` / `clip`
|
|
187
|
-
- `fillText` / `strokeText`
|
|
188
|
-
- `setTransform` / `transform` / `translate` / `rotate` / `scale`
|
|
189
|
-
- `save` / `restore`
|
|
190
|
-
- `globalAlpha`
|
|
191
|
-
- `globalCompositeOperation`
|
|
192
|
-
- `filter`
|
|
193
|
-
- `createLinearGradient` / `createRadialGradient` / `createPattern`
|
|
194
|
-
- `imageSmoothingEnabled`
|
|
195
|
-
|
|
196
|
-
## OffscreenCanvas And Worker Probes
|
|
197
|
-
|
|
198
|
-
- Hook `transferControlToOffscreen` before page scripts run when worker ownership is suspected.
|
|
199
|
-
- Record worker script URLs and message channels, but do not persist private message payloads unless they are public effect definitions needed for replay.
|
|
200
|
-
- Bind OffscreenCanvas evidence back to the visible placeholder canvas or DOM layer before promoting owner or backend facts.
|
|
201
|
-
- If worker source cannot be read, capture call timing, canvas dimensions, and message shapes as `PARTIAL` evidence and keep the missing source as a blocking or important unknown.
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
# Evidence Policy
|
|
2
|
-
|
|
3
|
-
Choose evidence by authority and collection cost.
|
|
4
|
-
|
|
5
|
-
## Truth Labels
|
|
6
|
-
|
|
7
|
-
Every implementation-critical fact needs a nearby truth label. If a fact has no label, treat it as `GUESS`.
|
|
8
|
-
|
|
9
|
-
| Label | Meaning | Valid evidence |
|
|
10
|
-
|---|---|---|
|
|
11
|
-
| `SOURCE` | Direct target-bound evidence from implementation or runtime. | Public source, source map, runtime object dump, captured shader/WGSL, GPU frame capture, network body with hash, or authoritative API output. |
|
|
12
|
-
| `PARTIAL` | Target-bound handle whose value, wiring, or replay role is not proven. | Symbol name, bundle slice, framework object, shader without draw/resource state, owner hint, or resource URL without use evidence. |
|
|
13
|
-
| `GUESS` | No direct evidence for the fact. | Visual fit, naming inference, copied defaults, hand-tuned constants, approximate behavior rebuild, or unverified assumption. |
|
|
14
|
-
|
|
15
|
-
Do not describe `PARTIAL` or `GUESS` facts as extracted source. A behavior rebuild can be used, but it stays approximate until promoted by evidence.
|
|
16
|
-
|
|
17
|
-
## Leaf Facts vs Wiring Facts
|
|
18
|
-
|
|
19
|
-
False conclusions often come from proving a leaf fact and guessing the wiring fact. Audit them separately:
|
|
20
|
-
|
|
21
|
-
- Leaf facts: shader source, WGSL, constants, config values, asset URLs, resource dimensions, sampler settings, context attributes.
|
|
22
|
-
- Wiring facts: target ownership, draw/pass order, FBO dependencies, coordinate transforms, time unit, delta rule, random source, input coupling, resize behavior, color/alpha/DOM composite.
|
|
23
|
-
|
|
24
|
-
`SOURCE` leaf facts do not promote unproven wiring.
|
|
25
|
-
A source shader string does not prove active pass order.
|
|
26
|
-
A config field named `velocity` does not prove units.
|
|
27
|
-
A framework signature does not prove the target canvas uses that framework.
|
|
28
|
-
|
|
29
|
-
## Promotion Rules
|
|
30
|
-
|
|
31
|
-
Promote a fact only when evidence improves:
|
|
32
|
-
|
|
33
|
-
- `GUESS -> PARTIAL`: a target-bound handle exists, but the value or wiring is still missing.
|
|
34
|
-
- `PARTIAL -> SOURCE`: direct source/runtime/frame evidence proves the value and its use in the target path.
|
|
35
|
-
- `SOURCE` for gate-critical wiring should have corroboration when practical. Examples: source plus runtime object, runtime plus frame capture, or source plus local replay smoke.
|
|
36
|
-
|
|
37
|
-
When evidence conflicts with the model, do not tune parameters to mask the conflict.
|
|
38
|
-
Route the mismatch back to attribution, source trace, or replay readiness.
|
|
39
|
-
Record the unresolved unknown.
|
|
40
|
-
|
|
41
|
-
## Unknown Classes
|
|
42
|
-
|
|
43
|
-
- `blocking`: cannot build a baseline that matches required evidence without resolving it
|
|
44
|
-
- `important`: baseline can run, but QA must focus on it
|
|
45
|
-
- `deferred`: affects projectization or polish, not baseline
|
|
46
|
-
- `external`: blocked by access, authorization, or legal permission
|
|
47
|
-
|
|
48
|
-
## Choosing The Next Action
|
|
49
|
-
|
|
50
|
-
Prefer the action that resolves the most blocking unknowns while keeping authority high and cost low.
|
|
51
|
-
|
|
52
|
-
Invalid action: "download every bundle and inspect everything."
|
|
53
|
-
|
|
54
|
-
Valid action: "target context creation stack points into `hero-renderer.*.js`; fetch only that source-mapped module to resolve owner and shader source."
|
|
55
|
-
|
|
56
|
-
## Evidence Ledger
|
|
57
|
-
|
|
58
|
-
Use ledger entries for facts that influence implementation:
|
|
59
|
-
|
|
60
|
-
```json
|
|
61
|
-
{
|
|
62
|
-
"id": "ev-0042",
|
|
63
|
-
"fact": "target surface is created by THREE.WebGLRenderer",
|
|
64
|
-
"value": true,
|
|
65
|
-
"truth": "SOURCE",
|
|
66
|
-
"targetIds": ["surface-1"],
|
|
67
|
-
"source": {
|
|
68
|
-
"type": "runtime|api|source-map|frame-capture|bundle|dom|screenshot|inference",
|
|
69
|
-
"location": "evidence/runtime/renderer.json#0",
|
|
70
|
-
"hash": "sha256:..."
|
|
71
|
-
},
|
|
72
|
-
"authority": "direct|corroborated|indirect|inferred",
|
|
73
|
-
"confidence": 0.96,
|
|
74
|
-
"verifiedBy": ["runtime-owner", "call-stack"]
|
|
75
|
-
}
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
Implementation-critical values should not rely only on `inferred` evidence unless the replay route is explicitly `BEHAVIOR_REBUILD`.
|
|
79
|
-
|
|
80
|
-
## Pre-Delivery Honesty Check
|
|
81
|
-
|
|
82
|
-
Before reporting completion, verify:
|
|
83
|
-
|
|
84
|
-
- Every implementation-critical value has `SOURCE`, `PARTIAL`, or `GUESS` evidence.
|
|
85
|
-
- No fitted value is labeled `SOURCE`.
|
|
86
|
-
- Wiring facts are proven separately from leaf facts.
|
|
87
|
-
- `REPLAY_READY` has no blocking unknowns without a documented fallback and fidelity downgrade.
|
|
88
|
-
- Known gaps describe the blocking unknown and the evidence needed to resolve it. Do not replace missing evidence with assumptions.
|
|
89
|
-
|
|
90
|
-
## Sensitive Data
|
|
91
|
-
|
|
92
|
-
Do not persist cookies, Authorization headers, access tokens, private API keys, or private account data.
|
|
93
|
-
When a browser session is already logged in, record only the minimum non-sensitive facts needed for target attribution and replay.
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
# Operating Contract
|
|
2
|
-
|
|
3
|
-
This contract defines the behavior of the Web Shader Extractor skill before any focused workflow begins.
|
|
4
|
-
|
|
5
|
-
## Objective
|
|
6
|
-
|
|
7
|
-
Start from the visual effect the user points to.
|
|
8
|
-
Lock the rendering surface, runtime, and source entry that produce it.
|
|
9
|
-
Use the lowest-cost target-bound evidence path.
|
|
10
|
-
Build a runnable and verifiable local baseline first.
|
|
11
|
-
Perform cleanup, modularization, and editability work only after that baseline passes verification.
|
|
12
|
-
|
|
13
|
-
This skill is not a general website cloner or a general JavaScript reverse-engineering workflow.
|
|
14
|
-
The core completion state is a local, runnable, verified replay of the target visual.
|
|
15
|
-
|
|
16
|
-
## Non-Negotiable Principles
|
|
17
|
-
|
|
18
|
-
1. Start from the visual target, not from bundles, framework names, or project structure.
|
|
19
|
-
2. Be canvas-first, not canvas-only: track iframes, OffscreenCanvas, workers, WebGPU, and DOM layers that participate in the effect.
|
|
20
|
-
3. Attribute before locking: the largest, fullscreen, or continuously animated canvas is not automatically the target.
|
|
21
|
-
4. Bind every conclusion to the target: a page-level Three.js, Babylon.js, or platform signature does not prove the target canvas uses it.
|
|
22
|
-
5. Lock the target before deep analysis: do not deobfuscate full bundles before `TARGET_LOCKED`.
|
|
23
|
-
6. Resolve one key unknown at a time: every action must state which unknown it resolves.
|
|
24
|
-
7. Prefer evidence over inference: public definitions, source, source maps, runtime objects, and frame captures outrank minified guesses.
|
|
25
|
-
8. Replay first: a runnable, verified local baseline is the core deliverable.
|
|
26
|
-
9. Restore before refactoring: projectization, modularization, lite versions, and native WebGL conversions happen after the baseline.
|
|
27
|
-
10. Choose the stack for evidence match: use native WebGL only when the scene is simple and conversion facts are complete.
|
|
28
|
-
11. Do not compensate by tuning: never change brightness, speed, position, or noise values to mask timing, color, FBO, resource, coordinate, or state-model errors.
|
|
29
|
-
12. Do not downgrade silently: if source replay falls back to pipeline replay or behavior rebuild, record it.
|
|
30
|
-
13. A matching single frame is not dynamic correctness: verify time, input, scroll, and multi-pass behavior separately.
|
|
31
|
-
14. Never overwrite the baseline: projectization and simplification happen in separate directories.
|
|
32
|
-
15. Do not ask by default: ask only for product-level scope changes or external authorization blockers.
|
|
33
|
-
16. Do not bypass access control: handle only public content or content the user is authorized to access and reproduce; do not save cookies, Authorization headers, tokens, or secrets.
|
|
34
|
-
17. Label implementation-critical facts as `SOURCE`, `PARTIAL`, or `GUESS`; an unlabeled value is treated as `GUESS`.
|
|
35
|
-
18. Separate leaf facts from wiring. Shader text, constants, asset URLs, and pass names can be source facts while render order, timing, input coupling, units, and ownership are still unproven.
|
|
36
|
-
|
|
37
|
-
## False Conclusion Rules
|
|
38
|
-
|
|
39
|
-
```text
|
|
40
|
-
1. The largest or fullscreen canvas is not necessarily the target canvas.
|
|
41
|
-
2. A framework existing on the page does not mean the target canvas uses it.
|
|
42
|
-
3. A visible first frame does not prove the render graph, time, and inputs are correct.
|
|
43
|
-
4. A similar screenshot does not prove the dynamic effect has been verified.
|
|
44
|
-
5. A source constant does not prove the pipeline wiring that consumes it.
|
|
45
|
-
6. A target-bound symbol name does not prove units, coordinate space, or timing semantics.
|
|
46
|
-
7. A local fix that improves appearance is not evidence; it is a GUESS until traced or independently verified.
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
## Fact Labels
|
|
50
|
-
|
|
51
|
-
Use truth labels close to facts that drive implementation:
|
|
52
|
-
|
|
53
|
-
- `SOURCE`: direct target-bound evidence. Examples: public original source, source-mapped module, runtime object dump, captured shader/WGSL, frame capture, or network body with hash.
|
|
54
|
-
- `PARTIAL`: a handle for the next probe. Examples: class/function/field name, target-bound bundle slice, framework object, or shader without state/pass/input facts.
|
|
55
|
-
- `GUESS`: visual fitting, naming inference, copied defaults, hand-tuned constants, or any behavior rebuild value without direct evidence.
|
|
56
|
-
|
|
57
|
-
Never upgrade a fact because output looks similar.
|
|
58
|
-
If a value is fitted so the baseline resembles the source, keep it labeled `GUESS`.
|
|
59
|
-
State which evidence would promote it.
|
|
60
|
-
If direct source conflicts with runtime behavior, treat wiring, units, or target attribution as unresolved before tuning.
|
|
61
|
-
|
|
62
|
-
Before declaring `TARGET_LOCKED`, `REPLAY_READY`, or `BASELINE_VERIFIED`, check both layers:
|
|
63
|
-
|
|
64
|
-
- Leaf facts: shader/WGSL text, constants, config, asset paths, resource dimensions, context attributes.
|
|
65
|
-
- Wiring facts: owner, pass order, FBO dependencies, coordinate transforms, time units, random rules, pointer/scroll/resize coupling, output composite.
|
|
66
|
-
|
|
67
|
-
Read `references/evidence-policy.md` for the full labeling and audit rules.
|
|
68
|
-
|
|
69
|
-
## External Blockers
|
|
70
|
-
|
|
71
|
-
Ask separately only for login, CAPTCHA, private pages, paid resources, or permission/license uncertainty.
|
|
72
|
-
Combine blockers into one note.
|
|
73
|
-
|
|
74
|
-
If connecting to an existing logged-in browser, tell the user credentials or page data may be visible to the agent.
|
|
75
|
-
Do not persist sensitive headers, cookies, tokens, or secrets.
|
|
76
|
-
|
|
77
|
-
## Completion States
|
|
78
|
-
|
|
79
|
-
- `DONE_BASELINE_VERIFIED`: baseline passed Source -> Baseline validation.
|
|
80
|
-
- `DONE_PROJECTIZED`: editable project passed Baseline -> Editable regression.
|
|
81
|
-
- `DONE_BASELINE_WITH_GAPS`: baseline runs, but differences or evidence gaps remain and are documented.
|
|
82
|
-
- `BLOCKED_EXTERNAL`: legal access, authorization, or permission prevents progress.
|