@aura3d/cli 4.6.2 → 4.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/admission/cubeLut.d.ts +18 -0
  2. package/dist/admission/cubeLut.d.ts.map +1 -0
  3. package/dist/admission/cubeLut.js +53 -0
  4. package/dist/admission/cubeLut.js.map +1 -0
  5. package/dist/asset-core-types.d.ts +7 -4
  6. package/dist/asset-core-types.d.ts.map +1 -1
  7. package/dist/cli-help.d.ts.map +1 -1
  8. package/dist/cli-help.js +7 -4
  9. package/dist/cli-help.js.map +1 -1
  10. package/dist/cli-options.d.ts +1 -1
  11. package/dist/cli-options.d.ts.map +1 -1
  12. package/dist/cli-options.js +2 -2
  13. package/dist/cli-options.js.map +1 -1
  14. package/dist/cli.js +3 -2
  15. package/dist/cli.js.map +1 -1
  16. package/dist/commands/assets/certifyCategories.d.ts +26 -0
  17. package/dist/commands/assets/certifyCategories.d.ts.map +1 -0
  18. package/dist/commands/assets/certifyCategories.js +31 -0
  19. package/dist/commands/assets/certifyCategories.js.map +1 -0
  20. package/dist/commands/assets/optimize.d.ts +66 -0
  21. package/dist/commands/assets/optimize.d.ts.map +1 -1
  22. package/dist/commands/assets/optimize.js +270 -1
  23. package/dist/commands/assets/optimize.js.map +1 -1
  24. package/dist/commands/assets/optimizeVerb.d.ts.map +1 -1
  25. package/dist/commands/assets/optimizeVerb.js +26 -1
  26. package/dist/commands/assets/optimizeVerb.js.map +1 -1
  27. package/dist/commands/evidence/judge.d.ts +50 -1
  28. package/dist/commands/evidence/judge.d.ts.map +1 -1
  29. package/dist/commands/evidence/judge.js +154 -6
  30. package/dist/commands/evidence/judge.js.map +1 -1
  31. package/dist/commands/prd05/index.js +1 -1
  32. package/dist/commands/prd05/index.js.map +1 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +25 -9
  35. package/dist/index.js.map +1 -1
  36. package/dist/look/judge.d.ts +53 -5
  37. package/dist/look/judge.d.ts.map +1 -1
  38. package/dist/look/judge.js +226 -50
  39. package/dist/look/judge.js.map +1 -1
  40. package/package.json +5 -5
  41. package/skills/aura3d-art-direction/references/look-recipes.md +2 -1
  42. package/skills/aura3d-game-art/SKILL.md +39 -17
  43. package/skills/aura3d-materials-environments/SKILL.md +4 -4
  44. package/skills/aura3d-materials-environments/references/look-overrides-4.7.md +93 -0
  45. package/skills/llms.txt +2 -2
@@ -4,16 +4,63 @@
4
4
  *
5
5
  * `look judge --validate <file>` validates a LookJudgement and reports the
6
6
  * per-category scores, weakest category and next-change hint.
7
- * `--judge prism` delegates to C-32 judgeWithPrism when the provider ships it;
8
- * while the export is absent the command exits 2 with `judge-unavailable`
9
- * rather than fabricating a score (no new provider code here).
7
+ * `look judge --judge prism --shots <jpg,...|dir>` (GU47 WP-9 E-I) sends up to
8
+ * 4 JPEG frames to the C-32 provider `judgeWithPrism`
9
+ * (tools/quality-gate/src/judge-prism.ts) with a 12-category look prompt,
10
+ * turns the GameJudgementRecord into a LookJudgement (judge "prism"),
11
+ * validates it and writes it. The provider is imported from source, so the
12
+ * path works where tools/ exists (a repo checkout, `tsx`); elsewhere it exits
13
+ * 2 with `judge-unavailable`, never a fabricated score. The key comes only
14
+ * from PRISM_API_KEY or the file named by PRISM_KEY_FILE and is never printed.
10
15
  */
16
+ import { type LookJudgement } from "./rubric.js";
11
17
  import type { AuraCliCommand } from "../contracts/commands.js";
12
- export declare function runLookJudge(argv: readonly string[], io: {
18
+ /** The C-32 provider signature (`judgeWithPrism` in tools/quality-gate/src/judge-prism.ts:38). */
19
+ export type PrismJudgeFn = (packet: {
20
+ readonly itemId: string;
21
+ readonly images: readonly string[];
22
+ readonly prompt: string;
23
+ readonly kind: "benchmark" | "game";
24
+ }, opts: {
25
+ readonly baseUrl: string;
26
+ readonly apiKeyEnv: "PRISM_API_KEY";
27
+ readonly model: "claude-opus-5.5";
28
+ }) => Promise<unknown>;
29
+ export interface LookJudgeDeps {
30
+ /** Test seam: replaces the import of tools/quality-gate/src/judge-prism.ts (resolves undefined when absent). */
31
+ readonly loadPrismJudge?: () => Promise<PrismJudgeFn | undefined>;
32
+ }
33
+ /** Prism model of the C-32 provider (PrismJudgeOptions.model). */
34
+ export declare const PRISM_LOOK_MODEL: "claude-opus-5.5";
35
+ /** Prism accepts at most 4 images per turn (judge-prism.ts). */
36
+ export declare const PRISM_MAX_SHOTS = 4;
37
+ /** The look-judge prompt: the 12 AGENT_LOOK_CATEGORIES, answered in the C-32 GameJudgementRecord shape plus observations. */
38
+ export declare function lookJudgePrompt(input: {
39
+ readonly itemId: string;
40
+ readonly subject: string;
41
+ readonly genre?: string;
42
+ readonly shots: number;
43
+ }): string;
44
+ /** Map the provider's GameJudgementRecord (plus the prompt's `observations`) onto a LookJudgement with judge "prism". */
45
+ export declare function lookJudgementFromPrism(record: unknown, input: {
46
+ readonly round: number;
47
+ readonly shots: readonly {
48
+ readonly path: string;
49
+ readonly sha256: string;
50
+ }[];
51
+ readonly references?: readonly string[];
52
+ }): LookJudgement;
53
+ /** `--shots a.jpg,b.jpg` or a folder: JPEG files only (the provider labels every image image/jpeg). */
54
+ export declare function collectJudgeShots(spec: string, cwd: string): {
55
+ readonly files: readonly string[];
56
+ readonly error?: string;
57
+ };
58
+ type JudgeIo = {
13
59
  readonly cwd: string;
14
60
  stdout(s: string): void;
15
61
  stderr(s: string): void;
16
- }): Promise<number>;
62
+ };
63
+ export declare function runLookJudge(argv: readonly string[], io: JudgeIo, deps?: LookJudgeDeps): Promise<number>;
17
64
  export declare function runLookRubric(argv: readonly string[], io: {
18
65
  readonly cwd: string;
19
66
  stdout(s: string): void;
@@ -21,4 +68,5 @@ export declare function runLookRubric(argv: readonly string[], io: {
21
68
  }): number;
22
69
  export declare const lookJudgeCommand: AuraCliCommand;
23
70
  export declare const lookRubricCommand: AuraCliCommand;
71
+ export {};
24
72
  //# sourceMappingURL=judge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../../../../../packages/aura3d-cli/src/look/judge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAaH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAyB/D,wBAAsB,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAwE3J;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,MAAM,CA4B7I;AAED,eAAO,MAAM,gBAAgB,EAAE,cAM9B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,cAM/B,CAAC"}
1
+ {"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../../../../../packages/aura3d-cli/src/look/judge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,EAQL,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,kGAAkG;AAClG,MAAM,MAAM,YAAY,GAAG,CACzB,MAAM,EAAE;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAAA;CAAE,EACrI,IAAI,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAA;CAAE,KACvG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB,MAAM,WAAW,aAAa;IAC5B,gHAAgH;IAChH,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAAC;CACnE;AAED,kEAAkE;AAClE,eAAO,MAAM,gBAAgB,EAAG,iBAA0B,CAAC;AAC3D,gEAAgE;AAChE,eAAO,MAAM,eAAe,IAAI,CAAC;AAQjC,6HAA6H;AAC7H,wBAAgB,eAAe,CAAC,KAAK,EAAE;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAWrJ;AAID,yHAAyH;AACzH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,OAAO,EACf,KAAK,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,GACxJ,aAAa,CAkCf;AAED,uGAAuG;AACvG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAkB3H;AA2ED,KAAK,OAAO,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC;AAsE1F,wBAAsB,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,GAAE,aAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAoClH;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,EAAE,EAAE;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,MAAM,CA4B7I;AAED,eAAO,MAAM,gBAAgB,EAAE,cAM9B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,cAM/B,CAAC"}
@@ -4,13 +4,159 @@
4
4
  *
5
5
  * `look judge --validate <file>` validates a LookJudgement and reports the
6
6
  * per-category scores, weakest category and next-change hint.
7
- * `--judge prism` delegates to C-32 judgeWithPrism when the provider ships it;
8
- * while the export is absent the command exits 2 with `judge-unavailable`
9
- * rather than fabricating a score (no new provider code here).
7
+ * `look judge --judge prism --shots <jpg,...|dir>` (GU47 WP-9 E-I) sends up to
8
+ * 4 JPEG frames to the C-32 provider `judgeWithPrism`
9
+ * (tools/quality-gate/src/judge-prism.ts) with a 12-category look prompt,
10
+ * turns the GameJudgementRecord into a LookJudgement (judge "prism"),
11
+ * validates it and writes it. The provider is imported from source, so the
12
+ * path works where tools/ exists (a repo checkout, `tsx`); elsewhere it exits
13
+ * 2 with `judge-unavailable`, never a fabricated score. The key comes only
14
+ * from PRISM_API_KEY or the file named by PRISM_KEY_FILE and is never printed.
10
15
  */
11
- import { existsSync, readFileSync } from "node:fs";
12
- import { resolve } from "node:path";
16
+ import { createHash } from "node:crypto";
17
+ import { existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
18
+ import { dirname, extname, join, relative, resolve, sep } from "node:path";
13
19
  import { AGENT_LOOK_CATEGORIES, GENRE_RECIPE_ROWS, LOOK_JUDGEMENT_SCHEMA, lookHintFor, validateLookJudgement, weakestLookCategory } from "./rubric.js";
20
+ /** Prism model of the C-32 provider (PrismJudgeOptions.model). */
21
+ export const PRISM_LOOK_MODEL = "claude-opus-5.5";
22
+ /** Prism accepts at most 4 images per turn (judge-prism.ts). */
23
+ export const PRISM_MAX_SHOTS = 4;
24
+ async function importPrismJudge() {
25
+ const { judgeWithPrism } = await import("../../../../tools/quality-gate/src/judge-prism.js");
26
+ const fn = judgeWithPrism;
27
+ return typeof fn === "function" ? fn : undefined;
28
+ }
29
+ /** The look-judge prompt: the 12 AGENT_LOOK_CATEGORIES, answered in the C-32 GameJudgementRecord shape plus observations. */
30
+ export function lookJudgePrompt(input) {
31
+ const recipe = input.genre ? GENRE_RECIPE_ROWS[input.genre] : undefined;
32
+ return [
33
+ `You are an art director and rendering engineer judging ${input.shots} screenshot${input.shots === 1 ? "" : "s"} of one browser 3D game (${input.subject}) against a ${AGENT_LOOK_CATEGORIES.length}-category look rubric.`,
34
+ "Judge only what is visible in the frames. Score each category from 0 to 10 in 0.5 steps; omit a category the frames cannot show.",
35
+ "Every score below 7 needs at least one observation for that category naming what you saw.",
36
+ ...(recipe ? [`Genre ${input.genre}: the recipe expects look ${recipe.look}, ${recipe.camera}, subject ${recipe.subjectPercent}% of the frame, key ${recipe.keyLight}, palette ${recipe.palette}, atmosphere ${recipe.atmosphere}, post ${recipe.post}.`] : []),
37
+ `Categories: ${AGENT_LOOK_CATEGORIES.join(", ")}`,
38
+ "Respond with one JSON object and nothing else, exactly these keys:",
39
+ `{ "itemId": ${JSON.stringify(input.itemId)}, "judge": { "id": "prism" }, "scores": { "<category>": <0-10> }, "observations": [{ "category": "<category>", "seen": "<what is visible>" }], "dominantCauses": [{ "cause": "<cause>", "percent": <0-100> }], "competitiveWithModernThree": <true if the frames hold up against current well-made browser 3D games>, "critique": "<at least 200 characters>" }`
40
+ ].join("\n");
41
+ }
42
+ const snapHalf = (n) => Math.min(10, Math.max(0, Math.round(n * 2) / 2));
43
+ /** Map the provider's GameJudgementRecord (plus the prompt's `observations`) onto a LookJudgement with judge "prism". */
44
+ export function lookJudgementFromPrism(record, input) {
45
+ const r = (record ?? {});
46
+ const scores = {};
47
+ for (const category of AGENT_LOOK_CATEGORIES) {
48
+ const value = r.scores?.[category];
49
+ if (typeof value === "number" && Number.isFinite(value))
50
+ scores[category] = snapHalf(value);
51
+ }
52
+ const observations = [];
53
+ if (Array.isArray(r.observations)) {
54
+ for (const o of r.observations) {
55
+ if (typeof o?.category === "string" && typeof o.seen === "string" && o.seen.trim() && AGENT_LOOK_CATEGORIES.includes(o.category)) {
56
+ observations.push({ category: o.category, seen: o.seen.trim() });
57
+ }
58
+ }
59
+ }
60
+ const critique = typeof r.critique === "string" ? r.critique.trim() : "";
61
+ for (const [category, score] of Object.entries(scores)) {
62
+ if (score < 7 && !observations.some((o) => o.category === category)) {
63
+ observations.push({ category, seen: critique ? `critique: ${critique.slice(0, 240)}` : "scored below 7 by the prism judge without an observation" });
64
+ }
65
+ }
66
+ const draft = {
67
+ schema: LOOK_JUDGEMENT_SCHEMA,
68
+ round: input.round,
69
+ shots: input.shots,
70
+ references: input.references ?? [],
71
+ scores,
72
+ observations,
73
+ nextChange: { category: "", change: "", api: "" },
74
+ judge: "prism"
75
+ };
76
+ const weakest = weakestLookCategory(draft);
77
+ const hint = weakest ? lookHintFor(weakest) : undefined;
78
+ return { ...draft, nextChange: hint ? { category: hint.category, change: hint.change, api: hint.api } : draft.nextChange };
79
+ }
80
+ /** `--shots a.jpg,b.jpg` or a folder: JPEG files only (the provider labels every image image/jpeg). */
81
+ export function collectJudgeShots(spec, cwd) {
82
+ const files = [];
83
+ for (const part of spec.split(",").map((s) => s.trim()).filter(Boolean)) {
84
+ const path = resolve(cwd, part);
85
+ if (!existsSync(path))
86
+ return { files, error: `shot not found: ${part}` };
87
+ if (statSync(path).isDirectory()) {
88
+ for (const name of readdirSync(path).sort())
89
+ if (/\.jpe?g$/i.test(name))
90
+ files.push(join(path, name));
91
+ }
92
+ else
93
+ files.push(path);
94
+ }
95
+ if (files.length === 0)
96
+ return { files, error: "no JPEG shots given (--shots <a.jpg,b.jpg,...|dir>)" };
97
+ if (files.length > PRISM_MAX_SHOTS)
98
+ return { files, error: `Prism takes at most ${PRISM_MAX_SHOTS} images per turn; got ${files.length}` };
99
+ for (const file of files) {
100
+ const head = readFileSync(file).subarray(0, 3);
101
+ if (!/\.jpe?g$/i.test(extname(file)) || head[0] !== 0xff || head[1] !== 0xd8 || head[2] !== 0xff) {
102
+ return { files, error: `not a JPEG: ${relative(cwd, file) || file} (the prism judge sends image/jpeg only)` };
103
+ }
104
+ }
105
+ return { files };
106
+ }
107
+ /** Run `fn` with PRISM_API_KEY present: from the env, else read from PRISM_KEY_FILE for the call only. Never printed. */
108
+ async function withPrismKey(fn) {
109
+ const previous = process.env.PRISM_API_KEY;
110
+ const fromFile = !previous?.trim() && process.env.PRISM_KEY_FILE ? readFileSync(process.env.PRISM_KEY_FILE, "utf8").trim() : "";
111
+ const key = previous?.trim() || fromFile;
112
+ if (!key)
113
+ throw new KeyMissing();
114
+ if (fromFile)
115
+ process.env.PRISM_API_KEY = fromFile;
116
+ try {
117
+ return await fn(key);
118
+ }
119
+ finally {
120
+ if (fromFile) {
121
+ if (previous === undefined)
122
+ delete process.env.PRISM_API_KEY;
123
+ else
124
+ process.env.PRISM_API_KEY = previous;
125
+ }
126
+ }
127
+ }
128
+ class KeyMissing extends Error {
129
+ constructor() {
130
+ super("set PRISM_API_KEY or PRISM_KEY_FILE (the key is read from the environment only and never printed)");
131
+ }
132
+ }
133
+ function printJudgement(judgement, io, asJson, header) {
134
+ const weakest = weakestLookCategory(judgement);
135
+ const hint = weakest ? lookHintFor(weakest) : undefined;
136
+ if (asJson) {
137
+ io.stdout(JSON.stringify({
138
+ ok: true,
139
+ schema: LOOK_JUDGEMENT_SCHEMA,
140
+ judge: judgement.judge,
141
+ round: judgement.round,
142
+ scores: judgement.scores,
143
+ weakestCategory: weakest ?? null,
144
+ hint: hint ?? null
145
+ }, null, 2));
146
+ return;
147
+ }
148
+ io.stdout(header);
149
+ for (const category of AGENT_LOOK_CATEGORIES) {
150
+ const score = judgement.scores[category];
151
+ if (score !== undefined)
152
+ io.stdout(` ${category}: ${score}`);
153
+ }
154
+ if (weakest) {
155
+ io.stdout(`weakest category: ${weakest}`);
156
+ io.stdout(`next change: ${hint.change}`);
157
+ io.stdout(`api: ${hint.api}`);
158
+ }
159
+ }
14
160
  function parseArgs(argv) {
15
161
  const flags = new Map();
16
162
  const switches = new Set();
@@ -29,28 +175,82 @@ function parseArgs(argv) {
29
175
  }
30
176
  return { flags, switches };
31
177
  }
32
- export async function runLookJudge(argv, io) {
178
+ async function runPrismLookJudge(flags, asJson, io, deps) {
179
+ const spec = flags.get("shots");
180
+ if (!spec) {
181
+ io.stderr(`look judge --judge prism requires --shots <a.jpg,b.jpg,...|dir> (at most ${PRISM_MAX_SHOTS} JPEG frames)`);
182
+ return 2;
183
+ }
184
+ const round = Number(flags.get("round") ?? 1);
185
+ if (!Number.isInteger(round) || round < 1) {
186
+ io.stderr("--round must be an integer >= 1");
187
+ return 2;
188
+ }
189
+ const genre = flags.get("genre");
190
+ if (genre && !GENRE_RECIPE_ROWS[genre]) {
191
+ io.stderr(`unknown genre "${genre}"; genres: ${Object.keys(GENRE_RECIPE_ROWS).join(", ")}`);
192
+ return 2;
193
+ }
194
+ const { files, error } = collectJudgeShots(spec, io.cwd);
195
+ if (error) {
196
+ io.stderr(error);
197
+ return 2;
198
+ }
199
+ let judgeFn;
200
+ try {
201
+ judgeFn = await (deps.loadPrismJudge ?? importPrismJudge)();
202
+ }
203
+ catch {
204
+ judgeFn = undefined;
205
+ }
206
+ if (!judgeFn) {
207
+ io.stderr("judge-unavailable: C-32 judgeWithPrism (tools/quality-gate/src/judge-prism.ts) cannot be loaded here; run the CLI from a repo checkout");
208
+ return 2;
209
+ }
210
+ const images = files.map((file) => readFileSync(file));
211
+ const shots = files.map((file, i) => ({ path: relative(io.cwd, file).split(sep).join("/") || file, sha256: createHash("sha256").update(images[i]).digest("hex") }));
212
+ const itemId = flags.get("item") ?? "look-judge";
213
+ const prompt = lookJudgePrompt({ itemId, subject: flags.get("subject") ?? "a browser 3D game", genre, shots: files.length });
214
+ let record;
215
+ let key = "";
216
+ try {
217
+ record = await withPrismKey(async (k) => {
218
+ key = k;
219
+ return judgeFn({ itemId, images: images.map((b) => b.toString("base64")), prompt, kind: "game" }, { baseUrl: process.env.PRISM_BASE_URL ?? "https://prism.auraone.ai", apiKeyEnv: "PRISM_API_KEY", model: PRISM_LOOK_MODEL });
220
+ });
221
+ }
222
+ catch (e) {
223
+ if (e instanceof KeyMissing) {
224
+ io.stderr(`judge-unavailable: ${e.message}`);
225
+ return 2;
226
+ }
227
+ const message = String(e instanceof Error ? e.message : e);
228
+ io.stderr(`prism judge failed: ${(key ? message.split(key).join("[redacted]") : message).slice(0, 300)}`);
229
+ return 1;
230
+ }
231
+ const references = (flags.get("references") ?? "").split(",").map((s) => s.trim()).filter(Boolean);
232
+ const judgement = lookJudgementFromPrism(record, { round, shots, references });
233
+ const validation = validateLookJudgement(judgement);
234
+ if (!validation.ok) {
235
+ for (const problem of validation.errors)
236
+ io.stderr(`invalid prism judgement: ${problem}`);
237
+ return 1;
238
+ }
239
+ const out = resolve(io.cwd, flags.get("out") ?? "look-judgement.json");
240
+ mkdirSync(dirname(out), { recursive: true });
241
+ writeFileSync(out, `${JSON.stringify(judgement, null, 2)}\n`);
242
+ printJudgement(judgement, io, asJson, `prism judgement ${LOOK_JUDGEMENT_SCHEMA} round ${round} (${PRISM_LOOK_MODEL}, ${files.length} shot${files.length === 1 ? "" : "s"}), wrote ${relative(io.cwd, out) || out}`);
243
+ return 0;
244
+ }
245
+ export async function runLookJudge(argv, io, deps = {}) {
33
246
  const { flags, switches } = parseArgs(argv);
34
247
  const judge = flags.get("judge") ?? "self";
35
248
  const asJson = switches.has("json");
36
- if (judge === "prism") {
37
- // C-32 provider slot: tools/quality-gate exports judgeWithPrism when PRD 12
38
- // lands the provider. Absent → exit 2 `judge-unavailable` (spec'd behaviour).
39
- try {
40
- const mod = (await import("../../../../tools/quality-gate/src/types.js"));
41
- if (typeof mod.judgeWithPrism !== "function") {
42
- io.stderr("judge-unavailable: C-32 judgeWithPrism is not exported by tools/quality-gate yet");
43
- return 2;
44
- }
45
- // Provider path for when PRD 12 lands: delegate and pass through.
46
- const result = await mod.judgeWithPrism({ argv, cwd: io.cwd });
47
- io.stdout(asJson ? JSON.stringify(result, null, 2) : String(result));
48
- return 0;
49
- }
50
- catch {
51
- io.stderr("judge-unavailable: C-32 judgeWithPrism is not exported by tools/quality-gate yet");
52
- return 2;
53
- }
249
+ if (judge === "prism" && !flags.has("validate"))
250
+ return runPrismLookJudge(flags, asJson, io, deps);
251
+ if (judge !== "self" && judge !== "prism") {
252
+ io.stderr(`unknown judge "${judge}" (self or prism)`);
253
+ return 2;
54
254
  }
55
255
  const validatePath = flags.get("validate");
56
256
  if (!validatePath) {
@@ -77,31 +277,7 @@ export async function runLookJudge(argv, io) {
77
277
  return 1;
78
278
  }
79
279
  const judgement = parsed;
80
- const weakest = weakestLookCategory(judgement);
81
- const hint = weakest ? lookHintFor(weakest) : undefined;
82
- if (asJson) {
83
- io.stdout(JSON.stringify({
84
- ok: true,
85
- schema: LOOK_JUDGEMENT_SCHEMA,
86
- judge: judgement.judge,
87
- round: judgement.round,
88
- scores: judgement.scores,
89
- weakestCategory: weakest ?? null,
90
- hint: hint ?? null
91
- }, null, 2));
92
- return 0;
93
- }
94
- io.stdout(`judgement ${LOOK_JUDGEMENT_SCHEMA} round ${judgement.round} (${judgement.judge}) is valid`);
95
- for (const category of AGENT_LOOK_CATEGORIES) {
96
- const score = judgement.scores[category];
97
- if (score !== undefined)
98
- io.stdout(` ${category}: ${score}`);
99
- }
100
- if (weakest) {
101
- io.stdout(`weakest category: ${weakest}`);
102
- io.stdout(`next change: ${hint.change}`);
103
- io.stdout(`api: ${hint.api}`);
104
- }
280
+ printJudgement(judgement, io, asJson, `judgement ${LOOK_JUDGEMENT_SCHEMA} round ${judgement.round} (${judgement.judge}) is valid`);
105
281
  return 0;
106
282
  }
107
283
  export function runLookRubric(argv, io) {
@@ -138,7 +314,7 @@ export const lookJudgeCommand = {
138
314
  name: "look judge",
139
315
  owner: "prd13",
140
316
  summary: "Validate a LookJudgement, print scores, weakest category and next-change hint",
141
- usage: "aura3d look judge --validate <look-judgement.json> [--judge self|prism] [--json]",
317
+ usage: "aura3d look judge --validate <look-judgement.json> [--json] | aura3d look judge --judge prism --shots <a.jpg,b.jpg,...|dir> [--round 1] [--genre <genre>] [--item <id>] [--subject <text>] [--references <id,...>] [--out look-judgement.json] [--json]",
142
318
  run: (argv, io) => runLookJudge(argv, io)
143
319
  };
144
320
  export const lookRubricCommand = {
@@ -1 +1 @@
1
- {"version":3,"file":"judge.js","sourceRoot":"","sources":["../../../../../packages/aura3d-cli/src/look/judge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"judge.js","sourceRoot":"","sources":["../../../../../packages/aura3d-cli/src/look/judge.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aura3d/cli",
3
- "version": "4.6.2",
3
+ "version": "4.7.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "aura3d": "dist/cli.js",
@@ -28,10 +28,10 @@
28
28
  "types": "./dist/index.d.ts",
29
29
  "dependencies": {
30
30
  "typescript": "^5.8.3",
31
- "@aura3d/asset-index": "4.6.2",
32
- "@aura3d/audio": "4.6.2",
33
- "@aura3d/rendering": "4.6.2",
34
- "create-aura3d": "4.6.2"
31
+ "@aura3d/asset-index": "4.7.0",
32
+ "@aura3d/audio": "4.7.0",
33
+ "@aura3d/rendering": "4.7.0",
34
+ "create-aura3d": "4.7.0"
35
35
  },
36
36
  "description": "Bring real GLB/glTF assets into Aura3D browser apps with typed references, provenance, catalog search, validation, screenshots, and deploy checks.",
37
37
  "keywords": [
@@ -1,4 +1,4 @@
1
- # Look recipes — 13 genre rows
1
+ # Look recipes — 14 genre rows
2
2
 
3
3
  One row per genre. Use the row's look id verbatim, take its camera/framing/palette
4
4
  as the starting point, then iterate in the look-dev loop. Palettes: 3 base tones +
@@ -11,6 +11,7 @@ is the subject's share of frame height.
11
11
  | racing | `golden-hour` | `chase`, fov 60 | 15–25 | 12° / 35° (low sun) | warm asphalt, burnt orange, charcoal + headlight amber | fog 30–180 m | `cinematic-film` | brake glow, speed dust | `webgl_materials_car` |
12
12
  | fighting | `arena-fight` | `follow` (side-on), fov 45 | 20–30 (pair) | top spot 60° / 0° | arena dark, rope colour, crowd shadow + spotlight rim | haze cone | `arena-fight` | hit sparks, knockback flash | `webgl_animation_skinning_morph` |
13
13
  | arena shooter | `space` | `orthographic` (top-down) 60°, fov 55 | 10–15 (field) | rim 70° / 210° | deep space blue, graphite, teal + laser magenta | none (space background exception) | `space` | model muzzle flash, shield segments | `webgl_shaders_sky` |
14
+ | maze-arcade | `neon-arcade` | `orthographic` (top-down) 55°, fov 40 | 70–85 (maze board) | 55° / 210° (one shadowed key) | ink navy floor, slate walls, graphite trim + pellet cyan | fog 60–320 m (half night-city) | `neon-night` | pellet pickup sparkle, emissive wall trace along the runner's path | `webgl_lights_spotlights` |
14
15
  | sports/table | `interior-industrial` | broadcast `orthographic` (top-down) 70°, fov 40 | 25–40 (table) | flood 55° / 45° | turf green, line white, crowd dark + ball accent | indoor haze | `arena-fight` | scoreboard pulse | `webgl_materials_lightmap` |
15
16
  | product | `product-studio` | `orbit` autoframe, fov 35 | 45–70 | softbox 45° / 30° | neutral grey, white, metal + one brand accent | none | `product-studio` | sweep highlight on turn | `webgl_materials_video` |
16
17
  | character | `character-showcase` | `orbit`, fov 40 | 50–70 | 3-point 50° / 35° | costume-driven neutrals + rim pick | light room haze | `product-studio` | cloth/hair motion settle | `webgl_animation_skinning_blending` |
@@ -1,12 +1,13 @@
1
1
  ---
2
2
  name: aura3d-game-art
3
- description: Produces 2D game art that a real Aura3D consumer uses: flipbook VFX sprite sheets for `effects.flipbook` (the `flipbook-sprite` effect with `spriteColumns` / `spriteRows`) and HUD icons or UI sprites for DOM overlays, each admitted as a typed texture asset. Use when a game template (`mini-game`, `racing-starter`, `falling-blocks-starter`, `fighting-game`) needs explosion, muzzle-flash, or hit VFX sheets, HUD icons, score or health sprites, or a style-consistent batch of UI art.
3
+ description: Produces 2D game art that a real Aura3D consumer uses: flipbook VFX sprite sheets for `effects.flipbook({ texture })` (the `flipbook-sprite` effect with `spriteColumns` / `spriteRows`) or particle `sprite` sheets, and HUD icons or UI sprites for DOM overlays, each admitted as a typed texture asset; also names the built-in atlas sprites, registered presets and trails that need no art. Use when a game template (`mini-game`, `racing-starter`, `falling-blocks-starter`, `fighting-game`) needs explosion, muzzle-flash, or hit VFX sheets, HUD icons, score or health sprites, or a style-consistent batch of UI art.
4
4
  ---
5
5
 
6
6
  # Aura3D game art (flipbook VFX and HUD sprites)
7
7
 
8
- Only two consumers exist, so only two kinds of art are produced: flipbook
9
- sheets for the `flipbook-sprite` effect and icons for the DOM HUD. Tilesets
8
+ Only two kinds of consumer exist, so only two kinds of art are produced:
9
+ sprite sheets (the `flipbook-sprite` effect, or a particle `sprite` sheet) and
10
+ icons for the DOM HUD. Tilesets
10
11
  are out of scope: no 2D tile runtime consumes them, so 3D levels come from
11
12
  `aura3d-browser-game` and `aura3d-assets`. Shared rules (claim labels, typed
12
13
  assets, CSS/DOM is UI only, benchmark mode) are in
@@ -28,12 +29,13 @@ texture viewer hides.
28
29
  2. Read `src/aura-assets.ts` and `aura.assets.json`, and find the consumer
29
30
  first: the `effects.flipbook(...)` call, or the HUD element in `src/main.ts`
30
31
  (the `mini-game` HUD is a DOM `aside`). No consumer means no art.
31
- 3. Know the flipbook state. `effects.flipbook` records validated sheet
32
- geometry (`spriteColumns`, `spriteRows`, `frameRate`) but the root renderer
33
- has no sprite-sheet sampler yet and submits no flipbook pass.
34
- `renderer.diagnostics(scene)` reports the warning "flipbook-sprite is
35
- recorded but withheld". Any route relying on it is `prototype` for that
36
- effect.
32
+ 3. Know the flipbook state. `effects.flipbook({ texture: assets.sheet,
33
+ spriteColumns, spriteRows, frameRate })` draws through the particle pass
34
+ (A3D_QR_VFX, on by default): it samples the typed sheet on that grid.
35
+ Without `texture` it draws the built-in fireball sheet; `sprite:
36
+ "flame-loop"` uses a built-in atlas sequence instead. A sheet draws the
37
+ soft-dot until it has loaded, and a failed load is named
38
+ `VFX_SPRITE_UNAVAILABLE` in `app.diagnostics()`.
37
39
  4. Benchmark mode: `npm install && npm run build`, then stop.
38
40
 
39
41
  ## Procedure
@@ -65,11 +67,31 @@ Flipbook VFX sheets:
65
67
  npx @aura3d/cli@latest assets typegen
66
68
  ```
67
69
 
68
- 5. Declare the effect with the same grid:
69
- `effects.flipbook({ spriteColumns: 8, spriteRows: 4, frameRate: 24 })`.
70
- Mismatched or non-integer values throw a `RangeError` (fail loud); never
71
- catch and ignore it. The effect has no texture slot today, so the sheet is
72
- ready for the sampler but not yet drawn.
70
+ 5. Declare the effect with the same grid and the typed asset:
71
+ `effects.flipbook({ texture: assets.explosionSheet, spriteColumns: 8,
72
+ spriteRows: 4, frameRate: 24 })`. Mismatched or non-integer values throw a
73
+ `RangeError` (fail loud); never catch and ignore it. Author sheets with
74
+ straight alpha; frame 0 is the top-left cell.
75
+
76
+ Particles, presets and trails (when the game needs runtime VFX, not a sheet):
77
+
78
+ - Built-in atlas sprites need no art: `effects.particles({ sprite:
79
+ "smoke-a" })` or `app.effects.burst("dust", at, { sprite: "dust-mote" })`.
80
+ Names: soft-dot, glow, flare, spark-streak, ring, ring-thin, dust-mote,
81
+ bubble, rain-streak, snowflake, smoke-a, smoke-b, fireball, flame-loop,
82
+ muzzle, splash, electric, debris-chips. A sheet works on emitters too:
83
+ `sprite: { atlas: assets.sparkSheet, frame: 3 }` with `spriteColumns` and
84
+ `spriteRows`.
85
+ - A game's own pack: `app.effects.registerPreset("chalk-puff", { name:
86
+ "chalk-puff", layers: [{ type: "emitter", preset: "dust", color: "#f2efe6",
87
+ count: 18, sprite: "dust-mote" }, { type: "light", intensity: 4 }] })`, then
88
+ `app.effects.burst("chalk-puff", at)`. Registered names win over built-ins;
89
+ layers may be emitter, light, camera or decal, with an `at` delay in
90
+ seconds. Genre-coloured built-ins exist for spark, dust and pickup (for
91
+ example `spark-electric`, `dust-sand`, `pickup-gold`).
92
+ - Ribbons: `app.effects.trail(nodeId, { width: 0.4, life: 0.8, color:
93
+ "#ffcc66", widthOverSpeed: [2, 12] })` follows the node; the head is opaque,
94
+ the tail fades over `life`, and stopping its handle lets it fade out.
73
95
 
74
96
  HUD icons and UI sprites:
75
97
 
@@ -100,9 +122,9 @@ Style-consistent batches:
100
122
 
101
123
  - The sheet fails `sheet-check.mjs`, or frames bleed across cells: fix the
102
124
  sheet; do not change the grid in code to paper over it.
103
- - The route's VFX depends on flipbook pixels: label that effect `prototype`
104
- and quote the withheld warning. Do not fake it with CSS, a DOM overlay, or
105
- an animated `<img>` on top of the canvas.
125
+ - The sheet does not draw (`VFX_SPRITE_UNAVAILABLE`, or only soft dots in the
126
+ frame): label that effect `prototype` and quote the diagnostic. Do not fake
127
+ it with CSS, a DOM overlay, or an animated `<img>` on top of the canvas.
106
128
  - Someone asks for a tileset: decline it and route level work to
107
129
  `aura3d-browser-game`.
108
130
  - A file has no license or author: do not admit it.
@@ -14,10 +14,10 @@ labels, typed assets, catalog-first for models, benchmark mode) are in
14
14
 
15
15
  ## Look target
16
16
 
17
- Most scenes need no per-file HDRI at all: `looks.preset(<genre>)` already
18
- supplies environment light, sky/background, fog and grade — pick it from the
19
- recipe row in `../aura3d-art-direction/references/look-recipes.md` and only
20
- descend into manual environments when the look cannot express the mood.
17
+ Most scenes need no per-file HDRI at all: `looks.preset(<genre>)` already supplies environment light, sky/background, fog and grade — pick it from the
18
+ recipe row in `../aura3d-art-direction/references/look-recipes.md` and only descend into manual environments when the look cannot express the mood.
19
+ From 4.7.0 a look takes overrides (a catalogued `hdri` id, environment intensity and rotation, key, rim, fog, grade, post) and the app changes light,
20
+ environment, fog and post at runtime: [look overrides, HDRI ids and runtime setters](references/look-overrides-4.7.md).
21
21
 
22
22
  ## Establish the contract
23
23