aicodeman 1.2.1 → 1.3.0

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 (232) hide show
  1. package/README.md +264 -90
  2. package/dist/attachment-magic.d.ts +13 -0
  3. package/dist/attachment-magic.d.ts.map +1 -1
  4. package/dist/attachment-magic.js +47 -0
  5. package/dist/attachment-magic.js.map +1 -1
  6. package/dist/attachment-registry.d.ts.map +1 -1
  7. package/dist/attachment-registry.js +13 -2
  8. package/dist/attachment-registry.js.map +1 -1
  9. package/dist/config/buffer-limits.d.ts +2 -3
  10. package/dist/config/buffer-limits.d.ts.map +1 -1
  11. package/dist/config/buffer-limits.js +5 -5
  12. package/dist/config/buffer-limits.js.map +1 -1
  13. package/dist/config/map-limits.d.ts +11 -0
  14. package/dist/config/map-limits.d.ts.map +1 -1
  15. package/dist/config/map-limits.js +11 -0
  16. package/dist/config/map-limits.js.map +1 -1
  17. package/dist/config/server-timing.d.ts +6 -0
  18. package/dist/config/server-timing.d.ts.map +1 -1
  19. package/dist/config/server-timing.js +9 -0
  20. package/dist/config/server-timing.js.map +1 -1
  21. package/dist/config/terminal-history.d.ts +30 -0
  22. package/dist/config/terminal-history.d.ts.map +1 -0
  23. package/dist/config/terminal-history.js +43 -0
  24. package/dist/config/terminal-history.js.map +1 -0
  25. package/dist/cron/cron-input.d.ts +30 -0
  26. package/dist/cron/cron-input.d.ts.map +1 -0
  27. package/dist/cron/cron-input.js +7 -0
  28. package/dist/cron/cron-input.js.map +1 -0
  29. package/dist/cron/cron-service.d.ts +92 -0
  30. package/dist/cron/cron-service.d.ts.map +1 -0
  31. package/dist/cron/cron-service.js +606 -0
  32. package/dist/cron/cron-service.js.map +1 -0
  33. package/dist/cron/cron-time.d.ts +29 -0
  34. package/dist/cron/cron-time.d.ts.map +1 -0
  35. package/dist/cron/cron-time.js +87 -0
  36. package/dist/cron/cron-time.js.map +1 -0
  37. package/dist/document-thumbnailer.d.ts +1 -1
  38. package/dist/document-thumbnailer.d.ts.map +1 -1
  39. package/dist/document-thumbnailer.js +11 -2
  40. package/dist/document-thumbnailer.js.map +1 -1
  41. package/dist/generated-artifact-attachments.d.ts +26 -0
  42. package/dist/generated-artifact-attachments.d.ts.map +1 -0
  43. package/dist/generated-artifact-attachments.js +61 -0
  44. package/dist/generated-artifact-attachments.js.map +1 -0
  45. package/dist/index.js +11 -0
  46. package/dist/index.js.map +1 -1
  47. package/dist/mux-interface.d.ts +37 -5
  48. package/dist/mux-interface.d.ts.map +1 -1
  49. package/dist/remote-hosts.d.ts +66 -0
  50. package/dist/remote-hosts.d.ts.map +1 -0
  51. package/dist/remote-hosts.js +198 -0
  52. package/dist/remote-hosts.js.map +1 -0
  53. package/dist/services/unified-session-service.d.ts +115 -0
  54. package/dist/services/unified-session-service.d.ts.map +1 -0
  55. package/dist/services/unified-session-service.js +173 -0
  56. package/dist/services/unified-session-service.js.map +1 -0
  57. package/dist/session-cli-builder.d.ts +3 -1
  58. package/dist/session-cli-builder.d.ts.map +1 -1
  59. package/dist/session-cli-builder.js +26 -7
  60. package/dist/session-cli-builder.js.map +1 -1
  61. package/dist/session-pty-exit-breaker.d.ts +66 -0
  62. package/dist/session-pty-exit-breaker.d.ts.map +1 -0
  63. package/dist/session-pty-exit-breaker.js +77 -0
  64. package/dist/session-pty-exit-breaker.js.map +1 -0
  65. package/dist/session.d.ts +27 -1
  66. package/dist/session.d.ts.map +1 -1
  67. package/dist/session.js +102 -11
  68. package/dist/session.js.map +1 -1
  69. package/dist/state-store.d.ts +14 -0
  70. package/dist/state-store.d.ts.map +1 -1
  71. package/dist/state-store.js +49 -0
  72. package/dist/state-store.js.map +1 -1
  73. package/dist/tmux-manager.d.ts +100 -8
  74. package/dist/tmux-manager.d.ts.map +1 -1
  75. package/dist/tmux-manager.js +249 -26
  76. package/dist/tmux-manager.js.map +1 -1
  77. package/dist/types/api.d.ts +11 -0
  78. package/dist/types/api.d.ts.map +1 -1
  79. package/dist/types/api.js.map +1 -1
  80. package/dist/types/app-state.d.ts +5 -0
  81. package/dist/types/app-state.d.ts.map +1 -1
  82. package/dist/types/app-state.js.map +1 -1
  83. package/dist/types/cron.d.ts +88 -0
  84. package/dist/types/cron.d.ts.map +1 -0
  85. package/dist/types/cron.js +13 -0
  86. package/dist/types/cron.js.map +1 -0
  87. package/dist/types/session.d.ts +57 -0
  88. package/dist/types/session.d.ts.map +1 -1
  89. package/dist/types/session.js.map +1 -1
  90. package/dist/web/heic-jpeg-converter.d.ts +24 -0
  91. package/dist/web/heic-jpeg-converter.d.ts.map +1 -0
  92. package/dist/web/heic-jpeg-converter.js +76 -0
  93. package/dist/web/heic-jpeg-converter.js.map +1 -0
  94. package/dist/web/heic-jpeg-worker.d.ts +44 -0
  95. package/dist/web/heic-jpeg-worker.d.ts.map +1 -0
  96. package/dist/web/heic-jpeg-worker.js +78 -0
  97. package/dist/web/heic-jpeg-worker.js.map +1 -0
  98. package/dist/web/ports/config-port.d.ts +2 -0
  99. package/dist/web/ports/config-port.d.ts.map +1 -1
  100. package/dist/web/ports/cron-port.d.ts +9 -0
  101. package/dist/web/ports/cron-port.d.ts.map +1 -0
  102. package/dist/web/ports/cron-port.js +6 -0
  103. package/dist/web/ports/cron-port.js.map +1 -0
  104. package/dist/web/ports/index.d.ts +1 -0
  105. package/dist/web/ports/index.d.ts.map +1 -1
  106. package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
  107. package/dist/web/public/app.b0534652.js +38 -0
  108. package/dist/web/public/app.b0534652.js.br +0 -0
  109. package/dist/web/public/app.b0534652.js.gz +0 -0
  110. package/dist/web/public/{constants.1c779517.js → constants.5b18ed64.js} +65 -0
  111. package/dist/web/public/constants.5b18ed64.js.br +0 -0
  112. package/dist/web/public/constants.5b18ed64.js.gz +0 -0
  113. package/dist/web/public/cron-ui.js +328 -0
  114. package/dist/web/public/cron-ui.js.br +0 -0
  115. package/dist/web/public/cron-ui.js.gz +0 -0
  116. package/dist/web/public/image-input.ee16ad88.js.gz +0 -0
  117. package/dist/web/public/index.html +296 -25
  118. package/dist/web/public/index.html.br +0 -0
  119. package/dist/web/public/index.html.gz +0 -0
  120. package/dist/web/public/input-cjk.63794d0b.js +1 -0
  121. package/dist/web/public/input-cjk.63794d0b.js.br +0 -0
  122. package/dist/web/public/input-cjk.63794d0b.js.gz +0 -0
  123. package/dist/web/public/keyboard-accessory.3f91acef.js.gz +0 -0
  124. package/dist/web/public/mobile-handlers.b5a667ef.js.gz +0 -0
  125. package/dist/web/public/mobile.0644e3ac.css +1 -0
  126. package/dist/web/public/mobile.0644e3ac.css.br +0 -0
  127. package/dist/web/public/mobile.0644e3ac.css.gz +0 -0
  128. package/dist/web/public/notification-manager.ca9dc40d.js.gz +0 -0
  129. package/dist/web/public/orchestrator-panel.js.gz +0 -0
  130. package/dist/web/public/{panels-ui.772e92c9.js → panels-ui.ca03853f.js} +25 -17
  131. package/dist/web/public/panels-ui.ca03853f.js.br +0 -0
  132. package/dist/web/public/panels-ui.ca03853f.js.gz +0 -0
  133. package/dist/web/public/ralph-panel.6de2d0f8.js.gz +0 -0
  134. package/dist/web/public/ralph-wizard.13a1831e.js.gz +0 -0
  135. package/dist/web/public/respawn-ui.2d249da9.js.gz +0 -0
  136. package/dist/web/public/sanitize-html.bc7078d6.js.gz +0 -0
  137. package/dist/web/public/session-ui.b51814ef.js +49 -0
  138. package/dist/web/public/session-ui.b51814ef.js.br +0 -0
  139. package/dist/web/public/session-ui.b51814ef.js.gz +0 -0
  140. package/dist/web/public/settings-ui.6c67c125.js +67 -0
  141. package/dist/web/public/settings-ui.6c67c125.js.br +0 -0
  142. package/dist/web/public/settings-ui.6c67c125.js.gz +0 -0
  143. package/dist/web/public/styles.e1ba7849.css +1 -0
  144. package/dist/web/public/styles.e1ba7849.css.br +0 -0
  145. package/dist/web/public/styles.e1ba7849.css.gz +0 -0
  146. package/dist/web/public/subagent-windows.69b60c35.js.gz +0 -0
  147. package/dist/web/public/sw.js.gz +0 -0
  148. package/dist/web/public/terminal-ui.dbf141fa.js +3 -0
  149. package/dist/web/public/terminal-ui.dbf141fa.js.br +0 -0
  150. package/dist/web/public/terminal-ui.dbf141fa.js.gz +0 -0
  151. package/dist/web/public/ultracode-panel.js.gz +0 -0
  152. package/dist/web/public/ultracode-windows.js.gz +0 -0
  153. package/dist/web/public/upload.html.gz +0 -0
  154. package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
  155. package/dist/web/public/vendor/marked.min.js.gz +0 -0
  156. package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
  157. package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
  158. package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
  159. package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
  160. package/dist/web/public/vendor/xterm-zerolag-input.137ad9f0.js.gz +0 -0
  161. package/dist/web/public/vendor/xterm.css.gz +0 -0
  162. package/dist/web/public/vendor/xterm.min.js.gz +0 -0
  163. package/dist/web/public/voice-input.085e9e73.js.gz +0 -0
  164. package/dist/web/routes/case-routes.d.ts.map +1 -1
  165. package/dist/web/routes/case-routes.js +115 -1
  166. package/dist/web/routes/case-routes.js.map +1 -1
  167. package/dist/web/routes/cron-routes.d.ts +11 -0
  168. package/dist/web/routes/cron-routes.d.ts.map +1 -0
  169. package/dist/web/routes/cron-routes.js +70 -0
  170. package/dist/web/routes/cron-routes.js.map +1 -0
  171. package/dist/web/routes/index.d.ts +1 -0
  172. package/dist/web/routes/index.d.ts.map +1 -1
  173. package/dist/web/routes/index.js +1 -0
  174. package/dist/web/routes/index.js.map +1 -1
  175. package/dist/web/routes/respawn-routes.d.ts.map +1 -1
  176. package/dist/web/routes/respawn-routes.js +3 -0
  177. package/dist/web/routes/respawn-routes.js.map +1 -1
  178. package/dist/web/routes/session-routes.d.ts.map +1 -1
  179. package/dist/web/routes/session-routes.js +614 -68
  180. package/dist/web/routes/session-routes.js.map +1 -1
  181. package/dist/web/routes/system-routes.d.ts.map +1 -1
  182. package/dist/web/routes/system-routes.js +5 -0
  183. package/dist/web/routes/system-routes.js.map +1 -1
  184. package/dist/web/routes/ws-routes.d.ts.map +1 -1
  185. package/dist/web/routes/ws-routes.js +56 -17
  186. package/dist/web/routes/ws-routes.js.map +1 -1
  187. package/dist/web/schemas.d.ts +117 -0
  188. package/dist/web/schemas.d.ts.map +1 -1
  189. package/dist/web/schemas.js +168 -1
  190. package/dist/web/schemas.js.map +1 -1
  191. package/dist/web/server.d.ts +9 -2
  192. package/dist/web/server.d.ts.map +1 -1
  193. package/dist/web/server.js +82 -13
  194. package/dist/web/server.js.map +1 -1
  195. package/dist/web/session-listener-wiring.d.ts +5 -1
  196. package/dist/web/session-listener-wiring.d.ts.map +1 -1
  197. package/dist/web/session-listener-wiring.js +23 -1
  198. package/dist/web/session-listener-wiring.js.map +1 -1
  199. package/dist/web/sse-events.d.ts +15 -0
  200. package/dist/web/sse-events.d.ts.map +1 -1
  201. package/dist/web/sse-events.js +17 -0
  202. package/dist/web/sse-events.js.map +1 -1
  203. package/dist/web/ws-connection-registry.d.ts +77 -0
  204. package/dist/web/ws-connection-registry.d.ts.map +1 -0
  205. package/dist/web/ws-connection-registry.js +99 -0
  206. package/dist/web/ws-connection-registry.js.map +1 -0
  207. package/package.json +3 -1
  208. package/dist/web/public/app.a8d73c32.js +0 -38
  209. package/dist/web/public/app.a8d73c32.js.br +0 -0
  210. package/dist/web/public/app.a8d73c32.js.gz +0 -0
  211. package/dist/web/public/constants.1c779517.js.br +0 -0
  212. package/dist/web/public/constants.1c779517.js.gz +0 -0
  213. package/dist/web/public/input-cjk.4e950e0a.js +0 -1
  214. package/dist/web/public/input-cjk.4e950e0a.js.br +0 -0
  215. package/dist/web/public/input-cjk.4e950e0a.js.gz +0 -0
  216. package/dist/web/public/mobile.8a9aff7a.css +0 -1
  217. package/dist/web/public/mobile.8a9aff7a.css.br +0 -0
  218. package/dist/web/public/mobile.8a9aff7a.css.gz +0 -0
  219. package/dist/web/public/panels-ui.772e92c9.js.br +0 -0
  220. package/dist/web/public/panels-ui.772e92c9.js.gz +0 -0
  221. package/dist/web/public/session-ui.da3e53f2.js +0 -36
  222. package/dist/web/public/session-ui.da3e53f2.js.br +0 -0
  223. package/dist/web/public/session-ui.da3e53f2.js.gz +0 -0
  224. package/dist/web/public/settings-ui.38feb956.js +0 -61
  225. package/dist/web/public/settings-ui.38feb956.js.br +0 -0
  226. package/dist/web/public/settings-ui.38feb956.js.gz +0 -0
  227. package/dist/web/public/styles.1b3e6147.css +0 -1
  228. package/dist/web/public/styles.1b3e6147.css.br +0 -0
  229. package/dist/web/public/styles.1b3e6147.css.gz +0 -0
  230. package/dist/web/public/terminal-ui.865f21f6.js +0 -3
  231. package/dist/web/public/terminal-ui.865f21f6.js.br +0 -0
  232. package/dist/web/public/terminal-ui.865f21f6.js.gz +0 -0
@@ -16,16 +16,16 @@
16
16
  <link rel="manifest" href="manifest.json">
17
17
  <title>Codeman</title>
18
18
  <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0%25' y1='0%25' x2='100%25' y2='100%25'%3E%3Cstop offset='0%25' stop-color='%2360a5fa'/%3E%3Cstop offset='100%25' stop-color='%233b82f6'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='32' height='32' rx='6' fill='%230a0a0a'/%3E%3Cpath d='M18 4L8 18h6l-2 10 10-14h-6z' fill='url(%23g)'/%3E%3C/svg%3E">
19
- <link rel="stylesheet" href="styles.1b3e6147.css">
20
- <link rel="stylesheet" href="mobile.8a9aff7a.css" media="(max-width: 1023px)">
19
+ <link rel="stylesheet" href="styles.e1ba7849.css">
20
+ <link rel="stylesheet" href="mobile.0644e3ac.css" media="(max-width: 1023px)">
21
21
  <!-- xterm.css loaded async — terminal won't display until xterm.js runs anyway -->
22
22
  <link rel="preload" href="vendor/xterm.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
23
23
  <noscript><link rel="stylesheet" href="vendor/xterm.css"></noscript>
24
24
  <!-- Preload critical resources — lets browser discover these during HTML parse
25
25
  instead of waiting until <script> tags at bottom-of-body are reached. -->
26
26
  <link rel="preload" href="vendor/xterm.min.js" as="script">
27
- <link rel="preload" href="constants.1c779517.js" as="script">
28
- <link rel="preload" href="app.a8d73c32.js" as="script">
27
+ <link rel="preload" href="constants.5b18ed64.js" as="script">
28
+ <link rel="preload" href="app.b0534652.js" as="script">
29
29
  <!-- Self-hosted xterm.js — eliminates CDN DNS/TLS latency (~100ms).
30
30
  'defer' preserves execution order (xterm loads before fit addon). -->
31
31
  <script defer src="vendor/xterm.min.js"></script>
@@ -119,6 +119,7 @@
119
119
  <button class="btn-icon-header btn-redraw-terminal btn-redraw-terminal--hidden" onclick="app.restoreTerminalSize()" title="Redraw terminal to fit current screen (Ctrl+Shift+R)" aria-label="Redraw terminal"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="1 4 1 10 7 10"/><polyline points="23 20 23 14 17 14"/><path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15"/></svg></button>
120
120
  <button class="btn-icon-header btn-response-viewer-header btn-response-viewer-header--hidden" onclick="app.toggleResponseViewer()" title="View last response" aria-label="View last response"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/></svg></button>
121
121
  <button class="btn-icon-header btn-away-digest" onclick="app.openAwayDigest()" title="Away Digest" aria-label="Open away digest"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M8 6h13"/><path d="M8 12h13"/><path d="M8 18h13"/><path d="M3 6h.01"/><path d="M3 12h.01"/><path d="M3 18h.01"/></svg></button>
122
+ <button class="btn-icon-header btn-session-manager" onclick="app.openSessionManager()" title="Session Manager" aria-label="Open session manager"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="12 2 2 7 12 12 22 7 12 2"/><polyline points="2 17 12 22 22 17"/><polyline points="2 12 12 17 22 12"/></svg></button>
122
123
  <button class="btn-icon-header btn-attachments-history btn-attachments-history--hidden" id="attachmentsHistoryBtn" onclick="app.toggleAttachmentHistory()" title="Attachments" aria-label="Open attachment history" aria-expanded="false">
123
124
  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m21.44 11.05-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>
124
125
  <span class="attachment-history-badge" id="attachmentHistoryBadge" style="display:none;">0</span>
@@ -358,7 +359,7 @@
358
359
  <h3 class="history-title" id="historyTitle">Resume Conversation</h3>
359
360
  <div class="history-list" id="historyList"></div>
360
361
  </div>
361
- <p class="welcome-hint">Or press <kbd>Ctrl</kbd>+<kbd>Enter</kbd> to start</p>
362
+ <p class="welcome-hint">Or click Run to start</p>
362
363
  <button class="welcome-ralph-link" onclick="app.showRalphWizard()">Start Ralph Loop &rarr;</button>
363
364
  </div>
364
365
  </div>
@@ -427,7 +428,7 @@
427
428
  <!-- Run AI -->
428
429
  <div class="toolbar-group">
429
430
  <div class="run-btn-group">
430
- <button class="btn-toolbar btn-run" id="runBtn" onclick="app.run()" title="Run (Ctrl+Enter)">
431
+ <button class="btn-toolbar btn-run" id="runBtn" onclick="app.run()" title="Run">
431
432
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polygon points="5 3 19 12 5 21 5 3"/></svg>
432
433
  <span id="runBtnLabel">Run</span>
433
434
  </button>
@@ -469,7 +470,22 @@
469
470
  <button class="tab-count-btn" onclick="app.incrementShellCount()">+</button>
470
471
  </div>
471
472
  <div class="case-select-group">
472
- <select id="quickStartCase" class="toolbar-select" title="Select case">
473
+ <div class="case-combobox" id="quickStartCasePicker">
474
+ <input
475
+ type="text"
476
+ id="quickStartCaseSearch"
477
+ class="case-combobox-input"
478
+ role="combobox"
479
+ aria-controls="quickStartCaseList"
480
+ aria-expanded="false"
481
+ aria-autocomplete="list"
482
+ autocomplete="off"
483
+ spellcheck="false"
484
+ title="Select case"
485
+ >
486
+ <div id="quickStartCaseList" class="case-combobox-list hidden" role="listbox"></div>
487
+ </div>
488
+ <select id="quickStartCase" class="toolbar-select case-native-select" title="Select case" aria-hidden="true" tabindex="-1">
473
489
  <option value="testcase">testcase</option>
474
490
  </select>
475
491
  <button class="btn-case-add" onclick="app.showCreateCaseModal()" title="Create new case">+</button>
@@ -541,6 +557,7 @@
541
557
  <div class="toolbar-right">
542
558
  <!-- Orchestrator button hidden until feature is ready -->
543
559
  <!-- <button class="btn-toolbar btn-sm" onclick="app.toggleOrchestratorPanel()" title="Orchestrator Loop">&#x2699; Orchestrator</button> -->
560
+ <button class="btn-toolbar btn-sm" onclick="app.openCron()" title="Cron Jobs">&#x23F0; Cron</button>
544
561
  <span class="version-display" id="versionDisplay" title="Codeman version">v0.0.0</span>
545
562
  </div>
546
563
  </footer>
@@ -554,17 +571,141 @@
554
571
  <button class="modal-close" onclick="app.closeHelp()" aria-label="Close help">&times;</button>
555
572
  </div>
556
573
  <div class="modal-body">
557
- <div class="shortcuts-grid">
558
- <div><kbd>Ctrl</kbd>+<kbd>W</kbd></div><div>Close Session</div>
559
- <div><kbd>Ctrl</kbd>+<kbd>Tab</kbd></div><div>Next Session</div>
560
- <div><kbd>Alt/Option</kbd>+<kbd>[</kbd> / <kbd>Alt/Option</kbd>+<kbd>]</kbd></div><div>Previous / Next Session</div>
561
- <div><kbd>Alt/Option</kbd>+<kbd>1-9</kbd></div><div>Switch to Tab N</div>
562
- <div><kbd>Ctrl</kbd>+<kbd>L</kbd></div><div>Clear Terminal</div>
563
- <div><kbd>Ctrl</kbd>+<kbd>+</kbd></div><div>Increase Font</div>
564
- <div><kbd>Ctrl</kbd>+<kbd>-</kbd></div><div>Decrease Font</div>
565
- <div><kbd>Ctrl</kbd>+<kbd>?</kbd></div><div>Show Help</div>
566
- <div><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>V</kbd></div><div>Voice Input</div>
567
- <div><kbd>Escape</kbd></div><div>Close Panels</div>
574
+ <section class="shortcut-section">
575
+ <h4>Session</h4>
576
+ <div class="shortcuts-grid">
577
+ <div><kbd>Ctrl</kbd>+<kbd>W</kbd></div><div>Close Session</div>
578
+ <div><kbd>Ctrl/Cmd/Option</kbd>+<kbd>K</kbd></div><div>Find Open Session</div>
579
+ <div><kbd>Ctrl</kbd>+<kbd>Tab</kbd></div><div>Next Session</div>
580
+ <div><kbd>Alt/Option</kbd>+<kbd>[</kbd> / <kbd>Alt/Option</kbd>+<kbd>]</kbd></div><div>Previous / Next Session</div>
581
+ <div><kbd>Alt/Option</kbd>+<kbd>1-9</kbd></div><div>Switch to Tab N</div>
582
+ </div>
583
+ </section>
584
+ <section class="shortcut-section">
585
+ <h4>Tabs</h4>
586
+ <div class="shortcuts-grid">
587
+ <div><kbd>Ctrl</kbd>+<kbd>{</kbd></div><div>Move Active Tab Left</div>
588
+ <div><kbd>Ctrl</kbd>+<kbd>}</kbd></div><div>Move Active Tab Right</div>
589
+ <div><kbd>ArrowLeft</kbd></div><div>Focus Previous Tab</div>
590
+ <div><kbd>ArrowRight</kbd></div><div>Focus Next Tab</div>
591
+ <div><kbd>Home</kbd></div><div>Focus First Tab</div>
592
+ <div><kbd>End</kbd></div><div>Focus Last Tab</div>
593
+ <div><kbd>Enter</kbd> / <kbd>Space</kbd></div><div>Activate Focused Tab</div>
594
+ </div>
595
+ </section>
596
+ <section class="shortcut-section">
597
+ <h4>Terminal</h4>
598
+ <div class="shortcuts-grid">
599
+ <div><kbd>Ctrl</kbd>+<kbd>L</kbd></div><div>Clear Terminal</div>
600
+ <div><kbd>Ctrl</kbd>+<kbd>+</kbd></div><div>Increase Font</div>
601
+ <div><kbd>Ctrl</kbd>+<kbd>-</kbd></div><div>Decrease Font</div>
602
+ <div><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>R</kbd></div><div>Restore Terminal Size</div>
603
+ <div><kbd>Shift</kbd>+<kbd>Enter</kbd></div><div>Insert Newline</div>
604
+ <div><kbd>Ctrl</kbd>+<kbd>Enter</kbd></div><div>Insert Newline</div>
605
+ <div><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>V</kbd></div><div>Voice Input</div>
606
+ <div><kbd>Shift</kbd>+<kbd>Wheel</kbd></div><div>Scroll local history (when mouse passthrough is active)</div>
607
+ </div>
608
+ </section>
609
+ <section class="shortcut-section">
610
+ <h4>Panels</h4>
611
+ <div class="shortcuts-grid">
612
+ <div><kbd>Ctrl</kbd>+<kbd>?</kbd></div><div>Show Shortcuts</div>
613
+ <div><kbd>Alt/Option</kbd>+<kbd>?</kbd></div><div>Show Shortcuts</div>
614
+ <div><kbd>Escape</kbd></div><div>Close Panels</div>
615
+ </div>
616
+ </section>
617
+ </div>
618
+ </div>
619
+ </div>
620
+
621
+ <!-- Cron Jobs Modal -->
622
+ <div class="modal" id="cronModal">
623
+ <div class="modal-backdrop" onclick="app.closeCron()"></div>
624
+ <div class="modal-content modal-lg">
625
+ <div class="modal-header">
626
+ <h3>Cron Jobs</h3>
627
+ <button class="modal-close" onclick="app.closeCron()" aria-label="Close cron">&times;</button>
628
+ </div>
629
+ <div class="modal-body">
630
+ <p class="form-hint" style="margin-bottom:10px;">Times use the server's local timezone.</p>
631
+ <div style="margin-bottom:10px;">
632
+ <button class="btn-toolbar btn-sm btn-primary" onclick="app.openCronJobForm()">+ New Job</button>
633
+ <button class="btn-toolbar btn-sm" onclick="app.refreshCron()">Refresh</button>
634
+ </div>
635
+ <!-- Job list -->
636
+ <div id="cronJobList" class="cron-job-list"></div>
637
+
638
+ <!-- Create/Edit form (hidden until New/Edit) -->
639
+ <div id="cronJobForm" class="cron-job-form hidden">
640
+ <div class="form-section-header" id="cronFormTitle">New Cron Job</div>
641
+ <input type="hidden" id="schJobId">
642
+ <div class="form-row"><label>Name</label><input type="text" id="schName" placeholder="My nightly job"></div>
643
+ <div class="form-row"><label>Agent Type</label>
644
+ <select id="schAgentType" onchange="app.onCronAgentTypeChange()">
645
+ <option value="claude">Claude</option>
646
+ <option value="shell">Terminal / Shell</option>
647
+ <option value="opencode">OpenCode</option>
648
+ <option value="codex">Codex</option>
649
+ <option value="gemini">Gemini</option>
650
+ </select>
651
+ </div>
652
+ <div class="form-row"><label>Working Directory</label><input type="text" id="schWorkingDir" placeholder="/absolute/path"></div>
653
+ <div class="form-row hidden" id="schLaunchCommandRow"><label>Launch Command</label><input type="text" id="schLaunchCommand" placeholder="Optional — runs as the first command in the new shell"></div>
654
+ <div class="form-row"><label>Prompt Source</label>
655
+ <select id="schPromptMode" onchange="app.onCronPromptModeChange()">
656
+ <option value="inline_text">Inline text</option>
657
+ <option value="prompt_file_path">Prompt file path</option>
658
+ </select>
659
+ </div>
660
+ <div class="form-row" id="schPromptTextRow"><label>Prompt</label><textarea id="schPromptText" rows="4" placeholder="Prompt to send into the session"></textarea></div>
661
+ <div class="form-row hidden" id="schPromptFileRow"><label>Prompt File Path</label><input type="text" id="schPromptFilePath" placeholder="/absolute/path/to/prompt.md"></div>
662
+ <div class="form-row"><label>Input Mode</label>
663
+ <select id="schInputMode">
664
+ <option value="typed">Typed (via tmux)</option>
665
+ <option value="paste">Paste (direct)</option>
666
+ </select>
667
+ </div>
668
+ <div class="form-row"><label>Schedule Type</label>
669
+ <select id="schScheduleType" onchange="app.onCronScheduleTypeChange()">
670
+ <option value="once">Once</option>
671
+ <option value="interval">Interval</option>
672
+ <option value="daily">Daily</option>
673
+ <option value="weekly">Weekly</option>
674
+ </select>
675
+ </div>
676
+ <div class="form-row" id="schRunAtRow"><label>Run At</label><input type="datetime-local" id="schRunAt"></div>
677
+ <div class="form-row hidden" id="schIntervalRow"><label>Every (minutes)</label><input type="number" id="schIntervalMinutes" min="1" value="60"></div>
678
+ <div class="form-row hidden" id="schDailyRow"><label>Daily Time (HH:MM)</label><input type="time" id="schDailyTime"></div>
679
+ <div class="form-row hidden" id="schWeeklyDaysRow"><label>Weekdays</label>
680
+ <span id="schWeeklyDays" class="cron-weekdays">
681
+ <label><input type="checkbox" value="0">Sun</label>
682
+ <label><input type="checkbox" value="1">Mon</label>
683
+ <label><input type="checkbox" value="2">Tue</label>
684
+ <label><input type="checkbox" value="3">Wed</label>
685
+ <label><input type="checkbox" value="4">Thu</label>
686
+ <label><input type="checkbox" value="5">Fri</label>
687
+ <label><input type="checkbox" value="6">Sat</label>
688
+ </span>
689
+ </div>
690
+ <div class="form-row hidden" id="schWeeklyTimeRow"><label>Weekly Time (HH:MM)</label><input type="time" id="schWeeklyTime"></div>
691
+ <div class="form-row"><label>On auto-run, if same agent running</label>
692
+ <select id="schConcurrencyPolicy">
693
+ <option value="warn_only">Run anyway</option>
694
+ <option value="skip_if_same_agent_running">Skip this run</option>
695
+ </select>
696
+ </div>
697
+ <div class="form-row form-row-switch"><label title="Recurring schedules only: when the next run fires, the still-open session created by this job's previous run is closed first">Auto-close previous run's session</label>
698
+ <label class="switch"><input type="checkbox" id="schAutoClosePrev" checked><span class="slider"></span></label>
699
+ </div>
700
+ <div class="form-row form-row-switch"><label>Enabled</label>
701
+ <label class="switch"><input type="checkbox" id="schEnabled" checked><span class="slider"></span></label>
702
+ </div>
703
+ <div class="form-row"><label>Notes</label><input type="text" id="schNotes" placeholder="Optional"></div>
704
+ <div id="cronFormError" class="form-hint" style="color:var(--danger,#e55);"></div>
705
+ <div style="margin-top:10px;">
706
+ <button class="btn-toolbar btn-sm btn-primary" onclick="app.saveCronJob()">Save</button>
707
+ <button class="btn-toolbar btn-sm" onclick="app.cancelCronJobForm()">Cancel</button>
708
+ </div>
568
709
  </div>
569
710
  </div>
570
711
  </div>
@@ -996,6 +1137,7 @@
996
1137
  <button class="modal-tab-btn" data-tab="settings-paths">Paths</button>
997
1138
  <button class="modal-tab-btn" data-tab="settings-notifications">Notifications</button>
998
1139
  <button class="modal-tab-btn" data-tab="settings-voice">Voice</button>
1140
+ <button class="modal-tab-btn" data-tab="settings-shortcuts">Shortcuts</button>
999
1141
  </div>
1000
1142
  <div class="modal-body">
1001
1143
  <!-- Display Tab -->
@@ -1011,6 +1153,13 @@
1011
1153
  <option value="og">OG Codeman</option>
1012
1154
  </select>
1013
1155
  </div>
1156
+ <div class="settings-item" id="appSettingsWebglRendererItem" title="Use the GPU-accelerated WebGL terminal renderer (desktop only). Turn off to force the DOM renderer if you hit GPU glitches. Codeman also auto-falls-back to the DOM renderer after repeated GPU stalls.">
1157
+ <span class="settings-item-label">WebGL Renderer</span>
1158
+ <label class="switch switch-sm">
1159
+ <input type="checkbox" id="appSettingsWebglRenderer">
1160
+ <span class="slider"></span>
1161
+ </label>
1162
+ </div>
1014
1163
  <!-- Input Section -->
1015
1164
  <div class="settings-section-header">Input</div>
1016
1165
  <div class="settings-item settings-item-multiline" title="Shows typed characters instantly via overlay while forwarding keystrokes to the server in the background. Enables Tab completion, preserves input across tab switches, and protects against session crashes. Recommended for mobile and high-latency connections.">
@@ -1602,6 +1751,19 @@
1602
1751
  </div>
1603
1752
  </div>
1604
1753
  </div>
1754
+
1755
+ <!-- Shortcuts tab -->
1756
+ <div class="modal-tab-content hidden" id="settings-shortcuts">
1757
+ <div class="settings-grid">
1758
+ <div class="settings-section-header" style="grid-column: 1 / -1;">Keyboard Shortcuts</div>
1759
+ <p class="form-hint" style="grid-column: 1 / -1; margin: 0 0 0.5rem;">
1760
+ Customize keyboard shortcuts. Click the binding to capture a new key combination.
1761
+ </p>
1762
+ <div id="appSettingsShortcutsList" style="grid-column: 1 / -1;">
1763
+ <!-- Populated by app.renderShortcutSettingsList() -->
1764
+ </div>
1765
+ </div>
1766
+ </div>
1605
1767
  </div>
1606
1768
  <div class="form-actions">
1607
1769
  <button class="btn-toolbar" onclick="app.closeAppSettings()">Cancel</button>
@@ -1610,6 +1772,23 @@
1610
1772
  </div>
1611
1773
  </div>
1612
1774
 
1775
+ <!-- Shortcut Overlay Modal -->
1776
+ <div class="modal shortcut-overlay-modal" id="shortcutOverlayModal" tabindex="-1">
1777
+ <div class="modal-backdrop" onclick="app.closeShortcutOverlay()"></div>
1778
+ <div class="modal-content">
1779
+ <div class="modal-header">
1780
+ <span class="modal-title">Keyboard Shortcuts</span>
1781
+ <button class="modal-close" onclick="app.closeShortcutOverlay()" aria-label="Close">&#x2715;</button>
1782
+ </div>
1783
+ <div class="modal-body">
1784
+ <div id="shortcutOverlayList"></div>
1785
+ <div class="shortcut-overlay-footer">
1786
+ <button class="btn btn-sm" onclick="app.closeShortcutOverlay(); app.showHelp()">Full shortcut reference</button>
1787
+ </div>
1788
+ </div>
1789
+ </div>
1790
+ </div>
1791
+
1613
1792
  <!-- Create Case Modal -->
1614
1793
  <div class="modal" id="createCaseModal">
1615
1794
  <div class="modal-backdrop" onclick="app.closeCreateCaseModal()"></div>
@@ -1621,6 +1800,7 @@
1621
1800
  <div class="modal-tabs">
1622
1801
  <button class="modal-tab-btn active" data-tab="case-create">Create New</button>
1623
1802
  <button class="modal-tab-btn" data-tab="case-link">Link Existing</button>
1803
+ <button class="modal-tab-btn" data-tab="case-remote">Remote</button>
1624
1804
  <button class="modal-tab-btn" data-tab="case-manage">Manage</button>
1625
1805
  </div>
1626
1806
  <div class="modal-body">
@@ -1649,6 +1829,66 @@
1649
1829
  <span class="form-hint">Absolute path to an existing project folder, e.g. /home/you/my-project</span>
1650
1830
  </div>
1651
1831
  </div>
1832
+ <!-- Remote Tab -->
1833
+ <div class="modal-tab-content hidden" id="case-remote">
1834
+ <div class="form-row">
1835
+ <label>Case Name</label>
1836
+ <input type="text" id="remoteCaseName" placeholder="gpu-work" pattern="[a-zA-Z0-9_-]+" autocomplete="off" autocapitalize="off" spellcheck="false">
1837
+ <span class="form-hint">Name to identify this remote case in Codeman</span>
1838
+ </div>
1839
+ <div class="form-row">
1840
+ <label>Remote Path</label>
1841
+ <input type="text" id="remoteCasePath" placeholder="/home/user/projects/work" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false">
1842
+ <span class="form-hint">Absolute path on the remote host. Codeman will not create or delete it.</span>
1843
+ </div>
1844
+ <div class="form-row">
1845
+ <label>Host ID</label>
1846
+ <input type="text" id="remoteHostId" placeholder="gpu-box" pattern="[a-zA-Z0-9_-]+" autocomplete="off" autocapitalize="off" spellcheck="false">
1847
+ </div>
1848
+ <div class="form-row">
1849
+ <label>SSH Host/IP</label>
1850
+ <input type="text" id="remoteHostAddress" placeholder="10.0.0.42" autocomplete="off" autocapitalize="off" spellcheck="false">
1851
+ </div>
1852
+ <div class="form-row">
1853
+ <label>SSH Username</label>
1854
+ <input type="text" id="remoteHostUsername" placeholder="ubuntu" autocomplete="off" autocapitalize="off" spellcheck="false">
1855
+ </div>
1856
+ <div class="form-row">
1857
+ <label>SSH Port</label>
1858
+ <input type="number" id="remoteHostPort" placeholder="22" min="1" max="65535" autocomplete="off">
1859
+ <span class="form-hint">Optional. Leave blank for the default port 22.</span>
1860
+ </div>
1861
+ <div class="form-row">
1862
+ <label>Codex Command Override</label>
1863
+ <input type="text" id="remoteHostCodexCommand" placeholder="exec codx personal" autocomplete="off" autocapitalize="off" spellcheck="false">
1864
+ <span class="form-hint">Optional. Leave blank to use exec codex on the remote host.</span>
1865
+ </div>
1866
+ <details class="advanced-options">
1867
+ <summary>Advanced SSH</summary>
1868
+ <div class="advanced-options-content">
1869
+ <div class="form-row">
1870
+ <label>Identity File</label>
1871
+ <input type="text" id="remoteHostIdentityFile" placeholder="~/.ssh/remote_ed25519" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false">
1872
+ <span class="form-hint">Optional. Path to a private key on this machine (passed to ssh -i). Never the key contents.</span>
1873
+ </div>
1874
+ <div class="form-row">
1875
+ <label>SOCKS Proxy</label>
1876
+ <input type="text" id="remoteHostSocksProxy" placeholder="127.0.0.1:1080" autocomplete="off" autocapitalize="off" spellcheck="false">
1877
+ <span class="form-hint">Optional. host:port of a SOCKS5 proxy (e.g. cloudflared). Routes ssh through it via a ProxyCommand.</span>
1878
+ </div>
1879
+ <div class="form-row">
1880
+ <label>Jump Host</label>
1881
+ <input type="text" id="remoteHostJumpHost" placeholder="bastion@10.0.0.1:22" autocomplete="off" autocapitalize="off" spellcheck="false">
1882
+ <span class="form-hint">Optional. [user@]host[:port] for ssh -J (jump/bastion host).</span>
1883
+ </div>
1884
+ <div class="form-row">
1885
+ <label>Extra -o Options</label>
1886
+ <textarea id="remoteHostExtraSshOptions" rows="3" placeholder="StrictHostKeyChecking=accept-new&#10;ConnectTimeout=10" autocomplete="off" autocapitalize="off" spellcheck="false"></textarea>
1887
+ <span class="form-hint">Optional. One KEY=VALUE per line; each becomes an ssh -o option.</span>
1888
+ </div>
1889
+ </div>
1890
+ </details>
1891
+ </div>
1652
1892
  <!-- Manage Tab -->
1653
1893
  <div class="modal-tab-content hidden" id="case-manage">
1654
1894
  <div class="case-manage-list" id="caseManageList">
@@ -1948,6 +2188,36 @@
1948
2188
  </div>
1949
2189
  </div>
1950
2190
 
2191
+ <!-- Command Palette Modal -->
2192
+ <div class="modal command-palette-modal" id="commandPaletteModal">
2193
+ <div class="modal-backdrop" onclick="app.closeCommandPalette()"></div>
2194
+ <div class="command-palette-shell" role="dialog" aria-modal="true" aria-labelledby="commandPaletteTitle">
2195
+ <div class="command-palette-input-row">
2196
+ <span class="command-palette-search-icon" aria-hidden="true">⌕</span>
2197
+ <input type="search" id="commandPaletteSearch" class="command-palette-search" placeholder="Search open sessions or start a new one" autocomplete="off" maxlength="160" aria-labelledby="commandPaletteTitle">
2198
+ <kbd>Esc</kbd>
2199
+ </div>
2200
+ <div class="command-palette-label" id="commandPaletteTitle">Open sessions</div>
2201
+ <div id="commandPaletteList" class="command-palette-list"></div>
2202
+ </div>
2203
+ </div>
2204
+
2205
+ <!-- Session Manager Modal -->
2206
+ <div class="modal" id="sessionManagerModal">
2207
+ <div class="modal-backdrop" onclick="app.closeSessionManager()"></div>
2208
+ <div class="modal-content session-manager-modal">
2209
+ <div class="modal-header">
2210
+ <h3>Sessions</h3>
2211
+ <button class="modal-close" onclick="app.closeSessionManager()" aria-label="Close session manager">&times;</button>
2212
+ </div>
2213
+ <div class="modal-body">
2214
+ <input type="search" id="sessionManagerSearch" class="search-input" placeholder="Search sessions by name, prompt, or path&hellip;" autocomplete="off" maxlength="200">
2215
+ <div id="sessionManagerList" class="session-manager-list"></div>
2216
+ </div>
2217
+ </div>
2218
+ </div>
2219
+
2220
+
1951
2221
  <!-- Token Stats Modal -->
1952
2222
  <div class="modal" id="tokenStatsModal">
1953
2223
  <div class="modal-backdrop" onclick="app.closeTokenStats()"></div>
@@ -2043,23 +2313,24 @@
2043
2313
  <!-- Lines drawn dynamically -->
2044
2314
  </svg>
2045
2315
 
2046
- <script defer src="constants.1c779517.js"></script>
2316
+ <script defer src="constants.5b18ed64.js"></script>
2047
2317
  <script defer src="mobile-handlers.b5a667ef.js"></script>
2048
2318
  <script defer src="voice-input.085e9e73.js"></script>
2049
2319
  <script defer src="notification-manager.ca9dc40d.js"></script>
2050
2320
  <script defer src="keyboard-accessory.3f91acef.js"></script>
2051
- <script defer src="input-cjk.4e950e0a.js"></script>
2321
+ <script defer src="input-cjk.63794d0b.js"></script>
2052
2322
  <!-- Hardened markdown HTML sanitizer (wires DOMPurify). Must precede app.js. -->
2053
2323
  <script defer src="sanitize-html.bc7078d6.js"></script>
2054
- <script defer src="app.a8d73c32.js"></script>
2055
- <script defer src="terminal-ui.865f21f6.js"></script>
2324
+ <script defer src="app.b0534652.js"></script>
2325
+ <script defer src="terminal-ui.dbf141fa.js"></script>
2056
2326
  <script defer src="respawn-ui.2d249da9.js"></script>
2057
2327
  <script defer src="ralph-panel.6de2d0f8.js"></script>
2058
2328
  <script defer src="orchestrator-panel.js"></script>
2059
- <script defer src="settings-ui.38feb956.js"></script>
2060
- <script defer src="panels-ui.772e92c9.js"></script>
2329
+ <script defer src="cron-ui.js"></script>
2330
+ <script defer src="settings-ui.6c67c125.js"></script>
2331
+ <script defer src="panels-ui.ca03853f.js"></script>
2061
2332
  <script defer src="ultracode-panel.js"></script>
2062
- <script defer src="session-ui.da3e53f2.js"></script>
2333
+ <script defer src="session-ui.b51814ef.js"></script>
2063
2334
  <script defer src="ralph-wizard.13a1831e.js"></script>
2064
2335
  <script defer src="api-client.c9b1cddc.js"></script>
2065
2336
  <script defer src="subagent-windows.69b60c35.js"></script>
Binary file
Binary file
@@ -0,0 +1 @@
1
+ "use strict";const CjkInput=(()=>{let t=null,s=null,y=!1,o=!1,a=null,c=null,T=!1,_=null,w=0,h="";const i={},f="\u200B",D=200,k=[];function d(n){const e=String(n??"");return`len=${p(e).length}${e.includes(f)?"+ph":""}`}function b(n){const e=String(n??"");return[...e].length===1?"printable":e}function r(n){k.push(`${Date.now()%1e6} ${n}`),k.length>D&&k.shift();try{typeof _crashDiag<"u"&&_crashDiag.log("CJK "+n)}catch{}}const $=150,S=1500,L=3e3,E={ArrowUp:"\x1B[A",ArrowDown:"\x1B[B",ArrowLeft:"\x1B[D",ArrowRight:"\x1B[C",Home:"\x1B[H",End:"\x1B[F",Tab:" "},x={c:"",d:"",l:"\f",z:"",a:"",e:""};function p(n){return n.replace(/​/g,"")}function l(){if(t.value===f){(t.selectionStart!==1||t.selectionEnd!==1)&&t.setSelectionRange(1,1);return}t.value=f,t.setSelectionRange(1,1)}function m(){return!p(t.value)}function A(){if(o){r("flush SKIP composing");return}const n=p(t.value);r(`flush ${n?"send len="+n.length:"empty"}`),n&&s(n),l()}function u(){a&&(clearTimeout(a),a=null)}function C(){T=!0,clearTimeout(_),_=setTimeout(()=>{T=!1,_=null},L)}function g(){u(),a=setTimeout(()=>{a=null,A()},T?S:$)}return{init({send:n}){return y&&this.destroy(),s=n,o=!1,a=null,t=document.getElementById("cjkInput"),t?(l(),r("init v2-trace"),i.mousedown=e=>{e.stopPropagation()},/Android/i.test(navigator.userAgent)&&(i.pointerdown=()=>{document.activeElement===t&&!o&&m()&&(r("ime-reset (retap)"),t.blur(),setTimeout(()=>t.focus(),0))},t.addEventListener("pointerdown",i.pointerdown)),i.focus=()=>{r(`focus ${d(t.value)}`),window.cjkActive=!0,t.value||l()},i.blur=()=>{r(`blur composing=${o} ${d(t.value)}`),t.classList.contains("cjk-input-visible")||(window.cjkActive=!1),o=!1},t.addEventListener("mousedown",i.mousedown),t.addEventListener("focus",i.focus),t.addEventListener("blur",i.blur),i.compositionstart=()=>{r(`compstart ${d(t.value)}`),o=!0,u()},i.compositionend=()=>{r(`compend ${d(t.value)}`),o=!1,u(),clearTimeout(c),c=setTimeout(()=>{c=null,A()},0)},t.addEventListener("compositionstart",i.compositionstart),t.addEventListener("compositionend",i.compositionend),i.keydown=e=>{if(r(`keydown ${b(e.key)} kc=${e.keyCode} ic=${e.isComposing} c=${o}`),e.key==="Enter"){e.preventDefault(),o=!1,u();const v=p(t.value);s(v?v+"\r":"\r"),l();return}if(e.key==="Escape"){e.preventDefault(),o=!1,u(),l();return}if(e.ctrlKey&&x[e.key]){e.preventDefault(),s(x[e.key]);return}if(!(o||e.isComposing||e.keyCode===229)){if(e.key==="Backspace"&&m()){e.preventDefault(),s("\x7F"),l();return}if(E[e.key]&&m()){e.preventDefault(),s(E[e.key]);return}if(e.key.length===1&&!e.ctrlKey&&!e.altKey&&!e.metaKey&&m()){e.preventDefault(),s(e.key),w=performance.now(),h=e.key,l();return}}},t.addEventListener("keydown",i.keydown),i.input=e=>{if(r(`input ${e.inputType||"?"} ic=${e.isComposing} c=${o} ${d(t.value)}`),o&&e.isComposing===!1&&e.inputType!=="insertCompositionText"&&e.inputType!=="deleteCompositionText"&&(r("UNSTICK composing"),o=!1),e.inputType==="deleteContentBackward"||e.inputType==="deleteWordBackward"){if(o)return;if(m()){u(),s("\x7F"),l();return}C(),t.value.startsWith(f)||(t.value=f+t.value,t.setSelectionRange(1,1)),g();return}if(e.inputType==="insertReplacementText"){C(),g();return}if(!o){if(performance.now()-w<100){const v=p(t.value);if(v===""||v===h){r("echo-drop"),l();return}}g()}},t.addEventListener("input",i.input),y=!0,this):this},clear(){!y||!t||(r("clear (external)"),u(),clearTimeout(c),c=null,o=!1,l())},getTrace(){return k.slice()},destroy(){if(u(),clearTimeout(c),c=null,clearTimeout(_),T=!1,t)for(const[n,e]of Object.entries(i))e&&t.removeEventListener(n,e);window.cjkActive=!1,o=!1;for(const n of Object.keys(i))delete i[n];y=!1},get element(){return t}}})();
@@ -0,0 +1 @@
1
+ html.mobile-init .header-font-controls,html.mobile-init .header-system-stats,html.mobile-init .header-tokens,html.mobile-init .monitor-panel,html.mobile-init .subagents-panel,html.mobile-init .project-insights-panel,html.mobile-init .file-browser-panel{display:none!important}@media(max-width:768px){input,textarea,select{font-size:16px!important}html{touch-action:manipulation}.session-tab .tab-detach{display:none!important}}@media(max-width:768px)and (min-width:430px){.header{position:fixed;top:0;left:0;right:0;min-height:48px;max-height:48px;padding:.35rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));background:#0a0a0a;border-bottom:1px solid rgba(255,255,255,.08);contain:none;overflow:visible;z-index:1200}.ios-device .header{padding-top:calc(.35rem + var(--safe-area-top));min-height:calc(48px + var(--safe-area-top));max-height:calc(48px + var(--safe-area-top))}.app{padding-top:54px}.ios-device .app{padding-top:calc(54px + var(--safe-area-top))}.header-font-controls{gap:.15rem;padding:.15rem .25rem}.header-font-controls .btn-icon-sm{width:18px;height:18px}.header-system-stats{font-size:.6rem;gap:.25rem}.header-right{gap:.35rem}.btn-icon-header:not(.btn-sm){width:44px;height:44px}.session-tabs,.session-tabs.tabs-two-rows{flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scrollbar-width:none;max-height:52px;gap:3px}.session-tabs::-webkit-scrollbar{display:none}.session-tab{padding:.4rem .6rem;font-size:.75rem;min-height:40px}.session-tab .tab-name{max-width:80px}.toolbar{padding:.4rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));gap:.4rem}.tab-count-group{display:none}.btn-toolbar{padding:.4rem .8rem;font-size:.8rem;min-height:40px}.case-select-group{max-width:none}.case-combobox{width:160px}.toolbar-select{font-size:.75rem}.monitor-panel,.subagents-panel{width:100%;max-width:100%;left:0;right:0;border-radius:8px 8px 0 0;max-height:40vh}.project-insights-panel{max-width:280px;font-size:.7rem}.modal{z-index:1300}.command-palette-modal{padding:10vh .75rem 0}.command-palette-shell{width:100%;max-height:74vh}.command-palette-input-row{grid-template-columns:20px minmax(0,1fr)}.command-palette-input-row kbd{display:none}.command-palette-item{min-height:56px}.modal-tabs{overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;flex-wrap:nowrap}.modal-tabs::-webkit-scrollbar{display:none}.modal-tab-btn{padding:.4rem .75rem;font-size:.7rem;white-space:nowrap;flex-shrink:0}.settings-grid{gap:.4rem .75rem}.settings-item{font-size:.7rem}.event-type-grid{grid-template-columns:1fr 40px 40px 40px;gap:5px 6px}.event-label{font-size:.7rem}.subagent-window{width:320px;height:280px;min-width:240px;min-height:160px}.subagent-window-header{padding:.35rem .5rem}.subagent-window-title .id{font-size:.7rem;max-width:180px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.subagent-window-title .status{font-size:.55rem}.subagent-window-body{font-size:.7rem}.respawn-banner{padding:.25rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));font-size:.65rem}.respawn-compact-layout{gap:.75rem}.respawn-status-row1{gap:.4rem}.respawn-action-log{max-height:2.6em;font-size:.6rem}.respawn-countdown-timer{font-size:.55rem}.respawn-timer-bar{width:24px}.toolbar-center .btn-toolbar.btn-voice{display:flex!important}.toolbar{padding:0 .5rem;gap:.5rem}.toolbar-left,.toolbar-right,.toolbar-group{gap:.5rem}.btn-toolbar{padding:.4rem .75rem;font-size:.75rem;min-height:unset}}@media(max-width:430px){.header-brand{padding-right:.25rem;margin-right:.2rem;border-right:none}.header-brand .logo{font-size:.7rem}.header-font-controls{gap:.1rem;padding:.1rem .2rem}.header-font-controls .btn-icon-sm{width:16px;height:16px}.header-font-controls .font-size-display{font-size:.6rem;min-width:14px}.header-system-stats{font-size:.55rem;gap:.15rem}.header-tokens{font-size:.6rem;padding:.1rem .3rem}.header{position:fixed;top:0;left:0;right:0;min-height:36px;max-height:36px;padding:.15rem .3rem;padding-left:calc(.3rem + var(--safe-area-left));padding-right:calc(.3rem + var(--safe-area-right));gap:.15rem;overflow:hidden;background:#0a0a0a;border-bottom:1px solid rgba(255,255,255,.08);contain:none;z-index:1200}.ios-device .header{padding-top:calc(.15rem + var(--safe-area-top));min-height:calc(36px + var(--safe-area-top));max-height:calc(36px + var(--safe-area-top))}.app{padding-top:42px}.ios-device .app{padding-top:calc(42px + var(--safe-area-top))}.main{padding-bottom:calc(40px + var(--safe-area-bottom))}.ios-device.safari-browser .main{padding-bottom:calc(40px + var(--safe-area-bottom) + (100vh - var(--app-height, 100vh)))}.header-right{padding-left:.2rem;gap:.1rem;flex-shrink:0;border-left:none}.btn-icon-header{width:26px;height:26px;padding:0}.btn-icon-header svg{width:12px;height:12px}.btn-icon-header.btn-settings,.btn-icon-header.btn-lifecycle-log,.btn-icon-header.btn-away-digest,.btn-icon-header.btn-session-manager{display:none!important}.btn-voice-mobile{display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;background:#1a2a3f;border:1px solid rgba(59,130,246,.3);border-radius:4px;color:#93c5fd;cursor:pointer;flex-shrink:0;order:5}.btn-voice-mobile svg{width:13px;height:13px}.btn-voice-mobile:active{background:#2a3a5f}.btn-voice-mobile.recording{background:#ef444440;border-color:#ef444499;color:#ef4444;animation:mobile-voice-pulse 1.2s ease-in-out infinite}@keyframes mobile-voice-pulse{0%,to{box-shadow:inset 0 0 0 1px #ef444459;background:#ef444433}50%{box-shadow:inset 0 0 0 2px #ef4444bf;background:#ef444459}}.btn-settings-mobile{display:inline-flex!important;align-items:center;justify-content:center;width:26px;height:26px;background:transparent;border:1px solid rgba(255,255,255,.2);border-radius:4px;color:#9ca3af;font-size:.85rem;cursor:pointer;flex-shrink:0;order:6;position:relative}.btn-settings-mobile svg{width:13px;height:13px}.btn-settings-mobile:active{background:#ffffff1a;color:#fff}.app{overflow:hidden;position:relative}.keyboard-visible .app{position:fixed;inset:0 0 auto;height:var(--app-height, 100dvh)}.session-tabs,.session-tabs.tabs-two-rows{flex:1;flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scrollbar-width:none;max-height:36px;gap:2px;padding:0}.session-tabs::-webkit-scrollbar{display:none}.session-tab{flex-shrink:0;min-height:32px;max-height:32px;padding:.35rem .5rem;font-size:.7rem;gap:.25rem;border-radius:4px}.session-tab .tab-status{width:4px;height:4px}.session-tab .tab-name{max-width:50px;overflow:hidden;text-overflow:ellipsis}.session-tab .tab-close,.session-tab .tab-gear{display:none}.session-tab.active .tab-gear{display:inline-flex;align-items:center;justify-content:center;font-size:.65rem;line-height:1;width:32px;height:32px;margin-left:auto;opacity:.6}.session-tab.active .tab-close{display:inline-flex;align-items:center;justify-content:center;font-size:1.1rem;line-height:1;width:20px;height:18px;margin-left:-2px}.toolbar{position:fixed;bottom:var(--safe-area-bottom);left:0;right:0;height:40px;min-height:40px;max-height:40px;padding:.3rem .4rem;padding-left:calc(.4rem + var(--safe-area-left));padding-right:calc(.4rem + var(--safe-area-right));flex-wrap:nowrap;gap:.3rem;align-items:center;justify-content:space-between;background:#111;border-top:1px solid rgba(255,255,255,.1);z-index:50;transition:transform .15s ease-out;will-change:transform}.ios-device.safari-browser .toolbar{bottom:calc(var(--safe-area-bottom) + (100vh - var(--app-height, 100vh)))}.keyboard-visible.ios-device.safari-browser .toolbar{bottom:var(--safe-area-bottom)}.keyboard-visible.ios-device.safari-browser .keyboard-accessory-bar{bottom:calc(var(--safe-area-bottom) + 40px)}.toolbar-center{display:flex!important;align-items:center}.toolbar-center .btn-toolbar.btn-voice,.toolbar-right,.version-display{display:none!important}.toolbar-left{flex:1 1 0;min-width:0;align-items:center;gap:.3rem}.toolbar-left .toolbar-group{display:flex;flex:1 1 0;min-width:0;align-items:center;gap:.3rem}.toolbar-left .toolbar-group:first-child{flex:1 1 0;min-width:0;justify-content:space-between;gap:.3rem;flex-wrap:nowrap;align-items:center}.tab-count-group{display:none!important}.btn-toolbar{min-height:26px!important;max-height:26px!important;height:26px!important;padding:0 .5rem!important;font-size:.65rem!important;border-radius:4px;line-height:26px;display:inline-flex;align-items:center;justify-content:center;font-weight:500;letter-spacing:.01em;color:#fff}.run-btn-group{display:flex;flex:0 0 auto}.btn-toolbar.btn-run{flex:0 0 auto;padding:0 .6rem!important;font-weight:500;border-radius:4px 0 0 4px!important;border-right:none!important}.btn-toolbar.btn-run svg{width:10px;height:10px;margin-right:3px}.btn-toolbar.btn-run-gear{flex:0 0 auto;padding:0 .35rem!important;min-width:unset!important;border-radius:0 4px 4px 0!important;border-left:1px solid rgba(255,255,255,.15)!important}.btn-toolbar.btn-run-gear svg{width:10px;height:10px}.btn-toolbar.btn-run.mode-claude,.btn-toolbar.btn-run-gear.mode-claude{background:#1e3a5f;border-color:#3b82f64d;color:#93c5fd}.btn-toolbar.btn-run.mode-claude:active,.btn-toolbar.btn-run-gear.mode-claude:active{background:#2563eb;border-color:#3b82f680}.btn-toolbar.btn-run.mode-opencode,.btn-toolbar.btn-run-gear.mode-opencode{background:#0a2e2a;border-color:#10b9814d;color:#6ee7b7}.btn-toolbar.btn-run.mode-opencode:active,.btn-toolbar.btn-run-gear.mode-opencode:active{background:#0d4a40;border-color:#10b98180}.btn-toolbar.btn-run.mode-gemini,.btn-toolbar.btn-run-gear.mode-gemini{background:#10243f;border-color:#60a5fa4d;color:#dbeafe}.btn-toolbar.btn-run.mode-gemini:active,.btn-toolbar.btn-run-gear.mode-gemini:active{background:#174ea6;border-color:#60a5fa80}.run-mode-menu{bottom:100%;left:0;margin-bottom:6px;min-width:160px;max-width:80vw}.run-mode-option{padding:10px 12px;font-size:.8rem;cursor:pointer;-webkit-tap-highlight-color:rgba(255,255,255,.1)}.run-mode-history{-webkit-overflow-scrolling:touch;touch-action:manipulation}.btn-toolbar.btn-stop{display:flex!important;flex:0 0 auto;padding:0 8px!important;min-width:unset;order:3}.btn-toolbar.btn-stop svg{width:10px;height:10px;margin-right:0}.btn-toolbar.btn-shell{flex:0 0 auto;background:transparent;border:1px solid rgba(255,255,255,.2);color:#9ca3af;order:4}.btn-toolbar.btn-shell:hover,.btn-toolbar.btn-shell:active{background:#ffffff1a;color:#fff}.case-select-group{display:none!important}.toolbar-left .toolbar-group:first-child{width:100%;gap:8px}.btn-toolbar.btn-shell{flex:0 0 auto;min-width:54px;width:54px;white-space:nowrap;padding:0 8px!important;overflow:hidden;font-size:0!important}.btn-toolbar.btn-shell:after{content:"Shell";font-size:.65rem}.btn-toolbar.btn-case-mobile{display:flex!important;flex:1 1 0!important;min-width:0;padding:0 8px!important;order:2;overflow:hidden;justify-content:center;gap:4px}.btn-toolbar.btn-case-mobile #mobileCaseName{max-width:none;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.btn-case-settings-mobile{display:inline-flex!important;align-items:center;justify-content:center;width:26px;height:26px;background:transparent;border:1px solid rgba(255,255,255,.2);border-radius:4px;color:#9ca3af;cursor:pointer;flex-shrink:0;order:1}.btn-case-settings-mobile:active{background:#ffffff1a;color:#fff}@media(max-width:374px){.toolbar{padding:0 2px}.toolbar-left,.toolbar-left .toolbar-group,.toolbar-left .toolbar-group:first-child{gap:2px}}.btn-case-settings-mobile{display:none!important}.case-settings-popover-mobile{position:fixed;bottom:calc(var(--safe-area-bottom) + 46px);left:8px;right:8px;background:#1e1e1e;border:1px solid rgba(255,255,255,.15);border-radius:8px;padding:.6rem .75rem;z-index:1000;box-shadow:0 4px 16px #00000080;display:block}.case-settings-popover-mobile.hidden{display:none!important}.case-settings-popover-mobile .checkbox-inline{display:flex;align-items:center;gap:6px;font-size:.75rem;color:#e5e7eb}.case-settings-popover-mobile .form-hint{display:block;margin-top:.2rem;font-size:.6rem;color:#6b7280}.keyboard-accessory-bar{display:none;position:fixed;bottom:calc(var(--safe-area-bottom) + 40px);left:0;right:0;height:44px;background:#1a1a1a;border-top:1px solid rgba(255,255,255,.1);padding:6px 8px;padding-left:calc(8px + var(--safe-area-left));padding-right:calc(8px + var(--safe-area-right));gap:8px;align-items:center;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;z-index:51;transition:transform .15s ease-out;will-change:transform}.keyboard-accessory-bar.visible{display:flex}.keyboard-accessory-bar::-webkit-scrollbar{display:none}.accessory-btn{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;gap:4px;padding:6px 12px;background:#2a2a2a;border:1px solid rgba(255,255,255,.15);border-radius:6px;color:#e5e5e5;font-size:.65rem;font-weight:500;cursor:pointer;transition:background .15s,border-color .15s}.accessory-btn.confirming{background:#6b4f00;border-color:#b8860b;color:#ffd54f}.accessory-btn:active{background:#3a3a3a}.accessory-btn svg{width:14px;height:14px}.accessory-btn-arrow{padding:6px 10px;background:#2563eb;border-color:#3b82f680;color:#fff}.accessory-btn-arrow:active{background:#1d4ed8}.accessory-btn-dismiss{margin-left:auto;flex:1 1 0;max-width:100px;padding:10px 8px;background:#2563eb;border-color:#3b82f680;color:#fff;font-weight:600}.accessory-btn-dismiss svg{width:22px;height:22px}.accessory-btn-dismiss:active{background:#1d4ed8}.voice-preview{bottom:calc(var(--safe-area-bottom) + 94px);font-size:.8rem;max-width:90%;padding:6px 14px}.btn-case-add,.btn-case-settings,.toolbar-select{display:none!important}.toolbar .btn-case-add{min-width:26px!important;max-width:26px!important;width:26px!important;min-height:26px!important;max-height:26px!important;height:26px!important;padding:0!important;font-size:.9rem;font-weight:700;display:inline-flex!important;align-items:center;justify-content:center;line-height:1;border-radius:4px;background:transparent;border:1px solid rgba(255,255,255,.15);color:#9ca3af}.btn-case-add:hover,.btn-case-add:active{background:#ffffff1a;color:#fff}.monitor-panel,.subagents-panel{width:100%;max-width:100%;left:0;right:0;border-radius:8px 8px 0 0;bottom:calc(44px + 2rem + var(--safe-area-bottom));max-height:35vh}.modal{z-index:1300}.modal-content{width:100%;max-width:100%;height:100%;max-height:100%;border-radius:0;margin:0;display:flex;flex-direction:column}.modal-content.modal-sm{height:auto;max-height:85vh;border-radius:12px;margin:1rem;width:calc(100% - 2rem)}.ios-device .modal-content{padding-top:var(--safe-area-top);padding-bottom:var(--safe-area-bottom);padding-left:var(--safe-area-left);padding-right:var(--safe-area-right)}.modal-header{padding:.75rem 1rem}.modal-header h3{font-size:1rem}.modal-body{padding:.75rem 1rem;flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch}.away-digest-modal{width:100%;max-width:100%;height:100%;max-height:100%}.away-digest-ranges{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:.4rem}.away-digest-ranges .filter-btn{min-height:38px;padding:.4rem .5rem}.away-digest-custom-range,.away-digest-custom-range.active{grid-template-columns:1fr}.away-digest-summary{grid-template-columns:repeat(2,minmax(0,1fr));gap:.5rem}.away-digest-item{grid-template-columns:1fr;gap:.5rem}.away-digest-action{width:100%;min-height:38px}.modal-footer,.form-actions{padding:.75rem 1rem;padding-bottom:calc(.75rem + var(--safe-area-bottom))}.ios-device .terminal-container{padding-bottom:var(--safe-area-bottom)}.main{flex:1;min-height:0}.cli-info-bar{display:block}.terminal-container{height:100%;min-height:0;position:relative;overflow:visible;touch-action:none}.terminal-container .xterm,.terminal-container .xterm-viewport,.terminal-container .xterm-screen{touch-action:none}.response-viewer{padding-bottom:var(--safe-area-bottom, 0px);max-height:88vh;max-height:92dvh}.response-viewer-body{font-size:14.5px;line-height:1.65;padding:16px 16px 24px;--rv-content-max: 100%}.response-viewer-body .rv-text pre,.response-viewer-body pre{padding:12px 14px;margin-left:-4px;margin-right:-4px;border-radius:6px}.response-viewer-body .rv-text pre code,.response-viewer-body pre code{font-size:11.5px;line-height:1.5}.response-viewer-body .rv-text h1,.response-viewer-body>h1{font-size:1.35em}.response-viewer-body .rv-text h2,.response-viewer-body>h2{font-size:1.2em}.response-viewer-body .rv-text h3,.response-viewer-body>h3{font-size:1.08em}.welcome-content{max-width:calc(100vw - 1.5rem);padding:1rem .75rem}.welcome-title{font-size:1.2rem;margin-bottom:.5rem}.welcome-desc{font-size:.8rem;margin-bottom:.4rem}.welcome-actions{flex-direction:column;gap:.5rem;margin-top:1rem}.welcome-btn{width:100%;justify-content:center;min-height:44px;padding:.75rem 1rem;font-size:.85rem}.history-show-more{display:block;margin-bottom:.75rem}.welcome-ralph-link{display:block;margin:.75rem auto 0}.welcome-hint{font-size:.7rem;margin-top:.75rem}.modal-wizard{display:flex;flex-direction:column}.wizard-progress{padding:.5rem}.wizard-step{padding:.3rem}.wizard-step-number{width:24px;height:24px;font-size:.7rem}.wizard-step-label{display:none}.timer-banner{padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right))}.respawn-banner{padding:.3rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right));font-size:.65rem}.respawn-compact-layout{flex-direction:column;gap:.15rem}.respawn-status-col{flex-shrink:1;min-width:0;gap:.1rem}.respawn-status-row1{flex-wrap:wrap;gap:.25rem;row-gap:.1rem}.respawn-state{font-size:.6rem;padding:.05rem .3rem}.respawn-banner .detection-confidence{font-size:.5rem;padding:.02rem .2rem}.respawn-cycles{font-size:.55rem}.respawn-timer{font-size:.55rem;padding:0 .25rem}.respawn-tokens{font-size:.55rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:120px}.respawn-indicator{font-size:.65rem}.respawn-banner .btn-icon-only{min-width:36px;min-height:36px;font-size:1rem;display:flex;align-items:center;justify-content:center;margin-left:auto;border-radius:6px;flex-shrink:0}.respawn-status-row2{font-size:.55rem;gap:.3rem;min-height:0;flex-wrap:wrap}.respawn-banner .detection-hook,.respawn-banner .detection-ai-check,.respawn-banner .detection-status{font-size:.55rem;padding:.02rem .2rem}.respawn-countdown-timers{gap:.2rem}.respawn-countdown-timer{font-size:.5rem;padding:.02rem .2rem;gap:.15rem}.respawn-countdown-timer .respawn-timer-bar{display:none}.respawn-action-log{border-left:none;border-top:1px solid rgba(34,197,94,.15);padding-left:0;padding-top:.15rem;max-height:1.4em;font-size:.55rem;overflow:hidden}.respawn-header{flex-direction:row;gap:.4rem;align-items:center}.respawn-header .respawn-actions{display:flex;gap:.3rem;flex-shrink:0}.respawn-header .respawn-actions .btn-toolbar{min-height:28px!important;font-size:.7rem!important;padding:.2rem .5rem!important;border-radius:5px}.duration-presets{display:flex;flex-wrap:wrap;gap:.2rem}.duration-preset-btn{min-height:24px;padding:.1rem .4rem;font-size:.6rem;border-radius:4px;text-align:center}.duration-custom{display:flex;gap:.2rem;align-items:center}.duration-custom-input.visible{flex:0 1 auto}.duration-custom-input input{width:64px;min-height:24px;font-size:16px;padding:.1rem .3rem}.preset-selector{display:grid;grid-template-columns:1fr 1fr;gap:.25rem}.preset-selector select{grid-column:1 / -1;min-height:32px;font-size:16px;border-radius:5px;padding:.2rem .4rem}.preset-selector .btn{min-height:32px;font-size:.65rem;border-radius:5px;padding:.2rem .4rem}#sessionOptionsModal textarea{font-size:16px;min-height:32px!important;max-height:56px;height:auto!important;border-radius:6px;padding:.3rem .5rem}#modalRespawnPrompt{min-height:32px!important;max-height:56px}#modalRespawnKickstart{min-height:32px!important;max-height:48px}#sessionOptionsModal .checkbox-inline{min-height:30px;font-size:.75rem;padding:.15rem 0;gap:.4rem}#sessionOptionsModal .checkbox-inline input[type=checkbox]{width:18px;height:18px}#sessionOptionsModal .respawn-loop-title{font-size:.75rem}#sessionOptionsModal .respawn-loop-box .checkbox-inline{font-size:.65rem}#sessionOptionsModal .respawn-options-row{gap:.5rem}#sessionOptionsModal .form-section-header{margin-top:.75rem;padding-top:.5rem;font-size:.65rem}#sessionOptionsModal .form-row{margin-bottom:.5rem}#sessionOptionsModal .form-row label{font-size:.65rem;margin-bottom:.2rem}#sessionOptionsModal .form-hint{font-size:.6rem;margin-top:.2rem}.context-setting{padding:.625rem}.context-setting-header{flex-wrap:wrap;gap:.4rem}.context-setting-header .input-suffix-sm input{width:60px;font-size:16px;min-height:36px}.context-setting input[type=text]{font-size:16px;min-height:36px;padding:.4rem .6rem;border-radius:6px}.color-picker{gap:8px}.color-swatch{width:36px;height:36px;border-radius:6px}.form-row-switch{min-height:40px;gap:.4rem}.context-settings-grid input[type=number]{font-size:16px;min-height:36px}.ralph-limits-grid{grid-template-columns:1fr 1fr;gap:.5rem}.ralph-limits-grid .form-col input[type=number]{font-size:16px;min-height:36px;padding:.4rem .5rem;border-radius:6px}#modalRalphPhrase{font-size:16px;min-height:40px;border-radius:6px}.ralph-config-actions{margin-top:1rem}.ralph-config-actions .btn-toolbar{width:100%;min-height:44px;font-size:.85rem;border-radius:8px}.run-summary-filters{gap:.3rem;margin-bottom:.5rem}.filter-btn{padding:.35rem .75rem;font-size:.7rem;min-height:32px}.timeline-event{padding:.4rem .5rem;margin-bottom:.25rem;font-size:.7rem}.run-summary-footer{flex-direction:column;gap:.4rem;padding:.5rem 0}.run-summary-actions{flex-wrap:wrap;gap:.3rem}.run-summary-actions .btn-toolbar{flex:1;min-height:36px;font-size:.7rem;white-space:nowrap}.auto-refresh-label{font-size:.7rem}.ralph-panel{font-size:.75rem}.ralph-summary{padding:.4rem .5rem;padding-left:calc(.5rem + var(--safe-area-left));padding-right:calc(.5rem + var(--safe-area-right))}.project-insights-panel{max-width:100%;font-size:.65rem;bottom:calc(44px + 2rem + var(--safe-area-bottom))}.file-browser-panel{max-width:100%;max-height:50vh;bottom:calc(44px + 2rem + var(--safe-area-bottom))}.notification-drawer{width:100%;max-width:100%;right:0;border-radius:0;padding-left:var(--safe-area-left);padding-right:var(--safe-area-right);padding-bottom:var(--safe-area-bottom)}input,textarea,[contenteditable]{scroll-margin-bottom:200px;scroll-margin-top:80px}.keyboard-visible .modal-body{max-height:40vh;overflow-y:auto}.keyboard-visible #createCaseModal .modal-body{max-height:60vh}.mobile-case-picker .modal-backdrop{background:#00000080}.mobile-case-picker-sheet{max-height:60vh;padding-bottom:var(--safe-area-bottom);animation:slideUp .2s ease-out}@keyframes slideUp{0%{transform:translateY(100%)}to{transform:translateY(0)}}.mobile-case-picker-header .modal-close{width:32px;height:32px;font-size:1.5rem}.mobile-case-picker-footer{padding-bottom:calc(12px + var(--safe-area-bottom))}.modal-tabs{overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;gap:.25rem;padding:0 .75rem .5rem;flex-wrap:nowrap}.modal-tabs::-webkit-scrollbar{display:none}.modal-tab-btn{padding:.35rem .6rem;font-size:.65rem;white-space:nowrap;flex-shrink:0}#createCaseModal .modal-tabs{gap:.5rem;padding:.5rem 1rem .75rem}#createCaseModal .modal-tab-btn{flex:1;min-height:44px;padding:.6rem 1rem;font-size:.8rem;font-weight:500;border-radius:8px;justify-content:center;text-align:center}#createCaseModal .form-row{margin-bottom:1rem}#createCaseModal .form-row label{font-size:.8rem;margin-bottom:.4rem;font-weight:500;color:#e5e7eb}#createCaseModal .form-row input[type=text]{min-height:44px;font-size:16px;padding:.5rem .75rem;border-radius:8px}#createCaseModal .form-row .form-hint{font-size:.65rem;margin-top:.35rem;line-height:1.4}#createCaseModal .form-actions{padding:.75rem 1rem;padding-bottom:calc(.75rem + var(--safe-area-bottom));gap:.75rem}#createCaseModal .form-actions .btn-toolbar{min-height:44px!important;max-height:44px!important;height:44px!important;font-size:.85rem!important;font-weight:500;border-radius:8px}#caseModalSubmit.loading{opacity:.6;pointer-events:none}#createCaseModal.from-mobile .modal-content{animation:caseModalSlideUp .25s ease-out}@keyframes caseModalSlideUp{0%{transform:translateY(30px);opacity:0}to{transform:translateY(0);opacity:1}}.btn-case-create-mobile{min-height:48px!important;max-height:48px!important;height:48px!important;font-size:.85rem!important;font-weight:500;border-radius:10px}.settings-grid{grid-template-columns:1fr;gap:.35rem}.settings-grid-3col{grid-template-columns:1fr 1fr 1fr}.settings-item{padding:.35rem .5rem;font-size:.7rem}.settings-item-label{font-size:.7rem}.settings-section-header{font-size:.6rem;padding:.35rem 0 .2rem;margin-top:.5rem}.form-row{margin-bottom:.5rem}.form-row label{font-size:.7rem;margin-bottom:.2rem}.form-row .form-hint{font-size:.6rem}.form-row input[type=text],.form-row input[type=number],.form-row textarea,.form-row .form-select,.form-row select{font-size:.75rem;padding:.35rem .5rem;min-height:32px}.form-row-switch{gap:.3rem}.form-row-switch>label:first-child{font-size:.7rem}.form-section-header{font-size:.6rem;margin-top:.75rem}.event-type-grid{grid-template-columns:1fr 36px 36px 36px;gap:4px 4px;padding:6px;margin-top:6px}.event-header{font-size:.55rem}.event-label{font-size:.65rem}.event-type-grid input[type=checkbox]{width:12px;height:12px}.form-actions{gap:.5rem}.form-actions .btn-toolbar{flex:1;min-height:36px!important;max-height:36px!important;height:36px!important;font-size:.75rem!important}.subagent-window{position:fixed;width:calc(100% - 8px);max-width:calc(100% - 8px);height:110px;min-height:80px;max-height:110px;min-width:200px;border-radius:6px;resize:none;box-shadow:0 2px 8px #0006}.subagent-window:after{display:none}.subagent-window-header{padding:.2rem .4rem;min-height:24px}.subagent-window-title{gap:.2rem;overflow:hidden}.subagent-window-title .icon{font-size:.7rem}.subagent-window-title .id{font-size:.6rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:45vw}.subagent-window-title .status{font-size:.45rem;padding:.05rem .15rem}.subagent-model-badge{font-size:.45rem!important;padding:.05rem .15rem!important}.subagent-window-actions button{font-size:.7rem;padding:.15rem .35rem;min-width:26px;min-height:26px;display:flex;align-items:center;justify-content:center}.subagent-window-body{font-size:.6rem;padding:.2rem .35rem}.subagent-window-body .activity-line{gap:.15rem;padding:.05rem 0}.subagent-window-body .activity-line .time{font-size:.5rem}.subagent-window-body .activity-line .tool-name,.subagent-window-body .activity-line .tool-detail{font-size:.55rem}.subagent-window-parent{display:none}.session-tab .tab-subagent-badge{height:14px;padding:0 3px;border-radius:7px;margin-left:2px}.session-tab .tab-subagent-badge .subagent-label{font-size:.45rem}.subagent-dropdown{position:fixed!important;left:8px!important;right:8px!important;bottom:auto!important;min-width:auto!important;max-width:none!important;border-radius:8px;transform:none!important}}.ios-device.safari-browser{overscroll-behavior:none}@media(hover:none)and (pointer:coarse){.session-tab .tab-close,.session-tab .tab-gear{opacity:1;width:auto;padding:.15rem .25rem;align-items:center;justify-content:center}.btn-toolbar:hover,.btn-icon-header:hover{transform:none}.subagent-dropdown-trigger:active+.subagent-dropdown-menu,.subagent-dropdown-trigger:focus+.subagent-dropdown-menu{display:block}}@media(max-width:430px){.attachment-history-drawer{top:0;bottom:0;width:100%;max-width:100%;height:100vh;height:100dvh;border-left:none;border-radius:0;padding-top:var(--safe-area-top);padding-left:var(--safe-area-left);padding-right:var(--safe-area-right);padding-bottom:var(--safe-area-bottom)}.attachment-history-header{padding:12px}.attachment-history-list{padding:6px}.attachment-history-item{grid-template-columns:104px minmax(0,1fr);gap:8px;padding:8px 6px}.attachment-history-thumb{width:104px}.attachment-history-actions{gap:4px}.attachment-history-actions button{padding:4px 7px}}