stylegallery 0.1.6 → 0.1.8
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/AGENTS.md +13 -1
- package/DOMAINS.md +10 -6
- package/GOVERNANCE.md +14 -12
- package/LICENSE +28 -0
- package/LICENSE-DOCS +42 -0
- package/NOTICE +38 -0
- package/README.md +47 -15
- package/consumer-reference/agent-native/README.md +7 -7
- package/consumer-reference/agent-native/v2/admission-policy.json +196 -31
- package/consumer-reference/agent-native/v2/material-registry.json +1 -1
- package/consumer-reference/agent-native/v2/schema/admission-policy.schema.json +3 -3
- package/consumer-reference/agent-native/v2/schema/material-record.schema.json +1 -1
- package/design-engineering/component-contract.md +19 -3
- package/design-engineering/decision-tree.md +1 -0
- package/design-engineering/index.md +48 -0
- package/design-engineering/loading-and-feedback.md +91 -0
- package/design-engineering/native-interaction-contracts.md +94 -0
- package/design-engineering/state-management/decision-tree.md +60 -0
- package/design-engineering/state-management/index.md +61 -0
- package/design-engineering/state-management/patterns/derived-state.md +85 -0
- package/design-engineering/state-management/patterns/draft-and-baseline.md +86 -0
- package/design-engineering/state-management/patterns/id-selection.md +85 -0
- package/design-engineering/state-management/patterns/identity-reset.md +89 -0
- package/design-engineering/state-management/patterns/latest-request-wins.md +94 -0
- package/design-engineering/state-management/patterns/optimistic-overlay.md +98 -0
- package/design-engineering/state-management/patterns/single-flight.md +92 -0
- package/design-engineering/state-management/patterns/single-owner.md +89 -0
- package/design-engineering/state-management/patterns/submitted-snapshot.md +107 -0
- package/design-engineering/state-management/patterns/unsaved-navigation.md +100 -0
- package/design-engineering/state-management/patterns/url-state.md +96 -0
- package/design-engineering/state-management/patterns/versioned-restore.md +95 -0
- package/design-engineering/state-management/recipes/delete-undo.md +65 -0
- package/design-engineering/state-management/recipes/index.md +64 -0
- package/design-engineering/state-management/recipes/multi-step-form.md +65 -0
- package/design-engineering/state-management/recipes/search-detail.md +65 -0
- package/design-engineering/state-management/recipes/settings-save.md +64 -0
- package/design-engineering/state-management/state-brief.md +83 -0
- package/design-engineering/state-management/verification.md +65 -0
- package/design-engineering/text-input-and-internationalization.md +91 -0
- package/design-engineering/worked-examples.md +2 -0
- package/design-terminology/conflict-cases.md +51 -8
- package/design-terminology/index.md +6 -0
- package/design-terminology/interaction-semantics.md +87 -0
- package/design-terminology/source-kinds.md +1 -1
- package/design-terminology/source-vocabularies.md +17 -1
- package/design-terminology/token-semantics.md +90 -0
- package/design-terminology/typography-semantics.md +86 -0
- package/expression/brand-studies.md +50 -0
- package/expression/direction-brief.md +71 -0
- package/expression/directions/nocturne-editorial.md +80 -0
- package/expression/directions/warm-print.md +73 -0
- package/expression/index.md +40 -0
- package/expression/techniques/gradient-atmosphere.md +107 -0
- package/expression/techniques/grain-and-texture.md +83 -0
- package/expression/techniques/webgl-hero.md +123 -0
- package/guides/vocabulary.md +1 -1
- package/index.md +3 -3
- package/log.md +64 -0
- package/motion/accessible-motion.md +90 -0
- package/motion/index.md +9 -0
- package/motion/interaction-recipes.md +8 -2
- package/motion/interruption-and-retargeting.md +90 -0
- package/motion/observed-choreography.md +73 -0
- package/motion/rendering-and-performance.md +89 -0
- package/motion/techniques/kinetic-type.md +145 -0
- package/motion/techniques/scroll-choreography.md +154 -0
- package/package.json +76 -21
- package/platform-guides/adaptive-navigation.md +85 -0
- package/platform-guides/compatibility-matrix.md +1 -1
- package/platform-guides/index.md +6 -0
- package/platform-guides/input-and-focus.md +91 -0
- package/platform-guides/preferences-and-accessibility.md +90 -0
- package/quality/claim-records/stylegallery-multidomain-scope.md +2 -2
- package/quality/evidence/executable-evidence.md +1 -1
- package/quality/index.md +1 -2
- package/scripts/agent-native/v2/material-admission.mjs +1 -1
- package/scripts/agent-native/v2/material-identity.mjs +2 -2
- package/scripts/compiler/README.md +112 -0
- package/scripts/compiler/cli.mjs +51 -0
- package/scripts/compiler/mcp.mjs +53 -0
- package/scripts/compiler/operations.mjs +70 -0
- package/scripts/compiler/runtime.mjs +156 -0
- package/scripts/sg-entry.mjs +20 -0
- package/scripts/sg-server.mjs +20 -0
- package/showcase/README.md +113 -0
- package/game-ui/classification.md +0 -82
- package/game-ui/decision-tree.md +0 -81
- package/game-ui/index.md +0 -45
- package/game-ui/reference-record.md +0 -62
- package/game-ui/screen-hierarchy.md +0 -107
- package/game-ui/screen-recipes.md +0 -101
- package/game-ui/unity/architecture.md +0 -166
- package/game-ui/unity/cli-loop.md +0 -84
- package/game-ui/unity/org-wiki.md +0 -146
- package/game-ui/unity/repository-map.md +0 -102
- package/game-ui/unity/ui-systems.md +0 -85
- package/game-ui/verification-workflow.md +0 -100
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
export const upstream = Object.freeze({
|
|
4
|
+
repository: "https://github.com/changeroa/site-compiler",
|
|
5
|
+
verified_revision: "371849141ba68d12d578c804cc53fe7267c899b0",
|
|
6
|
+
verified_at: "2026-09-22",
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
const text = z.string().min(1).refine((value) => !value.includes("\0"), "must not contain NUL");
|
|
10
|
+
const file = text.describe("Filesystem path; relative paths resolve from the SG caller's working directory.");
|
|
11
|
+
const positive = z.number().int().positive();
|
|
12
|
+
const url = z.url().refine((value) => ["http:", "https:"].includes(new URL(value).protocol), "use an HTTP or HTTPS URL");
|
|
13
|
+
const optional = (shape) => Object.fromEntries(Object.entries(shape).map(([key, value]) => [key, value.optional()]));
|
|
14
|
+
const viewport = { width: positive.max(16384), height: positive.max(16384), wait: z.number().int().min(0).max(60000) };
|
|
15
|
+
const capture = { ...viewport, step: positive, quality: positive.max(100), grow: z.boolean() };
|
|
16
|
+
const batch = { only: text, force: z.boolean(), parallel: positive.max(32), timeout_ms: positive };
|
|
17
|
+
const model = { ...batch, model: text, timeout_ms: positive, stylegallery: file };
|
|
18
|
+
const operation = (script, description, required, options = {}, paths = [], extra = {}) => ({
|
|
19
|
+
script, description, paths,
|
|
20
|
+
schema: z.strictObject({ ...required, ...optional(options), runner_timeout_ms: positive.max(21600000).optional() }),
|
|
21
|
+
...extra,
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// This registry owns both public transports. Upstream scripts remain in the
|
|
25
|
+
// separately installed checkout and are never admitted as gallery material.
|
|
26
|
+
export const compilerOperations = Object.freeze({
|
|
27
|
+
compile: operation("compile.mjs", "Capture a live website as scenes.json, scene frames, and mounted text. Writes to out; does not transcribe the frames.",
|
|
28
|
+
{ url, out: file }, { ...viewport, substep: positive }, ["out"]),
|
|
29
|
+
timeline: operation("timeline.mjs", "Capture dense scroll frames and a pixel-difference curve. Writes timeline-curve.json and dense/ to out.",
|
|
30
|
+
{ url, out: file }, { ...capture, max_height: positive }, ["out"]),
|
|
31
|
+
transcribe: operation("transcribe.mjs", "Transcribe captured packs into SceneBook and Timeline documents using the installed Claude CLI. May incur model usage. Inspect transcribe.json for per-pack outcomes.",
|
|
32
|
+
{ in: file }, { ...model, image_budget: positive, phase: z.enum(["both", "scenebook", "timeline"]) }, ["in", "stylegallery"], { ledger: "transcribe.json" }),
|
|
33
|
+
sale: operation("sale-edition.mjs", "Generate a sale edition and a private copy audit from transcribed documents. Does not publish or establish rights clearance.",
|
|
34
|
+
{ in: file, out: file }, { audit: file }, ["in", "out", "audit"]),
|
|
35
|
+
gate: operation("qa-gate.mjs", "Check capture/transcription consistency and optionally a sale edition. A failed gate returns a nonzero exit code; json optionally writes the report.",
|
|
36
|
+
{ in: file }, { sale: file, json: file, max_gap_ratio: z.number().min(0).max(1), max_gaps_per_scene: z.number().int().min(0), static_score: z.number().min(0), high_score: z.number().min(0) }, ["in", "sale", "json"]),
|
|
37
|
+
build: operation("build.mjs", "Build package previews from sale editions with original-page and external-media access restricted. Not the faithful-reconstruction route. Uses the installed Claude CLI and may incur model usage. Inspect build.json for per-pack outcomes.",
|
|
38
|
+
{ packs: file, out: file }, model, ["packs", "out", "stylegallery"], { ledger: "build.json" }),
|
|
39
|
+
shots: operation("shots.mjs", "Render built sites into desktop/mobile screenshots and a reduced-motion report under each build's shots/ directory.",
|
|
40
|
+
{ slug: text, builds: file }, { steps: positive.max(1000) }, ["builds"]),
|
|
41
|
+
probe: operation("probe-scroll.mjs", "Inspect website scroll geometry with Chromium; chrome selects installed Chrome. Returns the upstream diagnostic log.",
|
|
42
|
+
{ url }, { chrome: z.boolean() }, [], { positional: ["url"] }),
|
|
43
|
+
"batch-triage": operation("batch-triage.mjs", "Capture candidate sites for triage. Inspect runs.json for individual failures even when the process exits successfully.",
|
|
44
|
+
{ candidates: file, out: file }, { ...batch, step: positive, wait: viewport.wait, quality: capture.quality, grow: z.boolean() }, ["candidates", "out"], { ledger: "runs.json" }),
|
|
45
|
+
triage: operation("triage.mjs", "Rank captured scroll curves and write a triage report. This is heuristic ranking, not product verification.",
|
|
46
|
+
{ in: file }, { json: file, md: file, min_height: positive, pin_score: z.number().min(0), spike_score: z.number().min(0) }, ["in", "json", "md"]),
|
|
47
|
+
"batch-capture": operation("batch-capture.mjs", "Capture scenes and timelines for candidate sites. Inspect capture.json for per-pack outcomes.",
|
|
48
|
+
{ candidates: file, out: file }, { ...batch, step: positive, quality: capture.quality }, ["candidates", "out"], { ledger: "capture.json" }),
|
|
49
|
+
"pack-status": operation("pack-status.mjs", "Update pack status, generating sale editions and running gates as needed. Writes status reports into in.",
|
|
50
|
+
{ candidates: file, in: file }, { force: z.boolean() }, ["candidates", "in"]),
|
|
51
|
+
"pack-release": operation("pack-release.mjs", "Package products from the compiler checkout's out/packs and out/builds into out/release. Replaces matching release folders and ZIP files locally; does not upload or publish.",
|
|
52
|
+
{ products: file }, { only: text }, ["products"]),
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
export const workflowSchema = z.strictObject({ document: z.enum(["workflow", "readme"]).default("workflow") });
|
|
56
|
+
|
|
57
|
+
export function compilerToolDefinitions() {
|
|
58
|
+
return Object.entries(compilerOperations).map(([name, operation]) => {
|
|
59
|
+
const { $schema, ...inputSchema } = z.toJSONSchema(operation.schema);
|
|
60
|
+
return {
|
|
61
|
+
name, description: operation.description, inputSchema,
|
|
62
|
+
annotations: { readOnlyHint: false, destructiveHint: true, idempotentHint: false, openWorldHint: true },
|
|
63
|
+
};
|
|
64
|
+
}).concat({
|
|
65
|
+
name: "workflow",
|
|
66
|
+
description: "Read the installed compiler's current workflow or README with revision and content hash, plus the SG component and motion contract routes.",
|
|
67
|
+
inputSchema: { type: "object", properties: { document: { type: "string", enum: ["workflow", "readme"], default: "workflow" } }, additionalProperties: false },
|
|
68
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
69
|
+
});
|
|
70
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
import { compilerOperations, compilerToolDefinitions, upstream, workflowSchema } from "./operations.mjs";
|
|
8
|
+
|
|
9
|
+
const galleryRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
|
|
10
|
+
const logLimit = 65536;
|
|
11
|
+
const hash = (bytes) => createHash("sha256").update(bytes).digest("hex");
|
|
12
|
+
const handoff = { consumer_reference: "consumer-reference/agent-native/registry.json" };
|
|
13
|
+
|
|
14
|
+
export function failure(operation, code, message) {
|
|
15
|
+
return { ok: false, operation, failures: [{ code, message }] };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function compilerLocation(config) {
|
|
19
|
+
const configured = config.compilerRoot ?? process.env.SG_COMPILER_ROOT;
|
|
20
|
+
if (!configured) throw Object.assign(new Error("Set SG_COMPILER_ROOT to your site-compiler checkout, or pass --compiler-root to the CLI."), { code: "compiler_not_configured" });
|
|
21
|
+
const root = fs.realpathSync(path.resolve(config.cwd ?? process.cwd(), configured));
|
|
22
|
+
const manifest = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8"));
|
|
23
|
+
if (manifest.name !== "site-compiler") throw Object.assign(new Error("SG_COMPILER_ROOT must contain the site-compiler package."), { code: "compiler_invalid" });
|
|
24
|
+
const revision = spawnSync("git", ["-C", root, "rev-parse", "HEAD"], { encoding: "utf8", timeout: 5000 });
|
|
25
|
+
const gitRoot = spawnSync("git", ["-C", root, "rev-parse", "--show-toplevel"], { encoding: "utf8", timeout: 5000 });
|
|
26
|
+
const isCheckout = gitRoot.status === 0 && fs.realpathSync(gitRoot.stdout.trim()) === root;
|
|
27
|
+
const status = isCheckout ? spawnSync("git", ["-C", root, "status", "--porcelain", "--untracked-files=no"], { encoding: "utf8", timeout: 5000 }) : null;
|
|
28
|
+
const actualRevision = isCheckout && revision.status === 0 ? revision.stdout.trim() : null;
|
|
29
|
+
return {
|
|
30
|
+
root, package_version: manifest.version, revision: actualRevision,
|
|
31
|
+
tracked_changes: status?.status === 0 ? status.stdout.length > 0 : null,
|
|
32
|
+
matches_verified_revision: actualRevision === upstream.verified_revision && status?.status === 0 && status.stdout.length === 0,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function compilerDiscovery(config = {}) {
|
|
37
|
+
let installation;
|
|
38
|
+
try { installation = { configured: true, ...compilerLocation(config) }; }
|
|
39
|
+
catch (error) { installation = { configured: false, code: error.code ?? "compiler_unavailable", message: error.message }; }
|
|
40
|
+
return {
|
|
41
|
+
...upstream, installation,
|
|
42
|
+
operations: compilerToolDefinitions(),
|
|
43
|
+
contracts: ["design-engineering/component-contract.md", "motion/observed-choreography.md"],
|
|
44
|
+
...handoff,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function checkedFile(root, name) {
|
|
49
|
+
const target = path.join(root, name);
|
|
50
|
+
if (fs.realpathSync(target) !== target || !fs.statSync(target).isFile()) {
|
|
51
|
+
throw Object.assign(new Error(`Compiler entry must be a regular file within its checkout: ${name}`), { code: "compiler_entry_invalid" });
|
|
52
|
+
}
|
|
53
|
+
return target;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function runProcess(script, args, { cwd, timeout, signal }) {
|
|
57
|
+
return new Promise((resolve) => {
|
|
58
|
+
if (signal?.aborted) return resolve({ exit_code: null, signal: null, cancelled: true, timed_out: false, stdout: "", stderr: "" });
|
|
59
|
+
const child = spawn(process.execPath, [script, ...args], {
|
|
60
|
+
cwd, shell: false, detached: process.platform !== "win32", stdio: ["ignore", "pipe", "pipe"],
|
|
61
|
+
});
|
|
62
|
+
const logs = { stdout: Buffer.alloc(0), stderr: Buffer.alloc(0) };
|
|
63
|
+
const truncated = { stdout: false, stderr: false };
|
|
64
|
+
let timedOut = false;
|
|
65
|
+
let cancelled = false;
|
|
66
|
+
let spawnError;
|
|
67
|
+
let forceTimer;
|
|
68
|
+
const kill = (signalName) => {
|
|
69
|
+
try {
|
|
70
|
+
if (process.platform === "win32" && child.pid) {
|
|
71
|
+
spawnSync("taskkill", ["/PID", String(child.pid), "/T", "/F"], { stdio: "ignore", windowsHide: true, timeout: 5000 });
|
|
72
|
+
}
|
|
73
|
+
else if (child.pid) process.kill(-child.pid, signalName);
|
|
74
|
+
} catch (error) { if (error.code !== "ESRCH") spawnError ??= error.message; }
|
|
75
|
+
};
|
|
76
|
+
const stop = () => {
|
|
77
|
+
kill("SIGTERM");
|
|
78
|
+
forceTimer ??= setTimeout(() => kill("SIGKILL"), 1000);
|
|
79
|
+
forceTimer.unref();
|
|
80
|
+
};
|
|
81
|
+
const abort = () => { cancelled = true; stop(); };
|
|
82
|
+
const timer = setTimeout(() => { timedOut = true; stop(); }, timeout);
|
|
83
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
84
|
+
if (signal?.aborted) abort();
|
|
85
|
+
for (const channel of ["stdout", "stderr"]) child[channel].on("data", (chunk) => {
|
|
86
|
+
const combined = Buffer.concat([logs[channel], chunk]);
|
|
87
|
+
truncated[channel] ||= combined.length > logLimit;
|
|
88
|
+
logs[channel] = combined.subarray(Math.max(0, combined.length - logLimit));
|
|
89
|
+
});
|
|
90
|
+
child.on("error", (error) => { spawnError = error.message; });
|
|
91
|
+
child.on("close", (exitCode, exitSignal) => {
|
|
92
|
+
clearTimeout(timer);
|
|
93
|
+
if (forceTimer) { kill("SIGKILL"); clearTimeout(forceTimer); }
|
|
94
|
+
signal?.removeEventListener("abort", abort);
|
|
95
|
+
resolve({
|
|
96
|
+
exit_code: exitCode, signal: exitSignal, timed_out: timedOut, cancelled,
|
|
97
|
+
stdout: logs.stdout.toString("utf8"), stderr: logs.stderr.toString("utf8"),
|
|
98
|
+
stdout_truncated: truncated.stdout, stderr_truncated: truncated.stderr,
|
|
99
|
+
...(spawnError ? { spawn_error: spawnError } : {}),
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export async function executeCompiler(operation, input = {}, config = {}) {
|
|
106
|
+
const spec = Object.hasOwn(compilerOperations, operation) ? compilerOperations[operation] : null;
|
|
107
|
+
if (!spec && operation !== "workflow") return failure(operation, "command_unknown", `Unknown compiler command: ${operation}`);
|
|
108
|
+
const parsed = (operation === "workflow" ? workflowSchema : spec.schema).safeParse(input);
|
|
109
|
+
if (!parsed.success) return failure(operation, "input_invalid", parsed.error.message);
|
|
110
|
+
try {
|
|
111
|
+
const compiler = compilerLocation(config);
|
|
112
|
+
if (operation === "workflow") {
|
|
113
|
+
const name = parsed.data.document === "readme" ? "README.md" : "SKILL.md";
|
|
114
|
+
const bytes = fs.readFileSync(checkedFile(compiler.root, name));
|
|
115
|
+
return { ok: true, operation, result: { compiler, source: name, sha256: hash(bytes), text: bytes.toString("utf8"), contracts: compilerDiscovery(config).contracts, ...handoff } };
|
|
116
|
+
}
|
|
117
|
+
const script = checkedFile(compiler.root, spec.script);
|
|
118
|
+
const scriptHash = hash(fs.readFileSync(script));
|
|
119
|
+
const values = { ...parsed.data };
|
|
120
|
+
const timeout = values.runner_timeout_ms ?? 1800000;
|
|
121
|
+
delete values.runner_timeout_ms;
|
|
122
|
+
if (operation === "transcribe" || operation === "build") values.stylegallery ??= galleryRoot;
|
|
123
|
+
for (const key of spec.paths) if (values[key] !== undefined) values[key] = path.resolve(config.cwd ?? process.cwd(), values[key]);
|
|
124
|
+
if (operation === "sale") {
|
|
125
|
+
if (values.in === values.out) return failure(operation, "input_invalid", "sale requires a separate output directory.");
|
|
126
|
+
values.audit ??= path.join(path.dirname(values.out), "copy-audit.private.json");
|
|
127
|
+
const relative = path.relative(values.out, values.audit);
|
|
128
|
+
if (relative === "" || (!relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative))) {
|
|
129
|
+
return failure(operation, "input_invalid", "The private copy audit must be outside the sale directory.");
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
const args = [];
|
|
133
|
+
for (const key of spec.positional ?? []) args.push(values[key]);
|
|
134
|
+
for (const [key, value] of Object.entries(values)) {
|
|
135
|
+
if (spec.positional?.includes(key) || value === false) continue;
|
|
136
|
+
args.push(`--${key.replaceAll("_", "-")}`);
|
|
137
|
+
if (value !== true) args.push(String(value));
|
|
138
|
+
}
|
|
139
|
+
const execution = await runProcess(script, args, { cwd: compiler.root, timeout, signal: config.signal });
|
|
140
|
+
const ok = execution.exit_code === 0 && !execution.timed_out && !execution.cancelled && !execution.spawn_error;
|
|
141
|
+
const result = {
|
|
142
|
+
compiler, script: spec.script, script_sha256: scriptHash,
|
|
143
|
+
arguments: args, paths: Object.fromEntries(spec.paths.filter((key) => values[key] !== undefined).map((key) => [key, values[key]])),
|
|
144
|
+
...execution, ...handoff,
|
|
145
|
+
...(spec.ledger ? { ledger: path.join(values.out ?? values.in, spec.ledger), success_scope: "process_exit_only; inspect ledger for each pack" } : {}),
|
|
146
|
+
...(operation === "pack-release" ? { output: path.join(compiler.root, "out/release") } : {}),
|
|
147
|
+
};
|
|
148
|
+
return {
|
|
149
|
+
ok, operation, result,
|
|
150
|
+
...(!ok ? { failures: [{
|
|
151
|
+
code: execution.cancelled ? "compiler_cancelled" : execution.timed_out ? "compiler_timeout" : "compiler_failed",
|
|
152
|
+
message: execution.spawn_error ?? (execution.cancelled ? "Compiler execution cancelled." : execution.timed_out ? `Compiler exceeded ${timeout}ms.` : `Compiler exited with ${execution.exit_code ?? execution.signal}.`),
|
|
153
|
+
}] } : {}),
|
|
154
|
+
};
|
|
155
|
+
} catch (error) { return failure(operation, error.code ?? "compiler_unavailable", error.message); }
|
|
156
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
try {
|
|
4
|
+
const { runSgCli } = await import("./compiler/cli.mjs");
|
|
5
|
+
const controller = new AbortController();
|
|
6
|
+
const cancel = () => controller.abort();
|
|
7
|
+
process.once("SIGINT", cancel);
|
|
8
|
+
process.once("SIGTERM", cancel);
|
|
9
|
+
try {
|
|
10
|
+
const result = await runSgCli(process.argv.slice(2), { signal: controller.signal });
|
|
11
|
+
process.stdout.write(result.output);
|
|
12
|
+
process.exitCode = result.exitCode;
|
|
13
|
+
} finally {
|
|
14
|
+
process.removeListener("SIGINT", cancel);
|
|
15
|
+
process.removeListener("SIGTERM", cancel);
|
|
16
|
+
}
|
|
17
|
+
} catch (error) {
|
|
18
|
+
process.stdout.write(`${JSON.stringify({ ok: false, operation: null, failures: [{ code: error.code ?? "cli_failed", message: error.message }] }, null, 2)}\n`);
|
|
19
|
+
process.exitCode = 1;
|
|
20
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { createSgMcpServer } from "./compiler/mcp.mjs";
|
|
5
|
+
|
|
6
|
+
try {
|
|
7
|
+
const controller = new AbortController();
|
|
8
|
+
const server = createSgMcpServer({ signal: controller.signal });
|
|
9
|
+
const shutdown = () => {
|
|
10
|
+
controller.abort();
|
|
11
|
+
server.close().catch(() => {});
|
|
12
|
+
};
|
|
13
|
+
process.once("SIGINT", shutdown);
|
|
14
|
+
process.once("SIGTERM", shutdown);
|
|
15
|
+
process.stdin.once("end", shutdown);
|
|
16
|
+
await server.connect(new StdioServerTransport());
|
|
17
|
+
} catch (error) {
|
|
18
|
+
process.stderr.write(`${error.message}\n`);
|
|
19
|
+
process.exitCode = 1;
|
|
20
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Showcase Guide
|
|
3
|
+
title: Showcase
|
|
4
|
+
description: Free-form, single-page expressive works checked by outcome instead of authoring rules.
|
|
5
|
+
lifecycle: experimental
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Showcase
|
|
9
|
+
|
|
10
|
+
Primary role: expressive work area.
|
|
11
|
+
|
|
12
|
+
`showcase/` holds complete, expressive pages: brand studies, landing pages, and art-directed experiments. The Layout authoring rules do not apply here. A work may use any CSS property, any selector, gradients, blend modes, WebGL, GSAP, Lenis, or its own fonts. Layout still sets the floor: a work has to pass the outcome checks below. It does not have to follow the pattern CSS style guide.
|
|
13
|
+
|
|
14
|
+
## Why It Exists
|
|
15
|
+
|
|
16
|
+
Reusable Layout patterns exclude decorative styling so they stay portable. That rule is correct for `patterns/**`, but it made the repository unable to express a finished product page. Showcase is the product layer where the finished page lives. It depends on Layout and Expression. Nothing depends on it.
|
|
17
|
+
|
|
18
|
+
## Work Contract
|
|
19
|
+
|
|
20
|
+
Each work is one directory, `showcase/<slug>/`, containing:
|
|
21
|
+
|
|
22
|
+
- `index.html`: the entry page. It may load local files or pinned CDN libraries.
|
|
23
|
+
- `brief.md`: the direction, frontmatter with `type: Showcase Brief`, `title`, `description`, and `brand_study: true|false`.
|
|
24
|
+
- Any other local assets the page needs.
|
|
25
|
+
|
|
26
|
+
A brand study (`brand_study: true`) reinterprets a named real brand. It additionally requires:
|
|
27
|
+
|
|
28
|
+
- `subject:` in the brief frontmatter, naming the brand being studied.
|
|
29
|
+
- `<meta name="robots" content="noindex, nofollow">` in `index.html`.
|
|
30
|
+
- Visible text containing "Unofficial" on the page.
|
|
31
|
+
- No copied logos, trademarks as artwork, or verbatim marketing copy. Write original copy in the brand's register instead.
|
|
32
|
+
|
|
33
|
+
See [Brand Studies](../expression/brand-studies.md) for the reasoning and limits.
|
|
34
|
+
|
|
35
|
+
## Brief Template
|
|
36
|
+
|
|
37
|
+
```md
|
|
38
|
+
---
|
|
39
|
+
type: Showcase Brief
|
|
40
|
+
title: <Work name>
|
|
41
|
+
description: <One sentence: what the page is and what it should feel like.>
|
|
42
|
+
brand_study: false
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
# <Work name>
|
|
46
|
+
|
|
47
|
+
## Direction
|
|
48
|
+
Reference, mood, and the one thing a visitor should remember.
|
|
49
|
+
|
|
50
|
+
## System
|
|
51
|
+
Type pairing, palette, texture, and motion density, with actual values or a link to an Expression direction.
|
|
52
|
+
|
|
53
|
+
## Techniques
|
|
54
|
+
Expression and Motion technique pages the work uses.
|
|
55
|
+
|
|
56
|
+
## Layout Floor
|
|
57
|
+
Scroll owner, pinned or sticky regions, and how the page collapses at 320px.
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Preview
|
|
61
|
+
|
|
62
|
+
```sh
|
|
63
|
+
bun run showcase:serve # http://localhost:4180/ (hub) and one URL per work
|
|
64
|
+
bun run showcase:serve -- --port 4190
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Working on a remote machine over SSH? Run this on your own machine, then open `http://localhost:4180/` in your local browser:
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
ssh -N -L 4180:127.0.0.1:4180 <user>@<remote-host>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The serve command prints this line with the right user and host filled in. Fonts and libraries load from CDNs in the visitor's browser, so the local machine needs internet access.
|
|
74
|
+
|
|
75
|
+
Once any work exists, `showcase/index.html` is the hub that lists every work: the first work creates it, every later work adds a card, and each work's footer links back to `../`.
|
|
76
|
+
|
|
77
|
+
## Outcome Checks
|
|
78
|
+
|
|
79
|
+
`bun run test:showcase` (or `node scripts/check-showcase.mjs --work <slug>`) runs the hub and every work in headless Chromium. Each check maps to a scenario in the [QA contract](QA.md):
|
|
80
|
+
|
|
81
|
+
| Check | Failure |
|
|
82
|
+
| --- | --- |
|
|
83
|
+
| Brief contract | Missing brief fields, or a brand study without `subject`, `noindex`, or visible "Unofficial" text. |
|
|
84
|
+
| Runtime and assets | Any uncaught page error, or any same-origin request answered with 4xx. Failed CDN requests alone are tolerated. |
|
|
85
|
+
| Horizontal overflow | Document wider than the viewport at 320, 768, or 1440 CSS pixels, at the top, middle, or bottom. |
|
|
86
|
+
| Focus | A tabbable element with no box, outside the viewport, covered by another element (such as a sticky header), or reached out of DOM order. |
|
|
87
|
+
| Reduced motion | With `prefers-reduced-motion: reduce`, a heading or paragraph invisible on arrival, or an infinite animation running. |
|
|
88
|
+
| Contrast | Text over a solid background below WCAG AA: 4.5:1, or 3:1 for large text. |
|
|
89
|
+
| Links and actions | A link to raw Markdown, an empty `#`, a missing `#id`, or `#top` outside the header; a `[data-demo]` action that is not a button, shows no visible `role="status"` message, or moves the page. |
|
|
90
|
+
| Identity | No title or no favicon. |
|
|
91
|
+
| Hash navigation | Clicking the first header nav link does not update the URL hash or lands its heading under the header or below the top half; Back does not return near the top; opening the last nav target's URL directly does not land on it. |
|
|
92
|
+
| Short viewport | At 1280x620, a fixed or pinned element that contains text is taller than the viewport. |
|
|
93
|
+
| Offscreen ambient | At 1440 wide, an infinite CSS animation or repeating GSAP tween still running on an element entirely offscreen. Mark ambient containers `data-ambient` and pause them with an IntersectionObserver. |
|
|
94
|
+
| Offline | With every non-local request blocked: page errors, hidden text, or overflow at 390 wide. |
|
|
95
|
+
| No script | With every script blocked: hidden text or overflow at 390 wide. |
|
|
96
|
+
| Hub | Works exist but `showcase/index.html` is missing, or a work directory it does not link. With no works, the check passes and reports that there is nothing to check. |
|
|
97
|
+
|
|
98
|
+
Fictional actions (subscribe, book, get a key) must be `<button type="button" data-demo="...">` elements that show an honest message in a `role="status"` region, never links that jump to the top.
|
|
99
|
+
|
|
100
|
+
Screenshots are taken after entrance tweens and CSS transitions settle and are written to `.tmp/showcase/<slug>/`. The checks do not judge taste: review the screenshots. `bun run test:showcase:self` proves each check can fail by running the checker against fixtures built to violate it.
|
|
101
|
+
|
|
102
|
+
## Works
|
|
103
|
+
|
|
104
|
+
The repository ships the contract, the checker, and the guidance, but no committed works. Works are built per project in `showcase/<slug>/` and must pass the checks above before they are shared.
|
|
105
|
+
|
|
106
|
+
## Starting A Work Fast
|
|
107
|
+
|
|
108
|
+
Read this page, one [Expression direction](../expression/index.md), and the [Motion techniques](../motion/techniques/scroll-choreography.md) you need. Skip governance, provenance, and consumer-reference documents: a showcase work creates no governed record. Build, add a hub card, run `bun run showcase:serve` and `node scripts/check-showcase.mjs --work <slug>`, look at the screenshots, and iterate.
|
|
109
|
+
|
|
110
|
+
## IA Navigation
|
|
111
|
+
|
|
112
|
+
Parent: [StyleGallery](../index.md).
|
|
113
|
+
Next: [Expression](../expression/index.md).
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: Domain Guide
|
|
3
|
-
title: Game UI Classification
|
|
4
|
-
description: Engine-neutral method for classifying game interfaces by player task, presentation, input, state, and motion.
|
|
5
|
-
domain: game-ui
|
|
6
|
-
lifecycle: experimental
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Game UI Classification
|
|
10
|
-
|
|
11
|
-
Primary role: game-interface classification guide.
|
|
12
|
-
|
|
13
|
-
## Repository Boundary
|
|
14
|
-
|
|
15
|
-
This guide proposes a local, project-neutral taxonomy for classifying observable game-interface behavior without assuming a specific engine or art direction. Its player-task classes and classification axes are review tools, not a universal ontology. It does not turn a visual genre into a functional category or authorize decorative properties in reusable Layout patterns.
|
|
16
|
-
|
|
17
|
-
## Reusable Method
|
|
18
|
-
|
|
19
|
-
1. Capture the rendered screen or interaction in context.
|
|
20
|
-
2. Assign one primary player-task class.
|
|
21
|
-
3. Add secondary classes only when the same surface genuinely composes responsibilities.
|
|
22
|
-
4. Record visual language, input, state, motion, and implementation as separate axes.
|
|
23
|
-
5. Attach evidence for default, exceptional, and transitional states.
|
|
24
|
-
6. State what is observed, inferred, and still unverified.
|
|
25
|
-
|
|
26
|
-
## Player-Task Classes
|
|
27
|
-
|
|
28
|
-
| Primary class | Player question | Typical examples |
|
|
29
|
-
| --- | --- | --- |
|
|
30
|
-
| `hud` | What is happening during play right now? | Health, ammo, objective, marker, cooldown |
|
|
31
|
-
| `navigation` | Where can I go next? | Main menu, pause menu, chapter or mode selection |
|
|
32
|
-
| `dialog` | What decision or interruption needs attention? | Confirmation, reconnect, privacy, system notice |
|
|
33
|
-
| `inventory` | What do I own, equip, compare, or improve? | Loadout, stash, equipment, crafting, upgrade |
|
|
34
|
-
| `progression` | What did I unlock or how am I advancing? | Results, level up, rewards, rank change |
|
|
35
|
-
| `commerce` | What can I acquire and at what cost? | Shop, offer, product detail, currency shortage |
|
|
36
|
-
| `tutorial` | What action should I learn or perform? | Coach mark, forced step, contextual hint |
|
|
37
|
-
| `narrative` | What story or authored event is being presented? | Dialogue, boss intro, cinematic overlay |
|
|
38
|
-
| `system-status` | Is the application ready and connected? | Splash, loading, sign-in, reconnect, patch status |
|
|
39
|
-
| `input-surface` | How do I directly control the game? | Virtual stick, action button, key binding |
|
|
40
|
-
|
|
41
|
-
## Classification Axes
|
|
42
|
-
|
|
43
|
-
| Axis | Example values | Evidence requirement |
|
|
44
|
-
| --- | --- | --- |
|
|
45
|
-
| World relationship | `diegetic`, `spatial`, `overlay`, `full-screen` | Capture placement relative to play space |
|
|
46
|
-
| Material character | `flat-graphic`, `framed`, `skeuomorphic`, `translucent`, `textural` | Capture repeated surface treatment |
|
|
47
|
-
| Genre signal | `tactical`, `industrial`, `fantasy-ornamental`, `arcade`, `horror`, `casual` | Show repeated shape, type, icon, and material cues |
|
|
48
|
-
| Information density | `sparse`, `standard`, `dense` | Count simultaneous choices and information groups |
|
|
49
|
-
| Emphasis model | `typographic`, `icon-led`, `character-led`, `item-led`, `effect-led` | Identify first and second attention targets |
|
|
50
|
-
| Input | pointer, keyboard, gamepad, touch, gaze, mixed | Exercise every declared input mode |
|
|
51
|
-
| Motion role | affordance, activation, state change, transition, value change, reward, guidance, ambient | Record trigger, properties, timing, and interruption |
|
|
52
|
-
|
|
53
|
-
## Opinionated Guidance
|
|
54
|
-
|
|
55
|
-
- Organize the gallery first by player task, then filter by presentation and implementation axes.
|
|
56
|
-
- Use two or three visual tags supported by repeated evidence.
|
|
57
|
-
- Classify independent player-task regions separately when a screen composes them.
|
|
58
|
-
- Do not infer style or behavior from project, prefab, widget, scene, or class names alone.
|
|
59
|
-
|
|
60
|
-
## Platform-Specific Guidance
|
|
61
|
-
|
|
62
|
-
Record engine, UI framework, render space, scaling policy, navigation system, text system, and motion system as implementation evidence. Route detailed engine hierarchy and API guidance to the matching engine-specific Game UI guide.
|
|
63
|
-
|
|
64
|
-
## Unsupported Absolutes
|
|
65
|
-
|
|
66
|
-
- A genre label does not establish a visual style.
|
|
67
|
-
- A screenshot does not prove responsive behavior, focus behavior, or motion interruption.
|
|
68
|
-
- A production project's folder structure is not a universal architecture.
|
|
69
|
-
- Similar appearance does not prove equivalent accessibility, performance, or interaction behavior.
|
|
70
|
-
|
|
71
|
-
## Verification Contract
|
|
72
|
-
|
|
73
|
-
Verify narrow and wide surfaces, every declared input mode, long localized text, empty and loading states, disabled and error states, repeated open and close, rapid selection changes, and interrupted motion where relevant.
|
|
74
|
-
|
|
75
|
-
## Source, License, And Attribution
|
|
76
|
-
|
|
77
|
-
This page is a locally authored, project-neutral proposed taxonomy. It reproduces no game assets, project-specific hierarchy, or upstream implementation samples.
|
|
78
|
-
|
|
79
|
-
## IA Navigation
|
|
80
|
-
|
|
81
|
-
Parent: [Game UI](index.md).
|
|
82
|
-
Next: [Game UI Screen Hierarchy](screen-hierarchy.md).
|
package/game-ui/decision-tree.md
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: Domain Guide
|
|
3
|
-
title: Game UI Decision Tree
|
|
4
|
-
description: Select player-task recipes, ownership boundaries, and engine routes from the screen's purpose.
|
|
5
|
-
domain: game-ui
|
|
6
|
-
lifecycle: experimental
|
|
7
|
-
provenance_kind: local
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# Game UI Decision Tree
|
|
11
|
-
|
|
12
|
-
Primary role: game screen planning route.
|
|
13
|
-
|
|
14
|
-
## Repository Boundary
|
|
15
|
-
|
|
16
|
-
This route selects game-interface responsibilities independently of engine and art direction. The [Classification](classification.md) remains the local taxonomy; the [Screen Hierarchy](screen-hierarchy.md) defines ownership roles.
|
|
17
|
-
|
|
18
|
-
## Reusable Method
|
|
19
|
-
|
|
20
|
-
1. Write the player's question while the interface is visible.
|
|
21
|
-
2. Choose one primary task class from the table below.
|
|
22
|
-
3. Decide whether play continues and which input actions must be blocked.
|
|
23
|
-
4. Assign lifetime, focus, sorting, and state ownership.
|
|
24
|
-
5. Adapt a [Screen Recipe](screen-recipes.md), then run the [Verification Workflow](verification-workflow.md).
|
|
25
|
-
|
|
26
|
-
## Player Task Route
|
|
27
|
-
|
|
28
|
-
| Player question | Primary class | Recipe |
|
|
29
|
-
| --- | --- | --- |
|
|
30
|
-
| What is happening during play? | `hud` | [Play status and input](screen-recipes.md#play-status-and-input) |
|
|
31
|
-
| How do I perform an action? | `input-surface` | [Play status and input](screen-recipes.md#play-status-and-input) |
|
|
32
|
-
| Where can I go, pause, or leave? | `navigation` | [Pause and navigation](screen-recipes.md#pause-and-navigation) |
|
|
33
|
-
| What decision requires attention? | `dialog` | [Blocking decisions and connection](screen-recipes.md#blocking-decisions-and-connection) |
|
|
34
|
-
| Is the game ready or connected? | `system-status` | [Blocking decisions and connection](screen-recipes.md#blocking-decisions-and-connection) |
|
|
35
|
-
| What can I equip or compare? | `inventory` | [Inventory and comparison](screen-recipes.md#inventory-and-comparison) |
|
|
36
|
-
| What have I earned or unlocked? | `progression` | [Results and progression](screen-recipes.md#results-and-progression) |
|
|
37
|
-
| What can I obtain, and at what cost? | `commerce` | [Offers and acquisition](screen-recipes.md#offers-and-acquisition) |
|
|
38
|
-
| What should I learn next? | `tutorial` | [Teaching and narrative](screen-recipes.md#teaching-and-narrative) |
|
|
39
|
-
| What story is being presented? | `narrative` | [Teaching and narrative](screen-recipes.md#teaching-and-narrative) |
|
|
40
|
-
|
|
41
|
-
If a screen contains several tasks, classify regions independently. A purchase confirmation inside an inventory screen is a dialog owned by a commerce operation; it is not another inventory slot.
|
|
42
|
-
|
|
43
|
-
## Ownership Decisions
|
|
44
|
-
|
|
45
|
-
| Decision | Record before implementing |
|
|
46
|
-
| --- | --- |
|
|
47
|
-
| Lifetime | Application, session, scene, screen, entity, or one operation |
|
|
48
|
-
| Play relationship | Continues, pauses locally, or requests a networked pause; identify authority |
|
|
49
|
-
| Input | Active action map, focus owner, pointer/gamepad coexistence, cancellation |
|
|
50
|
-
| Ordering | Screen, HUD, world-linked, modal, or transient host; name competing hosts |
|
|
51
|
-
| Data | Authoritative state versus preview, selection, pending operation and stale data |
|
|
52
|
-
| Exit | What is restored, destroyed, retained, or reconciled |
|
|
53
|
-
|
|
54
|
-
## Worked Selection
|
|
55
|
-
|
|
56
|
-
A loadout screen shows owned equipment, character attributes, and a purchase button for an unavailable slot. Inventory is primary; comparison is a supporting region. The purchase flow is commerce and any confirmation is a modal decision. Closing the modal returns to the same slot. Losing connection updates operation status without clearing the loadout selection. A server response after the screen closes belongs to the operation owner, not a destroyed view.
|
|
57
|
-
|
|
58
|
-
## Opinionated Guidance
|
|
59
|
-
|
|
60
|
-
Separate the player's task from visual genre. Assign one cancellation owner for each active layer so the same Back/Cancel input does not dismiss a dialog and its parent screen together.
|
|
61
|
-
|
|
62
|
-
## Platform-Specific Guidance
|
|
63
|
-
|
|
64
|
-
For Unity, select the [UI System](unity/ui-systems.md), map [Architecture](unity/architecture.md), then use the [CLI Loop](unity/cli-loop.md) for the declared stack. Other engines retain these role contracts but require their own verified API mapping; no cross-engine runtime equivalence is claimed.
|
|
65
|
-
|
|
66
|
-
## Unsupported Absolutes
|
|
67
|
-
|
|
68
|
-
A pause menu does not imply multiplayer simulation can pause. Hierarchy order does not prove input blocking, focus, or sorting. A taxonomy label does not establish rendered behavior.
|
|
69
|
-
|
|
70
|
-
## Verification Contract
|
|
71
|
-
|
|
72
|
-
Check one ordinary screen, one overlay composition, and one unexpected interruption such as disconnection or scene teardown. Every active layer needs a named lifetime, input, sorting, and exit owner. Revisit the route if a real player task cannot be classified without forcing unrelated responsibilities together.
|
|
73
|
-
|
|
74
|
-
## Source, License, And Attribution
|
|
75
|
-
|
|
76
|
-
Locally authored route and fictional loadout case. It imports no game assets, third-party hierarchy, or engine code.
|
|
77
|
-
|
|
78
|
-
## IA Navigation
|
|
79
|
-
|
|
80
|
-
Parent: [Game UI](index.md).
|
|
81
|
-
Next: [Game UI Screen Recipes](screen-recipes.md).
|
package/game-ui/index.md
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# Game UI
|
|
2
|
-
|
|
3
|
-
Game UI owns engine-neutral guidance for game-interface purpose, presentation, screen hierarchy, and evidence records, plus named engine implementation guides.
|
|
4
|
-
|
|
5
|
-
## Scope Boundary
|
|
6
|
-
|
|
7
|
-
In scope: player-task classification, screen and overlay hierarchy, reusable reference metadata, state coverage, cross-engine comparison vocabulary, and engine-specific implementation guidance.
|
|
8
|
-
|
|
9
|
-
Out of scope: reusable Layout CSS, universal visual prescriptions, and treating one engine's scene graph or API as a cross-engine requirement.
|
|
10
|
-
|
|
11
|
-
## Evidence And Research Boundary
|
|
12
|
-
|
|
13
|
-
The player-task classes and classification axes are a local taxonomy proposed for StyleGallery review, not Interface In Game's universal ontology.
|
|
14
|
-
|
|
15
|
-
Interface In Game was reviewed on 2026-07-14 through its [home page](https://interfaceingame.com/), [games index](https://interfaceingame.com/games/), and representative records for [Team Fortress 2](https://interfaceingame.com/games/team-fortress-2/), [Genshin Impact (Mobile)](https://interfaceingame.com/games/genshin-impact-mobile/), and [Gris](https://interfaceingame.com/games/gris/). In this bounded sample, the site exposed site-local facets such as Genres, Themes, and Platforms, while screenshots used Elements. The sample informs the local separation of player task from other axes; it does not cover the archive or establish the site's full information model.
|
|
16
|
-
|
|
17
|
-
## Start Here
|
|
18
|
-
|
|
19
|
-
| Task | Route |
|
|
20
|
-
| --- | --- |
|
|
21
|
-
| Choose by player task and ownership. | [Game UI Decision Tree](decision-tree.md) |
|
|
22
|
-
| Compose all ten player-task classes with failure cases. | [Game UI Screen Recipes](screen-recipes.md) |
|
|
23
|
-
| Record input, state, hierarchy, and teardown evidence. | [Game UI Verification Workflow](verification-workflow.md) |
|
|
24
|
-
|
|
25
|
-
These workflows and worked cases are usable experimental guidance. Expected-result tables are test designs; actual product, engine, and reader evidence must be recorded separately. Review on a failed task, a source change, or a changed ownership contract.
|
|
26
|
-
|
|
27
|
-
## Available Guides
|
|
28
|
-
|
|
29
|
-
- [Game UI Classification](classification.md) separates player purpose from visual language, input, state, and motion.
|
|
30
|
-
- [Game UI Screen Hierarchy](screen-hierarchy.md) defines engine-neutral layers from application shell to atomic control.
|
|
31
|
-
- [Game UI Reference Record](reference-record.md) provides the minimum evidence schema for gallery entries.
|
|
32
|
-
- [Unity UI Architecture](unity/architecture.md) maps the hierarchy roles to Unity Scenes, Canvas layers, prefabs, runtime instances, input, and motion ownership.
|
|
33
|
-
- [Unity UI Systems](unity/ui-systems.md) compares uGUI, UI Toolkit, and NGUI ownership and capability shapes at pinned sources.
|
|
34
|
-
- [Unity CLI Loop](unity/cli-loop.md) defines a source-pinned command loop for Unity UI inspection and stack-specific interaction evidence.
|
|
35
|
-
- [Unity Repository Map](unity/repository-map.md) maps the public Unity-Technologies repository snapshot by UI relevance, authority, and lifecycle.
|
|
36
|
-
- [Unity Organization Compressed Wiki](unity/org-wiki.md) routes all 804 captured public repositories through a tracked inventory and bounded exclusive clusters.
|
|
37
|
-
|
|
38
|
-
## Domain Contract
|
|
39
|
-
|
|
40
|
-
Game UI describes interface purpose, screen composition, and how named engines can realize that model. Platform Guides cover non-game platform conventions; Layout owns portable spatial patterns.
|
|
41
|
-
|
|
42
|
-
## IA Navigation
|
|
43
|
-
|
|
44
|
-
Parent: [StyleGallery](../index.md).
|
|
45
|
-
Next: [Game UI Decision Tree](decision-tree.md).
|