File size: 9,708 Bytes
dc32ce0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# SKILLS.md — how to work in this repo

Process rules and habits for editing Z-Image Studio. Companion to `CLAUDE.md` (which is *what & why*); this file is *how* — debugging, verification, deployment, when to commit, when to ship.

> **Default rule when in doubt:** stop and ask the user. The user prefers a question over wrong work.

---

## Investigation before fix

### Reproduce the bug before patching

When the user reports a layout, color, click, or visibility issue, **first action is verify, not code**. Open the local app (http://127.0.0.1:7860) in a browser OR via Playwright (`mcp__playwright__browser_*`) and reproduce the issue. Take a screenshot. THEN diagnose.

Skipping the visual repro twice in a row will produce a patch that fixes a different symptom than the one the user is seeing.

For shape / data bugs: read the stack trace fully, identify the line, then read the function — don't trust the line number alone.

### Pull HF Space logs when something runs there

For Spaces failures, the run logs are the source of truth.

```bash
HF_TOKEN=$(cat ~/.cache/huggingface/token)
curl -s -H "Authorization: Bearer ${HF_TOKEN}" \
  "https://huggingface.co/api/spaces/techfreakworm/z-image-studio/logs/run" \
  > /tmp/hf-runtime.log

# Decode the SSE-style `data: {...}` lines
python3 << 'PY'
import json
msgs = []
for line in open('/tmp/hf-runtime.log'):
    if line.startswith('data:'):
        try: msgs.append(json.loads(line[5:].strip()).get('data', '').rstrip())
        except Exception: pass
with open('/tmp/hf-runtime-decoded.log', 'w') as f:
    f.write('\n'.join(msgs))
print(f'Decoded {len(msgs)} lines')
PY

tail -100 /tmp/hf-runtime-decoded.log
```

`/logs/run` is runtime container output. `/logs/build` is the image-build phase (pip install, preload, etc.). Different problems, different endpoints.

### Stage check before action

```bash
curl -s https://huggingface.co/api/spaces/techfreakworm/z-image-studio/runtime | python3 -m json.tool
```

Terminal stages: `RUNNING`, `RUNTIME_ERROR`, `BUILD_ERROR`. Transient: `BUILDING`, `APP_STARTING`, `RUNNING_BUILDING` (live serving while a new build runs). Always check `errorMessage` first when stage is non-RUNNING.

### Sequential thinking for repeated failures

The user has called this out: if a fix doesn't work on the first try, **stop patching**. Use the `superpowers:sequential-thinking` MCP and the `superpowers:systematic-debugging` skill. Two failed fixes is the signal — go back to root-cause investigation before attempting fix #3.

Pattern that means you're guessing:
- "Just try changing X and see if it works"
- "I see another thing it could be — fix that too"
- Multiple changes in one commit chasing a symptom

Pattern that means you're investigating:
- One hypothesis per cycle
- Each hypothesis has a falsifying experiment
- Experiments produce evidence before code changes

---

## Running locally

```bash
cd /Users/techfreakworm/Projects/llm/z-image-studio
source .venv/bin/activate
# Restart cleanly (kill anything on 7860)
kill -9 $(lsof -ti:7860 2>/dev/null) 2>/dev/null || true
sleep 1
nohup .venv/bin/python app.py > /tmp/zimage-studio.log 2>&1 &
disown
# Wait for ready
for i in $(seq 1 30); do curl -sf http://127.0.0.1:7860/ -o /dev/null && echo "ready ${i}s" && break; sleep 1; done
```

`/tmp/zimage-studio.log` is the live log. Tail it during development. The Monitor tool with a `grep -E "ERROR|Traceback|Exception"` filter is the right way to watch it across many turns without blowing context.

LAN access for phone / tablet testing: `http://192.168.0.10:7860` (the LAN IP of the dev machine). Gradio binds to `0.0.0.0:7860` by default in `app.py`.

---

## Verification before committing

Before every commit:

1. **Tests pass.** `python -m pytest tests/ -q` → target 70/70 + 4 deselected. New code adds new tests.
2. **Ruff clean.** `ruff check . && ruff format --check .` — both no-op.
3. **App boots.** Restart the local server (kill 7860, relaunch). Confirm "ready" within ~5 seconds and no traceback in `/tmp/zimage-studio.log`.
4. **The change is visible.** For UI changes, click through the affected tab in the browser. For backend changes, click Generate and verify the output matches expectation.

Tests + ruff alone is not proof the UI works — the test suite mocks `pipe(...)` and doesn't exercise the Gradio render tree.

---

## When to commit

- **One logical change per commit.** A fix and a refactor are TWO commits, not one.
- After a test goes red → green, commit.
- After fixing a regression, commit BEFORE adding the next feature.
- Don't bundle "while I'm here" changes — they hide the actual fix in the diff.

Conventional Commits format:

```
<type>(<scope>): <subject>

<body — explains WHY, not what>
```

Types in use: `feat`, `fix`, `chore`, `docs`, `test`, `refactor`, `ci`, `perf`.

NO Claude trailer. NO "Generated with…" footer. See `CLAUDE.md` rule 1.

---

## Deployment workflow

The repo has two remotes:

```
origin  → git@github.com:techfreakworm/z-image-studio.git
space   → https://huggingface.co/spaces/techfreakworm/z-image-studio
```

To push:

```bash
git push origin main
git push space main
```

After the `space` push, HF starts rebuilding. Watch:

```bash
TOKEN=$(cat ~/.cache/huggingface/token)
while true; do
  STATE=$(curl -s -H "Authorization: Bearer $TOKEN" \
    https://huggingface.co/api/spaces/techfreakworm/z-image-studio/runtime \
    | python3 -c "import json,sys; print(json.load(sys.stdin).get('stage','?'))")
  echo "$(date +%H:%M:%S) $STATE"
  case "$STATE" in
    RUNNING|BUILD_ERROR|RUNTIME_ERROR) break ;;
  esac
  sleep 30
done
```

Typical build time: ~5 min after weights are cached. First build with new preload globs: ~15 – 20 min.

### Don't push during HF testing

When the user is actively testing on the live Space, hold local commits — don't push mid-test. They'll explicitly say "push it now" when they're ready.

---

## Adding a new model / weight

1. Add a `ModelConfig(...)` entry to `models.MODEL_CONFIGS`.
2. Add the file (or glob) to `preload_from_hub:` in `README.md`'s YAML frontmatter.
3. If it's the optional kind DiffSynth fetches lazily (siglip / dinov3 / image2lora), it appears in `_build_pipeline`'s `pool.fetch_model("…")` calls — those return `None` when absent and don't crash.
4. If the file is on ModelScope only (e.g. `PAI/…`), find the HF mirror first. The repo uses HF exclusively (`DIFFSYNTH_DOWNLOAD_SOURCE=huggingface`). Common mirror patterns: `PAI/X``alibaba-pai/X`. `xinntao/Real-ESRGAN``lllyasviel/Annotators`.
5. Run tests, restart server, verify in browser, then commit.

---

## Adding a new mode / tab

1. Spec the new mode in `docs/superpowers/specs/` first. Don't skip this.
2. Add a `call_<mode>(pipe, params)` to `modes.py`. Same shape as the existing three.
3. Add a `build_<mode>_tab()` to `ui.py`. Use the existing tabs as template — gr.Radio / gr.Checkbox / gr.Accordion patterns are already proven Gradio-friendly.
4. Wire `on_<mode>_generate()` in `app.py` with `progress=gr.Progress(track_tqdm=True)`. Connect `c["generate_btn"].click(...)`.
5. Add tests in `tests/test_modes.py` mocking the `pipe` boundary.
6. Update tooltips dict in `tooltips.py`.
7. Update the spec + plan to reflect the new mode.

---

## When you have 2+ failed fixes

This is a process signal, not a coding signal. Stop coding.

1. Read `superpowers:systematic-debugging` (the Iron Law: no fixes without root-cause investigation).
2. Use `mcp__sequential-thinking__sequentialthinking` to walk through hypotheses one at a time.
3. Each hypothesis needs a falsifying experiment (a log line, a Playwright eval, a test). Run the experiment before writing code.
4. If 3+ fixes have failed, the architecture is wrong — escalate to the user, don't attempt fix #4.

This rule has saved several hours of thrashing in this repo. Honour it.

---

## Brainstorm + visual companion

When making material UI changes, use:

- `superpowers:brainstorming` to clarify what's actually being built
- `superpowers:frontend-design` (or `frontend-design:frontend-design`) for design quality
- The visual companion server (under `.superpowers/brainstorm/.../content/`) for mockups the user can click through

The user's `.superpowers/` directory is git-ignored and persists per project. Don't prematurely re-mockup — confirm with the user that mockups are wanted before generating them.

The user has rejected over-designed mockups TWICE. Default to RESTRAINT — single accent, single font, gradio-native shapes, progressive disclosure. The Soft Dark Restraint design in this repo is what landed; future redesigns should match its discipline.

---

## Skills + sub-agents

When dispatching subagents (Agent tool):

- **Brief them like they walked in cold.** They see none of this conversation. Include file paths, line numbers, what to change, what NOT to change.
- **Don't make a subagent read the plan file.** Paste the relevant section into the prompt.
- **Use Opus for design + heavy refactors.** Sonnet for mechanical implementation. Haiku for trivial CSS / config changes.
- **One subagent per task.** Two parallel subagents touching the same file is a guaranteed merge conflict.
- **Subagents commit but don't push.** The user pushes when they've reviewed the diff locally. The "don't push during HF testing" rule means the human owns the push button.

---

## When in doubt

1. Re-read the spec at `docs/superpowers/specs/2026-05-13-z-image-studio-design.md`.
2. `git log --oneline` — every non-obvious decision has a fix-commit explaining the reasoning.
3. Ask the user. They prefer answering a clarifying question to debugging wrong code an hour later.