aicodeman 1.35.0 → 1.40.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (246) hide show
  1. package/README.md +8 -0
  2. package/README.zh-CN.md +8 -0
  3. package/dist/attachment-registry.d.ts +6 -0
  4. package/dist/attachment-registry.d.ts.map +1 -1
  5. package/dist/attachment-registry.js +9 -3
  6. package/dist/attachment-registry.js.map +1 -1
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +2 -2
  9. package/dist/cli.js.map +1 -1
  10. package/dist/config/cli-registry/patterns.d.ts +6 -0
  11. package/dist/config/cli-registry/patterns.d.ts.map +1 -1
  12. package/dist/config/cli-registry/patterns.js +13 -0
  13. package/dist/config/cli-registry/patterns.js.map +1 -1
  14. package/dist/config/cli-registry/schema.d.ts +13 -0
  15. package/dist/config/cli-registry/schema.d.ts.map +1 -1
  16. package/dist/config/cli-registry/schema.js +60 -2
  17. package/dist/config/cli-registry/schema.js.map +1 -1
  18. package/dist/config/cli-registry/stock.d.ts.map +1 -1
  19. package/dist/config/cli-registry/stock.js +175 -7
  20. package/dist/config/cli-registry/stock.js.map +1 -1
  21. package/dist/config/cli-registry/types.d.ts +93 -6
  22. package/dist/config/cli-registry/types.d.ts.map +1 -1
  23. package/dist/deepseek-route-config.d.ts +110 -0
  24. package/dist/deepseek-route-config.d.ts.map +1 -0
  25. package/dist/deepseek-route-config.js +477 -0
  26. package/dist/deepseek-route-config.js.map +1 -0
  27. package/dist/git-workspace-status.d.ts +31 -5
  28. package/dist/git-workspace-status.d.ts.map +1 -1
  29. package/dist/git-workspace-status.js +49 -29
  30. package/dist/git-workspace-status.js.map +1 -1
  31. package/dist/model-config-resolvers.d.ts +29 -0
  32. package/dist/model-config-resolvers.d.ts.map +1 -0
  33. package/dist/model-config-resolvers.js +34 -0
  34. package/dist/model-config-resolvers.js.map +1 -0
  35. package/dist/session-display-model.d.ts +110 -0
  36. package/dist/session-display-model.d.ts.map +1 -0
  37. package/dist/session-display-model.js +154 -0
  38. package/dist/session-display-model.js.map +1 -0
  39. package/dist/session.d.ts +145 -8
  40. package/dist/session.d.ts.map +1 -1
  41. package/dist/session.js +280 -35
  42. package/dist/session.js.map +1 -1
  43. package/dist/types/session.d.ts +28 -1
  44. package/dist/types/session.d.ts.map +1 -1
  45. package/dist/types/session.js.map +1 -1
  46. package/dist/types/tools.d.ts +1 -1
  47. package/dist/types/tools.d.ts.map +1 -1
  48. package/dist/utils/deepseek-cli-resolver.d.ts +8 -0
  49. package/dist/utils/deepseek-cli-resolver.d.ts.map +1 -1
  50. package/dist/utils/deepseek-cli-resolver.js +18 -2
  51. package/dist/utils/deepseek-cli-resolver.js.map +1 -1
  52. package/dist/web/launch-defaults.d.ts +22 -0
  53. package/dist/web/launch-defaults.d.ts.map +1 -0
  54. package/dist/web/launch-defaults.js +46 -0
  55. package/dist/web/launch-defaults.js.map +1 -0
  56. package/dist/web/public/admin-ui.js.gz +0 -0
  57. package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
  58. package/dist/web/public/app.abadc970.js +43 -0
  59. package/dist/web/public/app.abadc970.js.br +0 -0
  60. package/dist/web/public/app.abadc970.js.gz +0 -0
  61. package/dist/web/public/approvals-ui.js.gz +0 -0
  62. package/dist/web/public/{constants.d95fade9.js → constants.c0f8f9de.js} +1009 -127
  63. package/dist/web/public/constants.c0f8f9de.js.br +0 -0
  64. package/dist/web/public/constants.c0f8f9de.js.gz +0 -0
  65. package/dist/web/public/cron-ui.js.gz +0 -0
  66. package/dist/web/public/entrance-animations.js +1 -0
  67. package/dist/web/public/entrance-animations.js.br +0 -0
  68. package/dist/web/public/entrance-animations.js.gz +0 -0
  69. package/dist/web/public/git-status-ui.js +55 -9
  70. package/dist/web/public/git-status-ui.js.br +0 -0
  71. package/dist/web/public/git-status-ui.js.gz +0 -0
  72. package/dist/web/public/home-sessions.js +12 -9
  73. package/dist/web/public/home-sessions.js.br +0 -0
  74. package/dist/web/public/home-sessions.js.gz +0 -0
  75. package/dist/web/public/host-wake-ui.js.gz +0 -0
  76. package/dist/web/public/i18n.a31747a9.js +2 -0
  77. package/dist/web/public/i18n.a31747a9.js.br +0 -0
  78. package/dist/web/public/i18n.a31747a9.js.gz +0 -0
  79. package/dist/web/public/{image-input.a216cf9e.js → image-input.898a538b.js} +18 -8
  80. package/dist/web/public/image-input.898a538b.js.br +0 -0
  81. package/dist/web/public/image-input.898a538b.js.gz +0 -0
  82. package/dist/web/public/index.html +133 -37
  83. package/dist/web/public/index.html.br +0 -0
  84. package/dist/web/public/index.html.gz +0 -0
  85. package/dist/web/public/input-cjk.8bc46081.js.gz +0 -0
  86. package/dist/web/public/keyboard-accessory.c1e7c7b7.js.gz +0 -0
  87. package/dist/web/public/{mobile-handlers.23a85db1.js → mobile-handlers.0ef9c311.js} +20 -0
  88. package/dist/web/public/mobile-handlers.0ef9c311.js.br +0 -0
  89. package/dist/web/public/mobile-handlers.0ef9c311.js.gz +0 -0
  90. package/dist/web/public/mobile-ime-preview.2dbaf262.js.gz +0 -0
  91. package/dist/web/public/mobile-overview.js.gz +0 -0
  92. package/dist/web/public/mobile.111b187d.css +1 -0
  93. package/dist/web/public/mobile.111b187d.css.br +0 -0
  94. package/dist/web/public/mobile.111b187d.css.gz +0 -0
  95. package/dist/web/public/notification-manager.50bb87d8.js.gz +0 -0
  96. package/dist/web/public/orchestrator-panel.js.gz +0 -0
  97. package/dist/web/public/{panels-ui.6a5898d9.js → panels-ui.4735dfc2.js} +4 -4
  98. package/dist/web/public/panels-ui.4735dfc2.js.br +0 -0
  99. package/dist/web/public/{panels-ui.6a5898d9.js.gz → panels-ui.4735dfc2.js.gz} +0 -0
  100. package/dist/web/public/ralph-panel.b350e2ef.js.gz +0 -0
  101. package/dist/web/public/ralph-wizard.b6c0dd19.js.gz +0 -0
  102. package/dist/web/public/readmymind-ui.js.gz +0 -0
  103. package/dist/web/public/reboot-restore-ui.js.gz +0 -0
  104. package/dist/web/public/respawn-ui.ff0dae4c.js.gz +0 -0
  105. package/dist/web/public/sanitize-html.e7147e76.js.gz +0 -0
  106. package/dist/web/public/session-lineage.js +229 -86
  107. package/dist/web/public/session-lineage.js.br +0 -0
  108. package/dist/web/public/session-lineage.js.gz +0 -0
  109. package/dist/web/public/session-ui.f731602c.js +100 -0
  110. package/dist/web/public/session-ui.f731602c.js.br +0 -0
  111. package/dist/web/public/session-ui.f731602c.js.gz +0 -0
  112. package/dist/web/public/settings-ui.a97ab16f.js +97 -0
  113. package/dist/web/public/settings-ui.a97ab16f.js.br +0 -0
  114. package/dist/web/public/settings-ui.a97ab16f.js.gz +0 -0
  115. package/dist/web/public/spreadsheet-preview-worker.js +290 -0
  116. package/dist/web/public/spreadsheet-preview-worker.js.br +0 -0
  117. package/dist/web/public/spreadsheet-preview-worker.js.gz +0 -0
  118. package/dist/web/public/spreadsheet-preview.af82fa2f.js +555 -0
  119. package/dist/web/public/spreadsheet-preview.af82fa2f.js.br +0 -0
  120. package/dist/web/public/spreadsheet-preview.af82fa2f.js.gz +0 -0
  121. package/dist/web/public/spreadsheet-xlsx-core.js +1006 -0
  122. package/dist/web/public/spreadsheet-xlsx-core.js.br +0 -0
  123. package/dist/web/public/spreadsheet-xlsx-core.js.gz +0 -0
  124. package/dist/web/public/styles.8ee12666.css +1 -0
  125. package/dist/web/public/styles.8ee12666.css.br +0 -0
  126. package/dist/web/public/styles.8ee12666.css.gz +0 -0
  127. package/dist/web/public/subagent-windows.e6ca799f.js.gz +0 -0
  128. package/dist/web/public/sw.js +2 -2
  129. package/dist/web/public/sw.js.br +0 -0
  130. package/dist/web/public/sw.js.gz +0 -0
  131. package/dist/web/public/tab-layout-browser.065fcba4.js.gz +0 -0
  132. package/dist/web/public/{tab-rail-resize.94cd59f0.js → tab-rail-resize.a5867793.js} +1 -1
  133. package/dist/web/public/tab-rail-resize.a5867793.js.br +0 -0
  134. package/dist/web/public/{tab-rail-resize.94cd59f0.js.gz → tab-rail-resize.a5867793.js.gz} +0 -0
  135. package/dist/web/public/terminal-keycode229-recovery.af09f99a.js +1 -0
  136. package/dist/web/public/terminal-keycode229-recovery.af09f99a.js.br +0 -0
  137. package/dist/web/public/terminal-keycode229-recovery.af09f99a.js.gz +0 -0
  138. package/dist/web/public/terminal-split.js +146 -649
  139. package/dist/web/public/terminal-split.js.br +0 -0
  140. package/dist/web/public/terminal-split.js.gz +0 -0
  141. package/dist/web/public/terminal-tile.js +1611 -0
  142. package/dist/web/public/terminal-tile.js.br +0 -0
  143. package/dist/web/public/terminal-tile.js.gz +0 -0
  144. package/dist/web/public/terminal-ui.5059b30e.js +2 -0
  145. package/dist/web/public/terminal-ui.5059b30e.js.br +0 -0
  146. package/dist/web/public/terminal-ui.5059b30e.js.gz +0 -0
  147. package/dist/web/public/tile-grid.js +2684 -0
  148. package/dist/web/public/tile-grid.js.br +0 -0
  149. package/dist/web/public/tile-grid.js.gz +0 -0
  150. package/dist/web/public/ultracode-panel.js.gz +0 -0
  151. package/dist/web/public/ultracode-windows.js.gz +0 -0
  152. package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
  153. package/dist/web/public/vendor/exceljs.min.js +44 -0
  154. package/dist/web/public/vendor/exceljs.min.js.br +0 -0
  155. package/dist/web/public/vendor/exceljs.min.js.gz +0 -0
  156. package/dist/web/public/vendor/fflate.min.js +1 -0
  157. package/dist/web/public/vendor/fflate.min.js.br +0 -0
  158. package/dist/web/public/vendor/fflate.min.js.gz +0 -0
  159. package/dist/web/public/vendor/marked.min.js.gz +0 -0
  160. package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
  161. package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
  162. package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
  163. package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
  164. package/dist/web/public/vendor/xterm-predictive-echo.ae5e3d5d.js.gz +0 -0
  165. package/dist/web/public/vendor/xterm-zerolag-input.bbb5f84c.js.gz +0 -0
  166. package/dist/web/public/vendor/xterm.css.gz +0 -0
  167. package/dist/web/public/vendor/xterm.min.js.gz +0 -0
  168. package/dist/web/public/{voice-input.c4b51eb6.js → voice-input.2342c37b.js} +64 -10
  169. package/dist/web/public/voice-input.2342c37b.js.br +0 -0
  170. package/dist/web/public/voice-input.2342c37b.js.gz +0 -0
  171. package/dist/web/public/voice-pcm-worklet.js.gz +0 -0
  172. package/dist/web/public/webview-tabs.js +9 -1
  173. package/dist/web/public/webview-tabs.js.br +0 -0
  174. package/dist/web/public/webview-tabs.js.gz +0 -0
  175. package/dist/web/routes/cli-registry-routes.d.ts.map +1 -1
  176. package/dist/web/routes/cli-registry-routes.js +3 -1
  177. package/dist/web/routes/cli-registry-routes.js.map +1 -1
  178. package/dist/web/routes/file-routes.d.ts +7 -0
  179. package/dist/web/routes/file-routes.d.ts.map +1 -1
  180. package/dist/web/routes/file-routes.js +34 -4
  181. package/dist/web/routes/file-routes.js.map +1 -1
  182. package/dist/web/routes/git-status-routes.d.ts.map +1 -1
  183. package/dist/web/routes/git-status-routes.js +33 -6
  184. package/dist/web/routes/git-status-routes.js.map +1 -1
  185. package/dist/web/routes/session-routes.d.ts +18 -0
  186. package/dist/web/routes/session-routes.d.ts.map +1 -1
  187. package/dist/web/routes/session-routes.js +86 -34
  188. package/dist/web/routes/session-routes.js.map +1 -1
  189. package/dist/web/routes/status-telemetry-routes.d.ts +3 -0
  190. package/dist/web/routes/status-telemetry-routes.d.ts.map +1 -1
  191. package/dist/web/routes/status-telemetry-routes.js +12 -0
  192. package/dist/web/routes/status-telemetry-routes.js.map +1 -1
  193. package/dist/web/routes/system-routes.d.ts.map +1 -1
  194. package/dist/web/routes/system-routes.js +13 -0
  195. package/dist/web/routes/system-routes.js.map +1 -1
  196. package/dist/web/schemas.d.ts +27 -0
  197. package/dist/web/schemas.d.ts.map +1 -1
  198. package/dist/web/schemas.js +34 -0
  199. package/dist/web/schemas.js.map +1 -1
  200. package/dist/web/server.d.ts +5 -0
  201. package/dist/web/server.d.ts.map +1 -1
  202. package/dist/web/server.js +32 -11
  203. package/dist/web/server.js.map +1 -1
  204. package/dist/web/session-listener-wiring.d.ts +1 -0
  205. package/dist/web/session-listener-wiring.d.ts.map +1 -1
  206. package/dist/web/session-listener-wiring.js +11 -0
  207. package/dist/web/session-listener-wiring.js.map +1 -1
  208. package/package.json +3 -1
  209. package/scripts/postinstall.js +16 -0
  210. package/dist/web/public/app.b9516c7b.js +0 -43
  211. package/dist/web/public/app.b9516c7b.js.br +0 -0
  212. package/dist/web/public/app.b9516c7b.js.gz +0 -0
  213. package/dist/web/public/constants.d95fade9.js.br +0 -0
  214. package/dist/web/public/constants.d95fade9.js.gz +0 -0
  215. package/dist/web/public/i18n.52f5b7cc.js +0 -1
  216. package/dist/web/public/i18n.52f5b7cc.js.br +0 -0
  217. package/dist/web/public/i18n.52f5b7cc.js.gz +0 -0
  218. package/dist/web/public/image-input.a216cf9e.js.br +0 -0
  219. package/dist/web/public/image-input.a216cf9e.js.gz +0 -0
  220. package/dist/web/public/mobile-handlers.23a85db1.js.br +0 -0
  221. package/dist/web/public/mobile-handlers.23a85db1.js.gz +0 -0
  222. package/dist/web/public/mobile.1aa4952d.css +0 -1
  223. package/dist/web/public/mobile.1aa4952d.css.br +0 -0
  224. package/dist/web/public/mobile.1aa4952d.css.gz +0 -0
  225. package/dist/web/public/panels-ui.6a5898d9.js.br +0 -0
  226. package/dist/web/public/session-ui.6bddf916.js +0 -89
  227. package/dist/web/public/session-ui.6bddf916.js.br +0 -0
  228. package/dist/web/public/session-ui.6bddf916.js.gz +0 -0
  229. package/dist/web/public/settings-ui.6e798b7b.js +0 -97
  230. package/dist/web/public/settings-ui.6e798b7b.js.br +0 -0
  231. package/dist/web/public/settings-ui.6e798b7b.js.gz +0 -0
  232. package/dist/web/public/styles.2d175c60.css +0 -1
  233. package/dist/web/public/styles.2d175c60.css.br +0 -0
  234. package/dist/web/public/styles.2d175c60.css.gz +0 -0
  235. package/dist/web/public/tab-rail-resize.94cd59f0.js.br +0 -0
  236. package/dist/web/public/terminal-keycode229-recovery.fb91b25b.js +0 -1
  237. package/dist/web/public/terminal-keycode229-recovery.fb91b25b.js.br +0 -0
  238. package/dist/web/public/terminal-keycode229-recovery.fb91b25b.js.gz +0 -0
  239. package/dist/web/public/terminal-ui.a4535311.js +0 -2
  240. package/dist/web/public/terminal-ui.a4535311.js.br +0 -0
  241. package/dist/web/public/terminal-ui.a4535311.js.gz +0 -0
  242. package/dist/web/public/upload.html +0 -155
  243. package/dist/web/public/upload.html.br +0 -0
  244. package/dist/web/public/upload.html.gz +0 -0
  245. package/dist/web/public/voice-input.c4b51eb6.js.br +0 -0
  246. package/dist/web/public/voice-input.c4b51eb6.js.gz +0 -0
@@ -11,7 +11,7 @@ import fs from 'node:fs/promises';
11
11
  import { randomBytes, randomUUID } from 'node:crypto';
12
12
  import { performance } from 'node:perf_hooks';
13
13
  import { ApiErrorCode, createErrorResponse, getErrorMessage, } from '../../types.js';
14
- import { Session, cliTakesSessionModel, isAltScreenStripMode, isExternalCliMode, isMuxAltScreenOnlyStripMode, } from '../../session.js';
14
+ import { Session, cliTakesSessionModel, isAltScreenStripMode, isExternalCliMode, isMuxAltScreenOnlyStripMode, isMuxMouseStripMode, } from '../../session.js';
15
15
  import { SseEvent } from '../sse-events.js';
16
16
  import { webviewCapabilities } from '../../webview-capabilities.js';
17
17
  import { CreateSessionSchema, SessionNameSchema, SessionColorSchema, RunPromptSchema, SessionInputWithLimitSchema, ResizeSchema, AutoClearSchema, AutoCompactSchema, AutoResumeSchema, PinSessionSchema, ImageWatcherSchema, FlickerFilterSchema, QuickRunSchema, QuickStartSchema, InteractiveStartSchema, SessionOrderUpdateSchema, SessionWaitQuerySchema, SessionWaitOutputQuerySchema, CustomModelSelectionSchema, } from '../schemas.js';
@@ -30,6 +30,7 @@ import { canUsernameRunPrivilegedCommands, resolveClaudeModeForUsername } from '
30
30
  import { clampEnvOverridesForOwner } from '../../session-env-clamp.js';
31
31
  import { enabledClis, getCli } from '../../config/cli-registry/registry.js';
32
32
  import { resolveCliLaunchError } from '../../utils/cli-launcher.js';
33
+ import { applyLaunchDefaults } from '../launch-defaults.js';
33
34
  import { legacyConfigForMode } from '../../session-cli-registry-bridge.js';
34
35
  import { isMultiUserMode } from '../../config/multiuser.js';
35
36
  import { AUTH_COOKIE_NAME } from '../middleware/auth.js';
@@ -88,6 +89,37 @@ const ERASE_SCROLLBACK_PATTERN = /\x1b\[3J/g;
88
89
  // strip existed can still carry them; strip on replay for parity.
89
90
  // eslint-disable-next-line no-control-regex
90
91
  const MOUSE_TRACKING_PATTERN = /\x1b\[\?(?:1000|1001|1002|1003|1005|1006|1007)[hl]/g;
92
+ /**
93
+ * The replay half of the strip parity triangle: what `_handleTerminalOutput` (session.ts)
94
+ * removes from the live stream, removed again from a stored buffer before it is replayed,
95
+ * because a buffer recorded before the live-side strip existed (or by an older server)
96
+ * still carries the sequences, and one replayed enable is enough to re-park xterm.
97
+ *
98
+ * - `strip-full` (claude/codex/gemini): alt-screen toggles, `3J` and mouse DECSETs.
99
+ * xterm obeys the toggles by switching to its scrollback-less alt buffer and wiping
100
+ * saved lines, so history disappeared on tab switch.
101
+ * - `strip-mux-and-mouse` (opencode, tmux-backed): alt-screen toggles and mouse DECSETs.
102
+ * A replayed tracking enable parks xterm in report mode, where a drag goes to the CLI
103
+ * instead of selecting text (and Ctrl+C without a selection is opencode's app_exit).
104
+ * `3J` stays: a TUI is not a `clear` consumer.
105
+ * - every other mode, tmux-backed: tmux's own client smcup only (#205).
106
+ *
107
+ * Exported so the parity with the live strip is a test (claude-scrollback-strip.test.ts).
108
+ */
109
+ export function stripReplayBuffer(buffer, mode, usesMux) {
110
+ if (isAltScreenStripMode(mode)) {
111
+ return buffer
112
+ .replace(ALT_SCREEN_TOGGLE_PATTERN, '')
113
+ .replace(ERASE_SCROLLBACK_PATTERN, '')
114
+ .replace(MOUSE_TRACKING_PATTERN, '');
115
+ }
116
+ if (isMuxMouseStripMode(mode, usesMux)) {
117
+ return buffer.replace(ALT_SCREEN_TOGGLE_PATTERN, '').replace(MOUSE_TRACKING_PATTERN, '');
118
+ }
119
+ if (isMuxAltScreenOnlyStripMode(mode, usesMux))
120
+ return buffer.replace(ALT_SCREEN_TOGGLE_PATTERN, '');
121
+ return buffer;
122
+ }
91
123
  /**
92
124
  * Strip redundant Ink spinner/status-bar redraw frames from the terminal buffer.
93
125
  * Ink (Claude Code's TUI) uses absolute cursor positioning (CSI n d = VPA) to animate
@@ -593,6 +625,20 @@ export function resolveOmpConfigForCreate(mode, workingDir, ompConfig) {
593
625
  }
594
626
  return resolvedId ? { ...ompConfig, resumeSessionId: resolvedId } : ompConfig;
595
627
  }
628
+ /**
629
+ * The tmux history lines a full capture may read (`capture-pane -S -<n>`): the
630
+ * optional `lines` query parameter, an integer of at least 1, never more than
631
+ * the configured history limit; absent or malformed, the limit itself, as
632
+ * before. A grid tile sends its own scrollback size: its xterm keeps no more
633
+ * than that, while a capture of the whole history (tens of thousands of lines,
634
+ * cut to `tail` only afterwards) is synchronous work on this event loop.
635
+ */
636
+ function captureHistoryLines(raw, historyLimit) {
637
+ if (typeof raw !== 'string' || !/^\d{1,9}$/.test(raw))
638
+ return historyLimit;
639
+ const lines = Number(raw);
640
+ return lines >= 1 ? Math.min(lines, historyLimit) : historyLimit;
641
+ }
596
642
  /**
597
643
  * `RemoteHost` → the wake registry's host shape. They differ in one field name only
598
644
  * (`id` in host config vs `hostId` on a session's `remote`), but the rename is load-
@@ -880,6 +926,10 @@ options = {}) {
880
926
  const globalNice = await ctx.getGlobalNiceConfig();
881
927
  const modelConfig = await ctx.getModelConfig();
882
928
  const mode = body.mode || 'claude';
929
+ // Synced App Settings launch defaults (capabilities.launchDefaults, codex's model and
930
+ // effort today) fill the CLI's own config object where the caller left it unset.
931
+ // Local launches only: a remote attach runs whatever the remote pane already runs.
932
+ const launchBody = remote ? body : await applyLaunchDefaults(mode, body);
883
933
  // Where a model override comes from is a capability, and the three answers are
884
934
  // genuinely different mechanisms:
885
935
  // 'flag' — the CLI takes --model, so read the value the caller sent
@@ -893,7 +943,7 @@ options = {}) {
893
943
  // (docs/deepseek-integration.md). Both get nothing.
894
944
  const modelSource = getCli(mode)?.capabilities.model;
895
945
  const model = modelSource?.source === 'flag'
896
- ? legacyConfigForMode(mode, body)?.[modelSource.param ?? 'model']
946
+ ? legacyConfigForMode(mode, launchBody)?.[modelSource.param ?? 'model']
897
947
  : modelSource?.source === 'claude-settings-file'
898
948
  ? body.model || modelConfig?.defaultModel || undefined
899
949
  : undefined;
@@ -901,7 +951,7 @@ options = {}) {
901
951
  // Section 6.3: force non-granted users to a classifier-guarded mode.
902
952
  const effectiveClaudeMode = await resolveClaudeModeForUsername(claudeModeConfig.claudeMode, owner);
903
953
  // Section 6.3: clamp Codex/Gemini/Antigravity bypass switches for a non-granted owner (no-op single-user/granted).
904
- const { codexConfig: gatedCodexConfig, geminiConfig: gatedGeminiConfig, antigravityConfig: gatedAntigravityConfig, piConfig: gatedPiConfig, grokConfig: gatedGrokConfig, deepSeekConfig: gatedDeepSeekConfig, } = await _clampExternalCliBypassForOwner(owner, body.codexConfig, body.geminiConfig, body.antigravityConfig, body.piConfig, body.grokConfig, body.deepSeekConfig);
954
+ const { codexConfig: gatedCodexConfig, geminiConfig: gatedGeminiConfig, antigravityConfig: gatedAntigravityConfig, piConfig: gatedPiConfig, grokConfig: gatedGrokConfig, deepSeekConfig: gatedDeepSeekConfig, } = await _clampExternalCliBypassForOwner(owner, launchBody.codexConfig, launchBody.geminiConfig, launchBody.antigravityConfig, launchBody.piConfig, launchBody.grokConfig, launchBody.deepSeekConfig);
905
955
  const terminalHistoryConfig = await ctx.getTerminalHistoryConfig();
906
956
  const session = new Session({
907
957
  workingDir,
@@ -913,14 +963,14 @@ options = {}) {
913
963
  model,
914
964
  claudeMode: effectiveClaudeMode,
915
965
  allowedTools: claudeModeConfig.allowedTools,
916
- openCodeConfig: mode === 'opencode' ? body.openCodeConfig : undefined,
966
+ openCodeConfig: mode === 'opencode' ? launchBody.openCodeConfig : undefined,
917
967
  codexConfig: mode === 'codex' ? gatedCodexConfig : undefined,
918
968
  geminiConfig: mode === 'gemini' ? gatedGeminiConfig : undefined,
919
969
  antigravityConfig: mode === 'antigravity' ? gatedAntigravityConfig : undefined,
920
970
  piConfig: mode === 'pi' ? gatedPiConfig : undefined,
921
971
  grokConfig: mode === 'grok' ? gatedGrokConfig : undefined,
922
972
  deepSeekConfig: mode === 'deepseek' ? gatedDeepSeekConfig : undefined,
923
- ompConfig: resolveOmpConfigForCreate(mode, workingDir, body.ompConfig),
973
+ ompConfig: resolveOmpConfigForCreate(mode, workingDir, launchBody.ompConfig),
924
974
  resumeSessionId: validatedResumeId,
925
975
  envOverrides: await clampEnvOverridesForOwner(owner, body.envOverrides),
926
976
  effort: body.effort,
@@ -2594,8 +2644,14 @@ options = {}) {
2594
2644
  // single reason: `capturedGeometry` comes BACK on it, and the response has
2595
2645
  // to tell the client what size the frame it is about to render was built
2596
2646
  // for. See PaneCaptureOptions.capturedGeometry.
2647
+ // `lines` bounds only the history a FULL capture reads; the visible-frame
2648
+ // path reads no history and is untouched by it.
2597
2649
  const captureOpts = isFullReload
2598
- ? { fullHistory: true, historyLimitLines: tmuxHistoryLimit, maxCaptureBytes: terminalBufferMaxBytes }
2650
+ ? {
2651
+ fullHistory: true,
2652
+ historyLimitLines: captureHistoryLines(query.lines, tmuxHistoryLimit),
2653
+ maxCaptureBytes: terminalBufferMaxBytes,
2654
+ }
2599
2655
  : {};
2600
2656
  const liveMuxBuffer = muxName && typeof ctx.mux.captureActivePaneBuffer === 'function'
2601
2657
  ? ctx.mux.captureActivePaneBuffer(muxName, captureOpts)
@@ -2667,22 +2723,9 @@ options = {}) {
2667
2723
  let strippedBuffer = isFullCapture || getCli(session.mode)?.capabilities.stripInkBloat === false
2668
2724
  ? rawBuffer
2669
2725
  : stripInkRedrawBloat(rawBuffer);
2670
- // Strip alt-screen toggles and scrollback-erase from Codex/Claude byte
2671
- // streams. xterm.js obeys them by switching to its scrollback-less alt
2672
- // buffer and wiping saved lines, so conversation history disappears on tab
2673
- // switch. Same gate as the live-stream strip in session.ts.
2674
- if (isAltScreenStripMode(session.mode)) {
2675
- strippedBuffer = strippedBuffer
2676
- .replace(ALT_SCREEN_TOGGLE_PATTERN, '')
2677
- .replace(ERASE_SCROLLBACK_PATTERN, '')
2678
- .replace(MOUSE_TRACKING_PATTERN, '');
2679
- }
2680
- else if (isMuxAltScreenOnlyStripMode(session.mode, session.usesMux)) {
2681
- // tmux-backed shell/opencode/antigravity: drop tmux's own client smcup only.
2682
- // A byte buffer recorded before the live-side strip existed can still carry
2683
- // it, and one replayed `\x1b[?1049h` re-parks xterm in the alt buffer (#205).
2684
- strippedBuffer = strippedBuffer.replace(ALT_SCREEN_TOGGLE_PATTERN, '');
2685
- }
2726
+ // Same strip as the live stream (session.ts), so a buffer recorded before the
2727
+ // live-side strip existed cannot re-park xterm on replay. See stripReplayBuffer.
2728
+ strippedBuffer = stripReplayBuffer(strippedBuffer, session.mode, session.usesMux);
2686
2729
  if (tailBytes > 0 && strippedBuffer.length > tailBytes) {
2687
2730
  // Fast path: tail from the end, skip expensive banner search on full 2MB buffer.
2688
2731
  // Banner is near the top and gets discarded by tail anyway.
@@ -3295,28 +3338,37 @@ options = {}) {
3295
3338
  // Apply global Nice priority config and model config from settings
3296
3339
  const niceConfig = await ctx.getGlobalNiceConfig();
3297
3340
  const qsModelConfig = await ctx.getModelConfig();
3341
+ // Synced App Settings launch defaults, as on the create path: local launches only, so
3342
+ // never a remote or Docker case, and never a custom model endpoint launch.
3343
+ const qsRequestConfigs = {
3344
+ openCodeConfig,
3345
+ codexConfig,
3346
+ geminiConfig,
3347
+ antigravityConfig,
3348
+ piConfig,
3349
+ grokConfig,
3350
+ deepSeekConfig,
3351
+ ompConfig,
3352
+ };
3353
+ const qsLaunchConfigs = remote || docker ? qsRequestConfigs : await applyLaunchDefaults(mode, qsRequestConfigs, !!customModel);
3354
+ // ⚠️ The model is read from a bag WITHOUT ompConfig, as it always was here: quick-start
3355
+ // has never taken omp's session model from ompConfig (the create path does). Kept as
3356
+ // found rather than changed in passing.
3357
+ const { ompConfig: qsLaunchOmpConfig, ...qsModelConfigs } = qsLaunchConfigs;
3298
3358
  // See the create path for why this is a capability rather than a mode ladder.
3299
3359
  const qsModelSource = getCli(mode)?.capabilities.model;
3300
3360
  const qsModel = qsModelSource?.source === 'flag'
3301
- ? legacyConfigForMode(mode, {
3302
- openCodeConfig,
3303
- codexConfig,
3304
- geminiConfig,
3305
- antigravityConfig,
3306
- piConfig,
3307
- grokConfig,
3308
- deepSeekConfig,
3309
- })?.[qsModelSource.param ?? 'model']
3361
+ ? legacyConfigForMode(mode, qsModelConfigs)?.[qsModelSource.param ?? 'model']
3310
3362
  : qsModelSource?.source === 'claude-settings-file'
3311
3363
  ? qsModelConfig?.defaultModel || undefined
3312
3364
  : undefined;
3313
3365
  const qsClaudeModeConfig = await ctx.getClaudeModeConfig();
3314
3366
  const qsEffectiveClaudeMode = await resolveClaudeModeForUsername(qsClaudeModeConfig.claudeMode, owner);
3315
3367
  // Section 6.3: clamp Codex/Gemini/Antigravity bypass switches for a non-granted owner (no-op single-user/granted).
3316
- const { codexConfig: qsGatedCodexConfig, geminiConfig: qsGatedGeminiConfig, antigravityConfig: qsGatedAntigravityConfig, piConfig: qsGatedPiConfig, grokConfig: qsGatedGrokConfig, deepSeekConfig: qsGatedDeepSeekConfig, } = await _clampExternalCliBypassForOwner(owner, codexConfig, geminiConfig, antigravityConfig, piConfig, grokConfig, deepSeekConfig);
3368
+ const { codexConfig: qsGatedCodexConfig, geminiConfig: qsGatedGeminiConfig, antigravityConfig: qsGatedAntigravityConfig, piConfig: qsGatedPiConfig, grokConfig: qsGatedGrokConfig, deepSeekConfig: qsGatedDeepSeekConfig, } = await _clampExternalCliBypassForOwner(owner, qsLaunchConfigs.codexConfig, qsLaunchConfigs.geminiConfig, qsLaunchConfigs.antigravityConfig, qsLaunchConfigs.piConfig, qsLaunchConfigs.grokConfig, qsLaunchConfigs.deepSeekConfig);
3317
3369
  const qsTerminalHistoryConfig = await ctx.getTerminalHistoryConfig();
3318
3370
  const qsGatedEnvOverrides = await clampEnvOverridesForOwner(owner, envOverrides);
3319
- const qsResolvedOmpConfig = resolveOmpConfigForCreate(mode, resolvedCasePath, ompConfig);
3371
+ const qsResolvedOmpConfig = resolveOmpConfigForCreate(mode, resolvedCasePath, qsLaunchOmpConfig);
3320
3372
  // Custom Model Endpoint Profiles, applied AT CREATE TIME (docs/custom-model-endpoints-plan.md)
3321
3373
  // rather than via the dedicated restart-in-place route (POST /api/sessions/:id/custom-
3322
3374
  // model, still what an ALREADY-RUNNING session uses to switch later): computing the
@@ -3442,7 +3494,7 @@ options = {}) {
3442
3494
  claudeMode: qsEffectiveClaudeMode,
3443
3495
  allowedTools: qsClaudeModeConfig.allowedTools,
3444
3496
  owner,
3445
- openCodeConfig: mode === 'opencode' ? openCodeConfig : undefined,
3497
+ openCodeConfig: mode === 'opencode' ? qsLaunchConfigs.openCodeConfig : undefined,
3446
3498
  codexConfig: mode === 'codex' ? qsGatedCodexConfig : undefined,
3447
3499
  geminiConfig: mode === 'gemini' ? qsGatedGeminiConfig : undefined,
3448
3500
  antigravityConfig: mode === 'antigravity' ? qsGatedAntigravityConfig : undefined,