@shipit-ai/cli 1.166.1 → 1.167.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 (577) hide show
  1. package/README.md +26 -5
  2. package/apis/json-schema/AgentConfig.yaml +3 -0
  3. package/apis/json-schema/AgentPermissionSettings.yaml +23 -0
  4. package/apis/json-schema/AgentType.yaml +0 -1
  5. package/apis/json-schema/ClaudeCodePermissionMode.yaml +9 -0
  6. package/apis/json-schema/CodexPermissionMode.yaml +8 -0
  7. package/apis/json-schema/CopilotPermissionMode.yaml +8 -0
  8. package/apis/json-schema/CursorPermissionMode.yaml +7 -0
  9. package/apis/json-schema/Feature.yaml +3 -0
  10. package/apis/json-schema/GeminiPermissionMode.yaml +8 -0
  11. package/apis/json-schema/RovoDevPermissionMode.yaml +8 -0
  12. package/dist/packages/core/src/application/ports/output/agents/agent-executor.interface.d.ts +8 -0
  13. package/dist/packages/core/src/application/ports/output/agents/agent-executor.interface.d.ts.map +1 -1
  14. package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts +1 -0
  15. package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts.map +1 -1
  16. package/dist/packages/core/src/application/ports/output/agents/interactive-agent-executor.interface.d.ts +3 -0
  17. package/dist/packages/core/src/application/ports/output/agents/interactive-agent-executor.interface.d.ts.map +1 -1
  18. package/dist/packages/core/src/application/ports/output/services/index.d.ts +1 -0
  19. package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
  20. package/dist/packages/core/src/application/ports/output/services/settings-reader.interface.d.ts +13 -0
  21. package/dist/packages/core/src/application/ports/output/services/settings-reader.interface.d.ts.map +1 -0
  22. package/dist/packages/core/src/application/ports/output/services/settings-reader.interface.js +1 -0
  23. package/dist/packages/core/src/application/use-cases/agents/configure-agent.use-case.d.ts.map +1 -1
  24. package/dist/packages/core/src/application/use-cases/agents/configure-agent.use-case.js +4 -6
  25. package/dist/packages/core/src/application/use-cases/features/check-and-unblock-features.use-case.d.ts.map +1 -1
  26. package/dist/packages/core/src/application/use-cases/features/check-and-unblock-features.use-case.js +1 -0
  27. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  28. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +21 -2
  29. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +2 -0
  30. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
  31. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.d.ts.map +1 -1
  32. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.js +1 -0
  33. package/dist/packages/core/src/application/use-cases/features/start-feature.use-case.d.ts.map +1 -1
  34. package/dist/packages/core/src/application/use-cases/features/start-feature.use-case.js +1 -0
  35. package/dist/packages/core/src/application/use-cases/settings/complete-onboarding.use-case.d.ts +2 -0
  36. package/dist/packages/core/src/application/use-cases/settings/complete-onboarding.use-case.d.ts.map +1 -1
  37. package/dist/packages/core/src/application/use-cases/settings/complete-onboarding.use-case.js +23 -0
  38. package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts.map +1 -1
  39. package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +9 -1
  40. package/dist/packages/core/src/domain/generated/output.d.ts +68 -2
  41. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  42. package/dist/packages/core/src/domain/generated/output.js +36 -1
  43. package/dist/packages/core/src/infrastructure/di/modules/agents.module.d.ts.map +1 -1
  44. package/dist/packages/core/src/infrastructure/di/modules/agents.module.js +4 -2
  45. package/dist/packages/core/src/infrastructure/di/modules/services.module.d.ts.map +1 -1
  46. package/dist/packages/core/src/infrastructure/di/modules/services.module.js +2 -0
  47. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts +1 -0
  48. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts.map +1 -1
  49. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.js +4 -0
  50. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +6 -0
  51. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
  52. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +31 -0
  53. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/052-add-agent-permission-modes.d.ts +21 -0
  54. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/052-add-agent-permission-modes.d.ts.map +1 -0
  55. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/052-add-agent-permission-modes.js +35 -0
  56. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/053-add-feature-permission-mode.d.ts +14 -0
  57. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/053-add-feature-permission-mode.d.ts.map +1 -0
  58. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/053-add-feature-permission-mode.js +19 -0
  59. package/dist/packages/core/src/infrastructure/services/agents/analyze-repo/analyze-repository-graph.d.ts +3 -1
  60. package/dist/packages/core/src/infrastructure/services/agents/analyze-repo/analyze-repository-graph.d.ts.map +1 -1
  61. package/dist/packages/core/src/infrastructure/services/agents/analyze-repo/analyze-repository-graph.js +18 -7
  62. package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.d.ts +1 -1
  63. package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.d.ts.map +1 -1
  64. package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-factory.service.js +1 -6
  65. package/dist/packages/core/src/infrastructure/services/agents/common/agent-permissions.d.ts +21 -0
  66. package/dist/packages/core/src/infrastructure/services/agents/common/agent-permissions.d.ts.map +1 -0
  67. package/dist/packages/core/src/infrastructure/services/agents/common/agent-permissions.js +49 -0
  68. package/dist/packages/core/src/infrastructure/services/agents/common/agent-runner.service.d.ts +3 -1
  69. package/dist/packages/core/src/infrastructure/services/agents/common/agent-runner.service.d.ts.map +1 -1
  70. package/dist/packages/core/src/infrastructure/services/agents/common/agent-runner.service.js +4 -3
  71. package/dist/packages/core/src/infrastructure/services/agents/common/agent-validator.service.d.ts.map +1 -1
  72. package/dist/packages/core/src/infrastructure/services/agents/common/agent-validator.service.js +0 -3
  73. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts.map +1 -1
  74. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.js +11 -0
  75. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.d.ts.map +1 -1
  76. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-interactive-executor.service.js +1 -1
  77. package/dist/packages/core/src/infrastructure/services/agents/common/executors/codex-cli-executor.service.d.ts.map +1 -1
  78. package/dist/packages/core/src/infrastructure/services/agents/common/executors/codex-cli-executor.service.js +4 -1
  79. package/dist/packages/core/src/infrastructure/services/agents/common/executors/copilot-cli-executor.service.d.ts.map +1 -1
  80. package/dist/packages/core/src/infrastructure/services/agents/common/executors/copilot-cli-executor.service.js +11 -4
  81. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts.map +1 -1
  82. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.js +11 -1
  83. package/dist/packages/core/src/infrastructure/services/agents/common/executors/gemini-cli-executor.service.d.ts.map +1 -1
  84. package/dist/packages/core/src/infrastructure/services/agents/common/executors/gemini-cli-executor.service.js +2 -1
  85. package/dist/packages/core/src/infrastructure/services/agents/common/executors/rovo-dev-executor.service.d.ts.map +1 -1
  86. package/dist/packages/core/src/infrastructure/services/agents/common/executors/rovo-dev-executor.service.js +11 -4
  87. package/dist/packages/core/src/infrastructure/services/agents/common/structured-agent-caller.service.d.ts +3 -1
  88. package/dist/packages/core/src/infrastructure/services/agents/common/structured-agent-caller.service.d.ts.map +1 -1
  89. package/dist/packages/core/src/infrastructure/services/agents/common/structured-agent-caller.service.js +13 -6
  90. package/dist/packages/core/src/infrastructure/services/agents/conflict-resolution/conflict-resolution.service.d.ts +3 -1
  91. package/dist/packages/core/src/infrastructure/services/agents/conflict-resolution/conflict-resolution.service.d.ts.map +1 -1
  92. package/dist/packages/core/src/infrastructure/services/agents/conflict-resolution/conflict-resolution.service.js +12 -3
  93. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/fast-feature-agent-graph.d.ts +5 -0
  94. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/fast-feature-agent-graph.d.ts.map +1 -1
  95. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts +18 -1
  96. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts.map +1 -1
  97. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts +1 -0
  98. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts.map +1 -1
  99. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.js +3 -0
  100. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts +1 -0
  101. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
  102. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +8 -0
  103. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence.node.d.ts +3 -1
  104. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence.node.d.ts.map +1 -1
  105. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/evidence.node.js +3 -2
  106. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.d.ts +3 -0
  107. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.d.ts.map +1 -1
  108. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/ci-watch-fix-loop.js +1 -1
  109. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts +3 -0
  110. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.d.ts.map +1 -1
  111. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge/merge.node.js +2 -1
  112. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts +11 -3
  113. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts.map +1 -1
  114. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +20 -5
  115. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/repair.node.d.ts.map +1 -1
  116. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/repair.node.js +6 -0
  117. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts +1 -0
  118. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts.map +1 -1
  119. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.js +4 -0
  120. package/dist/packages/core/src/infrastructure/services/external/github-repository.service.d.ts.map +1 -1
  121. package/dist/packages/core/src/infrastructure/services/external/github-repository.service.js +14 -3
  122. package/dist/packages/core/src/infrastructure/services/settings-reader.service.d.ts +7 -0
  123. package/dist/packages/core/src/infrastructure/services/settings-reader.service.d.ts.map +1 -0
  124. package/dist/packages/core/src/infrastructure/services/settings-reader.service.js +25 -0
  125. package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
  126. package/dist/src/presentation/cli/commands/feat/new.command.js +18 -0
  127. package/dist/src/presentation/cli/commands/feat/show.command.d.ts.map +1 -1
  128. package/dist/src/presentation/cli/commands/feat/show.command.js +2 -1
  129. package/dist/src/presentation/cli/commands/settings/agent.command.js +2 -2
  130. package/dist/src/presentation/cli/commands/settings/index.d.ts.map +1 -1
  131. package/dist/src/presentation/cli/commands/settings/index.js +3 -1
  132. package/dist/src/presentation/cli/commands/settings/permission-modes.d.ts +19 -0
  133. package/dist/src/presentation/cli/commands/settings/permission-modes.d.ts.map +1 -0
  134. package/dist/src/presentation/cli/commands/settings/permission-modes.js +38 -0
  135. package/dist/src/presentation/cli/commands/settings/permissions.command.d.ts +16 -0
  136. package/dist/src/presentation/cli/commands/settings/permissions.command.d.ts.map +1 -0
  137. package/dist/src/presentation/cli/commands/settings/permissions.command.js +147 -0
  138. package/dist/src/presentation/tui/prompts/agent-select.prompt.d.ts +4 -10
  139. package/dist/src/presentation/tui/prompts/agent-select.prompt.d.ts.map +1 -1
  140. package/dist/src/presentation/tui/prompts/agent-select.prompt.js +8 -13
  141. package/dist/src/presentation/tui/wizards/onboarding/onboarding.wizard.d.ts +5 -3
  142. package/dist/src/presentation/tui/wizards/onboarding/onboarding.wizard.d.ts.map +1 -1
  143. package/dist/src/presentation/tui/wizards/onboarding/onboarding.wizard.js +10 -5
  144. package/dist/src/presentation/tui/wizards/onboarding/steps/agent-permissions.step.d.ts +17 -0
  145. package/dist/src/presentation/tui/wizards/onboarding/steps/agent-permissions.step.d.ts.map +1 -0
  146. package/dist/src/presentation/tui/wizards/onboarding/steps/agent-permissions.step.js +48 -0
  147. package/dist/src/presentation/tui/wizards/onboarding/types.d.ts +2 -0
  148. package/dist/src/presentation/tui/wizards/onboarding/types.d.ts.map +1 -1
  149. package/dist/src/presentation/web/app/actions/agent-permissions.d.ts +14 -0
  150. package/dist/src/presentation/web/app/actions/agent-permissions.d.ts.map +1 -0
  151. package/dist/src/presentation/web/app/actions/agent-permissions.js +181 -0
  152. package/dist/src/presentation/web/app/actions/check-agent-auth.d.ts.map +1 -1
  153. package/dist/src/presentation/web/app/actions/check-agent-auth.js +2 -5
  154. package/dist/src/presentation/web/app/actions/check-agent-tool.js +1 -1
  155. package/dist/src/presentation/web/app/actions/deploy-repository.d.ts.map +1 -1
  156. package/dist/src/presentation/web/app/actions/deploy-repository.js +14 -7
  157. package/dist/src/presentation/web/app/actions/get-all-agent-models.d.ts.map +1 -1
  158. package/dist/src/presentation/web/app/actions/get-all-agent-models.js +2 -17
  159. package/dist/src/presentation/web/app/actions/get-merge-review-data.d.ts.map +1 -1
  160. package/dist/src/presentation/web/app/actions/get-merge-review-data.js +67 -23
  161. package/dist/src/presentation/web/app/actions/open-folder.d.ts.map +1 -1
  162. package/dist/src/presentation/web/app/actions/open-folder.js +12 -4
  163. package/dist/src/presentation/web/app/actions/open-shell.d.ts.map +1 -1
  164. package/dist/src/presentation/web/app/actions/open-shell.js +47 -7
  165. package/dist/src/presentation/web/app/api/agent-events/route.d.ts.map +1 -1
  166. package/dist/src/presentation/web/app/api/agent-events/route.js +2 -6
  167. package/dist/src/presentation/web/app/api/attachments/upload-from-path/route.d.ts.map +1 -1
  168. package/dist/src/presentation/web/app/api/attachments/upload-from-path/route.js +21 -17
  169. package/dist/src/presentation/web/app/api/deployment-logs/route.d.ts.map +1 -1
  170. package/dist/src/presentation/web/app/api/deployment-logs/route.js +2 -6
  171. package/dist/src/presentation/web/app/api/directory/list/route.d.ts.map +1 -1
  172. package/dist/src/presentation/web/app/api/directory/list/route.js +39 -24
  173. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/stream/route.d.ts.map +1 -1
  174. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/stream/route.js +2 -6
  175. package/dist/src/presentation/web/app/api/interactive/sessions/[id]/stream/route.d.ts.map +1 -1
  176. package/dist/src/presentation/web/app/api/interactive/sessions/[id]/stream/route.js +2 -6
  177. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  178. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +1 -1
  179. package/dist/src/presentation/web/components/common/feature-create-drawer/types.d.ts +2 -0
  180. package/dist/src/presentation/web/components/common/feature-create-drawer/types.d.ts.map +1 -1
  181. package/dist/src/presentation/web/components/common/feature-create-drawer/use-feature-create-form.d.ts +2 -0
  182. package/dist/src/presentation/web/components/common/feature-create-drawer/use-feature-create-form.d.ts.map +1 -1
  183. package/dist/src/presentation/web/components/common/feature-create-drawer/use-feature-create-form.js +6 -0
  184. package/dist/src/presentation/web/components/common/feature-create-drawer/workflow-options-section.d.ts +7 -1
  185. package/dist/src/presentation/web/components/common/feature-create-drawer/workflow-options-section.d.ts.map +1 -1
  186. package/dist/src/presentation/web/components/common/feature-create-drawer/workflow-options-section.js +24 -3
  187. package/dist/src/presentation/web/components/common/feature-create-drawer/workflow-options-section.stories.d.ts.map +1 -1
  188. package/dist/src/presentation/web/components/common/feature-create-drawer/workflow-options-section.stories.js +3 -0
  189. package/dist/src/presentation/web/components/common/feature-list-item/feature-list-item.stories.js +2 -2
  190. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.d.ts +2 -2
  191. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.d.ts.map +1 -1
  192. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.js +4 -11
  193. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.stories.d.ts +1 -1
  194. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.stories.d.ts.map +1 -1
  195. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.stories.js +5 -6
  196. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +2 -0
  197. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
  198. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  199. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +2 -2
  200. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +10 -10
  201. package/dist/src/presentation/web/components/features/control-center/control-center.stories.js +1 -1
  202. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.js +2 -2
  203. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.d.ts +1 -1
  204. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.d.ts.map +1 -1
  205. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.js +3 -3
  206. package/dist/src/presentation/web/components/features/settings/agent-permission-picker.d.ts +8 -0
  207. package/dist/src/presentation/web/components/features/settings/agent-permission-picker.d.ts.map +1 -0
  208. package/dist/src/presentation/web/components/features/settings/agent-permission-picker.js +33 -0
  209. package/dist/src/presentation/web/components/features/settings/agent-permission-picker.stories.d.ts +15 -0
  210. package/dist/src/presentation/web/components/features/settings/agent-permission-picker.stories.d.ts.map +1 -0
  211. package/dist/src/presentation/web/components/features/settings/agent-permission-picker.stories.js +75 -0
  212. package/dist/src/presentation/web/components/features/settings/agent-settings-section.d.ts.map +1 -1
  213. package/dist/src/presentation/web/components/features/settings/agent-settings-section.js +32 -4
  214. package/dist/src/presentation/web/components/features/settings/agent-settings-section.stories.d.ts +1 -1
  215. package/dist/src/presentation/web/components/features/settings/agent-settings-section.stories.d.ts.map +1 -1
  216. package/dist/src/presentation/web/components/features/settings/agent-settings-section.stories.js +2 -2
  217. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.stories.js +2 -2
  218. package/dist/src/presentation/web/lib/path-sanitizers.d.ts +50 -0
  219. package/dist/src/presentation/web/lib/path-sanitizers.d.ts.map +1 -0
  220. package/dist/src/presentation/web/lib/path-sanitizers.js +137 -0
  221. package/dist/translations/ar/cli.json +16 -0
  222. package/dist/translations/ar/tui.json +12 -10
  223. package/dist/translations/ar/web.json +15 -0
  224. package/dist/translations/de/cli.json +16 -0
  225. package/dist/translations/de/tui.json +13 -5
  226. package/dist/translations/de/web.json +15 -0
  227. package/dist/translations/en/cli.json +16 -0
  228. package/dist/translations/en/tui.json +12 -10
  229. package/dist/translations/en/web.json +15 -0
  230. package/dist/translations/es/cli.json +16 -0
  231. package/dist/translations/es/tui.json +12 -10
  232. package/dist/translations/es/web.json +15 -0
  233. package/dist/translations/fr/cli.json +16 -0
  234. package/dist/translations/fr/tui.json +12 -10
  235. package/dist/translations/fr/web.json +15 -0
  236. package/dist/translations/he/cli.json +16 -0
  237. package/dist/translations/he/tui.json +12 -10
  238. package/dist/translations/he/web.json +15 -0
  239. package/dist/translations/pt/cli.json +16 -0
  240. package/dist/translations/pt/tui.json +12 -10
  241. package/dist/translations/pt/web.json +15 -0
  242. package/dist/translations/ru/cli.json +16 -0
  243. package/dist/translations/ru/tui.json +12 -10
  244. package/dist/translations/ru/web.json +15 -0
  245. package/dist/tsconfig.build.tsbuildinfo +1 -1
  246. package/package.json +6 -6
  247. package/web/.next/BUILD_ID +1 -1
  248. package/web/.next/build-manifest.json +3 -3
  249. package/web/.next/fallback-build-manifest.json +3 -3
  250. package/web/.next/prerender-manifest.json +3 -3
  251. package/web/.next/required-server-files.js +2 -2
  252. package/web/.next/required-server-files.json +2 -2
  253. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
  254. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +3 -4
  255. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  256. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  257. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
  258. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js +3 -4
  259. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  260. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  261. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +72 -60
  262. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +4 -4
  263. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  264. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  265. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
  266. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +4 -4
  267. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  268. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  269. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +37 -37
  270. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +4 -4
  271. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  272. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  273. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  274. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js +3 -4
  275. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  276. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  277. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  278. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +3 -4
  279. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  280. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  281. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
  282. package/web/.next/server/app/(dashboard)/chat/page.js +3 -4
  283. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  284. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  285. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +72 -60
  286. package/web/.next/server/app/(dashboard)/create/page.js +4 -4
  287. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  288. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  289. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
  290. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +4 -4
  291. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  292. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  293. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +37 -37
  294. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +4 -4
  295. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  296. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  297. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
  298. package/web/.next/server/app/(dashboard)/page.js +3 -4
  299. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  300. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  301. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  302. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js +3 -4
  303. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  304. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  305. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  306. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +3 -4
  307. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  308. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  309. package/web/.next/server/app/_global-error.html +1 -1
  310. package/web/.next/server/app/_global-error.rsc +1 -1
  311. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  312. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  313. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  314. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  315. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  316. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
  317. package/web/.next/server/app/_not-found/page.js +2 -3
  318. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  319. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  320. package/web/.next/server/app/api/agent-events/route.js +2 -1
  321. package/web/.next/server/app/api/agent-events/route.js.nft.json +1 -1
  322. package/web/.next/server/app/api/attachments/preview/route.js +1 -1
  323. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  324. package/web/.next/server/app/api/attachments/upload-from-path/route.js +1 -1
  325. package/web/.next/server/app/api/attachments/upload-from-path/route.js.nft.json +1 -1
  326. package/web/.next/server/app/api/deployment-logs/route.js +2 -1
  327. package/web/.next/server/app/api/deployment-logs/route.js.nft.json +1 -1
  328. package/web/.next/server/app/api/dialog/pick-files/route.js +1 -1
  329. package/web/.next/server/app/api/dialog/pick-files/route.js.nft.json +1 -1
  330. package/web/.next/server/app/api/directory/list/route.js +1 -1
  331. package/web/.next/server/app/api/directory/list/route.js.nft.json +1 -1
  332. package/web/.next/server/app/api/evidence/route.js +1 -1
  333. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  334. package/web/.next/server/app/api/graph-data/route.js +1 -1
  335. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  336. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js +1 -1
  337. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  338. package/web/.next/server/app/api/interactive/chat/[featureId]/stream/route.js +2 -1
  339. package/web/.next/server/app/api/interactive/chat/[featureId]/stream/route.js.nft.json +1 -1
  340. package/web/.next/server/app/api/interactive/sessions/[id]/stream/route.js +2 -1
  341. package/web/.next/server/app/api/interactive/sessions/[id]/stream/route.js.nft.json +1 -1
  342. package/web/.next/server/app/api/sessions-batch/route.js +1 -1
  343. package/web/.next/server/app/api/sessions-batch/route.js.nft.json +1 -1
  344. package/web/.next/server/app/settings/page/server-reference-manifest.json +11 -11
  345. package/web/.next/server/app/settings/page.js +3 -4
  346. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  347. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  348. package/web/.next/server/app/skills/page/server-reference-manifest.json +11 -11
  349. package/web/.next/server/app/skills/page.js +3 -3
  350. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  351. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  352. package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
  353. package/web/.next/server/app/tools/page.js +3 -3
  354. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  355. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  356. package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
  357. package/web/.next/server/app/version/page.js +2 -3
  358. package/web/.next/server/app/version/page.js.nft.json +1 -1
  359. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  360. package/web/.next/server/chunks/11es_next_dist_esm_build_templates_app-route_067cwst.js +1 -1
  361. package/web/.next/server/chunks/11es_next_dist_esm_build_templates_app-route_067cwst.js.map +1 -1
  362. package/web/.next/server/chunks/{[root-of-the-server]__02xmnal._.js → [root-of-the-server]__08cpfre._.js} +2 -2
  363. package/web/.next/server/chunks/[root-of-the-server]__0_-chcy._.js +3 -0
  364. package/web/.next/server/chunks/[root-of-the-server]__0_-chcy._.js.map +1 -0
  365. package/web/.next/server/chunks/[root-of-the-server]__0aft8l4._.js +9 -0
  366. package/web/.next/server/chunks/{[root-of-the-server]__0_6fhza._.js.map → [root-of-the-server]__0aft8l4._.js.map} +1 -1
  367. package/web/.next/server/chunks/[root-of-the-server]__0e9p7em._.js +3 -0
  368. package/web/.next/server/chunks/[root-of-the-server]__0e9p7em._.js.map +1 -0
  369. package/web/.next/server/chunks/{[root-of-the-server]__0.2exzi._.js → [root-of-the-server]__0gfvkg8._.js} +2 -2
  370. package/web/.next/server/chunks/{[root-of-the-server]__0ip_e1x._.js → [root-of-the-server]__0hcp97v._.js} +2 -2
  371. package/web/.next/server/chunks/{[root-of-the-server]__09118p2._.js → [root-of-the-server]__0iel39d._.js} +2 -2
  372. package/web/.next/server/chunks/[root-of-the-server]__0kc8ify._.js +12 -0
  373. package/web/.next/server/chunks/[root-of-the-server]__0kc8ify._.js.map +1 -0
  374. package/web/.next/server/chunks/[root-of-the-server]__0r5uk_8._.js +9 -0
  375. package/web/.next/server/chunks/[root-of-the-server]__0r5uk_8._.js.map +1 -0
  376. package/web/.next/server/chunks/[root-of-the-server]__0tb~wwk._.js +1 -1
  377. package/web/.next/server/chunks/{[root-of-the-server]__04jjtl_._.js → [root-of-the-server]__0u1jyv9._.js} +2 -2
  378. package/web/.next/server/chunks/{[root-of-the-server]__07suer1._.js → [root-of-the-server]__0zu_byw._.js} +2 -2
  379. package/web/.next/server/chunks/[root-of-the-server]__13e2_kk._.js +18 -0
  380. package/web/.next/server/chunks/[root-of-the-server]__13e2_kk._.js.map +1 -0
  381. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_create-drawer-client_tsx_0g70fc5._.js +1 -1
  382. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_create-drawer-client_tsx_0g70fc5._.js.map +1 -1
  383. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_feature-drawer-client_tsx_104cna.._.js +2 -2
  384. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_feature-drawer-client_tsx_104cna.._.js.map +1 -1
  385. package/web/.next/server/chunks/ssr/0ukq_presentation_web_components_features_settings_settings-page-client_tsx_0j1uius._.js +1 -1
  386. package/web/.next/server/chunks/ssr/0ukq_presentation_web_components_features_settings_settings-page-client_tsx_0j1uius._.js.map +1 -1
  387. package/web/.next/server/chunks/ssr/{_01mq~sm._.js → 11es_next_0q-kz~8._.js} +2 -2
  388. package/web/.next/server/chunks/ssr/11es_next_0q-kz~8._.js.map +1 -0
  389. package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_repository-drawer-client_tsx_09z.znp._.js +1 -1
  390. package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_repository-drawer-client_tsx_09z.znp._.js.map +1 -1
  391. package/web/.next/server/chunks/ssr/[root-of-the-server]__02.89uf._.js +4 -0
  392. package/web/.next/server/chunks/ssr/[root-of-the-server]__02.89uf._.js.map +1 -0
  393. package/web/.next/server/chunks/ssr/[root-of-the-server]__04rq9lr._.js +4 -0
  394. package/web/.next/server/chunks/ssr/[root-of-the-server]__04rq9lr._.js.map +1 -0
  395. package/web/.next/server/chunks/ssr/[root-of-the-server]__05_qc0n._.js +4 -0
  396. package/web/.next/server/chunks/ssr/[root-of-the-server]__05_qc0n._.js.map +1 -0
  397. package/web/.next/server/chunks/ssr/[root-of-the-server]__0c0xoi_._.js +3 -0
  398. package/web/.next/server/chunks/ssr/[root-of-the-server]__0c0xoi_._.js.map +1 -0
  399. package/web/.next/server/chunks/ssr/{[root-of-the-server]__0qh.wn.._.js → [root-of-the-server]__0q3-gz.._.js} +2 -2
  400. package/web/.next/server/chunks/ssr/[root-of-the-server]__0r5zhk.._.js +4 -0
  401. package/web/.next/server/chunks/ssr/[root-of-the-server]__0r5zhk.._.js.map +1 -0
  402. package/web/.next/server/chunks/ssr/[root-of-the-server]__0rv1gci._.js +1 -1
  403. package/web/.next/server/chunks/ssr/[root-of-the-server]__0rvrr1j._.js +4 -0
  404. package/web/.next/server/chunks/ssr/[root-of-the-server]__0rvrr1j._.js.map +1 -0
  405. package/web/.next/server/chunks/ssr/[root-of-the-server]__0tq2syh._.js +4 -0
  406. package/web/.next/server/chunks/ssr/[root-of-the-server]__0tq2syh._.js.map +1 -0
  407. package/web/.next/server/chunks/ssr/[root-of-the-server]__0uy_5rw._.js +4 -0
  408. package/web/.next/server/chunks/ssr/[root-of-the-server]__0uy_5rw._.js.map +1 -0
  409. package/web/.next/server/chunks/ssr/[root-of-the-server]__12j29w-._.js +4 -0
  410. package/web/.next/server/chunks/ssr/[root-of-the-server]__12j29w-._.js.map +1 -0
  411. package/web/.next/server/chunks/ssr/_00k65h-._.js.map +1 -1
  412. package/web/.next/server/chunks/ssr/_01sesw0._.js +1 -1
  413. package/web/.next/server/chunks/ssr/_01sesw0._.js.map +1 -1
  414. package/web/.next/server/chunks/ssr/_069y.js._.js +6 -0
  415. package/web/.next/server/chunks/ssr/_069y.js._.js.map +1 -0
  416. package/web/.next/server/chunks/ssr/_0__4si~._.js +4 -0
  417. package/web/.next/server/chunks/ssr/_0__4si~._.js.map +1 -0
  418. package/web/.next/server/chunks/ssr/_0_m17kl._.js +4 -0
  419. package/web/.next/server/chunks/ssr/_0_m17kl._.js.map +1 -0
  420. package/web/.next/server/chunks/ssr/_0d4miu.._.js +4 -0
  421. package/web/.next/server/chunks/ssr/_0d4miu.._.js.map +1 -0
  422. package/web/.next/server/chunks/ssr/_0e8ern9._.js +4 -0
  423. package/web/.next/server/chunks/ssr/_0e8ern9._.js.map +1 -0
  424. package/web/.next/server/chunks/ssr/{_0e4npv~._.js → _0l10ccg._.js} +2 -2
  425. package/web/.next/server/chunks/ssr/_0l10ccg._.js.map +1 -0
  426. package/web/.next/server/chunks/ssr/_0mo6j.n._.js +3 -0
  427. package/web/.next/server/chunks/ssr/_0mo6j.n._.js.map +1 -0
  428. package/web/.next/server/chunks/ssr/{_0nvrqsj._.js → _0mvhe_2._.js} +2 -2
  429. package/web/.next/server/chunks/ssr/{_0nvrqsj._.js.map → _0mvhe_2._.js.map} +1 -1
  430. package/web/.next/server/chunks/ssr/{_109n-y4._.js → _0n.magx._.js} +2 -2
  431. package/web/.next/server/chunks/ssr/_0n.magx._.js.map +1 -0
  432. package/web/.next/server/chunks/ssr/_0p3~u8u._.js +6 -0
  433. package/web/.next/server/chunks/ssr/_0p3~u8u._.js.map +1 -0
  434. package/web/.next/server/chunks/ssr/_0r.3n~3._.js +4 -0
  435. package/web/.next/server/chunks/ssr/_0r.3n~3._.js.map +1 -0
  436. package/web/.next/server/chunks/ssr/_0t59q8r._.js +4 -0
  437. package/web/.next/server/chunks/ssr/_0t59q8r._.js.map +1 -0
  438. package/web/.next/server/chunks/ssr/_0tcccbb._.js +3 -0
  439. package/web/.next/server/chunks/ssr/_0tcccbb._.js.map +1 -0
  440. package/web/.next/server/chunks/ssr/_0vyfc4b._.js +1 -1
  441. package/web/.next/server/chunks/ssr/_0vyfc4b._.js.map +1 -1
  442. package/web/.next/server/chunks/ssr/_0w-_hww._.js +1 -1
  443. package/web/.next/server/chunks/ssr/_0w-_hww._.js.map +1 -1
  444. package/web/.next/server/chunks/ssr/_0zk-h5w._.js +4 -0
  445. package/web/.next/server/chunks/ssr/_0zk-h5w._.js.map +1 -0
  446. package/web/.next/server/chunks/ssr/_0~7lwu_._.js +1 -1
  447. package/web/.next/server/chunks/ssr/_0~7lwu_._.js.map +1 -1
  448. package/web/.next/server/chunks/ssr/_1161g9x._.js +4 -0
  449. package/web/.next/server/chunks/ssr/_1161g9x._.js.map +1 -0
  450. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_05m2q~u.js +3 -0
  451. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_05m2q~u.js.map +1 -0
  452. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_0.6zk.t.js +3 -0
  453. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_0.6zk.t.js.map +1 -0
  454. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_approve-feature_ts_0pjb_re._.js +3 -0
  455. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_approve-feature_ts_0pjb_re._.js.map +1 -0
  456. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_0w2wqvu._.js +1 -1
  457. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_0w2wqvu._.js.map +1 -1
  458. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_0l3oxx9._.js +1 -1
  459. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_0l3oxx9._.js.map +1 -1
  460. package/web/.next/server/middleware-build-manifest.js +3 -3
  461. package/web/.next/server/pages/500.html +1 -1
  462. package/web/.next/server/server-reference-manifest.js +1 -1
  463. package/web/.next/server/server-reference-manifest.json +127 -109
  464. package/web/.next/static/chunks/{0awttldb-.7m..js → 0.8ue6wwr7ni~.js} +1 -1
  465. package/web/.next/static/chunks/{0d-2jp.f._l2e.js → 028x3z97mchhz.js} +1 -1
  466. package/web/.next/static/chunks/044f5piy5pt5t.js +1 -0
  467. package/web/.next/static/chunks/04~sw.nhpwy6s.css +1 -0
  468. package/web/.next/static/chunks/05enics63g._-.js +7 -0
  469. package/web/.next/static/chunks/0_.x~txb5da7d.js +1 -0
  470. package/web/.next/static/chunks/0_9k2ybutuphq.js +1 -0
  471. package/web/.next/static/chunks/{14g1l3~6i5251.js → 0hti2r43x0~b7.js} +2 -2
  472. package/web/.next/static/chunks/0jo5-_q.1n69j.js +1 -0
  473. package/web/.next/static/chunks/{0t8zwgaz.d1s5.js → 0n3u~4ytndfyd.js} +1 -1
  474. package/web/.next/static/chunks/{0nk2r-18.7g6r.js → 0pyz97q7eg0jz.js} +1 -1
  475. package/web/.next/static/chunks/0qqe9hx_txhso.js +1 -0
  476. package/web/.next/static/chunks/{0ntgq3d_.m5el.js → 0vx7ldqj8436q.js} +2 -2
  477. package/web/.next/static/chunks/11~m1ei9bh269.js +3 -0
  478. package/web/.next/static/chunks/{09dqgshddfxff.js → 13w6ziae82sjy.js} +1 -1
  479. package/web/.next/static/chunks/16.83v.xq8bn9.js +1 -0
  480. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.d.ts +0 -12
  481. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.d.ts.map +0 -1
  482. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.js +0 -233
  483. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/plan.fixture.d.ts +0 -8
  484. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/plan.fixture.d.ts.map +0 -1
  485. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/plan.fixture.js +0 -94
  486. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/research.fixture.d.ts +0 -8
  487. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/research.fixture.d.ts.map +0 -1
  488. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/research.fixture.js +0 -140
  489. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/spec-analyze.fixture.d.ts +0 -8
  490. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/spec-analyze.fixture.d.ts.map +0 -1
  491. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/spec-analyze.fixture.js +0 -81
  492. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/spec-requirements.fixture.d.ts +0 -8
  493. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/spec-requirements.fixture.d.ts.map +0 -1
  494. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/spec-requirements.fixture.js +0 -131
  495. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/tasks.fixture.d.ts +0 -6
  496. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/tasks.fixture.d.ts.map +0 -1
  497. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/tasks.fixture.js +0 -146
  498. package/web/.next/server/chunks/[root-of-the-server]__0-3b27b._.js +0 -9
  499. package/web/.next/server/chunks/[root-of-the-server]__0-3b27b._.js.map +0 -1
  500. package/web/.next/server/chunks/[root-of-the-server]__0_6fhza._.js +0 -9
  501. package/web/.next/server/chunks/[root-of-the-server]__0esdmru._.js +0 -12
  502. package/web/.next/server/chunks/[root-of-the-server]__0esdmru._.js.map +0 -1
  503. package/web/.next/server/chunks/[root-of-the-server]__0l1p8bx._.js +0 -3
  504. package/web/.next/server/chunks/[root-of-the-server]__0l1p8bx._.js.map +0 -1
  505. package/web/.next/server/chunks/[root-of-the-server]__0p~owgt._.js +0 -18
  506. package/web/.next/server/chunks/[root-of-the-server]__0p~owgt._.js.map +0 -1
  507. package/web/.next/server/chunks/[root-of-the-server]__0rru~m.._.js +0 -3
  508. package/web/.next/server/chunks/[root-of-the-server]__0rru~m.._.js.map +0 -1
  509. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_00~eq5i.js +0 -3
  510. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_00~eq5i.js.map +0 -1
  511. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_0979_c..js +0 -3
  512. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_0979_c..js.map +0 -1
  513. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_chat_page_actions_0dqll_1.js +0 -3
  514. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_chat_page_actions_0dqll_1.js.map +0 -1
  515. package/web/.next/server/chunks/ssr/[root-of-the-server]__045sv4b._.js +0 -3
  516. package/web/.next/server/chunks/ssr/[root-of-the-server]__045sv4b._.js.map +0 -1
  517. package/web/.next/server/chunks/ssr/[root-of-the-server]__0d_0_fp._.js +0 -3
  518. package/web/.next/server/chunks/ssr/[root-of-the-server]__0d_0_fp._.js.map +0 -1
  519. package/web/.next/server/chunks/ssr/[root-of-the-server]__0l4d7e.._.js +0 -3
  520. package/web/.next/server/chunks/ssr/[root-of-the-server]__0l4d7e.._.js.map +0 -1
  521. package/web/.next/server/chunks/ssr/[root-of-the-server]__0o3qggc._.js +0 -3
  522. package/web/.next/server/chunks/ssr/[root-of-the-server]__0o3qggc._.js.map +0 -1
  523. package/web/.next/server/chunks/ssr/[root-of-the-server]__0r32z03._.js +0 -3
  524. package/web/.next/server/chunks/ssr/[root-of-the-server]__0r32z03._.js.map +0 -1
  525. package/web/.next/server/chunks/ssr/[root-of-the-server]__12g8h3_._.js +0 -4
  526. package/web/.next/server/chunks/ssr/[root-of-the-server]__12g8h3_._.js.map +0 -1
  527. package/web/.next/server/chunks/ssr/_0.rsra~._.js +0 -3
  528. package/web/.next/server/chunks/ssr/_0.rsra~._.js.map +0 -1
  529. package/web/.next/server/chunks/ssr/_01mq~sm._.js.map +0 -1
  530. package/web/.next/server/chunks/ssr/_0a-ddx-._.js +0 -3
  531. package/web/.next/server/chunks/ssr/_0a-ddx-._.js.map +0 -1
  532. package/web/.next/server/chunks/ssr/_0e4npv~._.js.map +0 -1
  533. package/web/.next/server/chunks/ssr/_0jpbsh_._.js +0 -4
  534. package/web/.next/server/chunks/ssr/_0jpbsh_._.js.map +0 -1
  535. package/web/.next/server/chunks/ssr/_109n-y4._.js.map +0 -1
  536. package/web/.next/server/chunks/ssr/src_presentation_web_0.e4~xc._.js +0 -3
  537. package/web/.next/server/chunks/ssr/src_presentation_web_0.e4~xc._.js.map +0 -1
  538. package/web/.next/server/chunks/ssr/src_presentation_web_00dvh.m._.js +0 -3
  539. package/web/.next/server/chunks/ssr/src_presentation_web_00dvh.m._.js.map +0 -1
  540. package/web/.next/server/chunks/ssr/src_presentation_web_06b6~lt._.js +0 -5
  541. package/web/.next/server/chunks/ssr/src_presentation_web_06b6~lt._.js.map +0 -1
  542. package/web/.next/server/chunks/ssr/src_presentation_web_08fy2mf._.js +0 -3
  543. package/web/.next/server/chunks/ssr/src_presentation_web_08fy2mf._.js.map +0 -1
  544. package/web/.next/server/chunks/ssr/src_presentation_web_0f~udu1._.js +0 -3
  545. package/web/.next/server/chunks/ssr/src_presentation_web_0f~udu1._.js.map +0 -1
  546. package/web/.next/server/chunks/ssr/src_presentation_web_0qys821._.js +0 -5
  547. package/web/.next/server/chunks/ssr/src_presentation_web_0qys821._.js.map +0 -1
  548. package/web/.next/server/chunks/ssr/src_presentation_web_0q~dt0o._.js +0 -3
  549. package/web/.next/server/chunks/ssr/src_presentation_web_0q~dt0o._.js.map +0 -1
  550. package/web/.next/server/chunks/ssr/src_presentation_web_11jrkxt._.js +0 -3
  551. package/web/.next/server/chunks/ssr/src_presentation_web_11jrkxt._.js.map +0 -1
  552. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_1199d3x.js +0 -3
  553. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_1199d3x.js.map +0 -1
  554. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app__not-found_page_actions_0m2jqxx.js +0 -3
  555. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app__not-found_page_actions_0m2jqxx.js.map +0 -1
  556. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_version_page_actions_0krkh_0.js +0 -3
  557. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_version_page_actions_0krkh_0.js.map +0 -1
  558. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_load-settings_ts_0b8f3pf._.js +0 -3
  559. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_load-settings_ts_0b8f3pf._.js.map +0 -1
  560. package/web/.next/static/chunks/00dg6gti40.3i.js +0 -1
  561. package/web/.next/static/chunks/0_--5mgqukm__.js +0 -1
  562. package/web/.next/static/chunks/0_c5~n__lz4ks.js +0 -1
  563. package/web/.next/static/chunks/0ist7260j__0m.js +0 -3
  564. package/web/.next/static/chunks/0j_0i2qsrwh-c.js +0 -1
  565. package/web/.next/static/chunks/0njrgvmyafrod.js +0 -1
  566. package/web/.next/static/chunks/0r5dju6f1-i38.css +0 -1
  567. package/web/.next/static/chunks/0t.pzrmeoq6th.js +0 -7
  568. /package/web/.next/server/chunks/{[root-of-the-server]__02xmnal._.js.map → [root-of-the-server]__08cpfre._.js.map} +0 -0
  569. /package/web/.next/server/chunks/{[root-of-the-server]__0.2exzi._.js.map → [root-of-the-server]__0gfvkg8._.js.map} +0 -0
  570. /package/web/.next/server/chunks/{[root-of-the-server]__0ip_e1x._.js.map → [root-of-the-server]__0hcp97v._.js.map} +0 -0
  571. /package/web/.next/server/chunks/{[root-of-the-server]__09118p2._.js.map → [root-of-the-server]__0iel39d._.js.map} +0 -0
  572. /package/web/.next/server/chunks/{[root-of-the-server]__04jjtl_._.js.map → [root-of-the-server]__0u1jyv9._.js.map} +0 -0
  573. /package/web/.next/server/chunks/{[root-of-the-server]__07suer1._.js.map → [root-of-the-server]__0zu_byw._.js.map} +0 -0
  574. /package/web/.next/server/chunks/ssr/{[root-of-the-server]__0qh.wn.._.js.map → [root-of-the-server]__0q3-gz.._.js.map} +0 -0
  575. /package/web/.next/static/{ZpPnD_b687G9xVr2nzrds → ksBer6au8b_fS1_7dCF2D}/_buildManifest.js +0 -0
  576. /package/web/.next/static/{ZpPnD_b687G9xVr2nzrds → ksBer6au8b_fS1_7dCF2D}/_clientMiddlewareManifest.js +0 -0
  577. /package/web/.next/static/{ZpPnD_b687G9xVr2nzrds → ksBer6au8b_fS1_7dCF2D}/_ssgManifest.js +0 -0
@@ -4,7 +4,7 @@ import { useState } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
  import { useRouter } from 'next/navigation';
6
6
  import { Handle, Position } from '@xyflow/react';
7
- import { Plus, Trash2, Zap, ClipboardList, LoaderCircle, Globe, RotateCcw, Play, Square, Eye, Archive, ArchiveRestore, MessageSquare, } from 'lucide-react';
7
+ import { Plus, Trash2, Zap, ClipboardList, LoaderCircle, Globe, RotateCcw, Play, Square, Eye, Archive, ArchiveRestore, MessageSquare, Shield, } from 'lucide-react';
8
8
  import { cn } from '../../../lib/utils.js';
9
9
  import { ActionButton } from '../../common/action-button/action-button.js';
10
10
  import { Button } from '../../ui/button.js';
@@ -111,7 +111,7 @@ export function FeatureNode({ data, selected, }) {
111
111
  selected &&
112
112
  'border-e-rose-400 border-t-rose-400 border-b-rose-400 dark:border-e-amber-500 dark:border-t-amber-500 dark:border-b-amber-500', selected &&
113
113
  data.state !== 'action-required' &&
114
- 'border-blue-400 dark:border-amber-500/60', data.state === 'deleting' && 'opacity-60', data.state === 'archived' && 'opacity-50'), children: [data.state !== 'creating' ? (_jsx("div", { className: "absolute end-4 top-3", children: _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("span", { "data-testid": "feature-node-phase-badge", className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-muted-foreground text-[10px]", children: lifecyclePhaseBadge[data.lifecycle].tooltip }), _jsx("span", { className: cn('h-1.5 w-1.5 -translate-y-px rounded-full', lifecyclePhaseBadge[data.lifecycle].dot) })] }) }), _jsxs(TooltipContent, { side: "right", className: "max-w-56", children: [_jsx("p", { className: "font-semibold", children: lifecyclePhaseBadge[data.lifecycle].tooltip }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-neutral-500", children: lifecyclePhaseBadge[data.lifecycle].description })] })] }) }) })) : null, _jsxs("div", { className: "flex items-center gap-1.5 pe-24", children: [data.agentType ? (_jsx(AgentIcon, { agentType: data.agentType, className: "h-4 w-4 shrink-0" })) : null, _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { "data-testid": "feature-node-fast-mode-badge", className: "shrink-0", children: data.fastMode ? (_jsx(Zap, { className: "h-3.5 w-3.5 text-amber-500" })) : (_jsx(ClipboardList, { className: "h-3.5 w-3.5 text-indigo-500" })) }) }), _jsx(TooltipContent, { side: "top", children: data.fastMode ? t('featureNode.fastMode') : t('featureNode.specDriven') })] }) }), _jsx("h3", { className: "min-w-0 truncate text-sm font-bold", children: data.name })] }), data.description ? (_jsx("p", { "data-testid": "feature-node-description", className: "text-muted-foreground mt-1 line-clamp-2 text-xs", children: data.description })) : null, _jsxs("div", { className: "mt-auto pt-2", children: [config.showProgressBar ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-muted-foreground flex items-center justify-end text-[10px]", children: _jsxs("span", { children: [data.progress, "%"] }) }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', config.progressClass), style: { width: `${data.progress}%` } }) })] })) : null, !config.showProgressBar &&
114
+ 'border-blue-400 dark:border-amber-500/60', data.state === 'deleting' && 'opacity-60', data.state === 'archived' && 'opacity-50'), children: [data.state !== 'creating' ? (_jsx("div", { className: "absolute end-4 top-3", children: _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("span", { "data-testid": "feature-node-phase-badge", className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-muted-foreground text-[10px]", children: lifecyclePhaseBadge[data.lifecycle].tooltip }), _jsx("span", { className: cn('h-1.5 w-1.5 -translate-y-px rounded-full', lifecyclePhaseBadge[data.lifecycle].dot) })] }) }), _jsxs(TooltipContent, { side: "right", className: "max-w-56", children: [_jsx("p", { className: "font-semibold", children: lifecyclePhaseBadge[data.lifecycle].tooltip }), _jsx("p", { className: "mt-1 text-xs leading-relaxed text-neutral-500", children: lifecyclePhaseBadge[data.lifecycle].description })] })] }) }) })) : null, _jsxs("div", { className: "flex items-center gap-1.5 pe-24", children: [data.agentType ? (_jsx(AgentIcon, { agentType: data.agentType, className: "h-4 w-4 shrink-0" })) : null, _jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx("span", { "data-testid": "feature-node-fast-mode-badge", className: "shrink-0", children: data.fastMode ? (_jsx(Zap, { className: "h-3.5 w-3.5 text-amber-500" })) : (_jsx(ClipboardList, { className: "h-3.5 w-3.5 text-indigo-500" })) }) }), _jsx(TooltipContent, { side: "top", children: data.fastMode ? t('featureNode.fastMode') : t('featureNode.specDriven') })] }) }), _jsx("h3", { className: "min-w-0 truncate text-sm font-bold", children: data.name }), data.permissionMode ? (_jsx(TooltipProvider, { children: _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("span", { "data-testid": "feature-node-permission-badge", className: "flex shrink-0 items-center gap-0.5 rounded-full border px-1.5 py-0.5 text-[9px] font-medium text-violet-600 dark:text-violet-400", children: [_jsx(Shield, { className: "h-2.5 w-2.5" }), data.permissionMode] }) }), _jsx(TooltipContent, { side: "top", children: t('feature.card.permissionOverride', { mode: data.permissionMode }) })] }) })) : null] }), data.description ? (_jsx("p", { "data-testid": "feature-node-description", className: "text-muted-foreground mt-1 line-clamp-2 text-xs", children: data.description })) : null, _jsxs("div", { className: "mt-auto pt-2", children: [config.showProgressBar ? (_jsxs(_Fragment, { children: [_jsx("div", { className: "text-muted-foreground flex items-center justify-end text-[10px]", children: _jsxs("span", { children: [data.progress, "%"] }) }), _jsx("div", { "data-testid": "feature-node-progress-bar", className: "bg-muted mt-1.5 h-1 w-full overflow-hidden rounded-full", children: _jsx("div", { className: cn('h-full rounded-full transition-all', config.progressClass), style: { width: `${data.progress}%` } }) })] })) : null, !config.showProgressBar &&
115
115
  ![
116
116
  'deleting',
117
117
  'creating',
@@ -172,7 +172,7 @@ const allStatesData = [
172
172
  state: 'error',
173
173
  progress: 30,
174
174
  errorMessage: 'Build failed: Cannot find module @sendgrid/mail',
175
- agentType: 'aider',
175
+ agentType: 'copilot-cli',
176
176
  modelId: 'claude-sonnet-4-6',
177
177
  repositoryPath: '/home/user/my-repo',
178
178
  repositoryName: 'my-repo',
@@ -288,28 +288,28 @@ const allAgentTypesData = [
288
288
  branch: 'feat/gemini-cli',
289
289
  },
290
290
  {
291
- name: 'Aider Agent',
292
- description: 'Running with Aider executor',
291
+ name: 'Copilot CLI Agent',
292
+ description: 'Running with GitHub Copilot CLI executor',
293
293
  featureId: '#a4',
294
294
  lifecycle: 'implementation',
295
295
  state: 'running',
296
296
  progress: 50,
297
- agentType: 'aider',
297
+ agentType: 'copilot-cli',
298
298
  modelId: 'claude-sonnet-4-6',
299
299
  repositoryPath: '/home/user/my-repo',
300
- branch: 'feat/aider',
300
+ branch: 'feat/copilot-cli',
301
301
  },
302
302
  {
303
- name: 'Continue Agent',
304
- description: 'Running with Continue executor',
303
+ name: 'Rovo Dev Agent',
304
+ description: 'Running with Rovo Dev CLI executor',
305
305
  featureId: '#a5',
306
306
  lifecycle: 'implementation',
307
307
  state: 'running',
308
308
  progress: 50,
309
- agentType: 'continue',
310
- modelId: 'claude-sonnet-4-6',
309
+ agentType: 'rovo-dev',
310
+ modelId: 'auto',
311
311
  repositoryPath: '/home/user/my-repo',
312
- branch: 'feat/continue',
312
+ branch: 'feat/rovo-dev',
313
313
  },
314
314
  {
315
315
  name: 'Default (No Agent)',
@@ -306,7 +306,7 @@ const fullSpectrumFeatures = [
306
306
  progress: 71,
307
307
  repositoryPath: '/home/user/acme/infra',
308
308
  branch: 'feat/terraform-modules',
309
- agentType: 'aider',
309
+ agentType: 'copilot-cli',
310
310
  startedAt: Date.now() - 22 * 60_000,
311
311
  showHandles: true,
312
312
  onDelete: noop,
@@ -147,7 +147,7 @@ const multipleNodes = [
147
147
  repositoryName: 'my-repo',
148
148
  branch: 'feat/email-service',
149
149
  worktreePath: '/home/user/.shipit-ai/repos/abc123/wt/feat-email-service',
150
- agentType: 'aider',
150
+ agentType: 'copilot-cli',
151
151
  modelId: 'claude-sonnet-4-6',
152
152
  hasAgentRun: true,
153
153
  hasPlan: true,
@@ -955,7 +955,7 @@ const fullSpectrumNodes = [
955
955
  state: 'error',
956
956
  progress: 55,
957
957
  errorMessage: 'ENOMEM — out of memory during test execution',
958
- agentType: 'aider',
958
+ agentType: 'copilot-cli',
959
959
  modelId: 'claude-sonnet-4-6',
960
960
  repositoryPath: '/home/dev/platform',
961
961
  repositoryName: 'platform',
@@ -7,7 +7,7 @@ export declare const ClaudeCodeDefault: Story;
7
7
  export declare const CursorSelected: Story;
8
8
  export declare const GeminiCli: Story;
9
9
  export declare const CodexCliSelected: Story;
10
- export declare const DemoAgent: Story;
10
+ export declare const CopilotCli: Story;
11
11
  export declare const OverrideMode: Story;
12
12
  export declare const Disabled: Story;
13
13
  //# sourceMappingURL=AgentModelPicker.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AgentModelPicker.stories.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,gBAAgB,CAevC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,iBAAiB,EAAE,KAM/B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAM5B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAM9B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAOtB,CAAC"}
1
+ {"version":3,"file":"AgentModelPicker.stories.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,gBAAgB,CAevC,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,iBAAiB,EAAE,KAM/B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAM5B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAM9B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAMxB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAOtB,CAAC"}
@@ -42,10 +42,10 @@ export const CodexCliSelected = {
42
42
  mode: 'settings',
43
43
  },
44
44
  };
45
- export const DemoAgent = {
45
+ export const CopilotCli = {
46
46
  args: {
47
- initialAgentType: 'dev',
48
- initialModel: '',
47
+ initialAgentType: 'copilot-cli',
48
+ initialModel: 'claude-sonnet-4-5',
49
49
  mode: 'settings',
50
50
  },
51
51
  };
@@ -0,0 +1,8 @@
1
+ export interface AgentPermissionPickerProps {
2
+ agentType: string;
3
+ currentMode: string | undefined;
4
+ onChange: (mode: string) => void;
5
+ disabled?: boolean;
6
+ }
7
+ export declare function AgentPermissionPicker({ agentType, currentMode, onChange, disabled, }: AgentPermissionPickerProps): import("react/jsx-runtime").JSX.Element | null;
8
+ //# sourceMappingURL=agent-permission-picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-permission-picker.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/settings/agent-permission-picker.tsx"],"names":[],"mappings":"AAUA,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,qBAAqB,CAAC,EACpC,SAAS,EACT,WAAW,EACX,QAAQ,EACR,QAAgB,GACjB,EAAE,0BAA0B,kDA6E5B"}
@@ -0,0 +1,33 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from 'react';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { Shield } from 'lucide-react';
6
+ import { cn } from '../../../lib/utils.js';
7
+ import { Label } from '../../ui/label.js';
8
+ import { Badge } from '../../ui/badge.js';
9
+ import { getAgentPermissionOptions } from '../../../app/actions/agent-permissions.js';
10
+ export function AgentPermissionPicker({ agentType, currentMode, onChange, disabled = false, }) {
11
+ const { t } = useTranslation('web');
12
+ const [options, setOptions] = useState([]);
13
+ useEffect(() => {
14
+ let cancelled = false;
15
+ getAgentPermissionOptions(agentType).then((opts) => {
16
+ if (!cancelled)
17
+ setOptions(opts);
18
+ });
19
+ return () => {
20
+ cancelled = true;
21
+ };
22
+ }, [agentType]);
23
+ if (options.length === 0)
24
+ return null;
25
+ // If no currentMode, default to first option
26
+ const selectedMode = currentMode ?? options[0]?.value;
27
+ return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(Shield, { className: "text-muted-foreground h-3.5 w-3.5" }), _jsx(Label, { className: "text-sm", children: t('settings.agent.permissions.title') })] }), _jsx("div", { className: "space-y-1.5", children: options.map((option) => {
28
+ const isSelected = option.value === selectedMode;
29
+ return (_jsxs("button", { type: "button", disabled: disabled, onClick: () => onChange(option.value), "data-testid": `permission-option-${option.value}`, className: cn('flex w-full cursor-pointer items-start gap-3 rounded-md border px-3 py-2.5 text-start transition-colors', isSelected
30
+ ? 'border-primary bg-primary/5'
31
+ : 'border-input hover:border-primary/50 hover:bg-accent/50', disabled && 'cursor-not-allowed opacity-60'), children: [_jsx("span", { className: cn('mt-0.5 flex h-4 w-4 shrink-0 items-center justify-center rounded-full border-2 transition-colors', isSelected ? 'border-primary' : 'border-muted-foreground/40'), children: isSelected ? _jsx("span", { className: "bg-primary h-2 w-2 rounded-full" }) : null }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("span", { className: cn('text-sm font-medium', isSelected && 'text-primary'), children: option.label }), option.batchSafe ? (_jsx(Badge, { variant: "secondary", className: "px-1.5 py-0 text-[10px]", children: t('settings.agent.permissions.batchSafe') })) : (_jsx(Badge, { variant: "outline", className: "px-1.5 py-0 text-[10px]", children: t('settings.agent.permissions.interactiveOnly') }))] }), _jsx("p", { className: "text-muted-foreground mt-0.5 text-xs", children: option.description })] })] }, option.value));
32
+ }) })] }));
33
+ }
@@ -0,0 +1,15 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { AgentPermissionPicker } from './agent-permission-picker.js';
3
+ declare const meta: Meta<typeof AgentPermissionPicker>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof AgentPermissionPicker>;
6
+ export declare const ClaudeCode: Story;
7
+ export declare const Cursor: Story;
8
+ export declare const GeminiCli: Story;
9
+ export declare const CodexCli: Story;
10
+ export declare const CopilotCli: Story;
11
+ export declare const RovoDev: Story;
12
+ export declare const NoSelection: Story;
13
+ export declare const Disabled: Story;
14
+ export declare const Interactive: Story;
15
+ //# sourceMappingURL=agent-permission-picker.stories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-permission-picker.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/settings/agent-permission-picker.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAOlE,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,qBAAqB,CAiB5C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpD,eAAO,MAAM,UAAU,EAAE,KAKxB,CAAC;AAEF,eAAO,MAAM,MAAM,EAAE,KAKpB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAKvB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAKtB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAKxB,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAKrB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAKzB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAMtB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAEzB,CAAC"}
@@ -0,0 +1,75 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useState } from 'react';
3
+ import { fn } from 'storybook/test';
4
+ import { AgentPermissionPicker } from './agent-permission-picker.js';
5
+ function StatefulPicker({ agentType, initialMode }) {
6
+ const [mode, setMode] = useState(initialMode);
7
+ return _jsx(AgentPermissionPicker, { agentType: agentType, currentMode: mode, onChange: setMode });
8
+ }
9
+ const meta = {
10
+ title: 'Features/Settings/AgentPermissionPicker',
11
+ component: AgentPermissionPicker,
12
+ tags: ['autodocs'],
13
+ parameters: {
14
+ layout: 'padded',
15
+ },
16
+ args: {
17
+ onChange: fn(),
18
+ },
19
+ decorators: [
20
+ (Story) => (_jsx("div", { className: "w-[400px]", children: _jsx(Story, {}) })),
21
+ ],
22
+ };
23
+ export default meta;
24
+ export const ClaudeCode = {
25
+ args: {
26
+ agentType: 'claude-code',
27
+ currentMode: 'bypassPermissions',
28
+ },
29
+ };
30
+ export const Cursor = {
31
+ args: {
32
+ agentType: 'cursor',
33
+ currentMode: 'yolo',
34
+ },
35
+ };
36
+ export const GeminiCli = {
37
+ args: {
38
+ agentType: 'gemini-cli',
39
+ currentMode: 'yolo',
40
+ },
41
+ };
42
+ export const CodexCli = {
43
+ args: {
44
+ agentType: 'codex-cli',
45
+ currentMode: 'danger-full-access',
46
+ },
47
+ };
48
+ export const CopilotCli = {
49
+ args: {
50
+ agentType: 'copilot-cli',
51
+ currentMode: 'yolo',
52
+ },
53
+ };
54
+ export const RovoDev = {
55
+ args: {
56
+ agentType: 'rovo-dev',
57
+ currentMode: 'yolo',
58
+ },
59
+ };
60
+ export const NoSelection = {
61
+ args: {
62
+ agentType: 'claude-code',
63
+ currentMode: undefined,
64
+ },
65
+ };
66
+ export const Disabled = {
67
+ args: {
68
+ agentType: 'claude-code',
69
+ currentMode: 'bypassPermissions',
70
+ disabled: true,
71
+ },
72
+ };
73
+ export const Interactive = {
74
+ render: () => _jsx(StatefulPicker, { agentType: "claude-code", initialMode: "bypassPermissions" }),
75
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"agent-settings-section.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/settings/agent-settings-section.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAiB3E,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,wBAAgB,oBAAoB,CAAC,EAAE,KAAK,EAAE,EAAE,yBAAyB,2CA+IxE"}
1
+ {"version":3,"file":"agent-settings-section.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/settings/agent-settings-section.tsx"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yCAAyC,CAAC;AAgB3E,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,WAAW,CAAC;CACpB;AAkBD,wBAAgB,oBAAoB,CAAC,EAAE,KAAK,EAAE,EAAE,yBAAyB,2CAoKxE"}
@@ -9,26 +9,44 @@ import { Input } from '../../ui/input.js';
9
9
  import { Button } from '../../ui/button.js';
10
10
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../../ui/select.js';
11
11
  import { updateSettingsAction } from '../../../app/actions/update-settings.js';
12
+ import { setAgentPermissionMode } from '../../../app/actions/agent-permissions.js';
12
13
  import { AgentType, AgentAuthMethod } from '../../../../../../packages/core/src/domain/generated/output.js';
13
14
  import { getAgentTypeIcon } from '../../common/feature-node/agent-type-icons.js';
15
+ import { AgentPermissionPicker } from './agent-permission-picker.js';
14
16
  const AGENT_TYPE_OPTIONS = [
15
17
  { value: AgentType.ClaudeCode, label: 'Claude Code' },
16
18
  { value: AgentType.CodexCli, label: 'Codex CLI' },
19
+ { value: AgentType.CopilotCli, label: 'GitHub Copilot CLI' },
17
20
  { value: AgentType.Cursor, label: 'Cursor' },
18
21
  { value: AgentType.GeminiCli, label: 'Gemini CLI' },
19
- { value: AgentType.Aider, label: 'Aider' },
20
- { value: AgentType.Continue, label: 'Continue' },
21
- { value: AgentType.Dev, label: 'Dev' },
22
+ { value: AgentType.RovoDev, label: 'Rovo Dev CLI' },
22
23
  ];
23
24
  const AUTH_METHOD_OPTIONS = [
24
25
  { value: AgentAuthMethod.Session, label: 'Session' },
25
26
  { value: AgentAuthMethod.Token, label: 'Token' },
26
27
  ];
28
+ /** Resolve the current permission mode for the active agent from settings. */
29
+ function resolvePermissionMode(agent) {
30
+ const perms = agent.permissions;
31
+ if (!perms)
32
+ return undefined;
33
+ const keyMap = {
34
+ [AgentType.ClaudeCode]: 'claudeCode',
35
+ [AgentType.Cursor]: 'cursor',
36
+ [AgentType.GeminiCli]: 'geminiCli',
37
+ [AgentType.CodexCli]: 'codexCli',
38
+ [AgentType.CopilotCli]: 'copilotCli',
39
+ [AgentType.RovoDev]: 'rovoDev',
40
+ };
41
+ const key = keyMap[agent.type];
42
+ return key ? perms[key] : undefined;
43
+ }
27
44
  export function AgentSettingsSection({ agent }) {
28
45
  const [agentType, setAgentType] = useState(agent.type);
29
46
  const [authMethod, setAuthMethod] = useState(agent.authMethod);
30
47
  const [token, setToken] = useState(agent.token ?? '');
31
48
  const [showToken, setShowToken] = useState(false);
49
+ const [permissionMode, setPermissionMode] = useState(resolvePermissionMode(agent));
32
50
  const [isPending, startTransition] = useTransition();
33
51
  const [showSaved, setShowSaved] = useState(false);
34
52
  const prevPendingRef = useRef(false);
@@ -58,8 +76,18 @@ export function AgentSettingsSection({ agent }) {
58
76
  }
59
77
  function handleAgentTypeChange(value) {
60
78
  setAgentType(value);
79
+ setPermissionMode(undefined); // Reset permission mode when agent changes
61
80
  save(buildPayload({ type: value }));
62
81
  }
82
+ function handlePermissionModeChange(mode) {
83
+ setPermissionMode(mode);
84
+ startTransition(async () => {
85
+ const result = await setAgentPermissionMode(agentType, mode);
86
+ if (!result.success) {
87
+ toast.error(result.error ?? 'Failed to save permission mode');
88
+ }
89
+ });
90
+ }
63
91
  function handleAuthMethodChange(value) {
64
92
  setAuthMethod(value);
65
93
  save(buildPayload({ authMethod: value }));
@@ -72,5 +100,5 @@ export function AgentSettingsSection({ agent }) {
72
100
  return (_jsxs(Card, { id: "agent", className: "scroll-mt-6", "data-testid": "agent-settings-section", children: [_jsxs(CardHeader, { children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Bot, { className: "text-muted-foreground h-4 w-4" }), _jsx(CardTitle, { children: "Preferred Agent" })] }), isPending ? _jsx("span", { className: "text-muted-foreground text-xs", children: "Saving..." }) : null, showSaved && !isPending ? (_jsxs("span", { className: "flex items-center gap-1 text-xs text-green-600", children: [_jsx(Check, { className: "h-3 w-3" }), "Saved"] })) : null] }), _jsx(CardDescription, { children: "Choose your AI coding agent and authentication method" })] }), _jsxs(CardContent, { className: "space-y-4", children: [_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "agent-type", children: "Agent Type" }), _jsxs(Select, { value: agentType, onValueChange: handleAgentTypeChange, children: [_jsx(SelectTrigger, { id: "agent-type", "data-testid": "agent-type-select", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: AGENT_TYPE_OPTIONS.map((opt) => {
73
101
  const Icon = getAgentTypeIcon(opt.value);
74
102
  return (_jsx(SelectItem, { value: opt.value, children: _jsxs("span", { className: "flex items-center gap-2", children: [_jsx(Icon, { className: "h-4 w-4 shrink-0" }), opt.label] }) }, opt.value));
75
- }) })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "auth-method", children: "Authentication Method" }), _jsxs(Select, { value: authMethod, onValueChange: handleAuthMethodChange, children: [_jsx(SelectTrigger, { id: "auth-method", "data-testid": "auth-method-select", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: AUTH_METHOD_OPTIONS.map((opt) => (_jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value))) })] })] }), authMethod === AgentAuthMethod.Token && (_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "agent-token", children: "API Token" }), _jsxs("div", { className: "relative", children: [_jsx(Input, { id: "agent-token", "data-testid": "agent-token-input", type: showToken ? 'text' : 'password', value: token, onChange: (e) => setToken(e.target.value), onBlur: handleTokenBlur, placeholder: "Enter your API token", className: "pe-10" }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "absolute top-0 right-0 h-full px-3 hover:bg-transparent", onClick: () => setShowToken(!showToken), "data-testid": "toggle-token-visibility", "aria-label": showToken ? 'Hide token' : 'Show token', children: showToken ? _jsx(EyeOff, { className: "h-4 w-4" }) : _jsx(Eye, { className: "h-4 w-4" }) })] }), _jsx("p", { className: "text-muted-foreground text-xs", children: "Saves automatically when you leave the field" })] }))] })] }));
103
+ }) })] })] }), _jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "auth-method", children: "Authentication Method" }), _jsxs(Select, { value: authMethod, onValueChange: handleAuthMethodChange, children: [_jsx(SelectTrigger, { id: "auth-method", "data-testid": "auth-method-select", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: AUTH_METHOD_OPTIONS.map((opt) => (_jsx(SelectItem, { value: opt.value, children: opt.label }, opt.value))) })] })] }), _jsx(AgentPermissionPicker, { agentType: agentType, currentMode: permissionMode, onChange: handlePermissionModeChange, disabled: isPending }), authMethod === AgentAuthMethod.Token && (_jsxs("div", { className: "space-y-2", children: [_jsx(Label, { htmlFor: "agent-token", children: "API Token" }), _jsxs("div", { className: "relative", children: [_jsx(Input, { id: "agent-token", "data-testid": "agent-token-input", type: showToken ? 'text' : 'password', value: token, onChange: (e) => setToken(e.target.value), onBlur: handleTokenBlur, placeholder: "Enter your API token", className: "pe-10" }), _jsx(Button, { type: "button", variant: "ghost", size: "sm", className: "absolute top-0 right-0 h-full px-3 hover:bg-transparent", onClick: () => setShowToken(!showToken), "data-testid": "toggle-token-visibility", "aria-label": showToken ? 'Hide token' : 'Show token', children: showToken ? _jsx(EyeOff, { className: "h-4 w-4" }) : _jsx(Eye, { className: "h-4 w-4" }) })] }), _jsx("p", { className: "text-muted-foreground text-xs", children: "Saves automatically when you leave the field" })] }))] })] }));
76
104
  }
@@ -13,5 +13,5 @@ type Story = StoryObj<typeof meta>;
13
13
  export declare const Default: Story;
14
14
  export declare const TokenAuth: Story;
15
15
  export declare const CodexCli: Story;
16
- export declare const AiderSession: Story;
16
+ export declare const CopilotCli: Story;
17
17
  //# sourceMappingURL=agent-settings-section.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agent-settings-section.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/settings/agent-settings-section.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGhE,QAAA,MAAM,IAAI;;;;;;;CAOmC,CAAC;AAE9C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAOrB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAOtB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAO1B,CAAC"}
1
+ {"version":3,"file":"agent-settings-section.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/settings/agent-settings-section.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGhE,QAAA,MAAM,IAAI;;;;;;;CAOmC,CAAC;AAE9C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAOrB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAQvB,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,KAOtB,CAAC;AAEF,eAAO,MAAM,UAAU,EAAE,KAOxB,CAAC"}
@@ -34,10 +34,10 @@ export const CodexCli = {
34
34
  },
35
35
  },
36
36
  };
37
- export const AiderSession = {
37
+ export const CopilotCli = {
38
38
  args: {
39
39
  agent: {
40
- type: AgentType.Aider,
40
+ type: AgentType.CopilotCli,
41
41
  authMethod: AgentAuthMethod.Session,
42
42
  },
43
43
  },
@@ -82,8 +82,8 @@ const mockFeatures = [
82
82
  name: 'User Profile',
83
83
  status: 'done',
84
84
  duration: '1h',
85
- agentType: 'dev',
86
- modelId: 'gpt-8',
85
+ agentType: 'gemini-cli',
86
+ modelId: 'gemini-2.5-pro',
87
87
  repositoryPath: '/home/user/projects/my-app',
88
88
  repositoryName: 'my-app',
89
89
  },
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Resolve a path through `realpath` and return the resolved absolute path,
3
+ * or `null` if the path is missing, unreadable, or cannot be canonicalized
4
+ * for any other reason. Never throws.
5
+ *
6
+ * CodeQL recognizes `realpathSync` output as a sanitizer for
7
+ * `js/path-injection`, so the returned value is safe to flow into `stat`,
8
+ * `readFile`, `readdir`, `spawn`, and other filesystem sinks.
9
+ */
10
+ export declare function realpathOrNull(p: string): string | null;
11
+ /**
12
+ * Pure string containment check: does `resolvedCandidate` live at or
13
+ * beneath `resolvedRoot`? BOTH arguments are expected to already be
14
+ * realpath-resolved absolute paths — this helper does NOT resolve them.
15
+ * Separate the resolve step from the containment check so the caller can
16
+ * resolve once and validate many times without redundant syscalls or
17
+ * TOCTOU windows.
18
+ *
19
+ * Uses forward-slash normalization on both sides before comparing, which
20
+ * is lossless on POSIX (separator is already `/`) and lossless on Windows
21
+ * (where `/` cannot appear inside a path component). This makes the
22
+ * helper safe to use across all three platforms.
23
+ */
24
+ export declare function isWithinRoot(resolvedCandidate: string, resolvedRoot: string): boolean;
25
+ /**
26
+ * Resolve `candidate` through realpath and assert the result lives under
27
+ * at least one of the provided `allowedRoots`. Returns the resolved
28
+ * candidate path on success, or `null` if the candidate cannot be resolved
29
+ * or does not fall under any allowed root.
30
+ *
31
+ * The roots are resolved once, up-front, with graceful fallback to the
32
+ * unresolved form on failure (so a root that does not yet exist on disk
33
+ * is still honored as a literal prefix — this matches the existing
34
+ * behavior of the upload and directory-list routes). If the caller wants
35
+ * strict resolution of the roots too, pre-resolve them with
36
+ * `realpathOrNull` and filter out `null`s before calling this helper.
37
+ */
38
+ export declare function realpathWithinAllowedRoots(candidate: string, allowedRoots: readonly string[]): string | null;
39
+ /**
40
+ * Async variant of `realpathOrNull`. See the sync version for semantics.
41
+ */
42
+ export declare function realpathOrNullAsync(p: string): Promise<string | null>;
43
+ /**
44
+ * Async variant of `realpathWithinAllowedRoots`. See the sync version for
45
+ * semantics. Resolves the candidate and each root concurrently via
46
+ * `Promise.all` so the worst-case wall-clock time is a single realpath,
47
+ * not N of them serialized.
48
+ */
49
+ export declare function realpathWithinAllowedRootsAsync(candidate: string, allowedRoots: readonly string[]): Promise<string | null>;
50
+ //# sourceMappingURL=path-sanitizers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-sanitizers.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/path-sanitizers.ts"],"names":[],"mappings":"AAsCA;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMvD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,iBAAiB,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAIrF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACxC,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,SAAS,MAAM,EAAE,GAC9B,MAAM,GAAG,IAAI,CAWf;AAUD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAO3E;AAED;;;;;GAKG;AACH,wBAAsB,+BAA+B,CACnD,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,SAAS,MAAM,EAAE,GAC9B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAcxB"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Path sanitization helpers for the web presentation layer.
3
+ *
4
+ * Provides the small set of primitives used by every route and server
5
+ * action that touches a user-influenced filesystem path. Each helper
6
+ * does one thing, is recognized by CodeQL's js/path-injection taint
7
+ * analysis as a sanitizer, and is portable across macOS/Linux/Windows.
8
+ *
9
+ * Design principles:
10
+ *
11
+ * - `realpathOrNull(p)` resolves a path through `realpath` and returns
12
+ * `null` on any error (missing file, permission denied, broken symlink).
13
+ * Callers never have to care about the thrown error variants.
14
+ *
15
+ * - `isWithinRoot(candidate, root)` is a pure string containment check
16
+ * that expects both arguments to already be realpath-resolved. It
17
+ * normalizes backslash separators to forward slashes before comparing,
18
+ * so Windows realpath output matches the forward-slash roots that
19
+ * shipit uses throughout the codebase for persistence and comparison.
20
+ *
21
+ * - `realpathWithinAllowedRoots(candidate, roots)` combines the two:
22
+ * resolves the candidate once, resolves each root once (with graceful
23
+ * fallback to the unresolved form for the roots), then checks
24
+ * containment. Returns the resolved candidate on success, `null` on
25
+ * failure. Use this when a value must live under one of several
26
+ * permitted directories (e.g. cwd OR home-dir for the uploads API).
27
+ *
28
+ * These helpers intentionally do NOT compose realpath with the
29
+ * containment check into a single `realpathWithinRoot(candidate, root)`
30
+ * function, because that composition re-resolves an already-resolved
31
+ * root on every nested call and opens a TOCTOU window where filesystem
32
+ * state can change between the resolve and the containment check. Keep
33
+ * realpath and containment separate so the caller can resolve once and
34
+ * validate many.
35
+ */
36
+ import { realpathSync } from 'node:fs';
37
+ import { realpath } from 'node:fs/promises';
38
+ /**
39
+ * Resolve a path through `realpath` and return the resolved absolute path,
40
+ * or `null` if the path is missing, unreadable, or cannot be canonicalized
41
+ * for any other reason. Never throws.
42
+ *
43
+ * CodeQL recognizes `realpathSync` output as a sanitizer for
44
+ * `js/path-injection`, so the returned value is safe to flow into `stat`,
45
+ * `readFile`, `readdir`, `spawn`, and other filesystem sinks.
46
+ */
47
+ export function realpathOrNull(p) {
48
+ try {
49
+ return realpathSync(p);
50
+ }
51
+ catch {
52
+ return null;
53
+ }
54
+ }
55
+ /**
56
+ * Pure string containment check: does `resolvedCandidate` live at or
57
+ * beneath `resolvedRoot`? BOTH arguments are expected to already be
58
+ * realpath-resolved absolute paths — this helper does NOT resolve them.
59
+ * Separate the resolve step from the containment check so the caller can
60
+ * resolve once and validate many times without redundant syscalls or
61
+ * TOCTOU windows.
62
+ *
63
+ * Uses forward-slash normalization on both sides before comparing, which
64
+ * is lossless on POSIX (separator is already `/`) and lossless on Windows
65
+ * (where `/` cannot appear inside a path component). This makes the
66
+ * helper safe to use across all three platforms.
67
+ */
68
+ export function isWithinRoot(resolvedCandidate, resolvedRoot) {
69
+ const normRoot = resolvedRoot.replace(/\\/g, '/');
70
+ const normCandidate = resolvedCandidate.replace(/\\/g, '/');
71
+ return normCandidate === normRoot || normCandidate.startsWith(`${normRoot}/`);
72
+ }
73
+ /**
74
+ * Resolve `candidate` through realpath and assert the result lives under
75
+ * at least one of the provided `allowedRoots`. Returns the resolved
76
+ * candidate path on success, or `null` if the candidate cannot be resolved
77
+ * or does not fall under any allowed root.
78
+ *
79
+ * The roots are resolved once, up-front, with graceful fallback to the
80
+ * unresolved form on failure (so a root that does not yet exist on disk
81
+ * is still honored as a literal prefix — this matches the existing
82
+ * behavior of the upload and directory-list routes). If the caller wants
83
+ * strict resolution of the roots too, pre-resolve them with
84
+ * `realpathOrNull` and filter out `null`s before calling this helper.
85
+ */
86
+ export function realpathWithinAllowedRoots(candidate, allowedRoots) {
87
+ const resolvedCandidate = realpathOrNull(candidate);
88
+ if (!resolvedCandidate)
89
+ return null;
90
+ for (const root of allowedRoots) {
91
+ const resolvedRoot = realpathOrNull(root) ?? root;
92
+ if (isWithinRoot(resolvedCandidate, resolvedRoot)) {
93
+ return resolvedCandidate;
94
+ }
95
+ }
96
+ return null;
97
+ }
98
+ // ─── Async variants ─────────────────────────────────────────────────────
99
+ //
100
+ // Route handlers that already use async fs APIs should use these rather
101
+ // than the sync variants so they don't block the event loop under
102
+ // concurrent load. The async helpers mirror the sync ones exactly in
103
+ // semantics — same null-on-error contract, same normalization, same
104
+ // containment rules.
105
+ /**
106
+ * Async variant of `realpathOrNull`. See the sync version for semantics.
107
+ */
108
+ export async function realpathOrNullAsync(p) {
109
+ try {
110
+ // codeql[js/path-injection] -- this function IS the sanitizer: callers gate access via isWithinRoot containment checks on the resolved result
111
+ return await realpath(p);
112
+ }
113
+ catch {
114
+ return null;
115
+ }
116
+ }
117
+ /**
118
+ * Async variant of `realpathWithinAllowedRoots`. See the sync version for
119
+ * semantics. Resolves the candidate and each root concurrently via
120
+ * `Promise.all` so the worst-case wall-clock time is a single realpath,
121
+ * not N of them serialized.
122
+ */
123
+ export async function realpathWithinAllowedRootsAsync(candidate, allowedRoots) {
124
+ const [resolvedCandidate, ...resolvedRoots] = await Promise.all([
125
+ realpathOrNullAsync(candidate),
126
+ ...allowedRoots.map((r) => realpathOrNullAsync(r)),
127
+ ]);
128
+ if (!resolvedCandidate)
129
+ return null;
130
+ for (let i = 0; i < resolvedRoots.length; i++) {
131
+ const resolvedRoot = resolvedRoots[i] ?? allowedRoots[i];
132
+ if (isWithinRoot(resolvedCandidate, resolvedRoot)) {
133
+ return resolvedCandidate;
134
+ }
135
+ }
136
+ return null;
137
+ }