@bastani/atomic 0.9.28-alpha.2 → 0.9.28-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/dist/builtin/intercom/package.json +2 -2
- package/dist/builtin/mcp/native-client-licenses/NOTICE +2 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +6 -0
- package/dist/builtin/subagents/package.json +3 -3
- package/dist/builtin/subagents/skills/agent-browser/SKILL.md +1 -1
- package/dist/builtin/subagents/skills/cua-driver/BROWSER.md +60 -39
- package/dist/builtin/subagents/skills/cua-driver/EMBEDDING.md +119 -36
- package/dist/builtin/subagents/skills/cua-driver/LINUX.md +225 -183
- package/dist/builtin/subagents/skills/cua-driver/MACOS.md +120 -89
- package/dist/builtin/subagents/skills/cua-driver/README.md +16 -7
- package/dist/builtin/subagents/skills/cua-driver/RECORDING.md +85 -115
- package/dist/builtin/subagents/skills/cua-driver/RUNTIME.md +113 -0
- package/dist/builtin/subagents/skills/cua-driver/SKILL.md +55 -1071
- package/dist/builtin/subagents/skills/cua-driver/VISUAL.md +125 -0
- package/dist/builtin/subagents/skills/cua-driver/WINDOWS.md +145 -185
- package/dist/builtin/subagents/skills/cua-driver/WORKFLOW.md +173 -0
- package/dist/builtin/web-access/package.json +2 -2
- package/dist/builtin/workflows/CHANGELOG.md +21 -0
- package/dist/builtin/workflows/README.md +1 -1
- package/dist/builtin/workflows/package.json +2 -2
- package/dist/builtin/workflows/skills/impeccable/SKILL.md +8 -2
- package/dist/builtin/workflows/skills/impeccable/reference/adapt.md +6 -0
- package/dist/builtin/workflows/skills/impeccable/reference/audit.md +2 -1
- package/dist/builtin/workflows/skills/impeccable/reference/component-review.md +63 -0
- package/dist/builtin/workflows/skills/impeccable/reference/degraded/asset-producer.md +5 -0
- package/dist/builtin/workflows/skills/impeccable/reference/degraded/finish-reviewer.md +1 -1
- package/dist/builtin/workflows/skills/impeccable/reference/generate.md +101 -0
- package/dist/builtin/workflows/skills/impeccable/reference/harden.md +9 -0
- package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +3 -1
- package/dist/builtin/workflows/skills/impeccable/reference/mode-operate.md +21 -0
- package/dist/builtin/workflows/skills/impeccable/reference/mode-persuade.md +19 -0
- package/dist/builtin/workflows/skills/impeccable/reference/mode-read.md +21 -0
- package/dist/builtin/workflows/skills/impeccable/reference/new-work.md +19 -12
- package/dist/builtin/workflows/skills/impeccable/reference/region-map.md +26 -0
- package/dist/builtin/workflows/skills/impeccable/reference/routing.md +1 -1
- package/dist/builtin/workflows/skills/impeccable/reference/visualize.md +5 -5
- package/dist/builtin/workflows/skills/impeccable/scripts/VERSION +1 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/command-metadata.json +4 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/impeccable.cmd +2 -2
- package/dist/builtin/workflows/skills/impeccable/scripts/live-browser-session.js +5 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +524 -4
- package/dist/builtin/workflows/skills/prompt-engineer/SKILL.md +1 -0
- package/dist/builtin/workflows/skills/prompt-engineer/references/claude_haiku_5_5.md +81 -0
- package/dist/builtin/workflows/src/extension/index.bundle.mjs +14733 -14704
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +8 -1
- package/dist/cli/args.js.map +1 -1
- package/dist/codemode-worker.js +2 -2
- package/dist/config.d.ts +2 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -2
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-compaction.d.ts +3 -3
- package/dist/core/agent-session-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-compaction.js +5 -1
- package/dist/core/agent-session-compaction.js.map +1 -1
- package/dist/core/agent-session-events.d.ts.map +1 -1
- package/dist/core/agent-session-events.js +1 -0
- package/dist/core/agent-session-events.js.map +1 -1
- package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
- package/dist/core/agent-session-extension-bindings.js +7 -2
- package/dist/core/agent-session-extension-bindings.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +7 -1
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +3 -2
- package/dist/core/agent-session-prompt.js.map +1 -1
- package/dist/core/agent-session-tool-registry.js.map +1 -1
- package/dist/core/agent-session-types.d.ts +2 -0
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/agent-session.d.ts +2 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +6 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +22 -4
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/child-session-options.d.ts.map +1 -1
- package/dist/core/child-session-options.js +17 -2
- package/dist/core/child-session-options.js.map +1 -1
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
- package/dist/core/export-html/tool-renderer.js +2 -0
- package/dist/core/export-html/tool-renderer.js.map +1 -1
- package/dist/core/extensions/agent-events.d.ts +2 -0
- package/dist/core/extensions/agent-events.d.ts.map +1 -1
- package/dist/core/extensions/agent-events.js.map +1 -1
- package/dist/core/extensions/context-types.d.ts +2 -0
- package/dist/core/extensions/context-types.d.ts.map +1 -1
- package/dist/core/extensions/context-types.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts +3 -4
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +14 -9
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/extensions/mcp-server-registry.d.ts +4 -1
- package/dist/core/extensions/mcp-server-registry.d.ts.map +1 -1
- package/dist/core/extensions/mcp-server-registry.js +7 -4
- package/dist/core/extensions/mcp-server-registry.js.map +1 -1
- package/dist/core/extensions/runner.d.ts +3 -0
- package/dist/core/extensions/runner.d.ts.map +1 -1
- package/dist/core/extensions/runner.js +19 -0
- package/dist/core/extensions/runner.js.map +1 -1
- package/dist/core/extensions/tool-events.d.ts +1 -1
- package/dist/core/extensions/tool-events.js.map +1 -1
- package/dist/core/extensions/tool-types.d.ts +2 -0
- package/dist/core/extensions/tool-types.d.ts.map +1 -1
- package/dist/core/extensions/tool-types.js.map +1 -1
- package/dist/core/extensions/ts-source-specifiers.d.ts +18 -0
- package/dist/core/extensions/ts-source-specifiers.d.ts.map +1 -0
- package/dist/core/extensions/ts-source-specifiers.js +142 -0
- package/dist/core/extensions/ts-source-specifiers.js.map +1 -0
- package/dist/core/fast-model-variants.d.ts.map +1 -1
- package/dist/core/fast-model-variants.js +3 -2
- package/dist/core/fast-model-variants.js.map +1 -1
- package/dist/core/model-resolver-defaults.d.ts.map +1 -1
- package/dist/core/model-resolver-defaults.js +2 -0
- package/dist/core/model-resolver-defaults.js.map +1 -1
- package/dist/core/nested-tool-calls.d.ts +1 -0
- package/dist/core/nested-tool-calls.d.ts.map +1 -1
- package/dist/core/nested-tool-calls.js +1 -0
- package/dist/core/nested-tool-calls.js.map +1 -1
- package/dist/core/sdk-exports.d.ts +2 -2
- package/dist/core/sdk-exports.js.map +1 -1
- package/dist/core/sdk-types.d.ts +3 -0
- package/dist/core/sdk-types.d.ts.map +1 -1
- package/dist/core/sdk-types.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +17 -8
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager-basic-accessors.js.map +1 -1
- package/dist/core/settings-manager-core.js.map +1 -1
- package/dist/core/settings-merge.d.ts +3 -0
- package/dist/core/settings-merge.d.ts.map +1 -1
- package/dist/core/settings-merge.js +18 -4
- package/dist/core/settings-merge.js.map +1 -1
- package/dist/core/settings-storage.js.map +1 -1
- package/dist/core/settings-types.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +7 -3
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit.js +1 -1
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/extensions/codemode/execute.d.ts.map +1 -1
- package/dist/extensions/codemode/execute.js +69 -8
- package/dist/extensions/codemode/execute.js.map +1 -1
- package/dist/extensions/codemode/index.d.ts.map +1 -1
- package/dist/extensions/codemode/index.js +7 -0
- package/dist/extensions/codemode/index.js.map +1 -1
- package/dist/extensions/codemode/tool.d.ts +2 -0
- package/dist/extensions/codemode/tool.d.ts.map +1 -1
- package/dist/extensions/codemode/tool.js +4 -2
- package/dist/extensions/codemode/tool.js.map +1 -1
- package/dist/extensions/llama/provider.d.ts.map +1 -1
- package/dist/extensions/llama/provider.js +19 -8
- package/dist/extensions/llama/provider.js.map +1 -1
- package/dist/extensions/mcp/cli.js +18 -24
- package/dist/extensions/mcp/cli.js.map +1 -1
- package/dist/extensions/mcp/client/auth-provider.d.ts +4 -0
- package/dist/extensions/mcp/client/auth-provider.d.ts.map +1 -1
- package/dist/extensions/mcp/client/auth-provider.js.map +1 -1
- package/dist/extensions/mcp/client/oauth/discovery.d.ts +3 -0
- package/dist/extensions/mcp/client/oauth/discovery.d.ts.map +1 -1
- package/dist/extensions/mcp/client/oauth/discovery.js +8 -5
- package/dist/extensions/mcp/client/oauth/discovery.js.map +1 -1
- package/dist/extensions/mcp/client/oauth/flow.d.ts +4 -0
- package/dist/extensions/mcp/client/oauth/flow.d.ts.map +1 -1
- package/dist/extensions/mcp/client/oauth/flow.js +12 -2
- package/dist/extensions/mcp/client/oauth/flow.js.map +1 -1
- package/dist/extensions/mcp/client/transports/streamable-http.d.ts +3 -0
- package/dist/extensions/mcp/client/transports/streamable-http.d.ts.map +1 -1
- package/dist/extensions/mcp/client/transports/streamable-http.js +17 -14
- package/dist/extensions/mcp/client/transports/streamable-http.js.map +1 -1
- package/dist/extensions/mcp/index.d.ts.map +1 -1
- package/dist/extensions/mcp/index.js +150 -72
- package/dist/extensions/mcp/index.js.map +1 -1
- package/dist/extensions/mcp/oauth.d.ts +5 -3
- package/dist/extensions/mcp/oauth.d.ts.map +1 -1
- package/dist/extensions/mcp/oauth.js +36 -10
- package/dist/extensions/mcp/oauth.js.map +1 -1
- package/dist/extensions/mcp/ui.d.ts +3 -3
- package/dist/extensions/mcp/ui.d.ts.map +1 -1
- package/dist/extensions/mcp/ui.js +10 -2
- package/dist/extensions/mcp/ui.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/main-deferred-startup.d.ts +1 -0
- package/dist/main-deferred-startup.d.ts.map +1 -1
- package/dist/main-deferred-startup.js +9 -21
- package/dist/main-deferred-startup.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +8 -6
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/bash-execution.d.ts +5 -1
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/bash-execution.js +17 -14
- package/dist/modes/interactive/components/bash-execution.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +2 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js +5 -2
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.d.ts +1 -0
- package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-message-renderer.js +19 -8
- package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
- package/dist/modes/interactive/components/compaction-boundary-message.d.ts +3 -2
- package/dist/modes/interactive/components/compaction-boundary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-boundary-message.js +7 -4
- package/dist/modes/interactive/components/compaction-boundary-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-entry.d.ts +3 -1
- package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-entry.js +8 -2
- package/dist/modes/interactive/components/custom-entry.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +1 -0
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector-items.js +1 -1
- package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -1
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/skill-invocation-message.js +5 -2
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts +4 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +10 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.js +3 -1
- package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
- package/dist/modes/interactive/interactive-auth-login.js +6 -0
- package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
- package/dist/modes/interactive/interactive-bash-compact.js +2 -2
- package/dist/modes/interactive/interactive-bash-compact.js.map +1 -1
- package/dist/modes/interactive/interactive-extension-dialogs.js +11 -2
- package/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.js +1 -47
- package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts +3 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +6 -1
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -2
- package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
- package/dist/modes/interactive/interactive-prompt-restore.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-prompt-restore.js +0 -5
- package/dist/modes/interactive/interactive-prompt-restore.js.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.js +7 -10
- package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
- package/dist/modes/interactive/interactive-selectors.js +8 -1
- package/dist/modes/interactive/interactive-selectors.js.map +1 -1
- package/dist/modes/interactive/interactive-session-runtime.js +1 -0
- package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +1 -0
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/modes/interactive/program-status-reporter.d.ts +24 -0
- package/dist/modes/interactive/program-status-reporter.d.ts.map +1 -0
- package/dist/modes/interactive/program-status-reporter.js +96 -0
- package/dist/modes/interactive/program-status-reporter.js.map +1 -0
- package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-custom-ui.js +1 -0
- package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
- package/dist/modes/interactive-engine/engine-render-service.d.ts.map +1 -1
- package/dist/modes/interactive-engine/engine-render-service.js +3 -1
- package/dist/modes/interactive-engine/engine-render-service.js.map +1 -1
- package/dist/modes/interactive-engine/protocol.d.ts +1 -0
- package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
- package/dist/modes/interactive-engine/protocol.js +1 -0
- package/dist/modes/interactive-engine/protocol.js.map +1 -1
- package/dist/modes/interactive-engine/remote-renderer.d.ts +3 -0
- package/dist/modes/interactive-engine/remote-renderer.d.ts.map +1 -1
- package/dist/modes/interactive-engine/remote-renderer.js +7 -0
- package/dist/modes/interactive-engine/remote-renderer.js.map +1 -1
- package/dist/modes/rpc/rpc-client-process.d.ts +7 -0
- package/dist/modes/rpc/rpc-client-process.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client-process.js +20 -3
- package/dist/modes/rpc/rpc-client-process.js.map +1 -1
- package/dist/modes/rpc/rpc-command-timeouts.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-command-timeouts.js +1 -0
- package/dist/modes/rpc/rpc-command-timeouts.js.map +1 -1
- package/dist/utils/ansi.d.ts +8 -0
- package/dist/utils/ansi.d.ts.map +1 -1
- package/dist/utils/ansi.js +29 -10
- package/dist/utils/ansi.js.map +1 -1
- package/dist/utils/clipboard.d.ts.map +1 -1
- package/dist/utils/clipboard.js +13 -3
- package/dist/utils/clipboard.js.map +1 -1
- package/dist/utils/image-resize-core.d.ts +8 -0
- package/dist/utils/image-resize-core.d.ts.map +1 -1
- package/dist/utils/image-resize-core.js +1 -0
- package/dist/utils/image-resize-core.js.map +1 -1
- package/dist/utils/image-resize-worker.js +3 -2
- package/dist/utils/image-resize-worker.js.map +1 -1
- package/dist/utils/image-resize.d.ts +2 -2
- package/dist/utils/image-resize.d.ts.map +1 -1
- package/dist/utils/image-resize.js +7 -10
- package/dist/utils/image-resize.js.map +1 -1
- package/docs/codemode.md +30 -6
- package/docs/compaction.md +1 -1
- package/docs/computer-use.md +9 -9
- package/docs/custom-provider/streaming.md +4 -0
- package/docs/environment-variables.md +2 -0
- package/docs/extensions/api-reference.md +1 -1
- package/docs/extensions/authoring.md +2 -0
- package/docs/extensions/events.md +5 -1
- package/docs/getting-started/first-session.md +1 -1
- package/docs/json.md +6 -1
- package/docs/llama-cpp.md +9 -2
- package/docs/mcp-servers.md +3 -3
- package/docs/models/evals.md +34 -3
- package/docs/models.md +10 -0
- package/docs/providers.md +35 -4
- package/docs/reference/cli.md +2 -2
- package/docs/sdk/reference.md +3 -3
- package/docs/sdk.md +7 -1
- package/docs/settings.md +3 -3
- package/docs/skills.md +1 -1
- package/docs/terminal-setup.md +14 -0
- package/docs/tools.md +1 -1
- package/docs/workflows/authoring.md +3 -3
- package/docs/workflows/operations.md +2 -2
- package/examples/extensions/sandbox/package-lock.json +3 -3
- package/npm-shrinkwrap.json +67 -67
- package/package.json +8 -8
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Observe, act, verify
|
|
2
|
+
|
|
3
|
+
## Choose the route
|
|
4
|
+
|
|
5
|
+
Name the user's postcondition and any method constraint before acting.
|
|
6
|
+
|
|
7
|
+
1. For a non-GUI outcome, use a caller-provided application API, filesystem operation, or CLI when permitted; independently read back its result. An MCP-only client must not assume it has a shell.
|
|
8
|
+
2. For exact window geometry, prefer `set_window_frame` and verify with `list_windows`. For a known native menu path, use `invoke_menu` and verify the command's effect. It can temporarily activate the target, so apply the foreground authorization boundary.
|
|
9
|
+
3. For supported browser page content, use [BROWSER.md](BROWSER.md) when page-aware automation is permitted. GUI-only or native-input proof stays on the native route.
|
|
10
|
+
4. For native controls, prefer snapshot-bound accessibility actions. If semantics cannot reach the target, use a fresh, valid screenshot and the window pixel route.
|
|
11
|
+
5. If the selected background route refuses or visibly fails, consider explicitly authorized foreground delivery for that action.
|
|
12
|
+
6. If exact-window observation or delivery is unavailable, use the desktop route only when the task and authorization admit full-display capture and visible input.
|
|
13
|
+
|
|
14
|
+
Skip a route whose prerequisite is demonstrably absent: no valid window image means no window-pixel attempt. Do not exhaust impossible actions just to reach a later rung. A refusal never grants broader authority.
|
|
15
|
+
|
|
16
|
+
## Select the target
|
|
17
|
+
|
|
18
|
+
Discover running applications and their windows before assuming a remembered PID still exists. Use `launch_app` when the user requests or implies launch. Select the intended window from its returned `windows` or `list_windows({pid})`; never blindly take the first item.
|
|
19
|
+
|
|
20
|
+
A cold launch may return a process before a window appears. Retry bounded window discovery, not repeated launches. Empty discovery does not prove the process exited. For closure, absence from `list_windows` proves no listed windows, not process termination.
|
|
21
|
+
|
|
22
|
+
Choose the target on each action:
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{ "target": { "kind": "window", "pid": 844, "window_id": 10725 } }
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{ "target": { "kind": "desktop", "display_id": "primary" } }
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
These objects are argument fragments for tools advertising `target`, not standalone commands. Replace example IDs and coordinates with observed values. Do not combine `target` with flat `scope`, `pid`, or `window_id` input fields. Observation tools and semantic-only tools such as `get_window_state` and `set_value` retain their own `pid`/`window_id` schema.
|
|
33
|
+
|
|
34
|
+
`list_windows.z_index` uses larger integers for windows nearer the front. A null value is unknown, not zero; array order is not stacking evidence. Titles, bounds, and application identity help select among returned candidates but never replace an exact identifier.
|
|
35
|
+
|
|
36
|
+
## Observe
|
|
37
|
+
|
|
38
|
+
`get_window_state({pid, window_id})` requests the accessibility tree and a grounding screenshot by default. Check what actually came back: permission, backing-store, or surface-identity failures can leave usable tree data without an image. `screenshot_error` and `screenshot_frame_valid:false` are not empty-tree signals.
|
|
39
|
+
|
|
40
|
+
Prefer `structuredContent.elements` in MCP (the CLI prints structured fields directly) over parsing `tree_markdown`. Rows may contain `element_token`, role, label, value, actions, parent, depth, enabled/selected state, `frame` (screen coordinates, the space of `scope:"desktop"` actions), and `screenshot_frame` (pixels of the screenshot in the same response, the space of window-local pointer `x`/`y`). Missing fields are unknown.
|
|
41
|
+
|
|
42
|
+
- Use `query` to project matching rows plus ancestors without renumbering their indices.
|
|
43
|
+
- Use `max_elements` / `max_depth` to bound the walk, and compare returned/total counts. Truncation does not prove absence.
|
|
44
|
+
- Use `include_screenshot:false` only when tree-only observation is enough; it cannot ground a pixel action.
|
|
45
|
+
- Where advertised, `include_accessibility_tree:false` requests capture without a tree walk. Check the installed schema first.
|
|
46
|
+
- `capture_mode` is deprecated and ignored. Do not change configuration to repair a sparse tree.
|
|
47
|
+
- Use `screenshot_out_file` to save a PNG instead of inlining it, then actually read the image. Use an absolute, run-scoped output path.
|
|
48
|
+
|
|
49
|
+
The accessibility model may lag or disagree with rendered state: Electron text shims can echo writes, Catalyst may expose placeholders, and virtualized rows may have unusable frames. Cross-check the relevant visible outcome. An empty tree can also mean an unavailable accessibility bridge; inspect `degraded_reason` and the platform guide. Retry once for lazy initialization, not indefinitely.
|
|
50
|
+
|
|
51
|
+
## Act once
|
|
52
|
+
|
|
53
|
+
Use an opaque `element_token` from the latest snapshot of the intended window. Do not derive or edit tokens. A later snapshot can invalidate a pending action, including when another agent observes the same window.
|
|
54
|
+
|
|
55
|
+
Example CLI window action, with IDs and token replaced from the preceding response:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
cua-driver click '{"target":{"kind":"window","pid":844,"window_id":10725},"element_token":"s0000002a:14","session":"run-1"}'
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
| Intent | Arguments in addition to exact target/session |
|
|
62
|
+
| ------------------------------- | ------------------------------------------------------------------------------ |
|
|
63
|
+
| Activate a control | `click` with `element_token` |
|
|
64
|
+
| Double/right click | `double_click` / `right_click`; inspect the host schema and delivery result |
|
|
65
|
+
| Insert text | `type_text` with `element_token` and `text` |
|
|
66
|
+
| Focus a visible field and type | `type_text` with `x,y,text`, when that form is advertised |
|
|
67
|
+
| Replace an exposed native value | `set_value` with `pid,element_token,value` (its own schema, no `target`) |
|
|
68
|
+
| Send a key or combination | `press_key` with `key`, or `hotkey` with `keys` |
|
|
69
|
+
| Scroll / drag | Inspect `describe scroll` / `describe drag`; units and supported shapes matter |
|
|
70
|
+
|
|
71
|
+
Text insertion and value replacement are different intents. Setting a field does not prove a form submission, navigation, or rename committed. Open a collapsed search/input control and reobserve before typing into it; one focus-click may not both open and focus it. Inspect the existing value/selection before replacing content.
|
|
72
|
+
|
|
73
|
+
If a text action returns `unverifiable`, take a fresh snapshot before retrying. A deferred provider can publish after the call unwinds, so retrying immediately may duplicate text. If renderer focus is missing, the advertised `type_text` pixel form focuses then types in one call. For minimized windows, prefer an exposed semantic commit control; do not assume Return or a value write commits, and do not silently restore the window.
|
|
74
|
+
|
|
75
|
+
Keep `delivery_mode:"background"` as the default for window input. The route may use accessibility hit-testing even when addressed by pixels: pixel coordinates do not promise physical pointer delivery. Read the returned `route` instead of inferring it from the tool name.
|
|
76
|
+
|
|
77
|
+
## Pixel coordinates
|
|
78
|
+
|
|
79
|
+
Ground window actions on the PNG from that exact `get_window_state`; ground desktop actions on `get_desktop_state`. Origins are top-left, increasing downward. The driver handles its own window capture scaling; do not add window offsets to window-local input.
|
|
80
|
+
|
|
81
|
+
The harness may downsample the displayed preview independently of the returned PNG. Use the returned dimensions and the original file. If measuring on a resized preview, account for its exact scale in both axes; do not assume the preview is native resolution. Do not guess from accessibility frames or another app's geometry.
|
|
82
|
+
|
|
83
|
+
After movement, resize, navigation, or a competing desktop interaction, reobserve. When using `zoom`, read its schema and preserve the `from_zoom` mapping on the supported follow-up action. A manually cropped image requires its crop offset; an untracked crop is not an action coordinate source.
|
|
84
|
+
|
|
85
|
+
For tiny targets, inspect at full resolution or annotate a copy without changing its dimensions. Keep the raw evidence unmodified. `debug_image_out`, where advertised, captures an action diagnostic; it is not a pre-action approval step.
|
|
86
|
+
|
|
87
|
+
## Desktop loop
|
|
88
|
+
|
|
89
|
+
Use the full-display path when authorized and the narrower route cannot satisfy the task. It is global input to the visible desktop, not background targeting. Ensure the desired app/field is visible and focused before keyboard input; stop if the user or another controller changes it.
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
cua-driver get_desktop_state '{"session":"run-1","screenshot_out_file":"/absolute/run-dir/before.png"}'
|
|
93
|
+
# Read before.png; replace x/y with the observed target.
|
|
94
|
+
cua-driver click '{"target":{"kind":"desktop","display_id":"primary"},"x":600,"y":300,"session":"run-1"}'
|
|
95
|
+
cua-driver get_desktop_state '{"session":"run-1","screenshot_out_file":"/absolute/run-dir/after.png"}'
|
|
96
|
+
# Read after.png and verify the intended outcome.
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Desktop calls use the portable `display_id:"primary"` target. Do not assume arbitrary display IDs work. A desktop action does not change the modality or authority of later calls; the next action can target a window again.
|
|
100
|
+
|
|
101
|
+
## Verify and stop
|
|
102
|
+
|
|
103
|
+
For an expressible exact-window postcondition, use `verify_state` with bounded predicates and stable samples. Its result is `satisfied`, `unsatisfied`, or `unknown`. The driver does not interpret its optional final image; the agent does. Read `unknown_reason`: ambiguous matches, unavailable observations, untrusted web state, or insufficient stable samples are not success.
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
cua-driver verify_state '{"pid":844,"window_id":10725,"expect":[{"element":{"selector":{"label_contains":"Saved"},"exists":true}}],"include_screenshot":true,"session":"run-1"}'
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
This example proves a matching trusted element exists, not that every application has a meaningful “Saved” indicator. `label_contains` matches an element's accessible name, which for label-less text is its value. On macOS a selector also reaches display-only text (static text, read-only values) when no addressable control matches it. Text inside web content stays `unknown` with `untrusted_source`; read it from a fresh snapshot instead. Choose predicates that establish this task. Use fresh `get_window_state` for outcomes the predicate language cannot express, and fresh `get_desktop_state` for desktop proof. `verify_state` remains an exact-window tool; a previous desktop action does not disable it.
|
|
110
|
+
|
|
111
|
+
Action facts are not task outcomes:
|
|
112
|
+
|
|
113
|
+
| Field | Meaning for the next decision |
|
|
114
|
+
| -------------------- | ----------------------------------------------------------------------------------------------------- |
|
|
115
|
+
| `effect:"confirmed"` | The action has publishable readback; still check the task postcondition |
|
|
116
|
+
| `partial` | Only the reported delivered portion landed; inspect before repair |
|
|
117
|
+
| `unverifiable` | Delivery cannot prove effect; observe before retrying |
|
|
118
|
+
| `suspected_noop` | Available evidence suggests no useful change |
|
|
119
|
+
| `refused` | The route deliberately did not deliver |
|
|
120
|
+
| `route` | Public actuator class: `accessibility`, `synthetic_events`, `global_input`, `dom`, or `trusted_input` |
|
|
121
|
+
| `escalation` | Suggested next route/reason, never authorization or an automatic retry |
|
|
122
|
+
|
|
123
|
+
Successful action escalation uses `target` (`pixel`, `foreground`, or `page`) and `reason` (`route_unavailable`, `delivery_failed`, `effect_unconfirmed`, `suspected_noop`, or `permission_required`). Error diagnostics may have a different shape; inspect their code and current schema. Missing action facts are not confirmation.
|
|
124
|
+
|
|
125
|
+
When the postcondition is visibly satisfied, stop acting. For media, selection alone is not playback: check the title, playing/pause indicator, and elapsed progress after preroll/buffering. For closure, verify the requested window disappeared. State only what the evidence proves.
|
|
126
|
+
|
|
127
|
+
Never replay canceled, partial, or unknown actions automatically. An interrupted transport may have delivered input before losing its response. Report the interruption accurately and obtain fresh state before any further action.
|
|
128
|
+
|
|
129
|
+
## Filesystem outcomes and GUI fallbacks
|
|
130
|
+
|
|
131
|
+
When the requested outcome is a filesystem change and the caller has a
|
|
132
|
+
headless filesystem or command capability, use that semantic route. Enumerate the
|
|
133
|
+
exact source set, decide the destination-conflict policy before changing
|
|
134
|
+
anything, perform one batch-safe operation, then independently read back both
|
|
135
|
+
source and destination manifests. Do not open a file manager merely to mimic a
|
|
136
|
+
move, copy, or rename that the caller can execute and verify directly.
|
|
137
|
+
|
|
138
|
+
If the caller has no such capability, use the file manager as a GUI fallback
|
|
139
|
+
and keep each claim narrow:
|
|
140
|
+
|
|
141
|
+
1. After entering an inline rename and setting its value, commit it with the
|
|
142
|
+
platform's confirmation key, then take a fresh snapshot. Value readback from
|
|
143
|
+
the inline editor proves only that the editor changed; it does not prove the
|
|
144
|
+
filesystem rename committed.
|
|
145
|
+
2. For a multi-selection, use the platform modifier (`cmd` on macOS, `ctrl` on
|
|
146
|
+
Windows/Linux). With authorization for visible control on macOS and Windows, issue that modified click with
|
|
147
|
+
`delivery_mode:"foreground"` so the target observes physical modifier state;
|
|
148
|
+
a refused background attempt is an escalation signal, not a failed action to
|
|
149
|
+
trust or repeat. Re-snapshot before the next operation. Continue only when
|
|
150
|
+
every intended item is selected and the prior selection was preserved.
|
|
151
|
+
3. After a cross-window drag or paste, verify the destination contains the
|
|
152
|
+
complete expected set and the source reflects copy-versus-move semantics.
|
|
153
|
+
A delivered drag, keypress, or menu action is not file-operation proof.
|
|
154
|
+
4. If a destination conflict presents an unrecognized policy or ambiguous
|
|
155
|
+
partial result, stop that GUI path and surface the unresolved state instead
|
|
156
|
+
of retrying blindly.
|
|
157
|
+
|
|
158
|
+
### Clipboard outcomes and GUI fallbacks
|
|
159
|
+
|
|
160
|
+
When the requested postcondition is an exact value on the system clipboard,
|
|
161
|
+
rather than the literal gesture of selecting and copying it, keep the operation
|
|
162
|
+
semantic. Read the value from the narrowest typed source, call
|
|
163
|
+
`clipboard_write`, then prove the real clipboard state with `clipboard_read`.
|
|
164
|
+
For browser content, this means reading the page with `get_browser_state` and
|
|
165
|
+
writing the exact observed text; a passive page-text ref does not need to be
|
|
166
|
+
clicked first.
|
|
167
|
+
|
|
168
|
+
Use visual selection followed by the platform copy hotkey only when the user
|
|
169
|
+
explicitly asks for that gesture, the source cannot expose the value
|
|
170
|
+
semantically, or direct clipboard tools are unavailable. Treat that as a GUI
|
|
171
|
+
fallback: re-snapshot before acting, verify the selected range when the
|
|
172
|
+
application exposes it, and escalate only the delivery step that cannot land
|
|
173
|
+
in the background.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/web-access",
|
|
3
|
-
"version": "0.9.28-alpha.
|
|
3
|
+
"version": "0.9.28-alpha.4",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension for web search, URL fetching, GitHub repo cloning, PDF/video extraction. Fork of: https://github.com/nicobailon/pi-web-access",
|
|
6
6
|
"contributors": [
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"@bastani/atomic": "*",
|
|
34
|
-
"@earendil-works/pi-tui": "^1.0
|
|
34
|
+
"@earendil-works/pi-tui": "^1.1.0"
|
|
35
35
|
},
|
|
36
36
|
"peerDependenciesMeta": {
|
|
37
37
|
"@bastani/atomic": {
|
|
@@ -6,6 +6,27 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.9.28-alpha.4] - 2026-10-07
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added a Claude Haiku 5.5 prompt-engineering guide based on Anthropic's model-specific guidance, covering effort, search grounding, JSON/tool interactions, completion, verification, and refusal handling.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Updated the bundled Impeccable skill to 4.5.0 with engine 0.1.11, adding the `generate` playbook, component-review guidance, and reading, operating, and persuasion design modes. Atomic's telemetry and update-check defaults remain off.
|
|
18
|
+
|
|
19
|
+
## [0.9.28-alpha.3] - 2026-10-07
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Changed the `resumeInFlight` default from `"ask"` to `"never"`. Atomic no longer prompts at startup to resume interrupted durable workflows; resume them with `/workflow resume`, or set `resumeInFlight` to `"ask"` or `"auto"` in the workflow config to restore startup recovery.
|
|
24
|
+
|
|
25
|
+
### Fixed
|
|
26
|
+
|
|
27
|
+
- Fixed Atomic hanging at startup, never accepting input, when the current directory had interrupted durable workflows and `resumeInFlight` was `ask`. Startup no longer waits for workflow recovery; the "Resume interrupted workflows?" prompt now appears after the session is ready.
|
|
28
|
+
- Fixed startup recovery and SDK crash recovery skipping interrupted workflows when the project directory was reached through a symlink, such as `/tmp` or `/var` on macOS.
|
|
29
|
+
|
|
9
30
|
## [0.9.28-alpha.2] - 2026-10-07
|
|
10
31
|
|
|
11
32
|
### Added
|
|
@@ -846,7 +846,7 @@ The live session is unbounded: accepted variants and steered edits are written i
|
|
|
846
846
|
|
|
847
847
|
The session starts at `user-feedback-N-start`; durable `live-poll-N-M` and `live-reply-N-M` tool nodes own polling and acknowledgements, while `live-generate-*`, `live-steer-*`, `live-manual_edit_apply-*`, and `live-variant_mount_failed-*` mint model stages. Replies pass the event id before the status. Successful `variant_mounted` events are journal-only; `accept`, `discard`, and `prefetch` mint no model stage, and `timeout` is absorbed in the poll node. Nonzero helper exits fail the run rather than looking like timeouts. No `<artifact_dir>/feedback/` directory or per-session record is written.
|
|
848
848
|
|
|
849
|
-
The poll and reply nodes run the bundled Impeccable 4.
|
|
849
|
+
The poll and reply nodes run the bundled Impeccable 4.5.0 launcher (`skills/impeccable/scripts/impeccable`, or `impeccable.cmd` on Windows) with the `live-poll` verb; the launcher runs the engine binary beside it or downloads and checksum-verifies the pinned engine release on first use, so a machine without network access needs `IMPECCABLE_BIN` pointed at a preinstalled engine. Live sessions persist the selected app root for every helper and support SvelteKit, Nuxt, TanStack Start, Astro, Next.js, Vite, and static HTML injection.
|
|
850
850
|
|
|
851
851
|
Research context moves between stages as artifact files, not inline prompt payloads: the project design context is written to `<artifact_dir>/design-context.md` and the curated references brief to `<artifact_dir>/references.md`; `reference-discovery`, `generate-1`, and `exporter` read the required files via `reads`.
|
|
852
852
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/workflows",
|
|
3
|
-
"version": "0.9.28-alpha.
|
|
3
|
+
"version": "0.9.28-alpha.4",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension for multi-stage workflow authoring and execution.",
|
|
6
6
|
"contributors": [
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
},
|
|
86
86
|
"peerDependencies": {
|
|
87
87
|
"@bastani/atomic": "*",
|
|
88
|
-
"@earendil-works/pi-tui": "^1.0
|
|
88
|
+
"@earendil-works/pi-tui": "^1.1.0",
|
|
89
89
|
"typebox": "*"
|
|
90
90
|
},
|
|
91
91
|
"peerDependenciesMeta": {
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: impeccable
|
|
3
3
|
description: Use when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, and empty states. Handles UX review, visual hierarchy, information architecture, cognitive load, accessibility, performance, responsive behavior, theming, anti-patterns, typography, fonts, spacing, layout, alignment, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, and reusable design systems or tokens. Also use for bland designs that need to become bolder or more delightful, loud designs that should become quieter, live browser iteration on UI elements, or ambitious visual effects that should feel technically extraordinary. Not for backend-only or non-UI tasks.
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.5.0
|
|
5
5
|
license: Apache 2.0
|
|
6
|
+
metadata:
|
|
7
|
+
github-repo: https://github.com/pbakaus/impeccable
|
|
8
|
+
github-path: .pi/skills/impeccable
|
|
9
|
+
github-ref: refs/tags/skill-v4.5.0
|
|
10
|
+
github-tree-sha: 2493a4daa753fb20fdab53a51fb89ba8f5157496
|
|
6
11
|
allowed-tools:
|
|
7
12
|
- Bash(npx impeccable *)
|
|
8
13
|
- Bash(.pi/skills/impeccable/scripts/impeccable *)
|
|
@@ -66,7 +71,8 @@ Choose the mode from the requested surface, not the product, and persist it only
|
|
|
66
71
|
| `clarify [target]` | Fix | Improve UX copy, labels, and error messages | [reference/clarify.md](reference/clarify.md) |
|
|
67
72
|
| `adapt [target]` | Fix | Adapt for different devices and screen sizes | [reference/adapt.md](reference/adapt.md) · native: [reference/adapt.native.md](reference/adapt.native.md) |
|
|
68
73
|
| `optimize [target]` | Fix | Diagnose and fix UI performance | [reference/optimize.md](reference/optimize.md) |
|
|
69
|
-
| `live` | Iterate | Visual variant mode: pick elements in the browser,
|
|
74
|
+
| `live` | Iterate | Visual variant mode: pick elements in the browser, iterate on alternatives | [reference/live.md](reference/live.md) |
|
|
75
|
+
| `generate [n] [action] [element]` | Iterate | Variants, versions, or alternatives of a named element to choose from in the live browser; no manual picking | [reference/generate.md](reference/generate.md) |
|
|
70
76
|
|
|
71
77
|
Routing:
|
|
72
78
|
|
|
@@ -188,6 +188,12 @@ Test thoroughly across contexts:
|
|
|
188
188
|
- **Edge cases**: Very small screens (320px), very large screens (4K)
|
|
189
189
|
- **Slow connections**: Test on throttled network
|
|
190
190
|
|
|
191
|
+
**Custom controls** (sliders, drag surfaces, scrollable control strips): a before/after slider can pass every width check above and still refuse to drag on iOS, so exercise each one in scope in the same batched round as the checks above:
|
|
192
|
+
|
|
193
|
+
- **Primary gesture**: Tap it and confirm it responds as designed, then drag it with the target input method; the drag must complete, not just start
|
|
194
|
+
- **Scroll across it**: A swipe along the page's scroll axis across the control scrolls the page or container without activating it; a drag that starts on the control along its axis moves the control, not the page. Neither failure throws an error, so try both
|
|
195
|
+
- **Evidence**: Say what produced the evidence: an emulated viewport, synthesized touch input through a browser tool, which engine ran it (Chromium is not Safari), or a physical device. Screenshots and resized viewports verify layout, never a gesture. Name what stayed untested and move on; unreachable hardware is a reported gap, not a blocker
|
|
196
|
+
|
|
191
197
|
When the adaptation feels native to each context, hand off to `/impeccable polish` for the final pass.
|
|
192
198
|
|
|
193
199
|
---
|
|
@@ -48,11 +48,12 @@ Run comprehensive checks across 5 dimensions. Score each dimension 0-4 using the
|
|
|
48
48
|
**Check for**:
|
|
49
49
|
- **Fixed widths**: Hard-coded widths that break on mobile
|
|
50
50
|
- **Touch targets**: Interactive elements < 44x44px
|
|
51
|
+
- **Broken touch interaction**: Custom sliders, drag surfaces, and scrollable control strips whose primary gesture fails under touch, that swallow page scroll or lose the drag to it, or that stay stuck after an interrupted gesture. Code tells: mouse-only handlers, no `touch-action` on a pointer-event drag surface, drag state that nothing clears on cancel, lost capture, or blur. Exercise the gesture when a browser tool can synthesize touch (a rendered viewport proves layout, not the gesture), then say what produced the evidence (emulated viewport, synthesized touch, which engine, physical device) and what stayed untested
|
|
51
52
|
- **Horizontal scroll**: Content overflow on narrow viewports
|
|
52
53
|
- **Text scaling**: Layouts that break when text size increases
|
|
53
54
|
- **Missing breakpoints**: No mobile/tablet variants
|
|
54
55
|
|
|
55
|
-
**Score 0-4**: 0=Desktop-only (breaks on mobile), 1=Major issues (some breakpoints, many failures), 2=Partial (works on mobile, rough edges), 3=Good (responsive, minor touch target or overflow issues), 4=Excellent (fluid, all viewports, proper touch targets)
|
|
56
|
+
**Score 0-4**: 0=Desktop-only (breaks on mobile), 1=Major issues (some breakpoints, many failures), 2=Partial (works on mobile, rough edges), 3=Good (responsive, minor touch target or overflow issues), 4=Excellent (fluid, all viewports, proper touch targets, gestures work under touch)
|
|
56
57
|
|
|
57
58
|
### 5. Implementation Integrity (CRITICAL)
|
|
58
59
|
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Plan and asset review
|
|
2
|
+
|
|
3
|
+
Use this checkpoint on comp-led builds once every raster region has its plate and the plates gate has scored them, before any page code exists. The approved comp is the reference. The user reviews two things: the plates that will ship, and the production plan for everything else, meaning which regions code draws. A painted region planned as code is the most expensive mistake a comp-led build makes, and this is where the user catches it. Text, controls and chrome are judged later, in the assembled first viewport.
|
|
4
|
+
|
|
5
|
+
## Plan, capture, serve
|
|
6
|
+
|
|
7
|
+
Run `.pi/skills/impeccable/scripts/impeccable component-review plan`. It writes `.impeccable/review/components.json` from the measured spec, the comp and the plate files, and refuses, naming each one, while any raster region lacks its plate. Never write or edit that file for this stage: the packet is derived from the spec, so every change belongs in the regions file.
|
|
8
|
+
|
|
9
|
+
If the harness exposes `component_review`, call it with `manifest_path` set to `.impeccable/review/components.json`. The host captures, presents the review and returns the user's decisions. A suspended request is waiting for the user; it is not a failed build or an approval.
|
|
10
|
+
|
|
11
|
+
Otherwise run `.pi/skills/impeccable/scripts/impeccable component-review capture --manifest .impeccable/review/components.json`, then start `.pi/skills/impeccable/scripts/impeccable component-review serve --session <returned session>` in the background. Open the URL it prints in the available browser and wait for the user; `serve` exits 0 once they submit. Read the decisions with `.pi/skills/impeccable/scripts/impeccable component-review status --session <id>`; `.pi/skills/impeccable/scripts/impeccable component-review verify --manifest .impeccable/review/components.json` confirms approval and refuses pending, needs-work and stale input. Never submit the page or write a receipt on the user's behalf.
|
|
12
|
+
|
|
13
|
+
`serve` exits 2 when this session has no browser (the same signal as the decision page) and 4 when it closes after 30 idle minutes without a decision. Either way no one is reviewing: stop waiting, do not approve anything yourself, and do not build past this checkpoint. End the run and report the plan and asset review as pending with its session ID, so the user can resume it. A waiting review is pending work, not a completed build.
|
|
14
|
+
|
|
15
|
+
## Act on the receipt
|
|
16
|
+
|
|
17
|
+
Apply the user's decisions as given, never your own favorable verdict in their place.
|
|
18
|
+
|
|
19
|
+
- **approve**: once every item is approved and the inventory is confirmed, advance to the hero.
|
|
20
|
+
- **revise** (a plate): regenerate that plate at the same path with the user's feedback.
|
|
21
|
+
- **revise with split** (an asset): replace that region in the regions file with its layers: a frame plate with a transparent opening (kind `plate`, same box), the content as its own `image` region at the opening's box, and each moving part (a shutter, a door) as its own plate. Name each layer after the original region, as `<id>-frame`, `<id>-view` or `<id>-shutter-left`, so the next round shows it as part of the user's request. Rerun `.pi/skills/impeccable/scripts/impeccable comp-spec --comp <comp.png> --regions <regions.json>` and produce the plates.
|
|
22
|
+
- **revise** (a plan item): change the regions file as the feedback says (resize or extend a raster region, split material into its own plate region, or adjust the code region), rerun `.pi/skills/impeccable/scripts/impeccable comp-spec --comp <comp.png> --regions <regions.json>`, and produce any new plates.
|
|
23
|
+
- **reclassify** (a code region): in the regions file, change that region's `kind` to the one the user chose and rewrite its `note` to describe the material. Rerun `.pi/skills/impeccable/scripts/impeccable comp-spec --comp <comp.png> --regions <regions.json>`, then produce the new plates, with the asset producer when subagents are available.
|
|
24
|
+
- **missing**: add the region to the regions file, rerun `.pi/skills/impeccable/scripts/impeccable comp-spec --comp <comp.png> --regions <regions.json>`, and produce its plate if it is raster.
|
|
25
|
+
|
|
26
|
+
Then run `plan`, `capture` and `serve` again. Unchanged decisions carry over, so the user sees only what changed. Any spec change, or a plate replaced after acceptance, needs a new round; the build-phase gate stays closed until the review of the current spec is accepted.
|
|
27
|
+
|
|
28
|
+
## Assemble and review
|
|
29
|
+
|
|
30
|
+
Build the first viewport from the approved plates and plan, and run the hero gate. Human review does not waive its integrity checks. After three failed hero attempts, stop iterating and present the first-viewport review with the current build; the user's eye settles what the readings could not.
|
|
31
|
+
|
|
32
|
+
Present a second manifest at `.impeccable/review/hero.json`. You write this one, and its shape is fixed:
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"schemaVersion": 2,
|
|
37
|
+
"stage": "hero",
|
|
38
|
+
"id": "hero",
|
|
39
|
+
"title": "First viewport",
|
|
40
|
+
"comp": {"path": ".impeccable/mocks/comp.png", "width": 1536, "height": 1024},
|
|
41
|
+
"components": [{
|
|
42
|
+
"id": "first-viewport",
|
|
43
|
+
"name": "First viewport",
|
|
44
|
+
"medium": "HTML / CSS",
|
|
45
|
+
"note": "Assembled first viewport",
|
|
46
|
+
"box": {"x": 0, "y": 0, "w": 1, "h": 1},
|
|
47
|
+
"preview": {"kind": "page", "path": "index.html"},
|
|
48
|
+
"dependencies": ["styles.css", "assets/plates/sky.png", "fonts/display.woff2"]
|
|
49
|
+
}]
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- `schemaVersion` is 2. Version 3 is the plan review packet and requires stage `components`. `codeRegions` and `specSha256` exist only in version 3 and are refused here. `reviewGroup` is refused too: version 3 rejects it, and any other version accepts it only on a page preview in a `components`-stage manifest, never in a hero manifest.
|
|
54
|
+
- `comp.path` is the `comp` value in `.impeccable/build/spec.json`, and `width` and `height` are that PNG's pixel size.
|
|
55
|
+
- Exactly one component, with `box` exactly `{"x": 0, "y": 0, "w": 1, "h": 1}` and `name`, `medium` and `note` as strings.
|
|
56
|
+
- `preview.path` is the page entry the build gates (`artifact` in `.impeccable/build/state.json`).
|
|
57
|
+
- `dependencies` lists every other file the page loads (stylesheets, scripts, plates, images, fonts) as bare strings. Every path, here and above, is project-relative and plain: no leading `./` or `/`, no `..`, no URL, no `?`, `#`, `%`, `:` or backslash. A request to a file missing from this list, or to another host, fails the capture.
|
|
58
|
+
|
|
59
|
+
The reference stays the approved comp. Call the same host review tool, or run `capture`, `serve` and `verify` with this manifest. Needs-work feedback starts another assembly round.
|
|
60
|
+
|
|
61
|
+
Acceptance closes human review for this build: never request plan, asset or assembly approval again. While the page renders what the user accepted, the hero score, the palette check and every numeric reading are advisories; material vetoes still hold (a missing or unreferenced plate, an SVG illustration, an organic clip, a clipped plate, invented ink, failed rendered presence). When the capture no longer matches the accepted screenshot, restore what the user accepted; until then the readings apply. Complete the rest of the page, responsive behavior, finish checks and documentation with the accepted first viewport as the visual direction. This is first-viewport calibration, not a claim that the user reviewed the rest of the page. Shared stylesheet edits do not reopen approval. Preserve the accepted direction; a later explicit user change is a new task.
|
|
62
|
+
|
|
63
|
+
Assembled-page capture executes inline and declared local scripts from the pinned inputs. Network APIs, frames and workers are unavailable; the initial viewport must settle before capture. Keep the real page and declare its scripts rather than removing behavior to pass review.
|
|
@@ -13,6 +13,10 @@ Do not redesign. Preserve the reference's visual role, silhouette, palette, ligh
|
|
|
13
13
|
|
|
14
14
|
When the parent hands you a decision card packet instead of an approved mock, the job is one comp: one card, one file, written to the card's declared `comp` path the moment it renders. The parent runs several of you in parallel, one per card, so this card is your entire contract; generate first, plan never, because the file on disk is the deliverable and the decision page is waiting on it. Work from the card's structured fields and PRODUCT.md alone; report a card too thin to brief a comp, never pad it from imagination. Render the card's direction as a north-star comp at full fidelity: the requested surface's first viewport, prompt led by the surface's own structure (regions named in order with their scale relationships, never the world's atmosphere), fully committed in the card's own palette, type character, and material world. A native app or mobile-first surface is a portrait frame at its device viewport, never a landscape default. Every sibling renders at the same full fidelity in its own grammar, one surface, one aspect; equal commitment keeps the comparison honest. Real product name and real content only; never invent commercial claims, prices, benchmarks, or dates PRODUCT.md does not carry. Exclusions bind those claims, never a medium the card's own world has not excluded: a subject that lives in photographs keeps its photographs. Write the prompt sidecar beside the file. Return one line naming the path and any deviation, nothing more. Everything below this section is the asset-production job; none of it applies to a decision-comp run.
|
|
15
15
|
|
|
16
|
+
## Review handoff
|
|
17
|
+
|
|
18
|
+
Return the actual files and any unresolved drift to the parent for the user's plan and asset review in [component-review.md](../component-review.md). A parent or automatic visual check is not a substitute for that human checkpoint. The parent may call you again after it: for regions the user reclassified from code to raster (the spec now lists them with a plate path), or for plates the user asked to revise, with their feedback as the prompt notes. Produce only those, preserve unchanged assets, and hand off real files as before; never self-approve. This checkpoint does not apply to the Decision Comps job above.
|
|
19
|
+
|
|
16
20
|
## Input Contract
|
|
17
21
|
|
|
18
22
|
Expect the measured spec (`.impeccable/build/spec.json`, written by `impeccable comp-spec` from the approved comp), the approved comp path, and the skill scripts path. Optionally: a subset of region ids to produce, extra prompt notes per region, and format or transparency needs. Everything else you need is in the spec: each raster region's id, kind (plate, image, texture), pixel box, sampled palette, aspect, note, and the plate path it must land on.
|
|
@@ -29,6 +33,7 @@ Per region, in the spec's order:
|
|
|
29
33
|
2. Choose the background from the approved region: an isolated figure, object, or line drawing on the page ground is a **transparent cutout**; a photograph, full-frame illustration, or texture stays **opaque**. Save `.pi/skills/impeccable/scripts/impeccable comp-spec --plate-prompt <id> --background transparent` to a UTF-8 prompt file for a cutout; use `--background opaque` otherwise. The transparent prompt preserves reference placement and clear margins, white paint, fine edges, and interior holes.
|
|
30
34
|
3. Produce the plate at its exact spec `plate` path. Create the output directory first and choose a supported output size matching the region's aspect, at least 1.5x its pixel dimensions. Prefer the harness-native image tool with the crop as input and the saved prompt; request a transparent PNG for cutouts, then run `.pi/skills/impeccable/scripts/impeccable embed-prompt <plate> --prompt-file <prompt.txt>` (if you refine the prompt, save and embed the exact text sent). With the API fallback, run `.pi/skills/impeccable/scripts/impeccable generate-image --ref <crop.png> --prompt-file <prompt.txt> --out <plate.png> --size <WxH> --quality high --background transparent` for a cutout, or `--background opaque` otherwise. The API fallback embeds the prompt and records the background in the sidecar. The output must be PNG; the fallback requests native alpha and performs no chroma-keying.
|
|
31
35
|
4. Open the plate beside the crop and compare subject, placement, scale, palette, and style. For cutouts, verify a real alpha channel and inspect composites on light and dark grounds: white paint must stay solid, interior holes must clear, and fine edges must avoid halos. Inspect glass and soft shadows carefully; partial alpha alone does not ensure convincing translucency. Never chroma-key native transparent output or flatten it before saving. If a native tool returns opaque pixels or a painted checkerboard, retry with the API fallback when available; otherwise report the transparency blocker. On a visual miss, tighten the prompt and regenerate once. Two misses on one region: keep the better plate, mark it `needs_parent_review`, and name the drift. The parent runs the plates gate after all assets exist; report `unscored` until a gate score is available.
|
|
36
|
+
5. A frame plate (a window, a doorway, an arch) is a transparent cutout with an opening: generate it with a transparent background and keep the opening fully transparent. Verify the alpha inside the opening before saving: no baked view, no glow or vignette halo across it. The content seen through the opening is its own image region; produce it separately at the opening's size.
|
|
32
37
|
|
|
33
38
|
Do not redesign. Do not add objects, restyle, or reinterpret; the comp was approved as it is. Do not touch the page code, the spec, or the comp. Do not produce anything the spec does not list; a region the parent forgot goes back as a one-line note, not a plate.
|
|
34
39
|
|
|
@@ -16,7 +16,7 @@ Expect: the original request; the confirmed user answers; the artifact path(s);
|
|
|
16
16
|
## Checks, in order
|
|
17
17
|
|
|
18
18
|
0. **Evidence.** Before any other check, verify the required captures exist and every capture is valid. Required: the platform's full viewport set (web: `desktop.png` and `mobile.png`; native: one capture per shipped device class), plus every capture the calling brief names as required, a reported user viewport (`user-<width>.png`) included. Valid: no black or blank regions, content matching what the filename claims (a visit capture showing the About section is invalid), the document top visible where the file claims a full page, dimensions that make sense for the named viewport. A required capture that is absent fails exactly like one that is malformed: a viewport nobody captured is a viewport nobody inspected, and it cannot ship. When any capture fails, the whole review changes shape: return `disposition: recapture` as the first line, then one section, `recapture`, listing each missing or invalid file and what a valid capture of it shows, and stop. Never build a matrix on malformed evidence; a verdict derived from a broken capture launders the breakage into an approval, and the parent owes you a full re-review on valid captures, not a scoring round.
|
|
19
|
-
1. **Persistence.** PRODUCT.md exists. On a comp-led build, `.impeccable/build/state.json` exists and
|
|
19
|
+
1. **Persistence.** PRODUCT.md exists. On a comp-led build, `.impeccable/build/state.json` exists and every phase before `review` is `closed` or explicitly `skipped`; an open or failed phase is a material finding. A comp-led config with no state file, or a state whose `comps` phase is neither `closed` nor `skipped`, means the comp round was skipped and the build ran from a world description alone, a material finding that outranks craft; a phase closed with a `forced` record is disclosed as a material finding unless the user downgraded the comp in words the packet quotes; a state file whose `hero.gate.score` sits under 0.72, or a missing state file, means the reproduction ran unproven, a material finding, and `.impeccable/review/hero-repro.png` must exist either way. When DESIGN.md predates this build (an extension or redesign), it matches the built world; on a new world it is written after this review by the documenter, so its absence here is not a finding. When comp-round comps exist under `.impeccable/mocks/`, an approval record exists too: the surface brief naming the approved comp, or an `approved` flag in its sidecar. Comp-round comps with no recorded pick mean the approval point was skipped, a material finding. Files under `.impeccable/mocks/decision/` are exempt: they are the direction round's dealt hand, produced before any comp round, and imply no approval whatever the build path; a code-led build has no comp round at all.
|
|
20
20
|
2. **Fidelity.** Start from the measurement, then judge what it cannot: read `.impeccable/review/diff/final/report.json` (and hero) first; every region scored `missing` or `contradicted` is a matrix row in that state unless the paired crop under `regions/` shows the score is wrong, and you say why; a region scored `match` still gets your eye for lettering character and material, which the numbers do not measure. Then, against your own element inventory of the approved comp, never against the contract's summary of it: topology, reading order, focal scale, overlaps and z-order, density, signature geometry, the primary action's treatment (a CTA the comp physically works, dissolves, or stamps is a signature element; its plain-rectangle rendition is contradicted), navigation items and icons, headline levels and scale relationships. Classify every salient element: match, acceptable adaptation, missing, contradicted, or added without approval. Three rows are mandatory in every matrix. TYPE: the display lettering's character, compression, width, weight, contrast, terminals, against the comp's; a face of a different character is contradicted however the layout matches. MATERIAL: an element rendered as flat CSS or clean vector where the comp shows painted, textured, dimensional, or photographic material is contradicted regardless of placement; medium is part of the promise. GROUND: the page field's value and temperature against the comp's, sampled from pixels on both sides when tooling allows rather than judged from memory, and read as the net on-screen result where a texture or tile paints over the base color; a ground warmer or cooler than the comp's is contradicted however faithfully the layout matches, and drift toward the rendition prior (warm cream on light grounds, blue-black slate on dark) is the direction to hunt. With no approved comp, TYPE and MATERIAL do not lapse: judge them against the contract's OWN-WORLD and the world's real materials, and treat faked physicality (CSS bevels, embossing, stamped-metal or chalk effects imitating a material the page never renders) as contradicted on its face; imitation material is the single most reliable mark of machine-made design. GROUND narrows rather than lapses: with no comp to sample, a color OWN-WORLD names is the target and the same warmer-or-cooler judgment applies; when OWN-WORLD names none, there is no GROUND authority, and the review says so in place of a verdict, because a target the reviewer invents turns the check into taste. A critique-reference comp on such a build is provocation, not spec: no element matrix, no adaptation citations, no asset obligations; its one contribution is what the image dared that the build did not, and dares worth adopting enter material_fixes as ordinary ordered fixes. An adaptation counts as intentional only when it cites the user answer, surface brief, accessibility need, or product truth that forced it; an uncited deviation is a defect. A missing signature element, a changed topology, or content added without approval fails fidelity and outranks every craft point in material_fixes. When MATERIAL is contradicted on the focal element, or contradiction is the page rather than the exception, stop ordering repairs: make the first material fix a rebuild directive naming the comp regions to re-derive and the assets to produce; a list of patches against a rejected page launders the rejection into an approval. A fix that requires producing an asset says so explicitly ("produce: <region> as a raster asset"), never phrased as a style adjustment the parent will answer with CSS. The comp is the spec for composition, topology, element inventory, density, lettering character, and material; it is not a pixel spec for semantics, accessibility, or responsive reflow, and that allowance covers translation, never replacement.
|
|
21
21
|
3. **Ceiling.** Against the QUALITY BAR card: name the world's native devices the build left unused, frame, depth, lettering treatment, ornament density, motion. The card governs commitment and finish, never composition.
|
|
22
22
|
4. **Contract, promise by promise.** First verify FORM carries the seed key the concept roll printed; a contract with no seed key, or one the parent cannot corroborate, means the roll was skipped, a material fix ahead of any craft point. Then, for each of the five blocks: does the render keep the promise? Apply the memory test to the first viewport.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
> **Additional context needed**: only the target element, when the request does not name one that resolves uniquely on the page.
|
|
2
|
+
|
|
3
|
+
Generate is the fast lane into live mode: the user names an element, a direction, and a count in one sentence, and within a minute they are cycling through variants in their browser. One command boots the helper, hands the element to the overlay in the page your harness already shows (it scrolls to it, selects it, and fires the same Go a click fires) and returns the generate event; one edit writes the variants; one call replies and waits for the user's choice, which the helper bakes into source itself. This file owns the lane's plumbing; from the event onward the design work is [live.md](live.md)'s, unchanged, so read it in full now if you have not this session.
|
|
4
|
+
|
|
5
|
+
**Web only.** Live mode's browser overlay has no native equivalent; on `ios` / `android` / `adaptive` projects, decline this command and offer `bolder` or `quieter` on the source instead.
|
|
6
|
+
|
|
7
|
+
The plumbing is where the lane saves time: one command starts the session around the page your harness already shows, one call replies and waits, and nothing here is a browser you have to babysit. The design work is not where it saves time. Setup runs as for any command (`impeccable context`, this reference, craft-floor.md before the edit), and the variants are planned, written, and accepted exactly the way a live session plans, writes, and accepts them.
|
|
8
|
+
|
|
9
|
+
Three prohibitions cover the known ways this command goes wrong:
|
|
10
|
+
|
|
11
|
+
- **Never run init or document, and never ask for PRODUCT.md or DESIGN.md.** When they exist, the start command prints them under `boot` and you use them. When they do not, it says so (`contextMissing`, `contextNote`) and you extract the identity from the event (Step 3). A missing file is never a reason to interview the user inside this command; offer `init` in one line after the session ends.
|
|
12
|
+
- **Never hand-write a variants wrapper or invent a session id.** Only the browser mints session ids (8 hex characters, at Go). A missing event is fixed by rerunning Step 2, never with a direct source edit.
|
|
13
|
+
- **Do not act on hook findings while live markers are in the file**, and do not restyle variants to appease them; the accept verifies the file once the variant is permanent.
|
|
14
|
+
|
|
15
|
+
## Step 1: Parse the request
|
|
16
|
+
|
|
17
|
+
Three parts, all from the user's sentence:
|
|
18
|
+
|
|
19
|
+
- **A number in the request**: that is the count. **No number**: 3. The protocol caps count at 8.
|
|
20
|
+
- **The direction wording** maps onto the live action vocabulary; never invent a new action value:
|
|
21
|
+
- **bold, bolder, stronger, punchier**: `bolder`
|
|
22
|
+
- **quiet, calmer, softer, toned down**: `quieter`
|
|
23
|
+
- **simpler, minimal, stripped**: `distill`
|
|
24
|
+
- **refined, tightened, polished**: `polish`
|
|
25
|
+
- **font and type words**: `typeset`
|
|
26
|
+
- **color words**: `colorize`
|
|
27
|
+
- **arrangement and spacing words**: `layout`
|
|
28
|
+
- **device and breakpoint words**: `adapt`
|
|
29
|
+
- **motion words**: `animate`
|
|
30
|
+
- **playful words**: `delight`
|
|
31
|
+
- **rule-breaking words**: `overdrive`
|
|
32
|
+
- **Wording that carries intent but no vocabulary word** ("make it feel like a bank", "warmer", "more premium"): `impeccable`, with the user's wording passed as the prompt.
|
|
33
|
+
- **An action fits AND extra intent rides along** ("bolder, but keep it monochrome"): that action, with the rest as the prompt.
|
|
34
|
+
- **The wording names no direction at all** ("better", "improve", "nicer", "different", "fresh", "new", "redesign", "fix", "some options", "ideas", "alternatives", or just "variants" with nothing else): Ask the user directly to clarify what you cannot infer. Ask one question, offering the vocabulary: *"Which direction should the variants take? bolder, quieter, simpler (distill), polished, typography (typeset), color (colorize), layout, motion (animate), playful (delight), or rule-breaking (overdrive)."* Map the answer with this list; an answer that is still open ("surprise me", "you pick") is `impeccable` with the user's original wording as the prompt, and Step 2 starts on that answer.
|
|
35
|
+
- **The element description** ("the pricing cards", "the hero heading"): Step 2 resolves it to a selector.
|
|
36
|
+
|
|
37
|
+
Done when you hold an action from the vocabulary (asked for, when the request named no direction), a count from 1 to 8, and the element description.
|
|
38
|
+
|
|
39
|
+
## Step 2: Reuse the page, then start
|
|
40
|
+
|
|
41
|
+
**Reuse** the dev server already running and the tab your harness already shows it in; a second server or a second browser window is the failure this step prevents.
|
|
42
|
+
|
|
43
|
+
1. **Find the dev server**, cheapest source first, and stop at the first hit: the user's message, a browser tab already on the app (Claude Code: an origin in `tabs_context`), a server your harness started (Claude Code: `preview_list`), a terminal that printed its URL. Its origin is your `--dev-url`. **No hit**: leave `--dev-url` off and run the start command with no wait; the boot probes for a running server and its verdict names the move. `browser_needed` carries the `devUrl` it found: open it as in 2, then rerun with `--dev-url <devUrl> --wait-for-browser 60000`. `no_dev_server` means nothing serves the app: start the dev script the way the verdict says (Claude Code: `preview_start`; Codex: an exec you yield from), wait for its URL, then rerun with `--dev-url <url>`.
|
|
44
|
+
2. **Open the page that renders the element in your browser, then start.** The route the request names, else the one `--target` serves; `--dev-url` takes only the origin.
|
|
45
|
+
- **Claude Code** (`navigate`, which opens the Browser pane when it is closed and takes the `tabId` from `tabs_context` when a tab is already on that origin): open the URL, then run the start command with `--dev-url <url> --wait-for-browser 60000`. The boot injects the overlay and the page reloads into it while the command waits. Your browser tool is the only opener on this harness; the engine ignores `--open` there.
|
|
46
|
+
- **No browser tool** (Codex, others): run the start command with `--open --wait-for-browser 120000`; it opens the system browser, and the longer wait covers the user finding the tab. **`browser_open_failed` back**: tell the user the `url` in one line and rerun with `--wait-for-browser 120000`.
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
.pi/skills/impeccable/scripts/impeccable live-generate --target src/App.jsx --dev-url http://127.0.0.1:5173/ --selector ".pricing-grid" --action bolder --count 3 --boot --wait-for-browser 60000
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Run it in the foreground in Claude Code (it returns within the wait); on Codex, in an exec you yield from, the way Step 3 runs the poll.
|
|
53
|
+
|
|
54
|
+
- `--target`: the file that renders the element when the request or the project makes it obvious; skip it otherwise.
|
|
55
|
+
- `--dev-url`: the origin from 1; omit it and the boot probes.
|
|
56
|
+
- `--selector`: a unique class first, then a landmark tag plus class, an id last (every variant mounts a copy of the element, so an id repeats in the DOM). **The request names a repeated component in plural** ("the pricing cards"): target the container that holds the set, so one scoped stylesheet restyles every instance. One read of the source file that renders the element is allowed when the selector is not obvious; `--dry-run` resolves and reports without starting anything when it is not certain.
|
|
57
|
+
- `--boot`: runs the lane's boot (PRODUCT.md and DESIGN.md loaded again for the helper, missing files tolerated, dev URL found, bottom bar hidden for the helper's lifetime) and reuses a helper that is already running. Its result rides along as `boot`.
|
|
58
|
+
- Also available: `--prompt`, `--text` (keep only matches whose visible text contains a snippet), `--index` (1-based pick among matches).
|
|
59
|
+
|
|
60
|
+
Read the output in this order: `boot` (or `boot.contextMissing` with `boot.contextNote`: the page is the source of truth, per the note), then `event`, the generate event for `sessionId`, with the same `_instructions` a user's Go gets. Every verdict carries `_instructions`, and they win over your recollection of this file; the ones whose move is a decision of yours:
|
|
61
|
+
|
|
62
|
+
- **`ambiguous`**: the candidates are listed; target their common container, or rerun with `--text "<visible text>"` or `--index <n>`.
|
|
63
|
+
- **`dev_server_gone`**: the dev server stopped answering while the command waited for the page. Start it the way the verdict says, then rerun with `--dev-url <url>`.
|
|
64
|
+
- **`no_match`**: the tab is on a route that does not render the element (navigate to the right route, rerun), or the selector is wrong (derive a better one from the source, or add `--text`).
|
|
65
|
+
- **`config_missing` / `config_invalid`** under `bootError`: follow [live-setup.md](live-setup.md) first, then rerun.
|
|
66
|
+
- **`event: null`** with `ok: true`: the event was slower than the wait; run `.pi/skills/impeccable/scripts/impeccable live-poll` once to collect it, then continue.
|
|
67
|
+
|
|
68
|
+
Done when the output shows `ok: true`, a `sessionId`, and an `event`, reached with at most one server started and one tab opened by you.
|
|
69
|
+
|
|
70
|
+
## Step 3: Generate
|
|
71
|
+
|
|
72
|
+
The event is a standard `generate` event: the picked element's context, a preflighted scaffold, and `_instructions` naming the action's reference, the planning section, and the exact splice. Handle it exactly per live.md's **Handle generate**, which owns everything from the identity lock to the done reply: read the action's reference and craft-floor.md as it says, plan per section 4 (identity first, then mode, then three different primary axes, then the squint test), declare knobs per section 7, and deliver per section 6 (a complete replacement of the element per variant, the preview CSS plus every variant in one edit at the scaffold's splice). The lane changes nothing about what a variant may be: the moves a live session would make on this element (a promoted tier, a restructured set, a reordered card, a different surface) are open here too. Never screenshot the page; the overlay preview is the review channel until accept.
|
|
73
|
+
|
|
74
|
+
**Reply and wait in one call**, with the file you wrote:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
.pi/skills/impeccable/scripts/impeccable live-poll --reply EVENT_ID done --file src/App.jsx --then-poll
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
This replies done (the browser mounts the variants) and then blocks until the user's choice arrives, so run it the way your harness runs a long wait: **Claude Code** in the foreground with your tool's longest timeout (600000 ms), so you are paused until the choice arrives; **Codex** in a yielded foreground exec. Never pass a short `--timeout=`. While it runs there is nothing else to do: never sleep and never poll its output on a timer; a harness that backgrounds it wakes you when it returns. `{"type":"timeout"}` means the user has not chosen yet: run `live-poll` again and keep waiting. If the edit fails after the browser flipped to GENERATING, `--reply EVENT_ID error "Short reason"` (without `--then-poll`) so the bar resets.
|
|
81
|
+
|
|
82
|
+
Then tell the user, in one line, where their variants are: *"Three [bolder] variants are live on [the pricing cards]: cycle with the floating bar's arrows, adjust the Tune knobs, and Accept the keeper."*
|
|
83
|
+
|
|
84
|
+
Outside the replace path, read the matching live.md section before acting: `scaffold.previewMode: "svelte-component"` (Svelte previews are edited as components, and their accept is mechanical), `mode: "insert"`, `variant_mount_failed`, `steer`, `manual_edit_apply`, and any `fallback: "agent-driven"` wrap error.
|
|
85
|
+
|
|
86
|
+
## Step 4: Accept and close
|
|
87
|
+
|
|
88
|
+
The call from Step 3 returns the user's choice. **`discard`**: nothing to do. **`accept`**: `_acceptResult.carbonize: true` is the normal case, and the cleanup is live.md's **Required after accept**, unchanged: move the accepted variant's rules into the stylesheet that already owns the element with real selectors, bake the chosen knob values in, unwrap the element and drop every `data-impeccable-*` attribute, delete the inline `<style>` block and both `impeccable-carbonize` markers, then `.pi/skills/impeccable/scripts/impeccable live-complete --id SESSION_ID` and confirm `phase: "completed"`. (`baked: true` appears only when the accept was run with `--bake`; then the helper already made the variant permanent and no `live-complete` is owed.)
|
|
89
|
+
|
|
90
|
+
Close without being asked, the moment the choice is handled:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
.pi/skills/impeccable/scripts/impeccable live-server stop
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Stopping removes the injected script and reloads the page once: the user sees the accepted design with no overlay chrome, still served by their dev server. **Never kill or restart the dev server**, including one you started in Step 2.
|
|
97
|
+
|
|
98
|
+
- **The user asks for more variants before you closed**: skip the close, run Step 2 again for the next element (the helper is reused), and close after the last choice.
|
|
99
|
+
- **Interrupted or unsure of the state**: `.pi/skills/impeccable/scripts/impeccable live-status`, then `live-resume`; the journal under `.impeccable/live/sessions/` is canonical.
|
|
100
|
+
|
|
101
|
+
Done when the helper is stopped and the dev site still answers with the accepted design.
|
|
@@ -205,6 +205,11 @@ t('items', { count }) // Handles complex plural rules
|
|
|
205
205
|
- Optimistic updates with rollback
|
|
206
206
|
- Conflict resolution
|
|
207
207
|
|
|
208
|
+
**Interrupted gestures** (custom sliders, drag surfaces, scrollable control strips):
|
|
209
|
+
- A second finger or pointer lands mid-drag: the first drag keeps its pointer or ends cleanly, never jumps to the new one
|
|
210
|
+
- The browser cancels the gesture to scroll (`pointercancel`), capture is lost (`lostpointercapture`), the pointer is released outside the control, or the window loses focus (`blur`) mid-drag: clear the dragging state and release capture
|
|
211
|
+
- After each of these, the next tap or drag works without a reload
|
|
212
|
+
|
|
208
213
|
**Permission states**:
|
|
209
214
|
- No permission to view
|
|
210
215
|
- No permission to edit
|
|
@@ -304,6 +309,7 @@ const throttledScroll = throttle(handleScroll, 100);
|
|
|
304
309
|
- Unit tests for edge cases
|
|
305
310
|
- Integration tests for error scenarios
|
|
306
311
|
- E2E tests for critical paths
|
|
312
|
+
- A behavioral regression for each confirmed gesture fix, when the project's test runner can drive input
|
|
307
313
|
- Visual regression tests
|
|
308
314
|
- Accessibility tests (axe, WAVE)
|
|
309
315
|
|
|
@@ -330,7 +336,10 @@ Test thoroughly with edge cases:
|
|
|
330
336
|
- **Network issues**: Disable internet, throttle connection
|
|
331
337
|
- **Large datasets**: Test with 1000+ items
|
|
332
338
|
- **Concurrent actions**: Click submit 10 times rapidly
|
|
339
|
+
- **Interrupted gestures**: Add a second finger mid-drag, scroll across the control, release outside it, switch windows mid-drag; then drag again
|
|
333
340
|
- **Errors**: Force API errors, test all error states
|
|
334
341
|
- **Empty**: Remove all data, test empty states
|
|
335
342
|
|
|
343
|
+
For gestures, say what produced the evidence (emulated viewport, synthesized touch, which engine, physical device) and name what stayed untested.
|
|
344
|
+
|
|
336
345
|
When edge cases are covered, hand off to `/impeccable polish` for the final pass.
|
|
@@ -16,6 +16,8 @@ Manual `npx impeccable detect` scans use the same project filter config by defau
|
|
|
16
16
|
|
|
17
17
|
Supported harnesses: Claude Code (`.claude/settings.local.json` in the project, which is gitignored so the hook stays machine-local; a hook you move into the shared `settings.json` is honored in place too), Codex (`.codex/hooks.json` in the project), Grok Build (`.grok/hooks/impeccable.json` in the project; requires `/hooks-trust` or `--trust`), and GitHub Copilot (`.github/hooks/impeccable.json` in the project, a team-shared committed file that both the Copilot CLI and the cloud agent read). For the Copilot CLI, repo-level hooks fire once `.github/hooks/impeccable.json` is committed to the repository's default branch.
|
|
18
18
|
|
|
19
|
+
Gemini installs session and completion hooks in `.gemini/settings.json`, merged into the settings already there (comments are tolerated; a commented file is backed up to `settings.json.bak` before the rewrite, and a file that is not valid JSON is left alone). It does not install a per-edit detector hook. The `BeforeTool` hook only rewrites shell commands that run `build-phase`, and only on macOS and Linux; on Windows (where Gemini runs hooks through PowerShell) no session id reaches the shell, so a comp build is not tied to the session and the completion reminder stays silent.
|
|
20
|
+
|
|
19
21
|
## Routing
|
|
20
22
|
|
|
21
23
|
The first argument is the action. Defaults to `status`.
|
|
@@ -101,7 +103,7 @@ Example whole-file exception, for a file that is out of scope entirely:
|
|
|
101
103
|
- Never modify `.impeccable/config.json` or `.impeccable/config.local.json` by hand from this command. Always go through `impeccable hooks` so writes stay validated and the file shape stays consistent. One exception: `detector.extensions` has no admin action, so when the user asks to cover a template stack, edit that one field in `.impeccable/config.json` directly and leave the rest of the file untouched.
|
|
102
104
|
- Do not edit the launcher or the binary behind `impeccable hook` from this flow. Those are skill plumbing.
|
|
103
105
|
- Claude Code, Codex, and GitHub Copilot do not block the edit; they emit a post-edit reminder instead. Disabling stops those reminders.
|
|
104
|
-
- The hook is bundled with the Impeccable skill and installed through project-local manifests: `.claude/settings.local.json`, `.codex/hooks.json`,
|
|
106
|
+
- The hook is bundled with the Impeccable skill and installed through project-local manifests: `.claude/settings.local.json`, `.codex/hooks.json`, `.github/hooks/impeccable.json`, and `.gemini/settings.json`. On Codex, the user must approve the hook via `/hooks` the first time. On GitHub Copilot, the CLI loads `.github/hooks/impeccable.json` once it is committed to the repository's default branch, and the cloud agent reads it from the repo directly.
|
|
105
107
|
|
|
106
108
|
## Failure modes
|
|
107
109
|
|