codex-autorunner 0.1.2__py3-none-any.whl → 1.1.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 (276) hide show
  1. codex_autorunner/__init__.py +12 -1
  2. codex_autorunner/__main__.py +4 -0
  3. codex_autorunner/agents/codex/harness.py +1 -1
  4. codex_autorunner/agents/opencode/client.py +68 -35
  5. codex_autorunner/agents/opencode/constants.py +3 -0
  6. codex_autorunner/agents/opencode/harness.py +6 -1
  7. codex_autorunner/agents/opencode/logging.py +21 -5
  8. codex_autorunner/agents/opencode/run_prompt.py +1 -0
  9. codex_autorunner/agents/opencode/runtime.py +176 -47
  10. codex_autorunner/agents/opencode/supervisor.py +36 -48
  11. codex_autorunner/agents/registry.py +155 -8
  12. codex_autorunner/api.py +25 -0
  13. codex_autorunner/bootstrap.py +22 -37
  14. codex_autorunner/cli.py +5 -1156
  15. codex_autorunner/codex_cli.py +20 -84
  16. codex_autorunner/core/__init__.py +4 -0
  17. codex_autorunner/core/about_car.py +49 -32
  18. codex_autorunner/core/adapter_utils.py +21 -0
  19. codex_autorunner/core/app_server_ids.py +59 -0
  20. codex_autorunner/core/app_server_logging.py +7 -3
  21. codex_autorunner/core/app_server_prompts.py +27 -260
  22. codex_autorunner/core/app_server_threads.py +26 -28
  23. codex_autorunner/core/app_server_utils.py +165 -0
  24. codex_autorunner/core/archive.py +349 -0
  25. codex_autorunner/core/codex_runner.py +12 -2
  26. codex_autorunner/core/config.py +587 -103
  27. codex_autorunner/core/docs.py +10 -2
  28. codex_autorunner/core/drafts.py +136 -0
  29. codex_autorunner/core/engine.py +1531 -866
  30. codex_autorunner/core/exceptions.py +4 -0
  31. codex_autorunner/core/flows/__init__.py +25 -0
  32. codex_autorunner/core/flows/controller.py +202 -0
  33. codex_autorunner/core/flows/definition.py +82 -0
  34. codex_autorunner/core/flows/models.py +88 -0
  35. codex_autorunner/core/flows/reasons.py +52 -0
  36. codex_autorunner/core/flows/reconciler.py +131 -0
  37. codex_autorunner/core/flows/runtime.py +382 -0
  38. codex_autorunner/core/flows/store.py +568 -0
  39. codex_autorunner/core/flows/transition.py +138 -0
  40. codex_autorunner/core/flows/ux_helpers.py +257 -0
  41. codex_autorunner/core/flows/worker_process.py +242 -0
  42. codex_autorunner/core/git_utils.py +62 -0
  43. codex_autorunner/core/hub.py +136 -16
  44. codex_autorunner/core/locks.py +4 -0
  45. codex_autorunner/core/notifications.py +14 -2
  46. codex_autorunner/core/ports/__init__.py +28 -0
  47. codex_autorunner/core/ports/agent_backend.py +150 -0
  48. codex_autorunner/core/ports/backend_orchestrator.py +41 -0
  49. codex_autorunner/core/ports/run_event.py +91 -0
  50. codex_autorunner/core/prompt.py +15 -7
  51. codex_autorunner/core/redaction.py +29 -0
  52. codex_autorunner/core/review_context.py +5 -8
  53. codex_autorunner/core/run_index.py +6 -0
  54. codex_autorunner/core/runner_process.py +5 -2
  55. codex_autorunner/core/state.py +0 -88
  56. codex_autorunner/core/state_roots.py +57 -0
  57. codex_autorunner/core/supervisor_protocol.py +15 -0
  58. codex_autorunner/core/supervisor_utils.py +67 -0
  59. codex_autorunner/core/text_delta_coalescer.py +54 -0
  60. codex_autorunner/core/ticket_linter_cli.py +201 -0
  61. codex_autorunner/core/ticket_manager_cli.py +432 -0
  62. codex_autorunner/core/update.py +24 -16
  63. codex_autorunner/core/update_paths.py +28 -0
  64. codex_autorunner/core/update_runner.py +2 -0
  65. codex_autorunner/core/usage.py +164 -12
  66. codex_autorunner/core/utils.py +120 -11
  67. codex_autorunner/discovery.py +2 -4
  68. codex_autorunner/flows/review/__init__.py +17 -0
  69. codex_autorunner/{core/review.py → flows/review/service.py} +15 -10
  70. codex_autorunner/flows/ticket_flow/__init__.py +3 -0
  71. codex_autorunner/flows/ticket_flow/definition.py +98 -0
  72. codex_autorunner/integrations/agents/__init__.py +17 -0
  73. codex_autorunner/integrations/agents/backend_orchestrator.py +284 -0
  74. codex_autorunner/integrations/agents/codex_adapter.py +90 -0
  75. codex_autorunner/integrations/agents/codex_backend.py +448 -0
  76. codex_autorunner/integrations/agents/opencode_adapter.py +108 -0
  77. codex_autorunner/integrations/agents/opencode_backend.py +598 -0
  78. codex_autorunner/integrations/agents/runner.py +91 -0
  79. codex_autorunner/integrations/agents/wiring.py +271 -0
  80. codex_autorunner/integrations/app_server/client.py +583 -152
  81. codex_autorunner/integrations/app_server/env.py +2 -107
  82. codex_autorunner/{core/app_server_events.py → integrations/app_server/event_buffer.py} +15 -8
  83. codex_autorunner/integrations/app_server/supervisor.py +59 -33
  84. codex_autorunner/integrations/telegram/adapter.py +204 -165
  85. codex_autorunner/integrations/telegram/api_schemas.py +120 -0
  86. codex_autorunner/integrations/telegram/config.py +221 -0
  87. codex_autorunner/integrations/telegram/constants.py +17 -2
  88. codex_autorunner/integrations/telegram/dispatch.py +17 -0
  89. codex_autorunner/integrations/telegram/doctor.py +47 -0
  90. codex_autorunner/integrations/telegram/handlers/callbacks.py +7 -4
  91. codex_autorunner/integrations/telegram/handlers/commands/__init__.py +2 -0
  92. codex_autorunner/integrations/telegram/handlers/commands/execution.py +53 -57
  93. codex_autorunner/integrations/telegram/handlers/commands/files.py +2 -6
  94. codex_autorunner/integrations/telegram/handlers/commands/flows.py +1364 -0
  95. codex_autorunner/integrations/telegram/handlers/commands/formatting.py +1 -1
  96. codex_autorunner/integrations/telegram/handlers/commands/github.py +41 -582
  97. codex_autorunner/integrations/telegram/handlers/commands/workspace.py +8 -8
  98. codex_autorunner/integrations/telegram/handlers/commands_runtime.py +137 -478
  99. codex_autorunner/integrations/telegram/handlers/commands_spec.py +17 -4
  100. codex_autorunner/integrations/telegram/handlers/messages.py +121 -9
  101. codex_autorunner/integrations/telegram/handlers/selections.py +61 -1
  102. codex_autorunner/integrations/telegram/helpers.py +111 -16
  103. codex_autorunner/integrations/telegram/outbox.py +208 -37
  104. codex_autorunner/integrations/telegram/progress_stream.py +3 -10
  105. codex_autorunner/integrations/telegram/service.py +221 -42
  106. codex_autorunner/integrations/telegram/state.py +100 -2
  107. codex_autorunner/integrations/telegram/ticket_flow_bridge.py +611 -0
  108. codex_autorunner/integrations/telegram/transport.py +39 -4
  109. codex_autorunner/integrations/telegram/trigger_mode.py +53 -0
  110. codex_autorunner/manifest.py +2 -0
  111. codex_autorunner/plugin_api.py +22 -0
  112. codex_autorunner/routes/__init__.py +37 -67
  113. codex_autorunner/routes/agents.py +2 -137
  114. codex_autorunner/routes/analytics.py +3 -0
  115. codex_autorunner/routes/app_server.py +2 -131
  116. codex_autorunner/routes/base.py +2 -624
  117. codex_autorunner/routes/file_chat.py +7 -0
  118. codex_autorunner/routes/flows.py +7 -0
  119. codex_autorunner/routes/messages.py +7 -0
  120. codex_autorunner/routes/repos.py +2 -196
  121. codex_autorunner/routes/review.py +2 -147
  122. codex_autorunner/routes/sessions.py +2 -175
  123. codex_autorunner/routes/settings.py +2 -168
  124. codex_autorunner/routes/shared.py +2 -275
  125. codex_autorunner/routes/system.py +4 -188
  126. codex_autorunner/routes/usage.py +3 -0
  127. codex_autorunner/routes/voice.py +2 -119
  128. codex_autorunner/routes/workspace.py +3 -0
  129. codex_autorunner/server.py +3 -2
  130. codex_autorunner/static/agentControls.js +41 -11
  131. codex_autorunner/static/agentEvents.js +248 -0
  132. codex_autorunner/static/app.js +35 -24
  133. codex_autorunner/static/archive.js +826 -0
  134. codex_autorunner/static/archiveApi.js +37 -0
  135. codex_autorunner/static/autoRefresh.js +36 -8
  136. codex_autorunner/static/bootstrap.js +1 -0
  137. codex_autorunner/static/bus.js +1 -0
  138. codex_autorunner/static/cache.js +1 -0
  139. codex_autorunner/static/constants.js +20 -4
  140. codex_autorunner/static/dashboard.js +344 -325
  141. codex_autorunner/static/diffRenderer.js +37 -0
  142. codex_autorunner/static/docChatCore.js +324 -0
  143. codex_autorunner/static/docChatStorage.js +65 -0
  144. codex_autorunner/static/docChatVoice.js +65 -0
  145. codex_autorunner/static/docEditor.js +133 -0
  146. codex_autorunner/static/env.js +1 -0
  147. codex_autorunner/static/eventSummarizer.js +166 -0
  148. codex_autorunner/static/fileChat.js +182 -0
  149. codex_autorunner/static/health.js +155 -0
  150. codex_autorunner/static/hub.js +126 -185
  151. codex_autorunner/static/index.html +839 -863
  152. codex_autorunner/static/liveUpdates.js +1 -0
  153. codex_autorunner/static/loader.js +1 -0
  154. codex_autorunner/static/messages.js +873 -0
  155. codex_autorunner/static/mobileCompact.js +2 -1
  156. codex_autorunner/static/preserve.js +17 -0
  157. codex_autorunner/static/settings.js +149 -217
  158. codex_autorunner/static/smartRefresh.js +52 -0
  159. codex_autorunner/static/styles.css +8850 -3876
  160. codex_autorunner/static/tabs.js +175 -11
  161. codex_autorunner/static/terminal.js +32 -0
  162. codex_autorunner/static/terminalManager.js +34 -59
  163. codex_autorunner/static/ticketChatActions.js +333 -0
  164. codex_autorunner/static/ticketChatEvents.js +16 -0
  165. codex_autorunner/static/ticketChatStorage.js +16 -0
  166. codex_autorunner/static/ticketChatStream.js +264 -0
  167. codex_autorunner/static/ticketEditor.js +844 -0
  168. codex_autorunner/static/ticketVoice.js +9 -0
  169. codex_autorunner/static/tickets.js +1988 -0
  170. codex_autorunner/static/utils.js +43 -3
  171. codex_autorunner/static/voice.js +1 -0
  172. codex_autorunner/static/workspace.js +765 -0
  173. codex_autorunner/static/workspaceApi.js +53 -0
  174. codex_autorunner/static/workspaceFileBrowser.js +504 -0
  175. codex_autorunner/surfaces/__init__.py +5 -0
  176. codex_autorunner/surfaces/cli/__init__.py +6 -0
  177. codex_autorunner/surfaces/cli/cli.py +1224 -0
  178. codex_autorunner/surfaces/cli/codex_cli.py +20 -0
  179. codex_autorunner/surfaces/telegram/__init__.py +3 -0
  180. codex_autorunner/surfaces/web/__init__.py +1 -0
  181. codex_autorunner/surfaces/web/app.py +2019 -0
  182. codex_autorunner/surfaces/web/hub_jobs.py +192 -0
  183. codex_autorunner/surfaces/web/middleware.py +587 -0
  184. codex_autorunner/surfaces/web/pty_session.py +370 -0
  185. codex_autorunner/surfaces/web/review.py +6 -0
  186. codex_autorunner/surfaces/web/routes/__init__.py +78 -0
  187. codex_autorunner/surfaces/web/routes/agents.py +138 -0
  188. codex_autorunner/surfaces/web/routes/analytics.py +277 -0
  189. codex_autorunner/surfaces/web/routes/app_server.py +132 -0
  190. codex_autorunner/surfaces/web/routes/archive.py +357 -0
  191. codex_autorunner/surfaces/web/routes/base.py +615 -0
  192. codex_autorunner/surfaces/web/routes/file_chat.py +836 -0
  193. codex_autorunner/surfaces/web/routes/flows.py +1164 -0
  194. codex_autorunner/surfaces/web/routes/messages.py +459 -0
  195. codex_autorunner/surfaces/web/routes/repos.py +197 -0
  196. codex_autorunner/surfaces/web/routes/review.py +148 -0
  197. codex_autorunner/surfaces/web/routes/sessions.py +176 -0
  198. codex_autorunner/surfaces/web/routes/settings.py +169 -0
  199. codex_autorunner/surfaces/web/routes/shared.py +280 -0
  200. codex_autorunner/surfaces/web/routes/system.py +196 -0
  201. codex_autorunner/surfaces/web/routes/usage.py +89 -0
  202. codex_autorunner/surfaces/web/routes/voice.py +120 -0
  203. codex_autorunner/surfaces/web/routes/workspace.py +271 -0
  204. codex_autorunner/surfaces/web/runner_manager.py +25 -0
  205. codex_autorunner/surfaces/web/schemas.py +417 -0
  206. codex_autorunner/surfaces/web/static_assets.py +490 -0
  207. codex_autorunner/surfaces/web/static_refresh.py +86 -0
  208. codex_autorunner/surfaces/web/terminal_sessions.py +78 -0
  209. codex_autorunner/tickets/__init__.py +27 -0
  210. codex_autorunner/tickets/agent_pool.py +399 -0
  211. codex_autorunner/tickets/files.py +89 -0
  212. codex_autorunner/tickets/frontmatter.py +55 -0
  213. codex_autorunner/tickets/lint.py +102 -0
  214. codex_autorunner/tickets/models.py +97 -0
  215. codex_autorunner/tickets/outbox.py +244 -0
  216. codex_autorunner/tickets/replies.py +179 -0
  217. codex_autorunner/tickets/runner.py +881 -0
  218. codex_autorunner/tickets/spec_ingest.py +77 -0
  219. codex_autorunner/web/__init__.py +5 -1
  220. codex_autorunner/web/app.py +2 -1771
  221. codex_autorunner/web/hub_jobs.py +2 -191
  222. codex_autorunner/web/middleware.py +2 -587
  223. codex_autorunner/web/pty_session.py +2 -369
  224. codex_autorunner/web/runner_manager.py +2 -24
  225. codex_autorunner/web/schemas.py +2 -396
  226. codex_autorunner/web/static_assets.py +4 -484
  227. codex_autorunner/web/static_refresh.py +2 -85
  228. codex_autorunner/web/terminal_sessions.py +2 -77
  229. codex_autorunner/workspace/__init__.py +40 -0
  230. codex_autorunner/workspace/paths.py +335 -0
  231. codex_autorunner-1.1.0.dist-info/METADATA +154 -0
  232. codex_autorunner-1.1.0.dist-info/RECORD +308 -0
  233. {codex_autorunner-0.1.2.dist-info → codex_autorunner-1.1.0.dist-info}/WHEEL +1 -1
  234. codex_autorunner/agents/execution/policy.py +0 -292
  235. codex_autorunner/agents/factory.py +0 -52
  236. codex_autorunner/agents/orchestrator.py +0 -358
  237. codex_autorunner/core/doc_chat.py +0 -1446
  238. codex_autorunner/core/snapshot.py +0 -580
  239. codex_autorunner/integrations/github/chatops.py +0 -268
  240. codex_autorunner/integrations/github/pr_flow.py +0 -1314
  241. codex_autorunner/routes/docs.py +0 -381
  242. codex_autorunner/routes/github.py +0 -327
  243. codex_autorunner/routes/runs.py +0 -250
  244. codex_autorunner/spec_ingest.py +0 -812
  245. codex_autorunner/static/docChatActions.js +0 -287
  246. codex_autorunner/static/docChatEvents.js +0 -300
  247. codex_autorunner/static/docChatRender.js +0 -205
  248. codex_autorunner/static/docChatStream.js +0 -361
  249. codex_autorunner/static/docs.js +0 -20
  250. codex_autorunner/static/docsClipboard.js +0 -69
  251. codex_autorunner/static/docsCrud.js +0 -257
  252. codex_autorunner/static/docsDocUpdates.js +0 -62
  253. codex_autorunner/static/docsDrafts.js +0 -16
  254. codex_autorunner/static/docsElements.js +0 -69
  255. codex_autorunner/static/docsInit.js +0 -285
  256. codex_autorunner/static/docsParse.js +0 -160
  257. codex_autorunner/static/docsSnapshot.js +0 -87
  258. codex_autorunner/static/docsSpecIngest.js +0 -263
  259. codex_autorunner/static/docsState.js +0 -127
  260. codex_autorunner/static/docsThreadRegistry.js +0 -44
  261. codex_autorunner/static/docsUi.js +0 -153
  262. codex_autorunner/static/docsVoice.js +0 -56
  263. codex_autorunner/static/github.js +0 -504
  264. codex_autorunner/static/logs.js +0 -678
  265. codex_autorunner/static/review.js +0 -157
  266. codex_autorunner/static/runs.js +0 -418
  267. codex_autorunner/static/snapshot.js +0 -124
  268. codex_autorunner/static/state.js +0 -94
  269. codex_autorunner/static/todoPreview.js +0 -27
  270. codex_autorunner/workspace.py +0 -16
  271. codex_autorunner-0.1.2.dist-info/METADATA +0 -249
  272. codex_autorunner-0.1.2.dist-info/RECORD +0 -222
  273. /codex_autorunner/{routes → surfaces/web/routes}/terminal_images.py +0 -0
  274. {codex_autorunner-0.1.2.dist-info → codex_autorunner-1.1.0.dist-info}/entry_points.txt +0 -0
  275. {codex_autorunner-0.1.2.dist-info → codex_autorunner-1.1.0.dist-info}/licenses/LICENSE +0 -0
  276. {codex_autorunner-0.1.2.dist-info → codex_autorunner-1.1.0.dist-info}/top_level.txt +0 -0
@@ -1,980 +1,956 @@
1
- <!doctype html>
1
+ <!DOCTYPE html>
2
+
2
3
  <html lang="en">
3
- <head>
4
- <script src="static/bootstrap.js?v=__CAR_ASSET_VERSION__" data-car-bootstrap></script>
5
- <meta charset="utf-8" />
6
- <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover" />
7
- <meta name="apple-mobile-web-app-capable" content="yes" />
8
- <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
9
- <meta name="theme-color" content="#0a0c12" />
10
- <title>Codex Autorunner</title>
11
- </head>
12
- <body>
13
- <div id="hub-shell" class="hub-shell hidden">
14
- <header class="hub-hero">
15
- <div class="hub-hero-text">
16
- <h1>CAR Hub</h1>
17
- <span id="hub-last-scan" class="pill pill-small pill-idle">–</span>
18
- <span id="hub-version" class="hub-version">v–</span>
19
- </div>
20
- <div class="hub-hero-actions">
21
- <button id="hub-new-repo" class="primary sm">+ New</button>
22
- <button id="hub-scan" class="sm">Scan</button>
23
- <button id="hub-refresh" class="ghost sm">Refresh</button>
24
- <button id="hub-settings" class="ghost sm icon-btn" title="Settings">⚙</button>
25
- </div>
26
- </header>
27
4
 
28
- <section class="hub-stats">
29
- <div class="hub-stat">
30
- <div id="hub-count-total" class="hub-stat-value">–</div>
31
- <p class="muted small">repos</p>
32
- </div>
33
- <div class="hub-stat">
34
- <div id="hub-count-running" class="hub-stat-value">–</div>
35
- <p class="muted small">running</p>
36
- </div>
37
- <div class="hub-stat">
38
- <div id="hub-count-missing" class="hub-stat-value">–</div>
39
- <p class="muted small">missing</p>
40
- </div>
41
- </section>
5
+ <head>
6
+ <script data-car-bootstrap="" src="static/bootstrap.js?v=__CAR_ASSET_VERSION__"></script>
7
+ <meta charset="utf-8" />
8
+ <meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover"
9
+ name="viewport" />
10
+ <meta content="yes" name="apple-mobile-web-app-capable" />
11
+ <meta content="black-translucent" name="apple-mobile-web-app-status-bar-style" />
12
+ <meta content="#0a0c12" name="theme-color" />
13
+ <title>Codex Autorunner</title>
14
+ </head>
42
15
 
43
- <section class="hub-usage-compact">
44
- <div class="hub-usage-header">
45
- <span class="label">Usage</span>
46
- <span id="hub-usage-meta" class="hub-usage-path">–</span>
47
- <button id="hub-usage-refresh" class="ghost sm icon-btn" title="Refresh usage">↻</button>
48
- </div>
49
- <div id="hub-usage-list" class="hub-usage-grid">Loading…</div>
50
- </section>
51
-
52
- <section class="hub-usage-chart">
53
- <div class="hub-usage-chart-header">
54
- <span class="label">Usage Trend</span>
55
- <div class="usage-chart-controls">
56
- <select id="hub-usage-chart-range" class="usage-chart-select" title="Range" aria-label="Range">
57
- <option value="7">1w</option>
58
- <option value="30" selected>1m</option>
59
- <option value="90">3m</option>
60
- <option value="180">6m</option>
61
- <option value="365">1y</option>
62
- </select>
63
- <select id="hub-usage-chart-segment" class="usage-chart-select" title="Group" aria-label="Group">
64
- <option value="none">Total</option>
65
- <option value="repo">By repo</option>
66
- <option value="agent">By agent</option>
67
- </select>
68
- </div>
16
+ <body>
17
+ <div class="hub-shell hidden" id="hub-shell">
18
+ <header class="hub-hero">
19
+ <div class="hub-hero-text">
20
+ <h1>CAR Hub</h1>
21
+ <span class="pill pill-small pill-idle" id="hub-last-scan">–</span>
22
+ <span class="hub-version" id="hub-version">v–</span>
23
+ </div>
24
+ <div class="hub-hero-actions">
25
+ <button class="primary sm" id="hub-new-repo">+ New</button>
26
+ <button class="sm" id="hub-scan">Scan</button>
27
+ <button class="ghost sm" id="hub-refresh">Refresh</button>
28
+ <button class="ghost sm icon-btn" id="hub-settings" title="Settings">⚙</button>
29
+ </div>
30
+ </header>
31
+ <section class="hub-stats">
32
+ <div class="hub-stat">
33
+ <div class="hub-stat-value" id="hub-count-total">–</div>
34
+ <p class="muted small">repos</p>
35
+ </div>
36
+ <div class="hub-stat">
37
+ <div class="hub-stat-value" id="hub-count-running">–</div>
38
+ <p class="muted small">running</p>
39
+ </div>
40
+ <div class="hub-stat">
41
+ <div class="hub-stat-value" id="hub-count-missing">–</div>
42
+ <p class="muted small">missing</p>
43
+ </div>
44
+ </section>
45
+ <section class="hub-inbox">
46
+ <div class="hub-panel-header">
47
+ <span class="label">Inbox</span>
48
+ <div class="hub-panel-actions">
49
+ <button class="ghost sm" id="hub-inbox-refresh">Refresh</button>
69
50
  </div>
70
- <div id="hub-usage-chart-canvas" class="usage-chart-canvas hub-usage-chart-canvas"></div>
71
- </section>
72
-
73
- <section class="hub-repo-panel">
74
- <div class="hub-panel-header">
75
- <span class="label">Repositories</span>
76
- <div class="hub-panel-actions">
77
- <button id="hub-quick-scan" class="ghost sm">Rescan</button>
78
- </div>
51
+ </div>
52
+ <div class="hub-inbox-list" id="hub-inbox-list">Loading…</div>
53
+ </section>
54
+ <section class="hub-usage-chart">
55
+ <div class="hub-usage-chart-header">
56
+ <span class="label">Usage Trend</span>
57
+ <div class="usage-chart-controls">
58
+ <select aria-label="Range" class="usage-chart-select" id="hub-usage-chart-range" title="Range">
59
+ <option value="7">1w</option>
60
+ <option selected="" value="30">1m</option>
61
+ <option value="90">3m</option>
62
+ <option value="180">6m</option>
63
+ <option value="365">1y</option>
64
+ </select>
65
+ <select aria-label="Group" class="usage-chart-select" id="hub-usage-chart-segment" title="Group">
66
+ <option value="none">Total</option>
67
+ <option value="repo">By repo</option>
68
+ <option value="agent">By agent</option>
69
+ </select>
79
70
  </div>
80
- <div id="hub-repo-list" class="hub-repo-list">
81
- <div class="muted small">Loading…</div>
71
+ </div>
72
+ <div class="usage-chart-canvas hub-usage-chart-canvas" id="hub-usage-chart-canvas"></div>
73
+ </section>
74
+ <section class="hub-repo-panel">
75
+ <div class="hub-panel-header">
76
+ <span class="label">Repositories</span>
77
+ <div class="hub-panel-actions">
78
+ <button class="ghost sm" id="hub-quick-scan">Rescan</button>
82
79
  </div>
83
- </section>
84
- </div>
85
-
86
- <div id="repo-shell" class="app-shell">
87
- <nav class="nav-bar">
88
- <span class="nav-brand">CAR</span>
89
- <div class="tabs">
90
- <!-- Tabs will be injected here by tabs.js -->
80
+ </div>
81
+ <div class="hub-repo-list" id="hub-repo-list">
82
+ <div class="muted small">Loading…</div>
83
+ </div>
84
+ </section>
85
+ </div>
86
+ <div class="app-shell" id="repo-shell">
87
+ <nav class="nav-bar">
88
+ <span class="nav-brand">CAR</span>
89
+ <div class="tabs">
90
+ <!-- Tabs will be injected here by tabs.js -->
91
+ </div>
92
+ </nav>
93
+ <main>
94
+ <div class="doc-banner hidden" id="repo-health-banner">
95
+ <div class="doc-banner-text">
96
+ <div class="doc-banner-title" id="repo-health-title">Repo server offline</div>
97
+ <div class="doc-banner-detail muted small" id="repo-health-detail"></div>
91
98
  </div>
92
- <div class="nav-actions">
93
- <button id="repo-settings" class="ghost sm icon-btn" title="Settings">⚙</button>
99
+ <div class="doc-banner-actions">
100
+ <button class="ghost sm" id="repo-health-retry">Retry</button>
94
101
  </div>
95
- </nav>
96
-
97
- <main>
98
- <section id="dashboard" class="panel active">
99
- <div class="cards">
100
- <div class="card status-card">
101
- <div class="card-header">
102
- <div class="card-header-left">
103
- <span class="label">Runner Status</span>
104
- <span id="repo-version" class="version-label">v–</span>
105
- </div>
106
- <span id="runner-status" class="pill pill-idle">idle</span>
102
+ </div>
103
+ <section class="panel" id="analytics">
104
+ <div class="cards">
105
+ <div class="card status-card">
106
+ <div class="card-header">
107
+ <div class="card-header-left">
108
+ <span class="label">Ticket Analytics</span>
109
+ <span class="version-label" id="repo-version">v–</span>
107
110
  </div>
108
- <div class="grid-two">
109
- <div>
110
- <p class="muted">Run ID</p>
111
- <p id="last-run-id" class="metric">–</p>
112
- </div>
113
- <div>
114
- <p class="muted">Exit</p>
115
- <p id="last-exit-code" class="metric">–</p>
116
- </div>
117
- <div>
118
- <p class="muted">Started</p>
119
- <p id="last-start" class="metric">–</p>
120
- </div>
121
- <div>
122
- <p class="muted">Finished</p>
123
- <p id="last-finish" class="metric">–</p>
124
- </div>
125
- <div>
126
- <p class="muted">TODO</p>
127
- <p id="todo-count" class="metric">–</p>
128
- </div>
129
- <div>
130
- <p class="muted">Done</p>
131
- <p id="done-count" class="metric">–</p>
132
- </div>
111
+ <span class="pill pill-idle" id="runner-status">idle</span>
112
+ </div>
113
+ <div class="grid-two">
114
+ <div>
115
+ <p class="muted">Started</p>
116
+ <p class="metric" id="last-start">–</p>
133
117
  </div>
134
- <div class="doc-agent-controls dashboard-agent-controls">
135
- <select id="dashboard-agent-select" title="Agent"></select>
136
- <select id="dashboard-model-select" title="Model"></select>
137
- <select id="dashboard-reasoning-select" title="Reasoning"></select>
118
+ <div>
119
+ <p class="muted">Finished</p>
120
+ <p class="metric" id="last-finish">–</p>
138
121
  </div>
139
- <div class="actions">
140
- <button id="start-run" class="primary" title="Run a full autorunner iteration through all tasks">Start</button>
141
- <button id="stop-run" class="ghost" title="Gracefully stop the current run (safe shutdown)">Stop</button>
142
- <button id="kill-run" class="danger" title="Immediately terminate the run (force stop - may cause data loss)">Kill</button>
143
- <button id="clear-lock" class="ghost hidden" title="Clear a stale autorunner lock">Clear lock</button>
144
- <button id="reset-runner" class="ghost" title="Clear run state and restart fresh (destructive)">Reset</button>
145
- <button id="refresh-state" class="ghost icon-btn" title="Refresh state">↻</button>
122
+ <div>
123
+ <p class="muted">Duration</p>
124
+ <p class="metric" id="last-duration">–</p>
146
125
  </div>
147
- <p class="muted small" id="runner-pid">PID: –</p>
148
- </div>
149
-
150
- <div class="card usage-card-compact">
151
- <div class="usage-header">
152
- <span class="label">Usage</span>
153
- <span class="usage-total-badge" id="usage-total">–</span>
154
- <span class="usage-events-badge" id="usage-events">–</span>
155
- <button id="usage-refresh" class="ghost sm icon-btn" title="Refresh usage">↻</button>
156
- </div>
157
- <div class="usage-breakdown">
158
- <div class="usage-stat">
159
- <span class="usage-stat-val" id="usage-input">–</span>
160
- <span class="usage-stat-lbl">in</span>
161
- </div>
162
- <div class="usage-stat usage-stat-cached">
163
- <span class="usage-stat-val" id="usage-cached">–</span>
164
- <span class="usage-stat-lbl">cached</span>
165
- </div>
166
- <div class="usage-stat">
167
- <span class="usage-stat-val" id="usage-output">–</span>
168
- <span class="usage-stat-lbl">out</span>
169
- </div>
170
- <div class="usage-stat">
171
- <span class="usage-stat-val" id="usage-reasoning">–</span>
172
- <span class="usage-stat-lbl">reason</span>
173
- </div>
126
+ <div>
127
+ <p class="muted">TODO</p>
128
+ <p class="metric" id="todo-count">–</p>
174
129
  </div>
175
- <div class="usage-chart">
176
- <div class="usage-chart-header">
177
- <span class="usage-chart-title">Trend</span>
178
- <div class="usage-chart-controls">
179
- <select id="usage-chart-range" class="usage-chart-select" title="Range" aria-label="Range">
180
- <option value="7">1w</option>
181
- <option value="30" selected>1m</option>
182
- <option value="90">3m</option>
183
- <option value="180">6m</option>
184
- <option value="365">1y</option>
185
- </select>
186
- <select id="usage-chart-segment" class="usage-chart-select" title="Group" aria-label="Group">
187
- <option value="none">Total</option>
188
- <option value="agent">Agent</option>
189
- <option value="model">Model</option>
190
- <option value="token_type">Token type</option>
191
- <option value="model_token">Model + type</option>
192
- </select>
193
- </div>
194
- </div>
195
- <div id="usage-chart-canvas" class="usage-chart-canvas"></div>
130
+ <div>
131
+ <p class="muted">Done</p>
132
+ <p class="metric" id="done-count">–</p>
196
133
  </div>
197
- <div class="usage-rates-visual">
198
- <div class="usage-rate-row">
199
- <span class="usage-rate-label">Primary</span>
200
- <div id="usage-rate-primary" class="usage-rate-bar-container"></div>
201
- </div>
202
- <div class="usage-rate-row">
203
- <span class="usage-rate-label">Secondary</span>
204
- <div id="usage-rate-secondary" class="usage-rate-bar-container"></div>
205
- </div>
134
+ <div>
135
+ <p class="muted">Active ticket</p>
136
+ <p class="metric" id="ticket-active">–</p>
137
+ </div>
138
+ <div>
139
+ <p class="muted">Ticket Turns</p>
140
+ <p class="metric" id="ticket-turns">–</p>
206
141
  </div>
207
- <div class="usage-footer">
208
- <span id="usage-rates" class="hidden">–</span>
209
- <span id="usage-meta">–</span>
142
+ <div>
143
+ <p class="muted">Total Turns</p>
144
+ <p class="metric" id="total-turns">–</p>
145
+ </div>
146
+ <div>
147
+ <p class="muted">Dispatches</p>
148
+ <p class="metric" id="message-dispatches">–</p>
149
+ </div>
150
+ <div>
151
+ <p class="muted">Replies</p>
152
+ <p class="metric" id="message-replies">–</p>
153
+ </div>
154
+ <div>
155
+ <p class="muted">Lines Changed</p>
156
+ <p class="metric diff-stats-metric" id="lines-changed">–</p>
157
+ </div>
158
+ <div>
159
+ <p class="muted">Run ID</p>
160
+ <p class="metric" id="last-run-id">–</p>
210
161
  </div>
211
162
  </div>
212
-
213
- <div class="card todo-preview">
214
- <div class="card-header">
215
- <span class="label">TODO</span>
216
- <button id="open-summary" class="primary sm hidden" title="Open final report (SUMMARY)">Summary</button>
217
- <button id="refresh-preview" class="ghost sm icon-btn" title="Refresh TODO preview">↻</button>
163
+ </div>
164
+ <details class="card" id="run-history">
165
+ <summary class="card-header">
166
+ <div class="card-header-left">
167
+ <span class="label">Run History</span>
168
+ <span class="muted small">Last 10 runs</span>
218
169
  </div>
219
- <ul id="todo-preview-list" class="checklist"></ul>
170
+ <button class="ghost sm icon-btn" id="analytics-refresh" title="Refresh analytics">↻</button>
171
+ </summary>
172
+ <div class="run-history-list" id="run-history-list">
173
+ <div class="muted">Loading…</div>
220
174
  </div>
221
-
222
- <div class="card github-card" id="github-card">
223
- <div class="card-header">
224
- <span class="label">GitHub</span>
225
- <span id="github-status-pill" class="pill pill-idle">–</span>
226
- </div>
227
- <div class="github-grid">
228
- <div class="github-row">
229
- <span class="muted">Repo</span>
230
- <a id="github-repo-link" class="github-link muted">–</a>
231
- </div>
232
- <div class="github-row">
233
- <span class="muted">Branch</span>
234
- <span id="github-branch" class="github-mono">–</span>
235
- </div>
236
- <div class="github-row">
237
- <span class="muted">Issue</span>
238
- <a id="github-issue-link" class="github-link muted">–</a>
239
- </div>
240
- <div class="github-row">
241
- <span class="muted">PR</span>
242
- <span class="github-pr-group">
243
- <a id="github-pr-link" class="github-link muted">–</a>
244
- <button id="github-open-pr-files" class="ghost icon-btn-inline" disabled title="View changed files">📄</button>
245
- <button id="github-copy-pr" class="ghost icon-btn-inline" disabled title="Copy PR link">📋</button>
246
- </span>
247
- </div>
175
+ </details>
176
+ <div class="card usage-card-compact">
177
+ <div class="usage-header">
178
+ <span class="label">Usage</span>
179
+ <span class="usage-total-badge" id="usage-total">–</span>
180
+ <span class="usage-events-badge" id="usage-events">–</span>
181
+ <button class="ghost sm icon-btn" id="usage-refresh" title="Refresh usage">↻</button>
182
+ </div>
183
+ <div class="usage-breakdown">
184
+ <div class="usage-stat">
185
+ <span class="usage-stat-val" id="usage-input">–</span>
186
+ <span class="usage-stat-lbl">in</span>
248
187
  </div>
249
- <div class="actions github-actions">
250
- <button id="github-sync-pr" class="primary sm">Sync PR</button>
188
+ <div class="usage-stat usage-stat-cached">
189
+ <span class="usage-stat-val" id="usage-cached">–</span>
190
+ <span class="usage-stat-lbl">cached</span>
251
191
  </div>
252
- <div class="github-flow">
253
- <div class="github-flow-header">
254
- <span class="muted">PR Flow</span>
255
- <span id="pr-flow-status" class="pill pill-idle">–</span>
256
- </div>
257
- <div class="github-flow-grid">
258
- <label class="muted" for="pr-flow-mode">Mode</label>
259
- <select id="pr-flow-mode">
260
- <option value="issue">Implement Issue → PR</option>
261
- <option value="pr">Fix Existing PR</option>
192
+ <div class="usage-stat">
193
+ <span class="usage-stat-val" id="usage-output">–</span>
194
+ <span class="usage-stat-lbl">out</span>
195
+ </div>
196
+ <div class="usage-stat">
197
+ <span class="usage-stat-val" id="usage-reasoning">–</span>
198
+ <span class="usage-stat-lbl">reason</span>
199
+ </div>
200
+ </div>
201
+ <div class="usage-chart">
202
+ <div class="usage-chart-header">
203
+ <span class="usage-chart-title">Trend</span>
204
+ <div class="usage-chart-controls">
205
+ <select aria-label="Range" class="usage-chart-select" id="usage-chart-range" title="Range">
206
+ <option value="7">1w</option>
207
+ <option selected="" value="30">1m</option>
208
+ <option value="90">3m</option>
209
+ <option value="180">6m</option>
210
+ <option value="365">1y</option>
262
211
  </select>
263
- <label class="muted" for="pr-flow-ref">Issue / PR</label>
264
- <input
265
- id="pr-flow-ref"
266
- type="text"
267
- spellcheck="false"
268
- autocomplete="off"
269
- placeholder="#123 or https://github.com/org/repo/issues/123"
270
- />
271
- <label class="muted" for="pr-flow-base">Base</label>
272
- <input
273
- id="pr-flow-base"
274
- type="text"
275
- spellcheck="false"
276
- autocomplete="off"
277
- placeholder="default"
278
- />
279
- <label class="muted" for="pr-flow-until">Until</label>
280
- <select id="pr-flow-until">
281
- <option value="no_issues">No issues</option>
282
- <option value="minor_only">Minor only</option>
212
+ <select aria-label="Group" class="usage-chart-select" id="usage-chart-segment" title="Group">
213
+ <option value="none">Total</option>
214
+ <option value="agent">Agent</option>
215
+ <option value="model">Model</option>
216
+ <option value="token_type">Token type</option>
217
+ <option value="model_token">Model + type</option>
283
218
  </select>
284
- <label class="muted" for="pr-flow-cycles">Max cycles</label>
285
- <input id="pr-flow-cycles" type="number" min="1" placeholder="3" />
286
- <label class="muted" for="pr-flow-runs">Impl runs</label>
287
- <input id="pr-flow-runs" type="number" min="1" placeholder="auto" />
288
- <label class="muted" for="pr-flow-timeout">Timeout (s)</label>
289
- <input id="pr-flow-timeout" type="number" min="0" placeholder="auto" />
290
- <label class="muted" for="pr-flow-draft">Draft</label>
291
- <input id="pr-flow-draft" type="checkbox" checked />
292
- </div>
293
- <div class="actions github-flow-actions">
294
- <button id="pr-flow-start" class="primary sm">Start</button>
295
- <button id="pr-flow-stop" class="ghost sm">Stop</button>
296
- <button id="pr-flow-resume" class="ghost sm">Resume</button>
297
- <button id="pr-flow-collect" class="ghost sm">Collect reviews</button>
298
- </div>
299
- <div class="github-flow-status">
300
- <div class="github-flow-row">
301
- <span class="muted">Step</span>
302
- <span id="pr-flow-step" class="github-mono">–</span>
303
- </div>
304
- <div class="github-flow-row">
305
- <span class="muted">Cycle</span>
306
- <span id="pr-flow-cycle" class="github-mono">–</span>
307
- </div>
308
- <div class="github-flow-row">
309
- <span class="muted">Review</span>
310
- <span id="pr-flow-review" class="github-mono">–</span>
311
- </div>
312
219
  </div>
313
- <div class="github-flow-artifacts">
314
- <a id="pr-flow-review-link" class="github-link muted">Review bundle</a>
315
- <a id="pr-flow-log-link" class="github-link muted">Workflow log</a>
316
- <a id="pr-flow-final-link" class="github-link muted">Final report</a>
317
- </div>
318
- </div>
319
- <p id="github-note" class="muted small">–</p>
320
- </div>
321
- </div>
322
-
323
- <div class="card review-card" id="review-card">
324
- <div class="card-header">
325
- <span class="label">Review</span>
326
- <span id="review-status-pill" class="pill pill-idle">–</span>
327
- </div>
328
- <div class="review-grid">
329
- <div class="review-row">
330
- <span class="muted">Run ID</span>
331
- <span id="review-run-id" class="review-mono">–</span>
332
- </div>
333
- <div class="review-row">
334
- <span class="muted">Started</span>
335
- <span id="review-started" class="review-mono">–</span>
336
- </div>
337
- <div class="review-row">
338
- <span class="muted">Finished</span>
339
- <span id="review-finished" class="review-mono">–</span>
340
- </div>
341
- </div>
342
- <div class="review-controls">
343
- <div class="review-inputs">
344
- <div class="review-input-row">
345
- <label class="muted" for="review-agent">Agent</label>
346
- <input id="review-agent" type="text" value="opencode" spellcheck="false" />
347
- </div>
348
- <div class="review-input-row">
349
- <label class="muted" for="review-model">Model</label>
350
- <input id="review-model" type="text" value="zai-coding-plan/glm-4.7" spellcheck="false" />
351
- </div>
352
- <div class="review-input-row">
353
- <label class="muted" for="review-reasoning">Reasoning</label>
354
- <input id="review-reasoning" type="text" placeholder="auto" spellcheck="false" />
355
- </div>
356
- <div class="review-input-row">
357
- <label class="muted" for="review-timeout">Timeout (s)</label>
358
- <input id="review-timeout" type="number" min="60" placeholder="auto" spellcheck="false" />
359
- </div>
360
- </div>
361
- <div class="review-buttons">
362
- <button id="review-start" class="primary sm">Start</button>
363
- <button id="review-stop" class="ghost sm">Stop</button>
364
- <button id="review-reset" class="ghost sm">Reset</button>
365
- </div>
366
- </div>
367
- <div class="review-artifacts">
368
- <a id="review-final-link" class="review-link muted">Final report</a>
369
- <a id="review-log-link" class="review-link muted">Log</a>
370
- <a id="review-scratchpad-link" class="review-link muted">Scratchpad</a>
371
- </div>
372
- </div>
373
- </section>
374
-
375
- <section id="docs" class="panel">
376
- <div class="doc-nav">
377
- <button class="chip active" data-doc="todo">TODO</button>
378
- <button class="chip" data-doc="progress">PROGRESS</button>
379
- <button class="chip" data-doc="opinions">OPINIONS</button>
380
- <button class="chip" data-doc="spec">SPEC</button>
381
- <button class="chip" data-doc="summary">SUMMARY</button>
382
- <button class="chip" data-doc="snapshot">SNAPSHOT</button>
383
- <span class="muted" id="doc-status"></span>
384
- </div>
385
- <div id="doc-thread-registry-banner" class="doc-banner hidden">
386
- <div class="doc-banner-text">
387
- <div class="doc-banner-title">
388
- Conversation state reset due to corrupted registry.
389
220
  </div>
390
- <div id="doc-thread-registry-detail" class="doc-banner-detail muted small"></div>
221
+ <div class="usage-chart-canvas" id="usage-chart-canvas"></div>
391
222
  </div>
392
- <div class="doc-banner-actions">
393
- <button id="doc-thread-registry-reset" class="ghost sm">Reset conversations</button>
394
- <button id="doc-thread-registry-download" class="ghost sm">Download backup</button>
223
+ <div class="usage-rates-visual">
224
+ <div class="usage-rate-row">
225
+ <span class="usage-rate-label">Primary</span>
226
+ <div class="usage-rate-bar-container" id="usage-rate-primary"></div>
227
+ </div>
228
+ <div class="usage-rate-row">
229
+ <span class="usage-rate-label">Secondary</span>
230
+ <div class="usage-rate-bar-container" id="usage-rate-secondary"></div>
231
+ </div>
395
232
  </div>
396
- </div>
397
- <div id="spec-issue-import" class="spec-issue-import hidden">
398
- <button id="spec-issue-import-toggle" class="ghost sm">Import Issue → SPEC</button>
399
- <div id="spec-issue-input-row" class="spec-issue-input-row hidden">
400
- <input
401
- id="spec-issue-input"
402
- type="text"
403
- spellcheck="false"
404
- autocomplete="off"
405
- placeholder="Issue number or URL (e.g. 123 or https://github.com/org/repo/issues/123)"
406
- />
407
- <button id="spec-issue-import-btn" class="primary sm">Import</button>
233
+ <div class="usage-footer">
234
+ <span class="hidden" id="usage-rates">–</span>
235
+ <span id="usage-meta">–</span>
408
236
  </div>
409
237
  </div>
410
- <div class="doc-editor">
411
- <div id="spec-ingest-patch-main" class="doc-patch-main hidden">
412
- <div class="doc-patch-header">
413
- <div class="doc-patch-info">
414
- <div class="muted small">Spec ingest patch</div>
415
- <div id="spec-ingest-patch-summary" class="doc-patch-summary"></div>
416
- <div class="doc-patch-legend">
417
- <span class="doc-patch-legend-item doc-patch-legend-add">Added</span>
418
- <span class="doc-patch-legend-item doc-patch-legend-del">Removed</span>
238
+ </div>
239
+
240
+ <!-- Legacy analytics section removed -->
241
+ </section>
242
+ <section class="panel" id="inbox">
243
+ <div class="cards">
244
+ <div class="card">
245
+ <div class="messages-layout">
246
+ <div class="messages-sidebar">
247
+ <div class="messages-thread-list" id="messages-thread-list"></div>
248
+ </div>
249
+ <div class="messages-main">
250
+ <div class="messages-detail-header mobile-only">
251
+ <button class="messages-back-btn" id="messages-back-btn">← Back</button>
252
+ <div class="messages-detail-meta" id="messages-detail-meta">
253
+ <span class="messages-detail-status pill pill-small pill-idle" id="messages-detail-status">–</span>
254
+ <span class="messages-detail-counts muted" id="messages-detail-counts">–</span>
419
255
  </div>
420
256
  </div>
421
- <div class="doc-patch-actions">
422
- <button id="spec-ingest-patch-apply" class="primary sm">Apply Patch</button>
423
- <button id="spec-ingest-patch-reload" class="ghost sm">Reload</button>
424
- <button id="spec-ingest-patch-discard" class="danger sm">Discard</button>
257
+ <div class="messages-thread-detail" id="messages-thread-detail">
258
+ <div class="messages-empty-state">
259
+ <div class="messages-empty-icon">💬</div>
260
+ <div class="messages-empty-title">Select a conversation</div>
261
+ <div class="messages-empty-hint">Choose a session from the left to view dispatches and replies.
262
+ </div>
263
+ </div>
264
+ </div>
265
+ <div class="messages-reply-box">
266
+ <textarea class="messages-reply-body" id="messages-reply-body"
267
+ placeholder="Write a reply…"></textarea>
268
+ <div class="messages-reply-row">
269
+ <input type="file" id="messages-reply-files" multiple />
270
+ <div class="messages-reply-actions">
271
+ <button class="primary sm" id="messages-reply-send">Send</button>
272
+ </div>
273
+ </div>
425
274
  </div>
426
275
  </div>
427
- <div id="spec-ingest-patch-body" class="doc-patch-body">(no patch)</div>
428
276
  </div>
429
- <div id="doc-patch-main" class="doc-patch-main hidden">
277
+ </div>
278
+ </div>
279
+ </section>
280
+ <section class="panel" id="archive">
281
+ <div class="cards">
282
+ <div class="card">
283
+ <div class="archive-layout">
284
+ <aside class="archive-sidebar">
285
+ <div class="archive-header">
286
+ <span class="label">Archive</span>
287
+ <button class="ghost sm" id="archive-refresh">Refresh</button>
288
+ </div>
289
+ <div class="archive-empty muted small hidden" id="archive-empty">
290
+ No archived snapshots found yet. Clean up a worktree to create a snapshot.
291
+ </div>
292
+ <div class="archive-list" id="archive-snapshot-list"></div>
293
+ </aside>
294
+ <div class="archive-detail" id="archive-snapshot-detail">
295
+ <div class="archive-empty-state">
296
+ <div class="archive-empty-title">Select a snapshot</div>
297
+ <div class="archive-empty-hint">Choose a snapshot to view metadata and summary.</div>
298
+ </div>
299
+ </div>
300
+ </div>
301
+ </div>
302
+ </div>
303
+ </section>
304
+ <section class="panel" id="workspace">
305
+ <div class="workspace-header workspace-header-desktop">
306
+ <div class="workspace-header-left">
307
+ <h3 class="workspace-title">Workspace</h3>
308
+ <span class="muted small" id="workspace-status"></span>
309
+ </div>
310
+ <div class="workspace-header-actions">
311
+ <input type="file" id="workspace-upload-input" multiple hidden />
312
+ <button class="ghost sm" id="workspace-upload" title="Upload to current folder">Upload</button>
313
+ <button class="ghost sm" id="workspace-new-folder" title="Create folder">New Folder</button>
314
+ <button class="ghost sm" id="workspace-new-file" title="Create markdown file">New File</button>
315
+ <button class="ghost sm hidden" id="workspace-generate-tickets" title="Generate tickets from spec">Generate
316
+ tickets</button>
317
+ <button class="ghost sm" id="workspace-reload">Reload</button>
318
+ <button class="primary sm" id="workspace-save">Save</button>
319
+ </div>
320
+ </div>
321
+ <div class="workspace-path-row">
322
+ <nav class="workspace-breadcrumbs" id="workspace-breadcrumbs"></nav>
323
+ <button class="ghost sm workspace-download-all-btn" id="workspace-download-all"
324
+ title="Download all as ZIP">⬇</button>
325
+ </div>
326
+ <div class="workspace-grid">
327
+ <aside class="workspace-file-browser">
328
+ <div class="workspace-file-mobile">
329
+ <select id="workspace-file-select"></select>
330
+ </div>
331
+ <div class="workspace-file-list" id="workspace-file-list"></div>
332
+ </aside>
333
+ <div class="workspace-main">
334
+ <div class="doc-patch-main hidden" id="workspace-patch-main">
430
335
  <div class="doc-patch-header">
431
336
  <div class="doc-patch-info">
432
337
  <div class="muted small">Pending draft</div>
433
- <div id="doc-patch-summary" class="doc-patch-summary"></div>
434
- <div id="doc-patch-meta" class="doc-patch-meta"></div>
338
+ <div class="doc-patch-summary" id="workspace-patch-summary"></div>
339
+ <div class="doc-patch-meta" id="workspace-patch-meta"></div>
435
340
  <div class="doc-patch-legend">
436
341
  <span class="doc-patch-legend-item doc-patch-legend-add">Added</span>
437
342
  <span class="doc-patch-legend-item doc-patch-legend-del">Removed</span>
438
343
  </div>
439
344
  </div>
440
345
  <div class="doc-patch-actions">
441
- <button id="doc-patch-apply" class="primary sm">Apply Draft</button>
442
- <button id="doc-patch-preview" class="ghost sm" aria-pressed="false">Preview draft</button>
443
- <button id="doc-patch-reload" class="ghost sm">Reload</button>
444
- <button id="doc-patch-discard" class="danger sm">Discard</button>
346
+ <button class="primary sm" id="workspace-patch-apply">Apply</button>
347
+ <button class="ghost sm" id="workspace-patch-reload">Reload</button>
348
+ <button class="danger sm" id="workspace-patch-discard">Discard</button>
445
349
  </div>
446
350
  </div>
447
- <div id="doc-patch-body" class="doc-patch-body">(no draft)</div>
351
+ <div class="doc-patch-body" id="workspace-patch-body">(no draft)</div>
448
352
  </div>
449
- <textarea id="doc-content" spellcheck="false"></textarea>
450
- <div class="doc-actions" id="doc-actions-standard">
451
- <button id="save-doc" class="primary" data-short="Save">Save</button>
452
- <button id="reload-doc" class="ghost" data-short="Reload">Reload</button>
453
- <button id="doc-copy" class="ghost hidden" data-short="Copy">Copy</button>
454
- <button id="spec-paste" class="ghost hidden" data-short="Paste">Paste</button>
455
- <button id="ingest-spec" class="ghost hidden" data-short="Ingest">Ingest SPEC → Docs</button>
456
- <button id="clear-docs" class="danger hidden" data-short="Clear">Clear TODO/PROGRESS/OPINIONS</button>
457
- </div>
458
- <div class="doc-actions hidden" id="doc-actions-snapshot">
459
- <button id="snapshot-generate" class="primary" data-short="Run">Run snapshot</button>
460
- <button id="snapshot-copy" class="ghost" data-short="Copy">Copy</button>
461
- <button id="snapshot-refresh" class="ghost" data-short="Reload">Reload</button>
353
+ <textarea id="workspace-content" spellcheck="false"></textarea>
354
+ <!-- Mobile toolbar: file selector + actions, positioned above compose -->
355
+ <div class="workspace-mobile-toolbar">
356
+ <button class="workspace-file-btn" id="workspace-file-pill" type="button">
357
+ <span class="workspace-file-btn-name" id="workspace-file-pill-name">active_context.md</span>
358
+ </button>
359
+ <div class="workspace-mobile-actions">
360
+ <span class="muted small" id="workspace-status-mobile"></span>
361
+ <button class="ghost sm" id="workspace-reload-mobile" title="Reload">↻</button>
362
+ <button class="primary sm" id="workspace-save-mobile">Save</button>
363
+ </div>
462
364
  </div>
463
365
  <div class="doc-chat-panel compose-panel">
464
366
  <div class="doc-chat-compose">
465
367
  <div class="doc-agent-controls">
466
- <select id="doc-agent-select" title="Agent"></select>
467
- <select id="doc-model-select" title="Model"></select>
468
- <select id="doc-reasoning-select" title="Reasoning"></select>
368
+ <select id="workspace-chat-agent-select" title="Agent"></select>
369
+ <select id="workspace-chat-model-select" title="Model"></select>
370
+ <select id="workspace-chat-reasoning-select" title="Reasoning"></select>
469
371
  </div>
470
372
  <div class="doc-chat-input-row compose-row">
471
- <textarea
472
- id="doc-chat-input"
473
- rows="1"
474
- placeholder="Chat about the work docs..."
475
- spellcheck="false"
476
- enterkeyhint="enter"
477
- ></textarea>
373
+ <textarea enterkeyhint="enter" id="workspace-chat-input"
374
+ placeholder="Ask AI to edit this workspace doc..." rows="1" spellcheck="false"></textarea>
478
375
  <div class="doc-chat-input-buttons compose-buttons">
479
- <button id="doc-chat-voice" class="ghost sm voice-button" title="Hold to talk"></button>
480
- <button id="doc-chat-send" class="primary sm" title="Send">↑</button>
376
+ <button class="ghost sm voice-button" id="workspace-chat-voice" title="Hold to talk"></button>
377
+ <button class="primary sm" id="workspace-chat-send" title="Send">↑</button>
481
378
  </div>
482
379
  </div>
483
380
  <div class="doc-chat-meta">
484
381
  <div class="doc-chat-meta-left">
485
- <span class="muted small" id="doc-chat-hint">Cmd+Enter/Ctrl+Enter to send · Enter for newline</span>
486
- <span class="muted small hidden voice-status" id="doc-chat-voice-status"></span>
382
+ <span class="muted small" id="workspace-chat-hint">Cmd+Enter/Ctrl+Enter to send · Enter for
383
+ newline</span>
487
384
  </div>
488
385
  <div class="doc-chat-meta-right">
489
- <button id="doc-chat-cancel" class="ghost sm hidden doc-chat-cancel-inline" title="Cancel">✕</button>
490
- <button id="doc-chat-new-thread" class="ghost sm" title="Start a new chat thread">New thread</button>
491
- <span id="doc-chat-status" class="pill pill-idle">idle</span>
386
+ <button class="ghost sm hidden doc-chat-cancel-inline" id="workspace-chat-cancel"
387
+ title="Cancel">✕</button>
388
+ <button class="ghost sm" id="workspace-chat-new-thread" title="Start a new chat thread">New
389
+ thread</button>
390
+ <span class="pill pill-idle" id="workspace-chat-status">idle</span>
492
391
  </div>
493
392
  </div>
494
393
  </div>
495
- <div class="doc-chat-stream" id="doc-chat-stream">
496
- <div id="doc-chat-error" class="doc-chat-error hidden"></div>
497
- <div id="doc-chat-events" class="doc-chat-events hidden">
394
+ <div class="doc-chat-stream" id="workspace-chat-stream">
395
+ <div class="doc-chat-error hidden" id="workspace-chat-error"></div>
396
+ <div class="doc-chat-events hidden" id="workspace-chat-events">
498
397
  <div class="doc-chat-section-header">
499
398
  <div class="doc-chat-section-title">
500
399
  Agent updates
501
- <span id="doc-chat-events-count" class="doc-chat-count">0</span>
400
+ <span class="doc-chat-count" id="workspace-chat-events-count">0</span>
502
401
  </div>
503
- <button id="doc-chat-events-toggle" class="ghost sm hidden">
504
- Show more
505
- </button>
402
+ <button class="ghost sm hidden" id="workspace-chat-events-toggle">Show more</button>
506
403
  </div>
507
- <div id="doc-chat-events-list" class="doc-chat-events-list"></div>
404
+ <div class="doc-chat-events-list" id="workspace-chat-events-list"></div>
508
405
  </div>
509
- <div class="doc-chat-section-header">
510
- <div class="doc-chat-section-title">
511
- History
512
- <span id="doc-chat-history-count" class="doc-chat-count">0</span>
513
- </div>
406
+ <div class="doc-chat-section-header" id="workspace-chat-history-header">
407
+ <div class="doc-chat-section-title">History</div>
514
408
  </div>
515
- <div id="doc-chat-history" class="doc-chat-history"></div>
409
+ <div class="doc-chat-history" id="workspace-chat-history"></div>
516
410
  </div>
517
411
  </div>
518
412
  </div>
519
- </section>
520
-
521
- <section id="logs" class="panel">
522
- <div class="inline-toolbar">
523
- <label class="chip" data-short="Sum">
524
- <input id="log-show-summary" type="checkbox" checked />
525
- <span>Summary</span>
526
- </label>
527
- <label>Run <input id="log-run-id" type="number" min="1" placeholder="latest" /></label>
528
- <label>Tail <input id="log-tail" type="number" min="10" value="200" /></label>
529
- <button id="load-logs" class="primary sm">Load</button>
530
- <button id="toggle-log-stream" class="ghost sm">Stream</button>
531
- <span id="log-stream-status" class="log-stream-status"></span>
532
- <label class="chip" data-short="TS">
533
- <input id="log-show-timestamp" type="checkbox" checked />
534
- <span>Timestamp</span>
535
- </label>
536
- <label class="chip" data-short="Run">
537
- <input id="log-show-run" type="checkbox" />
538
- <span>Run</span>
539
- </label>
540
- </div>
541
- <div class="log-legend">
542
- <span class="log-legend-item"><span class="log-legend-dot thinking"></span>Thinking</span>
543
- <span class="log-legend-item"><span class="log-legend-dot exec"></span>Tool calls</span>
544
- <span class="log-legend-item"><span class="log-legend-dot file"></span>File updates</span>
545
- <span class="log-legend-item"><span class="log-legend-dot diff-add"></span>Added</span>
546
- <span class="log-legend-item"><span class="log-legend-dot diff-del"></span>Removed</span>
547
- <span class="log-legend-item"><span class="log-legend-dot output"></span>Agent output</span>
548
- <span class="log-legend-item"><span class="log-legend-dot context"></span>Context</span>
413
+ </div>
414
+ </section>
415
+ <section class="panel active" id="tickets">
416
+ <div class="card ticket-card" id="ticket-card">
417
+ <div class="card-header">
418
+ <div class="card-header-left ticket-header-left">
419
+ <span class="label">Ticket Flow</span>
420
+ <span class="muted small ticket-mono" id="ticket-flow-run">–</span>
421
+ </div>
422
+ <span class="pill pill-idle" id="ticket-flow-status">idle</span>
549
423
  </div>
550
- <div class="log-container">
551
- <button id="log-load-older" class="log-load-btn hidden" title="Load older logs">Load older</button>
552
- <pre id="log-output" class="log-viewer">(no log loaded)</pre>
553
- <button id="log-jump-bottom" class="log-jump-btn hidden" title="Jump to latest">↓ Latest</button>
424
+ <div class="ticket-flow-actions">
425
+ <button class="primary sm" id="ticket-flow-bootstrap">Start Ticket Flow</button>
426
+ <button class="ghost sm" id="ticket-flow-stop">Stop</button>
427
+ <button class="ghost sm" id="ticket-flow-resume">Resume</button>
428
+ <button class="ghost sm ticket-desktop-only" id="ticket-flow-restart" style="display:none;">Restart</button>
429
+ <button class="ghost sm ticket-desktop-only" id="ticket-flow-archive" style="display:none;">Archive
430
+ Flow</button>
431
+ <button class="ghost sm icon-btn" id="ticket-flow-refresh" title="Refresh ticket flow">↻</button>
432
+ <!-- Overflow menu for mobile -->
433
+ <div class="ticket-overflow-menu">
434
+ <button class="ghost sm icon-btn" id="ticket-overflow-toggle" title="More actions">⋯</button>
435
+ <div class="ticket-overflow-dropdown hidden" id="ticket-overflow-dropdown">
436
+ <button class="ticket-overflow-item" id="ticket-overflow-new">+ New Ticket</button>
437
+ <button class="ticket-overflow-item" id="ticket-overflow-restart" style="display:none;">Restart</button>
438
+ <button class="ticket-overflow-item" id="ticket-overflow-archive" style="display:none;">Archive
439
+ Flow</button>
440
+ </div>
441
+ </div>
442
+ <button class="ghost sm ticket-desktop-only" id="ticket-new-btn" title="Create new ticket">+ New
443
+ Ticket</button>
554
444
  </div>
555
- </section>
556
-
557
- <section id="runs" class="panel">
558
- <div class="inline-toolbar runs-toolbar">
559
- <button id="runs-refresh" class="primary sm">Refresh</button>
560
- <label>
561
- Attribution
562
- <select id="runs-attribution-mode">
563
- <option value="split">Split (default)</option>
564
- <option value="full">Full (upper bound)</option>
565
- </select>
566
- </label>
567
- <label>
568
- TODO filter
569
- <input id="runs-todo-search" type="text" placeholder="Search TODOs" />
570
- </label>
445
+ <div class="ticket-flow-meta" id="ticket-flow-meta">
446
+ <div class="ticket-meta-details" id="ticket-meta-details">
447
+ <div class="ticket-meta-secondary">
448
+ <span class="muted">Current ticket</span>
449
+ <span class="ticket-mono" id="ticket-flow-current">–</span>
450
+ </div>
451
+ <div class="ticket-meta-secondary">
452
+ <span class="muted">Turn</span>
453
+ <span class="ticket-mono" id="ticket-flow-turn">–</span>
454
+ </div>
455
+ <div class="ticket-meta-secondary">
456
+ <span class="muted">Elapsed</span>
457
+ <span class="ticket-mono" id="ticket-flow-elapsed">–</span>
458
+ </div>
459
+ <div class="ticket-meta-secondary">
460
+ <span class="muted">Progress</span>
461
+ <span class="ticket-mono" id="ticket-flow-progress">–</span>
462
+ </div>
463
+ <div class="ticket-meta-secondary">
464
+ <span class="muted">Reason</span>
465
+ <span class="ticket-mono ticket-flow-reason" id="ticket-flow-reason">–</span>
466
+ </div>
467
+ <div class="ticket-meta-critical">
468
+ <span class="muted">Last activity</span>
469
+ <span class="ticket-mono" id="ticket-flow-last-activity">–</span>
470
+ <span class="pill pill-warn pill-small ticket-flow-pill" id="ticket-flow-stale"
471
+ style="display:none;">stale</span>
472
+ <button class="ghost sm ticket-flow-action" id="ticket-flow-reconnect"
473
+ style="display:none;">Reconnect</button>
474
+ </div>
475
+ <div class="ticket-meta-critical">
476
+ <span class="muted">Worker</span>
477
+ <span class="ticket-mono" id="ticket-flow-worker">–</span>
478
+ <span class="pill pill-error pill-small ticket-flow-pill" id="ticket-flow-worker-pill"
479
+ style="display:none;">dead</span>
480
+ <button class="ghost sm ticket-flow-action" id="ticket-flow-recover"
481
+ style="display:none;">Recover</button>
482
+ </div>
483
+ </div>
571
484
  </div>
572
- <div class="runs-layout">
573
- <div class="runs-card">
574
- <div class="runs-card-header">
575
- <span class="label">Runs</span>
576
- </div>
577
- <table class="runs-table">
578
- <thead>
579
- <tr>
580
- <th>Run</th>
581
- <th>Status</th>
582
- <th>Started</th>
583
- <th>Model</th>
584
- <th>Tokens</th>
585
- <th>Completed TODOs</th>
586
- </tr>
587
- </thead>
588
- <tbody id="runs-table-body"></tbody>
589
- </table>
590
- </div>
591
- <div class="runs-card">
592
- <div class="runs-card-header runs-card-header-inline">
593
- <span class="label">Tokens per TODO</span>
594
- <span id="runs-todo-summary" class="muted small">–</span>
595
- </div>
596
- <div id="runs-todo-list" class="runs-todo-list">No TODOs yet.</div>
485
+ <!-- Live Agent Output Panel -->
486
+ <div class="ticket-live-output-panel" id="ticket-live-output-panel">
487
+ <div class="ticket-live-output-header">
488
+ <span class="ticket-live-output-title">Agent</span>
489
+ <span class="ticket-live-output-status" id="ticket-live-output-status">Disconnected</span>
490
+ <span class="ticket-live-output-spacer"></span>
491
+ <button class="ticket-live-output-view-toggle" id="ticket-live-output-view-toggle"
492
+ title="Show full output">⋯</button>
493
+ </div>
494
+ <pre class="ticket-live-output-compact" id="ticket-live-output-compact"></pre>
495
+ <div class="ticket-live-output-detail hidden" id="ticket-live-output-detail">
496
+ <div class="ticket-live-output-events hidden" id="ticket-live-output-events">
497
+ <div class="ticket-live-output-events-header">
498
+ <span class="muted">Events</span>
499
+ <span class="ticket-live-output-events-count" id="ticket-live-output-events-count">0</span>
500
+ </div>
501
+ <div class="ticket-chat-events-list" id="ticket-live-output-events-list"></div>
502
+ </div>
503
+ <pre class="ticket-live-output-text" id="ticket-live-output-text"></pre>
597
504
  </div>
598
505
  </div>
599
- </section>
600
-
601
- <section id="terminal" class="panel">
602
- <div class="terminal-toolbar">
603
- <div class="terminal-toolbar-row terminal-toolbar-main">
604
- <span id="terminal-status" class="terminal-status muted">Disconnected</span>
605
- <div class="terminal-actions">
606
- <button id="terminal-connect" class="primary sm">New</button>
607
- <button id="terminal-resume" class="ghost sm">Resume</button>
608
- <button id="terminal-disconnect" class="ghost sm">Disconnect</button>
609
- </div>
610
- </div>
611
- <div class="terminal-toolbar-row terminal-toolbar-config">
612
- <div class="terminal-agent-controls">
613
- <select id="terminal-agent-select" title="Agent"></select>
614
- <select id="terminal-model-select" title="Model"></select>
615
- <select id="terminal-reasoning-select" title="Reasoning"></select>
616
- </div>
617
- <div class="terminal-toolbar-extras">
618
- <button
619
- id="terminal-text-input-toggle"
620
- class="ghost sm terminal-text-toggle"
621
- type="button"
622
- aria-controls="terminal-text-input"
623
- aria-expanded="false"
624
- title="Text input"
625
- >
626
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2"/><line x1="7" y1="12" x2="17" y2="12"/><line x1="7" y1="8" x2="13" y2="8"/><line x1="7" y1="16" x2="15" y2="16"/></svg>
627
- <span class="terminal-text-toggle-label">Text</span>
506
+ <div class="ticket-flow-grid">
507
+ <div class="ticket-panel">
508
+ <div class="ticket-panel-header">
509
+ <span class="muted">Tickets</span>
510
+ <span class="muted small" id="ticket-flow-dir">–</span>
511
+ </div>
512
+ <div class="ticket-progress-bar" id="ticket-progress-bar">
513
+ <div class="ticket-progress-fill" id="ticket-progress-fill"></div>
514
+ </div>
515
+ <div class="ticket-list" id="ticket-flow-tickets">Loading tickets…</div>
516
+ </div>
517
+ <div class="ticket-panel" id="dispatch-panel">
518
+ <div class="ticket-panel-header">
519
+ <span class="muted">Dispatch history</span>
520
+ <span class="muted small" id="ticket-dispatch-note">–</span>
521
+ <button class="ticket-panel-toggle" id="dispatch-panel-toggle" aria-label="Toggle dispatch panel"
522
+ title="Collapse/expand panel">
523
+ <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"
524
+ stroke-width="2">
525
+ <path stroke-linecap="round" stroke-linejoin="round" d="M9 5l7 7-7 7" />
526
+ </svg>
628
527
  </button>
629
- <div class="terminal-voice">
630
- <button id="terminal-voice" class="ghost sm voice-button" title="Hold to talk"></button>
631
- <span class="muted small hidden voice-status" id="terminal-voice-status"></span>
632
- </div>
528
+ </div>
529
+ <div class="dispatch-mini-list" id="dispatch-mini-list"></div>
530
+ <div class="ticket-list" id="ticket-dispatch-history">No dispatches yet. Agent messages will appear here.
633
531
  </div>
634
532
  </div>
635
533
  </div>
636
- <div id="terminal-container" class="terminal-container">
637
- <div class="terminal-overlay" id="terminal-overlay">
638
- <p class="muted">Press New or Resume to launch the agent TUI</p>
534
+ </div>
535
+ <!-- Ticket Editor Modal (Full Screen) -->
536
+ <div class="modal-overlay hidden" id="ticket-editor-modal">
537
+ <div class="modal-content ticket-editor-modal">
538
+ <div class="modal-header ticket-editor-header">
539
+ <div class="ticket-header-row">
540
+ <select class="ticket-fm-select" id="ticket-fm-agent" title="Agent">
541
+ <option value="codex">codex</option>
542
+ <option value="opencode">opencode</option>
543
+ <option value="user">user</option>
544
+ </select>
545
+ <select class="ticket-fm-select" id="ticket-fm-model" title="Model"></select>
546
+ <select class="ticket-fm-select" id="ticket-fm-reasoning" title="Reasoning"></select>
547
+ <input class="ticket-fm-input" id="ticket-fm-title" placeholder="Title (optional)" spellcheck="false"
548
+ type="text">
549
+ <div class="ticket-header-actions">
550
+ <button class="ghost sm icon-btn ticket-nav-btn" id="ticket-nav-prev" title="Previous ticket (←)"
551
+ aria-label="Previous ticket" aria-keyshortcuts="ArrowLeft Alt+ArrowLeft">←</button>
552
+ <button class="ghost sm icon-btn ticket-nav-btn" id="ticket-nav-next" title="Next ticket (→)"
553
+ aria-label="Next ticket" aria-keyshortcuts="ArrowRight Alt+ArrowRight">→</button>
554
+ <label class="ticket-fm-toggle" title="Mark as done">
555
+ <input id="ticket-fm-done" type="checkbox">
556
+ <span class="ticket-fm-toggle-label">Done</span>
557
+ </label>
558
+ <button class="ghost sm icon-btn" id="ticket-editor-close" title="Close">×</button>
559
+ </div>
560
+ </div>
561
+ </div>
562
+ <div class="ticket-editor-error hidden" id="ticket-editor-error"></div>
563
+ <div class="ticket-editor-main">
564
+ <!--
565
+ MUTUALLY EXCLUSIVE VIEWS:
566
+ The toolbar + textarea (content editor) and the patch-main (pending changes preview)
567
+ should NEVER be shown at the same time. When there's a pending draft from AI chat,
568
+ only show the patch preview. When there's no pending draft, only show the content editor.
569
+ See renderTicketChat() in ticketChatActions.ts for the toggle logic.
570
+ -->
571
+ <!-- Body Editor (hidden when patch preview is visible) -->
572
+ <div class="ticket-editor-toolbar" id="ticket-editor-toolbar">
573
+ <button class="ghost sm" id="ticket-insert-checkbox" title="Insert checkbox">+ Checkbox</button>
574
+ <button class="ghost sm" id="ticket-undo-btn" title="Undo changes" disabled>Undo</button>
575
+ <button class="danger sm hidden" id="ticket-editor-delete" title="Delete ticket">Delete</button>
576
+ <span class="ticket-autosave-status muted small" id="ticket-autosave-status"></span>
577
+ </div>
578
+ <textarea id="ticket-editor-content" class="ticket-editor-textarea" spellcheck="false"
579
+ placeholder="Describe the task details here..."></textarea>
580
+ <!-- Patch Preview (hidden when content editor is visible) -->
581
+ <div class="ticket-patch-main hidden" id="ticket-patch-main">
582
+ <div class="ticket-patch-header">
583
+ <span class="ticket-patch-title">Pending Changes</span>
584
+ <span class="ticket-patch-status muted" id="ticket-patch-status"></span>
585
+ </div>
586
+ <div class="ticket-patch-body" id="ticket-patch-body"></div>
587
+ <div class="ticket-patch-actions">
588
+ <button class="primary sm" id="ticket-patch-apply">Apply</button>
589
+ <button class="ghost sm" id="ticket-patch-discard">Discard</button>
590
+ </div>
591
+ </div>
592
+ <!-- Chat Panel (matches Docs chat) -->
593
+ <div class="ticket-chat-panel">
594
+ <div class="ticket-chat-compose">
595
+ <div class="ticket-chat-agent-controls">
596
+ <select class="mobile-hide-empty" id="ticket-chat-agent-select" title="Agent"></select>
597
+ <select id="ticket-chat-model-select" title="Model"></select>
598
+ <select id="ticket-chat-reasoning-select" title="Reasoning"></select>
599
+ </div>
600
+ <div class="ticket-chat-input-row">
601
+ <textarea id="ticket-chat-input" class="ticket-chat-input" enterkeyhint="enter"
602
+ placeholder="Ask AI to edit this ticket..." rows="1" spellcheck="false"></textarea>
603
+ <div class="ticket-chat-input-buttons">
604
+ <button class="ghost sm voice-button" id="ticket-chat-voice" title="Hold to talk"></button>
605
+ <button class="primary sm" id="ticket-chat-send" title="Send">↑</button>
606
+ </div>
607
+ </div>
608
+ <div class="ticket-chat-meta">
609
+ <div class="ticket-chat-meta-left">
610
+ <span class="muted small ticket-chat-hint" id="ticket-chat-hint">Cmd+Enter to send · Enter for
611
+ newline</span>
612
+ <span class="muted small hidden ticket-chat-voice-status" id="ticket-chat-voice-status"></span>
613
+ </div>
614
+ <div class="ticket-chat-meta-right">
615
+ <button class="ghost sm hidden ticket-chat-cancel-inline" id="ticket-chat-cancel"
616
+ title="Cancel">✕</button>
617
+ <button class="ghost sm" id="ticket-chat-new-thread" title="Start a new chat thread">New
618
+ thread</button>
619
+ <span class="ticket-chat-status" id="ticket-chat-status">idle</span>
620
+ </div>
621
+ </div>
622
+ </div>
623
+ <!-- Rich Chat Stream: shows message history and agent events -->
624
+ <div class="ticket-chat-stream" id="ticket-chat-stream">
625
+ <!-- Messages History (user prompts and assistant responses) -->
626
+ <div class="ticket-chat-messages" id="ticket-chat-messages"></div>
627
+ <!-- Agent Activity Events (thinking, tool calls, etc.) - shown during processing -->
628
+ <div class="ticket-chat-events hidden" id="ticket-chat-events">
629
+ <div class="ticket-chat-events-list" id="ticket-chat-events-list"></div>
630
+ </div>
631
+ <!-- Hidden elements for event tracking -->
632
+ <span class="hidden" id="ticket-chat-events-count">0</span>
633
+ <button class="ghost sm hidden" id="ticket-chat-events-toggle">Show more</button>
634
+ </div>
635
+ </div>
639
636
  </div>
640
- <button id="terminal-jump-bottom" class="terminal-jump-btn hidden" title="Jump to latest">
641
- ↓ Latest
642
- </button>
643
637
  </div>
644
- <!-- Mobile control bar - touch-friendly special keys (above text input) -->
645
- <div id="terminal-mobile-controls" class="terminal-mobile-controls">
646
- <div class="tmb-row">
647
- <button class="tmb-key tmb-mod" data-key="ctrl" id="tmb-ctrl">Ctrl</button>
648
- <button class="tmb-key tmb-mod" data-key="alt" id="tmb-alt">Alt</button>
649
- <button class="tmb-key" data-seq="&#x1b;">Esc</button>
650
- <button class="tmb-key" data-seq="&#x09;">Tab</button>
651
- <button class="tmb-key tmb-primary" data-seq="&#x0d;">Enter</button>
652
- </div>
653
- <div class="tmb-row">
654
- <button class="tmb-key tmb-ctrl-combo" data-ctrl="c">^C</button>
655
- <button class="tmb-key tmb-ctrl-combo" data-ctrl="d">^D</button>
656
- <button class="tmb-key tmb-ctrl-combo" data-ctrl="z">^Z</button>
657
- <button class="tmb-key tmb-bksp" data-seq="&#x7f;">Bksp</button>
658
- <button class="tmb-key tmb-arrow" data-seq="&#x1b;[D">←</button>
659
- <button class="tmb-key tmb-arrow" data-seq="&#x1b;[A">↑</button>
660
- <button class="tmb-key tmb-arrow" data-seq="&#x1b;[B">↓</button>
661
- <button class="tmb-key tmb-arrow" data-seq="&#x1b;[C">→</button>
638
+ </div>
639
+ </section>
640
+ <section class="panel" id="terminal">
641
+ <div class="terminal-toolbar">
642
+ <div class="terminal-toolbar-row terminal-toolbar-main">
643
+ <span class="terminal-status muted" id="terminal-status">Disconnected</span>
644
+ <div class="terminal-actions">
645
+ <button class="primary sm" id="terminal-connect">New</button>
646
+ <button class="ghost sm" id="terminal-resume">Resume</button>
647
+ <button class="ghost sm" id="terminal-disconnect">Disconnect</button>
662
648
  </div>
663
649
  </div>
664
- <div id="terminal-text-input" class="terminal-text-input compose-panel hidden" aria-hidden="true">
665
- <label class="terminal-text-input-title" for="terminal-textarea">Text input</label>
666
- <div class="terminal-text-input-row compose-row">
667
- <textarea
668
- id="terminal-textarea"
669
- rows="2"
670
- autocomplete="off"
671
- autocapitalize="off"
672
- spellcheck="false"
673
- enterkeyhint="enter"
674
- placeholder="Type or paste text/images to send to the terminal…"
675
- ></textarea>
676
- <div class="terminal-text-input-buttons compose-buttons">
677
- <button
678
- id="terminal-text-image"
679
- class="ghost sm terminal-text-image"
680
- type="button"
681
- title="Attach image"
682
- aria-label="Attach image"
683
- >Img</button>
684
- <input
685
- id="terminal-text-image-input"
686
- class="hidden"
687
- type="file"
688
- accept="image/*"
689
- />
690
- <button
691
- id="terminal-text-voice"
692
- class="ghost sm voice-button terminal-text-voice"
693
- type="button"
694
- title="Hold to talk"
695
- data-voice-mode="waveform"
696
- ></button>
697
- <button
698
- id="terminal-text-send"
699
- class="primary terminal-text-send-icon"
700
- type="button"
701
- aria-label="Send"
702
- >→</button>
650
+ <div class="terminal-toolbar-row terminal-toolbar-config">
651
+ <div class="terminal-agent-controls">
652
+ <select id="terminal-agent-select" title="Agent"></select>
653
+ <select id="terminal-model-select" title="Model"></select>
654
+ <select id="terminal-reasoning-select" title="Reasoning"></select>
655
+ </div>
656
+ <div class="terminal-toolbar-extras">
657
+ <button aria-controls="terminal-text-input" aria-expanded="false" class="ghost sm terminal-text-toggle"
658
+ id="terminal-text-input-toggle" title="Text input" type="button">
659
+ <svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
660
+ viewbox="0 0 24 24">
661
+ <rect height="18" rx="2" width="18" x="3" y="3"></rect>
662
+ <line x1="7" x2="17" y1="12" y2="12"></line>
663
+ <line x1="7" x2="13" y1="8" y2="8"></line>
664
+ <line x1="7" x2="15" y1="16" y2="16"></line>
665
+ </svg>
666
+ <span class="terminal-text-toggle-label">Text</span>
667
+ </button>
668
+ <div class="terminal-voice">
669
+ <button class="ghost sm voice-button" id="terminal-voice" title="Hold to talk"></button>
670
+ <span class="muted small hidden voice-status" id="terminal-voice-status"></span>
703
671
  </div>
704
672
  </div>
705
673
  </div>
706
- </section>
707
- </main>
708
- </div>
709
- <div id="toast" class="toast"></div>
710
-
711
- <!-- Confirmation Modal -->
712
- <div id="confirm-modal" class="modal-overlay" hidden>
713
- <div
714
- class="modal-dialog"
715
- role="dialog"
716
- aria-modal="true"
717
- aria-labelledby="confirm-modal-title"
718
- aria-describedby="confirm-modal-message"
719
- tabindex="-1"
720
- >
721
- <span id="confirm-modal-title" class="sr-only">Confirmation</span>
722
- <p id="confirm-modal-message"></p>
723
- <div class="modal-actions">
724
- <button id="confirm-modal-cancel" class="ghost">Cancel</button>
725
- <button id="confirm-modal-ok" class="danger">Confirm</button>
726
674
  </div>
727
- </div>
728
- </div>
729
-
730
- <!-- Input Modal -->
731
- <div id="input-modal" class="modal-overlay" hidden>
732
- <div
733
- class="modal-dialog modal-input"
734
- role="dialog"
735
- aria-modal="true"
736
- aria-labelledby="input-modal-title"
737
- aria-describedby="input-modal-message"
738
- tabindex="-1"
739
- >
740
- <span id="input-modal-title" class="sr-only">Input</span>
741
- <p id="input-modal-message"></p>
742
- <input type="text" id="input-modal-input" autocomplete="off" spellcheck="false" />
743
- <div class="modal-actions">
744
- <button id="input-modal-cancel" class="ghost">Cancel</button>
745
- <button id="input-modal-ok" class="primary">OK</button>
675
+ <div class="terminal-container" id="terminal-container">
676
+ <div class="terminal-overlay" id="terminal-overlay">
677
+ <p>Click <strong>New</strong> to start a fresh agent session, or <strong>Resume</strong> to continue an
678
+ existing one.</p>
679
+ <p class="terminal-overlay-hint">Use the agent dropdown above to switch between different agents.</p>
680
+ </div>
681
+ <button class="terminal-jump-btn hidden" id="terminal-jump-bottom" title="Jump to latest">
682
+ ↓ Latest
683
+ </button>
746
684
  </div>
747
- </div>
748
- </div>
749
-
750
- <!-- Ingest Spec Modal -->
751
- <div id="ingest-modal" class="modal-overlay" hidden>
752
- <div
753
- class="modal-dialog modal-ingest"
754
- role="dialog"
755
- aria-modal="true"
756
- aria-labelledby="ingest-modal-title"
757
- aria-describedby="ingest-modal-message"
758
- tabindex="-1"
759
- >
760
- <span id="ingest-modal-title" class="sr-only">Ingest Spec</span>
761
- <div id="ingest-modal-content">
762
- <p id="ingest-modal-message">Ready to ingest SPEC into TODO, PROGRESS, and OPINIONS?</p>
763
- <div id="ingest-modal-refinement" class="ingest-modal-refinement hidden">
764
- <textarea
765
- id="ingest-modal-input"
766
- rows="3"
767
- placeholder="Refine the ingest (optional)..."
768
- spellcheck="false"
769
- ></textarea>
685
+ <!-- Mobile control bar - touch-friendly special keys (above text input) -->
686
+ <div class="terminal-mobile-controls" id="terminal-mobile-controls">
687
+ <div class="tmb-row">
688
+ <button class="tmb-key tmb-mod" data-key="ctrl" id="tmb-ctrl">Ctrl</button>
689
+ <button class="tmb-key tmb-mod" data-key="alt" id="tmb-alt">Alt</button>
690
+ <button class="tmb-key" data-seq="">Esc</button>
691
+ <button class="tmb-key" data-seq=" ">Tab</button>
692
+ <button class="tmb-key tmb-primary" data-seq="
693
+ ">Enter</button>
694
+ </div>
695
+ <div class="tmb-row">
696
+ <button class="tmb-key tmb-ctrl-combo" data-ctrl="c">^C</button>
697
+ <button class="tmb-key tmb-ctrl-combo" data-ctrl="d">^D</button>
698
+ <button class="tmb-key tmb-ctrl-combo" data-ctrl="z">^Z</button>
699
+ <button class="tmb-key tmb-bksp" data-seq="">Bksp</button>
700
+ <button class="tmb-key tmb-arrow" data-seq="[D">←</button>
701
+ <button class="tmb-key tmb-arrow" data-seq="[A">↑</button>
702
+ <button class="tmb-key tmb-arrow" data-seq="[B">↓</button>
703
+ <button class="tmb-key tmb-arrow" data-seq="[C">→</button>
770
704
  </div>
771
705
  </div>
772
- <div class="modal-actions">
773
- <button id="ingest-modal-cancel" class="ghost">Cancel</button>
774
- <button id="ingest-modal-ok" class="primary">Ingest</button>
706
+ <div aria-hidden="true" class="terminal-text-input compose-panel hidden" id="terminal-text-input">
707
+ <label class="terminal-text-input-title" for="terminal-textarea">Text input</label>
708
+ <div class="terminal-text-input-row compose-row">
709
+ <textarea autocapitalize="off" autocomplete="off" enterkeyhint="enter" id="terminal-textarea"
710
+ placeholder="Type or paste text/images to send to the terminal…" rows="2" spellcheck="false"></textarea>
711
+ <div class="terminal-text-input-buttons compose-buttons">
712
+ <button aria-label="Attach image" class="ghost sm terminal-text-image" id="terminal-text-image"
713
+ title="Attach image" type="button">Img</button>
714
+ <input accept="image/*" class="hidden" id="terminal-text-image-input" type="file" />
715
+ <button class="ghost sm voice-button terminal-text-voice" data-voice-mode="waveform"
716
+ id="terminal-text-voice" title="Hold to talk" type="button"></button>
717
+ <button aria-label="Send" class="primary terminal-text-send-icon" id="terminal-text-send"
718
+ type="button">→</button>
719
+ </div>
720
+ </div>
775
721
  </div>
722
+ </section>
723
+ </main>
724
+ </div>
725
+ <div class="toast" id="toast"></div>
726
+ <!-- Confirmation Modal -->
727
+ <div class="modal-overlay" hidden="" id="confirm-modal">
728
+ <div aria-describedby="confirm-modal-message" aria-labelledby="confirm-modal-title" aria-modal="true"
729
+ class="modal-dialog" role="dialog" tabindex="-1">
730
+ <span class="sr-only" id="confirm-modal-title">Confirmation</span>
731
+ <p id="confirm-modal-message"></p>
732
+ <div class="modal-actions">
733
+ <button class="ghost" id="confirm-modal-cancel">Cancel</button>
734
+ <button class="danger" id="confirm-modal-ok">Confirm</button>
735
+ </div>
736
+ </div>
737
+ </div>
738
+ <!-- Input Modal -->
739
+ <div class="modal-overlay" hidden="" id="input-modal">
740
+ <div aria-describedby="input-modal-message" aria-labelledby="input-modal-title" aria-modal="true"
741
+ class="modal-dialog modal-input" role="dialog" tabindex="-1">
742
+ <span class="sr-only" id="input-modal-title">Input</span>
743
+ <p id="input-modal-message"></p>
744
+ <input autocomplete="off" id="input-modal-input" spellcheck="false" type="text" />
745
+ <div class="modal-actions">
746
+ <button class="ghost" id="input-modal-cancel">Cancel</button>
747
+ <button class="primary" id="input-modal-ok">OK</button>
776
748
  </div>
777
749
  </div>
778
-
779
- <!-- Create Repo Modal -->
780
- <div id="create-repo-modal" class="modal-overlay" hidden>
781
- <div
782
- class="modal-dialog modal-create-repo"
783
- role="dialog"
784
- aria-modal="true"
785
- aria-labelledby="create-repo-modal-title"
786
- aria-describedby="create-repo-modal-body"
787
- tabindex="-1"
788
- >
789
- <div class="modal-header">
790
- <span class="label" id="create-repo-modal-title">Create New Repository</span>
750
+ </div>
751
+ <!-- Create Repo Modal -->
752
+ <div class="modal-overlay" hidden="" id="create-repo-modal">
753
+ <div aria-describedby="create-repo-modal-body" aria-labelledby="create-repo-modal-title" aria-modal="true"
754
+ class="modal-dialog modal-create-repo" role="dialog" tabindex="-1">
755
+ <div class="modal-header">
756
+ <span class="label" id="create-repo-modal-title">Create New Repository</span>
757
+ </div>
758
+ <div class="modal-body" id="create-repo-modal-body">
759
+ <div class="form-group">
760
+ <label for="create-repo-id">Repo ID <span class="required">*</span></label>
761
+ <input autocomplete="off" id="create-repo-id" placeholder="my-project" spellcheck="false" type="text" />
762
+ <span class="form-hint">Used as directory name if path not specified</span>
791
763
  </div>
792
- <div class="modal-body" id="create-repo-modal-body">
793
- <div class="form-group">
794
- <label for="create-repo-id">Repo ID <span class="required">*</span></label>
795
- <input type="text" id="create-repo-id" placeholder="my-project" autocomplete="off" spellcheck="false" />
796
- <span class="form-hint">Used as directory name if path not specified</span>
797
- </div>
798
- <div class="form-group">
799
- <label for="create-repo-path">Path <span class="optional">(optional)</span></label>
800
- <input type="text" id="create-repo-path" placeholder="relative/path/to/repo" autocomplete="off" spellcheck="false" />
801
- <span class="form-hint">Leave empty to use repo ID as path</span>
802
- </div>
803
- <div class="form-group">
804
- <label for="create-repo-url">Git URL <span class="optional">(optional)</span></label>
805
- <input type="text" id="create-repo-url" placeholder="https://github.com/org/repo.git" autocomplete="off" spellcheck="false" />
806
- <span class="form-hint">If provided, the repo will be cloned automatically</span>
807
- </div>
808
- <div class="form-group form-checkbox">
809
- <label>
810
- <input type="checkbox" id="create-repo-git" checked />
811
- <span>Initialize git repository</span>
812
- </label>
813
- </div>
764
+ <div class="form-group">
765
+ <label for="create-repo-path">Path <span class="optional">(optional)</span></label>
766
+ <input autocomplete="off" id="create-repo-path" placeholder="relative/path/to/repo" spellcheck="false"
767
+ type="text" />
768
+ <span class="form-hint">Leave empty to use repo ID as path</span>
769
+ </div>
770
+ <div class="form-group">
771
+ <label for="create-repo-url">Git URL <span class="optional">(optional)</span></label>
772
+ <input autocomplete="off" id="create-repo-url" placeholder="https://github.com/org/repo.git"
773
+ spellcheck="false" type="text" />
774
+ <span class="form-hint">If provided, the repo will be cloned automatically</span>
814
775
  </div>
815
- <div class="modal-actions">
816
- <button id="create-repo-cancel" class="ghost">Cancel</button>
817
- <button id="create-repo-submit" class="primary">Create</button>
776
+ <div class="form-group form-checkbox">
777
+ <label>
778
+ <input checked="" id="create-repo-git" type="checkbox" />
779
+ <span>Initialize git repository</span>
780
+ </label>
818
781
  </div>
819
782
  </div>
783
+ <div class="modal-actions">
784
+ <button class="ghost" id="create-repo-cancel">Cancel</button>
785
+ <button class="primary" id="create-repo-submit">Create</button>
786
+ </div>
820
787
  </div>
821
-
822
- <!-- Hub Settings Modal -->
823
- <div id="hub-settings-modal" class="modal-overlay" hidden>
824
- <div
825
- class="modal-dialog"
826
- role="dialog"
827
- aria-modal="true"
828
- aria-labelledby="hub-settings-modal-title"
829
- aria-describedby="hub-settings-modal-body"
830
- tabindex="-1"
831
- >
832
- <div class="modal-header">
833
- <span class="label" id="hub-settings-modal-title">Hub Settings</span>
834
- </div>
835
- <div class="modal-body" id="hub-settings-modal-body">
836
- <p class="muted small">System-wide settings for Codex Autorunner.</p>
837
- <div class="form-group">
838
- <label>System Update</label>
839
- <select id="hub-update-target">
840
- <option value="both">Web + Telegram</option>
841
- <option value="web">Web only</option>
842
- <option value="telegram">Telegram only</option>
843
- </select>
844
- <button id="hub-update-btn" class="primary sm">Update CAR</button>
845
- <span class="form-hint">Pull latest code and restart selected services</span>
846
- </div>
847
- </div>
848
- <div class="modal-actions">
849
- <button id="hub-settings-close" class="ghost">Close</button>
788
+ </div>
789
+ <!-- Hub Settings Modal -->
790
+ <div class="modal-overlay" hidden="" id="hub-settings-modal">
791
+ <div aria-describedby="hub-settings-modal-body" aria-labelledby="hub-settings-modal-title" aria-modal="true"
792
+ class="modal-dialog" role="dialog" tabindex="-1">
793
+ <div class="modal-header">
794
+ <span class="label" id="hub-settings-modal-title">Hub Settings</span>
795
+ </div>
796
+ <div class="modal-body" id="hub-settings-modal-body">
797
+ <p class="muted small">System-wide settings for Codex Autorunner.</p>
798
+ <div class="form-group">
799
+ <label>System Update</label>
800
+ <select id="hub-update-target">
801
+ <option value="both">Web + Telegram</option>
802
+ <option value="web">Web only</option>
803
+ <option value="telegram">Telegram only</option>
804
+ </select>
805
+ <button class="primary sm" id="hub-update-btn">Update CAR</button>
806
+ <span class="form-hint">Pull latest code and restart selected services</span>
850
807
  </div>
851
808
  </div>
809
+ <div class="modal-actions">
810
+ <button class="ghost" id="hub-settings-close">Close</button>
811
+ </div>
852
812
  </div>
853
-
854
- <!-- Repo Settings Modal -->
855
- <div id="repo-settings-modal" class="modal-overlay" hidden>
856
- <div
857
- class="modal-dialog"
858
- role="dialog"
859
- aria-modal="true"
860
- aria-labelledby="repo-settings-modal-title"
861
- aria-describedby="repo-settings-modal-body"
862
- tabindex="-1"
863
- >
864
- <div class="modal-header">
865
- <span class="label" id="repo-settings-modal-title">Repo Settings</span>
813
+ </div>
814
+ <!-- Repo Settings Modal -->
815
+ <div class="modal-overlay" hidden="" id="repo-settings-modal">
816
+ <div aria-describedby="repo-settings-modal-body" aria-labelledby="repo-settings-modal-title" aria-modal="true"
817
+ class="modal-dialog" role="dialog" tabindex="-1">
818
+ <div class="modal-header">
819
+ <span class="label" id="repo-settings-modal-title">Repo Settings</span>
820
+ </div>
821
+ <div class="modal-body" id="repo-settings-modal-body">
822
+ <p class="muted small">Settings for the current repository session.</p>
823
+ <div class="form-group">
824
+ <label>System Update</label>
825
+ <select id="repo-update-target">
826
+ <option value="both">Web + Telegram</option>
827
+ <option value="web">Web only</option>
828
+ <option value="telegram">Telegram only</option>
829
+ </select>
830
+ <button class="primary sm" id="repo-update-btn">Update CAR</button>
831
+ <span class="form-hint">Pull latest code and restart selected services</span>
866
832
  </div>
867
- <div class="modal-body" id="repo-settings-modal-body">
868
- <p class="muted small">Settings for the current repository session.</p>
869
- <div class="form-group">
870
- <label>System Update</label>
871
- <select id="repo-update-target">
872
- <option value="both">Web + Telegram</option>
873
- <option value="web">Web only</option>
874
- <option value="telegram">Telegram only</option>
875
- </select>
876
- <button id="repo-update-btn" class="primary sm">Update CAR</button>
877
- <span class="form-hint">Pull latest code and restart selected services</span>
878
- </div>
879
- <div class="form-group">
880
- <label>Autorunner Settings</label>
881
- <div class="settings-grid">
882
- <div>
883
- <label for="autorunner-model-select" class="muted small">Model</label>
884
- <select id="autorunner-model-select"></select>
885
- </div>
886
- <div>
887
- <label for="autorunner-effort-select" class="muted small">Reasoning effort</label>
888
- <select id="autorunner-effort-select"></select>
889
- </div>
890
- <div>
891
- <label for="autorunner-approval-select" class="muted small">Approval policy</label>
892
- <select id="autorunner-approval-select"></select>
893
- </div>
894
- <div>
895
- <label for="autorunner-sandbox-select" class="muted small">Sandbox</label>
896
- <select id="autorunner-sandbox-select"></select>
897
- </div>
898
- <div>
899
- <label for="autorunner-max-runs-input" class="muted small">Max runs</label>
900
- <input id="autorunner-max-runs-input" type="number" min="1" step="1" placeholder="Unlimited" />
901
- <span class="form-hint">Maximum number of autorunner cycles (empty = unlimited)</span>
902
- </div>
833
+ <div class="form-group">
834
+ <label>Autorunner Settings</label>
835
+ <div class="settings-grid">
836
+ <div>
837
+ <label class="muted small" for="autorunner-model-select">Model</label>
838
+ <select id="autorunner-model-select"></select>
903
839
  </div>
904
- <div id="autorunner-network-row" class="settings-toggle-row">
905
- <label class="form-checkbox">
906
- <input id="autorunner-network-toggle" type="checkbox" />
907
- <span>Allow network access in workspace-write mode</span>
908
- </label>
840
+ <div>
841
+ <label class="muted small" for="autorunner-effort-select">Reasoning effort</label>
842
+ <select id="autorunner-effort-select"></select>
909
843
  </div>
910
- <div class="settings-actions">
911
- <button id="autorunner-settings-save" class="primary sm">Save settings</button>
912
- <button id="autorunner-settings-reload" class="ghost sm">Reload</button>
844
+ <div>
845
+ <label class="muted small" for="autorunner-approval-select">Approval policy</label>
846
+ <select id="autorunner-approval-select"></select>
913
847
  </div>
914
- <span id="autorunner-settings-warning" class="form-hint warning">Changing these settings starts a new autorunner conversation.</span>
915
- </div>
916
- <div class="form-group">
917
- <label>Thread Tools</label>
918
- <div id="thread-tools-list" class="thread-tools-list"></div>
919
- <div class="thread-tools-actions">
920
- <button id="thread-new-autorunner" class="ghost sm">New autorunner thread</button>
921
- <button id="thread-archive-autorunner" class="ghost sm">Archive autorunner thread</button>
922
- <button id="thread-reset-all" class="danger sm">Reset all conversations</button>
923
- <button id="thread-backup-download" class="ghost sm">Download backup</button>
924
- </div>
925
- <span class="form-hint">Resetting conversations clears stored thread IDs and restarts chats.</span>
926
- </div>
927
- </div>
928
- <div class="modal-actions">
929
- <button id="repo-settings-close" class="ghost">Close</button>
930
- </div>
931
- </div>
932
- </div>
933
-
934
- <div id="run-details-modal" class="modal-overlay" hidden>
935
- <div
936
- class="modal-dialog run-details-modal"
937
- role="dialog"
938
- aria-modal="true"
939
- aria-labelledby="run-details-title"
940
- aria-describedby="run-details-meta"
941
- tabindex="-1"
942
- >
943
- <div class="modal-header">
944
- <span class="label" id="run-details-title">Run</span>
945
- </div>
946
- <div class="modal-body">
947
- <div id="run-details-meta" class="muted small">–</div>
948
- <div class="run-details-grid">
949
- <div class="run-details-section">
950
- <div class="run-details-title">Completed TODOs</div>
951
- <div id="run-details-todos" class="run-details-list">–</div>
848
+ <div>
849
+ <label class="muted small" for="autorunner-sandbox-select">Sandbox</label>
850
+ <select id="autorunner-sandbox-select"></select>
952
851
  </div>
953
- <div class="run-details-section">
954
- <div class="run-details-title">Token breakdown</div>
955
- <div id="run-details-tokens" class="run-details-list">–</div>
852
+ <div>
853
+ <label class="muted small" for="autorunner-max-runs-input">Max runs</label>
854
+ <input id="autorunner-max-runs-input" min="1" placeholder="Unlimited" step="1" type="number" />
855
+ <span class="form-hint">Maximum number of autorunner cycles (empty = unlimited)</span>
956
856
  </div>
957
857
  </div>
958
- <div class="run-details-section">
959
- <div class="run-details-title">Plan</div>
960
- <pre id="run-details-plan" class="run-details-artifact">–</pre>
858
+ <div class="settings-toggle-row" id="autorunner-network-row">
859
+ <label class="form-checkbox">
860
+ <input id="autorunner-network-toggle" type="checkbox" />
861
+ <span>Allow network access in workspace-write mode</span>
862
+ </label>
961
863
  </div>
962
- <div class="run-details-section">
963
- <div class="run-details-title">Diff</div>
964
- <pre id="run-details-diff" class="run-details-artifact">–</pre>
864
+ <div class="settings-actions">
865
+ <button class="primary sm" id="autorunner-settings-save">Save settings</button>
866
+ <button class="ghost sm" id="autorunner-settings-reload">Reload</button>
965
867
  </div>
966
- <div class="run-details-section">
967
- <div class="run-details-title">Final output</div>
968
- <pre id="run-details-output" class="run-details-artifact">–</pre>
868
+ <span class="form-hint warning" id="autorunner-settings-warning">Changing these settings starts a new
869
+ autorunner conversation.</span>
870
+ </div>
871
+ <div class="form-group">
872
+ <label>Thread Tools</label>
873
+ <div class="thread-tools-list" id="thread-tools-list"></div>
874
+ <div class="thread-tools-actions">
875
+ <button class="ghost sm" id="thread-new-autorunner">New autorunner thread</button>
876
+ <button class="ghost sm" id="thread-archive-autorunner">Archive autorunner thread</button>
877
+ <button class="danger sm" id="thread-reset-all">Reset all conversations</button>
878
+ <button class="ghost sm" id="thread-backup-download">Download backup</button>
969
879
  </div>
880
+ <span class="form-hint">Resetting conversations clears stored thread IDs and restarts chats.</span>
970
881
  </div>
971
- <div class="modal-actions run-details-actions">
972
- <a id="run-details-log" class="ghost sm" target="_blank" rel="noreferrer">Open log</a>
973
- <button id="run-details-close" class="ghost">Close</button>
882
+ </div>
883
+ <div class="modal-actions">
884
+ <button class="ghost" id="repo-settings-close">Close</button>
885
+ </div>
886
+ </div>
887
+ </div>
888
+ <!-- Reason Details Modal -->
889
+ <div class="modal-overlay" hidden="" id="reason-modal">
890
+ <div aria-describedby="reason-modal-content" aria-labelledby="reason-modal-title" aria-modal="true"
891
+ class="modal-dialog reason-modal-dialog" role="dialog" tabindex="-1">
892
+ <h3 class="reason-modal-title" id="reason-modal-title">Status Details</h3>
893
+ <pre class="reason-modal-content" id="reason-modal-content"></pre>
894
+ <div class="modal-actions">
895
+ <button class="ghost" id="reason-modal-close">Close</button>
896
+ </div>
897
+ </div>
898
+ </div>
899
+ <!-- File Picker Modal -->
900
+ <div class="modal-overlay file-picker-modal" hidden="" id="file-picker-modal">
901
+ <div aria-labelledby="file-picker-modal-title" aria-modal="true" class="modal-dialog file-picker-dialog"
902
+ role="dialog" tabindex="-1">
903
+ <div class="file-picker-header">
904
+ <span class="file-picker-title" id="file-picker-modal-title">Select File</span>
905
+ <button class="file-picker-close" id="file-picker-close" aria-label="Close">&times;</button>
906
+ </div>
907
+ <div class="file-picker-body" id="file-picker-body">
908
+ <!-- File list rendered here by JS -->
909
+ </div>
910
+ </div>
911
+ </div>
912
+ <!-- Workspace Create Modal -->
913
+ <div class="modal-overlay" hidden="" id="workspace-create-modal">
914
+ <div aria-describedby="workspace-create-body" aria-labelledby="workspace-create-title" aria-modal="true"
915
+ class="modal-dialog workspace-create-dialog" role="dialog" tabindex="-1">
916
+ <div class="modal-header">
917
+ <span class="label" id="workspace-create-title">Create</span>
918
+ <button class="file-picker-close" id="workspace-create-close" aria-label="Close">&times;</button>
919
+ </div>
920
+ <div class="modal-body" id="workspace-create-body">
921
+ <div class="form-group">
922
+ <label class="muted small" for="workspace-create-name">Name</label>
923
+ <input id="workspace-create-name" placeholder="my-note.md" type="text" />
924
+ <span class="form-hint" id="workspace-create-hint">Created under current folder</span>
974
925
  </div>
926
+ <div class="form-group">
927
+ <label class="muted small" for="workspace-create-path">Location</label>
928
+ <select id="workspace-create-path"></select>
929
+ </div>
930
+ </div>
931
+ <div class="modal-actions workspace-create-actions">
932
+ <button class="ghost sm" id="workspace-create-cancel">Cancel</button>
933
+ <button class="primary sm" id="workspace-create-submit">Create</button>
975
934
  </div>
976
935
  </div>
977
-
978
- <script src="static/loader.js?v=__CAR_ASSET_VERSION__" data-car-loader></script>
979
- </body>
980
- </html>
936
+ </div>
937
+ <!-- Workspace Confirm Modal -->
938
+ <div class="modal-overlay" hidden="" id="workspace-confirm-modal">
939
+ <div aria-describedby="workspace-confirm-body" aria-labelledby="workspace-confirm-title" aria-modal="true"
940
+ class="modal-dialog workspace-confirm-dialog" role="dialog" tabindex="-1">
941
+ <div class="modal-header">
942
+ <span class="label" id="workspace-confirm-title">Confirm</span>
943
+ </div>
944
+ <div class="modal-body" id="workspace-confirm-body">
945
+ <p id="workspace-confirm-text"></p>
946
+ </div>
947
+ <div class="modal-actions workspace-confirm-actions">
948
+ <button class="ghost sm" id="workspace-confirm-cancel">Cancel</button>
949
+ <button class="primary sm" id="workspace-confirm-yes">Confirm</button>
950
+ </div>
951
+ </div>
952
+ </div>
953
+ <script data-car-loader="" src="static/loader.js?v=__CAR_ASSET_VERSION__"></script>
954
+ </body>
955
+
956
+ </html>