Compare commits

...
Author SHA1 Message Date
Paul Bakaus 329fa3e9f4 Release: prepare signed engine 0.1.2
Bump engine and platform-package pins for the first Azure-signed Windows release. Keep this branch off main until release assets and all platform packages are published; refresh bun.lock after publication.

AI assistance: Codex.
2026-09-05 15:41:58 -07:00
Paul BakausandGitHub bb7663ecfb Sign Windows engine releases with Azure Artifact Signing (#742)
* Sign Windows engine releases with Azure Artifact Signing

Isolate OIDC signing behind a maintainer-approved release environment and publish only verified, timestamped company-signed Windows output.

AI assistance: implemented and verified with Codex under maintainer direction.

* Clarify same-run artifact permissions

Keep least-privilege tokens: the pinned artifact actions use ACTIONS_RUNTIME_TOKEN for same-run transfers. Guard against opting into cross-run downloads and use role-based reviewer wording.

AI assistance: prepared and verified with Codex under maintainer direction.
2026-09-05 15:38:55 -07:00
github-actions[bot] 707fb6061c Sync generated provider output 2026-09-05 22:02:26 +00:00
044a04fd0d docs: add workflow guide for command entry points (#737)
* docs: add workflow guide for command entry points

* Refine workflow guidance into advice-only routing

Reuse the existing routing reference and docs map instead of shipping a parallel workflow catalog. Add reference-backed command comparisons, advice-only tests, and explicit-command precedence coverage.

AI-assisted maintainer revision prepared with Codex.

* Include routing guidance in behavior-test triggers

AI-assisted maintainer revision prepared with Codex.

* Constrain routing behavior tests to fixture-safe tools

Keep the real context loader but reject arbitrary host shell searches in the new advice scenarios. Preserve observable project writes and protect the staged skill; cover the restriction with offline regression tests.

AI-assisted maintainer revision prepared with Codex.

* Require actual reference reads in restricted routing tests

Do not count rejected shell reads as reference loading. Record the nine measured advice cases; explicit-command measurements remain pending the stricter retest.

AI-assisted maintainer revision prepared with Codex.

* Record measured workflow-routing baseline

All twelve focused cases pass across Claude Sonnet 5, GPT-5.6 Terra, and Gemini 3.7 Flash, including the stricter explicit-command retest.

AI-assisted verification prepared with Codex.

* Trim workflow routing guidance

Reduce added skill prose from 286 to 59 words while retaining the routing regression assertions. Record the missing-context reference-read flake and passing repeat.

AI assistance: prepared and verified with Codex under maintainer direction.

---------

Co-authored-by: Paul Bakaus <paul.bakaus@gmail.com>
2026-09-05 15:01:58 -07:00
github-actions[bot] 0ac0b6866f Sync generated provider output 2026-09-05 20:47:55 +00:00
Abdul WahabandGitHub 2a9957589c Fix: replace dead tests references with GitHub permalinks (#739)
Replace five repository-local test references with immutable GitHub links while preserving inline examples. Fixes #721.

AI-assisted contribution prepared with Cursor; maintainer verification and merge assisted by Codex. Verified pinned targets and matching examples, source-first build, generated links, and default tests (engine-dependent suites skipped without a local engine binary).
2026-09-05 13:47:28 -07:00
github-actions[bot] 4bee58d89e Sync generated provider output 2026-09-05 20:03:16 +00:00
Abdul WahabandGitHub a443ec0d8f Fix Claude non-interactive skill activation (#738)
Keep allowed-tools in shared source and suppress it only for Claude output and the plugin. Verified against current main with provider builds, local tests, real plugin loader checks, and an activation-only Claude A/B test reproducing the original denial and successful fixed activation. AI-assisted implementation and verification under maintainer direction.
2026-09-05 13:02:37 -07:00
github-actions[bot] 94d8611af6 Sync generated provider output 2026-09-05 18:30:47 +00:00
Paul BakausandGitHub 6e61113e3c Fix: report removed launcher downloads accurately (#741)
* Fix: distinguish removed launcher downloads from checksum failures

Related to #740; keep the antivirus investigation open. Add executable launcher regressions and a native Windows CI lane. AI assistance: prepared with Codex under Paul Bakaus direction.

* Fix: diagnose downloads removed during cache placement

Cover removal and truncation around rename and preserve fail-closed behavior through cache placement. AI-assisted under maintainer direction.

* Test Windows launcher hash and placement failures

Inject failures at command boundaries in a staged test copy while retaining real launcher control flow. Cover both platforms with the same assertions. AI-assisted under maintainer direction.
2026-09-05 11:30:19 -07:00
github-actions[bot] 381d52b38f Sync generated provider output 2026-09-05 17:47:59 +00:00
168 changed files with 2504 additions and 389 deletions
+2 -1
View File
@@ -69,7 +69,8 @@ Choose the mode from the requested surface, not the product, and persist it only
Routing:
- **No argument:** read [routing.md](reference/routing.md) and present its context-aware menu; never auto-run a command.
- **Explicit or clearly implied command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Explicit or clearly implied request to run a command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Workflow or command-selection question:** read [Workflow questions](reference/routing.md#workflow-questions).
- **Otherwise:** treat the request as general design work. Missing PRODUCT.md routes a new surface or replacement world through init, then new-work; a narrow refinement of existing code proceeds on the incumbent implementation as `impeccable context` directs, offering init afterward rather than blocking on it.
- `teach` aliases `init`. `craft` is a deprecated alias for ordinary new-work and adds nothing. `shape` owns task discovery, then enters new-work only for visual-world and surface-concept decisions.
@@ -78,7 +78,7 @@ const __impeccableLiveDev =
process.env.NODE_ENV === "development" ? ["http://localhost:8400"] : [];
```
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: `tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts`, `tests/framework-fixtures/sveltekit-csp/expected-after-patch.js`. Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: [nextjs-turborepo/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts), [sveltekit-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/sveltekit-csp/expected-after-patch.js). Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
### append-string
@@ -93,7 +93,7 @@ const __impeccableLiveDev =
- `script-src 'self' 'unsafe-inline'` becomes `` `script-src 'self' 'unsafe-inline'${__impeccableLiveDev}` ``
- `connect-src 'self'` becomes `` `connect-src 'self'${__impeccableLiveDev}` ``
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: `tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js`, `tests/framework-fixtures/nuxt-csp/expected-after-patch.ts`.
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: [nextjs-inline-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js), [nuxt-csp/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nuxt-csp/expected-after-patch.ts).
## Troubleshooting
+1 -1
View File
@@ -196,7 +196,7 @@ Complete HTML replacement of the original element per variant, not a CSS-only pa
Replace the style opening tag with `cssAuthoring.styleTag` when the tool returns a different one. **Each variant div contains exactly one top-level element**, same tag as the original; loose siblings break outline tracking and accept. First variant visible, all others `display: none`. The browser's MutationObserver accepts atomic or progressive arrival; accepting an arrived variant fences the worker, so later publications are rejected.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in `tests/live-e2e/agent.mjs` is a faithful template.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in the [repo agent template](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/live-e2e/agent.mjs) is a faithful template.
**JSX / TSX targets:** wrap `<style>` content in a template literal (CSS braces would parse as JSX), use `className=` / `style={{…}}`, keep `data-impeccable-*` attributes as plain strings:
@@ -1,4 +1,10 @@
# No-argument routing: the context-aware menu
# Command guidance
## Workflow questions
Give advice without executing commands; the menu below is only for bare invocations. Consult relevant command references as needed for prerequisites and scope. Link to the [docs](https://impeccable.style/docs/) for the broader workflow guide. If the user also requests execution, follow that request.
## No-argument routing: the context-aware menu
Read this when the user invokes `/impeccable` with no argument. They are asking "what should I do?" Make the menu context-aware instead of static.
+1 -1
View File
@@ -1 +1 @@
0.1.0
0.1.1
+38 -5
View File
@@ -96,6 +96,19 @@ fetch_url() {
return 1
fi
}
check_download() {
download_file=${1:-$tmp}
if [ ! -f "$download_file" ]; then
rm -f "$tmp.sha256"
echo "impeccable: download completed but the file was removed before execution: $url; check your antivirus quarantine or logs. Refusing to continue; do not disable protection." >&2
exit 127
fi
if [ ! -s "$download_file" ]; then
rm -f "$download_file" "$tmp.sha256"
echo "impeccable: downloaded file is empty: $url; refusing the unverified download" >&2
exit 127
fi
}
if [ -n "$probing" ]; then
# Inside another launcher's probe: no download, fail fast and quiet.
exit 127
@@ -116,6 +129,7 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
fetch_url "$url" && fetched=1
fi
if [ "$fetched" = 1 ]; then
check_download
# Fail closed: a freshly downloaded binary runs only after verifying
# against its .sha256 sidecar. A sidecar that cannot be fetched, or a
# machine with no sha256 tool, refuses the download instead of exec'ing
@@ -127,15 +141,20 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
elif command -v wget >/dev/null 2>&1; then
wget -q -O "$tmp.sha256" "$url.sha256" 2>/dev/null && sidecar_ok=1
fi
check_download
expected=""
[ "$sidecar_ok" = 1 ] && expected=$(cut -d' ' -f1 < "$tmp.sha256")
actual=""
if command -v shasum >/dev/null 2>&1; then actual=$(shasum -a 256 "$tmp" | cut -d' ' -f1)
elif command -v sha256sum >/dev/null 2>&1; then actual=$(sha256sum "$tmp" | cut -d' ' -f1); fi
if command -v shasum >/dev/null 2>&1; then
if digest=$(shasum -a 256 "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
elif command -v sha256sum >/dev/null 2>&1; then
if digest=$(sha256sum "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
fi
check_download
rm -f "$tmp.sha256"
if [ -z "$expected" ] || [ -z "$actual" ]; then
rm -f "$tmp"
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or no sha256 tool); refusing the unverified download" >&2
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or hashing failed); refusing the unverified download" >&2
exit 127
fi
if [ "$actual" != "$expected" ]; then
@@ -143,8 +162,22 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
echo "impeccable: checksum mismatch downloading $url" >&2
exit 127
fi
chmod +x "$tmp" 2>/dev/null
mv -f "$tmp" "$cached" && exec "$cached" "$@"
check_download
if ! chmod +x "$tmp" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not make the verified download executable: $url" >&2
exit 127
fi
check_download
if ! mv -f "$tmp" "$cached" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not cache the verified download: $url" >&2
exit 127
fi
check_download "$cached"
exec "$cached" "$@"
fi
rm -f "$tmp" 2>/dev/null
fi
@@ -82,6 +82,8 @@ curl.exe -fsSL -o "%cached%.part" "%url%" >nul 2>nul
if errorlevel 1 goto fail
:verify
call :check_download
if errorlevel 1 exit /b 127
rem Mirrors the sh launcher and fails closed: a freshly downloaded binary
rem runs only after verifying against its .sha256 sidecar. A sidecar that
rem cannot be fetched, or an empty certutil result, refuses the download
@@ -91,8 +93,16 @@ if errorlevel 1 goto verify_refuse
set "expected="
set /p expected=<"%cached%.sha256"
for /f "tokens=1" %%h in ("%expected%") do set "expected=%%h"
call :check_download
if errorlevel 1 exit /b 127
set "actual="
for /f "skip=1 delims=" %%h in ('certutil -hashfile "%cached%.part" SHA256 2^>nul') do if not defined actual set "actual=%%h"
rem Reuse the sidecar staging file after reading expected. Check certutil's
rem status before parsing: its error text on stdout is not a digest.
certutil -hashfile "%cached%.part" SHA256 >"%cached%.sha256" 2>nul
if errorlevel 1 goto verify_refuse
call :check_download
if errorlevel 1 exit /b 127
for /f "usebackq skip=1 delims=" %%h in ("%cached%.sha256") do if not defined actual set "actual=%%h"
del "%cached%.sha256" >nul 2>nul
if not defined expected goto verify_refuse
if not defined actual goto verify_refuse
@@ -103,17 +113,48 @@ echo impeccable: checksum mismatch downloading %url% 1>&2
exit /b 127
:verify_refuse
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: cannot verify %url% against %url%.sha256; refusing the unverified download 1>&2
exit /b 127
:check_download
set "download_file=%~1"
if not defined download_file set "download_file=%cached%.part"
if not exist "%download_file%" goto download_missing
for %%f in ("%download_file%") do if %%~zf==0 goto download_empty
exit /b 0
:download_missing
del "%cached%.sha256" >nul 2>nul
echo impeccable: download completed but the file was removed before execution: %url%; check your antivirus quarantine or logs. Refusing to continue; do not disable protection. 1>&2
exit /b 127
:download_empty
del "%download_file%" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: downloaded file is empty: %url%; refusing the unverified download 1>&2
exit /b 127
:place
call :check_download
if errorlevel 1 exit /b 127
move /y "%cached%.part" "%cached%" >nul 2>nul
if not exist "%cached%" goto fail
if errorlevel 1 goto place_failed
call :check_download "%cached%"
if errorlevel 1 exit /b 127
set "run=%cached%"
goto run
:place_failed
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
echo impeccable: could not cache the verified download: %url% 1>&2
exit /b 127
:run
"%run%" %*
exit /b
@@ -7834,7 +7834,6 @@
if (editBadgeEl && editBadgeEl.style.display !== 'none') renderEditBadge('idle-disabled');
showBar('generating');
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -7916,7 +7915,6 @@
showBar('generating');
startScrollTracking();
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -8238,7 +8236,8 @@
// rasterization from delaying the fetch itself.
if (!hasAnnotations) {
basePayload.clientSentAt = Date.now();
await sendEvent(basePayload);
const created = await sendEvent(basePayload);
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
let screenshotPath;
@@ -8279,7 +8278,10 @@
// is semantic input. Plain requests were already dispatched above.
if (hasAnnotations) {
basePayload.clientSentAt = Date.now();
sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
const created = await sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
// Capture/upload can take seconds. Progress before this acknowledgment
// refers to an unknown session and would clear our own active work.
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
}
+2 -1
View File
@@ -66,7 +66,8 @@ Choose the mode from the requested surface, not the product, and persist it only
Routing:
- **No argument:** read [routing.md](reference/routing.md) and present its context-aware menu; never auto-run a command.
- **Explicit or clearly implied command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Explicit or clearly implied request to run a command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Workflow or command-selection question:** read [Workflow questions](reference/routing.md#workflow-questions).
- **Otherwise:** treat the request as general design work. Missing PRODUCT.md routes a new surface or replacement world through init, then new-work; a narrow refinement of existing code proceeds on the incumbent implementation as `impeccable context` directs, offering init afterward rather than blocking on it.
- `teach` aliases `init`. `craft` is a deprecated alias for ordinary new-work and adds nothing. `shape` owns task discovery, then enters new-work only for visual-world and surface-concept decisions.
@@ -78,7 +78,7 @@ const __impeccableLiveDev =
process.env.NODE_ENV === "development" ? ["http://localhost:8400"] : [];
```
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: `tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts`, `tests/framework-fixtures/sveltekit-csp/expected-after-patch.js`. Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: [nextjs-turborepo/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts), [sveltekit-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/sveltekit-csp/expected-after-patch.js). Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
### append-string
@@ -93,7 +93,7 @@ const __impeccableLiveDev =
- `script-src 'self' 'unsafe-inline'` becomes `` `script-src 'self' 'unsafe-inline'${__impeccableLiveDev}` ``
- `connect-src 'self'` becomes `` `connect-src 'self'${__impeccableLiveDev}` ``
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: `tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js`, `tests/framework-fixtures/nuxt-csp/expected-after-patch.ts`.
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: [nextjs-inline-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js), [nuxt-csp/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nuxt-csp/expected-after-patch.ts).
## Troubleshooting
+1 -1
View File
@@ -198,7 +198,7 @@ Complete HTML replacement of the original element per variant, not a CSS-only pa
Replace the style opening tag with `cssAuthoring.styleTag` when the tool returns a different one. **Each variant div contains exactly one top-level element**, same tag as the original; loose siblings break outline tracking and accept. First variant visible, all others `display: none`. The browser's MutationObserver accepts atomic or progressive arrival; accepting an arrived variant fences the worker, so later publications are rejected.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in `tests/live-e2e/agent.mjs` is a faithful template.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in the [repo agent template](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/live-e2e/agent.mjs) is a faithful template.
**JSX / TSX targets:** wrap `<style>` content in a template literal (CSS braces would parse as JSX), use `className=` / `style={{…}}`, keep `data-impeccable-*` attributes as plain strings:
@@ -1,4 +1,10 @@
# No-argument routing: the context-aware menu
# Command guidance
## Workflow questions
Give advice without executing commands; the menu below is only for bare invocations. Consult relevant command references as needed for prerequisites and scope. Link to the [docs](https://impeccable.style/docs/) for the broader workflow guide. If the user also requests execution, follow that request.
## No-argument routing: the context-aware menu
Read this when the user invokes `$impeccable` with no argument. They are asking "what should I do?" Make the menu context-aware instead of static.
+1 -1
View File
@@ -1 +1 @@
0.1.0
0.1.1
+38 -5
View File
@@ -96,6 +96,19 @@ fetch_url() {
return 1
fi
}
check_download() {
download_file=${1:-$tmp}
if [ ! -f "$download_file" ]; then
rm -f "$tmp.sha256"
echo "impeccable: download completed but the file was removed before execution: $url; check your antivirus quarantine or logs. Refusing to continue; do not disable protection." >&2
exit 127
fi
if [ ! -s "$download_file" ]; then
rm -f "$download_file" "$tmp.sha256"
echo "impeccable: downloaded file is empty: $url; refusing the unverified download" >&2
exit 127
fi
}
if [ -n "$probing" ]; then
# Inside another launcher's probe: no download, fail fast and quiet.
exit 127
@@ -116,6 +129,7 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
fetch_url "$url" && fetched=1
fi
if [ "$fetched" = 1 ]; then
check_download
# Fail closed: a freshly downloaded binary runs only after verifying
# against its .sha256 sidecar. A sidecar that cannot be fetched, or a
# machine with no sha256 tool, refuses the download instead of exec'ing
@@ -127,15 +141,20 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
elif command -v wget >/dev/null 2>&1; then
wget -q -O "$tmp.sha256" "$url.sha256" 2>/dev/null && sidecar_ok=1
fi
check_download
expected=""
[ "$sidecar_ok" = 1 ] && expected=$(cut -d' ' -f1 < "$tmp.sha256")
actual=""
if command -v shasum >/dev/null 2>&1; then actual=$(shasum -a 256 "$tmp" | cut -d' ' -f1)
elif command -v sha256sum >/dev/null 2>&1; then actual=$(sha256sum "$tmp" | cut -d' ' -f1); fi
if command -v shasum >/dev/null 2>&1; then
if digest=$(shasum -a 256 "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
elif command -v sha256sum >/dev/null 2>&1; then
if digest=$(sha256sum "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
fi
check_download
rm -f "$tmp.sha256"
if [ -z "$expected" ] || [ -z "$actual" ]; then
rm -f "$tmp"
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or no sha256 tool); refusing the unverified download" >&2
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or hashing failed); refusing the unverified download" >&2
exit 127
fi
if [ "$actual" != "$expected" ]; then
@@ -143,8 +162,22 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
echo "impeccable: checksum mismatch downloading $url" >&2
exit 127
fi
chmod +x "$tmp" 2>/dev/null
mv -f "$tmp" "$cached" && exec "$cached" "$@"
check_download
if ! chmod +x "$tmp" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not make the verified download executable: $url" >&2
exit 127
fi
check_download
if ! mv -f "$tmp" "$cached" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not cache the verified download: $url" >&2
exit 127
fi
check_download "$cached"
exec "$cached" "$@"
fi
rm -f "$tmp" 2>/dev/null
fi
@@ -82,6 +82,8 @@ curl.exe -fsSL -o "%cached%.part" "%url%" >nul 2>nul
if errorlevel 1 goto fail
:verify
call :check_download
if errorlevel 1 exit /b 127
rem Mirrors the sh launcher and fails closed: a freshly downloaded binary
rem runs only after verifying against its .sha256 sidecar. A sidecar that
rem cannot be fetched, or an empty certutil result, refuses the download
@@ -91,8 +93,16 @@ if errorlevel 1 goto verify_refuse
set "expected="
set /p expected=<"%cached%.sha256"
for /f "tokens=1" %%h in ("%expected%") do set "expected=%%h"
call :check_download
if errorlevel 1 exit /b 127
set "actual="
for /f "skip=1 delims=" %%h in ('certutil -hashfile "%cached%.part" SHA256 2^>nul') do if not defined actual set "actual=%%h"
rem Reuse the sidecar staging file after reading expected. Check certutil's
rem status before parsing: its error text on stdout is not a digest.
certutil -hashfile "%cached%.part" SHA256 >"%cached%.sha256" 2>nul
if errorlevel 1 goto verify_refuse
call :check_download
if errorlevel 1 exit /b 127
for /f "usebackq skip=1 delims=" %%h in ("%cached%.sha256") do if not defined actual set "actual=%%h"
del "%cached%.sha256" >nul 2>nul
if not defined expected goto verify_refuse
if not defined actual goto verify_refuse
@@ -103,17 +113,48 @@ echo impeccable: checksum mismatch downloading %url% 1>&2
exit /b 127
:verify_refuse
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: cannot verify %url% against %url%.sha256; refusing the unverified download 1>&2
exit /b 127
:check_download
set "download_file=%~1"
if not defined download_file set "download_file=%cached%.part"
if not exist "%download_file%" goto download_missing
for %%f in ("%download_file%") do if %%~zf==0 goto download_empty
exit /b 0
:download_missing
del "%cached%.sha256" >nul 2>nul
echo impeccable: download completed but the file was removed before execution: %url%; check your antivirus quarantine or logs. Refusing to continue; do not disable protection. 1>&2
exit /b 127
:download_empty
del "%download_file%" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: downloaded file is empty: %url%; refusing the unverified download 1>&2
exit /b 127
:place
call :check_download
if errorlevel 1 exit /b 127
move /y "%cached%.part" "%cached%" >nul 2>nul
if not exist "%cached%" goto fail
if errorlevel 1 goto place_failed
call :check_download "%cached%"
if errorlevel 1 exit /b 127
set "run=%cached%"
goto run
:place_failed
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
echo impeccable: could not cache the verified download: %url% 1>&2
exit /b 127
:run
"%run%" %*
exit /b
@@ -7834,7 +7834,6 @@
if (editBadgeEl && editBadgeEl.style.display !== 'none') renderEditBadge('idle-disabled');
showBar('generating');
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -7916,7 +7915,6 @@
showBar('generating');
startScrollTracking();
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -8238,7 +8236,8 @@
// rasterization from delaying the fetch itself.
if (!hasAnnotations) {
basePayload.clientSentAt = Date.now();
await sendEvent(basePayload);
const created = await sendEvent(basePayload);
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
let screenshotPath;
@@ -8279,7 +8278,10 @@
// is semantic input. Plain requests were already dispatched above.
if (hasAnnotations) {
basePayload.clientSentAt = Date.now();
sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
const created = await sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
// Capture/upload can take seconds. Progress before this acknowledgment
// refers to an unknown session and would clear our own active work.
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
}
+2 -4
View File
@@ -5,9 +5,6 @@ version: 4.2.0
user-invocable: true
argument-hint: "[shape · audit|critique · animate|bolder|colorize|delight|layout|overdrive|quieter|typeset · adapt|clarify|distill · harden|onboard|optimize|polish · init|document|extract|live] [target]"
license: Apache 2.0
allowed-tools:
- Bash(npx impeccable *)
- Bash(.claude/skills/impeccable/scripts/impeccable *)
---
This skill gives you the tools and permission to create design that earns to be called out-of-distribution craft: Whereas before, your design work would have been safe, timid and measured, you now approach every design task as an award-winning design director with impeccable understanding for what makes exceptional design work: production-grade code, peak creativity, a clear POV, deep understanding of the needs of the client and users, and exceptional craft.
@@ -71,7 +68,8 @@ Choose the mode from the requested surface, not the product, and persist it only
Routing:
- **No argument:** read [routing.md](reference/routing.md) and present its context-aware menu; never auto-run a command.
- **Explicit or clearly implied command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Explicit or clearly implied request to run a command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Workflow or command-selection question:** read [Workflow questions](reference/routing.md#workflow-questions).
- **Otherwise:** treat the request as general design work. Missing PRODUCT.md routes a new surface or replacement world through init, then new-work; a narrow refinement of existing code proceeds on the incumbent implementation as `impeccable context` directs, offering init afterward rather than blocking on it.
- `teach` aliases `init`. `craft` is a deprecated alias for ordinary new-work and adds nothing. `shape` owns task discovery, then enters new-work only for visual-world and surface-concept decisions.
@@ -78,7 +78,7 @@ const __impeccableLiveDev =
process.env.NODE_ENV === "development" ? ["http://localhost:8400"] : [];
```
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: `tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts`, `tests/framework-fixtures/sveltekit-csp/expected-after-patch.js`. Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: [nextjs-turborepo/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts), [sveltekit-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/sveltekit-csp/expected-after-patch.js). Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
### append-string
@@ -93,7 +93,7 @@ const __impeccableLiveDev =
- `script-src 'self' 'unsafe-inline'` becomes `` `script-src 'self' 'unsafe-inline'${__impeccableLiveDev}` ``
- `connect-src 'self'` becomes `` `connect-src 'self'${__impeccableLiveDev}` ``
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: `tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js`, `tests/framework-fixtures/nuxt-csp/expected-after-patch.ts`.
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: [nextjs-inline-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js), [nuxt-csp/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nuxt-csp/expected-after-patch.ts).
## Troubleshooting
+1 -1
View File
@@ -196,7 +196,7 @@ Complete HTML replacement of the original element per variant, not a CSS-only pa
Replace the style opening tag with `cssAuthoring.styleTag` when the tool returns a different one. **Each variant div contains exactly one top-level element**, same tag as the original; loose siblings break outline tracking and accept. First variant visible, all others `display: none`. The browser's MutationObserver accepts atomic or progressive arrival; accepting an arrived variant fences the worker, so later publications are rejected.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in `tests/live-e2e/agent.mjs` is a faithful template.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in the [repo agent template](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/live-e2e/agent.mjs) is a faithful template.
**JSX / TSX targets:** wrap `<style>` content in a template literal (CSS braces would parse as JSX), use `className=` / `style={{…}}`, keep `data-impeccable-*` attributes as plain strings:
@@ -1,4 +1,10 @@
# No-argument routing: the context-aware menu
# Command guidance
## Workflow questions
Give advice without executing commands; the menu below is only for bare invocations. Consult relevant command references as needed for prerequisites and scope. Link to the [docs](https://impeccable.style/docs/) for the broader workflow guide. If the user also requests execution, follow that request.
## No-argument routing: the context-aware menu
Read this when the user invokes `/impeccable` with no argument. They are asking "what should I do?" Make the menu context-aware instead of static.
+1 -1
View File
@@ -1 +1 @@
0.1.0
0.1.1
+38 -5
View File
@@ -96,6 +96,19 @@ fetch_url() {
return 1
fi
}
check_download() {
download_file=${1:-$tmp}
if [ ! -f "$download_file" ]; then
rm -f "$tmp.sha256"
echo "impeccable: download completed but the file was removed before execution: $url; check your antivirus quarantine or logs. Refusing to continue; do not disable protection." >&2
exit 127
fi
if [ ! -s "$download_file" ]; then
rm -f "$download_file" "$tmp.sha256"
echo "impeccable: downloaded file is empty: $url; refusing the unverified download" >&2
exit 127
fi
}
if [ -n "$probing" ]; then
# Inside another launcher's probe: no download, fail fast and quiet.
exit 127
@@ -116,6 +129,7 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
fetch_url "$url" && fetched=1
fi
if [ "$fetched" = 1 ]; then
check_download
# Fail closed: a freshly downloaded binary runs only after verifying
# against its .sha256 sidecar. A sidecar that cannot be fetched, or a
# machine with no sha256 tool, refuses the download instead of exec'ing
@@ -127,15 +141,20 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
elif command -v wget >/dev/null 2>&1; then
wget -q -O "$tmp.sha256" "$url.sha256" 2>/dev/null && sidecar_ok=1
fi
check_download
expected=""
[ "$sidecar_ok" = 1 ] && expected=$(cut -d' ' -f1 < "$tmp.sha256")
actual=""
if command -v shasum >/dev/null 2>&1; then actual=$(shasum -a 256 "$tmp" | cut -d' ' -f1)
elif command -v sha256sum >/dev/null 2>&1; then actual=$(sha256sum "$tmp" | cut -d' ' -f1); fi
if command -v shasum >/dev/null 2>&1; then
if digest=$(shasum -a 256 "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
elif command -v sha256sum >/dev/null 2>&1; then
if digest=$(sha256sum "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
fi
check_download
rm -f "$tmp.sha256"
if [ -z "$expected" ] || [ -z "$actual" ]; then
rm -f "$tmp"
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or no sha256 tool); refusing the unverified download" >&2
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or hashing failed); refusing the unverified download" >&2
exit 127
fi
if [ "$actual" != "$expected" ]; then
@@ -143,8 +162,22 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
echo "impeccable: checksum mismatch downloading $url" >&2
exit 127
fi
chmod +x "$tmp" 2>/dev/null
mv -f "$tmp" "$cached" && exec "$cached" "$@"
check_download
if ! chmod +x "$tmp" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not make the verified download executable: $url" >&2
exit 127
fi
check_download
if ! mv -f "$tmp" "$cached" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not cache the verified download: $url" >&2
exit 127
fi
check_download "$cached"
exec "$cached" "$@"
fi
rm -f "$tmp" 2>/dev/null
fi
@@ -82,6 +82,8 @@ curl.exe -fsSL -o "%cached%.part" "%url%" >nul 2>nul
if errorlevel 1 goto fail
:verify
call :check_download
if errorlevel 1 exit /b 127
rem Mirrors the sh launcher and fails closed: a freshly downloaded binary
rem runs only after verifying against its .sha256 sidecar. A sidecar that
rem cannot be fetched, or an empty certutil result, refuses the download
@@ -91,8 +93,16 @@ if errorlevel 1 goto verify_refuse
set "expected="
set /p expected=<"%cached%.sha256"
for /f "tokens=1" %%h in ("%expected%") do set "expected=%%h"
call :check_download
if errorlevel 1 exit /b 127
set "actual="
for /f "skip=1 delims=" %%h in ('certutil -hashfile "%cached%.part" SHA256 2^>nul') do if not defined actual set "actual=%%h"
rem Reuse the sidecar staging file after reading expected. Check certutil's
rem status before parsing: its error text on stdout is not a digest.
certutil -hashfile "%cached%.part" SHA256 >"%cached%.sha256" 2>nul
if errorlevel 1 goto verify_refuse
call :check_download
if errorlevel 1 exit /b 127
for /f "usebackq skip=1 delims=" %%h in ("%cached%.sha256") do if not defined actual set "actual=%%h"
del "%cached%.sha256" >nul 2>nul
if not defined expected goto verify_refuse
if not defined actual goto verify_refuse
@@ -103,17 +113,48 @@ echo impeccable: checksum mismatch downloading %url% 1>&2
exit /b 127
:verify_refuse
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: cannot verify %url% against %url%.sha256; refusing the unverified download 1>&2
exit /b 127
:check_download
set "download_file=%~1"
if not defined download_file set "download_file=%cached%.part"
if not exist "%download_file%" goto download_missing
for %%f in ("%download_file%") do if %%~zf==0 goto download_empty
exit /b 0
:download_missing
del "%cached%.sha256" >nul 2>nul
echo impeccable: download completed but the file was removed before execution: %url%; check your antivirus quarantine or logs. Refusing to continue; do not disable protection. 1>&2
exit /b 127
:download_empty
del "%download_file%" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: downloaded file is empty: %url%; refusing the unverified download 1>&2
exit /b 127
:place
call :check_download
if errorlevel 1 exit /b 127
move /y "%cached%.part" "%cached%" >nul 2>nul
if not exist "%cached%" goto fail
if errorlevel 1 goto place_failed
call :check_download "%cached%"
if errorlevel 1 exit /b 127
set "run=%cached%"
goto run
:place_failed
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
echo impeccable: could not cache the verified download: %url% 1>&2
exit /b 127
:run
"%run%" %*
exit /b
@@ -7834,7 +7834,6 @@
if (editBadgeEl && editBadgeEl.style.display !== 'none') renderEditBadge('idle-disabled');
showBar('generating');
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -7916,7 +7915,6 @@
showBar('generating');
startScrollTracking();
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -8238,7 +8236,8 @@
// rasterization from delaying the fetch itself.
if (!hasAnnotations) {
basePayload.clientSentAt = Date.now();
await sendEvent(basePayload);
const created = await sendEvent(basePayload);
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
let screenshotPath;
@@ -8279,7 +8278,10 @@
// is semantic input. Plain requests were already dispatched above.
if (hasAnnotations) {
basePayload.clientSentAt = Date.now();
sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
const created = await sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
// Capture/upload can take seconds. Progress before this acknowledgment
// refers to an unknown session and would clear our own active work.
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
}
+2 -1
View File
@@ -66,7 +66,8 @@ Choose the mode from the requested surface, not the product, and persist it only
Routing:
- **No argument:** read [routing.md](reference/routing.md) and present its context-aware menu; never auto-run a command.
- **Explicit or clearly implied command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Explicit or clearly implied request to run a command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Workflow or command-selection question:** read [Workflow questions](reference/routing.md#workflow-questions).
- **Otherwise:** treat the request as general design work. Missing PRODUCT.md routes a new surface or replacement world through init, then new-work; a narrow refinement of existing code proceeds on the incumbent implementation as `impeccable context` directs, offering init afterward rather than blocking on it.
- `teach` aliases `init`. `craft` is a deprecated alias for ordinary new-work and adds nothing. `shape` owns task discovery, then enters new-work only for visual-world and surface-concept decisions.
@@ -78,7 +78,7 @@ const __impeccableLiveDev =
process.env.NODE_ENV === "development" ? ["http://localhost:8400"] : [];
```
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: `tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts`, `tests/framework-fixtures/sveltekit-csp/expected-after-patch.js`. Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: [nextjs-turborepo/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts), [sveltekit-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/sveltekit-csp/expected-after-patch.js). Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
### append-string
@@ -93,7 +93,7 @@ const __impeccableLiveDev =
- `script-src 'self' 'unsafe-inline'` becomes `` `script-src 'self' 'unsafe-inline'${__impeccableLiveDev}` ``
- `connect-src 'self'` becomes `` `connect-src 'self'${__impeccableLiveDev}` ``
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: `tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js`, `tests/framework-fixtures/nuxt-csp/expected-after-patch.ts`.
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: [nextjs-inline-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js), [nuxt-csp/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nuxt-csp/expected-after-patch.ts).
## Troubleshooting
+1 -1
View File
@@ -196,7 +196,7 @@ Complete HTML replacement of the original element per variant, not a CSS-only pa
Replace the style opening tag with `cssAuthoring.styleTag` when the tool returns a different one. **Each variant div contains exactly one top-level element**, same tag as the original; loose siblings break outline tracking and accept. First variant visible, all others `display: none`. The browser's MutationObserver accepts atomic or progressive arrival; accepting an arrived variant fences the worker, so later publications are rejected.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in `tests/live-e2e/agent.mjs` is a faithful template.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in the [repo agent template](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/live-e2e/agent.mjs) is a faithful template.
**JSX / TSX targets:** wrap `<style>` content in a template literal (CSS braces would parse as JSX), use `className=` / `style={{…}}`, keep `data-impeccable-*` attributes as plain strings:
@@ -1,4 +1,10 @@
# No-argument routing: the context-aware menu
# Command guidance
## Workflow questions
Give advice without executing commands; the menu below is only for bare invocations. Consult relevant command references as needed for prerequisites and scope. Link to the [docs](https://impeccable.style/docs/) for the broader workflow guide. If the user also requests execution, follow that request.
## No-argument routing: the context-aware menu
Read this when the user invokes `/impeccable` with no argument. They are asking "what should I do?" Make the menu context-aware instead of static.
+1 -1
View File
@@ -1 +1 @@
0.1.0
0.1.1
+38 -5
View File
@@ -96,6 +96,19 @@ fetch_url() {
return 1
fi
}
check_download() {
download_file=${1:-$tmp}
if [ ! -f "$download_file" ]; then
rm -f "$tmp.sha256"
echo "impeccable: download completed but the file was removed before execution: $url; check your antivirus quarantine or logs. Refusing to continue; do not disable protection." >&2
exit 127
fi
if [ ! -s "$download_file" ]; then
rm -f "$download_file" "$tmp.sha256"
echo "impeccable: downloaded file is empty: $url; refusing the unverified download" >&2
exit 127
fi
}
if [ -n "$probing" ]; then
# Inside another launcher's probe: no download, fail fast and quiet.
exit 127
@@ -116,6 +129,7 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
fetch_url "$url" && fetched=1
fi
if [ "$fetched" = 1 ]; then
check_download
# Fail closed: a freshly downloaded binary runs only after verifying
# against its .sha256 sidecar. A sidecar that cannot be fetched, or a
# machine with no sha256 tool, refuses the download instead of exec'ing
@@ -127,15 +141,20 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
elif command -v wget >/dev/null 2>&1; then
wget -q -O "$tmp.sha256" "$url.sha256" 2>/dev/null && sidecar_ok=1
fi
check_download
expected=""
[ "$sidecar_ok" = 1 ] && expected=$(cut -d' ' -f1 < "$tmp.sha256")
actual=""
if command -v shasum >/dev/null 2>&1; then actual=$(shasum -a 256 "$tmp" | cut -d' ' -f1)
elif command -v sha256sum >/dev/null 2>&1; then actual=$(sha256sum "$tmp" | cut -d' ' -f1); fi
if command -v shasum >/dev/null 2>&1; then
if digest=$(shasum -a 256 "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
elif command -v sha256sum >/dev/null 2>&1; then
if digest=$(sha256sum "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
fi
check_download
rm -f "$tmp.sha256"
if [ -z "$expected" ] || [ -z "$actual" ]; then
rm -f "$tmp"
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or no sha256 tool); refusing the unverified download" >&2
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or hashing failed); refusing the unverified download" >&2
exit 127
fi
if [ "$actual" != "$expected" ]; then
@@ -143,8 +162,22 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
echo "impeccable: checksum mismatch downloading $url" >&2
exit 127
fi
chmod +x "$tmp" 2>/dev/null
mv -f "$tmp" "$cached" && exec "$cached" "$@"
check_download
if ! chmod +x "$tmp" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not make the verified download executable: $url" >&2
exit 127
fi
check_download
if ! mv -f "$tmp" "$cached" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not cache the verified download: $url" >&2
exit 127
fi
check_download "$cached"
exec "$cached" "$@"
fi
rm -f "$tmp" 2>/dev/null
fi
@@ -82,6 +82,8 @@ curl.exe -fsSL -o "%cached%.part" "%url%" >nul 2>nul
if errorlevel 1 goto fail
:verify
call :check_download
if errorlevel 1 exit /b 127
rem Mirrors the sh launcher and fails closed: a freshly downloaded binary
rem runs only after verifying against its .sha256 sidecar. A sidecar that
rem cannot be fetched, or an empty certutil result, refuses the download
@@ -91,8 +93,16 @@ if errorlevel 1 goto verify_refuse
set "expected="
set /p expected=<"%cached%.sha256"
for /f "tokens=1" %%h in ("%expected%") do set "expected=%%h"
call :check_download
if errorlevel 1 exit /b 127
set "actual="
for /f "skip=1 delims=" %%h in ('certutil -hashfile "%cached%.part" SHA256 2^>nul') do if not defined actual set "actual=%%h"
rem Reuse the sidecar staging file after reading expected. Check certutil's
rem status before parsing: its error text on stdout is not a digest.
certutil -hashfile "%cached%.part" SHA256 >"%cached%.sha256" 2>nul
if errorlevel 1 goto verify_refuse
call :check_download
if errorlevel 1 exit /b 127
for /f "usebackq skip=1 delims=" %%h in ("%cached%.sha256") do if not defined actual set "actual=%%h"
del "%cached%.sha256" >nul 2>nul
if not defined expected goto verify_refuse
if not defined actual goto verify_refuse
@@ -103,17 +113,48 @@ echo impeccable: checksum mismatch downloading %url% 1>&2
exit /b 127
:verify_refuse
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: cannot verify %url% against %url%.sha256; refusing the unverified download 1>&2
exit /b 127
:check_download
set "download_file=%~1"
if not defined download_file set "download_file=%cached%.part"
if not exist "%download_file%" goto download_missing
for %%f in ("%download_file%") do if %%~zf==0 goto download_empty
exit /b 0
:download_missing
del "%cached%.sha256" >nul 2>nul
echo impeccable: download completed but the file was removed before execution: %url%; check your antivirus quarantine or logs. Refusing to continue; do not disable protection. 1>&2
exit /b 127
:download_empty
del "%download_file%" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: downloaded file is empty: %url%; refusing the unverified download 1>&2
exit /b 127
:place
call :check_download
if errorlevel 1 exit /b 127
move /y "%cached%.part" "%cached%" >nul 2>nul
if not exist "%cached%" goto fail
if errorlevel 1 goto place_failed
call :check_download "%cached%"
if errorlevel 1 exit /b 127
set "run=%cached%"
goto run
:place_failed
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
echo impeccable: could not cache the verified download: %url% 1>&2
exit /b 127
:run
"%run%" %*
exit /b
@@ -7834,7 +7834,6 @@
if (editBadgeEl && editBadgeEl.style.display !== 'none') renderEditBadge('idle-disabled');
showBar('generating');
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -7916,7 +7915,6 @@
showBar('generating');
startScrollTracking();
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -8238,7 +8236,8 @@
// rasterization from delaying the fetch itself.
if (!hasAnnotations) {
basePayload.clientSentAt = Date.now();
await sendEvent(basePayload);
const created = await sendEvent(basePayload);
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
let screenshotPath;
@@ -8279,7 +8278,10 @@
// is semantic input. Plain requests were already dispatched above.
if (hasAnnotations) {
basePayload.clientSentAt = Date.now();
sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
const created = await sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
// Capture/upload can take seconds. Progress before this acknowledgment
// refers to an unknown session and would clear our own active work.
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
}
+2 -1
View File
@@ -65,7 +65,8 @@ Choose the mode from the requested surface, not the product, and persist it only
Routing:
- **No argument:** read [routing.md](reference/routing.md) and present its context-aware menu; never auto-run a command.
- **Explicit or clearly implied command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Explicit or clearly implied request to run a command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Workflow or command-selection question:** read [Workflow questions](reference/routing.md#workflow-questions).
- **Otherwise:** treat the request as general design work. Missing PRODUCT.md routes a new surface or replacement world through init, then new-work; a narrow refinement of existing code proceeds on the incumbent implementation as `impeccable context` directs, offering init afterward rather than blocking on it.
- `teach` aliases `init`. `craft` is a deprecated alias for ordinary new-work and adds nothing. `shape` owns task discovery, then enters new-work only for visual-world and surface-concept decisions.
@@ -78,7 +78,7 @@ const __impeccableLiveDev =
process.env.NODE_ENV === "development" ? ["http://localhost:8400"] : [];
```
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: `tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts`, `tests/framework-fixtures/sveltekit-csp/expected-after-patch.js`. Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: [nextjs-turborepo/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts), [sveltekit-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/sveltekit-csp/expected-after-patch.js). Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
### append-string
@@ -93,7 +93,7 @@ const __impeccableLiveDev =
- `script-src 'self' 'unsafe-inline'` becomes `` `script-src 'self' 'unsafe-inline'${__impeccableLiveDev}` ``
- `connect-src 'self'` becomes `` `connect-src 'self'${__impeccableLiveDev}` ``
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: `tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js`, `tests/framework-fixtures/nuxt-csp/expected-after-patch.ts`.
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: [nextjs-inline-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js), [nuxt-csp/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nuxt-csp/expected-after-patch.ts).
## Troubleshooting
+1 -1
View File
@@ -196,7 +196,7 @@ Complete HTML replacement of the original element per variant, not a CSS-only pa
Replace the style opening tag with `cssAuthoring.styleTag` when the tool returns a different one. **Each variant div contains exactly one top-level element**, same tag as the original; loose siblings break outline tracking and accept. First variant visible, all others `display: none`. The browser's MutationObserver accepts atomic or progressive arrival; accepting an arrived variant fences the worker, so later publications are rejected.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in `tests/live-e2e/agent.mjs` is a faithful template.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in the [repo agent template](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/live-e2e/agent.mjs) is a faithful template.
**JSX / TSX targets:** wrap `<style>` content in a template literal (CSS braces would parse as JSX), use `className=` / `style={{…}}`, keep `data-impeccable-*` attributes as plain strings:
@@ -1,4 +1,10 @@
# No-argument routing: the context-aware menu
# Command guidance
## Workflow questions
Give advice without executing commands; the menu below is only for bare invocations. Consult relevant command references as needed for prerequisites and scope. Link to the [docs](https://impeccable.style/docs/) for the broader workflow guide. If the user also requests execution, follow that request.
## No-argument routing: the context-aware menu
Read this when the user invokes `/impeccable` with no argument. They are asking "what should I do?" Make the menu context-aware instead of static.
+1 -1
View File
@@ -1 +1 @@
0.1.0
0.1.1
+38 -5
View File
@@ -96,6 +96,19 @@ fetch_url() {
return 1
fi
}
check_download() {
download_file=${1:-$tmp}
if [ ! -f "$download_file" ]; then
rm -f "$tmp.sha256"
echo "impeccable: download completed but the file was removed before execution: $url; check your antivirus quarantine or logs. Refusing to continue; do not disable protection." >&2
exit 127
fi
if [ ! -s "$download_file" ]; then
rm -f "$download_file" "$tmp.sha256"
echo "impeccable: downloaded file is empty: $url; refusing the unverified download" >&2
exit 127
fi
}
if [ -n "$probing" ]; then
# Inside another launcher's probe: no download, fail fast and quiet.
exit 127
@@ -116,6 +129,7 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
fetch_url "$url" && fetched=1
fi
if [ "$fetched" = 1 ]; then
check_download
# Fail closed: a freshly downloaded binary runs only after verifying
# against its .sha256 sidecar. A sidecar that cannot be fetched, or a
# machine with no sha256 tool, refuses the download instead of exec'ing
@@ -127,15 +141,20 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
elif command -v wget >/dev/null 2>&1; then
wget -q -O "$tmp.sha256" "$url.sha256" 2>/dev/null && sidecar_ok=1
fi
check_download
expected=""
[ "$sidecar_ok" = 1 ] && expected=$(cut -d' ' -f1 < "$tmp.sha256")
actual=""
if command -v shasum >/dev/null 2>&1; then actual=$(shasum -a 256 "$tmp" | cut -d' ' -f1)
elif command -v sha256sum >/dev/null 2>&1; then actual=$(sha256sum "$tmp" | cut -d' ' -f1); fi
if command -v shasum >/dev/null 2>&1; then
if digest=$(shasum -a 256 "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
elif command -v sha256sum >/dev/null 2>&1; then
if digest=$(sha256sum "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
fi
check_download
rm -f "$tmp.sha256"
if [ -z "$expected" ] || [ -z "$actual" ]; then
rm -f "$tmp"
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or no sha256 tool); refusing the unverified download" >&2
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or hashing failed); refusing the unverified download" >&2
exit 127
fi
if [ "$actual" != "$expected" ]; then
@@ -143,8 +162,22 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
echo "impeccable: checksum mismatch downloading $url" >&2
exit 127
fi
chmod +x "$tmp" 2>/dev/null
mv -f "$tmp" "$cached" && exec "$cached" "$@"
check_download
if ! chmod +x "$tmp" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not make the verified download executable: $url" >&2
exit 127
fi
check_download
if ! mv -f "$tmp" "$cached" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not cache the verified download: $url" >&2
exit 127
fi
check_download "$cached"
exec "$cached" "$@"
fi
rm -f "$tmp" 2>/dev/null
fi
@@ -82,6 +82,8 @@ curl.exe -fsSL -o "%cached%.part" "%url%" >nul 2>nul
if errorlevel 1 goto fail
:verify
call :check_download
if errorlevel 1 exit /b 127
rem Mirrors the sh launcher and fails closed: a freshly downloaded binary
rem runs only after verifying against its .sha256 sidecar. A sidecar that
rem cannot be fetched, or an empty certutil result, refuses the download
@@ -91,8 +93,16 @@ if errorlevel 1 goto verify_refuse
set "expected="
set /p expected=<"%cached%.sha256"
for /f "tokens=1" %%h in ("%expected%") do set "expected=%%h"
call :check_download
if errorlevel 1 exit /b 127
set "actual="
for /f "skip=1 delims=" %%h in ('certutil -hashfile "%cached%.part" SHA256 2^>nul') do if not defined actual set "actual=%%h"
rem Reuse the sidecar staging file after reading expected. Check certutil's
rem status before parsing: its error text on stdout is not a digest.
certutil -hashfile "%cached%.part" SHA256 >"%cached%.sha256" 2>nul
if errorlevel 1 goto verify_refuse
call :check_download
if errorlevel 1 exit /b 127
for /f "usebackq skip=1 delims=" %%h in ("%cached%.sha256") do if not defined actual set "actual=%%h"
del "%cached%.sha256" >nul 2>nul
if not defined expected goto verify_refuse
if not defined actual goto verify_refuse
@@ -103,17 +113,48 @@ echo impeccable: checksum mismatch downloading %url% 1>&2
exit /b 127
:verify_refuse
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: cannot verify %url% against %url%.sha256; refusing the unverified download 1>&2
exit /b 127
:check_download
set "download_file=%~1"
if not defined download_file set "download_file=%cached%.part"
if not exist "%download_file%" goto download_missing
for %%f in ("%download_file%") do if %%~zf==0 goto download_empty
exit /b 0
:download_missing
del "%cached%.sha256" >nul 2>nul
echo impeccable: download completed but the file was removed before execution: %url%; check your antivirus quarantine or logs. Refusing to continue; do not disable protection. 1>&2
exit /b 127
:download_empty
del "%download_file%" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: downloaded file is empty: %url%; refusing the unverified download 1>&2
exit /b 127
:place
call :check_download
if errorlevel 1 exit /b 127
move /y "%cached%.part" "%cached%" >nul 2>nul
if not exist "%cached%" goto fail
if errorlevel 1 goto place_failed
call :check_download "%cached%"
if errorlevel 1 exit /b 127
set "run=%cached%"
goto run
:place_failed
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
echo impeccable: could not cache the verified download: %url% 1>&2
exit /b 127
:run
"%run%" %*
exit /b
@@ -7834,7 +7834,6 @@
if (editBadgeEl && editBadgeEl.style.display !== 'none') renderEditBadge('idle-disabled');
showBar('generating');
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -7916,7 +7915,6 @@
showBar('generating');
startScrollTracking();
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -8238,7 +8236,8 @@
// rasterization from delaying the fetch itself.
if (!hasAnnotations) {
basePayload.clientSentAt = Date.now();
await sendEvent(basePayload);
const created = await sendEvent(basePayload);
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
let screenshotPath;
@@ -8279,7 +8278,10 @@
// is semantic input. Plain requests were already dispatched above.
if (hasAnnotations) {
basePayload.clientSentAt = Date.now();
sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
const created = await sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
// Capture/upload can take seconds. Progress before this acknowledgment
// refers to an unknown session and would clear our own active work.
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
}
+2 -1
View File
@@ -68,7 +68,8 @@ Choose the mode from the requested surface, not the product, and persist it only
Routing:
- **No argument:** read [routing.md](reference/routing.md) and present its context-aware menu; never auto-run a command.
- **Explicit or clearly implied command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Explicit or clearly implied request to run a command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Workflow or command-selection question:** read [Workflow questions](reference/routing.md#workflow-questions).
- **Otherwise:** treat the request as general design work. Missing PRODUCT.md routes a new surface or replacement world through init, then new-work; a narrow refinement of existing code proceeds on the incumbent implementation as `impeccable context` directs, offering init afterward rather than blocking on it.
- `teach` aliases `init`. `craft` is a deprecated alias for ordinary new-work and adds nothing. `shape` owns task discovery, then enters new-work only for visual-world and surface-concept decisions.
@@ -78,7 +78,7 @@ const __impeccableLiveDev =
process.env.NODE_ENV === "development" ? ["http://localhost:8400"] : [];
```
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: `tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts`, `tests/framework-fixtures/sveltekit-csp/expected-after-patch.js`. Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: [nextjs-turborepo/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts), [sveltekit-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/sveltekit-csp/expected-after-patch.js). Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
### append-string
@@ -93,7 +93,7 @@ const __impeccableLiveDev =
- `script-src 'self' 'unsafe-inline'` becomes `` `script-src 'self' 'unsafe-inline'${__impeccableLiveDev}` ``
- `connect-src 'self'` becomes `` `connect-src 'self'${__impeccableLiveDev}` ``
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: `tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js`, `tests/framework-fixtures/nuxt-csp/expected-after-patch.ts`.
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: [nextjs-inline-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js), [nuxt-csp/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nuxt-csp/expected-after-patch.ts).
## Troubleshooting
+1 -1
View File
@@ -196,7 +196,7 @@ Complete HTML replacement of the original element per variant, not a CSS-only pa
Replace the style opening tag with `cssAuthoring.styleTag` when the tool returns a different one. **Each variant div contains exactly one top-level element**, same tag as the original; loose siblings break outline tracking and accept. First variant visible, all others `display: none`. The browser's MutationObserver accepts atomic or progressive arrival; accepting an arrived variant fences the worker, so later publications are rejected.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in `tests/live-e2e/agent.mjs` is a faithful template.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in the [repo agent template](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/live-e2e/agent.mjs) is a faithful template.
**JSX / TSX targets:** wrap `<style>` content in a template literal (CSS braces would parse as JSX), use `className=` / `style={{…}}`, keep `data-impeccable-*` attributes as plain strings:
@@ -1,4 +1,10 @@
# No-argument routing: the context-aware menu
# Command guidance
## Workflow questions
Give advice without executing commands; the menu below is only for bare invocations. Consult relevant command references as needed for prerequisites and scope. Link to the [docs](https://impeccable.style/docs/) for the broader workflow guide. If the user also requests execution, follow that request.
## No-argument routing: the context-aware menu
Read this when the user invokes `/impeccable` with no argument. They are asking "what should I do?" Make the menu context-aware instead of static.
+1 -1
View File
@@ -1 +1 @@
0.1.0
0.1.1
+38 -5
View File
@@ -96,6 +96,19 @@ fetch_url() {
return 1
fi
}
check_download() {
download_file=${1:-$tmp}
if [ ! -f "$download_file" ]; then
rm -f "$tmp.sha256"
echo "impeccable: download completed but the file was removed before execution: $url; check your antivirus quarantine or logs. Refusing to continue; do not disable protection." >&2
exit 127
fi
if [ ! -s "$download_file" ]; then
rm -f "$download_file" "$tmp.sha256"
echo "impeccable: downloaded file is empty: $url; refusing the unverified download" >&2
exit 127
fi
}
if [ -n "$probing" ]; then
# Inside another launcher's probe: no download, fail fast and quiet.
exit 127
@@ -116,6 +129,7 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
fetch_url "$url" && fetched=1
fi
if [ "$fetched" = 1 ]; then
check_download
# Fail closed: a freshly downloaded binary runs only after verifying
# against its .sha256 sidecar. A sidecar that cannot be fetched, or a
# machine with no sha256 tool, refuses the download instead of exec'ing
@@ -127,15 +141,20 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
elif command -v wget >/dev/null 2>&1; then
wget -q -O "$tmp.sha256" "$url.sha256" 2>/dev/null && sidecar_ok=1
fi
check_download
expected=""
[ "$sidecar_ok" = 1 ] && expected=$(cut -d' ' -f1 < "$tmp.sha256")
actual=""
if command -v shasum >/dev/null 2>&1; then actual=$(shasum -a 256 "$tmp" | cut -d' ' -f1)
elif command -v sha256sum >/dev/null 2>&1; then actual=$(sha256sum "$tmp" | cut -d' ' -f1); fi
if command -v shasum >/dev/null 2>&1; then
if digest=$(shasum -a 256 "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
elif command -v sha256sum >/dev/null 2>&1; then
if digest=$(sha256sum "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
fi
check_download
rm -f "$tmp.sha256"
if [ -z "$expected" ] || [ -z "$actual" ]; then
rm -f "$tmp"
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or no sha256 tool); refusing the unverified download" >&2
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or hashing failed); refusing the unverified download" >&2
exit 127
fi
if [ "$actual" != "$expected" ]; then
@@ -143,8 +162,22 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
echo "impeccable: checksum mismatch downloading $url" >&2
exit 127
fi
chmod +x "$tmp" 2>/dev/null
mv -f "$tmp" "$cached" && exec "$cached" "$@"
check_download
if ! chmod +x "$tmp" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not make the verified download executable: $url" >&2
exit 127
fi
check_download
if ! mv -f "$tmp" "$cached" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not cache the verified download: $url" >&2
exit 127
fi
check_download "$cached"
exec "$cached" "$@"
fi
rm -f "$tmp" 2>/dev/null
fi
@@ -82,6 +82,8 @@ curl.exe -fsSL -o "%cached%.part" "%url%" >nul 2>nul
if errorlevel 1 goto fail
:verify
call :check_download
if errorlevel 1 exit /b 127
rem Mirrors the sh launcher and fails closed: a freshly downloaded binary
rem runs only after verifying against its .sha256 sidecar. A sidecar that
rem cannot be fetched, or an empty certutil result, refuses the download
@@ -91,8 +93,16 @@ if errorlevel 1 goto verify_refuse
set "expected="
set /p expected=<"%cached%.sha256"
for /f "tokens=1" %%h in ("%expected%") do set "expected=%%h"
call :check_download
if errorlevel 1 exit /b 127
set "actual="
for /f "skip=1 delims=" %%h in ('certutil -hashfile "%cached%.part" SHA256 2^>nul') do if not defined actual set "actual=%%h"
rem Reuse the sidecar staging file after reading expected. Check certutil's
rem status before parsing: its error text on stdout is not a digest.
certutil -hashfile "%cached%.part" SHA256 >"%cached%.sha256" 2>nul
if errorlevel 1 goto verify_refuse
call :check_download
if errorlevel 1 exit /b 127
for /f "usebackq skip=1 delims=" %%h in ("%cached%.sha256") do if not defined actual set "actual=%%h"
del "%cached%.sha256" >nul 2>nul
if not defined expected goto verify_refuse
if not defined actual goto verify_refuse
@@ -103,17 +113,48 @@ echo impeccable: checksum mismatch downloading %url% 1>&2
exit /b 127
:verify_refuse
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: cannot verify %url% against %url%.sha256; refusing the unverified download 1>&2
exit /b 127
:check_download
set "download_file=%~1"
if not defined download_file set "download_file=%cached%.part"
if not exist "%download_file%" goto download_missing
for %%f in ("%download_file%") do if %%~zf==0 goto download_empty
exit /b 0
:download_missing
del "%cached%.sha256" >nul 2>nul
echo impeccable: download completed but the file was removed before execution: %url%; check your antivirus quarantine or logs. Refusing to continue; do not disable protection. 1>&2
exit /b 127
:download_empty
del "%download_file%" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: downloaded file is empty: %url%; refusing the unverified download 1>&2
exit /b 127
:place
call :check_download
if errorlevel 1 exit /b 127
move /y "%cached%.part" "%cached%" >nul 2>nul
if not exist "%cached%" goto fail
if errorlevel 1 goto place_failed
call :check_download "%cached%"
if errorlevel 1 exit /b 127
set "run=%cached%"
goto run
:place_failed
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
echo impeccable: could not cache the verified download: %url% 1>&2
exit /b 127
:run
"%run%" %*
exit /b
@@ -7834,7 +7834,6 @@
if (editBadgeEl && editBadgeEl.style.display !== 'none') renderEditBadge('idle-disabled');
showBar('generating');
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -7916,7 +7915,6 @@
showBar('generating');
startScrollTracking();
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -8238,7 +8236,8 @@
// rasterization from delaying the fetch itself.
if (!hasAnnotations) {
basePayload.clientSentAt = Date.now();
await sendEvent(basePayload);
const created = await sendEvent(basePayload);
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
let screenshotPath;
@@ -8279,7 +8278,10 @@
// is semantic input. Plain requests were already dispatched above.
if (hasAnnotations) {
basePayload.clientSentAt = Date.now();
sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
const created = await sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
// Capture/upload can take seconds. Progress before this acknowledgment
// refers to an unknown session and would clear our own active work.
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
}
+14
View File
@@ -188,6 +188,20 @@ jobs:
- run: cargo build --workspace --all-targets
- run: cargo test --workspace --no-fail-fast
launcher-windows:
runs-on: windows-latest
needs: changes
if: needs.changes.outputs.core == 'true'
steps:
- name: Checkout repository
uses: actions/checkout@v7
- name: Setup Node
uses: actions/setup-node@v7
with:
node-version: 24
- name: Exercise Windows launcher downloads and verification
run: node --test tests/launcher-download.test.mjs
# Behavior gate: replays the tests/oracle/ goldens against a release build
# of the engine from THIS checkout (so a PR is judged on its own source,
# not on the last published binary). Without this job the oracle only ever
+70 -4
View File
@@ -11,8 +11,10 @@ name: release-engine
on:
push:
tags: ['engine-v*']
# Same-run artifact transfers use ACTIONS_RUNTIME_TOKEN, not GITHUB_TOKEN;
# they do not require actions: read/write. Keep downloads scoped to this run.
permissions:
contents: write
contents: read
jobs:
build:
strategy:
@@ -53,15 +55,79 @@ jobs:
run: target/${{ matrix.target }}/release/impeccable${{ runner.os == 'Windows' && '.exe' || '' }} engine-probe
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: impeccable-${{ matrix.short }}
# Keep unsigned Windows output outside the publish job's pattern.
name: ${{ matrix.short == 'windows-x64' && 'unsigned-windows-x64' || format('impeccable-{0}', matrix.short) }}
path: target/${{ matrix.target }}/release/impeccable${{ runner.os == 'Windows' && '.exe' || '' }}
if-no-files-found: error
publish:
sign-windows:
needs: build
runs-on: windows-latest
timeout-minutes: 15
environment: windows-signing
permissions:
contents: read
id-token: write
steps:
# A fresh runner signs only this run's engine. It does not check out or
# execute repository code with the Azure identity available.
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with:
name: unsigned-windows-x64
path: unsigned
- name: Azure login (OIDC)
uses: azure/login@7ddb5af1ef8758cf1353cf3b42f940aee27ba21c # v3
with:
client-id: ${{ vars.AZURE_CLIENT_ID }}
tenant-id: ${{ vars.AZURE_TENANT_ID }}
subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
- name: Sign Windows engine
uses: azure/artifact-signing-action@c7ab2a863ab5f9a846ddb8265964877ef296ee82 # v2
with:
endpoint: https://eus.codesigning.azure.net/
signing-account-name: impeccable-signing
certificate-profile-name: impeccable-windows
files: ${{ github.workspace }}\unsigned\impeccable.exe
file-digest: SHA256
timestamp-rfc3161: http://timestamp.acs.microsoft.com
timestamp-digest: SHA256
description: Impeccable engine
description-url: https://impeccable.style
exclude-environment-credential: true
# Only the preceding OIDC Azure CLI login is used. Other credential
# types are excluded by this pinned action's defaults.
exclude-azure-cli-credential: false
cache-dependencies: false
- name: Verify signed engine
shell: pwsh
run: |
$ErrorActionPreference = 'Stop'
$signature = Get-AuthenticodeSignature -LiteralPath 'unsigned/impeccable.exe'
if ($signature.Status -ne 'Valid') {
throw "Invalid Windows signature: $($signature.Status) — $($signature.StatusMessage)"
}
$publisher = $signature.SignerCertificate.GetNameInfo([System.Security.Cryptography.X509Certificates.X509NameType]::SimpleName, $false)
if ($publisher -cne 'Renaissance Geek, Inc.') {
throw "Unexpected Windows publisher: $publisher"
}
if ($null -eq $signature.TimeStamperCertificate) {
throw 'The Windows signature has no timestamp.'
}
Write-Output "Verified publisher: $publisher; certificate: $($signature.SignerCertificate.Thumbprint)"
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: impeccable-windows-x64
path: unsigned/impeccable.exe
if-no-files-found: error
publish:
needs: [build, sign-windows]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
with: { path: artifacts }
with:
pattern: impeccable-*
path: artifacts
- name: Lay out release assets with checksums
run: |
set -e
+2 -1
View File
@@ -71,7 +71,8 @@ Choose the mode from the requested surface, not the product, and persist it only
Routing:
- **No argument:** read [routing.md](reference/routing.md) and present its context-aware menu; never auto-run a command.
- **Explicit or clearly implied command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Explicit or clearly implied request to run a command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Workflow or command-selection question:** read [Workflow questions](reference/routing.md#workflow-questions).
- **Otherwise:** treat the request as general design work. Missing PRODUCT.md routes a new surface or replacement world through init, then new-work; a narrow refinement of existing code proceeds on the incumbent implementation as `impeccable context` directs, offering init afterward rather than blocking on it.
- `teach` aliases `init`. `craft` is a deprecated alias for ordinary new-work and adds nothing. `shape` owns task discovery, then enters new-work only for visual-world and surface-concept decisions.
@@ -78,7 +78,7 @@ const __impeccableLiveDev =
process.env.NODE_ENV === "development" ? ["http://localhost:8400"] : [];
```
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: `tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts`, `tests/framework-fixtures/sveltekit-csp/expected-after-patch.js`. Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: [nextjs-turborepo/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts), [sveltekit-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/sveltekit-csp/expected-after-patch.js). Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
### append-string
@@ -93,7 +93,7 @@ const __impeccableLiveDev =
- `script-src 'self' 'unsafe-inline'` becomes `` `script-src 'self' 'unsafe-inline'${__impeccableLiveDev}` ``
- `connect-src 'self'` becomes `` `connect-src 'self'${__impeccableLiveDev}` ``
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: `tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js`, `tests/framework-fixtures/nuxt-csp/expected-after-patch.ts`.
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: [nextjs-inline-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js), [nuxt-csp/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nuxt-csp/expected-after-patch.ts).
## Troubleshooting
+1 -1
View File
@@ -196,7 +196,7 @@ Complete HTML replacement of the original element per variant, not a CSS-only pa
Replace the style opening tag with `cssAuthoring.styleTag` when the tool returns a different one. **Each variant div contains exactly one top-level element**, same tag as the original; loose siblings break outline tracking and accept. First variant visible, all others `display: none`. The browser's MutationObserver accepts atomic or progressive arrival; accepting an arrived variant fences the worker, so later publications are rejected.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in `tests/live-e2e/agent.mjs` is a faithful template.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in the [repo agent template](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/live-e2e/agent.mjs) is a faithful template.
**JSX / TSX targets:** wrap `<style>` content in a template literal (CSS braces would parse as JSX), use `className=` / `style={{…}}`, keep `data-impeccable-*` attributes as plain strings:
+7 -1
View File
@@ -1,4 +1,10 @@
# No-argument routing: the context-aware menu
# Command guidance
## Workflow questions
Give advice without executing commands; the menu below is only for bare invocations. Consult relevant command references as needed for prerequisites and scope. Link to the [docs](https://impeccable.style/docs/) for the broader workflow guide. If the user also requests execution, follow that request.
## No-argument routing: the context-aware menu
Read this when the user invokes `/impeccable` with no argument. They are asking "what should I do?" Make the menu context-aware instead of static.
+1 -1
View File
@@ -1 +1 @@
0.1.0
0.1.1
+38 -5
View File
@@ -96,6 +96,19 @@ fetch_url() {
return 1
fi
}
check_download() {
download_file=${1:-$tmp}
if [ ! -f "$download_file" ]; then
rm -f "$tmp.sha256"
echo "impeccable: download completed but the file was removed before execution: $url; check your antivirus quarantine or logs. Refusing to continue; do not disable protection." >&2
exit 127
fi
if [ ! -s "$download_file" ]; then
rm -f "$download_file" "$tmp.sha256"
echo "impeccable: downloaded file is empty: $url; refusing the unverified download" >&2
exit 127
fi
}
if [ -n "$probing" ]; then
# Inside another launcher's probe: no download, fail fast and quiet.
exit 127
@@ -116,6 +129,7 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
fetch_url "$url" && fetched=1
fi
if [ "$fetched" = 1 ]; then
check_download
# Fail closed: a freshly downloaded binary runs only after verifying
# against its .sha256 sidecar. A sidecar that cannot be fetched, or a
# machine with no sha256 tool, refuses the download instead of exec'ing
@@ -127,15 +141,20 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
elif command -v wget >/dev/null 2>&1; then
wget -q -O "$tmp.sha256" "$url.sha256" 2>/dev/null && sidecar_ok=1
fi
check_download
expected=""
[ "$sidecar_ok" = 1 ] && expected=$(cut -d' ' -f1 < "$tmp.sha256")
actual=""
if command -v shasum >/dev/null 2>&1; then actual=$(shasum -a 256 "$tmp" | cut -d' ' -f1)
elif command -v sha256sum >/dev/null 2>&1; then actual=$(sha256sum "$tmp" | cut -d' ' -f1); fi
if command -v shasum >/dev/null 2>&1; then
if digest=$(shasum -a 256 "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
elif command -v sha256sum >/dev/null 2>&1; then
if digest=$(sha256sum "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
fi
check_download
rm -f "$tmp.sha256"
if [ -z "$expected" ] || [ -z "$actual" ]; then
rm -f "$tmp"
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or no sha256 tool); refusing the unverified download" >&2
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or hashing failed); refusing the unverified download" >&2
exit 127
fi
if [ "$actual" != "$expected" ]; then
@@ -143,8 +162,22 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
echo "impeccable: checksum mismatch downloading $url" >&2
exit 127
fi
chmod +x "$tmp" 2>/dev/null
mv -f "$tmp" "$cached" && exec "$cached" "$@"
check_download
if ! chmod +x "$tmp" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not make the verified download executable: $url" >&2
exit 127
fi
check_download
if ! mv -f "$tmp" "$cached" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not cache the verified download: $url" >&2
exit 127
fi
check_download "$cached"
exec "$cached" "$@"
fi
rm -f "$tmp" 2>/dev/null
fi
+43 -2
View File
@@ -82,6 +82,8 @@ curl.exe -fsSL -o "%cached%.part" "%url%" >nul 2>nul
if errorlevel 1 goto fail
:verify
call :check_download
if errorlevel 1 exit /b 127
rem Mirrors the sh launcher and fails closed: a freshly downloaded binary
rem runs only after verifying against its .sha256 sidecar. A sidecar that
rem cannot be fetched, or an empty certutil result, refuses the download
@@ -91,8 +93,16 @@ if errorlevel 1 goto verify_refuse
set "expected="
set /p expected=<"%cached%.sha256"
for /f "tokens=1" %%h in ("%expected%") do set "expected=%%h"
call :check_download
if errorlevel 1 exit /b 127
set "actual="
for /f "skip=1 delims=" %%h in ('certutil -hashfile "%cached%.part" SHA256 2^>nul') do if not defined actual set "actual=%%h"
rem Reuse the sidecar staging file after reading expected. Check certutil's
rem status before parsing: its error text on stdout is not a digest.
certutil -hashfile "%cached%.part" SHA256 >"%cached%.sha256" 2>nul
if errorlevel 1 goto verify_refuse
call :check_download
if errorlevel 1 exit /b 127
for /f "usebackq skip=1 delims=" %%h in ("%cached%.sha256") do if not defined actual set "actual=%%h"
del "%cached%.sha256" >nul 2>nul
if not defined expected goto verify_refuse
if not defined actual goto verify_refuse
@@ -103,17 +113,48 @@ echo impeccable: checksum mismatch downloading %url% 1>&2
exit /b 127
:verify_refuse
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: cannot verify %url% against %url%.sha256; refusing the unverified download 1>&2
exit /b 127
:check_download
set "download_file=%~1"
if not defined download_file set "download_file=%cached%.part"
if not exist "%download_file%" goto download_missing
for %%f in ("%download_file%") do if %%~zf==0 goto download_empty
exit /b 0
:download_missing
del "%cached%.sha256" >nul 2>nul
echo impeccable: download completed but the file was removed before execution: %url%; check your antivirus quarantine or logs. Refusing to continue; do not disable protection. 1>&2
exit /b 127
:download_empty
del "%download_file%" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: downloaded file is empty: %url%; refusing the unverified download 1>&2
exit /b 127
:place
call :check_download
if errorlevel 1 exit /b 127
move /y "%cached%.part" "%cached%" >nul 2>nul
if not exist "%cached%" goto fail
if errorlevel 1 goto place_failed
call :check_download "%cached%"
if errorlevel 1 exit /b 127
set "run=%cached%"
goto run
:place_failed
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
echo impeccable: could not cache the verified download: %url% 1>&2
exit /b 127
:run
"%run%" %*
exit /b
@@ -7834,7 +7834,6 @@
if (editBadgeEl && editBadgeEl.style.display !== 'none') renderEditBadge('idle-disabled');
showBar('generating');
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -7916,7 +7915,6 @@
showBar('generating');
startScrollTracking();
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -8238,7 +8236,8 @@
// rasterization from delaying the fetch itself.
if (!hasAnnotations) {
basePayload.clientSentAt = Date.now();
await sendEvent(basePayload);
const created = await sendEvent(basePayload);
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
let screenshotPath;
@@ -8279,7 +8278,10 @@
// is semantic input. Plain requests were already dispatched above.
if (hasAnnotations) {
basePayload.clientSentAt = Date.now();
sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
const created = await sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
// Capture/upload can take seconds. Progress before this acknowledgment
// refers to an unknown session and would clear our own active work.
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
}
+2 -1
View File
@@ -66,7 +66,8 @@ Choose the mode from the requested surface, not the product, and persist it only
Routing:
- **No argument:** read [routing.md](reference/routing.md) and present its context-aware menu; never auto-run a command.
- **Explicit or clearly implied command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Explicit or clearly implied request to run a command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Workflow or command-selection question:** read [Workflow questions](reference/routing.md#workflow-questions).
- **Otherwise:** treat the request as general design work. Missing PRODUCT.md routes a new surface or replacement world through init, then new-work; a narrow refinement of existing code proceeds on the incumbent implementation as `impeccable context` directs, offering init afterward rather than blocking on it.
- `teach` aliases `init`. `craft` is a deprecated alias for ordinary new-work and adds nothing. `shape` owns task discovery, then enters new-work only for visual-world and surface-concept decisions.
@@ -78,7 +78,7 @@ const __impeccableLiveDev =
process.env.NODE_ENV === "development" ? ["http://localhost:8400"] : [];
```
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: `tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts`, `tests/framework-fixtures/sveltekit-csp/expected-after-patch.js`. Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: [nextjs-turborepo/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts), [sveltekit-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/sveltekit-csp/expected-after-patch.js). Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
### append-string
@@ -93,7 +93,7 @@ const __impeccableLiveDev =
- `script-src 'self' 'unsafe-inline'` becomes `` `script-src 'self' 'unsafe-inline'${__impeccableLiveDev}` ``
- `connect-src 'self'` becomes `` `connect-src 'self'${__impeccableLiveDev}` ``
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: `tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js`, `tests/framework-fixtures/nuxt-csp/expected-after-patch.ts`.
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: [nextjs-inline-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js), [nuxt-csp/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nuxt-csp/expected-after-patch.ts).
## Troubleshooting
+1 -1
View File
@@ -196,7 +196,7 @@ Complete HTML replacement of the original element per variant, not a CSS-only pa
Replace the style opening tag with `cssAuthoring.styleTag` when the tool returns a different one. **Each variant div contains exactly one top-level element**, same tag as the original; loose siblings break outline tracking and accept. First variant visible, all others `display: none`. The browser's MutationObserver accepts atomic or progressive arrival; accepting an arrived variant fences the worker, so later publications are rejected.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in `tests/live-e2e/agent.mjs` is a faithful template.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in the [repo agent template](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/live-e2e/agent.mjs) is a faithful template.
**JSX / TSX targets:** wrap `<style>` content in a template literal (CSS braces would parse as JSX), use `className=` / `style={{…}}`, keep `data-impeccable-*` attributes as plain strings:
@@ -1,4 +1,10 @@
# No-argument routing: the context-aware menu
# Command guidance
## Workflow questions
Give advice without executing commands; the menu below is only for bare invocations. Consult relevant command references as needed for prerequisites and scope. Link to the [docs](https://impeccable.style/docs/) for the broader workflow guide. If the user also requests execution, follow that request.
## No-argument routing: the context-aware menu
Read this when the user invokes `/impeccable` with no argument. They are asking "what should I do?" Make the menu context-aware instead of static.
+1 -1
View File
@@ -1 +1 @@
0.1.0
0.1.1
+38 -5
View File
@@ -96,6 +96,19 @@ fetch_url() {
return 1
fi
}
check_download() {
download_file=${1:-$tmp}
if [ ! -f "$download_file" ]; then
rm -f "$tmp.sha256"
echo "impeccable: download completed but the file was removed before execution: $url; check your antivirus quarantine or logs. Refusing to continue; do not disable protection." >&2
exit 127
fi
if [ ! -s "$download_file" ]; then
rm -f "$download_file" "$tmp.sha256"
echo "impeccable: downloaded file is empty: $url; refusing the unverified download" >&2
exit 127
fi
}
if [ -n "$probing" ]; then
# Inside another launcher's probe: no download, fail fast and quiet.
exit 127
@@ -116,6 +129,7 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
fetch_url "$url" && fetched=1
fi
if [ "$fetched" = 1 ]; then
check_download
# Fail closed: a freshly downloaded binary runs only after verifying
# against its .sha256 sidecar. A sidecar that cannot be fetched, or a
# machine with no sha256 tool, refuses the download instead of exec'ing
@@ -127,15 +141,20 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
elif command -v wget >/dev/null 2>&1; then
wget -q -O "$tmp.sha256" "$url.sha256" 2>/dev/null && sidecar_ok=1
fi
check_download
expected=""
[ "$sidecar_ok" = 1 ] && expected=$(cut -d' ' -f1 < "$tmp.sha256")
actual=""
if command -v shasum >/dev/null 2>&1; then actual=$(shasum -a 256 "$tmp" | cut -d' ' -f1)
elif command -v sha256sum >/dev/null 2>&1; then actual=$(sha256sum "$tmp" | cut -d' ' -f1); fi
if command -v shasum >/dev/null 2>&1; then
if digest=$(shasum -a 256 "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
elif command -v sha256sum >/dev/null 2>&1; then
if digest=$(sha256sum "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
fi
check_download
rm -f "$tmp.sha256"
if [ -z "$expected" ] || [ -z "$actual" ]; then
rm -f "$tmp"
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or no sha256 tool); refusing the unverified download" >&2
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or hashing failed); refusing the unverified download" >&2
exit 127
fi
if [ "$actual" != "$expected" ]; then
@@ -143,8 +162,22 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
echo "impeccable: checksum mismatch downloading $url" >&2
exit 127
fi
chmod +x "$tmp" 2>/dev/null
mv -f "$tmp" "$cached" && exec "$cached" "$@"
check_download
if ! chmod +x "$tmp" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not make the verified download executable: $url" >&2
exit 127
fi
check_download
if ! mv -f "$tmp" "$cached" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not cache the verified download: $url" >&2
exit 127
fi
check_download "$cached"
exec "$cached" "$@"
fi
rm -f "$tmp" 2>/dev/null
fi
@@ -82,6 +82,8 @@ curl.exe -fsSL -o "%cached%.part" "%url%" >nul 2>nul
if errorlevel 1 goto fail
:verify
call :check_download
if errorlevel 1 exit /b 127
rem Mirrors the sh launcher and fails closed: a freshly downloaded binary
rem runs only after verifying against its .sha256 sidecar. A sidecar that
rem cannot be fetched, or an empty certutil result, refuses the download
@@ -91,8 +93,16 @@ if errorlevel 1 goto verify_refuse
set "expected="
set /p expected=<"%cached%.sha256"
for /f "tokens=1" %%h in ("%expected%") do set "expected=%%h"
call :check_download
if errorlevel 1 exit /b 127
set "actual="
for /f "skip=1 delims=" %%h in ('certutil -hashfile "%cached%.part" SHA256 2^>nul') do if not defined actual set "actual=%%h"
rem Reuse the sidecar staging file after reading expected. Check certutil's
rem status before parsing: its error text on stdout is not a digest.
certutil -hashfile "%cached%.part" SHA256 >"%cached%.sha256" 2>nul
if errorlevel 1 goto verify_refuse
call :check_download
if errorlevel 1 exit /b 127
for /f "usebackq skip=1 delims=" %%h in ("%cached%.sha256") do if not defined actual set "actual=%%h"
del "%cached%.sha256" >nul 2>nul
if not defined expected goto verify_refuse
if not defined actual goto verify_refuse
@@ -103,17 +113,48 @@ echo impeccable: checksum mismatch downloading %url% 1>&2
exit /b 127
:verify_refuse
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: cannot verify %url% against %url%.sha256; refusing the unverified download 1>&2
exit /b 127
:check_download
set "download_file=%~1"
if not defined download_file set "download_file=%cached%.part"
if not exist "%download_file%" goto download_missing
for %%f in ("%download_file%") do if %%~zf==0 goto download_empty
exit /b 0
:download_missing
del "%cached%.sha256" >nul 2>nul
echo impeccable: download completed but the file was removed before execution: %url%; check your antivirus quarantine or logs. Refusing to continue; do not disable protection. 1>&2
exit /b 127
:download_empty
del "%download_file%" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: downloaded file is empty: %url%; refusing the unverified download 1>&2
exit /b 127
:place
call :check_download
if errorlevel 1 exit /b 127
move /y "%cached%.part" "%cached%" >nul 2>nul
if not exist "%cached%" goto fail
if errorlevel 1 goto place_failed
call :check_download "%cached%"
if errorlevel 1 exit /b 127
set "run=%cached%"
goto run
:place_failed
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
echo impeccable: could not cache the verified download: %url% 1>&2
exit /b 127
:run
"%run%" %*
exit /b
@@ -7834,7 +7834,6 @@
if (editBadgeEl && editBadgeEl.style.display !== 'none') renderEditBadge('idle-disabled');
showBar('generating');
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -7916,7 +7915,6 @@
showBar('generating');
startScrollTracking();
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -8238,7 +8236,8 @@
// rasterization from delaying the fetch itself.
if (!hasAnnotations) {
basePayload.clientSentAt = Date.now();
await sendEvent(basePayload);
const created = await sendEvent(basePayload);
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
let screenshotPath;
@@ -8279,7 +8278,10 @@
// is semantic input. Plain requests were already dispatched above.
if (hasAnnotations) {
basePayload.clientSentAt = Date.now();
sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
const created = await sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
// Capture/upload can take seconds. Progress before this acknowledgment
// refers to an unknown session and would clear our own active work.
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
}
+2 -1
View File
@@ -66,7 +66,8 @@ Choose the mode from the requested surface, not the product, and persist it only
Routing:
- **No argument:** read [routing.md](reference/routing.md) and present its context-aware menu; never auto-run a command.
- **Explicit or clearly implied command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Explicit or clearly implied request to run a command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Workflow or command-selection question:** read [Workflow questions](reference/routing.md#workflow-questions).
- **Otherwise:** treat the request as general design work. Missing PRODUCT.md routes a new surface or replacement world through init, then new-work; a narrow refinement of existing code proceeds on the incumbent implementation as `impeccable context` directs, offering init afterward rather than blocking on it.
- `teach` aliases `init`. `craft` is a deprecated alias for ordinary new-work and adds nothing. `shape` owns task discovery, then enters new-work only for visual-world and surface-concept decisions.
@@ -78,7 +78,7 @@ const __impeccableLiveDev =
process.env.NODE_ENV === "development" ? ["http://localhost:8400"] : [];
```
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: `tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts`, `tests/framework-fixtures/sveltekit-csp/expected-after-patch.js`. Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: [nextjs-turborepo/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts), [sveltekit-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/sveltekit-csp/expected-after-patch.js). Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
### append-string
@@ -93,7 +93,7 @@ const __impeccableLiveDev =
- `script-src 'self' 'unsafe-inline'` becomes `` `script-src 'self' 'unsafe-inline'${__impeccableLiveDev}` ``
- `connect-src 'self'` becomes `` `connect-src 'self'${__impeccableLiveDev}` ``
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: `tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js`, `tests/framework-fixtures/nuxt-csp/expected-after-patch.ts`.
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: [nextjs-inline-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js), [nuxt-csp/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nuxt-csp/expected-after-patch.ts).
## Troubleshooting
+1 -1
View File
@@ -196,7 +196,7 @@ Complete HTML replacement of the original element per variant, not a CSS-only pa
Replace the style opening tag with `cssAuthoring.styleTag` when the tool returns a different one. **Each variant div contains exactly one top-level element**, same tag as the original; loose siblings break outline tracking and accept. First variant visible, all others `display: none`. The browser's MutationObserver accepts atomic or progressive arrival; accepting an arrived variant fences the worker, so later publications are rejected.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in `tests/live-e2e/agent.mjs` is a faithful template.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in the [repo agent template](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/live-e2e/agent.mjs) is a faithful template.
**JSX / TSX targets:** wrap `<style>` content in a template literal (CSS braces would parse as JSX), use `className=` / `style={{…}}`, keep `data-impeccable-*` attributes as plain strings:
+7 -1
View File
@@ -1,4 +1,10 @@
# No-argument routing: the context-aware menu
# Command guidance
## Workflow questions
Give advice without executing commands; the menu below is only for bare invocations. Consult relevant command references as needed for prerequisites and scope. Link to the [docs](https://impeccable.style/docs/) for the broader workflow guide. If the user also requests execution, follow that request.
## No-argument routing: the context-aware menu
Read this when the user invokes `/impeccable` with no argument. They are asking "what should I do?" Make the menu context-aware instead of static.
+1 -1
View File
@@ -1 +1 @@
0.1.0
0.1.1
+38 -5
View File
@@ -96,6 +96,19 @@ fetch_url() {
return 1
fi
}
check_download() {
download_file=${1:-$tmp}
if [ ! -f "$download_file" ]; then
rm -f "$tmp.sha256"
echo "impeccable: download completed but the file was removed before execution: $url; check your antivirus quarantine or logs. Refusing to continue; do not disable protection." >&2
exit 127
fi
if [ ! -s "$download_file" ]; then
rm -f "$download_file" "$tmp.sha256"
echo "impeccable: downloaded file is empty: $url; refusing the unverified download" >&2
exit 127
fi
}
if [ -n "$probing" ]; then
# Inside another launcher's probe: no download, fail fast and quiet.
exit 127
@@ -116,6 +129,7 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
fetch_url "$url" && fetched=1
fi
if [ "$fetched" = 1 ]; then
check_download
# Fail closed: a freshly downloaded binary runs only after verifying
# against its .sha256 sidecar. A sidecar that cannot be fetched, or a
# machine with no sha256 tool, refuses the download instead of exec'ing
@@ -127,15 +141,20 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
elif command -v wget >/dev/null 2>&1; then
wget -q -O "$tmp.sha256" "$url.sha256" 2>/dev/null && sidecar_ok=1
fi
check_download
expected=""
[ "$sidecar_ok" = 1 ] && expected=$(cut -d' ' -f1 < "$tmp.sha256")
actual=""
if command -v shasum >/dev/null 2>&1; then actual=$(shasum -a 256 "$tmp" | cut -d' ' -f1)
elif command -v sha256sum >/dev/null 2>&1; then actual=$(sha256sum "$tmp" | cut -d' ' -f1); fi
if command -v shasum >/dev/null 2>&1; then
if digest=$(shasum -a 256 "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
elif command -v sha256sum >/dev/null 2>&1; then
if digest=$(sha256sum "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
fi
check_download
rm -f "$tmp.sha256"
if [ -z "$expected" ] || [ -z "$actual" ]; then
rm -f "$tmp"
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or no sha256 tool); refusing the unverified download" >&2
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or hashing failed); refusing the unverified download" >&2
exit 127
fi
if [ "$actual" != "$expected" ]; then
@@ -143,8 +162,22 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
echo "impeccable: checksum mismatch downloading $url" >&2
exit 127
fi
chmod +x "$tmp" 2>/dev/null
mv -f "$tmp" "$cached" && exec "$cached" "$@"
check_download
if ! chmod +x "$tmp" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not make the verified download executable: $url" >&2
exit 127
fi
check_download
if ! mv -f "$tmp" "$cached" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not cache the verified download: $url" >&2
exit 127
fi
check_download "$cached"
exec "$cached" "$@"
fi
rm -f "$tmp" 2>/dev/null
fi
+43 -2
View File
@@ -82,6 +82,8 @@ curl.exe -fsSL -o "%cached%.part" "%url%" >nul 2>nul
if errorlevel 1 goto fail
:verify
call :check_download
if errorlevel 1 exit /b 127
rem Mirrors the sh launcher and fails closed: a freshly downloaded binary
rem runs only after verifying against its .sha256 sidecar. A sidecar that
rem cannot be fetched, or an empty certutil result, refuses the download
@@ -91,8 +93,16 @@ if errorlevel 1 goto verify_refuse
set "expected="
set /p expected=<"%cached%.sha256"
for /f "tokens=1" %%h in ("%expected%") do set "expected=%%h"
call :check_download
if errorlevel 1 exit /b 127
set "actual="
for /f "skip=1 delims=" %%h in ('certutil -hashfile "%cached%.part" SHA256 2^>nul') do if not defined actual set "actual=%%h"
rem Reuse the sidecar staging file after reading expected. Check certutil's
rem status before parsing: its error text on stdout is not a digest.
certutil -hashfile "%cached%.part" SHA256 >"%cached%.sha256" 2>nul
if errorlevel 1 goto verify_refuse
call :check_download
if errorlevel 1 exit /b 127
for /f "usebackq skip=1 delims=" %%h in ("%cached%.sha256") do if not defined actual set "actual=%%h"
del "%cached%.sha256" >nul 2>nul
if not defined expected goto verify_refuse
if not defined actual goto verify_refuse
@@ -103,17 +113,48 @@ echo impeccable: checksum mismatch downloading %url% 1>&2
exit /b 127
:verify_refuse
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: cannot verify %url% against %url%.sha256; refusing the unverified download 1>&2
exit /b 127
:check_download
set "download_file=%~1"
if not defined download_file set "download_file=%cached%.part"
if not exist "%download_file%" goto download_missing
for %%f in ("%download_file%") do if %%~zf==0 goto download_empty
exit /b 0
:download_missing
del "%cached%.sha256" >nul 2>nul
echo impeccable: download completed but the file was removed before execution: %url%; check your antivirus quarantine or logs. Refusing to continue; do not disable protection. 1>&2
exit /b 127
:download_empty
del "%download_file%" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: downloaded file is empty: %url%; refusing the unverified download 1>&2
exit /b 127
:place
call :check_download
if errorlevel 1 exit /b 127
move /y "%cached%.part" "%cached%" >nul 2>nul
if not exist "%cached%" goto fail
if errorlevel 1 goto place_failed
call :check_download "%cached%"
if errorlevel 1 exit /b 127
set "run=%cached%"
goto run
:place_failed
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
echo impeccable: could not cache the verified download: %url% 1>&2
exit /b 127
:run
"%run%" %*
exit /b
@@ -7834,7 +7834,6 @@
if (editBadgeEl && editBadgeEl.style.display !== 'none') renderEditBadge('idle-disabled');
showBar('generating');
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -7916,7 +7915,6 @@
showBar('generating');
startScrollTracking();
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -8238,7 +8236,8 @@
// rasterization from delaying the fetch itself.
if (!hasAnnotations) {
basePayload.clientSentAt = Date.now();
await sendEvent(basePayload);
const created = await sendEvent(basePayload);
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
let screenshotPath;
@@ -8279,7 +8278,10 @@
// is semantic input. Plain requests were already dispatched above.
if (hasAnnotations) {
basePayload.clientSentAt = Date.now();
sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
const created = await sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
// Capture/upload can take seconds. Progress before this acknowledgment
// refers to an unknown session and would clear our own active work.
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
}
+2 -1
View File
@@ -71,7 +71,8 @@ Choose the mode from the requested surface, not the product, and persist it only
Routing:
- **No argument:** read [routing.md](reference/routing.md) and present its context-aware menu; never auto-run a command.
- **Explicit or clearly implied command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Explicit or clearly implied request to run a command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Workflow or command-selection question:** read [Workflow questions](reference/routing.md#workflow-questions).
- **Otherwise:** treat the request as general design work. Missing PRODUCT.md routes a new surface or replacement world through init, then new-work; a narrow refinement of existing code proceeds on the incumbent implementation as `impeccable context` directs, offering init afterward rather than blocking on it.
- `teach` aliases `init`. `craft` is a deprecated alias for ordinary new-work and adds nothing. `shape` owns task discovery, then enters new-work only for visual-world and surface-concept decisions.
@@ -78,7 +78,7 @@ const __impeccableLiveDev =
process.env.NODE_ENV === "development" ? ["http://localhost:8400"] : [];
```
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: `tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts`, `tests/framework-fixtures/sveltekit-csp/expected-after-patch.js`. Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: [nextjs-turborepo/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts), [sveltekit-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/sveltekit-csp/expected-after-patch.js). Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
### append-string
@@ -93,7 +93,7 @@ const __impeccableLiveDev =
- `script-src 'self' 'unsafe-inline'` becomes `` `script-src 'self' 'unsafe-inline'${__impeccableLiveDev}` ``
- `connect-src 'self'` becomes `` `connect-src 'self'${__impeccableLiveDev}` ``
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: `tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js`, `tests/framework-fixtures/nuxt-csp/expected-after-patch.ts`.
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: [nextjs-inline-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js), [nuxt-csp/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nuxt-csp/expected-after-patch.ts).
## Troubleshooting
@@ -196,7 +196,7 @@ Complete HTML replacement of the original element per variant, not a CSS-only pa
Replace the style opening tag with `cssAuthoring.styleTag` when the tool returns a different one. **Each variant div contains exactly one top-level element**, same tag as the original; loose siblings break outline tracking and accept. First variant visible, all others `display: none`. The browser's MutationObserver accepts atomic or progressive arrival; accepting an arrived variant fences the worker, so later publications are rejected.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in `tests/live-e2e/agent.mjs` is a faithful template.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in the [repo agent template](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/live-e2e/agent.mjs) is a faithful template.
**JSX / TSX targets:** wrap `<style>` content in a template literal (CSS braces would parse as JSX), use `className=` / `style={{…}}`, keep `data-impeccable-*` attributes as plain strings:
@@ -1,4 +1,10 @@
# No-argument routing: the context-aware menu
# Command guidance
## Workflow questions
Give advice without executing commands; the menu below is only for bare invocations. Consult relevant command references as needed for prerequisites and scope. Link to the [docs](https://impeccable.style/docs/) for the broader workflow guide. If the user also requests execution, follow that request.
## No-argument routing: the context-aware menu
Read this when the user invokes `/impeccable` with no argument. They are asking "what should I do?" Make the menu context-aware instead of static.
+1 -1
View File
@@ -1 +1 @@
0.1.0
0.1.1
+38 -5
View File
@@ -96,6 +96,19 @@ fetch_url() {
return 1
fi
}
check_download() {
download_file=${1:-$tmp}
if [ ! -f "$download_file" ]; then
rm -f "$tmp.sha256"
echo "impeccable: download completed but the file was removed before execution: $url; check your antivirus quarantine or logs. Refusing to continue; do not disable protection." >&2
exit 127
fi
if [ ! -s "$download_file" ]; then
rm -f "$download_file" "$tmp.sha256"
echo "impeccable: downloaded file is empty: $url; refusing the unverified download" >&2
exit 127
fi
}
if [ -n "$probing" ]; then
# Inside another launcher's probe: no download, fail fast and quiet.
exit 127
@@ -116,6 +129,7 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
fetch_url "$url" && fetched=1
fi
if [ "$fetched" = 1 ]; then
check_download
# Fail closed: a freshly downloaded binary runs only after verifying
# against its .sha256 sidecar. A sidecar that cannot be fetched, or a
# machine with no sha256 tool, refuses the download instead of exec'ing
@@ -127,15 +141,20 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
elif command -v wget >/dev/null 2>&1; then
wget -q -O "$tmp.sha256" "$url.sha256" 2>/dev/null && sidecar_ok=1
fi
check_download
expected=""
[ "$sidecar_ok" = 1 ] && expected=$(cut -d' ' -f1 < "$tmp.sha256")
actual=""
if command -v shasum >/dev/null 2>&1; then actual=$(shasum -a 256 "$tmp" | cut -d' ' -f1)
elif command -v sha256sum >/dev/null 2>&1; then actual=$(sha256sum "$tmp" | cut -d' ' -f1); fi
if command -v shasum >/dev/null 2>&1; then
if digest=$(shasum -a 256 "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
elif command -v sha256sum >/dev/null 2>&1; then
if digest=$(sha256sum "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
fi
check_download
rm -f "$tmp.sha256"
if [ -z "$expected" ] || [ -z "$actual" ]; then
rm -f "$tmp"
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or no sha256 tool); refusing the unverified download" >&2
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or hashing failed); refusing the unverified download" >&2
exit 127
fi
if [ "$actual" != "$expected" ]; then
@@ -143,8 +162,22 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
echo "impeccable: checksum mismatch downloading $url" >&2
exit 127
fi
chmod +x "$tmp" 2>/dev/null
mv -f "$tmp" "$cached" && exec "$cached" "$@"
check_download
if ! chmod +x "$tmp" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not make the verified download executable: $url" >&2
exit 127
fi
check_download
if ! mv -f "$tmp" "$cached" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not cache the verified download: $url" >&2
exit 127
fi
check_download "$cached"
exec "$cached" "$@"
fi
rm -f "$tmp" 2>/dev/null
fi
@@ -82,6 +82,8 @@ curl.exe -fsSL -o "%cached%.part" "%url%" >nul 2>nul
if errorlevel 1 goto fail
:verify
call :check_download
if errorlevel 1 exit /b 127
rem Mirrors the sh launcher and fails closed: a freshly downloaded binary
rem runs only after verifying against its .sha256 sidecar. A sidecar that
rem cannot be fetched, or an empty certutil result, refuses the download
@@ -91,8 +93,16 @@ if errorlevel 1 goto verify_refuse
set "expected="
set /p expected=<"%cached%.sha256"
for /f "tokens=1" %%h in ("%expected%") do set "expected=%%h"
call :check_download
if errorlevel 1 exit /b 127
set "actual="
for /f "skip=1 delims=" %%h in ('certutil -hashfile "%cached%.part" SHA256 2^>nul') do if not defined actual set "actual=%%h"
rem Reuse the sidecar staging file after reading expected. Check certutil's
rem status before parsing: its error text on stdout is not a digest.
certutil -hashfile "%cached%.part" SHA256 >"%cached%.sha256" 2>nul
if errorlevel 1 goto verify_refuse
call :check_download
if errorlevel 1 exit /b 127
for /f "usebackq skip=1 delims=" %%h in ("%cached%.sha256") do if not defined actual set "actual=%%h"
del "%cached%.sha256" >nul 2>nul
if not defined expected goto verify_refuse
if not defined actual goto verify_refuse
@@ -103,17 +113,48 @@ echo impeccable: checksum mismatch downloading %url% 1>&2
exit /b 127
:verify_refuse
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: cannot verify %url% against %url%.sha256; refusing the unverified download 1>&2
exit /b 127
:check_download
set "download_file=%~1"
if not defined download_file set "download_file=%cached%.part"
if not exist "%download_file%" goto download_missing
for %%f in ("%download_file%") do if %%~zf==0 goto download_empty
exit /b 0
:download_missing
del "%cached%.sha256" >nul 2>nul
echo impeccable: download completed but the file was removed before execution: %url%; check your antivirus quarantine or logs. Refusing to continue; do not disable protection. 1>&2
exit /b 127
:download_empty
del "%download_file%" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: downloaded file is empty: %url%; refusing the unverified download 1>&2
exit /b 127
:place
call :check_download
if errorlevel 1 exit /b 127
move /y "%cached%.part" "%cached%" >nul 2>nul
if not exist "%cached%" goto fail
if errorlevel 1 goto place_failed
call :check_download "%cached%"
if errorlevel 1 exit /b 127
set "run=%cached%"
goto run
:place_failed
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
echo impeccable: could not cache the verified download: %url% 1>&2
exit /b 127
:run
"%run%" %*
exit /b
@@ -7834,7 +7834,6 @@
if (editBadgeEl && editBadgeEl.style.display !== 'none') renderEditBadge('idle-disabled');
showBar('generating');
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -7916,7 +7915,6 @@
showBar('generating');
startScrollTracking();
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -8238,7 +8236,8 @@
// rasterization from delaying the fetch itself.
if (!hasAnnotations) {
basePayload.clientSentAt = Date.now();
await sendEvent(basePayload);
const created = await sendEvent(basePayload);
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
let screenshotPath;
@@ -8279,7 +8278,10 @@
// is semantic input. Plain requests were already dispatched above.
if (hasAnnotations) {
basePayload.clientSentAt = Date.now();
sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
const created = await sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
// Capture/upload can take seconds. Progress before this acknowledgment
// refers to an unknown session and would clear our own active work.
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
}
+2 -1
View File
@@ -69,7 +69,8 @@ Choose the mode from the requested surface, not the product, and persist it only
Routing:
- **No argument:** read [routing.md](reference/routing.md) and present its context-aware menu; never auto-run a command.
- **Explicit or clearly implied command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Explicit or clearly implied request to run a command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Workflow or command-selection question:** read [Workflow questions](reference/routing.md#workflow-questions).
- **Otherwise:** treat the request as general design work. Missing PRODUCT.md routes a new surface or replacement world through init, then new-work; a narrow refinement of existing code proceeds on the incumbent implementation as `impeccable context` directs, offering init afterward rather than blocking on it.
- `teach` aliases `init`. `craft` is a deprecated alias for ordinary new-work and adds nothing. `shape` owns task discovery, then enters new-work only for visual-world and surface-concept decisions.
@@ -78,7 +78,7 @@ const __impeccableLiveDev =
process.env.NODE_ENV === "development" ? ["http://localhost:8400"] : [];
```
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: `tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts`, `tests/framework-fixtures/sveltekit-csp/expected-after-patch.js`. Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: [nextjs-turborepo/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts), [sveltekit-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/sveltekit-csp/expected-after-patch.js). Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
### append-string
@@ -93,7 +93,7 @@ const __impeccableLiveDev =
- `script-src 'self' 'unsafe-inline'` becomes `` `script-src 'self' 'unsafe-inline'${__impeccableLiveDev}` ``
- `connect-src 'self'` becomes `` `connect-src 'self'${__impeccableLiveDev}` ``
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: `tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js`, `tests/framework-fixtures/nuxt-csp/expected-after-patch.ts`.
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: [nextjs-inline-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js), [nuxt-csp/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nuxt-csp/expected-after-patch.ts).
## Troubleshooting
+1 -1
View File
@@ -196,7 +196,7 @@ Complete HTML replacement of the original element per variant, not a CSS-only pa
Replace the style opening tag with `cssAuthoring.styleTag` when the tool returns a different one. **Each variant div contains exactly one top-level element**, same tag as the original; loose siblings break outline tracking and accept. First variant visible, all others `display: none`. The browser's MutationObserver accepts atomic or progressive arrival; accepting an arrived variant fences the worker, so later publications are rejected.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in `tests/live-e2e/agent.mjs` is a faithful template.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in the [repo agent template](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/live-e2e/agent.mjs) is a faithful template.
**JSX / TSX targets:** wrap `<style>` content in a template literal (CSS braces would parse as JSX), use `className=` / `style={{…}}`, keep `data-impeccable-*` attributes as plain strings:
+7 -1
View File
@@ -1,4 +1,10 @@
# No-argument routing: the context-aware menu
# Command guidance
## Workflow questions
Give advice without executing commands; the menu below is only for bare invocations. Consult relevant command references as needed for prerequisites and scope. Link to the [docs](https://impeccable.style/docs/) for the broader workflow guide. If the user also requests execution, follow that request.
## No-argument routing: the context-aware menu
Read this when the user invokes `/impeccable` with no argument. They are asking "what should I do?" Make the menu context-aware instead of static.
+1 -1
View File
@@ -1 +1 @@
0.1.0
0.1.1
+38 -5
View File
@@ -96,6 +96,19 @@ fetch_url() {
return 1
fi
}
check_download() {
download_file=${1:-$tmp}
if [ ! -f "$download_file" ]; then
rm -f "$tmp.sha256"
echo "impeccable: download completed but the file was removed before execution: $url; check your antivirus quarantine or logs. Refusing to continue; do not disable protection." >&2
exit 127
fi
if [ ! -s "$download_file" ]; then
rm -f "$download_file" "$tmp.sha256"
echo "impeccable: downloaded file is empty: $url; refusing the unverified download" >&2
exit 127
fi
}
if [ -n "$probing" ]; then
# Inside another launcher's probe: no download, fail fast and quiet.
exit 127
@@ -116,6 +129,7 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
fetch_url "$url" && fetched=1
fi
if [ "$fetched" = 1 ]; then
check_download
# Fail closed: a freshly downloaded binary runs only after verifying
# against its .sha256 sidecar. A sidecar that cannot be fetched, or a
# machine with no sha256 tool, refuses the download instead of exec'ing
@@ -127,15 +141,20 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
elif command -v wget >/dev/null 2>&1; then
wget -q -O "$tmp.sha256" "$url.sha256" 2>/dev/null && sidecar_ok=1
fi
check_download
expected=""
[ "$sidecar_ok" = 1 ] && expected=$(cut -d' ' -f1 < "$tmp.sha256")
actual=""
if command -v shasum >/dev/null 2>&1; then actual=$(shasum -a 256 "$tmp" | cut -d' ' -f1)
elif command -v sha256sum >/dev/null 2>&1; then actual=$(sha256sum "$tmp" | cut -d' ' -f1); fi
if command -v shasum >/dev/null 2>&1; then
if digest=$(shasum -a 256 "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
elif command -v sha256sum >/dev/null 2>&1; then
if digest=$(sha256sum "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
fi
check_download
rm -f "$tmp.sha256"
if [ -z "$expected" ] || [ -z "$actual" ]; then
rm -f "$tmp"
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or no sha256 tool); refusing the unverified download" >&2
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or hashing failed); refusing the unverified download" >&2
exit 127
fi
if [ "$actual" != "$expected" ]; then
@@ -143,8 +162,22 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
echo "impeccable: checksum mismatch downloading $url" >&2
exit 127
fi
chmod +x "$tmp" 2>/dev/null
mv -f "$tmp" "$cached" && exec "$cached" "$@"
check_download
if ! chmod +x "$tmp" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not make the verified download executable: $url" >&2
exit 127
fi
check_download
if ! mv -f "$tmp" "$cached" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not cache the verified download: $url" >&2
exit 127
fi
check_download "$cached"
exec "$cached" "$@"
fi
rm -f "$tmp" 2>/dev/null
fi
+43 -2
View File
@@ -82,6 +82,8 @@ curl.exe -fsSL -o "%cached%.part" "%url%" >nul 2>nul
if errorlevel 1 goto fail
:verify
call :check_download
if errorlevel 1 exit /b 127
rem Mirrors the sh launcher and fails closed: a freshly downloaded binary
rem runs only after verifying against its .sha256 sidecar. A sidecar that
rem cannot be fetched, or an empty certutil result, refuses the download
@@ -91,8 +93,16 @@ if errorlevel 1 goto verify_refuse
set "expected="
set /p expected=<"%cached%.sha256"
for /f "tokens=1" %%h in ("%expected%") do set "expected=%%h"
call :check_download
if errorlevel 1 exit /b 127
set "actual="
for /f "skip=1 delims=" %%h in ('certutil -hashfile "%cached%.part" SHA256 2^>nul') do if not defined actual set "actual=%%h"
rem Reuse the sidecar staging file after reading expected. Check certutil's
rem status before parsing: its error text on stdout is not a digest.
certutil -hashfile "%cached%.part" SHA256 >"%cached%.sha256" 2>nul
if errorlevel 1 goto verify_refuse
call :check_download
if errorlevel 1 exit /b 127
for /f "usebackq skip=1 delims=" %%h in ("%cached%.sha256") do if not defined actual set "actual=%%h"
del "%cached%.sha256" >nul 2>nul
if not defined expected goto verify_refuse
if not defined actual goto verify_refuse
@@ -103,17 +113,48 @@ echo impeccable: checksum mismatch downloading %url% 1>&2
exit /b 127
:verify_refuse
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: cannot verify %url% against %url%.sha256; refusing the unverified download 1>&2
exit /b 127
:check_download
set "download_file=%~1"
if not defined download_file set "download_file=%cached%.part"
if not exist "%download_file%" goto download_missing
for %%f in ("%download_file%") do if %%~zf==0 goto download_empty
exit /b 0
:download_missing
del "%cached%.sha256" >nul 2>nul
echo impeccable: download completed but the file was removed before execution: %url%; check your antivirus quarantine or logs. Refusing to continue; do not disable protection. 1>&2
exit /b 127
:download_empty
del "%download_file%" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: downloaded file is empty: %url%; refusing the unverified download 1>&2
exit /b 127
:place
call :check_download
if errorlevel 1 exit /b 127
move /y "%cached%.part" "%cached%" >nul 2>nul
if not exist "%cached%" goto fail
if errorlevel 1 goto place_failed
call :check_download "%cached%"
if errorlevel 1 exit /b 127
set "run=%cached%"
goto run
:place_failed
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
echo impeccable: could not cache the verified download: %url% 1>&2
exit /b 127
:run
"%run%" %*
exit /b
@@ -7834,7 +7834,6 @@
if (editBadgeEl && editBadgeEl.style.display !== 'none') renderEditBadge('idle-disabled');
showBar('generating');
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -7916,7 +7915,6 @@
showBar('generating');
startScrollTracking();
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -8238,7 +8236,8 @@
// rasterization from delaying the fetch itself.
if (!hasAnnotations) {
basePayload.clientSentAt = Date.now();
await sendEvent(basePayload);
const created = await sendEvent(basePayload);
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
let screenshotPath;
@@ -8279,7 +8278,10 @@
// is semantic input. Plain requests were already dispatched above.
if (hasAnnotations) {
basePayload.clientSentAt = Date.now();
sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
const created = await sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
// Capture/upload can take seconds. Progress before this acknowledgment
// refers to an unknown session and would clear our own active work.
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
}
+2 -1
View File
@@ -71,7 +71,8 @@ Choose the mode from the requested surface, not the product, and persist it only
Routing:
- **No argument:** read [routing.md](reference/routing.md) and present its context-aware menu; never auto-run a command.
- **Explicit or clearly implied command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Explicit or clearly implied request to run a command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Workflow or command-selection question:** read [Workflow questions](reference/routing.md#workflow-questions).
- **Otherwise:** treat the request as general design work. Missing PRODUCT.md routes a new surface or replacement world through init, then new-work; a narrow refinement of existing code proceeds on the incumbent implementation as `impeccable context` directs, offering init afterward rather than blocking on it.
- `teach` aliases `init`. `craft` is a deprecated alias for ordinary new-work and adds nothing. `shape` owns task discovery, then enters new-work only for visual-world and surface-concept decisions.
@@ -78,7 +78,7 @@ const __impeccableLiveDev =
process.env.NODE_ENV === "development" ? ["http://localhost:8400"] : [];
```
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: `tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts`, `tests/framework-fixtures/sveltekit-csp/expected-after-patch.js`. Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: [nextjs-turborepo/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts), [sveltekit-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/sveltekit-csp/expected-after-patch.js). Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
### append-string
@@ -93,7 +93,7 @@ const __impeccableLiveDev =
- `script-src 'self' 'unsafe-inline'` becomes `` `script-src 'self' 'unsafe-inline'${__impeccableLiveDev}` ``
- `connect-src 'self'` becomes `` `connect-src 'self'${__impeccableLiveDev}` ``
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: `tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js`, `tests/framework-fixtures/nuxt-csp/expected-after-patch.ts`.
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: [nextjs-inline-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js), [nuxt-csp/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nuxt-csp/expected-after-patch.ts).
## Troubleshooting
+1 -1
View File
@@ -196,7 +196,7 @@ Complete HTML replacement of the original element per variant, not a CSS-only pa
Replace the style opening tag with `cssAuthoring.styleTag` when the tool returns a different one. **Each variant div contains exactly one top-level element**, same tag as the original; loose siblings break outline tracking and accept. First variant visible, all others `display: none`. The browser's MutationObserver accepts atomic or progressive arrival; accepting an arrived variant fences the worker, so later publications are rejected.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in `tests/live-e2e/agent.mjs` is a faithful template.
For `styleMode: "scoped"`, author every `:scope` rule with a descendant combinator: the `@scope` boundary is the variant wrapper div, not your element, so a bare `:scope { ... }` styles a `display: contents` shell. Always step in (`:scope > .card`, `:scope .hero-title`). The fake test agent's CSS in the [repo agent template](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/live-e2e/agent.mjs) is a faithful template.
**JSX / TSX targets:** wrap `<style>` content in a template literal (CSS braces would parse as JSX), use `className=` / `style={{…}}`, keep `data-impeccable-*` attributes as plain strings:
@@ -1,4 +1,10 @@
# No-argument routing: the context-aware menu
# Command guidance
## Workflow questions
Give advice without executing commands; the menu below is only for bare invocations. Consult relevant command references as needed for prerequisites and scope. Link to the [docs](https://impeccable.style/docs/) for the broader workflow guide. If the user also requests execution, follow that request.
## No-argument routing: the context-aware menu
Read this when the user invokes `/impeccable` with no argument. They are asking "what should I do?" Make the menu context-aware instead of static.
+1 -1
View File
@@ -1 +1 @@
0.1.0
0.1.1
+38 -5
View File
@@ -96,6 +96,19 @@ fetch_url() {
return 1
fi
}
check_download() {
download_file=${1:-$tmp}
if [ ! -f "$download_file" ]; then
rm -f "$tmp.sha256"
echo "impeccable: download completed but the file was removed before execution: $url; check your antivirus quarantine or logs. Refusing to continue; do not disable protection." >&2
exit 127
fi
if [ ! -s "$download_file" ]; then
rm -f "$download_file" "$tmp.sha256"
echo "impeccable: downloaded file is empty: $url; refusing the unverified download" >&2
exit 127
fi
}
if [ -n "$probing" ]; then
# Inside another launcher's probe: no download, fail fast and quiet.
exit 127
@@ -116,6 +129,7 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
fetch_url "$url" && fetched=1
fi
if [ "$fetched" = 1 ]; then
check_download
# Fail closed: a freshly downloaded binary runs only after verifying
# against its .sha256 sidecar. A sidecar that cannot be fetched, or a
# machine with no sha256 tool, refuses the download instead of exec'ing
@@ -127,15 +141,20 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
elif command -v wget >/dev/null 2>&1; then
wget -q -O "$tmp.sha256" "$url.sha256" 2>/dev/null && sidecar_ok=1
fi
check_download
expected=""
[ "$sidecar_ok" = 1 ] && expected=$(cut -d' ' -f1 < "$tmp.sha256")
actual=""
if command -v shasum >/dev/null 2>&1; then actual=$(shasum -a 256 "$tmp" | cut -d' ' -f1)
elif command -v sha256sum >/dev/null 2>&1; then actual=$(sha256sum "$tmp" | cut -d' ' -f1); fi
if command -v shasum >/dev/null 2>&1; then
if digest=$(shasum -a 256 "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
elif command -v sha256sum >/dev/null 2>&1; then
if digest=$(sha256sum "$tmp" 2>/dev/null); then actual=${digest%% *}; fi
fi
check_download
rm -f "$tmp.sha256"
if [ -z "$expected" ] || [ -z "$actual" ]; then
rm -f "$tmp"
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or no sha256 tool); refusing the unverified download" >&2
echo "impeccable: cannot verify $url against $url.sha256 (sidecar unavailable or hashing failed); refusing the unverified download" >&2
exit 127
fi
if [ "$actual" != "$expected" ]; then
@@ -143,8 +162,22 @@ if [ -n "$version" ] && [ "$os" != unknown ] && [ "$arch" != unknown ]; then
echo "impeccable: checksum mismatch downloading $url" >&2
exit 127
fi
chmod +x "$tmp" 2>/dev/null
mv -f "$tmp" "$cached" && exec "$cached" "$@"
check_download
if ! chmod +x "$tmp" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not make the verified download executable: $url" >&2
exit 127
fi
check_download
if ! mv -f "$tmp" "$cached" 2>/dev/null; then
check_download
rm -f "$tmp"
echo "impeccable: could not cache the verified download: $url" >&2
exit 127
fi
check_download "$cached"
exec "$cached" "$@"
fi
rm -f "$tmp" 2>/dev/null
fi
@@ -82,6 +82,8 @@ curl.exe -fsSL -o "%cached%.part" "%url%" >nul 2>nul
if errorlevel 1 goto fail
:verify
call :check_download
if errorlevel 1 exit /b 127
rem Mirrors the sh launcher and fails closed: a freshly downloaded binary
rem runs only after verifying against its .sha256 sidecar. A sidecar that
rem cannot be fetched, or an empty certutil result, refuses the download
@@ -91,8 +93,16 @@ if errorlevel 1 goto verify_refuse
set "expected="
set /p expected=<"%cached%.sha256"
for /f "tokens=1" %%h in ("%expected%") do set "expected=%%h"
call :check_download
if errorlevel 1 exit /b 127
set "actual="
for /f "skip=1 delims=" %%h in ('certutil -hashfile "%cached%.part" SHA256 2^>nul') do if not defined actual set "actual=%%h"
rem Reuse the sidecar staging file after reading expected. Check certutil's
rem status before parsing: its error text on stdout is not a digest.
certutil -hashfile "%cached%.part" SHA256 >"%cached%.sha256" 2>nul
if errorlevel 1 goto verify_refuse
call :check_download
if errorlevel 1 exit /b 127
for /f "usebackq skip=1 delims=" %%h in ("%cached%.sha256") do if not defined actual set "actual=%%h"
del "%cached%.sha256" >nul 2>nul
if not defined expected goto verify_refuse
if not defined actual goto verify_refuse
@@ -103,17 +113,48 @@ echo impeccable: checksum mismatch downloading %url% 1>&2
exit /b 127
:verify_refuse
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: cannot verify %url% against %url%.sha256; refusing the unverified download 1>&2
exit /b 127
:check_download
set "download_file=%~1"
if not defined download_file set "download_file=%cached%.part"
if not exist "%download_file%" goto download_missing
for %%f in ("%download_file%") do if %%~zf==0 goto download_empty
exit /b 0
:download_missing
del "%cached%.sha256" >nul 2>nul
echo impeccable: download completed but the file was removed before execution: %url%; check your antivirus quarantine or logs. Refusing to continue; do not disable protection. 1>&2
exit /b 127
:download_empty
del "%download_file%" >nul 2>nul
del "%cached%.sha256" >nul 2>nul
echo impeccable: downloaded file is empty: %url%; refusing the unverified download 1>&2
exit /b 127
:place
call :check_download
if errorlevel 1 exit /b 127
move /y "%cached%.part" "%cached%" >nul 2>nul
if not exist "%cached%" goto fail
if errorlevel 1 goto place_failed
call :check_download "%cached%"
if errorlevel 1 exit /b 127
set "run=%cached%"
goto run
:place_failed
call :check_download
if errorlevel 1 exit /b 127
del "%cached%.part" >nul 2>nul
echo impeccable: could not cache the verified download: %url% 1>&2
exit /b 127
:run
"%run%" %*
exit /b
@@ -7834,7 +7834,6 @@
if (editBadgeEl && editBadgeEl.style.display !== 'none') renderEditBadge('idle-disabled');
showBar('generating');
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -7916,7 +7915,6 @@
showBar('generating');
startScrollTracking();
saveSession();
sendCheckpoint('generate_started');
writeScrollY(window.scrollY);
if (variantObserver) variantObserver.disconnect();
variantObserver = startVariantObserver(currentSessionId);
@@ -8238,7 +8236,8 @@
// rasterization from delaying the fetch itself.
if (!hasAnnotations) {
basePayload.clientSentAt = Date.now();
await sendEvent(basePayload);
const created = await sendEvent(basePayload);
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
let screenshotPath;
@@ -8279,7 +8278,10 @@
// is semantic input. Plain requests were already dispatched above.
if (hasAnnotations) {
basePayload.clientSentAt = Date.now();
sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
const created = await sendEvent(screenshotPath ? { ...basePayload, screenshotPath } : basePayload);
// Capture/upload can take seconds. Progress before this acknowledgment
// refers to an unknown session and would clear our own active work.
if (created?.ok && currentSessionId === basePayload.id) sendCheckpoint('generate_started');
}
}
+2 -1
View File
@@ -71,7 +71,8 @@ Choose the mode from the requested surface, not the product, and persist it only
Routing:
- **No argument:** read [routing.md](reference/routing.md) and present its context-aware menu; never auto-run a command.
- **Explicit or clearly implied command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Explicit or clearly implied request to run a command:** load its reference (native variant on native platforms) and follow it. Ask once if two commands fit.
- **Workflow or command-selection question:** read [Workflow questions](reference/routing.md#workflow-questions).
- **Otherwise:** treat the request as general design work. Missing PRODUCT.md routes a new surface or replacement world through init, then new-work; a narrow refinement of existing code proceeds on the incumbent implementation as `impeccable context` directs, offering init afterward rather than blocking on it.
- `teach` aliases `init`. `craft` is a deprecated alias for ordinary new-work and adds nothing. `shape` owns task discovery, then enters new-work only for visual-world and surface-concept decisions.
@@ -78,7 +78,7 @@ const __impeccableLiveDev =
process.env.NODE_ENV === "development" ? ["http://localhost:8400"] : [];
```
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: `tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts`, `tests/framework-fixtures/sveltekit-csp/expected-after-patch.js`. Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
Per-framework: Next.js + monorepo helper: edit the *app's* `next.config.*` (not the shared helper), appending to `additionalScriptSrc` / `additionalConnectSrc`. SvelteKit: `svelte.config.js`, `kit.csp.directives['script-src']` and `['connect-src']`. Nuxt + nuxt-security: `nuxt.config.*`, `security.headers.contentSecurityPolicy['script-src']` and `['connect-src']`. Reference outputs: [nextjs-turborepo/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-turborepo/expected-after-patch.ts), [sveltekit-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/sveltekit-csp/expected-after-patch.js). Idempotency: if `__impeccableLiveDev` already exists in the file, the patch is applied; just mark `cspChecked: true`.
### append-string
@@ -93,7 +93,7 @@ const __impeccableLiveDev =
- `script-src 'self' 'unsafe-inline'` becomes `` `script-src 'self' 'unsafe-inline'${__impeccableLiveDev}` ``
- `connect-src 'self'` becomes `` `connect-src 'self'${__impeccableLiveDev}` ``
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: `tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js`, `tests/framework-fixtures/nuxt-csp/expected-after-patch.ts`.
Per-framework: Next.js inline `headers()` in `next.config.*`; Nuxt `routeRules['/**'].headers['Content-Security-Policy']` in `nuxt.config.*`. Reference outputs: [nextjs-inline-csp/expected-after-patch.js](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nextjs-inline-csp/expected-after-patch.js), [nuxt-csp/expected-after-patch.ts](https://github.com/pbakaus/impeccable/blob/8dac6ae7e020c43ab10ce9b41939f6fd42627b96/tests/framework-fixtures/nuxt-csp/expected-after-patch.ts).
## Troubleshooting

Some files were not shown because too many files have changed in this diff Show More