devlyn-cli 1.8.1 → 1.9.1
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/CLAUDE.md +6 -2
- package/README.md +5 -3
- package/bin/devlyn.js +1 -0
- package/config/skills/devlyn:auto-resolve/SKILL.md +62 -2
- package/config/skills/devlyn:auto-resolve/references/build-gate.md +116 -0
- package/config/skills/devlyn:preflight/references/auditors/code-auditor.md +13 -0
- package/optional-skills/asset-creator/CATALOG-SCHEMA.md +99 -0
- package/optional-skills/asset-creator/SKILL.md +291 -0
- package/optional-skills/asset-creator/STYLE-GUIDE.md +174 -0
- package/package.json +1 -1
package/CLAUDE.md
CHANGED
|
@@ -56,13 +56,17 @@ For hands-free build-evaluate-polish cycles — works for bugs, features, refact
|
|
|
56
56
|
/devlyn:auto-resolve [task description]
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
This runs the full pipeline automatically: **Build → Browser Validate → Evaluate → Fix Loop → Simplify → Review → Security Review → Clean → Docs**. Each phase runs as a separate subagent with its own context. Communication between phases happens via files (`.devlyn/done-criteria.md`, `.devlyn/EVAL-FINDINGS.md`, `.devlyn/BROWSER-RESULTS.md`).
|
|
59
|
+
This runs the full pipeline automatically: **Build → Build Gate → Browser Validate → Evaluate → Fix Loop → Simplify → Review → Security Review → Clean → Docs**. Each phase runs as a separate subagent with its own context. Communication between phases happens via files (`.devlyn/done-criteria.md`, `.devlyn/BUILD-GATE.md`, `.devlyn/EVAL-FINDINGS.md`, `.devlyn/BROWSER-RESULTS.md`).
|
|
60
|
+
|
|
61
|
+
The **Build Gate** (Phase 1.4) runs real compilers, typecheckers, and linters — the same commands CI/Docker/production will run. It auto-detects project types (Next.js, Rust, Go, Solidity, Expo, Swift, etc.) and Dockerfiles. This is the primary defense against "tests pass locally, breaks in CI/Docker" class of bugs (type errors in un-tested files, cross-package drift, Dockerfile copy mismatches).
|
|
60
62
|
|
|
61
63
|
For web projects, the Browser Validate phase starts the dev server and tests the implemented feature in a real browser — clicking buttons, filling forms, verifying results. If the feature doesn't work, findings feed back into the fix loop.
|
|
62
64
|
|
|
63
65
|
Optional flags:
|
|
64
66
|
- `--max-rounds 6` — increase max evaluate-fix iterations (default: 4)
|
|
65
67
|
- `--skip-browser` — skip browser validation phase (auto-skipped for non-web changes)
|
|
68
|
+
- `--skip-build-gate` — skip the deterministic build gate (not recommended)
|
|
69
|
+
- `--build-gate strict` — treat warnings as errors; `--build-gate no-docker` — skip Docker builds for speed
|
|
66
70
|
- `--skip-review` — skip team-review phase
|
|
67
71
|
- `--skip-clean` — skip clean phase
|
|
68
72
|
- `--skip-docs` — skip update-docs phase
|
|
@@ -76,7 +80,7 @@ After completing a roadmap (or a phase), verify that everything was actually imp
|
|
|
76
80
|
/devlyn:preflight
|
|
77
81
|
```
|
|
78
82
|
|
|
79
|
-
This reads every commitment from VISION.md, ROADMAP.md, and item specs, then audits the codebase evidence-based.
|
|
83
|
+
This reads every commitment from VISION.md, ROADMAP.md, and item specs, then audits the codebase evidence-based. The code auditor now runs real build/typecheck commands as its first step — any project that doesn't compile is flagged as BROKEN at CRITICAL severity before individual commitments are even checked. Also checks in the browser for web projects.
|
|
80
84
|
|
|
81
85
|
Output: `.devlyn/PREFLIGHT-REPORT.md` with categorized findings (MISSING, INCOMPLETE, DIVERGENT, BROKEN, STALE_DOC). Confirmed gaps can be promoted to new roadmap items for auto-resolve.
|
|
82
86
|
|
package/README.md
CHANGED
|
@@ -65,18 +65,20 @@ Point it at a spec (or just describe what you want) and walk away.
|
|
|
65
65
|
/devlyn:auto-resolve "Implement per spec at docs/roadmap/phase-1/1.1-user-auth.md"
|
|
66
66
|
```
|
|
67
67
|
|
|
68
|
-
It runs a **
|
|
68
|
+
It runs a **10-phase pipeline** autonomously:
|
|
69
69
|
|
|
70
70
|
```
|
|
71
|
-
Build → Browser Test → Evaluate → Fix Loop → Simplify → Review → Security → Clean → Docs
|
|
71
|
+
Build → Build Gate → Browser Test → Evaluate → Fix Loop → Simplify → Review → Security → Clean → Docs
|
|
72
72
|
```
|
|
73
73
|
|
|
74
74
|
- Each phase runs as a separate agent with fresh context
|
|
75
75
|
- Git checkpoints at every phase for safe rollback
|
|
76
|
+
- **Build Gate** runs your project's real compilers, typecheckers, and linters — catches type errors, cross-package drift, and Docker build failures that tests alone miss. Auto-detects project type (Next.js, Rust, Go, Solidity, Expo, Swift, and more) and Dockerfiles.
|
|
76
77
|
- Browser validation tests your feature end-to-end (clicks, forms, verification)
|
|
77
78
|
- Evaluation grades against done-criteria — if it fails, auto-fix and re-evaluate
|
|
78
79
|
|
|
79
|
-
Skip phases you don't need: `--skip-browser`, `--skip-review`, `--skip-clean`, `--skip-docs`, `--max-rounds 6`
|
|
80
|
+
Skip phases you don't need: `--skip-browser`, `--skip-review`, `--skip-clean`, `--skip-docs`, `--skip-build-gate`, `--max-rounds 6`
|
|
81
|
+
Customize the build gate: `--build-gate strict` (warnings = errors), `--build-gate no-docker` (skip Docker builds for speed)
|
|
80
82
|
|
|
81
83
|
### Step 3 — Verify with `/devlyn:preflight`
|
|
82
84
|
|
package/bin/devlyn.js
CHANGED
|
@@ -138,6 +138,7 @@ ${g} v${PKG.version} ${COLORS.dim}· ${k}🍩 by Nocodecat @ Donu
|
|
|
138
138
|
|
|
139
139
|
const OPTIONAL_ADDONS = [
|
|
140
140
|
// Local optional skills (copied to .claude/skills/)
|
|
141
|
+
{ name: 'asset-creator', desc: 'AI pixel art game asset pipeline — generate, chroma-key, catalog', type: 'local' },
|
|
141
142
|
{ name: 'cloudflare-nextjs-setup', desc: 'Cloudflare Workers + Next.js deployment with OpenNext', type: 'local' },
|
|
142
143
|
{ name: 'generate-skill', desc: 'Create well-structured Claude Code skills following Anthropic best practices', type: 'local' },
|
|
143
144
|
{ name: 'prompt-engineering', desc: 'Claude 4 prompt optimization using Anthropic best practices', type: 'local' },
|
|
@@ -31,6 +31,8 @@ This pipeline runs hands-free. The user launches it to walk away and come back t
|
|
|
31
31
|
- `--skip-clean` (false) — skip clean phase
|
|
32
32
|
- `--skip-browser` (false) — skip browser validation phase (auto-skipped for non-web changes)
|
|
33
33
|
- `--skip-docs` (false) — skip update-docs phase
|
|
34
|
+
- `--skip-build-gate` (false) — skip the deterministic build gate (Phase 1.4). Not recommended — the build gate is the primary defense against "tests pass locally, breaks in CI/Docker/production" class of bugs.
|
|
35
|
+
- `--build-gate MODE` (auto) — controls build gate behavior. `auto`: detect project type and run appropriate build/typecheck/lint commands; if Dockerfile(s) are present, Docker builds are included automatically. `strict`: auto + treat warnings as errors. `no-docker`: auto but skip Docker builds even if Dockerfiles exist (for faster iteration). `skip`: same as --skip-build-gate.
|
|
34
36
|
- `--with-codex` (false) — use OpenAI Codex as a cross-model evaluator/reviewer via `mcp__codex-cli__*` MCP tools. Accepts: `evaluate`, `review`, or `both` (default when flag is present without value). When enabled, Codex provides an independent second opinion from a different model family, creating a GAN-like dynamic where Claude builds and Codex critiques.
|
|
35
37
|
|
|
36
38
|
Flags can be passed naturally: `/devlyn:auto-resolve fix the auth bug --max-rounds 3 --skip-docs`
|
|
@@ -43,7 +45,7 @@ This pipeline runs hands-free. The user launches it to walk away and come back t
|
|
|
43
45
|
```
|
|
44
46
|
Auto-resolve pipeline starting
|
|
45
47
|
Task: [extracted task description]
|
|
46
|
-
Phases: Build → [Browser] → Evaluate → [Fix loop if needed] → Simplify → [Review] → [Security] → [Clean] → [Docs]
|
|
48
|
+
Phases: Build → Build Gate → [Browser] → Evaluate → [Fix loop if needed] → Simplify → [Review] → [Security] → [Clean] → [Docs]
|
|
47
49
|
Max evaluation rounds: [N]
|
|
48
50
|
Cross-model evaluation (Codex): [evaluate / review / both / disabled]
|
|
49
51
|
```
|
|
@@ -86,6 +88,63 @@ The task is: [paste the task description here]
|
|
|
86
88
|
3. If no changes were made, report failure and stop
|
|
87
89
|
4. **Checkpoint**: Run `git add -A && git commit -m "chore(pipeline): phase 1 — build complete"` to create a rollback point
|
|
88
90
|
|
|
91
|
+
## PHASE 1.4: BUILD GATE
|
|
92
|
+
|
|
93
|
+
Skip if `--skip-build-gate` or `--build-gate skip` was set.
|
|
94
|
+
|
|
95
|
+
This phase runs the project's real build, typecheck, and lint commands — the same ones CI, Docker, and production environments will run. It catches the entire class of bugs that LLM-based evaluation and test suites cannot: type errors in un-tested files, cross-package type drift in monorepos, lint violations, missing production dependencies, and Dockerfile copy mismatches.
|
|
96
|
+
|
|
97
|
+
This is deterministic — if the compiler says no, the pipeline stops. No LLM judgment involved.
|
|
98
|
+
|
|
99
|
+
Spawn a subagent using the Agent tool with `mode: "bypassPermissions"`.
|
|
100
|
+
|
|
101
|
+
Agent prompt — pass this to the Agent tool:
|
|
102
|
+
|
|
103
|
+
You are the build gate agent. Read `references/build-gate.md` from the auto-resolve skill directory for the full project-type detection matrix and execution rules.
|
|
104
|
+
|
|
105
|
+
Your job: detect every project type in this repo, run their build/typecheck/lint commands, and report results. You do NOT reason about code quality — you run commands and faithfully report what they output.
|
|
106
|
+
|
|
107
|
+
1. Read the detection matrix in `references/build-gate.md`
|
|
108
|
+
2. Scan the repo to detect all matching project types (a monorepo may match several)
|
|
109
|
+
3. Detect the package manager (npm/pnpm/yarn/bun) per the rules in the reference file
|
|
110
|
+
4. Run all gate commands. Sequential within a project type, parallel across unrelated types.
|
|
111
|
+
5. If `--build-gate strict` is set, apply strict-mode flags per the reference file
|
|
112
|
+
6. Run Dockerfile builds if Dockerfiles are detected, UNLESS `--build-gate no-docker` is set (see reference file)
|
|
113
|
+
7. Write results to `.devlyn/BUILD-GATE.md` following the output format in the reference file
|
|
114
|
+
|
|
115
|
+
For failures: include the FULL error output (not truncated) and extract root file:line references with concrete fix guidance so the fix agent knows exactly where to look.
|
|
116
|
+
|
|
117
|
+
**After the agent completes**:
|
|
118
|
+
1. Read `.devlyn/BUILD-GATE.md`
|
|
119
|
+
2. Extract verdict
|
|
120
|
+
3. Branch:
|
|
121
|
+
- `PASS` → continue to PHASE 1.5
|
|
122
|
+
- `FAIL` → go to PHASE 1.4-fix (build gate fix loop)
|
|
123
|
+
|
|
124
|
+
## PHASE 1.4-fix: BUILD GATE FIX LOOP
|
|
125
|
+
|
|
126
|
+
Triggered only when PHASE 1.4 returns FAIL.
|
|
127
|
+
|
|
128
|
+
Track a round counter (shared with the main fix loop counter against `max-rounds`). If `round >= max-rounds`, stop with a clear failure report — do NOT continue to evaluate/browser/etc. Code that doesn't build cannot be meaningfully evaluated or tested.
|
|
129
|
+
|
|
130
|
+
Spawn a subagent using the Agent tool with `mode: "bypassPermissions"`.
|
|
131
|
+
|
|
132
|
+
Agent prompt — pass this to the Agent tool:
|
|
133
|
+
|
|
134
|
+
Read `.devlyn/BUILD-GATE.md` — it contains deterministic build/typecheck/lint failures from real compiler output. These are not opinions; the compiler rejected this code. Fix every listed failure at the root cause level.
|
|
135
|
+
|
|
136
|
+
For each failure:
|
|
137
|
+
1. Read the referenced file:line and enough surrounding context to understand the error
|
|
138
|
+
2. For type errors: check BOTH sides of the type contract — the consumer AND the type definition. The fix may belong to either side. Do NOT suppress errors with `any`, `@ts-ignore`, `as unknown as`, `// eslint-disable`, or equivalent escape hatches.
|
|
139
|
+
3. For lint errors: fix the underlying issue, do not disable the rule.
|
|
140
|
+
4. For missing module/dependency errors: investigate the cause — it may be a missing dep in package.json, a typo in the import path, or a tsconfig paths misconfiguration.
|
|
141
|
+
5. After fixing, do NOT re-run the build yourself. The orchestrator re-runs PHASE 1.4.
|
|
142
|
+
|
|
143
|
+
**After the agent completes**:
|
|
144
|
+
1. **Checkpoint**: `git add -A && git commit -m "chore(pipeline): build gate fix round [N]"`
|
|
145
|
+
2. Increment round counter
|
|
146
|
+
3. Go back to PHASE 1.4 (re-run the gate)
|
|
147
|
+
|
|
89
148
|
## PHASE 1.5: BROWSER VALIDATE (conditional)
|
|
90
149
|
|
|
91
150
|
Skip if `--skip-browser` was set.
|
|
@@ -284,7 +343,7 @@ Synchronize documentation with recent code changes. Use `git log --oneline -20`
|
|
|
284
343
|
After all phases complete:
|
|
285
344
|
|
|
286
345
|
1. Clean up temporary files:
|
|
287
|
-
- Delete the `.devlyn/` directory entirely (contains done-criteria.md, EVAL-FINDINGS.md, BROWSER-RESULTS.md, screenshots/, playwright temp files)
|
|
346
|
+
- Delete the `.devlyn/` directory entirely (contains done-criteria.md, BUILD-GATE.md, EVAL-FINDINGS.md, BROWSER-RESULTS.md, screenshots/, playwright temp files)
|
|
288
347
|
- Kill any dev server process still running from browser validation
|
|
289
348
|
|
|
290
349
|
2. Run `git log --oneline -10` to show commits made during the pipeline
|
|
@@ -300,6 +359,7 @@ After all phases complete:
|
|
|
300
359
|
| Phase | Status | Notes |
|
|
301
360
|
|-------|--------|-------|
|
|
302
361
|
| Build (team-resolve) | [completed] | [brief summary] |
|
|
362
|
+
| Build gate | [completed / skipped / FAIL after N rounds] | [project types detected, commands run, pass/fail per command] |
|
|
303
363
|
| Browser validate | [completed / skipped / auto-skipped] | [verdict, tier used, console errors, flow results] |
|
|
304
364
|
| Evaluate (Claude) | [PASS/NEEDS WORK after N rounds] | [verdict + key findings] |
|
|
305
365
|
| Evaluate (Codex) | [completed / skipped] | [Codex-only findings count, merged verdict] |
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Build Gate — Project Type Detection & Commands
|
|
2
|
+
|
|
3
|
+
Reference for PHASE 1.4 (Build Gate). The build gate agent reads this file to determine which commands to run.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Project Type Detection Matrix
|
|
8
|
+
|
|
9
|
+
Inspect the repository root and subdirectories (up to 2 levels). A repo can match **multiple** signals — run ALL matching gates. Do not pick "the main one"; a monorepo with a Next.js dashboard + Rust service needs both.
|
|
10
|
+
|
|
11
|
+
| Signal file(s) | Project type | Gate commands (run in order) |
|
|
12
|
+
|---|---|---|
|
|
13
|
+
| `package.json` with `next` dep | Next.js | `npx tsc --noEmit` → `npx next build` |
|
|
14
|
+
| `package.json` with `nuxt` dep | Nuxt | `npx nuxi typecheck` → `npx nuxi build` |
|
|
15
|
+
| `package.json` with `vite` + `tsconfig.json` | Vite+TS | `npx tsc --noEmit` → `npm run build` (if script exists) |
|
|
16
|
+
| `package.json` with `expo` dep | Expo (React Native) | `npx tsc --noEmit` → `npx expo-doctor` |
|
|
17
|
+
| `package.json` with `react-native` (no expo) | React Native | `npx tsc --noEmit` |
|
|
18
|
+
| `package.json` with `svelte` + `@sveltejs/kit` | SvelteKit | `npm run check` → `npm run build` |
|
|
19
|
+
| `package.json` only, has `build` script | Generic Node | `npm run build` |
|
|
20
|
+
| `package.json` only, has `tsconfig.json` but no `build` | TS library | `npx tsc --noEmit` |
|
|
21
|
+
| `pnpm-workspace.yaml` / `turbo.json` / `lerna.json` | Monorepo | `pnpm -r build` or `turbo run build typecheck lint` — **workspace-wide**, NOT just the changed package |
|
|
22
|
+
| `Cargo.toml` | Rust | `cargo check --all-targets` → `cargo clippy -- -D warnings` |
|
|
23
|
+
| `go.mod` | Go | `go build ./...` → `go vet ./...` |
|
|
24
|
+
| `foundry.toml` | Foundry (Solidity) | `forge build` |
|
|
25
|
+
| `hardhat.config.{js,ts,cjs}` | Hardhat (Solidity) | `npx hardhat compile` |
|
|
26
|
+
| `Anchor.toml` | Anchor (Solana) | `anchor build` |
|
|
27
|
+
| `Move.toml` | Move (Sui/Aptos) | `sui move build` or `aptos move compile` |
|
|
28
|
+
| `pyproject.toml` / `setup.py` + mypy config | Python+mypy | `mypy .` |
|
|
29
|
+
| `pyproject.toml` with `ruff` | Python+Ruff | `ruff check .` |
|
|
30
|
+
| `Package.swift` | Swift package | `swift build` |
|
|
31
|
+
| `*.xcodeproj` / `*.xcworkspace` | iOS/macOS (Xcode) | Skip by default — log "Xcode project detected, manual build gate recommended". Too project-specific without knowing the scheme. |
|
|
32
|
+
| `build.gradle*` / `settings.gradle*` | Gradle/Android | `./gradlew assembleDebug` (debug, not release — keep it fast) |
|
|
33
|
+
| `CMakeLists.txt` | C/C++ (CMake) | `cmake -B build && cmake --build build` |
|
|
34
|
+
| `Makefile` (with no other signals) | Generic Make | `make` (only if no other type matched — Makefiles are too generic) |
|
|
35
|
+
| `Unity/ProjectSettings/` or `ProjectSettings/ProjectVersion.txt` | Unity | Skip by default — log "Unity project detected, manual build gate recommended" |
|
|
36
|
+
| `project.godot` | Godot | Skip by default — log "Godot project detected, manual build gate recommended" |
|
|
37
|
+
| `Dockerfile*` | Docker | `docker build -f <dockerfile> -t _pipeline_gate_test .` — included by default in `auto` mode. Skip with `--build-gate no-docker`. |
|
|
38
|
+
|
|
39
|
+
## Package Manager Detection
|
|
40
|
+
|
|
41
|
+
Respect the project's package manager. Check in order:
|
|
42
|
+
1. `packageManager` field in root `package.json` → use that
|
|
43
|
+
2. `pnpm-lock.yaml` exists → `pnpm`
|
|
44
|
+
3. `yarn.lock` exists → `yarn`
|
|
45
|
+
4. `bun.lockb` / `bun.lock` exists → `bun`
|
|
46
|
+
5. Default → `npm`
|
|
47
|
+
|
|
48
|
+
Replace `npm run build` / `npx` accordingly: `pnpm build` / `pnpm exec`, `yarn build` / `yarn`, `bun run build` / `bunx`.
|
|
49
|
+
|
|
50
|
+
## Monorepo Handling
|
|
51
|
+
|
|
52
|
+
Monorepo is the most critical case — cross-package type drift is the #1 source of "tests pass locally, build fails in CI."
|
|
53
|
+
|
|
54
|
+
1. Detect workspace root markers: `pnpm-workspace.yaml`, `turbo.json`, `lerna.json`, `workspaces` in root `package.json`
|
|
55
|
+
2. Run gates at the **workspace root** level, not per-changed-package:
|
|
56
|
+
- Turbo: `turbo run build typecheck lint` (respects dependency graph)
|
|
57
|
+
- pnpm: `pnpm -r build` (runs in topological order)
|
|
58
|
+
- yarn workspaces: `yarn workspaces foreach -A run build`
|
|
59
|
+
- npm workspaces: `npm run build --workspaces`
|
|
60
|
+
3. This ensures Package A's type change that breaks Package B's consumer is caught, even if only Package A was directly modified.
|
|
61
|
+
|
|
62
|
+
## Strict Mode (`--build-gate strict`)
|
|
63
|
+
|
|
64
|
+
When strict mode is set, treat warnings as failures:
|
|
65
|
+
- TypeScript: add `--strict` if not already in tsconfig (or verify it's set)
|
|
66
|
+
- Clippy: `-D warnings` (already default in the matrix)
|
|
67
|
+
- ESLint: `--max-warnings 0`
|
|
68
|
+
- Go vet: already treats warnings as errors
|
|
69
|
+
- Foundry: `--deny-warnings`
|
|
70
|
+
|
|
71
|
+
In default (auto) mode, only hard errors (non-zero exit code from the tool's perspective) block.
|
|
72
|
+
|
|
73
|
+
## Docker Build (default in `auto` mode)
|
|
74
|
+
|
|
75
|
+
When `Dockerfile*` files are detected AND `--build-gate no-docker` is NOT set:
|
|
76
|
+
1. Run all non-Docker gates first (they're faster and catch most errors before the slow Docker step)
|
|
77
|
+
2. Then run `docker build -f <dockerfile> -t _pipeline_gate_test .` for each Dockerfile found in the repo root and subdirectories (up to 2 levels)
|
|
78
|
+
3. If Docker daemon is not available, log the skip with a warning but do NOT fail — developers without Docker should not be blocked. The warning should note: "Docker builds were skipped because the Docker daemon is unavailable. Use `--build-gate no-docker` to suppress this warning, or ensure Docker is running to catch Dockerfile-specific issues."
|
|
79
|
+
4. This catches Dockerfile-specific issues that no other gate can: COPY paths referencing files excluded by .dockerignore, multi-stage build failures, production-only dependency resolution, and environment differences between dev and container builds
|
|
80
|
+
|
|
81
|
+
Use `--build-gate no-docker` to skip Docker builds for faster iteration during development — the language-level gates (tsc, cargo check, etc.) still run and catch the majority of issues. Docker builds are most valuable as a final gate before shipping.
|
|
82
|
+
|
|
83
|
+
## Output Format
|
|
84
|
+
|
|
85
|
+
Write results to `.devlyn/BUILD-GATE.md`:
|
|
86
|
+
|
|
87
|
+
```markdown
|
|
88
|
+
# Build Gate Results
|
|
89
|
+
## Verdict: [PASS / FAIL]
|
|
90
|
+
## Detected Project Types
|
|
91
|
+
- [type] ([path/])
|
|
92
|
+
## Gate Commands Run
|
|
93
|
+
| # | Command | Dir | Exit | Status | Time |
|
|
94
|
+
|---|---|---|---|---|---|
|
|
95
|
+
| 1 | `npx tsc --noEmit` | dashboard/ | 0 | PASS | 4.2s |
|
|
96
|
+
| 2 | `npx next build` | dashboard/ | 1 | FAIL | 9.8s |
|
|
97
|
+
| 3 | `cargo check --all-targets` | services/indexer/ | 0 | PASS | 12.1s |
|
|
98
|
+
|
|
99
|
+
## Failures
|
|
100
|
+
|
|
101
|
+
### Command #2: `npx next build` (dashboard/, exit 1)
|
|
102
|
+
```
|
|
103
|
+
[full error output — do NOT truncate. Build errors reference files from earlier in output.]
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
**Root file:line(s)**:
|
|
107
|
+
- `dashboard/app/(dashboard)/settings/page.tsx:90` — Type error: Property 'config' does not exist on type 'SettingsTabsProps'
|
|
108
|
+
|
|
109
|
+
**Fix guidance**:
|
|
110
|
+
Read `dashboard/app/(dashboard)/settings/page.tsx:88-93` and `dashboard/components/settings/SettingsTabs.tsx` (the SettingsTabsProps type definition). Either add `config` to SettingsTabsProps or remove the prop from the parent. Then re-run `npx next build` from `dashboard/` to verify.
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Verdict rules:
|
|
114
|
+
- Any exit code != 0 → **FAIL**
|
|
115
|
+
- All exit codes == 0 → **PASS**
|
|
116
|
+
- No gates detected → **PASS** with note "No build gate detected — project type unknown. Consider adding `--build-gate deploy` if Dockerfiles are present."
|
|
@@ -8,6 +8,19 @@ You are auditing a codebase against its planning commitments. Your job is to ver
|
|
|
8
8
|
|
|
9
9
|
Read `.devlyn/commitment-registry.md` for the full list of commitments to verify. Skip any items in the "Not Started (Planned)" section — those are acknowledged future work, not gaps.
|
|
10
10
|
|
|
11
|
+
**Step 0 — Build health check**: Before auditing individual commitments, verify the project actually builds. Detect the project type(s) and run their build/typecheck commands:
|
|
12
|
+
- `package.json` with `next` → `npx tsc --noEmit && npx next build`
|
|
13
|
+
- `package.json` with `vite` + `tsconfig.json` → `npx tsc --noEmit`
|
|
14
|
+
- `Cargo.toml` → `cargo check --all-targets`
|
|
15
|
+
- `go.mod` → `go build ./... && go vet ./...`
|
|
16
|
+
- `foundry.toml` → `forge build`
|
|
17
|
+
- `hardhat.config.*` → `npx hardhat compile`
|
|
18
|
+
- Monorepo (`pnpm-workspace.yaml`/`turbo.json`) → workspace-wide build
|
|
19
|
+
- `Dockerfile*` → `docker build` (if Docker available)
|
|
20
|
+
- For other project types, look for a `build` script in `package.json` or equivalent
|
|
21
|
+
|
|
22
|
+
Any build/typecheck failure is a BROKEN finding at CRITICAL severity — code that doesn't compile cannot fulfill any commitment. Include the full compiler error output with file:line references. This catches type errors, missing imports, cross-package drift, and Dockerfile build failures that text-based code reading alone cannot detect.
|
|
23
|
+
|
|
11
24
|
**For each active commitment (not planned):**
|
|
12
25
|
1. Search the codebase for its implementation (use Grep, Glob, Read in parallel where possible)
|
|
13
26
|
2. Read the implementing code thoroughly — line by line for critical paths
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Asset Catalog Schema
|
|
2
|
+
|
|
3
|
+
The manifest.json file catalogs all generated assets with metadata that supports both runtime rendering and future marketplace features.
|
|
4
|
+
|
|
5
|
+
## manifest.json structure
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"version": "1.0",
|
|
10
|
+
"style": "gather-town",
|
|
11
|
+
"generatedWith": "gemini-3-pro-image-preview",
|
|
12
|
+
"assets": {
|
|
13
|
+
"furniture/desk-basic": {
|
|
14
|
+
"file": "furniture/desk-basic.png",
|
|
15
|
+
"category": "furniture",
|
|
16
|
+
"width": 765,
|
|
17
|
+
"height": 746,
|
|
18
|
+
"anchorX": 0.5,
|
|
19
|
+
"anchorY": 1.0,
|
|
20
|
+
"tags": ["workspace", "desk", "monitor"],
|
|
21
|
+
"theme": "default",
|
|
22
|
+
"tier": "free",
|
|
23
|
+
"price": 0,
|
|
24
|
+
"animation": null
|
|
25
|
+
},
|
|
26
|
+
"characters/char-research-sitting": {
|
|
27
|
+
"file": "characters/char-research-sitting.png",
|
|
28
|
+
"category": "character",
|
|
29
|
+
"width": 342,
|
|
30
|
+
"height": 500,
|
|
31
|
+
"anchorX": 0.5,
|
|
32
|
+
"anchorY": 1.0,
|
|
33
|
+
"tags": ["research", "sitting", "typing"],
|
|
34
|
+
"theme": "default",
|
|
35
|
+
"tier": "free",
|
|
36
|
+
"price": 0,
|
|
37
|
+
"animation": {
|
|
38
|
+
"frameWidth": 342,
|
|
39
|
+
"frameCount": 1,
|
|
40
|
+
"fps": 0
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Field reference
|
|
48
|
+
|
|
49
|
+
| Field | Type | Required | Description |
|
|
50
|
+
|-------|------|----------|-------------|
|
|
51
|
+
| `file` | string | yes | Relative path from asset root |
|
|
52
|
+
| `category` | enum | yes | `tile`, `furniture`, `character`, `pet`, `decoration`, `background` |
|
|
53
|
+
| `width` | number | yes | Pixel width after trim |
|
|
54
|
+
| `height` | number | yes | Pixel height after trim |
|
|
55
|
+
| `anchorX` | number | yes | 0-1, horizontal anchor for positioning (0.5 = center) |
|
|
56
|
+
| `anchorY` | number | yes | 0-1, vertical anchor (1.0 = bottom for isometric depth sort) |
|
|
57
|
+
| `tags` | string[] | yes | Searchable keywords |
|
|
58
|
+
| `theme` | string | yes | Theme pack ID (`"default"`, `"cyberpunk"`, `"nature"`, etc.) |
|
|
59
|
+
| `tier` | enum | yes | `"free"`, `"premium"`, `"exclusive"` |
|
|
60
|
+
| `price` | number | yes | 0 for free, positive integer for paid (currency unit TBD) |
|
|
61
|
+
| `animation` | object\|null | no | Spritesheet info if animated |
|
|
62
|
+
|
|
63
|
+
## Animation field
|
|
64
|
+
|
|
65
|
+
For spritesheet assets (multiple frames in one image):
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"frameWidth": 64,
|
|
70
|
+
"frameCount": 4,
|
|
71
|
+
"fps": 8
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The renderer reads left-to-right, each frame `frameWidth` pixels wide, cycling at `fps` frames per second.
|
|
76
|
+
|
|
77
|
+
## Anchor conventions
|
|
78
|
+
|
|
79
|
+
| Asset type | anchorX | anchorY | Reason |
|
|
80
|
+
|------------|---------|---------|--------|
|
|
81
|
+
| Most assets | 0.5 | 1.0 | Bottom-center — standard for isometric depth sorting |
|
|
82
|
+
| Ceiling items (lights, plants) | 0.5 | 0.0 | Top-center — hangs from above |
|
|
83
|
+
| Wall items (clock, frame) | 0.5 | 0.5 | Center — placed on wall surface |
|
|
84
|
+
| Floor tiles | 0.5 | 0.5 | Center — aligned to grid |
|
|
85
|
+
|
|
86
|
+
## Theme packs
|
|
87
|
+
|
|
88
|
+
A theme is a set of assets that share a visual style. The `"default"` theme ships free with the product. Premium themes are sold as packs.
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
assets/
|
|
92
|
+
├── themes/
|
|
93
|
+
│ ├── default/ → symlinks or copies of base assets
|
|
94
|
+
│ ├── cyberpunk/ → neon-tinted variants
|
|
95
|
+
│ ├── nature/ → wood-and-leaf variants
|
|
96
|
+
│ └── cozy-night/ → warm lamp-lit variants
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
When a user switches themes, the renderer swaps asset paths: `furniture/desk-basic.png` → `themes/cyberpunk/desk-basic.png`. Assets not overridden by the theme fall back to `default`.
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: asset-creator
|
|
3
|
+
description: >
|
|
4
|
+
Generate consistent pixel art game assets using AI image generation + meta-prompting
|
|
5
|
+
for style lock + HSL chroma-key background removal. Produces transparent PNGs ready
|
|
6
|
+
for PixiJS, Phaser, or any 2D game engine. Use when building pixel art games, creating
|
|
7
|
+
game sprites, generating isometric assets, making character sprites, or when user says
|
|
8
|
+
"create asset", "generate sprite", "make game art", "pixel art asset", or "에셋 만들어".
|
|
9
|
+
allowed-tools: Read, Grep, Glob, Edit, Write, Bash
|
|
10
|
+
argument-hint: "[category] [name] \"[description]\" or batch [category] or list or init"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Asset Creator — AI-Powered Game Asset Pipeline
|
|
14
|
+
|
|
15
|
+
Generate production-ready pixel art game assets with consistent style, transparent backgrounds, and catalog metadata.
|
|
16
|
+
|
|
17
|
+
Reference files in this skill directory:
|
|
18
|
+
- `STYLE-GUIDE.md` — Art direction defaults, per-category templates, predefined asset batches
|
|
19
|
+
- `CATALOG-SCHEMA.md` — manifest.json structure and marketplace metadata
|
|
20
|
+
|
|
21
|
+
## Pipeline overview
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
0. STYLE LOCK Meta-prompt one reference asset → extract style DNA (once per project)
|
|
25
|
+
1. GENERATE Swap [SUBJECT] in meta prompt → Gemini 3.0 Pro Image
|
|
26
|
+
2. BG REMOVE HSL flood fill (Pillow) — magenta + near-white removal
|
|
27
|
+
3. NORMALIZE Auto-crop + category-based size normalization
|
|
28
|
+
4. CATALOG manifest.json auto-registration with marketplace metadata
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This pipeline was validated through iterative testing. The meta-prompting approach extracts the "style DNA" from one good asset and replicates it precisely — more consistent than reference images (which the AI may reinterpret) and more token-efficient (264 chars vs 2MB image per call).
|
|
32
|
+
|
|
33
|
+
## Prerequisites
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Python 3 with Pillow — required for HSL background removal
|
|
37
|
+
python3 -c "from PIL import Image; print('OK')"
|
|
38
|
+
|
|
39
|
+
# API key — required for AI image generation
|
|
40
|
+
grep GEMINI_API_KEY .env
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
ImageMagick is NOT required — the pipeline uses pure Python (Pillow) for background removal.
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
/asset-creator init — Set up project + extract meta prompt from reference
|
|
49
|
+
/asset-creator [category] [name] "[description]" — Generate one asset
|
|
50
|
+
/asset-creator batch [category] — Generate all predefined assets in a category
|
|
51
|
+
/asset-creator list — Show current asset inventory
|
|
52
|
+
/asset-creator gallery — Generate visual review HTML
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Workflow
|
|
56
|
+
|
|
57
|
+
### Parse the command
|
|
58
|
+
|
|
59
|
+
Read `$ARGUMENTS` and determine the mode:
|
|
60
|
+
|
|
61
|
+
| Input | Mode | Action |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `init` | **Init** | Set up directories + extract meta prompt from reference asset |
|
|
64
|
+
| `[category] [name] "[desc]"` | **Single** | Generate one asset |
|
|
65
|
+
| `batch [category]` | **Batch** | Generate all predefined assets for category |
|
|
66
|
+
| `list` | **List** | Show asset inventory from manifest.json |
|
|
67
|
+
| `gallery` | **Gallery** | Generate review HTML |
|
|
68
|
+
| Empty | **Interactive** | Ask what to create |
|
|
69
|
+
|
|
70
|
+
Valid categories: `tile`, `furniture`, `character`, `pet`, `decoration`, `background`
|
|
71
|
+
|
|
72
|
+
### Step 0: Style Lock (init mode, or first run)
|
|
73
|
+
|
|
74
|
+
This is the foundation of style consistency. Run once per project.
|
|
75
|
+
|
|
76
|
+
**If no meta prompt exists** (`{asset-root}/style-prompt.txt` missing):
|
|
77
|
+
|
|
78
|
+
1. Check if the project has a reference asset. If not, generate one "hero asset" (a character or prominent furniture piece) using the default style from `STYLE-GUIDE.md`.
|
|
79
|
+
|
|
80
|
+
2. Send the reference asset to Gemini for meta-prompt extraction:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
# Send image + extraction prompt to Gemini (text model, not image gen)
|
|
84
|
+
prompt = """Look at this pixel art game asset. Reverse-engineer the EXACT image
|
|
85
|
+
generation prompt that would recreate this STYLE. Replace the specific subject
|
|
86
|
+
with [SUBJECT]. Capture: pixel density, outline thickness, shading technique,
|
|
87
|
+
color palette warmth, perspective angle, proportions, and the solid magenta
|
|
88
|
+
#FF00FF background. Output ONLY the prompt text, max 3 sentences, be precise."""
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Use `gemini-2.5-flash` (text model) for extraction — it's fast and cheap. NOT the image model.
|
|
92
|
+
|
|
93
|
+
3. Save the extracted meta prompt to `{asset-root}/style-prompt.txt`.
|
|
94
|
+
|
|
95
|
+
4. **Validate**: Generate a test asset using the meta prompt. Show it to the user alongside the reference. If the style matches, the meta prompt is locked. If not, regenerate with adjusted extraction prompt.
|
|
96
|
+
|
|
97
|
+
**If meta prompt exists**: Read `{asset-root}/style-prompt.txt` and use it for all generation.
|
|
98
|
+
|
|
99
|
+
### Step 1: Locate project asset directory
|
|
100
|
+
|
|
101
|
+
Look for existing asset directories in order:
|
|
102
|
+
1. `dashboard/public/assets/office/` (Pyx Org)
|
|
103
|
+
2. `public/assets/game/` (generic game)
|
|
104
|
+
3. `assets/` (fallback)
|
|
105
|
+
|
|
106
|
+
If none exists, create:
|
|
107
|
+
```
|
|
108
|
+
{asset-root}/
|
|
109
|
+
├── tiles/
|
|
110
|
+
├── furniture/
|
|
111
|
+
├── characters/
|
|
112
|
+
├── pets/
|
|
113
|
+
├── decorations/
|
|
114
|
+
├── backgrounds/
|
|
115
|
+
├── raw/ # AI originals (magenta bg, never delete)
|
|
116
|
+
├── manifest.json
|
|
117
|
+
└── style-prompt.txt # Meta prompt (style DNA)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Step 2: Generate the asset
|
|
121
|
+
|
|
122
|
+
Read the meta prompt from `{asset-root}/style-prompt.txt`.
|
|
123
|
+
|
|
124
|
+
Construct the final prompt by replacing `[SUBJECT]`:
|
|
125
|
+
```
|
|
126
|
+
{meta_prompt with [SUBJECT] replaced by user's description}
|
|
127
|
+
|
|
128
|
+
Generate a pixel art IMAGE.
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Call Gemini 3.0 Pro Image API (`gemini-3-pro-image-preview`):
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
import json, base64, urllib.request
|
|
135
|
+
|
|
136
|
+
api_key = os.environ.get("GEMINI_API_KEY") or read_from_dotenv()
|
|
137
|
+
|
|
138
|
+
payload = {
|
|
139
|
+
"contents": [{"parts": [{"text": full_prompt}]}],
|
|
140
|
+
"generationConfig": {
|
|
141
|
+
"responseModalities": ["IMAGE", "TEXT"],
|
|
142
|
+
"temperature": 0.3
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-image-preview:generateContent?key={api_key}"
|
|
147
|
+
req = urllib.request.Request(url, data=json.dumps(payload).encode(),
|
|
148
|
+
headers={"Content-Type": "application/json"}, method="POST")
|
|
149
|
+
|
|
150
|
+
with urllib.request.urlopen(req, timeout=120) as resp:
|
|
151
|
+
result = json.loads(resp.read().decode())
|
|
152
|
+
|
|
153
|
+
# Extract image from response
|
|
154
|
+
for part in result["candidates"][0]["content"]["parts"]:
|
|
155
|
+
if "inlineData" in part:
|
|
156
|
+
data = base64.b64decode(part["inlineData"]["data"])
|
|
157
|
+
with open(f"{asset_root}/raw/{name}.jpg", "wb") as f:
|
|
158
|
+
f.write(data)
|
|
159
|
+
break
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Step 3: Remove background (HSL flood fill)
|
|
163
|
+
|
|
164
|
+
This is the optimized approach — uses HSL color space instead of RGB for robust chroma-key removal that handles JPG compression artifacts.
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
from PIL import Image
|
|
168
|
+
import colorsys
|
|
169
|
+
from collections import deque
|
|
170
|
+
|
|
171
|
+
def remove_background(input_path, output_path):
|
|
172
|
+
img = Image.open(input_path).convert("RGBA")
|
|
173
|
+
pixels = img.load()
|
|
174
|
+
w, h = img.size
|
|
175
|
+
|
|
176
|
+
def should_remove(r, g, b):
|
|
177
|
+
rn, gn, bn = r/255.0, g/255.0, b/255.0
|
|
178
|
+
h_val, l_val, s_val = colorsys.rgb_to_hls(rn, gn, bn)
|
|
179
|
+
hue_deg = h_val * 360
|
|
180
|
+
# Magenta hue range (robust against JPG compression)
|
|
181
|
+
if 250 <= hue_deg <= 340 and s_val > 0.2:
|
|
182
|
+
return True
|
|
183
|
+
# Near-white (catches desaturated magenta from JPG artifacts)
|
|
184
|
+
if r > 230 and g > 230 and b > 230:
|
|
185
|
+
return True
|
|
186
|
+
# Very light + low saturation
|
|
187
|
+
if l_val > 0.9 and s_val < 0.15:
|
|
188
|
+
return True
|
|
189
|
+
return False
|
|
190
|
+
|
|
191
|
+
# Phase 1: Flood fill from all edges (only removes connected background)
|
|
192
|
+
visited = set()
|
|
193
|
+
queue = deque()
|
|
194
|
+
for x in range(w):
|
|
195
|
+
queue.append((x, 0)); queue.append((x, h-1))
|
|
196
|
+
for y in range(h):
|
|
197
|
+
queue.append((0, y)); queue.append((w-1, y))
|
|
198
|
+
|
|
199
|
+
while queue:
|
|
200
|
+
x, y = queue.popleft()
|
|
201
|
+
if (x, y) in visited or x < 0 or x >= w or y < 0 or y >= h:
|
|
202
|
+
continue
|
|
203
|
+
visited.add((x, y))
|
|
204
|
+
r, g, b, a = pixels[x, y]
|
|
205
|
+
if should_remove(r, g, b):
|
|
206
|
+
pixels[x, y] = (0, 0, 0, 0)
|
|
207
|
+
for dx, dy in [(-1,0),(1,0),(0,-1),(0,1),(-1,-1),(1,-1),(-1,1),(1,1)]:
|
|
208
|
+
nx, ny = x+dx, y+dy
|
|
209
|
+
if 0 <= nx < w and 0 <= ny < h and (nx, ny) not in visited:
|
|
210
|
+
queue.append((nx, ny))
|
|
211
|
+
|
|
212
|
+
# Phase 2: Edge cleanup (remove remaining pink fringe)
|
|
213
|
+
for y in range(1, h-1):
|
|
214
|
+
for x in range(1, w-1):
|
|
215
|
+
r, g, b, a = pixels[x, y]
|
|
216
|
+
if a == 0: continue
|
|
217
|
+
rn, gn, bn = r/255.0, g/255.0, b/255.0
|
|
218
|
+
h_val, l_val, s_val = colorsys.rgb_to_hls(rn, gn, bn)
|
|
219
|
+
hue_deg = h_val * 360
|
|
220
|
+
if (250 <= hue_deg <= 340 and s_val > 0.1) or (l_val > 0.85 and s_val < 0.2):
|
|
221
|
+
for dx, dy in [(-1,0),(1,0),(0,-1),(0,1)]:
|
|
222
|
+
if pixels[x+dx, y+dy][3] == 0:
|
|
223
|
+
pixels[x, y] = (0, 0, 0, 0)
|
|
224
|
+
break
|
|
225
|
+
|
|
226
|
+
# Auto-crop to content
|
|
227
|
+
bbox = img.getbbox()
|
|
228
|
+
if bbox:
|
|
229
|
+
img = img.crop(bbox)
|
|
230
|
+
img.save(output_path)
|
|
231
|
+
return img.size
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Why HSL instead of RGB:
|
|
235
|
+
- JPG compression shifts RGB values but barely affects Hue
|
|
236
|
+
- Magenta has a distinctive hue (~300°) that's stable across compression levels
|
|
237
|
+
- Saturation check prevents false positives on gray/white pixels
|
|
238
|
+
- Flood fill from edges ensures interior light pixels are preserved
|
|
239
|
+
|
|
240
|
+
### Step 4: Register in manifest
|
|
241
|
+
|
|
242
|
+
Read `{asset-root}/manifest.json`. Get dimensions from the processed PNG. Add entry:
|
|
243
|
+
|
|
244
|
+
```json
|
|
245
|
+
{
|
|
246
|
+
"{category}/{name}": {
|
|
247
|
+
"file": "{category}/{name}.png",
|
|
248
|
+
"category": "{category}",
|
|
249
|
+
"width": W,
|
|
250
|
+
"height": H,
|
|
251
|
+
"anchorX": 0.5,
|
|
252
|
+
"anchorY": 1.0,
|
|
253
|
+
"tags": ["inferred", "from", "description"],
|
|
254
|
+
"theme": "default",
|
|
255
|
+
"tier": "free",
|
|
256
|
+
"price": 0
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
See `CATALOG-SCHEMA.md` for full field reference and anchor conventions.
|
|
262
|
+
|
|
263
|
+
### Step 5: Show result
|
|
264
|
+
|
|
265
|
+
Display the generated PNG using the Read tool. Report:
|
|
266
|
+
- File path and size
|
|
267
|
+
- Dimensions (W × H)
|
|
268
|
+
- Category, tags, tier
|
|
269
|
+
- Manifest status
|
|
270
|
+
|
|
271
|
+
If unsatisfied, offer to regenerate with an adjusted subject description.
|
|
272
|
+
|
|
273
|
+
## Batch Mode
|
|
274
|
+
|
|
275
|
+
Read predefined asset lists from `STYLE-GUIDE.md`. Generate each sequentially with 1.5s delay (rate limiting). Show progress. Generate gallery at end.
|
|
276
|
+
|
|
277
|
+
## List Mode
|
|
278
|
+
|
|
279
|
+
Read manifest.json, group by category, display inventory table with dimensions, tier, and file size.
|
|
280
|
+
|
|
281
|
+
## Gallery Mode
|
|
282
|
+
|
|
283
|
+
Generate `{asset-root}/gallery.html` showing all assets on checkered transparency background, grouped by category. Suggest `python3 -m http.server 8888` to view.
|
|
284
|
+
|
|
285
|
+
## Adapting to other AI generators
|
|
286
|
+
|
|
287
|
+
The pipeline is model-agnostic. To swap generators:
|
|
288
|
+
1. Replace the API call in Step 2
|
|
289
|
+
2. Keep the meta prompt + magenta background instruction
|
|
290
|
+
3. HSL background removal works identically regardless of source
|
|
291
|
+
4. If your model outputs PNG with native transparency, skip Step 3
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Asset Creator — Style Guide
|
|
2
|
+
|
|
3
|
+
This document defines the art direction defaults and per-category templates. In production, the meta prompt (extracted from a reference asset) overrides the default style prefix.
|
|
4
|
+
|
|
5
|
+
## Style System: Meta Prompting
|
|
6
|
+
|
|
7
|
+
The best way to ensure style consistency is **meta prompting** — extracting the "style DNA" from one good reference asset, then using that exact prompt for all subsequent generations with only the `[SUBJECT]` swapped.
|
|
8
|
+
|
|
9
|
+
### How it works
|
|
10
|
+
|
|
11
|
+
1. Generate or find one "hero asset" that nails the visual style you want
|
|
12
|
+
2. Send it to Gemini text model to reverse-engineer the prompt
|
|
13
|
+
3. Save the extracted prompt as `style-prompt.txt` in the asset root
|
|
14
|
+
4. Every subsequent generation uses this prompt, replacing `[SUBJECT]` only
|
|
15
|
+
|
|
16
|
+
### Why meta prompting beats alternatives
|
|
17
|
+
|
|
18
|
+
| Approach | Consistency | Token cost | Reliability |
|
|
19
|
+
|---|---|---|---|
|
|
20
|
+
| Fixed text prefix (old approach) | Medium — AI interprets loosely | Low | Medium |
|
|
21
|
+
| Reference image every call | High — but AI may reinterpret | Very High (~2MB/call) | Medium |
|
|
22
|
+
| **Meta prompt (current)** | **High — exact reproduction** | **Low (264 chars)** | **High** |
|
|
23
|
+
| Fine-tuned model (Scenario.gg) | Highest | Setup cost | Highest |
|
|
24
|
+
|
|
25
|
+
### Default style prefix (fallback)
|
|
26
|
+
|
|
27
|
+
If no `style-prompt.txt` exists yet (first run / init), use this as the initial generation prompt:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
Gather Town / Habbo Hotel style pixel art game asset, isometric 3/4 view, bright cheerful warm colors, clean pixel outlines, highly detailed pixel art
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Then extract the meta prompt from the first successful generation.
|
|
34
|
+
|
|
35
|
+
## Background Instruction (always appended)
|
|
36
|
+
|
|
37
|
+
Regardless of meta prompt, ALWAYS append this to every generation prompt:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
on a solid bright magenta #FF00FF background. The ENTIRE background must be exactly #FF00FF magenta, with NO gradients or shadows on the background. ONLY the single isolated object, nothing else in the scene.
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
This is required by the HSL chroma-key removal pipeline. Magenta (#FF00FF) is the game industry standard chroma-key color — it never appears in natural pixel art palettes.
|
|
44
|
+
|
|
45
|
+
## Perspective
|
|
46
|
+
|
|
47
|
+
- **Angle**: Isometric ¾ top-down view (~30° from horizontal)
|
|
48
|
+
- **Camera**: Looking from bottom-left toward top-right
|
|
49
|
+
- **Shadow direction**: Bottom-right, short and crisp
|
|
50
|
+
- **Light source**: Top-left (consistent with shadow direction)
|
|
51
|
+
|
|
52
|
+
## Proportions (relative to character height)
|
|
53
|
+
|
|
54
|
+
| Element | Relative size | Notes |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| Character (standing) | 1.0x | Reference unit |
|
|
57
|
+
| Character (sitting) | 0.7x | At desk |
|
|
58
|
+
| Desk | 0.5x height, 1.2x width | With monitor, wider than tall |
|
|
59
|
+
| Chair | 0.4x | Office swivel chair |
|
|
60
|
+
| Bookshelf | 1.2x | Taller than character |
|
|
61
|
+
| Door | 1.5x | Tallest common furniture |
|
|
62
|
+
| Floor plant | 0.8-1.0x | Varies by type |
|
|
63
|
+
| Desk plant | 0.2x | Small succulent/cactus |
|
|
64
|
+
| Wall decoration | 0.3-0.5x | Clock, picture frame |
|
|
65
|
+
| Bean bag | 0.4x height, 0.8x width | Wide and low |
|
|
66
|
+
| Kit (pet) | 0.5x | Smaller than character |
|
|
67
|
+
|
|
68
|
+
## Color palette guidelines
|
|
69
|
+
|
|
70
|
+
- **Warm base**: Browns, beiges, warm grays for furniture and floors
|
|
71
|
+
- **Department accents**: Orange (Research), Green (Engineering), Blue (Growth), Purple (Ops)
|
|
72
|
+
- **Skin tones**: Varied, warm undertones
|
|
73
|
+
- **Outlines**: Dark brown or black, 1-2px, clean and consistent
|
|
74
|
+
- **Highlights**: Top-left facing surfaces lighter
|
|
75
|
+
- **Shadows**: Bottom-right facing surfaces darker, 2-3 tone steps
|
|
76
|
+
|
|
77
|
+
## Per-category prompt templates
|
|
78
|
+
|
|
79
|
+
### tile
|
|
80
|
+
```
|
|
81
|
+
{STYLE_PREFIX}. A single isometric {description} tile, 64x64 pixel grid aligned, seamlessly tileable. {BG_SUFFIX}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### furniture
|
|
85
|
+
```
|
|
86
|
+
{STYLE_PREFIX}. A single {description}. Isometric perspective, detailed with visible texture and shading. {BG_SUFFIX}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### character
|
|
90
|
+
```
|
|
91
|
+
{STYLE_PREFIX}. A single cute office worker character, {description}. Gather Town style proportions: blocky square head wider than body, dot eyes with white highlight, small body. {BG_SUFFIX}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### pet
|
|
95
|
+
```
|
|
96
|
+
{STYLE_PREFIX}. A single small cute {description}. Expressive face, big eyes, stubby limbs. Game mascot style. {BG_SUFFIX}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### decoration
|
|
100
|
+
```
|
|
101
|
+
{STYLE_PREFIX}. A single {description}. Small decorative object, detailed pixel art. {BG_SUFFIX}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### background
|
|
105
|
+
```
|
|
106
|
+
{STYLE_PREFIX}. A wide panoramic {description}. Suitable as a background layer, horizontally tileable or wide format. {BG_SUFFIX}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Predefined asset batches
|
|
110
|
+
|
|
111
|
+
### tile
|
|
112
|
+
| name | description |
|
|
113
|
+
|------|-------------|
|
|
114
|
+
| floor-wood | wooden floor tile with warm wood grain texture |
|
|
115
|
+
| floor-carpet-orange | orange carpet tile for Research department |
|
|
116
|
+
| floor-carpet-green | green carpet tile for Engineering department |
|
|
117
|
+
| floor-carpet-blue | blue carpet tile for Growth department |
|
|
118
|
+
| floor-carpet-purple | purple carpet tile for Ops department |
|
|
119
|
+
| wall-back | cream/beige back wall section |
|
|
120
|
+
| wall-side | slightly darker side wall section |
|
|
121
|
+
|
|
122
|
+
### furniture
|
|
123
|
+
| name | description |
|
|
124
|
+
|------|-------------|
|
|
125
|
+
| desk-basic | wooden office desk with computer monitor, keyboard, mouse, and coffee mug |
|
|
126
|
+
| desk-standing | modern standing desk with large monitor and adjustable height |
|
|
127
|
+
| chair-office | dark office swivel chair with armrests |
|
|
128
|
+
| bookshelf | tall wooden bookshelf packed with colorful books, small plant on top |
|
|
129
|
+
| whiteboard | office whiteboard covered in colorful sticky notes, marker tray at bottom |
|
|
130
|
+
| beanbag-green | large green bean bag chair, puffy and round |
|
|
131
|
+
| beanbag-orange | large orange bean bag chair, puffy and round |
|
|
132
|
+
| beanbag-purple | large purple bean bag chair, puffy and round |
|
|
133
|
+
| coffee-station | espresso machine on wooden counter with white mug underneath |
|
|
134
|
+
| water-cooler | water cooler dispenser with blue water jug on top |
|
|
135
|
+
| meeting-table | round meeting table with 4 small chairs |
|
|
136
|
+
| sofa | comfortable modern office couch |
|
|
137
|
+
|
|
138
|
+
### character
|
|
139
|
+
| name | description |
|
|
140
|
+
|------|-------------|
|
|
141
|
+
| char-research-sitting | in orange shirt, brown hair, sitting and typing on laptop |
|
|
142
|
+
| char-research-standing | in orange shirt, brown hair, standing casually |
|
|
143
|
+
| char-engineering-sitting | in green shirt, black hair, sitting and typing on laptop |
|
|
144
|
+
| char-engineering-standing | in green shirt, black hair, standing casually |
|
|
145
|
+
| char-growth-sitting | in blue shirt, blonde hair, sitting and typing on laptop |
|
|
146
|
+
| char-growth-standing | in blue shirt, blonde hair, standing casually |
|
|
147
|
+
| char-ops-sitting | in purple shirt, red ponytail, sitting and typing on laptop |
|
|
148
|
+
| char-ops-standing | in purple shirt, red ponytail, standing casually |
|
|
149
|
+
|
|
150
|
+
### pet
|
|
151
|
+
| name | description |
|
|
152
|
+
|------|-------------|
|
|
153
|
+
| kit-idle | golden yellow cat creature mascot, happy expression, standing still |
|
|
154
|
+
| kit-bounce-1 | golden yellow cat creature mascot, jumping up with arms raised |
|
|
155
|
+
| kit-bounce-2 | golden yellow cat creature mascot, at peak of jump |
|
|
156
|
+
| kit-blink | golden yellow cat creature mascot, eyes closed, smiling |
|
|
157
|
+
|
|
158
|
+
### decoration
|
|
159
|
+
| name | description |
|
|
160
|
+
|------|-------------|
|
|
161
|
+
| plant-hanging | hanging potted plant with green vines draping from terracotta pot on chain |
|
|
162
|
+
| plant-floor-large | tall floor potted plant with large green leaves in brown pot |
|
|
163
|
+
| plant-desk | small succulent in tiny pot for desk |
|
|
164
|
+
| clock-wall | round wall clock with simple markers |
|
|
165
|
+
| picture-frame | framed picture/certificate for wall |
|
|
166
|
+
| pendant-light | hanging ceiling pendant light with warm glow |
|
|
167
|
+
| window-large | large floor-to-ceiling window panel |
|
|
168
|
+
| bulletin-board | cork board with pinned papers and photos |
|
|
169
|
+
|
|
170
|
+
### background
|
|
171
|
+
| name | description |
|
|
172
|
+
|------|-------------|
|
|
173
|
+
| skyline-day | city skyline with buildings, blue sky, white clouds, wide panorama |
|
|
174
|
+
| skyline-night | nighttime city skyline with lit windows, dark blue sky, wide panorama |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devlyn-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.1",
|
|
4
4
|
"description": "AI development toolkit for Claude Code — ideate, auto-resolve, and ship with context engineering and agent orchestration",
|
|
5
5
|
"homepage": "https://github.com/fysoul17/devlyn-cli#readme",
|
|
6
6
|
"bin": {
|