specrails-desktop 2.60.0 → 2.62.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 (190) hide show
  1. package/client/dist/assets/ActivityFeedPage-C_pqc281.js +1 -0
  2. package/client/dist/assets/{AgentBrowserCapture-D4a3wYM1.js → AgentBrowserCapture-vz6rbDtu.js} +1 -1
  3. package/client/dist/assets/AgentModeAnalyticsPane-BHCcUahS.js +2 -0
  4. package/client/dist/assets/AgentModeCodePane-DhmxgG3W.js +2 -0
  5. package/client/dist/assets/{AgentModeJobsPane-25tQlLpF.js → AgentModeJobsPane-99fBBLri.js} +1 -1
  6. package/client/dist/assets/{AgentsPage-CUDp_sfw.js → AgentsPage-CTwm_6T8.js} +3 -3
  7. package/client/dist/assets/{AnalyticsPage-DXWMGn8b.js → AnalyticsPage-YD8MLoPa.js} +1 -1
  8. package/client/dist/assets/CodePage-CLJn2F2e.js +3 -0
  9. package/client/dist/assets/{DesktopAnalyticsPage-BkFBq0E6.js → DesktopAnalyticsPage-MWGQVbwp.js} +1 -1
  10. package/client/dist/assets/{DocsDialog-BL7uSbIJ.js → DocsDialog-XUCYKoq0.js} +1 -1
  11. package/client/dist/assets/{DocsPage-CsDLbmZX.js → DocsPage-dOLC8bXA.js} +1 -1
  12. package/client/dist/assets/{ExportDropdown-B4Olg1Fk.js → ExportDropdown-BvKQgwM9.js} +1 -1
  13. package/client/dist/assets/InteractiveJobComposer-DxOvwmBF.js +19 -0
  14. package/client/dist/assets/{JobDetailModal-DS_Owxs6.js → JobDetailModal-CkiubrkZ.js} +1 -1
  15. package/client/dist/assets/JobDetailPage-CNe4Wn7l.js +1 -0
  16. package/client/dist/assets/JobsPage-DSts_L_d.js +1 -0
  17. package/client/dist/assets/LoopBuilderPage-C9D9eer5.js +1 -0
  18. package/client/dist/assets/{LoopPreviewModal-CH1r-KhU.js → LoopPreviewModal-Dv3dxHr_.js} +1 -1
  19. package/client/dist/assets/{LoopWindowSurface-CiZdI6aw.js → LoopWindowSurface-DN2lbSnL.js} +1 -1
  20. package/client/dist/assets/{LoopsPage-BwFujdGi.js → LoopsPage-DHgIreEW.js} +2 -2
  21. package/client/dist/assets/MinimizedChatsContext-Ds2-R6qJ.js +1 -0
  22. package/client/dist/assets/PluginsPage-D1EJ9oja.js +2 -0
  23. package/client/dist/assets/ProjectSettingsDialog-DKpa1wKk.js +1 -0
  24. package/client/dist/assets/{RepositoryDeliveries-NNorcGzT.js → RepositoryDeliveries-CW4eKG3x.js} +1 -1
  25. package/client/dist/assets/{RepositoryScopeSelector-D-jb4bI_.js → RepositoryScopeSelector-DrtPqvc_.js} +1 -1
  26. package/client/dist/assets/ReviewPacketPage-BtjPI0Cc.js +4 -0
  27. package/client/dist/assets/{TemplatePreviewModal-5CZdAZ0G.js → TemplatePreviewModal-DcFlhUxy.js} +1 -1
  28. package/client/dist/assets/TicketDetailModalContext-Dea22CI-.js +16 -0
  29. package/client/dist/assets/{Trans-wmTUDVyC.js → Trans-CAY2Rd2f.js} +1 -1
  30. package/client/dist/assets/agent-5bSixVzz.js +1 -0
  31. package/client/dist/assets/agent-BR4EHfhq.js +1 -0
  32. package/client/dist/assets/agent-C0IKkJP8.js +1 -0
  33. package/client/dist/assets/agent-C7li9ayC.js +1 -0
  34. package/client/dist/assets/agent-D0dRmEen.js +1 -0
  35. package/client/dist/assets/{agent-BjttZLIl.js → agent-DZVGHm7H.js} +1 -1
  36. package/client/dist/assets/agent-Dip4h2YE.js +1 -0
  37. package/client/dist/assets/agent-Pp-P-n1p.js +1 -0
  38. package/client/dist/assets/agentRuntime-B-myNBUP.js +1 -0
  39. package/client/dist/assets/agentRuntime-Bjt7Ij6_.js +1 -0
  40. package/client/dist/assets/agentRuntime-C_yLPKDy.js +1 -0
  41. package/client/dist/assets/agentRuntime-D2kYQqNO.js +1 -0
  42. package/client/dist/assets/agentRuntime-DvhEe1um.js +1 -0
  43. package/client/dist/assets/agentRuntime-DxC6-9rN.js +1 -0
  44. package/client/dist/assets/agentRuntime-TKQyg137.js +1 -0
  45. package/client/dist/assets/agentRuntime-WSv8G0pW.js +1 -0
  46. package/client/dist/assets/ban-E4EaZe3a.js +1 -0
  47. package/client/dist/assets/chevron-up-CwGUHd6D.js +1 -0
  48. package/client/dist/assets/dist-Bq10nS2m.js +1 -0
  49. package/client/dist/assets/{formatDistanceToNow-Dax4zqPF.js → formatDistanceToNow-DlQY1Lm_.js} +1 -1
  50. package/client/dist/assets/{getTimezoneOffsetInMilliseconds-dpIo42JZ.js → getTimezoneOffsetInMilliseconds-COUeq65G.js} +1 -1
  51. package/client/dist/assets/index-BacrO_ub.css +2 -0
  52. package/client/dist/assets/index-CONHvEJw.js +83 -0
  53. package/client/dist/assets/{jira-api-CLrIvXFm.js → jira-api-C94VNHNY.js} +1 -1
  54. package/client/dist/assets/layers-eDMjG41I.js +1 -0
  55. package/client/dist/assets/{loops-Cm55CXJ4.js → loops-B2PhQLKR.js} +1 -1
  56. package/client/dist/assets/{loops-3IutojWt.js → loops-BqbF46st.js} +1 -1
  57. package/client/dist/assets/{loops-BAosWtXE.js → loops-CINnHbfI.js} +1 -1
  58. package/client/dist/assets/{loops-kIJJkaxf.js → loops-D-3XhH04.js} +1 -1
  59. package/client/dist/assets/{loops-DHQtnfze.js → loops-DKkEEjZ_.js} +1 -1
  60. package/client/dist/assets/{loops-D7tL_Saw.js → loops-DzWR5-v6.js} +1 -1
  61. package/client/dist/assets/{loops--KWr0X-w.js → loops-WyWDkhok.js} +1 -1
  62. package/client/dist/assets/{loops-BISDssL5.js → loops-scD5fIBf.js} +1 -1
  63. package/client/dist/assets/{narration-DvLQBW9U.js → narration-BEKMVxGm.js} +1 -1
  64. package/client/dist/assets/{narration-CHI06czm.js → narration-CjLwGKap.js} +1 -1
  65. package/client/dist/assets/{narration-DjKB3pQZ.js → narration-DANWuGsW.js} +1 -1
  66. package/client/dist/assets/{narration-eSx3gR0W.js → narration-DGeEDWiT.js} +1 -1
  67. package/client/dist/assets/{narration-DtCYvRLM.js → narration-DJgpGwIP.js} +1 -1
  68. package/client/dist/assets/{narration-n3hOA7LY.js → narration-DbHnz0qV.js} +1 -1
  69. package/client/dist/assets/{narration-thJOeT2-.js → narration-bZSsTZG8.js} +1 -1
  70. package/client/dist/assets/{narration--hUhjM5v.js → narration-i6aKJKEc.js} +1 -1
  71. package/client/dist/assets/{project-repositories-BkyT8AjU.js → project-repositories-Cc3oNv8X.js} +1 -1
  72. package/client/dist/assets/save-B6wGWwBR.js +1 -0
  73. package/client/dist/assets/{settings-Dn-pXukr.js → settings-BKJZ2KEM.js} +1 -1
  74. package/client/dist/assets/{settings-BBj_kZaD.js → settings-BV3jocIx.js} +1 -1
  75. package/client/dist/assets/{settings-COlH_P33.js → settings-BjM2Dw8_.js} +1 -1
  76. package/client/dist/assets/settings-CKu0LTib.js +1 -0
  77. package/client/dist/assets/{settings-D77mC_Lb.js → settings-DA77M48m.js} +1 -1
  78. package/client/dist/assets/{settings-ByVE7jdZ.js → settings-LfFnl1UH.js} +1 -1
  79. package/client/dist/assets/{settings-DZKy7MqN.js → settings-P1IQvhnL.js} +1 -1
  80. package/client/dist/assets/{settings-B5Hy_Kol.js → settings-eIMJjyK_.js} +1 -1
  81. package/client/dist/assets/{spending-Oov7p52A.js → spending-DemeFfrH.js} +1 -1
  82. package/client/dist/assets/{useDesktop-DpiS8Uov.js → useDesktop-9Lwoel_8.js} +1 -1
  83. package/client/dist/assets/{useRuntimeRuns-DBm1mul0.js → useRuntimeRuns-DL0xYoZ2.js} +1 -1
  84. package/client/dist/assets/{useSharedWebSocket-BZxKaVNT.js → useSharedWebSocket-BEHPeU1Y.js} +2 -2
  85. package/client/dist/assets/zap-CHo3aCD1.js +1 -0
  86. package/client/dist/index.html +26 -22
  87. package/docs/guide/de/integrations/6-agent-chat.md +11 -0
  88. package/docs/guide/en/integrations/6-agent-chat.md +11 -0
  89. package/docs/guide/es/integrations/6-agent-chat.md +11 -0
  90. package/docs/guide/fr/integrations/6-agent-chat.md +11 -0
  91. package/docs/guide/it/integrations/6-agent-chat.md +11 -0
  92. package/docs/guide/ja/integrations/6-agent-chat.md +11 -0
  93. package/docs/guide/pt/integrations/6-agent-chat.md +11 -0
  94. package/docs/guide/zh/integrations/6-agent-chat.md +11 -0
  95. package/docs/internals/README.md +1 -0
  96. package/docs/internals/agent-sessions.md +157 -0
  97. package/docs/internals/api-reference.md +33 -4
  98. package/docs/internals/configuration.md +36 -0
  99. package/docs/internals/core-runtime-updates.md +10 -3
  100. package/docs/internals/operations-runbook.md +11 -0
  101. package/docs/internals/programmatic-agent-runtime.md +2 -0
  102. package/docs/internals/source-map.md +40 -1
  103. package/mcp-bridge/dist/specrails-mcp.js +82 -15
  104. package/package.json +1 -1
  105. package/server/dist/agent-mcp-config.js +41 -0
  106. package/server/dist/core-compat.js +2 -0
  107. package/server/dist/desktop-db.js +101 -4
  108. package/server/dist/desktop-router.js +31 -2
  109. package/server/dist/index.js +58 -0
  110. package/server/dist/mcp/tools/app-settings.js +11 -0
  111. package/server/dist/mcp/tools/mission.js +45 -2
  112. package/server/dist/mcp/tools/specs.js +2 -2
  113. package/server/dist/modules/accounting/runtime/result-event.js +9 -1
  114. package/server/dist/modules/agent-runtime/runtime/agent-runtime-bridge.js +12 -0
  115. package/server/dist/modules/agent-runtime/runtime/agent-runtime-controls.js +25 -0
  116. package/server/dist/modules/agent-runtime/runtime/agent-runtime-effective-config.js +2 -0
  117. package/server/dist/modules/agent-runtime/runtime/agent-runtime-settings-router.js +6 -2
  118. package/server/dist/modules/agent-runtime/runtime/agent-runtime-settings.js +18 -6
  119. package/server/dist/modules/agent-sessions/adapters/host-process.js +73 -0
  120. package/server/dist/modules/agent-sessions/adapters/http.js +31 -0
  121. package/server/dist/modules/agent-sessions/adapters/rpc-client.js +147 -0
  122. package/server/dist/modules/agent-sessions/application/session-event-pump.js +99 -0
  123. package/server/dist/modules/agent-sessions/domain/availability.js +25 -0
  124. package/server/dist/modules/agent-sessions/domain/errors.js +23 -0
  125. package/server/dist/modules/agent-sessions/domain/host-state.js +80 -0
  126. package/server/dist/modules/agent-sessions/domain/projection.js +147 -0
  127. package/server/dist/modules/agent-sessions/domain/protocol.js +59 -0
  128. package/server/dist/modules/agent-sessions/domain/subagent-policy.js +34 -0
  129. package/server/dist/modules/agent-sessions/index.js +31 -0
  130. package/server/dist/modules/agent-sessions/ports.js +2 -0
  131. package/server/dist/modules/agent-sessions/runtime/core-sessions-availability.js +43 -0
  132. package/server/dist/modules/agent-sessions/runtime/session-host-registry.js +226 -0
  133. package/server/dist/modules/agents/runtime/agent-store.js +3 -1
  134. package/server/dist/modules/loops/runtime/loop-core-factory.js +2 -2
  135. package/server/dist/modules/loops/runtime/loop-definition.js +1 -0
  136. package/server/dist/modules/loops/runtime/loop-factory.js +1 -1
  137. package/server/dist/modules/loops/runtime/loop-graph.js +8 -1
  138. package/server/dist/modules/loops/runtime/loop-implement-recipe.js +41 -11
  139. package/server/dist/modules/loops/runtime/loop-run-manager.js +4 -0
  140. package/server/dist/modules/loops/runtime/loop-templates.js +3 -3
  141. package/server/dist/modules/missions/runtime/agent-chat-manager.js +137 -40
  142. package/server/dist/modules/missions/runtime/agent-chat-router.js +68 -0
  143. package/server/dist/modules/missions/runtime/agent-operator-prompt.js +8 -9
  144. package/server/dist/modules/missions/runtime/agent-session-store.js +133 -0
  145. package/server/dist/modules/missions/runtime/core-session-runner.js +204 -0
  146. package/server/dist/modules/missions/runtime/mission-core-sessions.js +286 -0
  147. package/server/dist/modules/missions/runtime/mission-session-projector.js +168 -0
  148. package/server/dist/modules/project-settings/adapters/http.js +14 -2
  149. package/server/dist/modules/project-settings/adapters/sqlite.js +30 -2
  150. package/server/dist/modules/project-settings/domain.js +24 -0
  151. package/server/dist/modules/project-settings/index.js +2 -1
  152. package/server/dist/modules/specs/runtime/spec-models.js +1 -1
  153. package/server/dist/plugins/codex-spawn.js +15 -7
  154. package/server/dist/project-registry.js +32 -0
  155. package/server/dist/project-router-settings.js +7 -1
  156. package/server/dist/providers/claude-adapter.js +6 -1
  157. package/server/dist/schemas/agent-runtime.schema.json +9 -7
  158. package/client/dist/assets/ActivityFeedPage-3J7fR8yB.js +0 -1
  159. package/client/dist/assets/AgentModeAnalyticsPane-Dps30tk9.js +0 -2
  160. package/client/dist/assets/AgentModeCodePane-CvLimey8.js +0 -2
  161. package/client/dist/assets/CodePage-D981zRHy.js +0 -3
  162. package/client/dist/assets/InteractiveJobComposer-Z6fl4791.js +0 -19
  163. package/client/dist/assets/JobDetailPage-1TUQ9vlE.js +0 -1
  164. package/client/dist/assets/JobsPage-BSrl8P7u.js +0 -1
  165. package/client/dist/assets/LoopBuilderPage-Dh5uk2Qy.js +0 -1
  166. package/client/dist/assets/MinimizedChatsContext-BD2bsRBe.js +0 -1
  167. package/client/dist/assets/PluginsPage-B8f49Mvn.js +0 -2
  168. package/client/dist/assets/ProjectSettingsDialog-D7q-O6h3.js +0 -1
  169. package/client/dist/assets/ReviewPacketPage-DpZSzF-Q.js +0 -4
  170. package/client/dist/assets/TicketDetailModalContext-BHmtj1As.js +0 -16
  171. package/client/dist/assets/agent--8QAfoXL.js +0 -1
  172. package/client/dist/assets/agent-3HxXkIWX.js +0 -1
  173. package/client/dist/assets/agent-CpFCz32T.js +0 -1
  174. package/client/dist/assets/agent-DVnw6ybO.js +0 -1
  175. package/client/dist/assets/agent-Z5s_GTP0.js +0 -1
  176. package/client/dist/assets/agent-hv57-zyG.js +0 -1
  177. package/client/dist/assets/agent-xGrZ_aN1.js +0 -1
  178. package/client/dist/assets/agentRuntime-7Ydcvr6P.js +0 -1
  179. package/client/dist/assets/agentRuntime-BHVw9orA.js +0 -1
  180. package/client/dist/assets/agentRuntime-DCPDaQcV.js +0 -1
  181. package/client/dist/assets/agentRuntime-DKTw4Ajg.js +0 -1
  182. package/client/dist/assets/agentRuntime-DVhij_i_.js +0 -1
  183. package/client/dist/assets/agentRuntime-Doss-T8o.js +0 -1
  184. package/client/dist/assets/agentRuntime-eZSMUlkM.js +0 -1
  185. package/client/dist/assets/agentRuntime-qSSU7fQk.js +0 -1
  186. package/client/dist/assets/index-Bfunvi6w.css +0 -2
  187. package/client/dist/assets/index-g8S62tpS.js +0 -83
  188. package/client/dist/assets/save-OsUqVn99.js +0 -1
  189. package/client/dist/assets/settings-Dbyd6gmj.js +0 -1
  190. package/client/dist/assets/zap-CUOlvtT1.js +0 -1
@@ -3,14 +3,26 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.registerProjectSettingsHttp = registerProjectSettingsHttp;
4
4
  const __1 = require("..");
5
5
  /** Inbound adapter: translate HTTP into use cases and domain errors into HTTP. */
6
- function registerProjectSettingsHttp(router, serviceForRequest) {
6
+ function registerProjectSettingsHttp(router, serviceForRequest,
7
+ /** Observer for committed changes (e.g. open agent sessions re-reading policy). */
8
+ onUpdated) {
7
9
  router.get('/:projectId/settings', (req, res) => {
8
10
  res.json(serviceForRequest(req).getSettings());
9
11
  });
10
12
  router.patch('/:projectId/settings', (req, res) => {
11
13
  try {
12
- const settings = serviceForRequest(req).updateSettings(req.body);
14
+ const service = serviceForRequest(req);
15
+ const previous = onUpdated ? service.getSettings() : null;
16
+ const settings = service.updateSettings(req.body);
13
17
  res.json({ ok: true, settings });
18
+ if (onUpdated && previous) {
19
+ try {
20
+ onUpdated(req, settings, previous);
21
+ }
22
+ catch (error) {
23
+ console.error('[project-router] settings observer error:', error);
24
+ }
25
+ }
14
26
  }
15
27
  catch (error) {
16
28
  if (error instanceof __1.SettingsValidationError) {
@@ -18,13 +18,25 @@ function parseWorktreeEnvPassthrough(raw) {
18
18
  return [];
19
19
  }
20
20
  }
21
+ /** A stored value that no longer parses (hand-edited, older shape) reads as "same as the mission agent". */
22
+ function readSubagentRuntime(raw) {
23
+ if (!raw)
24
+ return null;
25
+ try {
26
+ return (0, domain_1.parseSubagentRuntimeSetting)(JSON.parse(raw));
27
+ }
28
+ catch {
29
+ return null;
30
+ }
31
+ }
21
32
  function getProjectSettings(db) {
22
- // Read the settings as one snapshot instead of preparing six separate queries.
33
+ // Read the settings as one snapshot instead of preparing separate queries.
23
34
  const rows = db.prepare(`
24
35
  SELECT key, value FROM queue_state WHERE key IN (
25
36
  'config.pipeline_telemetry_enabled', 'config.orchestrator_model',
26
37
  'config.pre_prompt', 'config.freestyle_pre_prompt',
27
- 'config.integration_branch', 'config.worktree_env_passthrough'
38
+ 'config.integration_branch', 'config.worktree_env_passthrough',
39
+ 'config.allow_subagents', 'config.subagent_runtime'
28
40
  )
29
41
  `).all();
30
42
  const settings = new Map(rows.map(row => [row.key, row]));
@@ -42,6 +54,8 @@ function getProjectSettings(db) {
42
54
  freestylePrePrompt: freestylePrePromptRow?.value ?? '',
43
55
  integrationBranch: integrationBranchRow?.value ?? '',
44
56
  worktreeEnvPassthrough: parseWorktreeEnvPassthrough(worktreeEnvPassthroughRow?.value),
57
+ allowSubagents: settings.get('config.allow_subagents')?.value === 'true',
58
+ subagentRuntime: readSubagentRuntime(settings.get('config.subagent_runtime')?.value),
45
59
  };
46
60
  }
47
61
  /** Resolve the effective Freestyle pre-prompt: the per-project override when
@@ -81,6 +95,20 @@ function updateProjectSettings(db, patch) {
81
95
  db.prepare(`INSERT OR REPLACE INTO queue_state (key, value) VALUES ('config.integration_branch', ?)`).run(patch.integrationBranch.trim());
82
96
  }
83
97
  }
98
+ if (patch.allowSubagents !== undefined) {
99
+ if (patch.allowSubagents) {
100
+ db.prepare(`INSERT OR REPLACE INTO queue_state (key, value) VALUES ('config.allow_subagents', 'true')`).run();
101
+ }
102
+ else {
103
+ db.prepare(`DELETE FROM queue_state WHERE key = 'config.allow_subagents'`).run();
104
+ }
105
+ }
106
+ if (patch.subagentRuntime !== undefined) {
107
+ if (patch.subagentRuntime === null)
108
+ db.prepare(`DELETE FROM queue_state WHERE key = 'config.subagent_runtime'`).run();
109
+ else
110
+ db.prepare(`INSERT OR REPLACE INTO queue_state (key, value) VALUES ('config.subagent_runtime', ?)`).run(JSON.stringify(patch.subagentRuntime));
111
+ }
84
112
  if (patch.worktreeEnvPassthrough !== undefined) {
85
113
  const names = (0, domain_1.normalizeWorktreeEnvPassthrough)(patch.worktreeEnvPassthrough);
86
114
  if (names.length === 0) {
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SettingsValidationError = exports.WORKTREE_ENV_NAME_RE = exports.DEFAULT_FREESTYLE_PRE_PROMPT = void 0;
4
+ exports.parseSubagentRuntimeSetting = parseSubagentRuntimeSetting;
4
5
  exports.normalizeWorktreeEnvPassthrough = normalizeWorktreeEnvPassthrough;
5
6
  exports.parseProjectSettingsPatch = parseProjectSettingsPatch;
6
7
  const git_branch_name_1 = require("../../shared/git-branch-name");
@@ -18,6 +19,22 @@ exports.DEFAULT_FREESTYLE_PRE_PROMPT = [
18
19
  'Never ask for confirmation; there is no human to answer. Choose the recommended option and proceed.',
19
20
  'Run every command in the FOREGROUND and wait for it to finish — never background a command (no run_in_background, no trailing `&`): your reply ends the step and anything still running is killed with its output lost.',
20
21
  ].join('\n');
22
+ const PROVIDER_ID_RE = /^[a-z0-9][a-z0-9-]{0,63}$/;
23
+ /** Strict shape check shared by project and app settings; null clears the choice. */
24
+ function parseSubagentRuntimeSetting(value) {
25
+ if (value === null)
26
+ return null;
27
+ const input = value;
28
+ if (!input || typeof input !== 'object' || Array.isArray(input))
29
+ throw new SettingsValidationError('subagentRuntime must be an object or null');
30
+ if (typeof input.provider !== 'string' || !PROVIDER_ID_RE.test(input.provider))
31
+ throw new SettingsValidationError('subagentRuntime.provider must be a provider id');
32
+ if (typeof input.model !== 'string' || !input.model.trim() || input.model.length > 200)
33
+ throw new SettingsValidationError('subagentRuntime.model must be a model name');
34
+ if (input.effort !== undefined && input.effort !== null && (typeof input.effort !== 'string' || !input.effort.trim() || input.effort.length > 50))
35
+ throw new SettingsValidationError('subagentRuntime.effort must be an effort level or null');
36
+ return { provider: input.provider, model: input.model.trim(), effort: typeof input.effort === 'string' ? input.effort.trim() : null };
37
+ }
21
38
  exports.WORKTREE_ENV_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
22
39
  const WORKTREE_ENV_MAX_NAMES = 64;
23
40
  const WORKTREE_ENV_MAX_NAME_LENGTH = 128;
@@ -82,6 +99,13 @@ function parseProjectSettingsPatch(input) {
82
99
  throw new SettingsValidationError(error instanceof Error ? error.message : 'invalid worktreeEnvPassthrough');
83
100
  }
84
101
  }
102
+ if (values.subagentRuntime !== undefined)
103
+ patch.subagentRuntime = parseSubagentRuntimeSetting(values.subagentRuntime);
104
+ if (values.allowSubagents !== undefined) {
105
+ if (typeof values.allowSubagents !== 'boolean')
106
+ throw new SettingsValidationError('allowSubagents must be a boolean');
107
+ patch.allowSubagents = values.allowSubagents;
108
+ }
85
109
  if (values.integrationBranch !== undefined) {
86
110
  const branch = values.integrationBranch;
87
111
  if (typeof branch !== 'string')
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SettingsValidationError = exports.normalizeWorktreeEnvPassthrough = exports.WORKTREE_ENV_NAME_RE = exports.DEFAULT_FREESTYLE_PRE_PROMPT = exports.createProjectSettingsService = void 0;
3
+ exports.SettingsValidationError = exports.parseSubagentRuntimeSetting = exports.normalizeWorktreeEnvPassthrough = exports.WORKTREE_ENV_NAME_RE = exports.DEFAULT_FREESTYLE_PRE_PROMPT = exports.createProjectSettingsService = void 0;
4
4
  // Public application API. Infrastructure adapters are wired only at composition roots.
5
5
  var application_1 = require("./application");
6
6
  Object.defineProperty(exports, "createProjectSettingsService", { enumerable: true, get: function () { return application_1.createProjectSettingsService; } });
@@ -8,4 +8,5 @@ var domain_1 = require("./domain");
8
8
  Object.defineProperty(exports, "DEFAULT_FREESTYLE_PRE_PROMPT", { enumerable: true, get: function () { return domain_1.DEFAULT_FREESTYLE_PRE_PROMPT; } });
9
9
  Object.defineProperty(exports, "WORKTREE_ENV_NAME_RE", { enumerable: true, get: function () { return domain_1.WORKTREE_ENV_NAME_RE; } });
10
10
  Object.defineProperty(exports, "normalizeWorktreeEnvPassthrough", { enumerable: true, get: function () { return domain_1.normalizeWorktreeEnvPassthrough; } });
11
+ Object.defineProperty(exports, "parseSubagentRuntimeSetting", { enumerable: true, get: function () { return domain_1.parseSubagentRuntimeSetting; } });
11
12
  Object.defineProperty(exports, "SettingsValidationError", { enumerable: true, get: function () { return domain_1.SettingsValidationError; } });
@@ -9,7 +9,7 @@ exports.CLAUDE_MODELS = [
9
9
  { value: 'sonnet', label: 'Sonnet 5.5' },
10
10
  { value: 'fable', label: 'Fable 5.1' },
11
11
  { value: 'opus', label: 'Claude Opus' },
12
- { value: 'haiku', label: 'Claude Haiku' },
12
+ { value: 'haiku', label: 'Claude Haiku 5.5' },
13
13
  ];
14
14
  exports.CODEX_MODELS = [
15
15
  { value: 'gpt-6.1-sol', label: 'GPT-6.1 Sol' },
@@ -3,18 +3,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.resolveCodexPluginMcpServers = resolveCodexPluginMcpServers;
6
7
  exports.buildCodexPluginArgs = buildCodexPluginArgs;
7
8
  const path_1 = __importDefault(require("path"));
8
9
  const manager_1 = require("./manager");
9
- /** Materialize app-installed plugins in the actual Codex invocation. The
10
+ /** MCP servers of app-installed plugins active for this Codex invocation. The
10
11
  * legacy per-project CODEX_HOME is an install record, not the provider's
11
12
  * runtime home: switching HOME would discard the user's login and settings. */
12
- function buildCodexPluginArgs(options) {
13
+ function resolveCodexPluginMcpServers(options) {
13
14
  if (options.providerId !== 'codex')
14
15
  return [];
15
16
  const manager = (0, manager_1.getPluginManager)();
16
17
  const state = manager.getProjectState(options.stateRoot);
17
- const args = [];
18
+ const servers = [];
18
19
  for (const [name, installed] of Object.entries(state.plugins ?? {})) {
19
20
  if (!installed || typeof installed !== 'object')
20
21
  continue;
@@ -30,7 +31,6 @@ function buildCodexPluginArgs(options) {
30
31
  // owned keys or overwrite Specrails' authenticated bridge.
31
32
  if (keys.length !== 1 || !/^[A-Za-z][A-Za-z0-9_-]*$/.test(keys[0]) || keys[0] === 'specrails')
32
33
  continue;
33
- const server = keys[0];
34
34
  const serverArgs = [...entry.args];
35
35
  // Serena's '.' must mean this invocation's source/worktree, even when
36
36
  // the CLI starts in an app-managed conversation or artifact directory.
@@ -39,9 +39,17 @@ function buildCodexPluginArgs(options) {
39
39
  if (project >= 0)
40
40
  serverArgs[project + 1] = path_1.default.resolve(options.repositoryPath);
41
41
  }
42
- const prefix = `mcp_servers.${server}`;
43
- args.push('-c', `${prefix}.command=${JSON.stringify(entry.command)}`, '-c', `${prefix}.args=${JSON.stringify(serverArgs)}`, '-c', `${prefix}.enabled=true`);
44
- for (const [key, value] of Object.entries(entry.env ?? {})) {
42
+ servers.push({ name: keys[0], command: entry.command, args: serverArgs, ...(entry.env && Object.keys(entry.env).length ? { env: { ...entry.env } } : {}) });
43
+ }
44
+ return servers;
45
+ }
46
+ /** Materialize app-installed plugins in a spawned Codex CLI invocation. */
47
+ function buildCodexPluginArgs(options) {
48
+ const args = [];
49
+ for (const server of resolveCodexPluginMcpServers(options)) {
50
+ const prefix = `mcp_servers.${server.name}`;
51
+ args.push('-c', `${prefix}.command=${JSON.stringify(server.command)}`, '-c', `${prefix}.args=${JSON.stringify(server.args)}`, '-c', `${prefix}.enabled=true`);
52
+ for (const [key, value] of Object.entries(server.env ?? {})) {
45
53
  args.push('-c', `${prefix}.env.${JSON.stringify(key)}=${JSON.stringify(value)}`);
46
54
  }
47
55
  }
@@ -110,6 +110,9 @@ class ProjectRegistry {
110
110
  // M9: projects whose per-project DB failed to load at startup (corrupt, locked,
111
111
  // or migration-stuck). They stay registered but have no live context.
112
112
  _failedProjects;
113
+ /** Settings that running agent sessions depend on changed (`projectId: null` = app-global). */
114
+ _settingsListeners = new Set();
115
+ _removalListeners = new Set();
113
116
  _loadRetryTimers = new Map();
114
117
  _shuttingDown = false;
115
118
  // App-wide shared browser context for "Add Spec from a website": ONE persistent
@@ -443,6 +446,35 @@ class ProjectRegistry {
443
446
  }
444
447
  this._failedProjects.delete(id);
445
448
  (0, desktop_db_1.removeProject)(this._desktopDb, id);
449
+ if (persistedProject) {
450
+ for (const listener of this._removalListeners) {
451
+ try {
452
+ listener({ id, slug: persistedProject.slug });
453
+ }
454
+ catch (err) {
455
+ console.error('[project-registry] project removal listener failed (non-fatal):', err);
456
+ }
457
+ }
458
+ }
459
+ }
460
+ /** Observe project removal (e.g. to stop the project's Core session host). */
461
+ onSettingsChanged(listener) {
462
+ this._settingsListeners.add(listener);
463
+ return () => { this._settingsListeners.delete(listener); };
464
+ }
465
+ notifySettingsChanged(scope) {
466
+ for (const listener of this._settingsListeners) {
467
+ try {
468
+ listener(scope);
469
+ }
470
+ catch (error) {
471
+ console.error('[project-registry] settings listener failed:', error);
472
+ }
473
+ }
474
+ }
475
+ onProjectRemoved(listener) {
476
+ this._removalListeners.add(listener);
477
+ return () => { this._removalListeners.delete(listener); };
446
478
  }
447
479
  getContext(id) {
448
480
  return this._contexts.get(id);
@@ -29,7 +29,13 @@ function registerSettingsRoutes(deps) {
29
29
  (0, agent_runtime_controls_router_1.registerAgentRuntimeControlRoutes)(deps);
30
30
  const { router, registry, ctx } = deps;
31
31
  // ─── Project settings (pipeline telemetry) ───────────────────────────────────
32
- (0, http_1.registerProjectSettingsHttp)(router, req => (0, project_settings_1.createProjectSettingsService)((0, sqlite_1.createSqliteProjectSettingsRepository)(ctx(req).db)));
32
+ (0, http_1.registerProjectSettingsHttp)(router, req => (0, project_settings_1.createProjectSettingsService)((0, sqlite_1.createSqliteProjectSettingsRepository)(ctx(req).db)),
33
+ // Open agent sessions of this project re-read their sub-agent policy.
34
+ (req, settings, previous) => {
35
+ const runtimeChanged = JSON.stringify(settings.subagentRuntime) !== JSON.stringify(previous.subagentRuntime);
36
+ if (settings.allowSubagents !== previous.allowSubagents || runtimeChanged)
37
+ registry.notifySettingsChanged({ projectId: String(req.params.projectId) });
38
+ });
33
39
  // ─── Per-project Quick mode Contract Refine last-used value ─────────────────
34
40
  router.get('/:projectId/add-spec-quick-contract-refine-last', (req, res) => {
35
41
  res.json({
@@ -22,7 +22,7 @@ const CLAUDE_MODELS = [
22
22
  { value: 'sonnet', label: 'Sonnet 5.5', default: true },
23
23
  { value: 'fable', label: 'Fable 5.1' },
24
24
  { value: 'opus', label: 'Claude Opus 5.5' },
25
- { value: 'haiku', label: 'Claude Haiku' },
25
+ { value: 'haiku', label: 'Claude Haiku 5.5' },
26
26
  ];
27
27
  /** Mirror of ChatManager.normalizeClaudeCodeModel — pinned model strings the
28
28
  * CLI accepts collapse to the short alias. */
@@ -44,6 +44,8 @@ function normaliseModel(model) {
44
44
  case 'claude-opus-4-1-20250805':
45
45
  case 'claude-opus-4-20250514':
46
46
  return 'opus';
47
+ case 'claude-haiku-5-5':
48
+ case 'claude-haiku-5':
47
49
  case 'claude-haiku-4-5-20251001':
48
50
  case 'claude-3-5-haiku-20241022':
49
51
  case 'claude-3-5-haiku-latest':
@@ -65,6 +67,7 @@ function normaliseModel(model) {
65
67
  const PINNED_ALIAS_MODEL_IDS = {
66
68
  sonnet: 'claude-sonnet-5-5',
67
69
  opus: 'claude-opus-5-5',
70
+ haiku: 'claude-haiku-5-5',
68
71
  };
69
72
  /** Catalog value (or concrete id) in, spawn model id out. */
70
73
  function resolveSpawnModel(model) {
@@ -482,6 +485,8 @@ exports.claudeAdapter = {
482
485
  nativeOtelEnv: true,
483
486
  profileEnvSupport: true,
484
487
  systemPromptArg: true,
488
+ // Missions already run with --dangerously-skip-permissions; Specrails tiers gate actions.
489
+ sessionPermissions: 'bypass',
485
490
  persistentStdin: true,
486
491
  liveInputTransport: 'claude-stream-json',
487
492
  supportsReasoningEffort: true,
@@ -134,13 +134,8 @@
134
134
  "maxAttempts": { "$ref": "#/definitions/positiveInteger" }, "maxTokens": { "$ref": "#/definitions/positiveInteger" },
135
135
  "maxCostUsd": { "type": "number", "exclusiveMinimum": 0 }, "timeoutMs": { "$ref": "#/definitions/positiveInteger" }
136
136
  } },
137
- "verification": { "type": "array", "items": { "type": "object", "additionalProperties": false, "required": ["repositoryId", "command", "args"], "properties": {
138
- "key": { "$ref": "#/definitions/id" }, "label": { "type": "string", "minLength": 1, "maxLength": 256, "pattern": "\\S" }, "policy": { "$ref": "#/definitions/checkPolicy" },
139
- "repositoryId": { "$ref": "#/definitions/id" }, "command": { "type": "string", "minLength": 1 },
140
- "args": { "type": "array", "items": { "type": "string" } }, "cwd": { "type": "string", "minLength": 1 },
141
- "env": { "type": "object", "propertyNames": { "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" }, "additionalProperties": { "type": "string" } },
142
- "timeoutMs": { "$ref": "#/definitions/positiveInteger" }
143
- } } },
137
+ "verification": { "type": "array", "items": { "$ref": "#/definitions/checkCommand" } },
138
+ "setup": { "type": "array", "description": "Idempotent commands the verify piece runs sequentially in the admitted workspace before each verification plan; a failing setup command blocks the run instead of starting a correction round.", "items": { "$ref": "#/definitions/checkCommand" } },
144
139
  "approvalBeforeArchive": { "type": "boolean" },
145
140
  "review": { "type": "object", "additionalProperties": false, "description": "Review gate thresholds; unset fields keep Core's defaults (score 70, security 75, other aspects 60).", "properties": {
146
141
  "minScore": { "$ref": "#/definitions/score" },
@@ -154,6 +149,13 @@
154
149
  } }
155
150
  },
156
151
  "definitions": {
152
+ "checkCommand": { "type": "object", "additionalProperties": false, "required": ["repositoryId", "command", "args"], "properties": {
153
+ "key": { "$ref": "#/definitions/id" }, "label": { "type": "string", "minLength": 1, "maxLength": 256, "pattern": "\\S" }, "policy": { "$ref": "#/definitions/checkPolicy" },
154
+ "repositoryId": { "$ref": "#/definitions/id" }, "command": { "type": "string", "minLength": 1 },
155
+ "args": { "type": "array", "items": { "type": "string" } }, "cwd": { "type": "string", "minLength": 1 },
156
+ "env": { "type": "object", "propertyNames": { "pattern": "^[A-Za-z_][A-Za-z0-9_]*$" }, "additionalProperties": { "type": "string" } },
157
+ "timeoutMs": { "$ref": "#/definitions/positiveInteger" }
158
+ } },
157
159
  "effort": { "type": "string", "pattern": "^[a-z][a-z0-9_-]{0,31}$" },
158
160
  "inputList": { "type": "array", "maxItems": 256, "items": { "type": "string", "minLength": 1, "maxLength": 4096, "pattern": "\\S" } },
159
161
  "checkPolicy": { "type": "object", "additionalProperties": false, "properties": {
@@ -1 +0,0 @@
1
- import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{n as t,t as n}from"./jsx-runtime-zu2_FqZY.js";import{h as r,r as i}from"./useSharedWebSocket-BZxKaVNT.js";import{n as a}from"./createLucideIcon-Bjbbp_KS.js";import{a as o,r as s}from"./useDesktop-DpiS8Uov.js";import{n as c,t as l}from"./zap-CUOlvtT1.js";import{t as u}from"./circle-x-CMYsN4ZH.js";import{t as d}from"./loader-circle-DcygOQpC.js";import{$t as f,Gt as p}from"./index-g8S62tpS.js";var m=e(t(),1);function h(e){let t=new Set;return e.filter(e=>{let n=`${e.type}:${e.jobId}`;return t.has(n)?!1:(t.add(n),!0)})}function g({activeProjectId:e,limit:t=50}){let[n,a]=(0,m.useState)([]),[s,c]=(0,m.useState)(!1),[l,u]=(0,m.useState)(!0),d=(0,m.useRef)(e);(0,m.useEffect)(()=>{d.current=e},[e]);let{registerHandler:f,unregisterHandler:p}=i();(0,m.useEffect)(()=>{if(!e){a([]),u(!0);return}let n=!1;c(!0),a([]),u(!0);async function r(){let e=o();try{let r=await fetch(`${e}/activity?limit=${t}`);if(!r.ok||n)return;let i=await r.json();if(n)return;a(i),u(i.length===t)}catch{}finally{n||c(!1)}}return r(),()=>{n=!0}},[e,t]);let g=(0,m.useCallback)(async()=>{if(s||!l)return;c(!0);let e=o(),n=d.current;try{a(r=>{let i=r[r.length-1];if(!i)return r;let o=encodeURIComponent(i.timestamp);return fetch(`${e}/activity?limit=${t}&before=${o}`).then(e=>e.json()).then(e=>{if(d.current!==n){c(!1);return}a(t=>h([...t,...e])),u(e.length===t),c(!1)}).catch(()=>c(!1)),r})}catch{c(!1)}},[s,l,t]),_=(0,m.useCallback)(e=>{let t=e,n=d.current;if(!(!t||typeof t.type!=`string`)&&!(t.projectId&&t.projectId!==n)){if(t.type===`queue`&&Array.isArray(t.jobs)){let e=[];for(let n of t.jobs){let t=n.status===`completed`?`job_completed`:n.status===`failed`?`job_failed`:n.status===`canceled`?`job_canceled`:`job_started`;e.push({id:`${t}:${n.id}`,type:t,jobId:n.id,jobCommand:n.command??``,timestamp:n.startedAt??new Date().toISOString(),summary:`${t.replace(`_`,` `)}: ${n.command??``}`,costUsd:null})}e.length>0&&a(t=>h([...e,...t]))}if(t.type===`phase`&&t.phase&&t.state&&t.timestamp){let e={id:`phase:${t.phase}:${t.state}:${t.timestamp}`,type:`job_started`,jobId:`phase-${t.phase}`,jobCommand:r.t(`activity:feed.phaseCommand`,{phase:t.phase,state:t.state}),timestamp:t.timestamp,summary:`Phase ${t.phase} is ${t.state}`,costUsd:null};a(t=>h([e,...t]))}}},[]);return(0,m.useLayoutEffect)(()=>(f(`activity`,_),()=>p(`activity`)),[_,f,p]),{items:n,loading:s,hasMore:l,loadMore:g}}var _=n();function v(e,t){let n=Date.now()-new Date(e).getTime(),r=Math.floor(n/1e3);if(r<60)return t(`feed.relativeTime.seconds`,{value:r});let i=Math.floor(r/60);if(i<60)return t(`feed.relativeTime.minutes`,{value:i});let a=Math.floor(i/60);return a<24?t(`feed.relativeTime.hours`,{value:a}):t(`feed.relativeTime.days`,{value:Math.floor(a/24)})}function y({type:e}){switch(e){case`job_completed`:return(0,_.jsx)(p,{className:`w-4 h-4 text-green-500 aurora-light:text-accent-success flex-shrink-0`});case`job_failed`:return(0,_.jsx)(u,{className:`w-4 h-4 text-red-500 aurora-light:text-destructive flex-shrink-0`});case`job_canceled`:return(0,_.jsx)(c,{className:`w-4 h-4 text-muted-foreground flex-shrink-0`});default:return(0,_.jsx)(l,{className:`w-4 h-4 text-blue-500 aurora-light:text-accent-info flex-shrink-0`})}}function b(e,t){switch(e){case`job_completed`:return t(`common:status.completed`);case`job_failed`:return t(`common:status.failed`);case`job_canceled`:return t(`common:status.canceled`);default:return t(`feed.typeStarted`)}}function x(e){switch(e){case`job_completed`:return`text-green-500 aurora-light:text-accent-success`;case`job_failed`:return`text-red-500 aurora-light:text-destructive`;case`job_canceled`:return`text-muted-foreground`;default:return`text-blue-500 aurora-light:text-accent-info`}}function S(){let{t:e}=a(`activity`),{activeProjectId:t}=s(),{items:n,loading:r,hasMore:i,loadMore:o}=g({activeProjectId:t}),c=(0,m.useRef)(null);return(0,m.useEffect)(()=>{let e=c.current;if(!e)return;let t=new IntersectionObserver(e=>{e[0].isIntersecting&&i&&!r&&o()},{threshold:.1});return t.observe(e),()=>t.disconnect()},[i,r,o]),(0,_.jsxs)(`div`,{className:`flex flex-col h-full overflow-hidden`,children:[(0,_.jsxs)(`div`,{className:`flex items-center gap-2 px-4 py-3 border-b border-border bg-background/50`,children:[(0,_.jsx)(f,{className:`w-4 h-4 text-muted-foreground`}),(0,_.jsx)(`h1`,{className:`text-sm font-medium`,children:e(`feed.title`)})]}),(0,_.jsxs)(`div`,{className:`flex-1 overflow-y-auto`,children:[r&&n.length===0?(0,_.jsx)(`div`,{className:`flex items-center justify-center h-32`,children:(0,_.jsx)(d,{className:`w-4 h-4 animate-spin text-muted-foreground`})}):n.length===0?(0,_.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-48 gap-2 text-muted-foreground`,children:[(0,_.jsx)(f,{className:`w-8 h-8 opacity-40`}),(0,_.jsx)(`p`,{className:`text-sm`,children:e(`feed.emptyTitle`)}),(0,_.jsx)(`p`,{className:`text-xs opacity-70`,children:e(`feed.emptyHint`)})]}):(0,_.jsx)(`ul`,{className:`divide-y divide-border/50`,children:n.map(t=>(0,_.jsxs)(`li`,{className:`flex items-center gap-3 px-4 py-2.5 hover:bg-accent/30 transition-colors`,children:[(0,_.jsx)(y,{type:t.type}),(0,_.jsxs)(`div`,{className:`flex-1 min-w-0`,children:[(0,_.jsx)(`p`,{className:`text-xs text-foreground truncate`,title:t.jobCommand,children:t.jobCommand}),(0,_.jsxs)(`div`,{className:`flex items-center gap-2 mt-0.5`,children:[(0,_.jsx)(`span`,{className:`text-xs font-medium ${x(t.type)}`,children:b(t.type,e)}),t.costUsd!=null&&(0,_.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[`$`,t.costUsd.toFixed(4)]})]})]}),(0,_.jsx)(`span`,{className:`text-xs text-muted-foreground flex-shrink-0 tabular-nums`,children:v(t.timestamp,e)})]},`${t.type}:${t.jobId}`))}),(0,_.jsx)(`div`,{ref:c,className:`h-1`}),r&&n.length>0&&(0,_.jsx)(`div`,{className:`flex justify-center py-3`,children:(0,_.jsx)(d,{className:`w-4 h-4 animate-spin text-muted-foreground`})}),!i&&n.length>0&&(0,_.jsx)(`p`,{className:`text-center text-xs text-muted-foreground py-3`,children:e(`feed.allLoaded`)})]})]})}export{S as default};
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/AnalyticsPage-DXWMGn8b.js","assets/rolldown-runtime-CNC7AqOf.js","assets/jsx-runtime-zu2_FqZY.js","assets/chunk-KS7C4IRE-DEKu087k.js","assets/preload-helper-Czpn1I53.js","assets/useSharedWebSocket-BZxKaVNT.js","assets/activity-DiyjsgQV.js","assets/addspec-BOvgmcgk.js","assets/agent-Z5s_GTP0.js","assets/agentRuntime-BHVw9orA.js","assets/agents-Doe1sHY5.js","assets/agentstudio-BzugqB_N.js","assets/aiedit-iIjz2_Qk.js","assets/analytics-BWynXPEm.js","assets/attachments-B53PG733.js","assets/browser-CG0PE1j_.js","assets/builder-CpS9liE9.js","assets/chat-BGD7MXAy.js","assets/code-DaZ-ZwCT.js","assets/commands-BAWSYHjQ.js","assets/common-Bdi0qN4S.js","assets/dashboard-XGdQ5mjw.js","assets/explore-DgBACn39.js","assets/integrations-Dwl9KQp0.js","assets/jira-FXr7u2lh.js","assets/jobs-De3EqaO0.js","assets/loops--KWr0X-w.js","assets/mcp-CUAN6ORK.js","assets/narration-n3hOA7LY.js","assets/nav--u7iPYlS.js","assets/packet-B0H15elv.js","assets/settings-Dbyd6gmj.js","assets/setup-CKGUxKr-.js","assets/specs-DfIdoU5L.js","assets/subscriptionUsage-CdlE5Mg1.js","assets/terminal-BAzpHtpY.js","assets/tickets-D41ZMQpf.js","assets/createLucideIcon-Bjbbp_KS.js","assets/Trans-wmTUDVyC.js","assets/useDesktop-DpiS8Uov.js","assets/react-dom-DiWzBDP9.js","assets/provider-capabilities-lePfeT_Y.js","assets/spending-Oov7p52A.js","assets/clsx-CjueKrWZ.js","assets/formatDistanceToNow-Dax4zqPF.js","assets/getTimezoneOffsetInMilliseconds-dpIo42JZ.js","assets/index-g8S62tpS.js","assets/tauri-shell-DE6LfGPw.js","assets/TicketDetailModalContext-BHmtj1As.js","assets/save-OsUqVn99.js","assets/MinimizedChatsContext-BD2bsRBe.js","assets/sparkles-DrY8hb0X.js","assets/x-CBMI9ejn.js","assets/zap-CUOlvtT1.js","assets/file-text-BcLCfcWZ.js","assets/circle-x-CMYsN4ZH.js","assets/download-CFHyyHcw.js","assets/external-link-D6XxC_Cu.js","assets/git-branch-BRM0F5GN.js","assets/loader-circle-DcygOQpC.js","assets/pencil-C9RkrIPZ.js","assets/square-Ci-PFcFe.js","assets/plus-CsnjfkmX.js","assets/rotate-ccw-Wh4id13q.js","assets/search-Cq_gE3Ik.js","assets/trash-2-BOU3WdZZ.js","assets/triangle-alert-H9T4jAmh.js","assets/jira-api-CLrIvXFm.js","assets/dialog-CMgps2MY.js","assets/utils-BC4DHlz2.js","assets/lib-CGdyxIWg.js","assets/button-D1xExSTF.js","assets/RepositoryScopeSelector-D-jb4bI_.js","assets/project-repositories-BkyT8AjU.js","assets/core-B3mKBIh5.js","assets/RepositoryDeliveries-NNorcGzT.js","assets/useRuntimeRuns-DBm1mul0.js","assets/event-Bt7f3wXe.js","assets/index-Bfunvi6w.css","assets/ExportDropdown-B4Olg1Fk.js","assets/BarChart-nBOMNfiy.js","assets/value-s-gzBeyF.js"])))=>i.map(i=>d[i]);
2
- import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{n as t,t as n}from"./jsx-runtime-zu2_FqZY.js";import{t as r}from"./preload-helper-Czpn1I53.js";import{n as i}from"./createLucideIcon-Bjbbp_KS.js";import{t as a}from"./loader-circle-DcygOQpC.js";import{t as o}from"./x-CBMI9ejn.js";import{t as s}from"./utils-BC4DHlz2.js";import{At as c,Q as l,kt as u}from"./index-g8S62tpS.js";var d=e(t(),1),f=n(),p=(0,d.lazy)(()=>r(()=>import(`./AnalyticsPage-DXWMGn8b.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81]))),m=420,h=560;function g(){let{t:e}=i(`agent`),{closeAnalyticsPane:t}=l(),[n,r]=(0,d.useState)(h),[g,_]=(0,d.useState)(!1),v=(0,d.useCallback)(e=>{let t=e.clientX,i=n,a=window.innerWidth-m;try{e.currentTarget.setPointerCapture(e.pointerId)}catch{}let o=e=>{let n=Math.min(Math.max(i+(t-e.clientX),m),a);r(n)},s=()=>{window.removeEventListener(`pointermove`,o),window.removeEventListener(`pointerup`,s),window.removeEventListener(`pointercancel`,s)};window.addEventListener(`pointermove`,o),window.addEventListener(`pointerup`,s),window.addEventListener(`pointercancel`,s)},[n]);return(0,f.jsxs)(`div`,{className:s(`flex h-full flex-col overflow-hidden border-l border-border bg-background`,g&&`absolute inset-0 z-30 border-l-0`),style:g?void 0:{width:n,flexShrink:0},"data-testid":`agent-analytics-pane`,children:[(0,f.jsx)(`div`,{className:`relative flex items-center`,children:!g&&(0,f.jsx)(`div`,{role:`separator`,"aria-orientation":`vertical`,onPointerDown:v,className:`absolute left-0 top-0 h-full w-1.5 -translate-x-full cursor-col-resize select-none touch-none hover:bg-accent-primary/20`,title:e(`workspace.resizeAnalytics`)})}),(0,f.jsxs)(`div`,{className:`flex items-center gap-2 border-b border-border/60 bg-surface/40 px-3 py-1.5`,children:[(0,f.jsx)(`span`,{className:`text-xs font-medium text-foreground/70`,children:e(`workspace.analytics`)}),(0,f.jsxs)(`div`,{className:`ml-auto flex items-center gap-1`,children:[(0,f.jsx)(`button`,{type:`button`,onClick:()=>_(e=>!e),"aria-label":e(g?`restore`:`maximize`),title:e(g?`restore`:`maximize`),className:`rounded-md p-1 text-foreground/60 hover:bg-surface hover:text-foreground`,children:g?(0,f.jsx)(u,{className:`h-4 w-4`}):(0,f.jsx)(c,{className:`h-4 w-4`})}),(0,f.jsx)(`button`,{type:`button`,onClick:t,"aria-label":e(`workspace.closeAnalytics`),title:e(`workspace.closeAnalytics`),className:`rounded-md p-1 text-foreground/60 hover:bg-surface hover:text-foreground`,children:(0,f.jsx)(o,{className:`h-4 w-4`})})]})]}),(0,f.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto`,children:(0,f.jsx)(d.Suspense,{fallback:(0,f.jsx)(`div`,{className:`flex h-24 items-center justify-center text-muted-foreground`,children:(0,f.jsx)(a,{className:`h-4 w-4 animate-spin`})}),children:(0,f.jsx)(p,{})})})]})}export{g as AgentModeAnalyticsPane};
@@ -1,2 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/CodePage-D981zRHy.js","assets/rolldown-runtime-CNC7AqOf.js","assets/jsx-runtime-zu2_FqZY.js","assets/react-dom-DiWzBDP9.js","assets/preload-helper-Czpn1I53.js","assets/chunk-KS7C4IRE-DEKu087k.js","assets/useSharedWebSocket-BZxKaVNT.js","assets/activity-DiyjsgQV.js","assets/addspec-BOvgmcgk.js","assets/agent-Z5s_GTP0.js","assets/agentRuntime-BHVw9orA.js","assets/agents-Doe1sHY5.js","assets/agentstudio-BzugqB_N.js","assets/aiedit-iIjz2_Qk.js","assets/analytics-BWynXPEm.js","assets/attachments-B53PG733.js","assets/browser-CG0PE1j_.js","assets/builder-CpS9liE9.js","assets/chat-BGD7MXAy.js","assets/code-DaZ-ZwCT.js","assets/commands-BAWSYHjQ.js","assets/common-Bdi0qN4S.js","assets/dashboard-XGdQ5mjw.js","assets/explore-DgBACn39.js","assets/integrations-Dwl9KQp0.js","assets/jira-FXr7u2lh.js","assets/jobs-De3EqaO0.js","assets/loops--KWr0X-w.js","assets/mcp-CUAN6ORK.js","assets/narration-n3hOA7LY.js","assets/nav--u7iPYlS.js","assets/packet-B0H15elv.js","assets/settings-Dbyd6gmj.js","assets/setup-CKGUxKr-.js","assets/specs-DfIdoU5L.js","assets/subscriptionUsage-CdlE5Mg1.js","assets/terminal-BAzpHtpY.js","assets/tickets-D41ZMQpf.js","assets/createLucideIcon-Bjbbp_KS.js","assets/useDesktop-DpiS8Uov.js","assets/TicketDetailModalContext-BHmtj1As.js","assets/tauri-shell-DE6LfGPw.js","assets/Trans-wmTUDVyC.js","assets/provider-capabilities-lePfeT_Y.js","assets/save-OsUqVn99.js","assets/spending-Oov7p52A.js","assets/MinimizedChatsContext-BD2bsRBe.js","assets/sparkles-DrY8hb0X.js","assets/x-CBMI9ejn.js","assets/zap-CUOlvtT1.js","assets/file-text-BcLCfcWZ.js","assets/circle-x-CMYsN4ZH.js","assets/download-CFHyyHcw.js","assets/external-link-D6XxC_Cu.js","assets/git-branch-BRM0F5GN.js","assets/loader-circle-DcygOQpC.js","assets/pencil-C9RkrIPZ.js","assets/square-Ci-PFcFe.js","assets/plus-CsnjfkmX.js","assets/rotate-ccw-Wh4id13q.js","assets/search-Cq_gE3Ik.js","assets/trash-2-BOU3WdZZ.js","assets/triangle-alert-H9T4jAmh.js","assets/jira-api-CLrIvXFm.js","assets/dialog-CMgps2MY.js","assets/utils-BC4DHlz2.js","assets/clsx-CjueKrWZ.js","assets/lib-CGdyxIWg.js","assets/formatDistanceToNow-Dax4zqPF.js","assets/getTimezoneOffsetInMilliseconds-dpIo42JZ.js","assets/button-D1xExSTF.js","assets/RepositoryScopeSelector-D-jb4bI_.js","assets/project-repositories-BkyT8AjU.js","assets/index-g8S62tpS.js","assets/core-B3mKBIh5.js","assets/RepositoryDeliveries-NNorcGzT.js","assets/useRuntimeRuns-DBm1mul0.js","assets/event-Bt7f3wXe.js","assets/index-Bfunvi6w.css"])))=>i.map(i=>d[i]);
2
- import{a as e}from"./rolldown-runtime-CNC7AqOf.js";import{n as t,t as n}from"./jsx-runtime-zu2_FqZY.js";import{t as r}from"./preload-helper-Czpn1I53.js";import{n as i}from"./createLucideIcon-Bjbbp_KS.js";import{t as a}from"./x-CBMI9ejn.js";import{At as o,Q as s,dt as c,kt as l,ut as u}from"./index-g8S62tpS.js";var d=e(t(),1),f=n(),p=(0,d.lazy)(()=>r(()=>import(`./CodePage-D981zRHy.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78]))),m=420,h=560;function g({projectId:e,conversationId:t}){let{t:n}=i(`agent`),{closeCodePane:r}=s(),[g,_]=(0,d.useState)(h),[v,y]=(0,d.useState)(()=>window.innerWidth),[b,x]=(0,d.useState)(!1),S=(0,d.useRef)(null),C=(0,d.useRef)(null),w=Math.max(0,v-Math.min(m,v/2)),T=Math.min(m,w),E=Math.min(w,Math.max(T,g)),D=(0,d.useCallback)(e=>Math.min(w,Math.max(T,e)),[w,T]),O=`${e}:${t}`,k=(0,d.useCallback)(n=>{c(e,t,{path:n})},[e,t]);(0,d.useLayoutEffect)(()=>{let e=S.current,t=e?.parentElement;if(!e||!t)return;let n=()=>{let n=t.getBoundingClientRect().width||t.clientWidth||window.innerWidth,r=0;for(let n of t.children){if(n===e||!(n instanceof HTMLElement))continue;let t=getComputedStyle(n);t.display===`none`||t.position===`absolute`||t.position===`fixed`||Number(t.flexGrow)>0||(r+=n.getBoundingClientRect().width)}y(Math.max(0,n-r))},r=new ResizeObserver(n),i=()=>{r.disconnect(),r.observe(t);for(let n of t.children)n!==e&&r.observe(n);n()},a=new MutationObserver(i);return a.observe(t,{childList:!0}),i(),window.addEventListener(`resize`,n),()=>{r.disconnect(),a.disconnect(),window.removeEventListener(`resize`,n)}},[O]),(0,d.useEffect)(()=>()=>{C.current?.()},[O,b,w]);let A=(0,d.useCallback)(e=>{if(e.button!==0)return;e.preventDefault(),C.current?.();let t=e.clientX,n=E,r=e.pointerId,i=e.currentTarget;try{i.setPointerCapture(r)}catch{}let a=e=>{e.pointerId===r&&_(D(n+t-e.clientX))},o=()=>{window.removeEventListener(`pointermove`,a),window.removeEventListener(`pointerup`,s),window.removeEventListener(`pointercancel`,s),window.removeEventListener(`blur`,o),i.removeEventListener(`lostpointercapture`,o);try{i.hasPointerCapture(r)&&i.releasePointerCapture(r)}catch{}C.current=null},s=e=>{e.pointerId===r&&o()};C.current=o,window.addEventListener(`pointermove`,a),window.addEventListener(`pointerup`,s),window.addEventListener(`pointercancel`,s),window.addEventListener(`blur`,o),i.addEventListener(`lostpointercapture`,o)},[E,D]);return(0,f.jsxs)(`div`,{ref:S,className:`flex h-full min-w-0 flex-col overflow-hidden border-l border-border bg-background${b?` absolute inset-0 z-30 border-l-0`:` relative`}`,style:b?void 0:{width:E,maxWidth:`100%`,flexShrink:0},"data-testid":`agent-code-pane`,children:[!b&&(0,f.jsx)(`div`,{role:`separator`,"aria-orientation":`vertical`,onPointerDown:A,tabIndex:0,"aria-label":n(`workspace.resizeCode`),"aria-valuemin":Math.round(T),"aria-valuemax":Math.round(w),"aria-valuenow":Math.round(E),onKeyDown:e=>{let t=e.key===`ArrowLeft`?E+32:e.key===`ArrowRight`?E-32:e.key===`Home`?T:e.key===`End`?w:null;t!==null&&(e.preventDefault(),_(D(t)))},className:`absolute inset-y-0 left-0 z-20 w-1.5 cursor-col-resize select-none touch-none hover:bg-accent-primary/20 focus-visible:bg-accent-primary/30 focus-visible:outline-none`,title:n(`workspace.resizeCode`)}),(0,f.jsxs)(`div`,{className:`flex items-center gap-2 border-b border-border/60 bg-surface/40 px-3 py-1.5`,children:[(0,f.jsx)(`span`,{className:`text-xs font-medium text-foreground/70`,children:n(`workspace.files`)}),(0,f.jsxs)(`div`,{className:`ml-auto flex items-center gap-1`,children:[(0,f.jsx)(`button`,{type:`button`,onClick:()=>{C.current?.(),x(e=>!e)},"aria-label":n(b?`restore`:`maximize`),title:n(b?`restore`:`maximize`),className:`rounded-md p-1 text-foreground/60 hover:bg-surface hover:text-foreground`,children:b?(0,f.jsx)(l,{className:`h-4 w-4`}):(0,f.jsx)(o,{className:`h-4 w-4`})}),(0,f.jsx)(`button`,{type:`button`,onClick:()=>{C.current?.(),r()},"aria-label":n(`workspace.closeFiles`),title:n(`workspace.closeFiles`),className:`rounded-md p-1 text-foreground/60 hover:bg-surface hover:text-foreground`,children:(0,f.jsx)(a,{className:`h-4 w-4`})})]})]}),(0,f.jsx)(`div`,{className:`min-h-0 flex-1 overflow-hidden`,children:(0,f.jsx)(d.Suspense,{fallback:(0,f.jsx)(`div`,{className:`flex h-full items-center justify-center text-sm text-muted-foreground`,children:`…`}),children:(0,f.jsx)(p,{embedded:!0,initialRepositoryId:u(e,t).repositoryId,onRepositoryChange:n=>c(e,t,{repositoryId:n}),initialPath:u(e,t).path,onSelectedPathChange:k},O)})})]},O)}export{g as AgentModeCodePane};