@bastani/atomic 0.9.28-alpha.3 → 0.9.28-alpha.5

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.
Files changed (311) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/builtin/intercom/CHANGELOG.md +6 -0
  3. package/dist/builtin/intercom/README.md +3 -2
  4. package/dist/builtin/intercom/broker/broker.ts +90 -14
  5. package/dist/builtin/intercom/broker/paths.ts +4 -0
  6. package/dist/builtin/intercom/broker/socket-liveness.ts +32 -0
  7. package/dist/builtin/intercom/broker/socket-replacement-lock.ts +104 -0
  8. package/dist/builtin/intercom/broker/spawn.ts +108 -63
  9. package/dist/builtin/intercom/index.bundle.mjs +114 -61
  10. package/dist/builtin/intercom/package.json +2 -2
  11. package/dist/builtin/mcp/package.json +1 -1
  12. package/dist/builtin/subagents/CHANGELOG.md +6 -0
  13. package/dist/builtin/subagents/package.json +3 -3
  14. package/dist/builtin/subagents/skills/agent-browser/SKILL.md +1 -1
  15. package/dist/builtin/subagents/skills/cua-driver/BROWSER.md +60 -39
  16. package/dist/builtin/subagents/skills/cua-driver/EMBEDDING.md +119 -36
  17. package/dist/builtin/subagents/skills/cua-driver/LINUX.md +225 -183
  18. package/dist/builtin/subagents/skills/cua-driver/MACOS.md +120 -89
  19. package/dist/builtin/subagents/skills/cua-driver/README.md +16 -7
  20. package/dist/builtin/subagents/skills/cua-driver/RECORDING.md +85 -115
  21. package/dist/builtin/subagents/skills/cua-driver/RUNTIME.md +113 -0
  22. package/dist/builtin/subagents/skills/cua-driver/SKILL.md +55 -1071
  23. package/dist/builtin/subagents/skills/cua-driver/VISUAL.md +125 -0
  24. package/dist/builtin/subagents/skills/cua-driver/WINDOWS.md +145 -185
  25. package/dist/builtin/subagents/skills/cua-driver/WORKFLOW.md +173 -0
  26. package/dist/builtin/web-access/package.json +2 -2
  27. package/dist/builtin/workflows/CHANGELOG.md +16 -0
  28. package/dist/builtin/workflows/README.md +1 -1
  29. package/dist/builtin/workflows/builtin/{chunk-aqv8ny38.js → chunk-9ywkdsa9.js} +1 -1
  30. package/dist/builtin/workflows/builtin/{chunk-p6jagvyf.js → chunk-bnz4knhy.js} +1 -1
  31. package/dist/builtin/workflows/builtin/{chunk-br4ac9a3.js → chunk-dx5sjaxe.js} +1 -1
  32. package/dist/builtin/workflows/builtin/{chunk-p3xmajmj.js → chunk-v4scsq3y.js} +41 -13
  33. package/dist/builtin/workflows/builtin/goal.js +2 -2
  34. package/dist/builtin/workflows/builtin/index.js +3 -3
  35. package/dist/builtin/workflows/builtin/ralph.js +2 -2
  36. package/dist/builtin/workflows/package.json +2 -2
  37. package/dist/builtin/workflows/skills/impeccable/SKILL.md +8 -2
  38. package/dist/builtin/workflows/skills/impeccable/reference/adapt.md +6 -0
  39. package/dist/builtin/workflows/skills/impeccable/reference/audit.md +2 -1
  40. package/dist/builtin/workflows/skills/impeccable/reference/component-review.md +63 -0
  41. package/dist/builtin/workflows/skills/impeccable/reference/degraded/asset-producer.md +5 -0
  42. package/dist/builtin/workflows/skills/impeccable/reference/degraded/finish-reviewer.md +1 -1
  43. package/dist/builtin/workflows/skills/impeccable/reference/generate.md +101 -0
  44. package/dist/builtin/workflows/skills/impeccable/reference/harden.md +9 -0
  45. package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +3 -1
  46. package/dist/builtin/workflows/skills/impeccable/reference/mode-operate.md +21 -0
  47. package/dist/builtin/workflows/skills/impeccable/reference/mode-persuade.md +19 -0
  48. package/dist/builtin/workflows/skills/impeccable/reference/mode-read.md +21 -0
  49. package/dist/builtin/workflows/skills/impeccable/reference/new-work.md +19 -12
  50. package/dist/builtin/workflows/skills/impeccable/reference/region-map.md +26 -0
  51. package/dist/builtin/workflows/skills/impeccable/reference/routing.md +1 -1
  52. package/dist/builtin/workflows/skills/impeccable/reference/visualize.md +5 -5
  53. package/dist/builtin/workflows/skills/impeccable/scripts/VERSION +1 -1
  54. package/dist/builtin/workflows/skills/impeccable/scripts/command-metadata.json +4 -0
  55. package/dist/builtin/workflows/skills/impeccable/scripts/impeccable.cmd +2 -2
  56. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser-session.js +5 -1
  57. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +524 -4
  58. package/dist/builtin/workflows/skills/prompt-engineer/SKILL.md +1 -0
  59. package/dist/builtin/workflows/skills/prompt-engineer/references/claude_haiku_5_5.md +81 -0
  60. package/dist/builtin/workflows/src/extension/index.bundle.mjs +38 -14
  61. package/dist/builtin/workflows/src/index.js +38 -14
  62. package/dist/cli/startup-ui.d.ts +3 -2
  63. package/dist/cli/startup-ui.d.ts.map +1 -1
  64. package/dist/cli/startup-ui.js +19 -4
  65. package/dist/cli/startup-ui.js.map +1 -1
  66. package/dist/codemode-worker.js +2 -2
  67. package/dist/core/agent-session-compaction.d.ts +3 -3
  68. package/dist/core/agent-session-compaction.d.ts.map +1 -1
  69. package/dist/core/agent-session-compaction.js +5 -1
  70. package/dist/core/agent-session-compaction.js.map +1 -1
  71. package/dist/core/agent-session-events.d.ts.map +1 -1
  72. package/dist/core/agent-session-events.js +1 -0
  73. package/dist/core/agent-session-events.js.map +1 -1
  74. package/dist/core/agent-session-extension-bindings.d.ts.map +1 -1
  75. package/dist/core/agent-session-extension-bindings.js +4 -0
  76. package/dist/core/agent-session-extension-bindings.js.map +1 -1
  77. package/dist/core/agent-session-methods.d.ts +6 -1
  78. package/dist/core/agent-session-methods.d.ts.map +1 -1
  79. package/dist/core/agent-session-methods.js.map +1 -1
  80. package/dist/core/agent-session-prompt.d.ts.map +1 -1
  81. package/dist/core/agent-session-prompt.js +3 -2
  82. package/dist/core/agent-session-prompt.js.map +1 -1
  83. package/dist/core/agent-session-runtime.d.ts +5 -1
  84. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  85. package/dist/core/agent-session-runtime.js +13 -9
  86. package/dist/core/agent-session-runtime.js.map +1 -1
  87. package/dist/core/agent-session-types.d.ts +1 -0
  88. package/dist/core/agent-session-types.d.ts.map +1 -1
  89. package/dist/core/agent-session-types.js.map +1 -1
  90. package/dist/core/agent-session.d.ts +1 -0
  91. package/dist/core/agent-session.d.ts.map +1 -1
  92. package/dist/core/agent-session.js.map +1 -1
  93. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  94. package/dist/core/export-html/tool-renderer.js +2 -0
  95. package/dist/core/export-html/tool-renderer.js.map +1 -1
  96. package/dist/core/extensions/agent-events.d.ts +2 -0
  97. package/dist/core/extensions/agent-events.d.ts.map +1 -1
  98. package/dist/core/extensions/agent-events.js.map +1 -1
  99. package/dist/core/extensions/context-types.d.ts +2 -0
  100. package/dist/core/extensions/context-types.d.ts.map +1 -1
  101. package/dist/core/extensions/context-types.js.map +1 -1
  102. package/dist/core/extensions/mcp-server-registry.d.ts +4 -1
  103. package/dist/core/extensions/mcp-server-registry.d.ts.map +1 -1
  104. package/dist/core/extensions/mcp-server-registry.js +7 -4
  105. package/dist/core/extensions/mcp-server-registry.js.map +1 -1
  106. package/dist/core/extensions/runner.d.ts +3 -0
  107. package/dist/core/extensions/runner.d.ts.map +1 -1
  108. package/dist/core/extensions/runner.js +19 -0
  109. package/dist/core/extensions/runner.js.map +1 -1
  110. package/dist/core/extensions/session-events.d.ts +2 -0
  111. package/dist/core/extensions/session-events.d.ts.map +1 -1
  112. package/dist/core/extensions/session-events.js.map +1 -1
  113. package/dist/core/extensions/tool-types.d.ts +2 -0
  114. package/dist/core/extensions/tool-types.d.ts.map +1 -1
  115. package/dist/core/extensions/tool-types.js.map +1 -1
  116. package/dist/core/fast-model-variants.d.ts.map +1 -1
  117. package/dist/core/fast-model-variants.js +3 -2
  118. package/dist/core/fast-model-variants.js.map +1 -1
  119. package/dist/core/model-resolver-defaults.d.ts.map +1 -1
  120. package/dist/core/model-resolver-defaults.js +2 -0
  121. package/dist/core/model-resolver-defaults.js.map +1 -1
  122. package/dist/core/nested-tool-calls.d.ts +1 -0
  123. package/dist/core/nested-tool-calls.d.ts.map +1 -1
  124. package/dist/core/nested-tool-calls.js +1 -0
  125. package/dist/core/nested-tool-calls.js.map +1 -1
  126. package/dist/core/provider-alias.d.ts.map +1 -1
  127. package/dist/core/provider-alias.js +8 -0
  128. package/dist/core/provider-alias.js.map +1 -1
  129. package/dist/core/provider-composer-internal.d.ts.map +1 -1
  130. package/dist/core/provider-composer-internal.js +6 -3
  131. package/dist/core/provider-composer-internal.js.map +1 -1
  132. package/dist/core/resource-loader-reload.d.ts.map +1 -1
  133. package/dist/core/resource-loader-reload.js +1 -0
  134. package/dist/core/resource-loader-reload.js.map +1 -1
  135. package/dist/core/resource-loader-types.d.ts +1 -0
  136. package/dist/core/resource-loader-types.d.ts.map +1 -1
  137. package/dist/core/resource-loader-types.js.map +1 -1
  138. package/dist/core/settings-types.js.map +1 -1
  139. package/dist/core/tools/bash.d.ts.map +1 -1
  140. package/dist/core/tools/bash.js +7 -3
  141. package/dist/core/tools/bash.js.map +1 -1
  142. package/dist/core/tools/edit.js +1 -1
  143. package/dist/core/tools/edit.js.map +1 -1
  144. package/dist/extensions/codemode/execute.d.ts.map +1 -1
  145. package/dist/extensions/codemode/execute.js +55 -7
  146. package/dist/extensions/codemode/execute.js.map +1 -1
  147. package/dist/extensions/codemode/index.d.ts.map +1 -1
  148. package/dist/extensions/codemode/index.js +7 -0
  149. package/dist/extensions/codemode/index.js.map +1 -1
  150. package/dist/extensions/codemode/tool.d.ts +2 -0
  151. package/dist/extensions/codemode/tool.d.ts.map +1 -1
  152. package/dist/extensions/codemode/tool.js +2 -0
  153. package/dist/extensions/codemode/tool.js.map +1 -1
  154. package/dist/extensions/herdr/index.d.ts.map +1 -1
  155. package/dist/extensions/herdr/index.js +20 -2
  156. package/dist/extensions/herdr/index.js.map +1 -1
  157. package/dist/extensions/herdr/pane-owner.d.ts +7 -0
  158. package/dist/extensions/herdr/pane-owner.d.ts.map +1 -1
  159. package/dist/extensions/herdr/pane-owner.js +53 -11
  160. package/dist/extensions/herdr/pane-owner.js.map +1 -1
  161. package/dist/index.d.ts +1 -1
  162. package/dist/index.d.ts.map +1 -1
  163. package/dist/index.js.map +1 -1
  164. package/dist/main-deferred-startup.d.ts +8 -0
  165. package/dist/main-deferred-startup.d.ts.map +1 -1
  166. package/dist/main-deferred-startup.js +6 -0
  167. package/dist/main-deferred-startup.js.map +1 -1
  168. package/dist/main.d.ts.map +1 -1
  169. package/dist/main.js +11 -3
  170. package/dist/main.js.map +1 -1
  171. package/dist/modes/interactive/components/bash-execution.d.ts +5 -1
  172. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  173. package/dist/modes/interactive/components/bash-execution.js +17 -14
  174. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  175. package/dist/modes/interactive/components/branch-summary-message.d.ts +2 -1
  176. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  177. package/dist/modes/interactive/components/branch-summary-message.js +5 -2
  178. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  179. package/dist/modes/interactive/components/chat-message-renderer.d.ts +1 -0
  180. package/dist/modes/interactive/components/chat-message-renderer.d.ts.map +1 -1
  181. package/dist/modes/interactive/components/chat-message-renderer.js +19 -8
  182. package/dist/modes/interactive/components/chat-message-renderer.js.map +1 -1
  183. package/dist/modes/interactive/components/compaction-boundary-message.d.ts +3 -2
  184. package/dist/modes/interactive/components/compaction-boundary-message.d.ts.map +1 -1
  185. package/dist/modes/interactive/components/compaction-boundary-message.js +7 -4
  186. package/dist/modes/interactive/components/compaction-boundary-message.js.map +1 -1
  187. package/dist/modes/interactive/components/custom-entry.d.ts +3 -1
  188. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  189. package/dist/modes/interactive/components/custom-entry.js +8 -2
  190. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  191. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  192. package/dist/modes/interactive/components/custom-message.js +1 -0
  193. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  194. package/dist/modes/interactive/components/settings-selector-items.js +1 -1
  195. package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
  196. package/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -1
  197. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  198. package/dist/modes/interactive/components/skill-invocation-message.js +5 -2
  199. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  200. package/dist/modes/interactive/components/tool-execution.d.ts +4 -0
  201. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  202. package/dist/modes/interactive/components/tool-execution.js +10 -0
  203. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  204. package/dist/modes/interactive/interactive-agent-events.js +3 -1
  205. package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
  206. package/dist/modes/interactive/interactive-auth-login.js +6 -0
  207. package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
  208. package/dist/modes/interactive/interactive-auth-routing.js +2 -2
  209. package/dist/modes/interactive/interactive-auth-routing.js.map +1 -1
  210. package/dist/modes/interactive/interactive-bash-compact.js +2 -2
  211. package/dist/modes/interactive/interactive-bash-compact.js.map +1 -1
  212. package/dist/modes/interactive/interactive-extension-dialogs.js +19 -2
  213. package/dist/modes/interactive/interactive-extension-dialogs.js.map +1 -1
  214. package/dist/modes/interactive/interactive-mode-base.d.ts +4 -0
  215. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  216. package/dist/modes/interactive/interactive-mode-base.js +7 -0
  217. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  218. package/dist/modes/interactive/interactive-mode-helpers.js +1 -1
  219. package/dist/modes/interactive/interactive-mode-helpers.js.map +1 -1
  220. package/dist/modes/interactive/interactive-mode-surface.d.ts +2 -1
  221. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  222. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  223. package/dist/modes/interactive/interactive-mode-types.d.ts +1 -0
  224. package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
  225. package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
  226. package/dist/modes/interactive/interactive-process-lifecycle.js +1 -1
  227. package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
  228. package/dist/modes/interactive/interactive-render-chat.js +7 -5
  229. package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
  230. package/dist/modes/interactive/interactive-selectors.js +8 -1
  231. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  232. package/dist/modes/interactive/interactive-session-runtime.js +1 -0
  233. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  234. package/dist/modes/interactive/interactive-startup-trust.d.ts +6 -0
  235. package/dist/modes/interactive/interactive-startup-trust.d.ts.map +1 -0
  236. package/dist/modes/interactive/interactive-startup-trust.js +15 -0
  237. package/dist/modes/interactive/interactive-startup-trust.js.map +1 -0
  238. package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
  239. package/dist/modes/interactive/interactive-startup.js +4 -0
  240. package/dist/modes/interactive/interactive-startup.js.map +1 -1
  241. package/dist/modes/interactive/program-status-reporter.d.ts +24 -0
  242. package/dist/modes/interactive/program-status-reporter.d.ts.map +1 -0
  243. package/dist/modes/interactive/program-status-reporter.js +96 -0
  244. package/dist/modes/interactive/program-status-reporter.js.map +1 -0
  245. package/dist/modes/interactive-engine/engine-child-liveness.d.ts +1 -0
  246. package/dist/modes/interactive-engine/engine-child-liveness.d.ts.map +1 -1
  247. package/dist/modes/interactive-engine/engine-child-liveness.js +15 -1
  248. package/dist/modes/interactive-engine/engine-child-liveness.js.map +1 -1
  249. package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
  250. package/dist/modes/interactive-engine/engine-custom-ui.js +1 -0
  251. package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
  252. package/dist/modes/interactive-engine/engine-monitor.d.ts +4 -0
  253. package/dist/modes/interactive-engine/engine-monitor.d.ts.map +1 -1
  254. package/dist/modes/interactive-engine/engine-monitor.js +17 -0
  255. package/dist/modes/interactive-engine/engine-monitor.js.map +1 -1
  256. package/dist/modes/interactive-engine/engine-quit-intent.d.ts +16 -0
  257. package/dist/modes/interactive-engine/engine-quit-intent.d.ts.map +1 -0
  258. package/dist/modes/interactive-engine/engine-quit-intent.js +27 -0
  259. package/dist/modes/interactive-engine/engine-quit-intent.js.map +1 -0
  260. package/dist/modes/interactive-engine/engine-render-service.d.ts.map +1 -1
  261. package/dist/modes/interactive-engine/engine-render-service.js +3 -1
  262. package/dist/modes/interactive-engine/engine-render-service.js.map +1 -1
  263. package/dist/modes/interactive-engine/extension-ui-bridge.d.ts +1 -0
  264. package/dist/modes/interactive-engine/extension-ui-bridge.d.ts.map +1 -1
  265. package/dist/modes/interactive-engine/extension-ui-bridge.js +5 -0
  266. package/dist/modes/interactive-engine/extension-ui-bridge.js.map +1 -1
  267. package/dist/modes/interactive-engine/isolated-runtime.d.ts +4 -1
  268. package/dist/modes/interactive-engine/isolated-runtime.d.ts.map +1 -1
  269. package/dist/modes/interactive-engine/isolated-runtime.js +19 -2
  270. package/dist/modes/interactive-engine/isolated-runtime.js.map +1 -1
  271. package/dist/modes/interactive-engine/protocol.d.ts +19 -1
  272. package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
  273. package/dist/modes/interactive-engine/protocol.js +7 -0
  274. package/dist/modes/interactive-engine/protocol.js.map +1 -1
  275. package/dist/modes/interactive-engine/remote-renderer.d.ts +3 -0
  276. package/dist/modes/interactive-engine/remote-renderer.d.ts.map +1 -1
  277. package/dist/modes/interactive-engine/remote-renderer.js +7 -0
  278. package/dist/modes/interactive-engine/remote-renderer.js.map +1 -1
  279. package/dist/modes/rpc/rpc-client.d.ts +11 -0
  280. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  281. package/dist/modes/rpc/rpc-client.js +42 -0
  282. package/dist/modes/rpc/rpc-client.js.map +1 -1
  283. package/dist/modes/rpc/rpc-input-scheduler.js +2 -2
  284. package/dist/modes/rpc/rpc-input-scheduler.js.map +1 -1
  285. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  286. package/dist/modes/rpc/rpc-mode.js +23 -6
  287. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  288. package/dist/modes/rpc/rpc-provider-auth.js +1 -1
  289. package/dist/modes/rpc/rpc-provider-auth.js.map +1 -1
  290. package/docs/codemode.md +10 -6
  291. package/docs/compaction.md +1 -1
  292. package/docs/computer-use.md +9 -9
  293. package/docs/custom-provider/streaming.md +4 -0
  294. package/docs/environment-variables.md +2 -0
  295. package/docs/extensions/api-reference.md +1 -1
  296. package/docs/extensions/authoring.md +2 -0
  297. package/docs/extensions/events.md +8 -1
  298. package/docs/getting-started/first-session.md +1 -1
  299. package/docs/herdr.md +11 -2
  300. package/docs/json.md +6 -1
  301. package/docs/models/evals.md +34 -3
  302. package/docs/models.md +1 -1
  303. package/docs/providers.md +10 -0
  304. package/docs/sdk.md +8 -2
  305. package/docs/settings.md +2 -2
  306. package/docs/skills.md +1 -1
  307. package/docs/terminal-setup.md +14 -0
  308. package/docs/workflows/authoring.md +3 -3
  309. package/examples/extensions/sandbox/package-lock.json +3 -3
  310. package/npm-shrinkwrap.json +67 -67
  311. 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",
3
+ "version": "0.9.28-alpha.5",
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.4"
34
+ "@earendil-works/pi-tui": "^1.1.0"
35
35
  },
36
36
  "peerDependenciesMeta": {
37
37
  "@bastani/atomic": {
@@ -6,6 +6,22 @@ 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.5] - 2026-10-08
10
+
11
+ ### Fixed
12
+
13
+ - Fixed managed PostgreSQL health checks failing a workflow stage on a healthy but busy host: an unanswered check now retries with a short backoff for up to 15 seconds, the connection limit is 3 seconds instead of 1, and the "did not answer a health check in time" diagnostic clears once PostgreSQL answers again ([#3491](https://github.com/bastani-inc/atomic/issues/3491))
14
+
15
+ ## [0.9.28-alpha.4] - 2026-10-07
16
+
17
+ ### Added
18
+
19
+ - 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.
20
+
21
+ ### Changed
22
+
23
+ - 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.
24
+
9
25
  ## [0.9.28-alpha.3] - 2026-10-07
10
26
 
11
27
  ### Changed
@@ -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.3.1 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.
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
 
@@ -37,7 +37,7 @@ import {
37
37
  parseFailureDiagnostics,
38
38
  summarizeReviewConvergence,
39
39
  reverify_consolidated_batch
40
- } from "./chunk-p3xmajmj.js";
40
+ } from "./chunk-v4scsq3y.js";
41
41
  import {
42
42
  VERIFICATION_SCALE
43
43
  } from "./chunk-n1910xc4.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getDurableBackend2,
3
3
  getAvailableDurableBackend2
4
- } from "./chunk-p3xmajmj.js";
4
+ } from "./chunk-v4scsq3y.js";
5
5
  export {
6
6
  getAvailableDurableBackend2 as getAvailableDurableBackend,
7
7
  getDurableBackend2 as getDurableBackend
@@ -39,7 +39,7 @@ import {
39
39
  reviewerFailureText,
40
40
  summarizeReviewConvergence,
41
41
  reverify_consolidated_batch
42
- } from "./chunk-p3xmajmj.js";
42
+ } from "./chunk-v4scsq3y.js";
43
43
  import {
44
44
  fold_usage
45
45
  } from "./chunk-tgt0s5e5.js";
@@ -6542,6 +6542,9 @@ function resolveEmbeddedPostgresTarget(host) {
6542
6542
  // dist/builtin/workflows/src/durable/dbos-postgres-health.ts
6543
6543
  var HEALTH_INTERVAL_MS = 5000;
6544
6544
  var RECOVERY_ATTEMPTS = 3;
6545
+ var MONITORING_PROBE_RETRY_WINDOW_MS = 15000;
6546
+ var MONITORING_PROBE_RETRY_INITIAL_MS = 250;
6547
+ var MONITORING_PROBE_RETRY_MAX_MS = 2000;
6545
6548
  function isMonitoringConnectionTimeout(error) {
6546
6549
  if (!(error instanceof Error))
6547
6550
  return false;
@@ -6569,6 +6572,7 @@ class PostgresHealth {
6569
6572
  attempts = 0;
6570
6573
  nextRecoveryAt = 0;
6571
6574
  failure;
6575
+ failureUnanswered = false;
6572
6576
  healthySinceFailure = false;
6573
6577
  revision = 0;
6574
6578
  listeners = new Set;
@@ -6581,10 +6585,11 @@ class PostgresHealth {
6581
6585
  get endpoint() {
6582
6586
  return this.operations.url?.();
6583
6587
  }
6584
- retainFailure(error) {
6588
+ retainFailure(error, unanswered = false) {
6585
6589
  const message = error instanceof Error ? error.message : String(error);
6586
6590
  const safe = redactedDatabaseMessage(message, this.endpoint);
6587
6591
  this.failure = new Error(safe);
6592
+ this.failureUnanswered = unanswered;
6588
6593
  this.healthySinceFailure = false;
6589
6594
  }
6590
6595
  dependencyFailure(message) {
@@ -6612,7 +6617,7 @@ class PostgresHealth {
6612
6617
  await this.operations.validate?.(client);
6613
6618
  }
6614
6619
  } catch (error) {
6615
- this.retainFailure(error);
6620
+ this.retainFailure(error, isQueryReadTimeout(error));
6616
6621
  if (!isQueryReadTimeout(error)) {
6617
6622
  this.invalidate();
6618
6623
  if (this.endpoint === undefined)
@@ -6650,19 +6655,39 @@ class PostgresHealth {
6650
6655
  }
6651
6656
  async probe() {
6652
6657
  const revision = this.revision;
6658
+ const now = this.operations.now ?? Date.now;
6659
+ const wait = this.operations.wait ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
6653
6660
  let identity;
6654
6661
  try {
6655
6662
  identity = await this.operations.probe();
6656
6663
  } catch (error) {
6657
6664
  if (!(isMonitoringConnectionFailure(error) || isQueryReadTimeout(error)) || this.stopped)
6658
6665
  throw error;
6659
- try {
6660
- identity = await this.operations.probe();
6661
- } catch (retryError) {
6662
- if (isMonitoringConnectionTimeout(retryError) || !isMonitoringConnectionFailure(retryError))
6663
- throw retryError;
6664
- this.retainFailure(retryError);
6665
- return;
6666
+ const deadline = now() + MONITORING_PROBE_RETRY_WINDOW_MS;
6667
+ let delay = MONITORING_PROBE_RETRY_INITIAL_MS;
6668
+ let failure = error;
6669
+ for (;; ) {
6670
+ if (isMonitoringConnectionTimeout(failure) || isQueryReadTimeout(failure)) {
6671
+ if (now() >= deadline)
6672
+ throw failure;
6673
+ await wait(delay);
6674
+ delay = Math.min(delay * 2, MONITORING_PROBE_RETRY_MAX_MS);
6675
+ if (this.stopped)
6676
+ throw failure;
6677
+ }
6678
+ try {
6679
+ identity = await this.operations.probe();
6680
+ break;
6681
+ } catch (retryError) {
6682
+ if (isMonitoringConnectionTimeout(retryError) || isQueryReadTimeout(retryError)) {
6683
+ failure = retryError;
6684
+ continue;
6685
+ }
6686
+ if (!isMonitoringConnectionFailure(retryError))
6687
+ throw retryError;
6688
+ this.retainFailure(retryError);
6689
+ return;
6690
+ }
6666
6691
  }
6667
6692
  }
6668
6693
  if (revision !== this.revision)
@@ -6677,6 +6702,8 @@ class PostgresHealth {
6677
6702
  this.attempts = 0;
6678
6703
  this.nextRecoveryAt = 0;
6679
6704
  this.healthySinceFailure = true;
6705
+ if (this.failureUnanswered)
6706
+ this.failure = undefined;
6680
6707
  return identity.url;
6681
6708
  }
6682
6709
  async refresh() {
@@ -6686,7 +6713,7 @@ class PostgresHealth {
6686
6713
  return ready;
6687
6714
  } catch (error) {
6688
6715
  if (isQueryReadTimeout(error) || isMonitoringConnectionTimeout(error)) {
6689
- this.retainFailure(new Error("Managed PostgreSQL did not answer a health check in time."));
6716
+ this.retainFailure(new Error("Managed PostgreSQL did not answer a health check in time."), true);
6690
6717
  throw this.dependencyFailure("Managed PostgreSQL did not answer a health check in time.");
6691
6718
  }
6692
6719
  this.retainFailure(error);
@@ -6954,6 +6981,7 @@ var POSTGRES_IDENTITY_SQL = `SELECT current_setting('data_directory') AS data_di
6954
6981
  system_identifier::text, current_setting('server_version') AS server_version FROM pg_control_system()`;
6955
6982
  var POSTGRES_TIMEZONE_SQL = "SELECT set_config('timezone_abbreviations', 'Default', true)";
6956
6983
  var POSTGRES_HEALTH_QUERY_TIMEOUT_MS = 3000;
6984
+ var POSTGRES_HEALTH_CONNECT_TIMEOUT_MS = 3000;
6957
6985
  async function probePostgresTimezoneData(port) {
6958
6986
  const client = new Client({
6959
6987
  host: "127.0.0.1",
@@ -6962,7 +6990,7 @@ async function probePostgresTimezoneData(port) {
6962
6990
  password: "atomic",
6963
6991
  database: "postgres",
6964
6992
  ssl: false,
6965
- connectionTimeoutMillis: 1000,
6993
+ connectionTimeoutMillis: POSTGRES_HEALTH_CONNECT_TIMEOUT_MS,
6966
6994
  query_timeout: POSTGRES_HEALTH_QUERY_TIMEOUT_MS,
6967
6995
  statement_timeout: POSTGRES_HEALTH_QUERY_TIMEOUT_MS
6968
6996
  });
@@ -6982,7 +7010,7 @@ async function probePostgresIdentity(port) {
6982
7010
  password: "atomic",
6983
7011
  database: "postgres",
6984
7012
  ssl: false,
6985
- connectionTimeoutMillis: 1000,
7013
+ connectionTimeoutMillis: POSTGRES_HEALTH_CONNECT_TIMEOUT_MS,
6986
7014
  query_timeout: POSTGRES_HEALTH_QUERY_TIMEOUT_MS,
6987
7015
  statement_timeout: POSTGRES_HEALTH_QUERY_TIMEOUT_MS
6988
7016
  });
@@ -9894,7 +9922,7 @@ function createPendingStageDeliveryStoreMethods(context) {
9894
9922
  const run = context.findRun(input.runId);
9895
9923
  if (run === undefined)
9896
9924
  return;
9897
- const { getAvailableDurableBackend } = await import("./chunk-p6jagvyf.js");
9925
+ const { getAvailableDurableBackend } = await import("./chunk-bnz4knhy.js");
9898
9926
  const availableBackend = getAvailableDurableBackend();
9899
9927
  const backend = availableBackend === undefined ? undefined : durableBackendForRun(availableBackend, context.state.runs, input.runId);
9900
9928
  const receipt = await backend?.readSettledPendingStageMessage?.(input.runId, input.message.id);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  goal_default
3
- } from "./chunk-aqv8ny38.js";
4
- import"./chunk-p3xmajmj.js";
3
+ } from "./chunk-9ywkdsa9.js";
4
+ import"./chunk-v4scsq3y.js";
5
5
  import"./chunk-2377r57g.js";
6
6
  import"./chunk-z0d03ktm.js";
7
7
  import"./chunk-n1910xc4.js";
@@ -16,8 +16,8 @@ import {
16
16
  } from "./chunk-kb7s3gx2.js";
17
17
  import {
18
18
  goal_default
19
- } from "./chunk-aqv8ny38.js";
20
- import"./chunk-p3xmajmj.js";
19
+ } from "./chunk-9ywkdsa9.js";
20
+ import"./chunk-v4scsq3y.js";
21
21
  import"./chunk-z0d03ktm.js";
22
22
  import {
23
23
  open_claude_design_default
@@ -27,7 +27,7 @@ import {
27
27
  } from "./chunk-94f8zfz1.js";
28
28
  import {
29
29
  ralph_default
30
- } from "./chunk-br4ac9a3.js";
30
+ } from "./chunk-dx5sjaxe.js";
31
31
  import {
32
32
  tournament_default
33
33
  } from "./chunk-wf876n16.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ralph_default
3
- } from "./chunk-br4ac9a3.js";
4
- import"./chunk-p3xmajmj.js";
3
+ } from "./chunk-dx5sjaxe.js";
4
+ import"./chunk-v4scsq3y.js";
5
5
  import"./chunk-2377r57g.js";
6
6
  import"./chunk-z0d03ktm.js";
7
7
  import"./chunk-n1910xc4.js";
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/workflows",
3
- "version": "0.9.28-alpha.3",
3
+ "version": "0.9.28-alpha.5",
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.4",
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.3.1
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, generate alternatives | [reference/live.md](reference/live.md) |
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