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,635 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <!-- viewport-fit=contain, explicit on purpose: app surfaces (native loader, login, this page)
6
+ navigate in-place in one WKWebView, which leaks viewport-fit state across navigations. If
7
+ any surface uses cover, this page inherits cover mode and wakes the dormant
8
+ env(safe-area-inset-bottom) rules → empty bottom bar on iPad/iPhone. Keep every surface on
9
+ contain; don't introduce cover anywhere. -->
10
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=contain">
11
+ <title>pAInapple Code</title>
12
+
13
+ <!-- PWA Meta Tags -->
14
+ <meta name="description" content="Remote pAInapple Code client - AI-powered coding assistant">
15
+ <meta name="theme-color" content="#1a1a2e">
16
+ <meta name="apple-mobile-web-app-capable" content="yes">
17
+ <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
18
+ <meta name="apple-mobile-web-app-title" content="pAInapple Code">
19
+ <meta name="mobile-web-app-capable" content="yes">
20
+ <meta name="application-name" content="pAInapple Code">
21
+ <meta name="msapplication-TileColor" content="#1a1a2e">
22
+ <meta name="msapplication-config" content="none">
23
+
24
+ <!-- PWA Manifest -->
25
+ <link rel="manifest" href="/manifest.json">
26
+
27
+ <!-- Favicons & Icons -->
28
+ <link rel="icon" type="image/png" sizes="32x32" href="/static/icons/favicon-32.png">
29
+ <link rel="icon" type="image/x-icon" href="/static/icons/favicon.ico">
30
+ <link rel="apple-touch-icon" href="/static/icons/apple-touch-icon.png">
31
+ <link rel="apple-touch-icon" sizes="152x152" href="/static/icons/icon-152.png">
32
+ <link rel="apple-touch-icon" sizes="180x180" href="/static/icons/icon-180.png">
33
+ <link rel="apple-touch-icon" sizes="167x167" href="/static/icons/icon-152.png">
34
+
35
+ <!-- External Libraries (vendored via tools/package.json build pipeline) -->
36
+ <!-- Pin marked to v4 for stable API (v5+ has breaking changes) -->
37
+ <script src="/static/vendor/marked.min.js"></script>
38
+ <!-- DOMPurify sanitizes all marked output before it reaches innerHTML (XSS gate) -->
39
+ <script src="/static/vendor/purify.min.js"></script>
40
+ <script src="/static/vendor/highlight.min.js"></script>
41
+ <script src="/static/vendor/highlight-lang-dockerfile.min.js"></script>
42
+ <script src="/static/vendor/highlight-lang-scala.min.js"></script>
43
+ <script src="/static/vendor/highlight-lang-nginx.min.js"></script>
44
+ <script src="/static/vendor/highlight-lang-properties.min.js"></script>
45
+ <link rel="stylesheet" href="/static/vendor/highlight-github-dark.min.css">
46
+
47
+ <!-- Instance identity config. The server replaces the `null` body with its
48
+ JSON; a non-JS `type` makes this a data block the browser never
49
+ executes, so CSP's script-src does not gate it. boot.js reads it into
50
+ window.INSTANCE_CONFIG and MUST stay after this element. -->
51
+ <script type="application/json" id="instance-config">null</script>
52
+
53
+ <!-- Pre-app boot: instance config, layout density before first paint, and
54
+ service-worker registration. Classic script, deliberately synchronous
55
+ and render-blocking — see js/boot.js. -->
56
+ <script src="/static/js/boot.js"></script>
57
+
58
+ <!-- App Styles -->
59
+ <link rel="stylesheet" href="/static/styles.css">
60
+ </head>
61
+ <body>
62
+ <div id="app">
63
+ <!-- Header with tabs -->
64
+ <header>
65
+ <button id="rail-toggle-btn" class="rail-toggle-btn" data-tooltip-key="ui.tooltips.menu" data-shortcut-action="toggleRailMenu" aria-label="Open menu" aria-expanded="false">
66
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
67
+ <line x1="3" y1="6" x2="21" y2="6"/>
68
+ <line x1="3" y1="12" x2="21" y2="12"/>
69
+ <line x1="3" y1="18" x2="21" y2="18"/>
70
+ </svg>
71
+ <span class="rail-toggle-badge" id="rail-toggle-badge"></span>
72
+ </button>
73
+
74
+ <button class="tabs-overview-btn header-overview-btn" data-tooltip-key="ui.tooltips.all_sessions" data-shortcut-action="gridSwitcher">
75
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
76
+ <rect x="3" y="3" width="7" height="7"/>
77
+ <rect x="14" y="3" width="7" height="7"/>
78
+ <rect x="3" y="14" width="7" height="7"/>
79
+ <rect x="14" y="14" width="7" height="7"/>
80
+ </svg>
81
+ </button>
82
+
83
+ <div class="tabs-viewport">
84
+ <div id="tabs"></div>
85
+ <span class="tabs-overflow-indicator tabs-overflow-left" data-tooltip-key="ui.tooltips.tabs_overflow" style="display:none"></span>
86
+ <span class="tabs-overflow-indicator tabs-overflow-right" data-tooltip-key="ui.tooltips.tabs_overflow" style="display:none"></span>
87
+ </div>
88
+
89
+ <button id="new-tab-btn" data-tooltip-key="ui.tooltips.new_session" data-shortcut-action="newSession">
90
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
91
+ <path d="M12 5v14M5 12h14"/>
92
+ </svg>
93
+ </button>
94
+
95
+ </header>
96
+
97
+ <!-- App body: left rail + main content -->
98
+ <div id="app-body">
99
+ <!-- Scrim shown behind the rail drawer on mobile -->
100
+ <div id="rail-scrim" aria-hidden="true"></div>
101
+
102
+ <!-- Left rail with navigation icons -->
103
+ <nav id="left-rail">
104
+ <!-- Drawer header (mobile only) — instance label + tabs-overview button.
105
+ The instance badge is relocated here from <header> by app.js on mobile. -->
106
+ <div class="rail-drawer-header">
107
+ <button class="tabs-overview-btn rail-drawer-grid" data-tooltip-key="ui.tooltips.all_sessions" data-shortcut-action="gridSwitcher">
108
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
109
+ <rect x="3" y="3" width="7" height="7"/>
110
+ <rect x="14" y="3" width="7" height="7"/>
111
+ <rect x="3" y="14" width="7" height="7"/>
112
+ <rect x="14" y="14" width="7" height="7"/>
113
+ </svg>
114
+ </button>
115
+ </div>
116
+
117
+ <!-- Activity / running things (badge-driven) -->
118
+ <button class="rail-btn has-badges" id="rail-sessions-btn" data-tooltip-key="ui.tooltips.rail_sessions" data-tooltip-position="right" data-shortcut-action="toggleActiveSessions">
119
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
120
+ <polyline points="22 12 18 12 15 21 9 3 6 12 2 12"/>
121
+ </svg>
122
+ <span class="rail-badge sessions-badge" id="sessions-badge"></span>
123
+ <span class="rail-badge summary-badge" id="summary-badge"></span>
124
+ </button>
125
+ <div class="orphan-terminals-btn rail-btn-wrap" id="orphan-terminals-btn">
126
+ <button class="rail-btn has-badges" id="rail-orphan-terminals-btn" data-tooltip-key="ui.tooltips.rail_orphan_terminals" data-tooltip-position="right">
127
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
128
+ <polyline points="4 17 10 11 4 5"/>
129
+ <line x1="12" y1="19" x2="20" y2="19"/>
130
+ <circle cx="19" cy="6" r="2.2" fill="currentColor" stroke="none"/>
131
+ </svg>
132
+ <span class="rail-badge orphan-badge" id="orphan-badge"></span>
133
+ </button>
134
+ <div class="orphan-terminals-dropdown" id="orphan-dropdown">
135
+ <div class="orphan-dropdown-header">
136
+ <span>Orphaned Terminals</span>
137
+ <div class="orphan-bulk-actions" id="orphan-bulk-actions">
138
+ <button class="bulk-btn" id="orphan-tab-all-btn" data-tooltip-key="ui.tooltips.orphan_tab_all">Tab All</button>
139
+ <button class="bulk-btn danger" id="orphan-kill-all-btn" data-tooltip-key="ui.tooltips.orphan_kill_all">Kill All</button>
140
+ </div>
141
+ <button class="refresh-btn" id="orphan-refresh-btn" data-tooltip-key="ui.tooltips.orphan_refresh">
142
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
143
+ <path d="M23 4v6h-6M1 20v-6h6"/>
144
+ <path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/>
145
+ </svg>
146
+ </button>
147
+ </div>
148
+ <div class="orphan-dropdown-list" id="orphan-list"></div>
149
+ </div>
150
+ </div>
151
+ <button class="rail-btn has-badges" id="rail-agents-btn" data-tooltip-key="ui.tooltips.rail_agents" data-tooltip-position="right">
152
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
153
+ <rect x="3" y="3" width="7" height="7"/>
154
+ <rect x="14" y="3" width="7" height="7"/>
155
+ <rect x="3" y="14" width="7" height="7"/>
156
+ <rect x="14" y="14" width="7" height="7"/>
157
+ </svg>
158
+ <span class="rail-badge agents-badge" id="agents-badge"></span>
159
+ </button>
160
+ <button class="rail-btn has-badges" id="rail-bg-tasks-btn" data-tooltip-key="ui.tooltips.rail_bg_tasks" data-tooltip-position="right">
161
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
162
+ <line x1="12" y1="2" x2="12" y2="6"/>
163
+ <line x1="12" y1="18" x2="12" y2="22"/>
164
+ <line x1="4.93" y1="4.93" x2="7.76" y2="7.76"/>
165
+ <line x1="16.24" y1="16.24" x2="19.07" y2="19.07"/>
166
+ <line x1="2" y1="12" x2="6" y2="12"/>
167
+ <line x1="18" y1="12" x2="22" y2="12"/>
168
+ <line x1="4.93" y1="19.07" x2="7.76" y2="16.24"/>
169
+ <line x1="16.24" y1="7.76" x2="19.07" y2="4.93"/>
170
+ </svg>
171
+ <span class="rail-badge tasks-badge" id="tasks-badge"></span>
172
+ </button>
173
+
174
+ <div class="rail-separator"></div>
175
+
176
+ <!-- Files / Code -->
177
+ <button class="rail-btn" id="rail-files-btn" data-tooltip-key="ui.tooltips.rail_files" data-tooltip-position="right" data-shortcut-action="toggleFiles">
178
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
179
+ <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/>
180
+ </svg>
181
+ </button>
182
+ <button class="rail-btn" id="rail-preview-btn" data-tooltip-key="ui.tooltips.rail_preview" data-tooltip-position="right" data-shortcut-action="togglePreview">
183
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
184
+ <path d="M1 12s4-7 11-7 11 7 11 7-4 7-11 7-11-7-11-7z"/>
185
+ <circle cx="12" cy="12" r="3"/>
186
+ </svg>
187
+ </button>
188
+ <button class="rail-btn" id="rail-logs-btn" data-tooltip-key="ui.tooltips.rail_logs" data-tooltip-position="right" data-shortcut-action="toggleLogs">
189
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
190
+ <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/>
191
+ <polyline points="14 2 14 8 20 8"/>
192
+ <line x1="16" y1="13" x2="8" y2="13"/>
193
+ <line x1="16" y1="17" x2="8" y2="17"/>
194
+ </svg>
195
+ </button>
196
+ <button class="rail-btn" id="rail-terminal-btn" data-tooltip-key="ui.tooltips.rail_terminal" data-tooltip-position="right" data-shortcut-action="toggleTerminal">
197
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
198
+ <polyline points="4 17 10 11 4 5"/>
199
+ <line x1="12" y1="19" x2="20" y2="19"/>
200
+ </svg>
201
+ </button>
202
+ <button class="rail-btn" id="rail-git-btn" data-tooltip-key="ui.tooltips.rail_git" data-tooltip-position="right" data-shortcut-action="toggleGit">
203
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
204
+ <circle cx="18" cy="18" r="3"/>
205
+ <circle cx="6" cy="6" r="3"/>
206
+ <path d="M6 21V9a9 9 0 0 0 9 9"/>
207
+ </svg>
208
+ </button>
209
+ <button class="rail-btn" id="rail-browser-btn" data-tooltip-key="ui.tooltips.rail_browser" data-tooltip-position="right" data-shortcut-action="toggleBrowser">
210
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
211
+ <circle cx="12" cy="12" r="10"/>
212
+ <line x1="2" y1="12" x2="22" y2="12"/>
213
+ <path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/>
214
+ </svg>
215
+ </button>
216
+
217
+ <div class="rail-separator"></div>
218
+
219
+ <!-- Find -->
220
+ <button class="rail-btn" id="rail-search-btn" data-tooltip-key="ui.tooltips.rail_search" data-tooltip-position="right" data-shortcut-action="search">
221
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
222
+ <circle cx="11" cy="11" r="8"/>
223
+ <path d="M21 21l-4.35-4.35"/>
224
+ </svg>
225
+ </button>
226
+ <button class="rail-btn" id="rail-history-btn" data-tooltip-key="ui.tooltips.rail_history" data-tooltip-position="right" data-shortcut-action="toggleHistoryExplorer">
227
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
228
+ <circle cx="12" cy="12" r="10"/>
229
+ <polyline points="12 6 12 12 16 14"/>
230
+ </svg>
231
+ </button>
232
+
233
+ <div class="rail-separator"></div>
234
+
235
+ <!-- Library (skills / agents / snippets — manageable assets) -->
236
+ <button class="rail-btn" id="rail-skills-btn" data-tooltip-key="ui.tooltips.rail_skills" data-tooltip-position="right" data-shortcut-action="toggleSkills">
237
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
238
+ <line x1="12" y1="2" x2="12" y2="22"/>
239
+ <path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/>
240
+ </svg>
241
+ </button>
242
+ <button class="rail-btn" id="rail-agent-defs-btn" data-tooltip-key="ui.tooltips.rail_agent_defs" data-tooltip-position="right">
243
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
244
+ <path d="M9.5 2A2.5 2.5 0 0 1 12 4.5v15a2.5 2.5 0 0 1-4.96.44 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 1.32-4.24 2.5 2.5 0 0 1 4.44-1.54"/>
245
+ <path d="M14.5 2A2.5 2.5 0 0 0 12 4.5v15a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-1.32-4.24 2.5 2.5 0 0 0-4.44-1.54"/>
246
+ </svg>
247
+ </button>
248
+ <button class="rail-btn" id="rail-snippets-btn" data-tooltip-key="ui.tooltips.rail_snippets" data-tooltip-position="right">
249
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
250
+ <polyline points="16 18 22 12 16 6"/>
251
+ <polyline points="8 6 2 12 8 18"/>
252
+ </svg>
253
+ </button>
254
+
255
+ <div class="rail-separator"></div>
256
+
257
+ <button class="rail-btn" id="rail-discussion-btn" data-tooltip-key="ui.tooltips.rail_discussion" data-tooltip-position="right" data-shortcut-action="toggleDiscussion">
258
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
259
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
260
+ </svg>
261
+ <span class="rail-badge" id="rail-discussion-badge"></span>
262
+ </button>
263
+
264
+ <div class="rail-spacer"></div>
265
+
266
+ <button class="rail-btn" id="rail-cost-btn" data-tooltip-key="ui.tooltips.rail_costs" data-tooltip-position="right" data-shortcut-action="toggleCostAnalytics">
267
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
268
+ <circle cx="8" cy="8" r="6"/>
269
+ <path d="M18.09 10.37A6 6 0 1 1 10.34 18"/>
270
+ <path d="M7 6h1v4"/>
271
+ <path d="m16.71 13.88.7.71-2.82 2.82"/>
272
+ </svg>
273
+ </button>
274
+ <button class="rail-btn" id="rail-layout-btn" data-tooltip-key="ui.tooltips.rail_layout" data-tooltip-position="right">
275
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round">
276
+ <line x1="4" y1="5" x2="20" y2="5"/>
277
+ <line x1="4" y1="12" x2="20" y2="12"/>
278
+ <line x1="4" y1="19" x2="20" y2="19"/>
279
+ </svg>
280
+ </button>
281
+ <button class="rail-btn" id="rail-settings-btn" data-tooltip-key="ui.tooltips.rail_settings" data-tooltip-position="right" data-shortcut-action="settings">
282
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
283
+ <circle cx="12" cy="12" r="3"/>
284
+ <path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"/>
285
+ </svg>
286
+ </button>
287
+ <button class="rail-btn" id="rail-help-btn" data-tooltip-key="ui.tooltips.rail_help" data-tooltip-position="right" data-shortcut-action="help">
288
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
289
+ <circle cx="12" cy="12" r="10"/>
290
+ <path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3M12 17h.01"/>
291
+ </svg>
292
+ </button>
293
+ </nav>
294
+
295
+ <!-- Main content area -->
296
+ <div id="main-content">
297
+ <!-- Connection bar (shown when disconnected) — single button
298
+ that opens the Open dialog; label set from strings.js -->
299
+ <div id="connection-bar">
300
+ <button id="open-folder-btn"></button>
301
+ </div>
302
+
303
+ <!-- Confirm dialog for creating directories -->
304
+ <div id="confirm-dialog">
305
+ <div class="confirm-box">
306
+ <h4>Directory not found</h4>
307
+ <p>The directory <code id="confirm-path"></code> does not exist. Would you like to create it?</p>
308
+ <div class="confirm-buttons">
309
+ <button class="cancel-btn" id="confirm-cancel">Cancel</button>
310
+ <button class="confirm-btn" id="confirm-create">Create Directory</button>
311
+ </div>
312
+ </div>
313
+ </div>
314
+
315
+ <!-- Session View (conversation) - active by default -->
316
+ <div id="session-view" class="view active">
317
+ <!-- Chat Search Bar -->
318
+ <div id="chat-search-bar" class="chat-search-bar">
319
+ <div class="chat-search-input-wrap">
320
+ <svg class="chat-search-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
321
+ <circle cx="11" cy="11" r="8"/>
322
+ <path d="M21 21l-4.35-4.35"/>
323
+ </svg>
324
+ <input type="text" id="chat-search-input" placeholder="Search messages..." autocomplete="off" autocorrect="off" spellcheck="false" enterkeyhint="search" />
325
+ <span id="chat-search-count" class="chat-search-count"></span>
326
+ </div>
327
+ <div class="chat-search-nav">
328
+ <button id="chat-search-prev" class="chat-search-nav-btn" data-tooltip-key="ui.tooltips.chat_search_prev">
329
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
330
+ <polyline points="18 15 12 9 6 15"/>
331
+ </svg>
332
+ </button>
333
+ <button id="chat-search-next" class="chat-search-nav-btn" data-tooltip-key="ui.tooltips.chat_search_next">
334
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
335
+ <polyline points="6 9 12 15 18 9"/>
336
+ </svg>
337
+ </button>
338
+ <button id="chat-search-close" class="chat-search-close-btn" data-tooltip-key="ui.tooltips.chat_search_close">
339
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
340
+ <line x1="18" y1="6" x2="6" y2="18"/>
341
+ <line x1="6" y1="6" x2="18" y2="18"/>
342
+ </svg>
343
+ </button>
344
+ </div>
345
+ </div>
346
+ <div id="messages-container">
347
+ <div id="messages"></div>
348
+
349
+ </div>
350
+ </div>
351
+
352
+ <!-- Input area -->
353
+ <div id="input-area">
354
+ <!-- Activity strip — between messages and input, peripheral to cursor -->
355
+ <div class="activity-strip" id="activity-strip">
356
+ <span class="activity-strip-icon"></span>
357
+ <span class="activity-strip-timer"></span>
358
+ <span class="activity-strip-text"></span>
359
+ </div>
360
+ <div id="input-wrapper">
361
+ <div id="autocomplete"></div>
362
+
363
+ <!-- Stash picker dropdown -->
364
+ <div class="stash-picker" id="stash-picker">
365
+ <div class="stash-picker-header">
366
+ <span class="stash-picker-title">Comments Stash</span>
367
+ <div class="stash-picker-actions">
368
+ <button class="stash-move-btn" id="stash-move-btn" hidden>
369
+ <!-- Content injected by stash-ui initStashUI (strings.yaml) -->
370
+ </button>
371
+ <button class="stash-picker-clear" id="stash-clear-btn">Clear All</button>
372
+ <button class="stash-picker-close" id="stash-picker-close">
373
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
374
+ <line x1="18" y1="6" x2="6" y2="18"/>
375
+ <line x1="6" y1="6" x2="18" y2="18"/>
376
+ </svg>
377
+ </button>
378
+ </div>
379
+ </div>
380
+ <div class="stash-picker-list" id="stash-picker-list">
381
+ <!-- Items rendered dynamically -->
382
+ </div>
383
+ </div>
384
+
385
+ <div id="input-container">
386
+ <div id="input-resize-handle" data-tooltip-key="ui.tooltips.input_resize"></div>
387
+
388
+ <!-- Stash preview (shown when items in stash) -->
389
+ <div class="stash-preview" id="stash-preview">
390
+ <span class="stash-preview-icon">
391
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
392
+ <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
393
+ <polyline points="17 21 17 13 7 13 7 21"/>
394
+ <polyline points="7 3 7 8 15 8"/>
395
+ </svg>
396
+ </span>
397
+ <span class="stash-preview-text" id="stash-preview-text" data-tooltip-key="ui.tooltips.stash_preview">
398
+ <span class="stash-preview-count" id="stash-preview-count">0</span>
399
+ <span class="stash-preview-label" id="stash-preview-label">references will be attached</span>
400
+ </span>
401
+ <label class="stash-toggle" data-tooltip-key="ui.tooltips.stash_toggle">
402
+ <input type="checkbox" id="stash-preview-checkbox" checked>
403
+ <span class="stash-toggle-track">
404
+ <span class="stash-toggle-thumb"></span>
405
+ </span>
406
+ </label>
407
+ </div>
408
+
409
+ <!-- Recall hint: what the prompt under the cursor was sent with -->
410
+ <div class="history-refs-hint" id="history-refs-hint"></div>
411
+
412
+ <!-- Textarea with highlight overlay for thinking keywords -->
413
+ <div class="input-textarea-wrapper">
414
+ <div id="input-highlight-backdrop" aria-hidden="true"></div>
415
+ <span class="shell-prompt-prefix" id="shell-prompt-prefix">$</span>
416
+ <textarea id="message-input" placeholder="Message Claude... · @ files · # snippets/agents · $ skills · / commands" rows="1" autocomplete="off" enterkeyhint="send"></textarea>
417
+ <!-- Shortcut hints shown inside empty textarea (absolute-positioned;
418
+ overlay is pointer-events:none, individual rows are clickable) -->
419
+ <div id="shortcut-hints-overlay" class="shortcut-hints-overlay" aria-hidden="true"></div>
420
+ </div>
421
+ <div id="input-toolbar">
422
+ <div class="toolbar-left">
423
+ <!-- Primary actions (always visible) -->
424
+ <button id="snippets-btn" class="toolbar-btn toolbar-primary" data-tooltip-key="ui.tooltips.snippets_btn">
425
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
426
+ <path d="M4 9h16M4 15h16M10 3L8 21M16 3l-2 18"/>
427
+ </svg>
428
+ </button>
429
+ <button id="slash-cmd-btn" class="toolbar-btn toolbar-primary" data-tooltip-key="ui.tooltips.slash_cmd_btn">
430
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
431
+ <line x1="7" y1="20" x2="17" y2="4"/>
432
+ </svg>
433
+ </button>
434
+ <button id="file-mention-btn" class="toolbar-btn toolbar-primary" data-tooltip-key="ui.tooltips.file_mention_btn">
435
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
436
+ <circle cx="12" cy="12" r="4"/>
437
+ <path d="M16 8v5a3 3 0 0 0 6 0v-1a10 10 0 1 0-4 8"/>
438
+ </svg>
439
+ </button>
440
+ <button id="skills-btn" class="toolbar-btn toolbar-primary" data-tooltip-key="ui.tooltips.skills_btn">
441
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
442
+ <line x1="12" y1="2" x2="12" y2="22"/>
443
+ <path d="M17 5H9.5a3.5 3.5 0 0 0 0 7h5a3.5 3.5 0 0 1 0 7H6"/>
444
+ </svg>
445
+ </button>
446
+ <div class="toolbar-separator" aria-hidden="true"></div>
447
+ <button id="stash-btn" class="toolbar-btn toolbar-primary" data-tooltip-key="ui.tooltips.stash_btn">
448
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
449
+ <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
450
+ <polyline points="17 21 17 13 7 13 7 21"/>
451
+ <polyline points="7 3 7 8 15 8"/>
452
+ </svg>
453
+ <span class="stash-badge" id="stash-badge"></span>
454
+ </button>
455
+
456
+ <!-- Secondary actions (hidden on mobile) -->
457
+ <button id="prompt-history-btn" class="toolbar-btn toolbar-secondary" data-tooltip-key="ui.tooltips.prompt_history_btn" data-shortcut-action="togglePromptExplorer">
458
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
459
+ <circle cx="12" cy="12" r="10"/>
460
+ <polyline points="12 6 12 12 16 14"/>
461
+ <path d="M8 12H2"/>
462
+ <path d="M4 8l-2 4 2 4"/>
463
+ </svg>
464
+ </button>
465
+ <button id="uploads-btn" class="toolbar-btn toolbar-secondary" data-tooltip-key="ui.tooltips.uploads_btn">
466
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
467
+ <rect x="3" y="3" width="18" height="18" rx="2" ry="2"/>
468
+ <circle cx="8.5" cy="8.5" r="1.5"/>
469
+ <polyline points="21 15 16 10 5 21"/>
470
+ </svg>
471
+ </button>
472
+ </div>
473
+ <div class="toolbar-right">
474
+ <!-- Drafts pill: entry point to Prompt Explorer → Drafts, shown only on empty input (label/tooltip set from strings.js) -->
475
+ <button id="drafts-pill" class="drafts-pill" type="button"></button>
476
+ <button id="permission-btn" class="toolbar-btn permission-btn" data-tooltip-key="ui.tooltips.permission_btn" data-level="bypassPermissions">
477
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
478
+ <circle cx="7.5" cy="15.5" r="5.5"/>
479
+ <path d="m21 2-9.6 9.6"/>
480
+ <path d="m15.5 7.5 3 3L22 7l-3-3"/>
481
+ </svg>
482
+ <span class="permission-label">YOLO</span>
483
+ </button>
484
+ <div id="permission-popup" class="permission-popup">
485
+ <!-- Populated by permission-settings.js from strings.yaml -->
486
+ </div>
487
+ <button id="effort-btn" class="toolbar-btn effort-btn" data-tooltip-key="ui.tooltips.effort_btn" data-level="high" data-shortcut-action="toggleThinkingSettings">
488
+ <span class="effort-fill" aria-hidden="true"></span>
489
+ <span class="effort-value">Hi</span>
490
+ <span class="effort-oneshot-badge" aria-hidden="true">1</span>
491
+ </button>
492
+ <div id="effort-popup" class="effort-popup">
493
+ <div class="effort-popup-header">Effort Level</div>
494
+ <!-- Presets rendered by effort-settings.js from the
495
+ active engine/model's own effort vocabulary -->
496
+ <div class="effort-presets"></div>
497
+ <div class="effort-popup-footer">
498
+ <button class="effort-set-default">Set as default</button>
499
+ </div>
500
+ </div>
501
+ <button id="favorite-prompt-btn" class="toolbar-btn favorite-prompt-btn" data-tooltip-key="ui.tooltips.favorite_prompt_btn">
502
+ <svg class="heart-outline" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
503
+ <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>
504
+ </svg>
505
+ <svg class="heart-filled" viewBox="0 0 24 24" fill="currentColor" stroke="none">
506
+ <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"/>
507
+ </svg>
508
+ </button>
509
+ <button id="upload-btn" class="toolbar-btn" data-tooltip-key="ui.tooltips.upload_btn">
510
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
511
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
512
+ <polyline points="17 8 12 3 7 8"/>
513
+ <line x1="12" y1="3" x2="12" y2="15"/>
514
+ </svg>
515
+ </button>
516
+ <button id="send-btn" disabled data-tooltip-key="ui.input.send_tooltip">
517
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
518
+ <path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z"/>
519
+ </svg>
520
+ </button>
521
+ <button id="followup-btn" disabled data-tooltip-key="ui.tooltips.followup_btn">
522
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
523
+ <path d="M16 4 8 12"/>
524
+ <path d="M16 4l-5 14-2.5-6.5L2 9z"/>
525
+ <line x1="19" y1="16" x2="19" y2="22"/>
526
+ <line x1="16" y1="19" x2="22" y2="19"/>
527
+ </svg>
528
+ </button>
529
+ <button id="stop-btn" data-tooltip-key="ui.tooltips.stop_btn" data-shortcut-action="escape">
530
+ <svg viewBox="0 0 24 24" fill="currentColor">
531
+ <rect x="6" y="6" width="12" height="12" rx="2"/>
532
+ </svg>
533
+ </button>
534
+ </div>
535
+ </div>
536
+
537
+ </div>
538
+ <div id="input-hint"></div>
539
+ <div id="status-bar">
540
+ <div class="status-left">
541
+ <!-- Text, not a dot: a bare dot here sat immediately left
542
+ of the "Auto-journal" pill and read as that pill's
543
+ status light. StatusBar.updateStatus() fills in the
544
+ label; the tooltip key is only the pre-JS value. -->
545
+ <span class="status-item" id="status-connection" data-tooltip-key="ui.tooltips.status_connection"></span>
546
+ <span class="status-item" id="status-helpers" hidden></span>
547
+ <span class="status-item" id="status-engine"></span>
548
+ <span class="status-item" id="status-model"></span>
549
+ <span class="status-item" id="status-token-profile"></span>
550
+ <span class="status-item" id="status-project"></span>
551
+ <span class="status-item" id="status-branch" data-tooltip-key="ui.tooltips.status_branch"></span>
552
+ </div>
553
+ <div class="status-right">
554
+ <span class="status-item token-meter" id="status-tokens">
555
+ <span class="token-bar"><span class="token-fill"></span></span>
556
+ <span class="token-text"></span>
557
+ </span>
558
+ <span class="cost" id="status-cost"></span>
559
+ </div>
560
+ </div>
561
+ </div>
562
+ </div>
563
+
564
+ <!-- Welcome View (sibling of session/widget views) -->
565
+ <div id="welcome-view" class="view"></div>
566
+ </div> <!-- /#main-content -->
567
+ </div> <!-- /#app-body -->
568
+ </div> <!-- /#app -->
569
+
570
+ <!-- Selection Action Bar (floating panel, outside #app to avoid stacking context issues) -->
571
+ <div class="selection-bar" id="selection-bar">
572
+ <div class="selection-bar-drag" id="selection-bar-drag"></div>
573
+ <div class="selection-bar-resize" id="selection-bar-resize"></div>
574
+ <button class="selection-close selection-close-corner" id="selection-close" data-tooltip-key="ui.tooltips.selection_close">
575
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
576
+ <line x1="18" y1="6" x2="6" y2="18"/>
577
+ <line x1="6" y1="6" x2="18" y2="18"/>
578
+ </svg>
579
+ </button>
580
+ <div class="selection-quote-wrap" id="selection-quote-wrap">
581
+ <div class="selection-quote" id="selection-quote"></div>
582
+ <button class="selection-quote-toggle" id="selection-quote-toggle" type="button" data-tooltip-key="ui.tooltips.selection_quote_toggle">
583
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
584
+ <polyline points="6 9 12 15 18 9"/>
585
+ </svg>
586
+ </button>
587
+ </div>
588
+ <textarea class="selection-input" id="selection-input" placeholder="Add a note or question (optional)…" rows="2" autocomplete="off" autocorrect="on" autocapitalize="sentences" spellcheck="true"></textarea>
589
+ <div class="selection-actions">
590
+ <button class="selection-action-btn selection-discuss-btn" id="selection-discuss-btn" data-tooltip-key="ui.tooltips.selection_discuss">
591
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
592
+ <path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/>
593
+ </svg>
594
+ <span class="selection-action-label">Discuss</span>
595
+ <span class="selection-action-kbd">⌃⏎</span>
596
+ </button>
597
+ <button class="selection-action-btn selection-stash-btn" id="selection-stash-btn" data-tooltip-key="ui.tooltips.selection_stash">
598
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
599
+ <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/>
600
+ <polyline points="17 21 17 13 7 13 7 21"/>
601
+ <polyline points="7 3 7 8 15 8"/>
602
+ </svg>
603
+ <span class="selection-action-label">Stash</span>
604
+ <span class="selection-action-kbd">⏎</span>
605
+ </button>
606
+ </div>
607
+ </div>
608
+
609
+ <!-- File Explorer: Now managed by Widget System (see widgets/file-explorer-widget.js) -->
610
+
611
+ <!-- Log Explorer is now a widget (created dynamically by log-explorer-widget.js) -->
612
+
613
+ <!-- Help Modal -->
614
+ <div id="modal-overlay">
615
+ <div class="modal" id="help-modal">
616
+ <div class="modal-header">
617
+ <h3>Keyboard Shortcuts & Commands</h3>
618
+ <button class="modal-close" id="modal-close">
619
+ <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
620
+ <path d="M18 6L6 18M6 6l12 12"/>
621
+ </svg>
622
+ </button>
623
+ </div>
624
+ <div class="modal-body">
625
+ <!-- Content populated dynamically by ShortcutManager -->
626
+ </div>
627
+ </div>
628
+ </div>
629
+
630
+ <!-- App JavaScript (ES Modules) -->
631
+ <script type="module" src="/static/js/app.js"></script>
632
+
633
+ <!-- Service-worker registration moved into js/boot.js (CSP: no inline scripts). -->
634
+ </body>
635
+ </html>