Skip to content

Commit 6fc798b

Browse files
iOSDevSKclaude
andcommitted
1.0.0-gamma.3: the ZIP is the owner's "Make release"; the model never packages in a change turn (from 103b246)
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Xf7wTz9XZFZ1GCWzDzHaWW
1 parent b6fbb72 commit 6fc798b

11 files changed

Lines changed: 50 additions & 22 deletions

File tree

‎.claude-plugin/marketplace.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"source": "./",
1515
"displayName": "html2wp — HTML to WordPress",
1616
"description": "BETA. Convert a static HTML site into a standalone WordPress block theme, verified against the original at three viewport widths — and reviewed by you before handover. The conversion runs through a verified Astro 5 build, so the Astro project is a real output too — compared pixel by pixel against the source before anything WordPress-shaped is generated.",
17-
"version": "1.0.0-gamma.2",
17+
"version": "1.0.0-gamma.3",
1818
"author": {
1919
"name": "BELNEM s.r.o.",
2020
"email": "hello@html2wp.dev",

‎.claude-plugin/plugin.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "html2wp",
33
"displayName": "html2wp — HTML to WordPress",
44
"description": "BETA. Convert a static HTML site — or anything that builds to one (Lovable, Bolt, v0, Next export) — into a standalone WordPress block theme: verified pixel by pixel, pages, blog, forms, menus, SEO and redirects, with no plugin required and verification gates at every stage. Two modes: Full (every gate repaired until green, then your own page-by-page review) and Flash (every stage once, no repair loop, the gates reported). The gates catch most fidelity drift, not all of it.",
5-
"version": "1.0.0-gamma.2",
5+
"version": "1.0.0-gamma.3",
66
"author": {
77
"name": "BELNEM s.r.o.",
88
"email": "hello@html2wp.dev",

‎.codex-plugin/plugin.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "html2wp",
3-
"version": "1.0.0-gamma.2",
3+
"version": "1.0.0-gamma.3",
44
"description": "Convert static HTML or buildable web projects into verified, editable WordPress block themes.",
55
"author": {
66
"name": "BELNEM s.r.o.",

‎VERSION‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.0-gamma.2
1+
1.0.0-gamma.3

‎skills/html2wp/SKILL.md‎

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -587,20 +587,21 @@ delivered project (exit 3) — that refusal is the rule.
587587
python3 assets/scripts/apply-change.py {workspace} --what "<the owner's request, one line>" [--page <key or /route/>]
588588
```
589589

590-
It packages the edited theme (make-zip's lint and refusals), replaces it in
590+
It checks the edited theme with make-zip's lint and refusals, replaces it in
591591
the running preview through WordPress's own upload — the importer refreshes
592592
every page whose stored source is still the bundle's — and screenshots the
593593
touched pages at 1440 and 390 into `{workspace}/changes/`. Seconds, not
594594
minutes. It logs the change in `{workspace}/changes.json` and sets
595595
`changedSinceZip`. Exit 3 = no theme file changed (you edited something
596-
else); 1 = the package or the preview refused (its reason on stderr).
596+
else); 1 = make-zip's check or the preview refused (its reason on stderr).
597597
3. **Look before you answer:** open the screenshots it names. The change is
598598
there, and nothing else moved. If not, correct the theme file and apply
599599
again — at most twice for one request; then tell the owner what you see.
600600
4. **Answer the owner:** what changed, on which page, and that the preview
601-
shows it. The ZIP is theirs to take ("Get ZIP" runs
602-
`assets/scripts/package-theme.py`, no model turn): the live theme as the
603-
next revision.
601+
shows it. The ZIP is the owner's to take, with the app's "Make release"
602+
(the live theme as the next revision, no model turn). You never package in
603+
a change turn — no release ZIP, no script that makes one — not even when
604+
asked for the ZIP: point the owner to "Make release".
604605

605606
**A page the owner edited in the preview** keeps the owner's text — the
606607
importer never overwrites an owner's edit — so a change to that page's source
@@ -3372,10 +3373,11 @@ assets/scripts/apply-change.py after delivery: the edited live theme into
33723373
the running preview (make-zip, WordPress's
33733374
own replace, the importer's refresh),
33743375
screenshots, changes.json — no stage runs
3375-
assets/scripts/package-theme.py after delivery, the owner's "Get ZIP": the
3376-
live theme as the next revision in
3377-
result.json, or the last ZIP when nothing
3378-
changed
3376+
assets/scripts/package-theme.py after delivery, the app's "Make release"
3377+
(the owner's, never the model's in a
3378+
change turn): the live theme as the next
3379+
revision in result.json, or the last ZIP
3380+
when nothing changed
33793381
assets/scripts/write-result.py the end of every run: result.json (the
33803382
verdict a UI reads), the ZIPs, the report
33813383
and its PDF into H2WP_OUTPUT_DIR

‎skills/html2wp/VERSION‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.0-gamma.2
1+
1.0.0-gamma.3

‎skills/html2wp/assets/scripts/apply-change.py‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@
2121
source changed, else the front page) at 1440 and 390, for the model to
2222
look at before it answers;
2323
4. logs the change in {workspace}/changes.json (what, files, pages,
24-
screenshots, when) and sets changedSinceZip, which "Get ZIP"
25-
(package-theme.py) clears.
24+
screenshots, when) and sets changedSinceZip, which the owner's "Make
25+
release" (package-theme.py) clears. Its own ZIP only carries the theme into
26+
the preview; it is never a release.
2627
2728
No stage runs: no prerender, no build, no service conversion, no
2829
progress.json change. A preview that is down is brought back with

‎skills/html2wp/assets/scripts/lib/theme_state.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"""The delivered theme after delivery: what changed, and against what.
33
44
Shared by apply-change.py (a change applied to the running preview) and
5-
package-theme.py (the owner's "Get ZIP"). A delivered project is one whose
5+
package-theme.py (the owner's "Make release"). A delivered project is one whose
66
{workspace}/result.json says status "delivered"; its theme lives at
77
{workspace}/theme/<slug>/ and every comparison is by file content:
88

‎skills/html2wp/assets/scripts/package-theme.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#!/usr/bin/env python3
22
# Copyright (c) 2026 BELNEM s.r.o. html2wp Source-Available Licence — see LICENSE.
3-
"""The owner's "Get ZIP": the live theme, packaged — no model turn.
3+
"""The owner's "Make release": the live theme, packaged — no model turn.
4+
5+
The app runs it from its "Make release" button (outside the app, the owner
6+
runs it). The model never runs it in a change turn.
47
58
package-theme.py {workspace} [--output DIR]
69

‎skills/html2wp/assets/scripts/test-change-mode.py‎

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@
99
is set, and no stage starts — progress.json is not touched;
1010
- apply-change.py with nothing changed has nothing to apply (exit 3);
1111
- progress.sh refuses a stage start and a `mode` without --new while the
12-
project is delivered; `mode --new` (the app's Rebuild) starts a new run and
12+
project is delivered; `mode --new` (the app's "Start over from the
13+
original") starts a new run and
1314
puts the delivered result and change log aside;
14-
- package-theme.py ("Get ZIP") delivers the changed theme as revision 2 with
15+
- the change brief never tells the model to package: the ZIP is the owner's
16+
"Make release";
17+
- package-theme.py ("Make release") delivers the changed theme as revision 2 with
1518
its sha256 in result.json and clears changedSinceZip; with nothing changed
1619
it answers the existing ZIP (reused).
1720
@@ -23,6 +26,7 @@
2326
import hashlib
2427
import json
2528
import os
29+
import re
2630
import subprocess
2731
import sys
2832
import tempfile
@@ -151,6 +155,24 @@ def test_the_change_brief_never_offers_starting_over(self):
151155
for script in ('apply-change.py', 'package-theme.py'):
152156
self.assertNotRegex((HERE / script).read_text().lower(), r'rebuild|start over', script)
153157

158+
def test_the_change_brief_never_tells_the_model_to_package(self):
159+
# The ZIP is the owner's, with the app's "Make release"; the model
160+
# never packages in a change turn, not even when asked for the ZIP.
161+
skill = (HERE.parent.parent / 'SKILL.md').read_text()
162+
start = skill.index('## Changes after delivery')
163+
section = skill[start:skill.index('\n## ', start + 3)]
164+
self.assertIn('"Make release"', section)
165+
self.assertIn('You never package in a change turn', ' '.join(section.split()))
166+
self.assertNotRegex(section, r'package-theme|Get ZIP')
167+
# The only command the section hands the model is apply-change.py.
168+
commands = re.findall(r'```\n(.*?)```', section, re.S) + re.findall(r'`([^`\n]*\.(?:py|sh)[^`\n]*)`', section)
169+
self.assertTrue(commands)
170+
for command in commands:
171+
self.assertNotRegex(command, r'package-theme|make-zip|zip ', command)
172+
self.assertNotRegex(section.lower(), r'\b(run|use|call)\b[^.\n]{0,40}\bmake-zip')
173+
for script in ('apply-change.py', 'write-result.py'):
174+
self.assertNotIn('package-theme.py makes', (HERE / script).read_text(), script)
175+
154176
def test_not_a_delivered_project(self):
155177
(self.ws / 'result.json').write_text(json.dumps({'status': 'stopped'}))
156178
self.assertEqual(self.apply().returncode, 2)

0 commit comments

Comments
 (0)