painapple-code 1.0.0__py3-none-any.whl

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 (436) hide show
  1. painapple_code/__init__.py +30 -0
  2. painapple_code/__main__.py +18 -0
  3. painapple_code/_version.py +24 -0
  4. painapple_code/auth_middleware.py +930 -0
  5. painapple_code/cli/__init__.py +204 -0
  6. painapple_code/cli/deploy/__init__.py +15 -0
  7. painapple_code/cli/deploy/claude_seed.py +41 -0
  8. painapple_code/cli/deploy/config.py +260 -0
  9. painapple_code/cli/deploy/container.py +715 -0
  10. painapple_code/cli/deploy/launch.py +163 -0
  11. painapple_code/cli/deploy/runtime.py +223 -0
  12. painapple_code/cli/lifecycle_cmd.py +443 -0
  13. painapple_code/cli/list_cmd.py +572 -0
  14. painapple_code/cli/manage_cmd.py +670 -0
  15. painapple_code/cli/netinfo.py +125 -0
  16. painapple_code/cli/profiles.py +390 -0
  17. painapple_code/cli/serve_args.py +163 -0
  18. painapple_code/cli/serve_config.py +256 -0
  19. painapple_code/cli/setup_cmd.py +664 -0
  20. painapple_code/cli/ui.py +438 -0
  21. painapple_code/cost_analytics.py +879 -0
  22. painapple_code/data/models.defaults.yaml +18 -0
  23. painapple_code/data/models.yaml +18 -0
  24. painapple_code/data/presets.defaults.json +32 -0
  25. painapple_code/data/strings.yaml +2269 -0
  26. painapple_code/helpers.py +406 -0
  27. painapple_code/paths.py +1514 -0
  28. painapple_code/prompt_explorer.py +984 -0
  29. painapple_code/providers/__init__.py +224 -0
  30. painapple_code/providers/base.py +710 -0
  31. painapple_code/providers/claude/__init__.py +74 -0
  32. painapple_code/providers/claude/capabilities.py +218 -0
  33. painapple_code/providers/claude/errors.py +79 -0
  34. painapple_code/providers/claude/launch.py +50 -0
  35. painapple_code/providers/claude/summary.py +89 -0
  36. painapple_code/providers/claude/translate.py +74 -0
  37. painapple_code/providers/claude_sdk/__init__.py +139 -0
  38. painapple_code/providers/claude_sdk/driver.py +412 -0
  39. painapple_code/providers/codex/__init__.py +87 -0
  40. painapple_code/providers/codex/capabilities.py +321 -0
  41. painapple_code/providers/codex/errors.py +70 -0
  42. painapple_code/providers/codex/launch.py +142 -0
  43. painapple_code/providers/codex/summary.py +196 -0
  44. painapple_code/providers/codex/translate.py +204 -0
  45. painapple_code/providers/codex_app_server/__init__.py +100 -0
  46. painapple_code/providers/codex_app_server/capabilities.py +41 -0
  47. painapple_code/providers/codex_app_server/launch.py +202 -0
  48. painapple_code/providers/codex_app_server/summary.py +291 -0
  49. painapple_code/providers/codex_app_server/translate.py +263 -0
  50. painapple_code/providers/codex_app_server/transport.py +238 -0
  51. painapple_code/routes/__init__.py +0 -0
  52. painapple_code/routes/api_agents.py +441 -0
  53. painapple_code/routes/api_app.py +368 -0
  54. painapple_code/routes/api_app_commit_sections.py +127 -0
  55. painapple_code/routes/api_app_config.py +997 -0
  56. painapple_code/routes/api_app_session_prefs.py +217 -0
  57. painapple_code/routes/api_browser.py +690 -0
  58. painapple_code/routes/api_commands.py +374 -0
  59. painapple_code/routes/api_costs.py +128 -0
  60. painapple_code/routes/api_drafts.py +139 -0
  61. painapple_code/routes/api_exec.py +149 -0
  62. painapple_code/routes/api_files.py +542 -0
  63. painapple_code/routes/api_git.py +657 -0
  64. painapple_code/routes/api_logs.py +649 -0
  65. painapple_code/routes/api_plugins.py +275 -0
  66. painapple_code/routes/api_project_config.py +418 -0
  67. painapple_code/routes/api_prompts.py +231 -0
  68. painapple_code/routes/api_providers.py +53 -0
  69. painapple_code/routes/api_search.py +411 -0
  70. painapple_code/routes/api_session_stash.py +234 -0
  71. painapple_code/routes/api_session_welcome.py +151 -0
  72. painapple_code/routes/api_sessions.py +742 -0
  73. painapple_code/routes/api_shadow.py +323 -0
  74. painapple_code/routes/api_shadow_db.py +512 -0
  75. painapple_code/routes/api_shadow_files.py +332 -0
  76. painapple_code/routes/api_shadow_search.py +476 -0
  77. painapple_code/routes/api_skills.py +610 -0
  78. painapple_code/routes/api_tasks.py +147 -0
  79. painapple_code/routes/api_terminal.py +540 -0
  80. painapple_code/routes/api_upload.py +293 -0
  81. painapple_code/routes/api_viewer.py +229 -0
  82. painapple_code/routes/dependencies.py +109 -0
  83. painapple_code/routes/ws_chat.py +837 -0
  84. painapple_code/server.py +2208 -0
  85. painapple_code/server_logging.py +263 -0
  86. painapple_code/services/__init__.py +0 -0
  87. painapple_code/services/agent_session.py +2738 -0
  88. painapple_code/session_store.py +253 -0
  89. painapple_code/session_store_core.py +879 -0
  90. painapple_code/shadow_db.py +830 -0
  91. painapple_code/shadow_db_plans.py +369 -0
  92. painapple_code/shadow_db_queries.py +595 -0
  93. painapple_code/shadow_db_schema.py +676 -0
  94. painapple_code/shadow_git.py +1296 -0
  95. painapple_code/shadow_git_frontmatter.py +314 -0
  96. painapple_code/shadow_git_sections.py +520 -0
  97. painapple_code/shadow_git_summary.py +462 -0
  98. painapple_code/shadow_parser.py +560 -0
  99. painapple_code/static/css/00-variables.css +276 -0
  100. painapple_code/static/css/01-base.css +245 -0
  101. painapple_code/static/css/02-tooltips.css +36 -0
  102. painapple_code/static/css/09-left-rail.css +448 -0
  103. painapple_code/static/css/10-header.css +777 -0
  104. painapple_code/static/css/11-connection-bar.css +120 -0
  105. painapple_code/static/css/20-messages.css +750 -0
  106. painapple_code/static/css/21-tool-blocks.css +2340 -0
  107. painapple_code/static/css/22-edit-diff.css +619 -0
  108. painapple_code/static/css/23-thinking.css +1584 -0
  109. painapple_code/static/css/24-background-tasks.css +359 -0
  110. painapple_code/static/css/25-context-block.css +252 -0
  111. painapple_code/static/css/26-session-setup.css +144 -0
  112. painapple_code/static/css/30-markdown.css +854 -0
  113. painapple_code/static/css/40-input.css +2418 -0
  114. painapple_code/static/css/41-autocomplete.css +127 -0
  115. painapple_code/static/css/42-activity-strip.css +97 -0
  116. painapple_code/static/css/43-file-autocomplete.css +121 -0
  117. painapple_code/static/css/44-snippets-autocomplete.css +224 -0
  118. painapple_code/static/css/45-selection-bar.css +433 -0
  119. painapple_code/static/css/46-keyboard-bar.css +119 -0
  120. painapple_code/static/css/47-keyboard-longpress.css +116 -0
  121. painapple_code/static/css/47-token-profile.css +106 -0
  122. painapple_code/static/css/50-welcome.css +3095 -0
  123. painapple_code/static/css/51-modals.css +301 -0
  124. painapple_code/static/css/52-utilities.css +77 -0
  125. painapple_code/static/css/53-image-upload.css +456 -0
  126. painapple_code/static/css/54-todo-list.css +102 -0
  127. painapple_code/static/css/55-file-upload.css +113 -0
  128. painapple_code/static/css/56-chat-navigator.css +218 -0
  129. painapple_code/static/css/56-permission-card.css +332 -0
  130. painapple_code/static/css/56-plan-approval.css +204 -0
  131. painapple_code/static/css/56-question-form.css +602 -0
  132. painapple_code/static/css/57-swipe-indicator.css +95 -0
  133. painapple_code/static/css/58-session-families.css +627 -0
  134. painapple_code/static/css/59-about.css +196 -0
  135. painapple_code/static/css/61-log-explorer.css +723 -0
  136. painapple_code/static/css/62-json-tree.css +489 -0
  137. painapple_code/static/css/62-skills-widget.css +650 -0
  138. painapple_code/static/css/63-commands-widget.css +30 -0
  139. painapple_code/static/css/63-plugins-widget.css +174 -0
  140. painapple_code/static/css/63-terminal.css +516 -0
  141. painapple_code/static/css/64-search-files-widget.css +448 -0
  142. painapple_code/static/css/65-snippets-widget.css +426 -0
  143. painapple_code/static/css/66-active-sessions.css +979 -0
  144. painapple_code/static/css/66-agents-widget.css +265 -0
  145. painapple_code/static/css/66-file-explorer-widget.css +855 -0
  146. painapple_code/static/css/66-git-panel.css +791 -0
  147. painapple_code/static/css/66-history-explorer.css +1496 -0
  148. painapple_code/static/css/67-diff-viewer.css +602 -0
  149. painapple_code/static/css/67-editor-view.css +748 -0
  150. painapple_code/static/css/67-file-preview-widget.css +1873 -0
  151. painapple_code/static/css/68-browser-widget.css +337 -0
  152. painapple_code/static/css/68-compare-wizard.css +355 -0
  153. painapple_code/static/css/68-csv-preview.css +106 -0
  154. painapple_code/static/css/68-diff-preview.css +103 -0
  155. painapple_code/static/css/68-helpers-install-widget.css +491 -0
  156. painapple_code/static/css/68-image-annotate.css +346 -0
  157. painapple_code/static/css/68-terminal-view.css +98 -0
  158. painapple_code/static/css/68-uploads-widget.css +229 -0
  159. painapple_code/static/css/69-cost-analytics.css +537 -0
  160. painapple_code/static/css/70-config-panel.css +3736 -0
  161. painapple_code/static/css/70-excalidraw.css +136 -0
  162. painapple_code/static/css/70-prompt-explorer.css +890 -0
  163. painapple_code/static/css/71-chart.css +111 -0
  164. painapple_code/static/css/72-discussion-sidebar.css +678 -0
  165. painapple_code/static/css/74-debug-logs.css +656 -0
  166. painapple_code/static/css/80-open-dialog.css +146 -0
  167. painapple_code/static/css/80-quick-switcher.css +383 -0
  168. painapple_code/static/css/80-widget-system.css +1763 -0
  169. painapple_code/static/css/81-quick-actions.css +1020 -0
  170. painapple_code/static/css/82-context-popover.css +1233 -0
  171. painapple_code/static/css/83-context-menu.css +339 -0
  172. painapple_code/static/css/85-lazy-loading.css +102 -0
  173. painapple_code/static/css/86-zen-mode.css +708 -0
  174. painapple_code/static/css/87-grid-switcher.css +346 -0
  175. painapple_code/static/css/login.css +198 -0
  176. painapple_code/static/dist/app.bundle.js +7177 -0
  177. painapple_code/static/feature-triage.html +446 -0
  178. painapple_code/static/icons/apple-touch-icon.png +0 -0
  179. painapple_code/static/icons/favicon-32.png +0 -0
  180. painapple_code/static/icons/favicon.ico +0 -0
  181. painapple_code/static/icons/icon-128.png +0 -0
  182. painapple_code/static/icons/icon-144.png +0 -0
  183. painapple_code/static/icons/icon-152.png +0 -0
  184. painapple_code/static/icons/icon-180.png +0 -0
  185. painapple_code/static/icons/icon-192.png +0 -0
  186. painapple_code/static/icons/icon-384.png +0 -0
  187. painapple_code/static/icons/icon-512.png +0 -0
  188. painapple_code/static/icons/icon-72.png +0 -0
  189. painapple_code/static/icons/icon-96.png +0 -0
  190. painapple_code/static/js/action-delegate.js +187 -0
  191. painapple_code/static/js/activity-strip.js +193 -0
  192. painapple_code/static/js/app/context-menus.js +619 -0
  193. painapple_code/static/js/app/file-preview.js +163 -0
  194. painapple_code/static/js/app/init-ui.js +574 -0
  195. painapple_code/static/js/app/input-events.js +561 -0
  196. painapple_code/static/js/app/input-resize.js +313 -0
  197. painapple_code/static/js/app/message-actions.js +419 -0
  198. painapple_code/static/js/app/panels.js +210 -0
  199. painapple_code/static/js/app/rendering-delegators.js +246 -0
  200. painapple_code/static/js/app/server-loading.js +365 -0
  201. painapple_code/static/js/app/session-ops.js +287 -0
  202. painapple_code/static/js/app/session-switch.js +443 -0
  203. painapple_code/static/js/app/settings-helpers.js +280 -0
  204. painapple_code/static/js/app/startup-welcome.js +290 -0
  205. painapple_code/static/js/app-context.js +157 -0
  206. painapple_code/static/js/app.js +2134 -0
  207. painapple_code/static/js/auth-fetch.js +46 -0
  208. painapple_code/static/js/background-tasks.js +274 -0
  209. painapple_code/static/js/boot.js +73 -0
  210. painapple_code/static/js/caret-position.js +171 -0
  211. painapple_code/static/js/chat-navigator.js +710 -0
  212. painapple_code/static/js/chat-search.js +323 -0
  213. painapple_code/static/js/command-executor.js +176 -0
  214. painapple_code/static/js/command-store.js +497 -0
  215. painapple_code/static/js/components.js +1414 -0
  216. painapple_code/static/js/config.js +218 -0
  217. painapple_code/static/js/context-menu.js +740 -0
  218. painapple_code/static/js/controllers/chat-controller.js +4252 -0
  219. painapple_code/static/js/controllers/dialog-controller.js +217 -0
  220. painapple_code/static/js/controllers/tab-controller.js +1828 -0
  221. painapple_code/static/js/controllers/thinking-controller.js +915 -0
  222. painapple_code/static/js/diff-utils.js +486 -0
  223. painapple_code/static/js/drafts-pill.js +95 -0
  224. painapple_code/static/js/editor-view.js +815 -0
  225. painapple_code/static/js/effort-settings.js +430 -0
  226. painapple_code/static/js/feature-triage.js +811 -0
  227. painapple_code/static/js/file-autocomplete.js +516 -0
  228. painapple_code/static/js/file-tabs.js +123 -0
  229. painapple_code/static/js/gestures.js +448 -0
  230. painapple_code/static/js/grid-switcher.js +334 -0
  231. painapple_code/static/js/input-handler.js +1472 -0
  232. painapple_code/static/js/keyboard-bar.js +495 -0
  233. painapple_code/static/js/layout-switcher.js +109 -0
  234. painapple_code/static/js/linkify-utils.js +200 -0
  235. painapple_code/static/js/login.js +141 -0
  236. painapple_code/static/js/open-dialog.js +879 -0
  237. painapple_code/static/js/orphan-terminals.js +373 -0
  238. painapple_code/static/js/path-utils.js +179 -0
  239. painapple_code/static/js/perf-marks.js +102 -0
  240. painapple_code/static/js/permission-settings.js +475 -0
  241. painapple_code/static/js/pointer-input.js +59 -0
  242. painapple_code/static/js/preview/json-tree-menu.js +226 -0
  243. painapple_code/static/js/preview/json-tree-toolbar.js +291 -0
  244. painapple_code/static/js/preview/json-tree.js +457 -0
  245. painapple_code/static/js/preview/preview-breadcrumb.js +387 -0
  246. painapple_code/static/js/preview/preview-edit.js +367 -0
  247. painapple_code/static/js/preview/preview-events.js +361 -0
  248. painapple_code/static/js/preview/preview-history.js +567 -0
  249. painapple_code/static/js/preview/preview-inline-edit.js +869 -0
  250. painapple_code/static/js/preview/preview-poll.js +108 -0
  251. painapple_code/static/js/preview/preview-render.js +572 -0
  252. painapple_code/static/js/preview/preview-search.js +421 -0
  253. painapple_code/static/js/preview/preview-state.js +256 -0
  254. painapple_code/static/js/preview/preview-utils.js +251 -0
  255. painapple_code/static/js/preview-plugins/chart-plugin.js +22 -0
  256. painapple_code/static/js/preview-plugins/csv-plugin.js +188 -0
  257. painapple_code/static/js/preview-plugins/diff-plugin.js +258 -0
  258. painapple_code/static/js/preview-plugins/excalidraw-plugin.js +25 -0
  259. painapple_code/static/js/preview-plugins/html-plugin.js +104 -0
  260. painapple_code/static/js/preview-plugins/image-plugin.js +20 -0
  261. painapple_code/static/js/preview-plugins/index.js +34 -0
  262. painapple_code/static/js/preview-plugins/json-plugin.js +99 -0
  263. painapple_code/static/js/preview-plugins/jsonl-plugin.js +152 -0
  264. painapple_code/static/js/preview-plugins/markdown-plugin.js +266 -0
  265. painapple_code/static/js/preview-plugins/panzoom-plugin.js +63 -0
  266. painapple_code/static/js/preview-plugins/plugin-helpers.js +282 -0
  267. painapple_code/static/js/project-color-picker.js +110 -0
  268. painapple_code/static/js/project-colors.js +163 -0
  269. painapple_code/static/js/prompt-favorites.js +187 -0
  270. painapple_code/static/js/quick-actions-menu.js +1736 -0
  271. painapple_code/static/js/quick-actions-registry.js +1239 -0
  272. painapple_code/static/js/quick-switcher/controller.js +294 -0
  273. painapple_code/static/js/quick-switcher/fuzzy-scorer.js +123 -0
  274. painapple_code/static/js/quick-switcher/index.js +30 -0
  275. painapple_code/static/js/quick-switcher/providers/base-provider.js +51 -0
  276. painapple_code/static/js/quick-switcher/providers/command-provider.js +56 -0
  277. painapple_code/static/js/quick-switcher/providers/file-provider.js +291 -0
  278. painapple_code/static/js/quick-switcher/providers/panel-provider.js +132 -0
  279. painapple_code/static/js/quick-switcher/providers/project-provider.js +361 -0
  280. painapple_code/static/js/quick-switcher/providers/read-files-provider.js +104 -0
  281. painapple_code/static/js/quick-switcher/providers/skills-provider.js +129 -0
  282. painapple_code/static/js/quick-switcher/registry.js +69 -0
  283. painapple_code/static/js/quick-switcher/ui/item.js +54 -0
  284. painapple_code/static/js/quick-switcher/ui/picker.js +464 -0
  285. painapple_code/static/js/recent-opens.js +40 -0
  286. painapple_code/static/js/scroll-manager.js +530 -0
  287. painapple_code/static/js/scroll-state-machine.js +359 -0
  288. painapple_code/static/js/selection/action-bar.js +793 -0
  289. painapple_code/static/js/selection/index.js +15 -0
  290. painapple_code/static/js/selection/selection-handler.js +877 -0
  291. painapple_code/static/js/selection/state.js +181 -0
  292. painapple_code/static/js/session/agent-progress.js +202 -0
  293. painapple_code/static/js/session/handle-agent-message.js +481 -0
  294. painapple_code/static/js/session/handle-message.js +550 -0
  295. painapple_code/static/js/session/interactive.js +587 -0
  296. painapple_code/static/js/session/message-store.js +271 -0
  297. painapple_code/static/js/session/messages.js +253 -0
  298. painapple_code/static/js/session/persistence.js +179 -0
  299. painapple_code/static/js/session/restore.js +136 -0
  300. painapple_code/static/js/session/sync.js +333 -0
  301. painapple_code/static/js/session-container-pool.js +371 -0
  302. painapple_code/static/js/session-setup-panel.js +274 -0
  303. painapple_code/static/js/session.js +1047 -0
  304. painapple_code/static/js/shortcut-hints.js +272 -0
  305. painapple_code/static/js/shortcuts.js +1146 -0
  306. painapple_code/static/js/skills-autocomplete.js +262 -0
  307. painapple_code/static/js/snippets-autocomplete.js +738 -0
  308. painapple_code/static/js/stash-refs-view.js +83 -0
  309. painapple_code/static/js/stash-ui.js +768 -0
  310. painapple_code/static/js/stash.js +785 -0
  311. painapple_code/static/js/status-bar.js +1184 -0
  312. painapple_code/static/js/token-profile.js +274 -0
  313. painapple_code/static/js/tool-renderer-blocks.js +1626 -0
  314. painapple_code/static/js/tool-renderer-thinking.js +813 -0
  315. painapple_code/static/js/tool-renderer.js +1500 -0
  316. painapple_code/static/js/tooltips.js +197 -0
  317. painapple_code/static/js/upload-manager.js +1019 -0
  318. painapple_code/static/js/utils.js +521 -0
  319. painapple_code/static/js/welcome/api.js +363 -0
  320. painapple_code/static/js/welcome/cards.js +626 -0
  321. painapple_code/static/js/welcome/context-menu.js +585 -0
  322. painapple_code/static/js/welcome/families.js +801 -0
  323. painapple_code/static/js/welcome/preview.js +234 -0
  324. painapple_code/static/js/welcome/state.js +129 -0
  325. painapple_code/static/js/welcome.js +1874 -0
  326. painapple_code/static/js/widget-system/base-widget.js +717 -0
  327. painapple_code/static/js/widget-system/device-manager.js +178 -0
  328. painapple_code/static/js/widget-system/event-bus.js +152 -0
  329. painapple_code/static/js/widget-system/icons.js +120 -0
  330. painapple_code/static/js/widget-system/index.js +49 -0
  331. painapple_code/static/js/widget-system/init.js +54 -0
  332. painapple_code/static/js/widget-system/types/bottom-sheet.js +307 -0
  333. painapple_code/static/js/widget-system/types/floating.js +915 -0
  334. painapple_code/static/js/widget-system/types/index.js +40 -0
  335. painapple_code/static/js/widget-system/types/modal.js +147 -0
  336. painapple_code/static/js/widget-system/types/sidebar.js +158 -0
  337. painapple_code/static/js/widget-system/types/tab.js +146 -0
  338. painapple_code/static/js/widget-system/types/top-sheet.js +203 -0
  339. painapple_code/static/js/widget-system/widget-manager.js +1187 -0
  340. painapple_code/static/js/widgets/about-widget.js +260 -0
  341. painapple_code/static/js/widgets/active-sessions-widget.js +760 -0
  342. painapple_code/static/js/widgets/agents-widget.js +897 -0
  343. painapple_code/static/js/widgets/browser-widget.js +579 -0
  344. painapple_code/static/js/widgets/commands-widget.js +694 -0
  345. painapple_code/static/js/widgets/config/commit-sections.js +449 -0
  346. painapple_code/static/js/widgets/config/dir-autocomplete.js +224 -0
  347. painapple_code/static/js/widgets/config/gestures.js +161 -0
  348. painapple_code/static/js/widgets/config/models-tab.js +988 -0
  349. painapple_code/static/js/widgets/config/quick-actions-tab.js +882 -0
  350. painapple_code/static/js/widgets/config/shortcut-editor.js +587 -0
  351. painapple_code/static/js/widgets/config/state.js +517 -0
  352. painapple_code/static/js/widgets/config/system-controls.js +90 -0
  353. painapple_code/static/js/widgets/config-widget.js +1535 -0
  354. painapple_code/static/js/widgets/cost-analytics-widget.js +621 -0
  355. painapple_code/static/js/widgets/debug-widget.js +693 -0
  356. painapple_code/static/js/widgets/diff-viewer-widget.js +1420 -0
  357. painapple_code/static/js/widgets/discussion-widget.js +1107 -0
  358. painapple_code/static/js/widgets/file-explorer-widget.js +2166 -0
  359. painapple_code/static/js/widgets/file-preview-widget.js +861 -0
  360. painapple_code/static/js/widgets/git-widget.js +794 -0
  361. painapple_code/static/js/widgets/helpers-install-widget.js +720 -0
  362. painapple_code/static/js/widgets/history-explorer-widget.js +1804 -0
  363. painapple_code/static/js/widgets/image-annotate-widget.js +951 -0
  364. painapple_code/static/js/widgets/image-preview-widget.js +692 -0
  365. painapple_code/static/js/widgets/index.js +176 -0
  366. painapple_code/static/js/widgets/log-explorer-widget.js +1057 -0
  367. painapple_code/static/js/widgets/plugins-widget.js +305 -0
  368. painapple_code/static/js/widgets/prompt-explorer-widget.js +1119 -0
  369. painapple_code/static/js/widgets/search-files-widget.js +529 -0
  370. painapple_code/static/js/widgets/skills-widget.js +843 -0
  371. painapple_code/static/js/widgets/snippets-widget.js +479 -0
  372. painapple_code/static/js/widgets/sub-agents-widget.js +333 -0
  373. painapple_code/static/js/widgets/tasks-widget.js +379 -0
  374. painapple_code/static/js/widgets/terminal/connection.js +283 -0
  375. painapple_code/static/js/widgets/terminal/gestures.js +357 -0
  376. painapple_code/static/js/widgets/terminal/init.js +642 -0
  377. painapple_code/static/js/widgets/terminal/link-providers.js +532 -0
  378. painapple_code/static/js/widgets/terminal/osc52.js +213 -0
  379. painapple_code/static/js/widgets/terminal/render.js +159 -0
  380. painapple_code/static/js/widgets/terminal/size.js +54 -0
  381. painapple_code/static/js/widgets/terminal/state.js +211 -0
  382. painapple_code/static/js/widgets/terminal/wrap-utils.js +101 -0
  383. painapple_code/static/js/widgets/terminal-widget.js +793 -0
  384. painapple_code/static/js/widgets/uploads-widget.js +461 -0
  385. painapple_code/static/js/widgets/zen-widget.js +1001 -0
  386. painapple_code/static/login.html +51 -0
  387. painapple_code/static/manifest.json +73 -0
  388. painapple_code/static/sw.js +293 -0
  389. painapple_code/static/vendor/LICENSES.txt +769 -0
  390. painapple_code/static/vendor/README.md +103 -0
  391. painapple_code/static/vendor/codemirror.js +35 -0
  392. painapple_code/static/vendor/codemirror.js.LEGAL.txt +304 -0
  393. painapple_code/static/vendor/github-markdown-dark.min.css +1124 -0
  394. painapple_code/static/vendor/highlight-github-dark.min.css +10 -0
  395. painapple_code/static/vendor/highlight-lang-dockerfile.min.js +8 -0
  396. painapple_code/static/vendor/highlight-lang-nginx.min.js +21 -0
  397. painapple_code/static/vendor/highlight-lang-properties.min.js +10 -0
  398. painapple_code/static/vendor/highlight-lang-scala.min.js +28 -0
  399. painapple_code/static/vendor/highlight.min.js +1213 -0
  400. painapple_code/static/vendor/marked.min.js +6 -0
  401. painapple_code/static/vendor/purify.min.js +3 -0
  402. painapple_code/static/vendor/xterm-addon-fit.js +2 -0
  403. painapple_code/static/vendor/xterm.css +209 -0
  404. painapple_code/static/vendor/xterm.js +2 -0
  405. painapple_code/static/web-client.html +635 -0
  406. painapple_code/subprocess_registry.py +535 -0
  407. painapple_code/tls_cert.py +79 -0
  408. painapple_code/tools/agents/shadow-git-helper.md +400 -0
  409. painapple_code/tools/excalidraw-to-svg.js +143 -0
  410. painapple_code/tools/install-helpers.sh +148 -0
  411. painapple_code/tools/shadow-git +320 -0
  412. painapple_code/tools/shadow-query +120 -0
  413. painapple_code/tools/vegalite-to-svg.js +79 -0
  414. painapple_code/turn_query.py +766 -0
  415. painapple_code/turn_tracker.py +221 -0
  416. painapple_code/utils/__init__.py +0 -0
  417. painapple_code/utils/agent_cli.py +306 -0
  418. painapple_code/utils/chart.py +103 -0
  419. painapple_code/utils/excalidraw.py +107 -0
  420. painapple_code/utils/file_lock.py +162 -0
  421. painapple_code/utils/file_paths.py +648 -0
  422. painapple_code/utils/generate_icons.py +251 -0
  423. painapple_code/utils/proc.py +205 -0
  424. painapple_code/utils/pty_backend.py +59 -0
  425. painapple_code/utils/pty_posix.py +160 -0
  426. painapple_code/utils/pty_windows.py +245 -0
  427. painapple_code/utils/token_profiles.py +91 -0
  428. painapple_code/viewer_templates.py +657 -0
  429. painapple_code/welcome_search.py +879 -0
  430. painapple_code-1.0.0.dist-info/METADATA +292 -0
  431. painapple_code-1.0.0.dist-info/RECORD +436 -0
  432. painapple_code-1.0.0.dist-info/WHEEL +5 -0
  433. painapple_code-1.0.0.dist-info/entry_points.txt +2 -0
  434. painapple_code-1.0.0.dist-info/licenses/LICENSE +661 -0
  435. painapple_code-1.0.0.dist-info/licenses/THIRD_PARTY_NOTICES.md +261 -0
  436. painapple_code-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,520 @@
1
+ """
2
+ Shadow Git - Configurable commit sections.
3
+
4
+ The section definitions in `BUILTIN_SECTIONS` drive what the summary fork emits in
5
+ each rich commit: each entry becomes a key in the JSON schema fed to the model
6
+ and a `## Title` block in the resulting markdown commit body. Users can extend
7
+ or override sections via per-project config (`shadow_git.commit_sections`).
8
+
9
+ Public functions (consumed by ShadowGit and `routes/api_app_commit_sections.py`):
10
+ - `get_sections_config` — merge builtins with user overrides
11
+ - `build_commit_schema` — JSON schema for `--json-schema` output mode
12
+ - `build_commit_prompt_for_json` — natural-language prompt that mirrors the schema
13
+ - `structured_to_markdown` — render the summary fork's JSON response back into commit-body markdown
14
+
15
+ Also exposes `COMMIT_PROMPT_COMPACTION` — the prompt used when capturing a
16
+ compaction-checkpoint commit (no schema; freeform text).
17
+ """
18
+
19
+ # Built-in sections that users can enable/disable but not delete
20
+ # Each section has:
21
+ # - id: unique identifier (used in config)
22
+ # - title: markdown header (## Title)
23
+ # - prompt: instructions for the summarizer
24
+ # - required: if True, cannot be disabled
25
+ # - default_enabled: initial state
26
+ # - order: default sort order (10, 20, 30...)
27
+ # - applies_to: list of prompt types ["file_changes", "tool_only"]
28
+
29
+ BUILTIN_SECTIONS = {
30
+ "summary": {
31
+ "id": "summary",
32
+ "title": "Summary",
33
+ "prompt": "ONE SENTENCE: what was accomplished this turn. Future turns will see this as journey context, so make it concrete and informative — reference earlier turns when building on them (e.g., \"Fixed the CORS issue from turn 2 by switching to Authorization headers\"). Just the sentence, no prefix.",
34
+ "prompt_tool_only": "ONE SENTENCE: what was investigated and the key finding. Future turns will see this as journey context, so include the discovery (e.g., \"Investigated API routing — found 12 handlers across 4 controllers, all using JWT auth\"). Just the sentence, no prefix.",
35
+ "required": True,
36
+ "default_enabled": True,
37
+ "order": 10,
38
+ "applies_to": ["file_changes", "tool_only"],
39
+ },
40
+ "tags": {
41
+ "id": "tags",
42
+ "title": "Tags",
43
+ "prompt": "Searchable tags for this work. Include relevant: work type (bugfix, feature, refactor), domain (ui, api, auth), code elements (class names, functions, components), and technical concepts.",
44
+ "field_type": "array",
45
+ "required": False,
46
+ "default_enabled": True,
47
+ "order": 11,
48
+ "applies_to": ["file_changes", "tool_only"],
49
+ },
50
+ "entities": {
51
+ "id": "entities",
52
+ "title": "Entities",
53
+ "prompt": "Named code elements referenced or modified. Format: name:type (e.g., SessionManager:class, handleClick:function, deploy:endpoint). Skip filenames — they are tracked separately. Use consistent type labels.",
54
+ "prompt_tool_only": "Named code elements examined or discussed. Format: name:type (e.g., SessionManager:class, handleClick:function, deploy:endpoint). Skip filenames — they are tracked separately. Use consistent type labels.",
55
+ "field_type": "array",
56
+ "required": False,
57
+ "default_enabled": True,
58
+ "order": 12,
59
+ "applies_to": ["file_changes", "tool_only"],
60
+ },
61
+ "plan_title": {
62
+ "id": "plan_title",
63
+ "title": "Plan Title",
64
+ "prompt": "Short title (3-6 words) for the plan designed in this turn. What is being planned? Examples: 'Background Tasks Feature', 'JWT Auth Refactor', 'DuckDB Plan Tracking'. Just the title, no prefix.",
65
+ "required": False,
66
+ "default_enabled": True,
67
+ "order": 14,
68
+ "applies_to": ["file_changes", "tool_only"],
69
+ "only_when_tools": ["EnterPlanMode", "ExitPlanMode"],
70
+ },
71
+ "plan_summary": {
72
+ "id": "plan_summary",
73
+ "title": "Plan Summary",
74
+ "prompt": "2-3 sentence summary of what this plan proposes. What problem does it solve? What's the approach? What are the key components or changes?",
75
+ "required": False,
76
+ "default_enabled": True,
77
+ "order": 15,
78
+ "applies_to": ["file_changes", "tool_only"],
79
+ "only_when_tools": ["EnterPlanMode", "ExitPlanMode"],
80
+ },
81
+ "work_done": {
82
+ "id": "work_done",
83
+ "title": "Work Done",
84
+ "prompt": "- Bullet points of specific changes\n- Include patterns introduced or modified",
85
+ "required": False,
86
+ "default_enabled": True,
87
+ "order": 20,
88
+ "applies_to": ["file_changes"],
89
+ },
90
+ "investigation": {
91
+ "id": "investigation",
92
+ "title": "Investigation",
93
+ "prompt": "- What you examined and why\n- Hypothesis tested",
94
+ "required": False,
95
+ "default_enabled": True,
96
+ "order": 20,
97
+ "applies_to": ["tool_only"],
98
+ },
99
+ "findings": {
100
+ "id": "findings",
101
+ "title": "Findings",
102
+ "prompt": "- Key discoveries\n- Conclusions reached\n- Questions answered",
103
+ "required": False,
104
+ "default_enabled": True,
105
+ "order": 25,
106
+ "applies_to": ["tool_only"],
107
+ },
108
+ "decisions": {
109
+ "id": "decisions",
110
+ "title": "Decisions",
111
+ "prompt": "- Why this approach (vs alternatives considered)\n- Trade-offs made\n- Patterns chosen and why",
112
+ "required": False,
113
+ "default_enabled": True,
114
+ "order": 30,
115
+ "applies_to": ["file_changes"],
116
+ },
117
+ "problems_solved": {
118
+ "id": "problems_solved",
119
+ "title": "Problems Solved",
120
+ "prompt": "- What issue/bug was fixed (if any)\n- Root cause identified\n- Solution approach\n- Reference previous turns if this fixes an earlier issue",
121
+ "required": False,
122
+ "default_enabled": True,
123
+ "order": 40,
124
+ "applies_to": ["file_changes"],
125
+ },
126
+ "verification": {
127
+ "id": "verification",
128
+ "title": "Verification",
129
+ "prompt": "Commands to verify/test this work (only if tests/checks were run). Format: `command` - what it verifies\nExample: `pytest test_session.py::test_reconnect -v` - WebSocket reconnect\nExample: `curl localhost:8765/api/sessions | jq length` - API returns sessions\nSkip if no verification was done.",
130
+ "prompt_tool_only": "Commands used to investigate/verify. Format: `command` - what it checked\nExample: `curl -s localhost:8765/api/sessions | jq .` - checked API response\nSkip if no commands worth remembering.",
131
+ "required": False,
132
+ "default_enabled": True,
133
+ "order": 45,
134
+ "applies_to": ["file_changes", "tool_only"],
135
+ },
136
+ "commands": {
137
+ "id": "commands",
138
+ "title": "Commands",
139
+ "prompt": (
140
+ "Reusable shell commands from this turn worth remembering. "
141
+ "Include: diagnostic one-liners, curl/API calls, build/install commands, "
142
+ "project-specific scripts, data extraction pipelines, "
143
+ "and any command someone might search for later.\n"
144
+ "Exclude: trivial navigation (cd, ls, cat), routine git (add, commit, push), "
145
+ "and simple file reads.\n"
146
+ "Format: `command` - what it does\n"
147
+ "Example: `curl -s localhost:8765/api/sessions | jq '.[].name'` - list session names\n"
148
+ "Example: `lsof -i :8880 -t | xargs kill` - kill process on dev port\n"
149
+ "Example: `python3 -c \"import ast; ast.parse(open('server.py').read())\"` - syntax check\n"
150
+ "Skip if no interesting commands were run."
151
+ ),
152
+ "prompt_tool_only": (
153
+ "Reusable shell commands from this investigation worth remembering. "
154
+ "Include: diagnostic one-liners, curl/API calls, search commands with useful flags, "
155
+ "project-specific scripts, data extraction pipelines, "
156
+ "and any command someone might search for later.\n"
157
+ "Exclude: trivial navigation (cd, ls, cat), routine git (add, commit, push), "
158
+ "and simple file reads.\n"
159
+ "Format: `command` - what it does\n"
160
+ "Example: `du -sh ~/.painapple-code/projects/*/shadow-git/` - shadow git repo sizes\n"
161
+ "Example: `shadow-query 'SELECT count(*) FROM turns'` - total turn count via /api/shadow-db/sql\n"
162
+ "Example: `grep -rn 'ORPHAN_PROCESS_TIMEOUT' services/` - find timeout constant\n"
163
+ "Skip if no interesting commands were run."
164
+ ),
165
+ "field_type": "array",
166
+ "required": False,
167
+ "default_enabled": True,
168
+ "order": 47,
169
+ "applies_to": ["file_changes", "tool_only"],
170
+ },
171
+ "tools_used": {
172
+ "id": "tools_used",
173
+ "title": "Tools Used",
174
+ "prompt": "- Tool: input → key finding",
175
+ "required": False,
176
+ "default_enabled": True,
177
+ "order": 50,
178
+ "applies_to": ["file_changes", "tool_only"],
179
+ },
180
+ "context_for_resume": {
181
+ "id": "context_for_resume",
182
+ "title": "Context for Resume",
183
+ "prompt": "- Current state: what works now\n- Open items: what's left to do\n- Gotchas: things to remember",
184
+ "prompt_tool_only": "- Current understanding\n- Next steps to try\n- Related areas to explore",
185
+ "required": False,
186
+ "default_enabled": True,
187
+ "order": 60,
188
+ "applies_to": ["file_changes", "tool_only"],
189
+ },
190
+ "learnings": {
191
+ "id": "learnings",
192
+ "title": "Learnings",
193
+ "prompt": "- Discoveries worth remembering\n- Warnings for future work",
194
+ "prompt_tool_only": "- Things discovered worth remembering\n- Gotchas or warnings",
195
+ "required": False,
196
+ "default_enabled": True,
197
+ "order": 70,
198
+ "applies_to": ["file_changes", "tool_only"],
199
+ },
200
+ "session_title": {
201
+ "id": "session_title",
202
+ "title": "Session Title",
203
+ "prompt": """A SHORT title (3-6 words) for this entire session. This helps identify the session later.
204
+ - Capture the main goal or theme of the work
205
+ - Update if the focus has shifted from previous turns
206
+ - Examples: "JWT Auth Refactor", "Widget Empty Fix", "Cost Analytics Feature"
207
+ - Just the title, no prefix or formatting.""",
208
+ "required": True,
209
+ "default_enabled": True,
210
+ "order": 10,
211
+ "applies_to": ["file_changes", "tool_only"],
212
+ },
213
+ }
214
+
215
+
216
+ def get_sections_config(project_config: dict) -> dict:
217
+ """
218
+ Merge user's section config with built-in defaults.
219
+
220
+ Args:
221
+ project_config: Project config dict (from load_project_config)
222
+
223
+ Returns:
224
+ Dict of section_id -> merged section config
225
+ """
226
+ user_sections = project_config.get("shadow_git", {}).get("commit_sections", {})
227
+ result = {}
228
+
229
+ # Start with built-in sections
230
+ for section_id, builtin in BUILTIN_SECTIONS.items():
231
+ merged = builtin.copy()
232
+
233
+ # Apply user overrides
234
+ if section_id in user_sections:
235
+ user = user_sections[section_id]
236
+ if "enabled" in user:
237
+ # Can't disable required sections
238
+ if not builtin["required"]:
239
+ merged["enabled"] = user["enabled"]
240
+ else:
241
+ merged["enabled"] = True
242
+ else:
243
+ merged["enabled"] = builtin["default_enabled"]
244
+
245
+ if "order" in user:
246
+ merged["order"] = user["order"]
247
+
248
+ # Allow customizing prompt for non-required sections
249
+ if "prompt" in user and not builtin["required"]:
250
+ merged["prompt"] = user["prompt"]
251
+ else:
252
+ merged["enabled"] = builtin["default_enabled"]
253
+
254
+ merged["builtin"] = True
255
+ result[section_id] = merged
256
+
257
+ # Add custom user sections
258
+ for section_id, user_section in user_sections.items():
259
+ if section_id not in BUILTIN_SECTIONS:
260
+ # Custom section - must have title and prompt
261
+ if "title" in user_section and "prompt" in user_section:
262
+ result[section_id] = {
263
+ "id": section_id,
264
+ "title": user_section["title"],
265
+ "prompt": user_section["prompt"],
266
+ "prompt_tool_only": user_section.get("prompt_tool_only", user_section["prompt"]),
267
+ "required": False,
268
+ "enabled": user_section.get("enabled", True),
269
+ "order": user_section.get("order", 55), # Default between tools_used and context
270
+ "applies_to": user_section.get("applies_to", ["file_changes", "tool_only"]),
271
+ "field_type": user_section.get("field_type", "array"), # "string" or "array"
272
+ "builtin": False,
273
+ }
274
+
275
+ return result
276
+
277
+
278
+ def build_commit_schema(project_config: dict, prompt_type: str) -> dict:
279
+ """
280
+ Build JSON schema for structured commit message output.
281
+
282
+ The schema is dynamic based on which sections are enabled.
283
+
284
+ Args:
285
+ project_config: Project config dict
286
+ prompt_type: "file_changes" or "tool_only"
287
+
288
+ Returns:
289
+ JSON schema dict for --json-schema flag
290
+ """
291
+ sections_config = get_sections_config(project_config)
292
+
293
+ # Filter enabled sections for this prompt type
294
+ enabled_sections = [
295
+ s for s in sections_config.values()
296
+ if s.get("enabled", True) and prompt_type in s.get("applies_to", [])
297
+ ]
298
+
299
+ # Build properties for each enabled section
300
+ properties = {}
301
+ required = []
302
+
303
+ for section in enabled_sections:
304
+ section_id = section["id"]
305
+
306
+ # Determine field type - user can override, defaults based on section
307
+ # field_type: "string" for single value, "array" for bullet points
308
+ field_type = section.get("field_type")
309
+ if not field_type:
310
+ # Default: summary/title are strings, rest are arrays
311
+ if section_id in ("summary", "session_title"):
312
+ field_type = "string"
313
+ else:
314
+ field_type = "array"
315
+
316
+ if field_type == "string":
317
+ properties[section_id] = {
318
+ "type": "string",
319
+ "description": section.get("prompt", "")
320
+ }
321
+ else:
322
+ properties[section_id] = {
323
+ "type": "array",
324
+ "items": {"type": "string"},
325
+ "description": section.get("prompt", "")
326
+ }
327
+
328
+ # Required sections must be present
329
+ if section.get("required"):
330
+ required.append(section_id)
331
+
332
+ return {
333
+ "type": "object",
334
+ "properties": properties,
335
+ "required": required,
336
+ "additionalProperties": False
337
+ }
338
+
339
+
340
+ def build_commit_prompt_for_json(
341
+ project_config: dict,
342
+ prompt_type: str,
343
+ journey_section: str,
344
+ user_prompt: str,
345
+ files: str = "",
346
+ tools: str = ""
347
+ ) -> str:
348
+ """
349
+ Build prompt for JSON structured output (used with --json-schema).
350
+
351
+ Simpler than markdown prompt since schema enforces structure.
352
+
353
+ Args:
354
+ project_config: Project config dict
355
+ prompt_type: "file_changes" or "tool_only"
356
+ journey_section: Formatted journey context
357
+ user_prompt: User's original request
358
+ files: Comma-separated file list (for file_changes)
359
+ tools: Formatted tools list
360
+
361
+ Returns:
362
+ Prompt string for the summarizer (JSON output)
363
+ """
364
+ sections_config = get_sections_config(project_config)
365
+
366
+ # Parse tool names from the tools string for conditional section filtering
367
+ tools_set = set(t.strip() for t in tools.split(",")) if tools else set()
368
+
369
+ # Filter and sort enabled sections for this prompt type
370
+ enabled_sections = []
371
+ for s in sections_config.values():
372
+ if not s.get("enabled", True):
373
+ continue
374
+ if prompt_type not in s.get("applies_to", []):
375
+ continue
376
+ # Conditional sections: only include when specific tools were used
377
+ only_when = s.get("only_when_tools")
378
+ if only_when and not (set(only_when) & tools_set):
379
+ continue
380
+ enabled_sections.append(s)
381
+ enabled_sections.sort(key=lambda s: s.get("order", 50))
382
+
383
+ # Build intro
384
+ if prompt_type == "file_changes":
385
+ intro = "You just completed a turn helping the user. Generate a structured commit message as JSON."
386
+ else:
387
+ intro = "You just completed a turn (no files modified). Generate a structured commit message documenting your investigation as JSON."
388
+
389
+ # Build context
390
+ parts = [intro, ""]
391
+
392
+ if journey_section:
393
+ parts.append(journey_section)
394
+
395
+ parts.append(f"USER'S REQUEST:\n{user_prompt}")
396
+ parts.append("")
397
+
398
+ if prompt_type == "file_changes" and files:
399
+ parts.append(f"FILES MODIFIED: {files}")
400
+ parts.append("")
401
+
402
+ parts.append(f"TOOLS USED: {tools}")
403
+ parts.append("")
404
+
405
+ # Field instructions
406
+ parts.append("Fill each JSON field according to these guidelines:")
407
+ parts.append("")
408
+
409
+ for section in enabled_sections:
410
+ section_id = section["id"]
411
+ if prompt_type == "tool_only" and "prompt_tool_only" in section:
412
+ prompt_text = section["prompt_tool_only"]
413
+ else:
414
+ prompt_text = section["prompt"]
415
+
416
+ clean_prompt = prompt_text.replace("\n", " ").strip()
417
+ parts.append(f"- {section_id}: {clean_prompt}")
418
+
419
+ parts.append("")
420
+ parts.append("Be concise. Use keywords that are searchable.")
421
+
422
+ return "\n".join(parts)
423
+
424
+
425
+ def structured_to_markdown(structured: dict, project_config: dict, prompt_type: str) -> str:
426
+ """
427
+ Convert structured JSON response back to markdown for git commit message.
428
+
429
+ Args:
430
+ structured: Parsed JSON response from the summary fork
431
+ project_config: Project config dict
432
+ prompt_type: "file_changes" or "tool_only"
433
+
434
+ Returns:
435
+ Markdown formatted commit message body
436
+ """
437
+ sections_config = get_sections_config(project_config)
438
+
439
+ # Filter and sort enabled sections
440
+ enabled_sections = [
441
+ s for s in sections_config.values()
442
+ if s.get("enabled", True) and prompt_type in s.get("applies_to", [])
443
+ ]
444
+ enabled_sections.sort(key=lambda s: s.get("order", 50))
445
+
446
+ # Internal-only fields: produced by the summary fork and consumed elsewhere
447
+ # (session.name update, etc.) but not rendered as a commit-body section.
448
+ INTERNAL_ONLY = {"session_title"}
449
+
450
+ parts = []
451
+
452
+ for section in enabled_sections:
453
+ section_id = section["id"]
454
+ if section_id in INTERNAL_ONLY:
455
+ continue
456
+ title = section["title"]
457
+ value = structured.get(section_id)
458
+
459
+ if not value:
460
+ continue
461
+
462
+ parts.append(f"## {title}")
463
+
464
+ if isinstance(value, list):
465
+ for item in value:
466
+ if item:
467
+ parts.append(f"- {item}")
468
+ else:
469
+ parts.append(str(value))
470
+
471
+ parts.append("")
472
+
473
+ return "\n".join(parts).strip()
474
+
475
+
476
+ COMMIT_PROMPT_COMPACTION = """This conversation is about to be compacted. Generate a COMPREHENSIVE summary to preserve important context that will be lost.
477
+
478
+ Generate with this EXACT structure:
479
+
480
+ ## Session Overview
481
+ What was the user trying to accomplish? Key goals.
482
+
483
+ ## Tags
484
+ All relevant tags from the session: #feature #bugfix etc. + domain tags
485
+
486
+ ## Work Completed
487
+ - Major features/changes implemented
488
+ - Key milestones reached
489
+
490
+ ## Decisions Made
491
+ - Architectural decisions and rationale
492
+ - Trade-offs chosen
493
+ - Patterns established
494
+
495
+ ## Problems Solved
496
+ - Issues debugged
497
+ - Root causes found
498
+ - Solutions that worked
499
+
500
+ ## Files Changed
501
+ - Key files modified and why
502
+ - New files created
503
+ - Dependencies added
504
+
505
+ ## Current State
506
+ - What works now
507
+ - What's partially done
508
+ - Known issues
509
+
510
+ ## Critical Context
511
+ - Things that MUST be remembered
512
+ - Gotchas discovered
513
+ - Warnings for future work
514
+
515
+ ## Open Items
516
+ - What's left to do
517
+ - Blockers encountered
518
+ - Questions unanswered
519
+
520
+ Be THOROUGH - this is the only record of the full context."""