pyweb-stack 0.6.0__tar.gz → 0.6.2__tar.gz

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 (370) hide show
  1. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/CHANGELOG.md +112 -0
  2. {pyweb_stack-0.6.0/pyweb_stack.egg-info → pyweb_stack-0.6.2}/PKG-INFO +15 -4
  3. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/README.md +14 -3
  4. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/THREAT_MODEL.md +15 -0
  5. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/01-introduction.md +4 -0
  6. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/02-quickstart.md +13 -1
  7. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/14-cli.md +46 -7
  8. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/16-limitations-roadmap.md +12 -4
  9. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/17-ai-assistants.md +22 -1
  10. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/27-upgrading.md +1 -0
  11. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/29-performance.md +11 -1
  12. pyweb_stack-0.6.2/docs/35-dev-loop.md +151 -0
  13. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyproject.toml +2 -2
  14. pyweb_stack-0.6.2/pyweb/_templates.py +18 -0
  15. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/app_loader.py +53 -9
  16. pyweb_stack-0.6.2/pyweb/assist.py +394 -0
  17. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/bench.py +68 -1
  18. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/cli/__init__.py +354 -45
  19. pyweb_stack-0.6.2/pyweb/compiler/diskcache.py +72 -0
  20. pyweb_stack-0.6.2/pyweb/compiler/errors.py +223 -0
  21. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/lower.py +12 -3
  22. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/parser.py +56 -0
  23. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/pipeline.py +64 -2
  24. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/pyjs.py +17 -3
  25. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/devlink.py +37 -3
  26. pyweb_stack-0.6.2/pyweb/devopen.py +92 -0
  27. pyweb_stack-0.6.2/pyweb/doctor.py +303 -0
  28. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/hosting.py +4 -3
  29. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/lsp_ui.py +19 -2
  30. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/mcp.py +92 -49
  31. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/mcp_tools.py +22 -0
  32. pyweb_stack-0.6.2/pyweb/qr.py +273 -0
  33. pyweb_stack-0.6.2/pyweb/runtime/browser/dev/assist.js +156 -0
  34. pyweb_stack-0.6.2/pyweb/runtime/browser/dev/inspect.js +138 -0
  35. pyweb_stack-0.6.2/pyweb/runtime/browser/dev/reload.js +180 -0
  36. pyweb_stack-0.6.2/pyweb/runtime/browser/dev/timeline.js +144 -0
  37. pyweb_stack-0.6.2/pyweb/runtime/browser/dev/welcome.js +46 -0
  38. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/runtime.js +6 -4
  39. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/server/__init__.py +4 -2
  40. pyweb_stack-0.6.2/pyweb/share.py +172 -0
  41. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/telemetry/devtools.py +4 -1
  42. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/extending.py +7 -0
  43. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/upgrade.py +12 -1
  44. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2/pyweb_stack.egg-info}/PKG-INFO +15 -4
  45. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb_stack.egg-info/SOURCES.txt +22 -0
  46. pyweb_stack-0.6.2/tests/test_assist.py +243 -0
  47. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_auth.py +2 -1
  48. pyweb_stack-0.6.2/tests/test_cli_test.py +44 -0
  49. pyweb_stack-0.6.2/tests/test_compile_cache.py +149 -0
  50. pyweb_stack-0.6.2/tests/test_dev_reload.py +55 -0
  51. pyweb_stack-0.6.2/tests/test_devopen.py +87 -0
  52. pyweb_stack-0.6.2/tests/test_doctor.py +128 -0
  53. pyweb_stack-0.6.2/tests/test_error_messages.py +164 -0
  54. pyweb_stack-0.6.2/tests/test_first_run.py +119 -0
  55. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_forms_v5.py +2 -1
  56. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_mcp.py +3 -1
  57. pyweb_stack-0.6.2/tests/test_qr.py +103 -0
  58. pyweb_stack-0.6.2/tests/test_share.py +153 -0
  59. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_trusted_types.py +8 -0
  60. pyweb_stack-0.6.0/pyweb/_templates.py +0 -3
  61. pyweb_stack-0.6.0/pyweb/compiler/errors.py +0 -29
  62. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/LICENSE +0 -0
  63. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/MANIFEST.in +0 -0
  64. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/03-tutorial.md +0 -0
  65. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/04-pyweb-files.md +0 -0
  66. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/05-reactivity.md +0 -0
  67. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/06-server-functions.md +0 -0
  68. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/07-browser-python.md +0 -0
  69. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/08-pages-routing-assets.md +0 -0
  70. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/09-data.md +0 -0
  71. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/10-auth.md +0 -0
  72. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/11-testing.md +0 -0
  73. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/12-deployment.md +0 -0
  74. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/13-security.md +0 -0
  75. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/15-toolkit.md +0 -0
  76. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/18-npm-packages.md +0 -0
  77. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/19-layouts-navigation.md +0 -0
  78. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/20-ai-apps.md +0 -0
  79. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/21-live-data.md +0 -0
  80. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/22-recipe-web3.md +0 -0
  81. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/23-forms.md +0 -0
  82. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/24-jobs.md +0 -0
  83. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/25-scaling.md +0 -0
  84. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/26-observability.md +0 -0
  85. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/28-saas-tutorial.md +0 -0
  86. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/30-teams.md +0 -0
  87. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/31-pwa-push.md +0 -0
  88. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/32-desktop.md +0 -0
  89. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/33-webhooks-files.md +0 -0
  90. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/docs/34-ui-and-motion.md +0 -0
  91. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/__init__.py +0 -0
  92. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/_speedups.py +0 -0
  93. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/a11y.py +0 -0
  94. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ai/guide.md +0 -0
  95. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/app.py +0 -0
  96. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/asgi.py +0 -0
  97. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/auth.py +0 -0
  98. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/__init__.py +0 -0
  99. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/admin.py +0 -0
  100. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/html.py +0 -0
  101. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/models.py +0 -0
  102. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/oauth.py +0 -0
  103. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/orgpages.py +0 -0
  104. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/orgs.py +0 -0
  105. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/pages.py +0 -0
  106. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/passwords.py +0 -0
  107. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/privacy.py +0 -0
  108. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/teams.py +0 -0
  109. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/throttle.py +0 -0
  110. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/tokens.py +0 -0
  111. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/authkit/webauthn.py +0 -0
  112. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/browser.py +0 -0
  113. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/build.py +0 -0
  114. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/cache.py +0 -0
  115. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/cli/__main__.py +0 -0
  116. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/__init__.py +0 -0
  117. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/ast.py +0 -0
  118. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/codegen/__init__.py +0 -0
  119. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/codegen/ir.py +0 -0
  120. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/compiler/rpc.py +0 -0
  121. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/config.py +0 -0
  122. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/context.py +0 -0
  123. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/csp_report.py +0 -0
  124. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/css.py +0 -0
  125. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/db/__init__.py +0 -0
  126. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/db/dialect.py +0 -0
  127. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/db/migrate.py +0 -0
  128. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/db/rls.py +0 -0
  129. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/db/schema.py +0 -0
  130. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/db/seeds.py +0 -0
  131. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/decorators.py +0 -0
  132. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/deploy/__init__.py +0 -0
  133. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/deploy/legacy.py +0 -0
  134. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/deploy/plan.py +0 -0
  135. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/deploy/targets.py +0 -0
  136. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/deprecation.py +0 -0
  137. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/desktop/__init__.py +0 -0
  138. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/desktop/gate.py +0 -0
  139. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/desktop/package.py +0 -0
  140. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/desktop/shell.py +0 -0
  141. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/dts.py +0 -0
  142. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/fieldcrypt.py +0 -0
  143. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/filegc.py +0 -0
  144. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/forms.py +0 -0
  145. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/http.py +0 -0
  146. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/__init__.py +0 -0
  147. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/builtin.py +0 -0
  148. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/core.py +0 -0
  149. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/db.py +0 -0
  150. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/legacy.py +0 -0
  151. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/memory.py +0 -0
  152. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/redis.py +0 -0
  153. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/schedule.py +0 -0
  154. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/jobs/worker.py +0 -0
  155. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/keys.py +0 -0
  156. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/livedata.py +0 -0
  157. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/livetable.py +0 -0
  158. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/lsp.py +0 -0
  159. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/lsp_data.py +0 -0
  160. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/lsp_teams.py +0 -0
  161. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/mail.py +0 -0
  162. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/markdown.py +0 -0
  163. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/mcp_http.py +0 -0
  164. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/models/__init__.py +0 -0
  165. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/models/fields.py +0 -0
  166. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/models/query.py +0 -0
  167. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/models/relations.py +0 -0
  168. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/motion.py +0 -0
  169. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/net/__init__.py +0 -0
  170. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/net/http.py +0 -0
  171. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/net/live.py +0 -0
  172. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/net/server.py +0 -0
  173. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/net/ws.py +0 -0
  174. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/observability.py +0 -0
  175. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/openapi.py +0 -0
  176. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/packages.py +0 -0
  177. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/platform.py +0 -0
  178. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/plugins.py +0 -0
  179. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/profile.py +0 -0
  180. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/push.py +0 -0
  181. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/pwa.py +0 -0
  182. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/py.typed +0 -0
  183. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/realtime.py +0 -0
  184. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/rooms.py +0 -0
  185. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/rpc.py +0 -0
  186. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/rules.py +0 -0
  187. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/auth.js +0 -0
  188. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/desktop.js +0 -0
  189. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/forms.js +0 -0
  190. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/live.js +0 -0
  191. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/markdown.js +0 -0
  192. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/motion-api.js +0 -0
  193. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/motion-count.js +0 -0
  194. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/motion-drag.js +0 -0
  195. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/motion-layout.js +0 -0
  196. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/motion-math.js +0 -0
  197. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/motion.js +0 -0
  198. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/pwa.js +0 -0
  199. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/sw.js +0 -0
  200. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/accordion.js +0 -0
  201. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/calendar.js +0 -0
  202. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/carousel.js +0 -0
  203. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/checkbox.js +0 -0
  204. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/collapsible.js +0 -0
  205. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/combobox.js +0 -0
  206. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/command.js +0 -0
  207. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/context-menu.js +0 -0
  208. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/core.js +0 -0
  209. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/dialog.js +0 -0
  210. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/hover-card.js +0 -0
  211. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/index.js +0 -0
  212. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/listbox.js +0 -0
  213. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/menu.js +0 -0
  214. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/menubar.js +0 -0
  215. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/navigation-menu.js +0 -0
  216. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/otp.js +0 -0
  217. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/popover.js +0 -0
  218. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/radio-group.js +0 -0
  219. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/resizable.js +0 -0
  220. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/select.js +0 -0
  221. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/sidebar.js +0 -0
  222. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/slider.js +0 -0
  223. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/tabs.js +0 -0
  224. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/toaster.js +0 -0
  225. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/toggle-group.js +0 -0
  226. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/toggle.js +0 -0
  227. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/browser/ui/tooltip.js +0 -0
  228. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/runtime/server/argcheck.py +0 -0
  229. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/sbom.py +0 -0
  230. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/secret_scan.py +0 -0
  231. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/security.py +0 -0
  232. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/serve.py +0 -0
  233. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ssr.py +0 -0
  234. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ssr_codegen.py +0 -0
  235. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/storage.py +0 -0
  236. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/sync.py +0 -0
  237. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/telemetry/__init__.py +0 -0
  238. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/telemetry/instruments.py +0 -0
  239. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/telemetry/logs.py +0 -0
  240. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/telemetry/metrics.py +0 -0
  241. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/telemetry/tracing.py +0 -0
  242. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/ai-chat.pyweb +0 -0
  243. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/app.css +0 -0
  244. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/auth.pyweb +0 -0
  245. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/blog.pyweb +0 -0
  246. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/chat.pyweb +0 -0
  247. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/counter.pyweb +0 -0
  248. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/desktop/app.pyweb +0 -0
  249. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/desktop/test_app.py +0 -0
  250. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/saas/app.pyweb +0 -0
  251. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/saas/seeds.py +0 -0
  252. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/saas/test_app.py +0 -0
  253. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/templates/todo.pyweb +0 -0
  254. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/tenancy.py +0 -0
  255. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/testing.py +0 -0
  256. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/__init__.py +0 -0
  257. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/cli.py +0 -0
  258. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/button.pyweb +0 -0
  259. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/card.pyweb +0 -0
  260. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/carousel.pyweb +0 -0
  261. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/chart.pyweb +0 -0
  262. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/command.pyweb +0 -0
  263. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/controls.pyweb +0 -0
  264. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/data.pyweb +0 -0
  265. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/date.pyweb +0 -0
  266. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/dialog.pyweb +0 -0
  267. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/disclosure.pyweb +0 -0
  268. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/display.pyweb +0 -0
  269. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/layout.pyweb +0 -0
  270. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/menu.pyweb +0 -0
  271. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/overlay.pyweb +0 -0
  272. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/kit/style.pyweb +0 -0
  273. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/serve.py +0 -0
  274. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/source_edit.py +0 -0
  275. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/static/ui.css +0 -0
  276. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/ui/theme.py +0 -0
  277. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/uploads.py +0 -0
  278. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb/webhooks.py +0 -0
  279. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb_stack.egg-info/dependency_links.txt +0 -0
  280. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb_stack.egg-info/entry_points.txt +0 -0
  281. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb_stack.egg-info/requires.txt +0 -0
  282. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/pyweb_stack.egg-info/top_level.txt +0 -0
  283. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/setup.cfg +0 -0
  284. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/setup.py +0 -0
  285. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_account_privacy.py +0 -0
  286. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_api_tokens.py +0 -0
  287. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_auth_contract.py +0 -0
  288. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_auth_security.py +0 -0
  289. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_auth_sessions.py +0 -0
  290. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_auth_v1.py +0 -0
  291. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_authkit.py +0 -0
  292. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_authkit_units.py +0 -0
  293. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_backplane.py +0 -0
  294. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_browser_build.py +0 -0
  295. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_budget.py +0 -0
  296. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_cli_deploy.py +0 -0
  297. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_codegen.py +0 -0
  298. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_compiler.py +0 -0
  299. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_cron.py +0 -0
  300. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_customise.py +0 -0
  301. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_data_layer.py +0 -0
  302. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_db_production.py +0 -0
  303. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_deploy_upload_render.py +0 -0
  304. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_deploy_v5.py +0 -0
  305. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_desktop.py +0 -0
  306. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_docs.py +0 -0
  307. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_dts.py +0 -0
  308. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_dx_v5.py +0 -0
  309. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_e2e.py +0 -0
  310. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_encrypted_fields.py +0 -0
  311. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_examples.py +0 -0
  312. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_filegc.py +0 -0
  313. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_forms_security_obs.py +0 -0
  314. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_fuzz_requests.py +0 -0
  315. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_http_fetch.py +0 -0
  316. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_jobs_app.py +0 -0
  317. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_jobs_cache_realtime.py +0 -0
  318. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_jobs_v5.py +0 -0
  319. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_keys_sessions.py +0 -0
  320. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_live_patches.py +0 -0
  321. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_livedata.py +0 -0
  322. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_lsp.py +0 -0
  323. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_lsp_teams.py +0 -0
  324. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_markdown.py +0 -0
  325. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_mcp_teams.py +0 -0
  326. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_mcp_v6.py +0 -0
  327. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_migrations_property.py +0 -0
  328. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_migrations_v5.py +0 -0
  329. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_models_db.py +0 -0
  330. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_motion.py +0 -0
  331. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_multifile.py +0 -0
  332. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_multipage.py +0 -0
  333. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_net.py +0 -0
  334. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_observability.py +0 -0
  335. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_openapi.py +0 -0
  336. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_org_pages.py +0 -0
  337. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_packages.py +0 -0
  338. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_parser.py +0 -0
  339. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_parser_v1.py +0 -0
  340. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_plugins_platform_bench.py +0 -0
  341. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_production_gaps.py +0 -0
  342. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_profile.py +0 -0
  343. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_push.py +0 -0
  344. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_pwa.py +0 -0
  345. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_pyjs_semantics.py +0 -0
  346. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_rate_per_function.py +0 -0
  347. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_reactivity.py +0 -0
  348. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_realtime_transport.py +0 -0
  349. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_reference_apps.py +0 -0
  350. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_request_hardening.py +0 -0
  351. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_rpc_placement.py +0 -0
  352. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_rpc_production.py +0 -0
  353. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_runtime_signals.py +0 -0
  354. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_sbom.py +0 -0
  355. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_secret_scan.py +0 -0
  356. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_server_db.py +0 -0
  357. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_speedups.py +0 -0
  358. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_ssr_codegen.py +0 -0
  359. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_static_hashing.py +0 -0
  360. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_static_serving.py +0 -0
  361. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_streaming.py +0 -0
  362. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_sync_live.py +0 -0
  363. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_systems.py +0 -0
  364. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_telemetry.py +0 -0
  365. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_tenancy.py +0 -0
  366. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_testing_orgs.py +0 -0
  367. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_threat_model.py +0 -0
  368. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_ui_kit.py +0 -0
  369. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_webhooks.py +0 -0
  370. {pyweb_stack-0.6.0 → pyweb_stack-0.6.2}/tests/test_website.py +0 -0
@@ -6,6 +6,118 @@ project uses [semantic versioning](https://semver.org).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.6.2]
10
+
11
+ The dev loop. Saves update the open page in place with every page and
12
+ component keeping its state, any element opens its own line in your
13
+ editor, error pages fix themselves with AI (your assistant's model through
14
+ MCP, or your own key), a timeline steps back through every change, and
15
+ `pyweb dev --share` gives someone a link to try what you're building. All
16
+ of it lives in `pyweb dev`: production output is unchanged and there is
17
+ nothing to change in your apps. See [The dev loop](docs/35-dev-loop.md).
18
+
19
+ ### Added
20
+ - **Hot reload without a page load.** A save swaps the page in place
21
+ through client navigation: no reload, no flash. Page variables,
22
+ component variables (each instance keeps its own), form fields, scroll,
23
+ focus and the selection stay. A stylesheet-only save swaps just that
24
+ stylesheet. When the page changed too much to swap, it reloads with the
25
+ same state, also after a compile error is fixed.
26
+ - **Click to source.** Hold Alt to see where any element comes from;
27
+ Alt-click opens that line in your editor (`PYWEB_EDITOR`, else VS Code,
28
+ Cursor, Windsurf, Zed or Sublime Text, else a `vscode://` link) and
29
+ shows the **inspector**: the components around it with their live
30
+ variables, which you can edit.
31
+ - **Fix with AI and Edit with AI.** Compile error pages and dev 500 pages
32
+ have Fix with AI; Alt+Shift-click any element to ask for a change. The
33
+ answer is a compiled diff of one app file: Apply writes it (refused if
34
+ the file changed since) and Undo puts it back (`.pyweb/history/`). It is
35
+ answered by the assistant connected through `pyweb mcp` when its app
36
+ supports MCP sampling, else `ANTHROPIC_API_KEY` or
37
+ `OPENAI_API_KEY`/`OPENAI_BASE_URL`, else the page offers the prompt to
38
+ copy. Credentials in what's sent are replaced by placeholders and put
39
+ back in the answer.
40
+ - **Time-travel timeline.** The toolbar's Timeline tab records every change
41
+ to the page's variables with its cause (a click, typing, a server call);
42
+ a slider steps back through them with the page paused, and Resume
43
+ returns to now.
44
+ - **`pyweb dev --share`**: a temporary public link (cloudflared, else
45
+ localhost.run) with a QR code. The link's token sets a cookie that every
46
+ request through the tunnel needs; guests get the app and hot reload, not
47
+ your tools.
48
+ - **A better first five minutes.** `pyweb new` with no name asks for the
49
+ name, a starter and a colour preset (`--theme` without asking); `pyweb
50
+ dev` opens the browser, prints the network URL with a QR code for a phone
51
+ with `--host 0.0.0.0`, and shows a one-time Welcome panel with what to
52
+ try and how to connect your assistant.
53
+ - **A faster first start.** Parse results and compiled code are cached on
54
+ disk (`~/.cache/pyweb`; `PYWEB_CACHE=0` turns it off): loading the saas
55
+ example in a fresh process went from about 340 to 210 ms.
56
+ `pyweb.bench --system` reports `cold_dev_ms`.
57
+ - MCP: the `pyweb_assist_requests` tool and the `fix_errors` prompt;
58
+ `pyweb mcp` answers the page's AI requests through sampling.
59
+
60
+ ### Changed
61
+ - `pyweb dev`'s toolbar and its `/__pyweb/dev/` endpoints answer only the
62
+ person running it: a request from this machine to a loopback address.
63
+ Visitors from the network (`--host 0.0.0.0`) or a share link get hot
64
+ reload only.
65
+ - The runtime is 25 bytes bigger (gzip) for the dev hooks; nothing runs
66
+ in production.
67
+
68
+ ## [0.6.1]
69
+
70
+ Better error messages, `pyweb doctor`, a `pyweb dev` that keeps your place
71
+ when it reloads, much faster reloads and tests, and fixes found by
72
+ installing 0.6.0 from PyPI and putting every template through every
73
+ command. Nothing to change in your apps.
74
+
75
+ ### Added
76
+ - **Better error messages.** Compile errors show the line with a caret under
77
+ the problem, suggest the name you meant (a prop, component, variable,
78
+ server function argument, kit variant or motion preset: "did you mean
79
+ 'name'?"), and link the docs page that explains them. The CLI, the
80
+ `pyweb dev` overlay and the MCP tools (`frame`, `docs` fields) show the
81
+ same. When page code raises in `pyweb dev`, the error page starts with the
82
+ frames in your own files and their source lines.
83
+ - **`pyweb dev` keeps your place when it reloads.** After a save, the page
84
+ comes back with its variables (a counter's count, a bound input's text),
85
+ unbound form fields, scroll position and focus as they were. A variable
86
+ whose type changed, or that was renamed, starts over; add `?fresh` to the
87
+ URL to start everything over. Production builds only grow by the names
88
+ of page variables.
89
+ - **`pyweb doctor`** checks the project and the machine in one go: Python,
90
+ whether the app compiles, optional packages the app needs, the database
91
+ and pending migrations, Redis, secrets written in the source, changes
92
+ `pyweb upgrade` wants, a stale dev server link, tests, the port and the
93
+ editor extension, each with a fix (`--production` adds the production
94
+ settings, `--json` for CI). Assistants get it as the `pyweb_doctor` tool.
95
+ - **Faster reloads and tests.** The UI kit is compiled once per process and
96
+ each file's Python code is reused until it changes: on the saas example a
97
+ `pyweb dev` reload after a save went from about 255 to 60 ms, a
98
+ `TestClient` from about 255 to 55 ms, and compiling from about 240 to
99
+ 60 ms. The dev server notices a save within 0.1 s (was 0.4 s) and the
100
+ page asks for the new version every 0.25 s (was 0.6 s).
101
+ `python -m pyweb.bench --system` reports `reload_ms` and `test_client_ms`,
102
+ and CI's benchmark gate watches them.
103
+ - `pyweb check` warns about kit props and motion values that won't work
104
+ (`<Button variant="outlin">`), as the editor already did.
105
+
106
+ ### Fixed
107
+ - `pyweb check` printed the file and line twice for compile errors.
108
+ - Components drawn as a kit button (`DialogClose`) were flagged by the
109
+ editor for `variant="default"`, which they support.
110
+ - `pyweb test` with no path ran `pytest tests/`, which new apps don't have
111
+ (their test is `test_app.py` next to `app.pyweb`), so it failed in every
112
+ new project. It now runs the current folder, and accepts the app's
113
+ `.pyweb` file as well as a test file or folder.
114
+ - The `pyweb_test` MCP tool given the app's `.pyweb` file (as every other
115
+ tool takes) found no tests; it now tests that file's folder.
116
+ - `pyweb upgrade` says to apply pending migrations before creating the
117
+ `auth_sessions` one (on a fresh checkout `pyweb db diff` refused to run),
118
+ and notes that 0.6's `pyweb check` reports accessibility problems, which
119
+ `--strict` treats as failures.
120
+
9
121
  ## [0.6.0]
10
122
 
11
123
  Teams, installable and desktop apps, a UI kit and motion, and security by
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyweb-stack
3
- Version: 0.6.0
3
+ Version: 0.6.2
4
4
  Summary: Full-stack web apps in one Python file: server-rendered pages, reactive browser UI, typed RPC.
5
5
  Author-email: MaanavKrishna <67054795+MaanavKrishna@users.noreply.github.com>
6
6
  Maintainer-email: MaanavKrishna <67054795+MaanavKrishna@users.noreply.github.com>
@@ -400,6 +400,17 @@ develop a toolbar on every page shows each request's queries and flags
400
400
  N+1 loops. [Scaling & deploying →](docs/25-scaling.md) ·
401
401
  [Logs, metrics & tracing →](docs/26-observability.md)
402
402
 
403
+ ### A dev loop that keeps up
404
+
405
+ Save, and the open page changes in place: no reload, and every page and
406
+ component keeps its state. Hold Alt and click any element to open its
407
+ line in your editor; Alt+Shift-click to change it with AI, and error
408
+ pages have **Fix with AI** (your assistant's model through MCP, or your
409
+ own API key), with a diff to apply and Undo. The toolbar's timeline
410
+ steps back through every change and what caused it, and
411
+ `pyweb dev --share` gives someone a link to try what you're building.
412
+ [The dev loop →](docs/35-dev-loop.md)
413
+
403
414
  ### Small, fast and boring to run
404
415
 
405
416
  - **Every page is server-rendered**: complete HTML on first paint, then
@@ -442,7 +453,7 @@ it runs the real PyWeb, server functions included, in your browser.
442
453
  pip install pyweb-stack
443
454
  pyweb new myapp --template saas # saas | desktop | blank | counter | todo | blog | auth | chat | ai-chat
444
455
  cd myapp
445
- pyweb dev app.pyweb # edit app.pyweb; the page reloads on save
456
+ pyweb dev app.pyweb # saves update the open page in place, state kept
446
457
  ```
447
458
 
448
459
  Then:
@@ -478,7 +489,7 @@ The [architecture overview](ARCHITECTURE.md) goes through each stage.
478
489
 
479
490
  ## Build it with AI
480
491
 
481
- PyWeb ships an MCP server with 29 tools, so AI assistants can do what
492
+ PyWeb ships an MCP server with 31 tools, so AI assistants can do what
482
493
  you'd do: scaffold an app, search the docs, check each edit (errors come
483
494
  back as line numbers with fix hints), build with the UI kit and a theme,
484
495
  render pages and call server functions as any signed-in member, look at
@@ -566,7 +577,7 @@ Upgrade with `pip install -U pyweb-stack`.
566
577
 
567
578
  | Version | Highlights |
568
579
  |---|---|
569
- | 0.6 | Teams with roles, invitations and tenant-scoped Models (Postgres row-level security), API tokens and OpenAPI, webhooks, installable apps with Web Push, desktop windows and installers, a UI kit with themes and motion, Trusted Types, encrypted fields and a threat model, about 2.5× faster serving, Python 3.15 and free-threaded builds, a much richer MCP server |
580
+ | 0.6 | Teams with roles, invitations and tenant-scoped Models (Postgres row-level security), API tokens and OpenAPI, webhooks, installable apps with Web Push, desktop windows and installers, a UI kit with themes and motion, Trusted Types, encrypted fields and a threat model, about 2.5× faster serving, Python 3.15 and free-threaded builds, a much richer MCP server; 0.6.1: error messages with code frames and suggestions, `pyweb doctor`, dev reloads that keep page state, 4× faster reloads and tests; 0.6.2: the dev loop (hot reload in place with component state, Alt-click to source, Fix/Edit with AI, a time-travel timeline, `pyweb dev --share`, a guided `pyweb new`) |
570
581
  | 0.5 | Models with migrations, forms, auth kit with passkeys, OAuth and an admin, row-level live updates over WebSockets on PyWeb's own server, durable jobs and schedules, `pyweb deploy` for docker, compose, k8s, fly, render and railway, logs, metrics, tracing and a dev toolbar, data-aware editor and MCP tools, the `saas` template, `pyweb upgrade` |
571
582
  | 0.4 | npm packages without Node, layouts and client-side navigation, streaming server functions and `<Markdown>` for AI apps, live queries, page head tags, `.pyweb` error pages; 0.4.1: richer MCP tools; 0.4.2: VS Code run, new-app and MCP commands; 0.4.3: fixes, security hardening, gzip and caching; 0.4.4: key rotation, session revocation, typed arguments, Redis-shared limits, `check --production` |
572
583
  | 0.3 | Hydration, live updates (SSE), multi-file apps, language server + VS Code extension, browser playground, faster rendering, screenshot/test MCP tools |
@@ -326,6 +326,17 @@ develop a toolbar on every page shows each request's queries and flags
326
326
  N+1 loops. [Scaling & deploying →](docs/25-scaling.md) ·
327
327
  [Logs, metrics & tracing →](docs/26-observability.md)
328
328
 
329
+ ### A dev loop that keeps up
330
+
331
+ Save, and the open page changes in place: no reload, and every page and
332
+ component keeps its state. Hold Alt and click any element to open its
333
+ line in your editor; Alt+Shift-click to change it with AI, and error
334
+ pages have **Fix with AI** (your assistant's model through MCP, or your
335
+ own API key), with a diff to apply and Undo. The toolbar's timeline
336
+ steps back through every change and what caused it, and
337
+ `pyweb dev --share` gives someone a link to try what you're building.
338
+ [The dev loop →](docs/35-dev-loop.md)
339
+
329
340
  ### Small, fast and boring to run
330
341
 
331
342
  - **Every page is server-rendered**: complete HTML on first paint, then
@@ -368,7 +379,7 @@ it runs the real PyWeb, server functions included, in your browser.
368
379
  pip install pyweb-stack
369
380
  pyweb new myapp --template saas # saas | desktop | blank | counter | todo | blog | auth | chat | ai-chat
370
381
  cd myapp
371
- pyweb dev app.pyweb # edit app.pyweb; the page reloads on save
382
+ pyweb dev app.pyweb # saves update the open page in place, state kept
372
383
  ```
373
384
 
374
385
  Then:
@@ -404,7 +415,7 @@ The [architecture overview](ARCHITECTURE.md) goes through each stage.
404
415
 
405
416
  ## Build it with AI
406
417
 
407
- PyWeb ships an MCP server with 29 tools, so AI assistants can do what
418
+ PyWeb ships an MCP server with 31 tools, so AI assistants can do what
408
419
  you'd do: scaffold an app, search the docs, check each edit (errors come
409
420
  back as line numbers with fix hints), build with the UI kit and a theme,
410
421
  render pages and call server functions as any signed-in member, look at
@@ -492,7 +503,7 @@ Upgrade with `pip install -U pyweb-stack`.
492
503
 
493
504
  | Version | Highlights |
494
505
  |---|---|
495
- | 0.6 | Teams with roles, invitations and tenant-scoped Models (Postgres row-level security), API tokens and OpenAPI, webhooks, installable apps with Web Push, desktop windows and installers, a UI kit with themes and motion, Trusted Types, encrypted fields and a threat model, about 2.5× faster serving, Python 3.15 and free-threaded builds, a much richer MCP server |
506
+ | 0.6 | Teams with roles, invitations and tenant-scoped Models (Postgres row-level security), API tokens and OpenAPI, webhooks, installable apps with Web Push, desktop windows and installers, a UI kit with themes and motion, Trusted Types, encrypted fields and a threat model, about 2.5× faster serving, Python 3.15 and free-threaded builds, a much richer MCP server; 0.6.1: error messages with code frames and suggestions, `pyweb doctor`, dev reloads that keep page state, 4× faster reloads and tests; 0.6.2: the dev loop (hot reload in place with component state, Alt-click to source, Fix/Edit with AI, a time-travel timeline, `pyweb dev --share`, a guided `pyweb new`) |
496
507
  | 0.5 | Models with migrations, forms, auth kit with passkeys, OAuth and an admin, row-level live updates over WebSockets on PyWeb's own server, durable jobs and schedules, `pyweb deploy` for docker, compose, k8s, fly, render and railway, logs, metrics, tracing and a dev toolbar, data-aware editor and MCP tools, the `saas` template, `pyweb upgrade` |
497
508
  | 0.4 | npm packages without Node, layouts and client-side navigation, streaming server functions and `<Markdown>` for AI apps, live queries, page head tags, `.pyweb` error pages; 0.4.1: richer MCP tools; 0.4.2: VS Code run, new-app and MCP commands; 0.4.3: fixes, security hardening, gzip and caching; 0.4.4: key rotation, session revocation, typed arguments, Redis-shared limits, `check --production` |
498
509
  | 0.3 | Hydration, live updates (SSE), multi-file apps, language server + VS Code extension, browser playground, faster rendering, screenshot/test MCP tools |
@@ -177,6 +177,21 @@ websites in the user's browser.
177
177
  | T | An assistant's "read-only" SQL changing data | One statement, write keywords refused (even in a CTE), a read-only transaction that is rolled back; secrets redacted | `test_dx_v5.py::test_mcp_data_tools` |
178
178
  | T | Malformed tool arguments reaching app code | Arguments are checked against each tool's schema before it runs | `test_mcp_v6.py::test_arguments_are_checked_before_the_tool_runs` |
179
179
 
180
+ ## 7d. The dev loop: sharing, AI help, open in editor
181
+
182
+ `pyweb dev` only. Its tools change files, open programs and show request data, so they are for the
183
+ person running it, on that machine: a request must come from a loopback address and name a loopback
184
+ `Host` (a tunnel's or the LAN's requests don't), and writes must be same-origin.
185
+
186
+ | | Threat | Mitigation | Proof |
187
+ |---|---|---|---|
188
+ | S | Someone who learns the `--share` address (or guesses the tunnel name) using the app | Every request through the tunnel needs a cookie (`HttpOnly`, `Secure`, `SameSite=Lax`) set by the printed link's random token; forged cookies are refused | `test_share.py::test_the_link_sets_a_cookie_and_nothing_else_gets_in`, `test_share.py::test_pyweb_dev_share_end_to_end` |
189
+ | E/I | A share-link guest (or someone on the LAN) using the developer's tools: the toolbar's SQL and requests, the agent endpoints, AI fixes, opening files, saving the theme | Guests get the app and hot reload only; every `/__pyweb/dev/` endpoint but change polling answers 403 to them, and their pages carry no toolbar or tool scripts | `test_share.py::test_guests_get_the_app_and_hot_reload_only`, `test_share.py::test_you_still_get_everything_and_the_lan_gets_hot_reload`, `test_share.py::test_a_compile_error_page_for_guests_has_no_tools` |
190
+ | T | A web page making "Fix with AI" or "Edit with AI" write to the app | Same-origin, loopback-only POSTs; the answer is compiled first, applied only on Apply, only to `.pyweb` files in the app, refused if the file changed since; the old version is kept for Undo | `test_assist.py::test_endpoints_refuse_other_sites_and_other_machines`, `test_assist.py::test_a_change_that_does_not_compile_is_refused`, `test_assist.py::test_apply_refuses_when_the_file_changed_since`, `test_assist.py::test_only_app_files_are_targets` |
191
+ | I | Credentials in the app's source sent to a model | Known key formats and random-looking secret values are replaced by placeholders before sending and put back in the answer | `test_assist.py::test_secrets_are_replaced_before_sending_and_put_back`, `test_assist.py::test_the_connected_assistant_answers_through_mcp_sampling` |
192
+ | E | Alt-click "open in editor" used to open arbitrary files or run commands | Only `.pyweb` files inside the app folder or the UI kit; the editor gets an argument list, never a shell; same-origin and loopback only | `test_devopen.py::test_only_app_and_kit_files_resolve`, `e2e/test_dev_inspect_browser.py::test_open_refuses_cross_site_and_outside_files` |
193
+ | I | Dev-only markers or scripts in production pages | `data-pw-src` markers come from dev compiles only; the dev scripts are added by the dev server only | `test_devopen.py::test_other_builds_have_no_marks`, `test_trusted_types.py::test_dev_scripts_never_ship_in_built_pages` |
194
+
180
195
  ## 8. The release
181
196
 
182
197
  | | Threat | Mitigation | Proof |
@@ -43,6 +43,10 @@ Around that core, PyWeb has what a product needs, in the same file:
43
43
  ([Installable apps](31-pwa-push.md), [Desktop apps](32-desktop.md))
44
44
  - **Webhooks and files**: signed webhooks in and out, and unused uploads
45
45
  cleaned up. ([Webhooks & files](33-webhooks-files.md))
46
+ - **A dev loop that keeps up**: saves update the open page in place with
47
+ its state kept; Alt-click opens any element's source; Fix with AI and
48
+ Edit with AI; a time-travel timeline; `pyweb dev --share`.
49
+ ([The dev loop](35-dev-loop.md))
46
50
  - **Shipping**: `pyweb deploy` writes Docker, Compose, Kubernetes, Fly,
47
51
  Render or Railway files; logs, metrics and traces come built in.
48
52
  ([Scaling & deploying](25-scaling.md))
@@ -20,9 +20,14 @@ pip install "pyweb-stack[all]" # optional: Postgres, MySQL, Redis, argon2, O
20
20
  ```bash
21
21
  pyweb new hello
22
22
  cd hello
23
- pyweb dev app.pyweb # http://localhost:8000, reloads on save
23
+ pyweb dev app.pyweb # opens http://localhost:8000; saves update the page in place
24
24
  ```
25
25
 
26
+ (`pyweb new` with no name asks for one, a starter and colours.) Save a
27
+ change and the open page updates without losing its state; hold Alt and
28
+ click anything to open its line in your editor. [The dev loop](35-dev-loop.md)
29
+ has the rest: Fix with AI, time travel and sharing with `--share`.
30
+
26
31
  `pyweb new` writes `app.pyweb`, a starter test (`test_app.py`) and
27
32
  `AGENTS.md`/`CLAUDE.md` (instructions for AI coding agents). Add
28
33
  `--template saas` for a small product with teams, accounts, a database,
@@ -88,6 +93,12 @@ pyweb serve dist # production server with /healthz
88
93
  `dist/` contains your app source, static assets and a `Dockerfile`; see
89
94
  [Deployment](12-deployment.md).
90
95
 
96
+ If something doesn't work and the error isn't clear, `pyweb doctor`
97
+ checks the project and your machine (Python, the app, optional packages,
98
+ the database and migrations, the port, your editor) and prints a fix for
99
+ each problem; `pyweb doctor --production` also checks the production
100
+ settings.
101
+
91
102
  ## Next
92
103
 
93
104
  The [tutorial](03-tutorial.md) builds a notes app with a database,
@@ -101,6 +112,7 @@ ships it. Then, depending on what you're building:
101
112
  - work that runs later or on a schedule: [Background jobs](24-jobs.md);
102
113
  - teams that share data: [Teams & organizations](30-teams.md);
103
114
  - components, a theme and animation: [UI kit & motion](34-ui-and-motion.md);
115
+ - everything `pyweb dev` does for you: [The dev loop](35-dev-loop.md);
104
116
  - an app people install, or a desktop app: [Installable apps & push](31-pwa-push.md),
105
117
  [Desktop apps](32-desktop.md);
106
118
  - several pages with a shared header: [Layouts & navigation](19-layouts-navigation.md);
@@ -1,17 +1,30 @@
1
1
  # Command line
2
2
 
3
3
  ```text
4
- pyweb new NAME [--template T] create NAME/ with app.pyweb, test_app.py, AGENTS.md, CLAUDE.md, static/;
4
+ pyweb new [NAME] [--template T] [--theme PRESET]
5
+ create NAME/ with app.pyweb, test_app.py, AGENTS.md, CLAUDE.md, static/;
5
6
  T = blank | counter (default) | todo | blog | saas | auth | chat | ai-chat | desktop
6
- (apps with a database also get migrations/0001_initial.py and a README)
7
- pyweb dev FILE [--port 8000] [--host 127.0.0.1] [--no-reload]
8
- development server: recompile on save, live reload, error overlay,
9
- the dev toolbar (requests, SQL, jobs, emails, theme and motion
10
- editors), and background jobs in the same process; writes
7
+ (apps with a database also get migrations/0001_initial.py and a README);
8
+ PRESET = indigo | zinc | slate | rose | ocean | violet | emerald | amber
9
+ (written into App(theme=...)); with no NAME, in a terminal, it asks
10
+ pyweb dev FILE [--port 8000] [--host 127.0.0.1] [--no-reload] [--no-open] [--share]
11
+ development server (see The dev loop): saves update the open page
12
+ in place, keeping page and component state (?fresh starts over);
13
+ Alt-click opens an element's line in your editor, Alt+Shift-click
14
+ changes it with AI, error pages have Fix with AI; the dev toolbar
15
+ (requests, SQL, jobs, emails, theme, motion, a time-travel timeline);
16
+ background jobs in the same process; opens the browser (not in CI,
17
+ over SSH or with --no-open); --host 0.0.0.0 prints the network URL
18
+ with a QR code; --share prints a temporary public link; writes
11
19
  .pyweb/dev.json so `pyweb mcp` can see its errors and logs
12
20
  pyweb check FILE [--production] [--strict]
13
21
  compile, security and accessibility checks; --production also checks
14
22
  the environment; --strict fails on warnings too
23
+ pyweb doctor [FILE] [--production] [--json] [--port 8000]
24
+ is the project ready? Python, the app compiles, optional packages,
25
+ database and migrations, Redis, secrets in the source, upgrade
26
+ changes, a stale dev server link, tests, the port, the editor; a fix
27
+ for each problem (exit 1 on any failure; --json for CI)
15
28
  pyweb upgrade [FILE] [--fix] what to change for this PyWeb version (file and line); --fix applies
16
29
  the safe rewrites
17
30
  pyweb inspect FILE [--security] where every name runs and why; RPC table; findings
@@ -66,13 +79,39 @@ pyweb dts FILE.d.ts Python dataclasses from TypeScript declarat
66
79
  pyweb mcp MCP server over stdio for AI assistants (see AI assistants & MCP)
67
80
  pyweb mcp --http [--port 8765] [--token T] the same over Streamable HTTP (127.0.0.1 only without a token)
68
81
  pyweb lsp language server over stdio for editors (see below)
69
- pyweb test [PATH] run pytest
82
+ pyweb test [PATH] run pytest on PATH (a test file, a folder or app.pyweb's folder;
83
+ default: the current folder, where new apps keep test_app.py)
70
84
  pyweb fmt [PATH] / pyweb lint [PATH] run ruff format / ruff check (if installed)
71
85
  pyweb --version
72
86
  ```
73
87
 
74
88
  `python -m pyweb.cli ...` is equivalent to `pyweb ...`.
75
89
 
90
+ ## Error messages
91
+
92
+ A compile error names the file and line, shows the line with a caret under
93
+ the problem, suggests the name you probably meant, and links the docs page
94
+ that explains it:
95
+
96
+ ```text
97
+ error: app.pyweb:17: <Greeting> has no prop 'nme'; did you mean 'name'?
98
+
99
+ 16 | <h1>{count}</h1>
100
+ > 17 | <Greeting nme="x" />
101
+ | ^
102
+ 18 | </main>
103
+
104
+ hint: Use one of the component's parameter names as the attribute.
105
+ docs: https://maanavkrishna.github.io/PyWeb/language.html
106
+ ```
107
+
108
+ The first line keeps the `file:line: message` shape, so editors and CI
109
+ logs can jump to it. `pyweb check` also warns about kit props and motion
110
+ values that won't work (`<Button variant="outlin">`). The `pyweb dev`
111
+ overlay shows the same, and when page code raises, its error page starts
112
+ with the frames in your own files and their source lines, before the full
113
+ traceback.
114
+
76
115
  ## Exit codes
77
116
 
78
117
  `check` and `build` exit `1` on compile or security errors and `2` on
@@ -11,8 +11,9 @@ can decide up front whether they matter for your app.
11
11
  - **npm packages must ship ES modules.** CommonJS-only packages and
12
12
  packages built on Node.js modules can't run in the browser; see
13
13
  [npm packages](18-npm-packages.md).
14
- - **Dev reload is a full page reload.** State is not preserved across
15
- edits.
14
+ - **Time travel moves the page's state only.** The dev timeline puts the
15
+ page's and components' variables back; data on the server isn't
16
+ rolled back.
16
17
  - **SQLite is for one machine.** Several processes on one host share it
17
18
  fine, but more than one server needs Postgres or MySQL;
18
19
  `pyweb check --production` and `pyweb deploy` say so.
@@ -33,7 +34,13 @@ can decide up front whether they matter for your app.
33
34
  with Web Push, desktop windows and installers, a UI kit with themes and
34
35
  motion, Trusted Types, encrypted fields and a threat model, about 2.5×
35
36
  faster serving, Python 3.15 and free-threaded builds, and a much richer
36
- MCP server.
37
+ MCP server. 0.6.1 added error messages with code frames and
38
+ suggestions, `pyweb doctor`, dev reloads that keep page state, and 4×
39
+ faster reloads and tests. 0.6.2 made the [dev loop](35-dev-loop.md):
40
+ saves update the page in place with component state kept, Alt-click
41
+ opens any element's source, Fix with AI and Edit with AI, a
42
+ time-travel timeline, `pyweb dev --share`, a faster first start and a
43
+ guided `pyweb new`.
37
44
  - **0.5**: production apps. Models with relations and migrations, forms
38
45
  checked in the browser and on the server, an auth kit (passwords,
39
46
  passkeys, emailed links, OAuth, two-step sign-in, an admin), row-level
@@ -64,7 +71,8 @@ Planned, roughly in order. Nothing here is promised for a date.
64
71
  1. **1.0**: the API, RPC protocol and CLI frozen under semantic versioning,
65
72
  after 0.6 has been used in production for a while.
66
73
  2. **File uploads from the playground and the admin.**
67
- 3. **State-preserving hot reload** while developing.
74
+ 3. **Fix with AI in the editor**, from the same proposals the dev page
75
+ shows (diff, apply, undo), through the VS Code extension.
68
76
 
69
77
  Ideas, bug reports and pull requests are welcome; see
70
78
  [CONTRIBUTING.md](https://github.com/MaanavKrishna/PyWeb/blob/main/CONTRIBUTING.md).
@@ -70,7 +70,7 @@ tool runs. Slow tools (tests, screenshots, profiling) report progress.
70
70
  | `pyweb_guide` | The rules for writing `.pyweb` apps (or one section): what runs where, state, markup, components, server functions, the browser Python subset, and every common error with its fix. |
71
71
  | `pyweb_docs` | Searches the documentation (every page, the guide and the threat model) and returns the matching sections, or one whole page. For any "how do I..." question. |
72
72
  | `pyweb_new_app` | Creates an app from a template (`blank`, `counter`, `todo`, `blog`, `saas`, `auth`, `chat`, `ai-chat`, `desktop`) with `AGENTS.md`, `CLAUDE.md`, tests and a stylesheet; apps with a database also get their first migration. `saas` (teams, accounts, tenant Models, forms, live pages, jobs, webhooks, admin) is the best start for a product; `desktop` is a notes app for `pyweb desktop`. |
73
- | `pyweb_check` | Compiles the app and runs the security and accessibility checks. Returns `ok`, errors with `line`, `message` and a fix `hint`, plus pages (with their layouts, live-data variables and npm packages), signals, what's sent to the browser, JS size and the server functions. |
73
+ | `pyweb_check` | Compiles the app and runs the security and accessibility checks. Returns `ok`, errors with `line`, `message`, a fix `hint`, a code `frame` and a `docs` link, plus pages (with their layouts, live-data variables and npm packages), signals, what's sent to the browser, JS size and the server functions. |
74
74
  | `pyweb_explain` | What your editor shows for a line: for each name, where it runs and why (or its signature or npm type), the problems on that line and, with `complete`, the completions at a column. |
75
75
  | `pyweb_inspect` | For every name: does it run in the browser or on the server, and why. |
76
76
  | `pyweb_compiled` | The JavaScript generated for a page, and its server-rendered HTML. |
@@ -106,7 +106,9 @@ tool runs. Slow tools (tests, screenshots, profiling) report progress.
106
106
  | Tool | What it does |
107
107
  |---|---|
108
108
  | `pyweb_dev` | Whether `pyweb dev` is running for this app: its URL, whether the app compiles right now (with the error and traceback), its pages and recent 500 errors. |
109
+ | `pyweb_doctor` | Project health, as `pyweb doctor`: each check with `status` (ok, warn, fail), `detail` and a `fix`; `production=true` adds the production settings. |
109
110
  | `pyweb_logs` | The dev server's log lines (warnings, errors with tracebacks, slow queries, job failures); `since` returns only newer ones. |
111
+ | `pyweb_assist_requests` | What the developer asked for from the page (Fix with AI on an error page, Alt+Shift-click → Edit with AI) while no AI was set up to answer: the file, the error or the element's line, and the instruction. |
110
112
 
111
113
  When `pyweb dev` starts, it writes `.pyweb/dev.json` next to the app: its
112
114
  address and a random token, readable only by you (the folder has its own
@@ -148,6 +150,7 @@ Prompts are step-by-step workflows that name the tools to use:
148
150
  | `design_pass` | Kit components, a theme and motion, reviewed in light, dark and on a phone. |
149
151
  | `fix_failing_test` | Reproduce, find the cause in the app, fix, re-run. |
150
152
  | `debug_page` | Errors, logs, requests and a profile for one page. |
153
+ | `fix_errors` | Check, fix and test in a loop until the app compiles cleanly and the tests pass; first does what was asked from the page. |
151
154
 
152
155
  ### What a session looks like
153
156
 
@@ -171,6 +174,24 @@ Prompts are step-by-step workflows that name the tools to use:
171
174
  click around, the assistant reads the error with `pyweb_dev` and
172
175
  `pyweb_logs` and fixes it.
173
176
 
177
+ ### Fix with AI from the page (sampling)
178
+
179
+ `pyweb dev` puts a **Fix with AI** button on error pages, and
180
+ Alt+Shift-click asks for a change to any element (see
181
+ [The dev loop](35-dev-loop.md#fix-with-ai-and-edit-with-ai)). When your
182
+ assistant's app supports MCP **sampling** (the client lets a server ask
183
+ its model a question, after you approve), `pyweb mcp` answers those
184
+ requests with your assistant's own model: it notices the client offers
185
+ sampling when it connects, finds the running `pyweb dev` through
186
+ `.pyweb/dev.json`, and hands each request over. The page shows the
187
+ answer as a diff to apply or discard. This works over stdio (`pyweb
188
+ mcp`); set `PYWEB_APP` when the app file isn't `app.pyweb` in the folder
189
+ the assistant starts in.
190
+
191
+ Assistants without sampling see the same requests with
192
+ `pyweb_assist_requests` and can do them with their own file tools; the
193
+ `fix_errors` prompt starts there.
194
+
174
195
  `pyweb_render`, `pyweb_call`, `pyweb_screenshot`, `pyweb_review`,
175
196
  `pyweb_profile`, `pyweb_webhook_send`, `pyweb_jobs` and `pyweb_test` run
176
197
  your app's code, as `pyweb dev` or `pytest` would; `pyweb_packages`
@@ -19,6 +19,7 @@ pytest
19
19
  Apps that call `app.use_auth()` need the new `auth_sessions` table:
20
20
 
21
21
  ```bash
22
+ pyweb db upgrade # apply any migrations still pending
22
23
  pyweb db diff --name auth_sessions
23
24
  pyweb db upgrade
24
25
  ```
@@ -107,12 +107,22 @@ you use it in a browser.
107
107
  Profile against a copy of your real data. A page that's fast with ten
108
108
  rows can be slow with ten thousand.
109
109
 
110
+ ## Fast reloads and tests
111
+
112
+ The UI kit is compiled once per process, and each `.pyweb` file's Python
113
+ code is reused until the file changes. On the saas example that took a
114
+ reload in `pyweb dev` from about 255 to 60 ms and creating a
115
+ `TestClient` from about 255 to 55 ms; the dev server also notices a save
116
+ within a tenth of a second. Compiled output is byte-for-byte what a fresh
117
+ compile gives, and a test checks that.
118
+
110
119
  ## Benchmarks in CI
111
120
 
112
121
  `python -m pyweb.bench` reports compile time, shipped JavaScript and
113
122
  render time per page. `--system` measures the whole stack: requests per
114
123
  second over real sockets, a signed-in page with a database, start-up
115
- time, and live query hashing.
124
+ time, live query hashing, and how long loading an app again takes (what
125
+ `pyweb dev` does after a save, and what each `TestClient` does).
116
126
 
117
127
  PyWeb's CI runs `--compare` on every push and pull request. It checks out
118
128
  the commit before the change next to the new one and runs both five