aicodeman 1.9.6 → 1.9.7

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 (126) hide show
  1. package/dist/config/dependency-registry.d.ts.map +1 -1
  2. package/dist/config/dependency-registry.js +8 -0
  3. package/dist/config/dependency-registry.js.map +1 -1
  4. package/dist/docker-hosts.d.ts.map +1 -1
  5. package/dist/docker-hosts.js +1 -0
  6. package/dist/docker-hosts.js.map +1 -1
  7. package/dist/mux-interface.d.ts +3 -1
  8. package/dist/mux-interface.d.ts.map +1 -1
  9. package/dist/remote-hosts.d.ts.map +1 -1
  10. package/dist/remote-hosts.js +1 -0
  11. package/dist/remote-hosts.js.map +1 -1
  12. package/dist/session.d.ts +6 -1
  13. package/dist/session.d.ts.map +1 -1
  14. package/dist/session.js +18 -3
  15. package/dist/session.js.map +1 -1
  16. package/dist/tmux-manager.d.ts +2 -1
  17. package/dist/tmux-manager.d.ts.map +1 -1
  18. package/dist/tmux-manager.js +46 -5
  19. package/dist/tmux-manager.js.map +1 -1
  20. package/dist/types/session.d.ts +16 -4
  21. package/dist/types/session.d.ts.map +1 -1
  22. package/dist/types/session.js +2 -1
  23. package/dist/types/session.js.map +1 -1
  24. package/dist/utils/antigravity-cli-resolver.d.ts +20 -0
  25. package/dist/utils/antigravity-cli-resolver.d.ts.map +1 -0
  26. package/dist/utils/antigravity-cli-resolver.js +60 -0
  27. package/dist/utils/antigravity-cli-resolver.js.map +1 -0
  28. package/dist/utils/index.d.ts +1 -0
  29. package/dist/utils/index.d.ts.map +1 -1
  30. package/dist/utils/index.js +1 -0
  31. package/dist/utils/index.js.map +1 -1
  32. package/dist/web/public/admin-ui.js.gz +0 -0
  33. package/dist/web/public/api-client.c9b1cddc.js.gz +0 -0
  34. package/dist/web/public/{app.adc992cd.js → app.5805dde4.js} +6 -6
  35. package/dist/web/public/app.5805dde4.js.br +0 -0
  36. package/dist/web/public/app.5805dde4.js.gz +0 -0
  37. package/dist/web/public/constants.e7175b95.js.gz +0 -0
  38. package/dist/web/public/cron-ui.js.gz +0 -0
  39. package/dist/web/public/entrance-animations.js +754 -0
  40. package/dist/web/public/entrance-animations.js.br +0 -0
  41. package/dist/web/public/entrance-animations.js.gz +0 -0
  42. package/dist/web/public/i18n.04d07c98.js +1 -0
  43. package/dist/web/public/i18n.04d07c98.js.br +0 -0
  44. package/dist/web/public/i18n.04d07c98.js.gz +0 -0
  45. package/dist/web/public/image-input.ee16ad88.js.gz +0 -0
  46. package/dist/web/public/index.html +28 -9
  47. package/dist/web/public/index.html.br +0 -0
  48. package/dist/web/public/index.html.gz +0 -0
  49. package/dist/web/public/input-cjk.63794d0b.js.gz +0 -0
  50. package/dist/web/public/keyboard-accessory.9936227d.js.gz +0 -0
  51. package/dist/web/public/mobile-handlers.bc2b8c1d.js.gz +0 -0
  52. package/dist/web/public/mobile.f8466b0a.css +1 -0
  53. package/dist/web/public/mobile.f8466b0a.css.br +0 -0
  54. package/dist/web/public/mobile.f8466b0a.css.gz +0 -0
  55. package/dist/web/public/notification-manager.5d229063.js.gz +0 -0
  56. package/dist/web/public/orchestrator-panel.js.gz +0 -0
  57. package/dist/web/public/{panels-ui.3910e1e2.js → panels-ui.600881ae.js} +17 -17
  58. package/dist/web/public/panels-ui.600881ae.js.br +0 -0
  59. package/dist/web/public/panels-ui.600881ae.js.gz +0 -0
  60. package/dist/web/public/ralph-panel.6de2d0f8.js.gz +0 -0
  61. package/dist/web/public/ralph-wizard.13a1831e.js.gz +0 -0
  62. package/dist/web/public/respawn-ui.2d249da9.js.gz +0 -0
  63. package/dist/web/public/sanitize-html.bc7078d6.js.gz +0 -0
  64. package/dist/web/public/{session-ui.2d3541c6.js → session-ui.aab84498.js} +3 -3
  65. package/dist/web/public/session-ui.aab84498.js.br +0 -0
  66. package/dist/web/public/session-ui.aab84498.js.gz +0 -0
  67. package/dist/web/public/{settings-ui.08c08e71.js → settings-ui.1e126e75.js} +1 -1
  68. package/dist/web/public/settings-ui.1e126e75.js.br +0 -0
  69. package/dist/web/public/settings-ui.1e126e75.js.gz +0 -0
  70. package/dist/web/public/styles.7e638f69.css +1 -0
  71. package/dist/web/public/styles.7e638f69.css.br +0 -0
  72. package/dist/web/public/styles.7e638f69.css.gz +0 -0
  73. package/dist/web/public/{subagent-windows.69b60c35.js → subagent-windows.4cc8b005.js} +27 -3
  74. package/dist/web/public/subagent-windows.4cc8b005.js.br +0 -0
  75. package/dist/web/public/subagent-windows.4cc8b005.js.gz +0 -0
  76. package/dist/web/public/sw.js.gz +0 -0
  77. package/dist/web/public/terminal-ui.f3a51974.js.gz +0 -0
  78. package/dist/web/public/ultracode-panel.js.gz +0 -0
  79. package/dist/web/public/ultracode-windows.js +4 -0
  80. package/dist/web/public/ultracode-windows.js.br +0 -0
  81. package/dist/web/public/ultracode-windows.js.gz +0 -0
  82. package/dist/web/public/upload.html.gz +0 -0
  83. package/dist/web/public/vendor/dompurify.min.js.gz +0 -0
  84. package/dist/web/public/vendor/marked.min.js.gz +0 -0
  85. package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
  86. package/dist/web/public/vendor/xterm-addon-serialize.min.js.gz +0 -0
  87. package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
  88. package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
  89. package/dist/web/public/vendor/xterm-zerolag-input.137ad9f0.js.gz +0 -0
  90. package/dist/web/public/vendor/xterm.css.gz +0 -0
  91. package/dist/web/public/vendor/xterm.min.js.gz +0 -0
  92. package/dist/web/public/voice-input.085e9e73.js.gz +0 -0
  93. package/dist/web/public/webview-tabs.js.gz +0 -0
  94. package/dist/web/routes/session-routes.d.ts.map +1 -1
  95. package/dist/web/routes/session-routes.js +59 -25
  96. package/dist/web/routes/session-routes.js.map +1 -1
  97. package/dist/web/routes/system-routes.d.ts.map +1 -1
  98. package/dist/web/routes/system-routes.js +9 -1
  99. package/dist/web/routes/system-routes.js.map +1 -1
  100. package/dist/web/schemas.d.ts +16 -0
  101. package/dist/web/schemas.d.ts.map +1 -1
  102. package/dist/web/schemas.js +24 -5
  103. package/dist/web/schemas.js.map +1 -1
  104. package/dist/web/server.d.ts.map +1 -1
  105. package/dist/web/server.js +1 -0
  106. package/dist/web/server.js.map +1 -1
  107. package/package.json +1 -1
  108. package/dist/web/public/app.adc992cd.js.br +0 -0
  109. package/dist/web/public/app.adc992cd.js.gz +0 -0
  110. package/dist/web/public/i18n.4dcf1b87.js +0 -1
  111. package/dist/web/public/i18n.4dcf1b87.js.br +0 -0
  112. package/dist/web/public/i18n.4dcf1b87.js.gz +0 -0
  113. package/dist/web/public/mobile.40e2d64e.css +0 -1
  114. package/dist/web/public/mobile.40e2d64e.css.br +0 -0
  115. package/dist/web/public/mobile.40e2d64e.css.gz +0 -0
  116. package/dist/web/public/panels-ui.3910e1e2.js.br +0 -0
  117. package/dist/web/public/panels-ui.3910e1e2.js.gz +0 -0
  118. package/dist/web/public/session-ui.2d3541c6.js.br +0 -0
  119. package/dist/web/public/session-ui.2d3541c6.js.gz +0 -0
  120. package/dist/web/public/settings-ui.08c08e71.js.br +0 -0
  121. package/dist/web/public/settings-ui.08c08e71.js.gz +0 -0
  122. package/dist/web/public/styles.30e64547.css +0 -1
  123. package/dist/web/public/styles.30e64547.css.br +0 -0
  124. package/dist/web/public/styles.30e64547.css.gz +0 -0
  125. package/dist/web/public/subagent-windows.69b60c35.js.br +0 -0
  126. package/dist/web/public/subagent-windows.69b60c35.js.gz +0 -0
@@ -210,6 +210,9 @@ Object.assign(CodemanApp.prototype, {
210
210
  document.body.appendChild(win);
211
211
  // Drop the spawn class on the next frame so the transition runs.
212
212
  requestAnimationFrame(() => win.classList.remove('spawning'));
213
+ // Then hand over to the chosen entrance style (no-op for `fly`/`off`, which
214
+ // leave the small scale-in transition above as the whole animation).
215
+ this.applyWindowEntrance?.(win);
213
216
 
214
217
  const header = win.querySelector('.ultracode-window-header');
215
218
  const dragListeners = this.makeWindowDraggable(win, header);
@@ -586,6 +589,7 @@ Object.assign(CodemanApp.prototype, {
586
589
 
587
590
  document.body.appendChild(win);
588
591
  requestAnimationFrame(() => win.classList.remove('spawning'));
592
+ this.applyWindowEntrance?.(win);
589
593
 
590
594
  const header = win.querySelector('.ultracode-window-header');
591
595
  const dragListeners = this.makeWindowDraggable(win, header);
Binary file
Binary file
Binary file
@@ -1 +1 @@
1
- {"version":3,"file":"session-routes.d.ts","sourceRoot":"","sources":["../../../src/web/routes/session-routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA4E1C,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AA+DjG;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA0C1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAmCvE;AAWD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,OAAO,CAiBhF;AAGD,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAyBD,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAC/D,IAAI,CAisFN"}
1
+ {"version":3,"file":"session-routes.d.ts","sourceRoot":"","sources":["../../../src/web/routes/session-routes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA6E1C,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AA+DjG;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA0C1D;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAmCvE;AAWD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,MAAmB,GAAG,OAAO,CAiBhF;AAGD,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAmCD,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,WAAW,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GAC/D,IAAI,CAwuFN"}
@@ -201,22 +201,27 @@ export function _resetPasteRateBuckets() {
201
201
  }
202
202
  /**
203
203
  * Security (multi-user §6.3): the Claude-only permission-mode downgrade does not
204
- * cover the other CLIs' bypass switches. Codex `--dangerously-bypass-approvals-and-sandbox`
205
- * and Gemini `--approval-mode yolo` disable the safety classifier the non-granted-user
206
- * downgrade is meant to keep on, so clamp them for a non-granted owner. buildGeminiCommand
207
- * defaults an ABSENT approvalMode to yolo, so the gemini config must be MATERIALIZED
208
- * (auto_edit) even when the request sent none. No-op in single-user mode / for a granted
204
+ * cover the other CLIs' bypass switches. Codex `--dangerously-bypass-approvals-and-sandbox`,
205
+ * Gemini `--approval-mode yolo`, and Antigravity `--dangerously-skip-permissions` disable
206
+ * the safety classifier the non-granted-user downgrade is meant to keep on, so clamp them
207
+ * for a non-granted owner. buildGeminiCommand defaults an ABSENT approvalMode to yolo, so
208
+ * the gemini config must be MATERIALIZED (auto_edit) even when the request sent none.
209
+ * Antigravity is like Codex: an ABSENT config already defaults safe (no bypass flag), so
210
+ * only a sent config needs the flag forced off. No-op in single-user mode / for a granted
209
211
  * owner (canUsernameRunPrivilegedCommands returns true when !isMultiUserMode()).
210
212
  */
211
- async function clampExternalCliBypassForOwner(owner, codexConfig, geminiConfig) {
213
+ async function clampExternalCliBypassForOwner(owner, codexConfig, geminiConfig, antigravityConfig) {
212
214
  const granted = await canUsernameRunPrivilegedCommands(owner);
213
215
  if (granted)
214
- return { codexConfig, geminiConfig };
215
- // Non-granted: force codex bypass off (only meaningful when a config was sent) and
216
- // materialize gemini to auto_edit (clamps an explicit 'yolo' and the yolo default).
216
+ return { codexConfig, geminiConfig, antigravityConfig };
217
+ // Non-granted: force codex/antigravity bypass off (only meaningful when a config was
218
+ // sent) and materialize gemini to auto_edit (clamps an explicit 'yolo' and the yolo default).
217
219
  const clampedCodex = codexConfig ? { ...codexConfig, dangerouslyBypassApprovals: false } : codexConfig;
218
220
  const clampedGemini = { ...(geminiConfig ?? {}), approvalMode: 'auto_edit' };
219
- return { codexConfig: clampedCodex, geminiConfig: clampedGemini };
221
+ const clampedAntigravity = antigravityConfig
222
+ ? { ...antigravityConfig, dangerouslySkipPermissions: false }
223
+ : antigravityConfig;
224
+ return { codexConfig: clampedCodex, geminiConfig: clampedGemini, antigravityConfig: clampedAntigravity };
220
225
  }
221
226
  export function registerSessionRoutes(app, ctx) {
222
227
  // ═══════════════════════════════════════════════════════════════
@@ -315,6 +320,7 @@ export function registerSessionRoutes(app, ctx) {
315
320
  const canStripDisk = body.mode !== 'opencode' &&
316
321
  body.mode !== 'codex' &&
317
322
  body.mode !== 'gemini' &&
323
+ body.mode !== 'antigravity' &&
318
324
  body.envOverrides &&
319
325
  Object.keys(body.envOverrides).length > 0 &&
320
326
  (workingDir.startsWith(CASES_DIR + '/') || workingDir.startsWith(managedCasesBase + '/'));
@@ -366,6 +372,12 @@ export function registerSessionRoutes(app, ctx) {
366
372
  return createErrorResponse(ApiErrorCode.OPERATION_FAILED, 'Gemini CLI not found. Install with: npm install -g @google/gemini-cli');
367
373
  }
368
374
  }
375
+ if (body.mode === 'antigravity') {
376
+ const { isAntigravityAvailable } = await import('../../utils/antigravity-cli-resolver.js');
377
+ if (!isAntigravityAvailable()) {
378
+ return createErrorResponse(ApiErrorCode.OPERATION_FAILED, 'Antigravity CLI not found. Install with: curl -fsSL https://antigravity.google/cli/install.sh | bash');
379
+ }
380
+ }
369
381
  // Pre-validate resumeSessionId: check that the conversation file actually exists
370
382
  // in Claude's projects directory. If not, skip resume to avoid confusing
371
383
  // "No conversation found" errors from Claude CLI.
@@ -406,14 +418,16 @@ export function registerSessionRoutes(app, ctx) {
406
418
  ? body.codexConfig?.model
407
419
  : mode === 'gemini'
408
420
  ? body.geminiConfig?.model
409
- : mode !== 'shell'
410
- ? modelConfig?.defaultModel || undefined
411
- : undefined;
421
+ : mode === 'antigravity'
422
+ ? body.antigravityConfig?.model
423
+ : mode !== 'shell'
424
+ ? modelConfig?.defaultModel || undefined
425
+ : undefined;
412
426
  const claudeModeConfig = await ctx.getClaudeModeConfig();
413
427
  // Section 6.3: force non-granted users to a classifier-guarded mode.
414
428
  const effectiveClaudeMode = await resolveClaudeModeForUsername(claudeModeConfig.claudeMode, owner);
415
- // Section 6.3: clamp Codex/Gemini bypass switches for a non-granted owner (no-op single-user/granted).
416
- const { codexConfig: gatedCodexConfig, geminiConfig: gatedGeminiConfig } = await clampExternalCliBypassForOwner(owner, body.codexConfig, body.geminiConfig);
429
+ // Section 6.3: clamp Codex/Gemini/Antigravity bypass switches for a non-granted owner (no-op single-user/granted).
430
+ const { codexConfig: gatedCodexConfig, geminiConfig: gatedGeminiConfig, antigravityConfig: gatedAntigravityConfig, } = await clampExternalCliBypassForOwner(owner, body.codexConfig, body.geminiConfig, body.antigravityConfig);
417
431
  const terminalHistoryConfig = await ctx.getTerminalHistoryConfig();
418
432
  const session = new Session({
419
433
  workingDir,
@@ -428,6 +442,7 @@ export function registerSessionRoutes(app, ctx) {
428
442
  openCodeConfig: mode === 'opencode' ? body.openCodeConfig : undefined,
429
443
  codexConfig: mode === 'codex' ? gatedCodexConfig : undefined,
430
444
  geminiConfig: mode === 'gemini' ? gatedGeminiConfig : undefined,
445
+ antigravityConfig: mode === 'antigravity' ? gatedAntigravityConfig : undefined,
431
446
  resumeSessionId: validatedResumeId,
432
447
  envOverrides: body.envOverrides,
433
448
  effort: body.effort,
@@ -596,10 +611,11 @@ export function registerSessionRoutes(app, ctx) {
596
611
  }
597
612
  try {
598
613
  // Auto-detect completion phrase from CLAUDE.md BEFORE starting (only if globally enabled and not explicitly disabled by user)
599
- // Ralph tracker is not supported for opencode / codex / gemini sessions
614
+ // Ralph tracker is not supported for opencode / codex / gemini / antigravity sessions
600
615
  if (session.mode !== 'opencode' &&
601
616
  session.mode !== 'codex' &&
602
617
  session.mode !== 'gemini' &&
618
+ session.mode !== 'antigravity' &&
603
619
  ctx.store.getConfig().ralphEnabled &&
604
620
  !session.ralphTracker.autoEnableDisabled) {
605
621
  autoConfigureRalph(session, session.workingDir, ctx);
@@ -1648,7 +1664,7 @@ export function registerSessionRoutes(app, ctx) {
1648
1664
  const capMsg = sessionCapacityMessage(ctx.sessions, owner);
1649
1665
  if (capMsg)
1650
1666
  return createErrorResponse(ApiErrorCode.SESSION_BUSY, capMsg);
1651
- const { caseName = 'testcase', sessionName, mode = 'claude', modelOverride, openCodeConfig, codexConfig, geminiConfig, envOverrides, effort, } = parseBody(QuickStartSchema, req.body);
1667
+ const { caseName = 'testcase', sessionName, mode = 'claude', modelOverride, openCodeConfig, codexConfig, geminiConfig, antigravityConfig, envOverrides, effort, } = parseBody(QuickStartSchema, req.body);
1652
1668
  // Multi-user: shell mode is arbitrary host-account execution, gated by the grant.
1653
1669
  // Resolve the owner's grant from the store so a GRANTED regular user is not wrongly denied.
1654
1670
  if (mode === 'shell' && !(await canUsernameRunPrivilegedCommands(owner))) {
@@ -1684,6 +1700,7 @@ export function registerSessionRoutes(app, ctx) {
1684
1700
  modelOverride !== undefined ||
1685
1701
  codexConfig ||
1686
1702
  geminiConfig ||
1703
+ antigravityConfig ||
1687
1704
  openCodeConfig) {
1688
1705
  return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'envOverrides, effort, modelOverride, and per-CLI config are not supported for remote cases (they do not cross ssh). Configure the remote command via the host command override instead.');
1689
1706
  }
@@ -1709,6 +1726,7 @@ export function registerSessionRoutes(app, ctx) {
1709
1726
  effort ||
1710
1727
  codexConfig ||
1711
1728
  geminiConfig ||
1729
+ antigravityConfig ||
1712
1730
  openCodeConfig) {
1713
1731
  return createErrorResponse(ApiErrorCode.INVALID_INPUT, 'envOverrides, effort, and per-CLI config are not supported for docker cases (they do not cross into the container). Configure the container via the docker host command override instead.');
1714
1732
  }
@@ -1777,6 +1795,13 @@ export function registerSessionRoutes(app, ctx) {
1777
1795
  return createErrorResponse(ApiErrorCode.OPERATION_FAILED, 'Gemini CLI not found. Install with: npm install -g @google/gemini-cli');
1778
1796
  }
1779
1797
  }
1798
+ // Check Antigravity availability if requested
1799
+ if (mode === 'antigravity') {
1800
+ const { isAntigravityAvailable } = await import('../../utils/antigravity-cli-resolver.js');
1801
+ if (!isAntigravityAvailable()) {
1802
+ return createErrorResponse(ApiErrorCode.OPERATION_FAILED, 'Antigravity CLI not found. Install with: curl -fsSL https://antigravity.google/cli/install.sh | bash');
1803
+ }
1804
+ }
1780
1805
  // Resolve case path: check linked-cases registry first, then fall back to CASES_DIR.
1781
1806
  // This mirrors the behaviour of resolveCasePath() in case-routes so that linked
1782
1807
  // external project directories are honoured by quick-start just like regular case routes.
@@ -1819,8 +1844,8 @@ export function registerSessionRoutes(app, ctx) {
1819
1844
  const claudeMd = generateClaudeMd(caseName, '', templatePath);
1820
1845
  writeFileSync(join(resolvedCasePath, 'CLAUDE.md'), claudeMd);
1821
1846
  // Write .claude/settings.local.json with hooks for desktop notifications
1822
- // (Claude-specific — OpenCode, Codex, and Gemini use their own systems)
1823
- if (mode !== 'opencode' && mode !== 'codex' && mode !== 'gemini') {
1847
+ // (Claude-specific — OpenCode, Codex, Gemini, and Antigravity use their own systems)
1848
+ if (mode !== 'opencode' && mode !== 'codex' && mode !== 'gemini' && mode !== 'antigravity') {
1824
1849
  await writeHooksConfig(resolvedCasePath);
1825
1850
  }
1826
1851
  ctx.broadcast(SseEvent.CaseCreated, { name: caseName, path: resolvedCasePath });
@@ -1840,7 +1865,12 @@ export function registerSessionRoutes(app, ctx) {
1840
1865
  // Scaffold hooks (+ a CLAUDE.md) if MISSING so in-container permission prompts and
1841
1866
  // hook-idle detection fire (decision: wire hooks now). Never clobbers an existing
1842
1867
  // configured project. Skipped for external CLIs (they use their own systems).
1843
- if (docker && docker.hooksEnabled && mode !== 'opencode' && mode !== 'codex' && mode !== 'gemini') {
1868
+ if (docker &&
1869
+ docker.hooksEnabled &&
1870
+ mode !== 'opencode' &&
1871
+ mode !== 'codex' &&
1872
+ mode !== 'gemini' &&
1873
+ mode !== 'antigravity') {
1844
1874
  try {
1845
1875
  if (!existsSync(join(resolvedCasePath, 'CLAUDE.md'))) {
1846
1876
  const templatePath = await ctx.getDefaultClaudeMdPath();
@@ -1868,6 +1898,7 @@ export function registerSessionRoutes(app, ctx) {
1868
1898
  if (mode !== 'opencode' &&
1869
1899
  mode !== 'codex' &&
1870
1900
  mode !== 'gemini' &&
1901
+ mode !== 'antigravity' &&
1871
1902
  !remote &&
1872
1903
  envOverrides &&
1873
1904
  Object.keys(envOverrides).length > 0) {
@@ -1883,13 +1914,15 @@ export function registerSessionRoutes(app, ctx) {
1883
1914
  ? codexConfig?.model
1884
1915
  : mode === 'gemini'
1885
1916
  ? geminiConfig?.model
1886
- : mode !== 'shell'
1887
- ? qsModelConfig?.defaultModel || undefined
1888
- : undefined;
1917
+ : mode === 'antigravity'
1918
+ ? antigravityConfig?.model
1919
+ : mode !== 'shell'
1920
+ ? qsModelConfig?.defaultModel || undefined
1921
+ : undefined;
1889
1922
  const qsClaudeModeConfig = await ctx.getClaudeModeConfig();
1890
1923
  const qsEffectiveClaudeMode = await resolveClaudeModeForUsername(qsClaudeModeConfig.claudeMode, owner);
1891
- // Section 6.3: clamp Codex/Gemini bypass switches for a non-granted owner (no-op single-user/granted).
1892
- const { codexConfig: qsGatedCodexConfig, geminiConfig: qsGatedGeminiConfig } = await clampExternalCliBypassForOwner(owner, codexConfig, geminiConfig);
1924
+ // Section 6.3: clamp Codex/Gemini/Antigravity bypass switches for a non-granted owner (no-op single-user/granted).
1925
+ const { codexConfig: qsGatedCodexConfig, geminiConfig: qsGatedGeminiConfig, antigravityConfig: qsGatedAntigravityConfig, } = await clampExternalCliBypassForOwner(owner, codexConfig, geminiConfig, antigravityConfig);
1893
1926
  const qsTerminalHistoryConfig = await ctx.getTerminalHistoryConfig();
1894
1927
  const session = new Session({
1895
1928
  workingDir: resolvedCasePath,
@@ -1905,6 +1938,7 @@ export function registerSessionRoutes(app, ctx) {
1905
1938
  openCodeConfig: mode === 'opencode' ? openCodeConfig : undefined,
1906
1939
  codexConfig: mode === 'codex' ? qsGatedCodexConfig : undefined,
1907
1940
  geminiConfig: mode === 'gemini' ? qsGatedGeminiConfig : undefined,
1941
+ antigravityConfig: mode === 'antigravity' ? qsGatedAntigravityConfig : undefined,
1908
1942
  envOverrides,
1909
1943
  effort,
1910
1944
  remote,