@shipit-ai/cli 1.166.2 → 1.167.1

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 (506) 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 +2 -0
  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/settings-reader.service.d.ts +7 -0
  121. package/dist/packages/core/src/infrastructure/services/settings-reader.service.d.ts.map +1 -0
  122. package/dist/packages/core/src/infrastructure/services/settings-reader.service.js +25 -0
  123. package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
  124. package/dist/src/presentation/cli/commands/feat/new.command.js +18 -0
  125. package/dist/src/presentation/cli/commands/feat/show.command.d.ts.map +1 -1
  126. package/dist/src/presentation/cli/commands/feat/show.command.js +2 -1
  127. package/dist/src/presentation/cli/commands/settings/agent.command.js +2 -2
  128. package/dist/src/presentation/cli/commands/settings/index.d.ts.map +1 -1
  129. package/dist/src/presentation/cli/commands/settings/index.js +3 -1
  130. package/dist/src/presentation/cli/commands/settings/permission-modes.d.ts +19 -0
  131. package/dist/src/presentation/cli/commands/settings/permission-modes.d.ts.map +1 -0
  132. package/dist/src/presentation/cli/commands/settings/permission-modes.js +38 -0
  133. package/dist/src/presentation/cli/commands/settings/permissions.command.d.ts +16 -0
  134. package/dist/src/presentation/cli/commands/settings/permissions.command.d.ts.map +1 -0
  135. package/dist/src/presentation/cli/commands/settings/permissions.command.js +147 -0
  136. package/dist/src/presentation/tui/prompts/agent-select.prompt.d.ts +4 -10
  137. package/dist/src/presentation/tui/prompts/agent-select.prompt.d.ts.map +1 -1
  138. package/dist/src/presentation/tui/prompts/agent-select.prompt.js +8 -13
  139. package/dist/src/presentation/tui/wizards/onboarding/onboarding.wizard.d.ts +5 -3
  140. package/dist/src/presentation/tui/wizards/onboarding/onboarding.wizard.d.ts.map +1 -1
  141. package/dist/src/presentation/tui/wizards/onboarding/onboarding.wizard.js +10 -5
  142. package/dist/src/presentation/tui/wizards/onboarding/steps/agent-permissions.step.d.ts +17 -0
  143. package/dist/src/presentation/tui/wizards/onboarding/steps/agent-permissions.step.d.ts.map +1 -0
  144. package/dist/src/presentation/tui/wizards/onboarding/steps/agent-permissions.step.js +48 -0
  145. package/dist/src/presentation/tui/wizards/onboarding/types.d.ts +2 -0
  146. package/dist/src/presentation/tui/wizards/onboarding/types.d.ts.map +1 -1
  147. package/dist/src/presentation/web/app/actions/agent-permissions.d.ts +14 -0
  148. package/dist/src/presentation/web/app/actions/agent-permissions.d.ts.map +1 -0
  149. package/dist/src/presentation/web/app/actions/agent-permissions.js +181 -0
  150. package/dist/src/presentation/web/app/actions/check-agent-auth.d.ts.map +1 -1
  151. package/dist/src/presentation/web/app/actions/check-agent-auth.js +2 -5
  152. package/dist/src/presentation/web/app/actions/check-agent-tool.js +1 -1
  153. package/dist/src/presentation/web/app/actions/get-all-agent-models.d.ts.map +1 -1
  154. package/dist/src/presentation/web/app/actions/get-all-agent-models.js +2 -17
  155. package/dist/src/presentation/web/app/actions/get-merge-review-data.d.ts.map +1 -1
  156. package/dist/src/presentation/web/app/actions/get-merge-review-data.js +5 -0
  157. package/dist/src/presentation/web/app/actions/open-shell.d.ts.map +1 -1
  158. package/dist/src/presentation/web/app/actions/open-shell.js +5 -0
  159. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts.map +1 -1
  160. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +43 -9
  161. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  162. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +1 -1
  163. package/dist/src/presentation/web/components/common/feature-create-drawer/types.d.ts +2 -0
  164. package/dist/src/presentation/web/components/common/feature-create-drawer/types.d.ts.map +1 -1
  165. package/dist/src/presentation/web/components/common/feature-create-drawer/use-feature-create-form.d.ts +2 -0
  166. package/dist/src/presentation/web/components/common/feature-create-drawer/use-feature-create-form.d.ts.map +1 -1
  167. package/dist/src/presentation/web/components/common/feature-create-drawer/use-feature-create-form.js +6 -0
  168. package/dist/src/presentation/web/components/common/feature-create-drawer/workflow-options-section.d.ts +7 -1
  169. package/dist/src/presentation/web/components/common/feature-create-drawer/workflow-options-section.d.ts.map +1 -1
  170. package/dist/src/presentation/web/components/common/feature-create-drawer/workflow-options-section.js +24 -3
  171. package/dist/src/presentation/web/components/common/feature-create-drawer/workflow-options-section.stories.d.ts.map +1 -1
  172. package/dist/src/presentation/web/components/common/feature-create-drawer/workflow-options-section.stories.js +3 -0
  173. package/dist/src/presentation/web/components/common/feature-list-item/feature-list-item.stories.js +2 -2
  174. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.d.ts +2 -2
  175. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.d.ts.map +1 -1
  176. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.js +4 -11
  177. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.stories.d.ts +1 -1
  178. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.stories.d.ts.map +1 -1
  179. package/dist/src/presentation/web/components/common/feature-node/agent-type-icons.stories.js +5 -6
  180. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +2 -0
  181. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
  182. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  183. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +2 -2
  184. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +10 -10
  185. package/dist/src/presentation/web/components/features/control-center/control-center.stories.js +1 -1
  186. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.js +2 -2
  187. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.d.ts +1 -1
  188. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.d.ts.map +1 -1
  189. package/dist/src/presentation/web/components/features/settings/AgentModelPicker/AgentModelPicker.stories.js +3 -3
  190. package/dist/src/presentation/web/components/features/settings/agent-permission-picker.d.ts +8 -0
  191. package/dist/src/presentation/web/components/features/settings/agent-permission-picker.d.ts.map +1 -0
  192. package/dist/src/presentation/web/components/features/settings/agent-permission-picker.js +33 -0
  193. package/dist/src/presentation/web/components/features/settings/agent-permission-picker.stories.d.ts +15 -0
  194. package/dist/src/presentation/web/components/features/settings/agent-permission-picker.stories.d.ts.map +1 -0
  195. package/dist/src/presentation/web/components/features/settings/agent-permission-picker.stories.js +75 -0
  196. package/dist/src/presentation/web/components/features/settings/agent-settings-section.d.ts.map +1 -1
  197. package/dist/src/presentation/web/components/features/settings/agent-settings-section.js +32 -4
  198. package/dist/src/presentation/web/components/features/settings/agent-settings-section.stories.d.ts +1 -1
  199. package/dist/src/presentation/web/components/features/settings/agent-settings-section.stories.d.ts.map +1 -1
  200. package/dist/src/presentation/web/components/features/settings/agent-settings-section.stories.js +2 -2
  201. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.stories.js +2 -2
  202. package/dist/src/presentation/web/lib/path-sanitizers.d.ts.map +1 -1
  203. package/dist/src/presentation/web/lib/path-sanitizers.js +5 -0
  204. package/dist/translations/ar/cli.json +16 -0
  205. package/dist/translations/ar/tui.json +12 -10
  206. package/dist/translations/ar/web.json +15 -0
  207. package/dist/translations/de/cli.json +16 -0
  208. package/dist/translations/de/tui.json +13 -5
  209. package/dist/translations/de/web.json +15 -0
  210. package/dist/translations/en/cli.json +16 -0
  211. package/dist/translations/en/tui.json +12 -10
  212. package/dist/translations/en/web.json +15 -0
  213. package/dist/translations/es/cli.json +16 -0
  214. package/dist/translations/es/tui.json +12 -10
  215. package/dist/translations/es/web.json +15 -0
  216. package/dist/translations/fr/cli.json +16 -0
  217. package/dist/translations/fr/tui.json +12 -10
  218. package/dist/translations/fr/web.json +15 -0
  219. package/dist/translations/he/cli.json +16 -0
  220. package/dist/translations/he/tui.json +12 -10
  221. package/dist/translations/he/web.json +15 -0
  222. package/dist/translations/pt/cli.json +16 -0
  223. package/dist/translations/pt/tui.json +12 -10
  224. package/dist/translations/pt/web.json +15 -0
  225. package/dist/translations/ru/cli.json +16 -0
  226. package/dist/translations/ru/tui.json +12 -10
  227. package/dist/translations/ru/web.json +15 -0
  228. package/dist/tsconfig.build.tsbuildinfo +1 -1
  229. package/package.json +1 -1
  230. package/web/.next/BUILD_ID +1 -1
  231. package/web/.next/build-manifest.json +3 -3
  232. package/web/.next/fallback-build-manifest.json +3 -3
  233. package/web/.next/prerender-manifest.json +3 -3
  234. package/web/.next/required-server-files.js +2 -2
  235. package/web/.next/required-server-files.json +2 -2
  236. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
  237. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +2 -3
  238. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  239. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  240. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
  241. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js +2 -3
  242. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  243. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  244. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +72 -60
  245. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +3 -3
  246. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  247. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  248. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
  249. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +3 -4
  250. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  251. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  252. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +37 -37
  253. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +3 -4
  254. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  255. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  256. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  257. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js +2 -3
  258. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  259. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  260. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  261. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +2 -3
  262. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  263. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  264. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
  265. package/web/.next/server/app/(dashboard)/chat/page.js +2 -3
  266. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  267. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  268. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +72 -60
  269. package/web/.next/server/app/(dashboard)/create/page.js +3 -3
  270. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  271. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  272. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
  273. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +3 -4
  274. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  275. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  276. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +37 -37
  277. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +3 -4
  278. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  279. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  280. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
  281. package/web/.next/server/app/(dashboard)/page.js +2 -3
  282. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  283. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  284. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  285. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js +2 -3
  286. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  287. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  288. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  289. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +2 -3
  290. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  291. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  292. package/web/.next/server/app/_global-error.html +1 -1
  293. package/web/.next/server/app/_global-error.rsc +1 -1
  294. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  295. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  296. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  297. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  298. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  299. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
  300. package/web/.next/server/app/_not-found/page.js +2 -3
  301. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  302. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  303. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  304. package/web/.next/server/app/api/dialog/pick-files/route.js.nft.json +1 -1
  305. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  306. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  307. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  308. package/web/.next/server/app/settings/page/server-reference-manifest.json +11 -11
  309. package/web/.next/server/app/settings/page.js +3 -4
  310. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  311. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  312. package/web/.next/server/app/skills/page/server-reference-manifest.json +11 -11
  313. package/web/.next/server/app/skills/page.js +3 -3
  314. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  315. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  316. package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
  317. package/web/.next/server/app/tools/page.js +3 -3
  318. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  319. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  320. package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
  321. package/web/.next/server/app/version/page.js +2 -3
  322. package/web/.next/server/app/version/page.js.nft.json +1 -1
  323. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  324. package/web/.next/server/chunks/11es_next_dist_esm_build_templates_app-route_067cwst.js +1 -1
  325. package/web/.next/server/chunks/11es_next_dist_esm_build_templates_app-route_067cwst.js.map +1 -1
  326. package/web/.next/server/chunks/[root-of-the-server]__0_-chcy._.js.map +1 -1
  327. package/web/.next/server/chunks/[root-of-the-server]__0e9p7em._.js.map +1 -1
  328. package/web/.next/server/chunks/[root-of-the-server]__0tb~wwk._.js +1 -1
  329. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_create-drawer-client_tsx_0g70fc5._.js +1 -1
  330. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_create-drawer-client_tsx_0g70fc5._.js.map +1 -1
  331. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_feature-drawer-client_tsx_104cna.._.js +2 -2
  332. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_feature-drawer-client_tsx_104cna.._.js.map +1 -1
  333. package/web/.next/server/chunks/ssr/0ukq_presentation_web_components_features_settings_settings-page-client_tsx_0j1uius._.js +1 -1
  334. package/web/.next/server/chunks/ssr/0ukq_presentation_web_components_features_settings_settings-page-client_tsx_0j1uius._.js.map +1 -1
  335. package/web/.next/server/chunks/ssr/{_01mq~sm._.js → 11es_next_0q-kz~8._.js} +2 -2
  336. package/web/.next/server/chunks/ssr/11es_next_0q-kz~8._.js.map +1 -0
  337. package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_repository-drawer-client_tsx_09z.znp._.js +1 -1
  338. package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_repository-drawer-client_tsx_09z.znp._.js.map +1 -1
  339. package/web/.next/server/chunks/ssr/[root-of-the-server]__02.89uf._.js +4 -0
  340. package/web/.next/server/chunks/ssr/[root-of-the-server]__02.89uf._.js.map +1 -0
  341. package/web/.next/server/chunks/ssr/[root-of-the-server]__04rq9lr._.js +4 -0
  342. package/web/.next/server/chunks/ssr/[root-of-the-server]__04rq9lr._.js.map +1 -0
  343. package/web/.next/server/chunks/ssr/[root-of-the-server]__05_qc0n._.js +4 -0
  344. package/web/.next/server/chunks/ssr/[root-of-the-server]__05_qc0n._.js.map +1 -0
  345. package/web/.next/server/chunks/ssr/[root-of-the-server]__0c0xoi_._.js +3 -0
  346. package/web/.next/server/chunks/ssr/[root-of-the-server]__0c0xoi_._.js.map +1 -0
  347. package/web/.next/server/chunks/ssr/[root-of-the-server]__0r5zhk.._.js +4 -0
  348. package/web/.next/server/chunks/ssr/[root-of-the-server]__0r5zhk.._.js.map +1 -0
  349. package/web/.next/server/chunks/ssr/[root-of-the-server]__0rv1gci._.js +1 -1
  350. package/web/.next/server/chunks/ssr/[root-of-the-server]__0rvrr1j._.js +4 -0
  351. package/web/.next/server/chunks/ssr/[root-of-the-server]__0rvrr1j._.js.map +1 -0
  352. package/web/.next/server/chunks/ssr/[root-of-the-server]__0tq2syh._.js +4 -0
  353. package/web/.next/server/chunks/ssr/[root-of-the-server]__0tq2syh._.js.map +1 -0
  354. package/web/.next/server/chunks/ssr/[root-of-the-server]__0uy_5rw._.js +4 -0
  355. package/web/.next/server/chunks/ssr/[root-of-the-server]__0uy_5rw._.js.map +1 -0
  356. package/web/.next/server/chunks/ssr/[root-of-the-server]__12j29w-._.js +4 -0
  357. package/web/.next/server/chunks/ssr/[root-of-the-server]__12j29w-._.js.map +1 -0
  358. package/web/.next/server/chunks/ssr/{_04rrcmm._.js → _0-.ckn5._.js} +2 -2
  359. package/web/.next/server/chunks/ssr/_0-.ckn5._.js.map +1 -0
  360. package/web/.next/server/chunks/ssr/_00k65h-._.js.map +1 -1
  361. package/web/.next/server/chunks/ssr/_01sesw0._.js +1 -1
  362. package/web/.next/server/chunks/ssr/_01sesw0._.js.map +1 -1
  363. package/web/.next/server/chunks/ssr/_069y.js._.js +6 -0
  364. package/web/.next/server/chunks/ssr/_069y.js._.js.map +1 -0
  365. package/web/.next/server/chunks/ssr/_0__4si~._.js +4 -0
  366. package/web/.next/server/chunks/ssr/_0__4si~._.js.map +1 -0
  367. package/web/.next/server/chunks/ssr/_0_m17kl._.js +4 -0
  368. package/web/.next/server/chunks/ssr/_0_m17kl._.js.map +1 -0
  369. package/web/.next/server/chunks/ssr/_0aaotn-._.js +3 -0
  370. package/web/.next/server/chunks/ssr/_0aaotn-._.js.map +1 -0
  371. package/web/.next/server/chunks/ssr/_0d4miu.._.js +4 -0
  372. package/web/.next/server/chunks/ssr/_0d4miu.._.js.map +1 -0
  373. package/web/.next/server/chunks/ssr/_0e8ern9._.js +4 -0
  374. package/web/.next/server/chunks/ssr/_0e8ern9._.js.map +1 -0
  375. package/web/.next/server/chunks/ssr/{_109n-y4._.js → _0n.magx._.js} +2 -2
  376. package/web/.next/server/chunks/ssr/_0n.magx._.js.map +1 -0
  377. package/web/.next/server/chunks/ssr/_0p3~u8u._.js +6 -0
  378. package/web/.next/server/chunks/ssr/_0p3~u8u._.js.map +1 -0
  379. package/web/.next/server/chunks/ssr/_0r.3n~3._.js +4 -0
  380. package/web/.next/server/chunks/ssr/_0r.3n~3._.js.map +1 -0
  381. package/web/.next/server/chunks/ssr/_0t59q8r._.js +4 -0
  382. package/web/.next/server/chunks/ssr/_0t59q8r._.js.map +1 -0
  383. package/web/.next/server/chunks/ssr/_0tcccbb._.js +3 -0
  384. package/web/.next/server/chunks/ssr/_0tcccbb._.js.map +1 -0
  385. package/web/.next/server/chunks/ssr/_0vyfc4b._.js +1 -1
  386. package/web/.next/server/chunks/ssr/_0vyfc4b._.js.map +1 -1
  387. package/web/.next/server/chunks/ssr/_0w-_hww._.js +1 -1
  388. package/web/.next/server/chunks/ssr/_0w-_hww._.js.map +1 -1
  389. package/web/.next/server/chunks/ssr/_0zk-h5w._.js +4 -0
  390. package/web/.next/server/chunks/ssr/_0zk-h5w._.js.map +1 -0
  391. package/web/.next/server/chunks/ssr/_0~7lwu_._.js +1 -1
  392. package/web/.next/server/chunks/ssr/_0~7lwu_._.js.map +1 -1
  393. package/web/.next/server/chunks/ssr/_1161g9x._.js +4 -0
  394. package/web/.next/server/chunks/ssr/_1161g9x._.js.map +1 -0
  395. package/web/.next/server/chunks/ssr/{_0c497sr._.js → _138qywk._.js} +2 -2
  396. package/web/.next/server/chunks/ssr/{_0c497sr._.js.map → _138qywk._.js.map} +1 -1
  397. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_05m2q~u.js +3 -0
  398. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_05m2q~u.js.map +1 -0
  399. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_0.6zk.t.js +3 -0
  400. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_0.6zk.t.js.map +1 -0
  401. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_approve-feature_ts_0pjb_re._.js +1 -1
  402. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_approve-feature_ts_0pjb_re._.js.map +1 -1
  403. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_0w2wqvu._.js +1 -1
  404. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_0w2wqvu._.js.map +1 -1
  405. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_0l3oxx9._.js +1 -1
  406. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_0l3oxx9._.js.map +1 -1
  407. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_0aji.op._.js +1 -1
  408. package/web/.next/server/middleware-build-manifest.js +3 -3
  409. package/web/.next/server/pages/500.html +1 -1
  410. package/web/.next/server/server-reference-manifest.js +1 -1
  411. package/web/.next/server/server-reference-manifest.json +127 -109
  412. package/web/.next/static/chunks/0-woqr2brccx_.js +3 -0
  413. package/web/.next/static/chunks/{0ex35-_jtxyjc.js → 022nrd6snse79.js} +1 -1
  414. package/web/.next/static/chunks/{0t_6hx6ul7umb.js → 02phgt~f2c-2q.js} +1 -1
  415. package/web/.next/static/chunks/{0whez3wju~9ok.js → 03s7z6w1lj0w~.js} +1 -1
  416. package/web/.next/static/chunks/04~sw.nhpwy6s.css +1 -0
  417. package/web/.next/static/chunks/05enics63g._-.js +7 -0
  418. package/web/.next/static/chunks/08611baheit.t.js +1 -0
  419. package/web/.next/static/chunks/0_9k2ybutuphq.js +1 -0
  420. package/web/.next/static/chunks/{0oq-cvtg8rjjp.js → 0j.wph28jrce1.js} +1 -1
  421. package/web/.next/static/chunks/{0k~55i.ofbdeb.js → 0ls0v8h_qbctm.js} +1 -1
  422. package/web/.next/static/chunks/0ma7k9iohb3bb.js +1 -0
  423. package/web/.next/static/chunks/0ps5sykbi-z5-.js +1 -0
  424. package/web/.next/static/chunks/{0c_bi0dck80dt.js → 0q7ohuqneuur4.js} +1 -1
  425. package/web/.next/static/chunks/{07gx-h_y91lay.js → 0q8ax~44oybo2.js} +2 -2
  426. package/web/.next/static/chunks/15rbgqykl.er8.js +1 -0
  427. package/web/.next/static/chunks/{04xk1iouwcfcq.js → 17z2sq7c5z8cr.js} +3 -3
  428. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.d.ts +0 -12
  429. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.d.ts.map +0 -1
  430. package/dist/packages/core/src/infrastructure/services/agents/common/executors/dev-executor.service.js +0 -233
  431. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/plan.fixture.d.ts +0 -8
  432. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/plan.fixture.d.ts.map +0 -1
  433. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/plan.fixture.js +0 -94
  434. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/research.fixture.d.ts +0 -8
  435. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/research.fixture.d.ts.map +0 -1
  436. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/research.fixture.js +0 -140
  437. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/spec-analyze.fixture.d.ts +0 -8
  438. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/spec-analyze.fixture.d.ts.map +0 -1
  439. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/spec-analyze.fixture.js +0 -81
  440. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/spec-requirements.fixture.d.ts +0 -8
  441. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/spec-requirements.fixture.d.ts.map +0 -1
  442. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/spec-requirements.fixture.js +0 -131
  443. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/tasks.fixture.d.ts +0 -6
  444. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/tasks.fixture.d.ts.map +0 -1
  445. package/dist/packages/core/src/infrastructure/services/agents/common/executors/fixtures/tasks.fixture.js +0 -146
  446. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_00~eq5i.js +0 -3
  447. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_00~eq5i.js.map +0 -1
  448. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_0979_c..js +0 -3
  449. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_0979_c..js.map +0 -1
  450. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_chat_page_actions_0dqll_1.js +0 -3
  451. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_chat_page_actions_0dqll_1.js.map +0 -1
  452. package/web/.next/server/chunks/ssr/[root-of-the-server]__04nnbmc._.js +0 -3
  453. package/web/.next/server/chunks/ssr/[root-of-the-server]__04nnbmc._.js.map +0 -1
  454. package/web/.next/server/chunks/ssr/[root-of-the-server]__07740t6._.js +0 -3
  455. package/web/.next/server/chunks/ssr/[root-of-the-server]__07740t6._.js.map +0 -1
  456. package/web/.next/server/chunks/ssr/[root-of-the-server]__0l~puw4._.js +0 -3
  457. package/web/.next/server/chunks/ssr/[root-of-the-server]__0l~puw4._.js.map +0 -1
  458. package/web/.next/server/chunks/ssr/[root-of-the-server]__0o3qggc._.js +0 -3
  459. package/web/.next/server/chunks/ssr/[root-of-the-server]__0o3qggc._.js.map +0 -1
  460. package/web/.next/server/chunks/ssr/[root-of-the-server]__0vwjc_m._.js +0 -3
  461. package/web/.next/server/chunks/ssr/[root-of-the-server]__0vwjc_m._.js.map +0 -1
  462. package/web/.next/server/chunks/ssr/[root-of-the-server]__0w4__yd._.js +0 -4
  463. package/web/.next/server/chunks/ssr/[root-of-the-server]__0w4__yd._.js.map +0 -1
  464. package/web/.next/server/chunks/ssr/_0.rsra~._.js +0 -3
  465. package/web/.next/server/chunks/ssr/_0.rsra~._.js.map +0 -1
  466. package/web/.next/server/chunks/ssr/_01mq~sm._.js.map +0 -1
  467. package/web/.next/server/chunks/ssr/_04rrcmm._.js.map +0 -1
  468. package/web/.next/server/chunks/ssr/_0c741v_._.js +0 -3
  469. package/web/.next/server/chunks/ssr/_0c741v_._.js.map +0 -1
  470. package/web/.next/server/chunks/ssr/_0jpbsh_._.js +0 -4
  471. package/web/.next/server/chunks/ssr/_0jpbsh_._.js.map +0 -1
  472. package/web/.next/server/chunks/ssr/_109n-y4._.js.map +0 -1
  473. package/web/.next/server/chunks/ssr/src_presentation_web_0.e4~xc._.js +0 -3
  474. package/web/.next/server/chunks/ssr/src_presentation_web_0.e4~xc._.js.map +0 -1
  475. package/web/.next/server/chunks/ssr/src_presentation_web_00dvh.m._.js +0 -3
  476. package/web/.next/server/chunks/ssr/src_presentation_web_00dvh.m._.js.map +0 -1
  477. package/web/.next/server/chunks/ssr/src_presentation_web_06b6~lt._.js +0 -5
  478. package/web/.next/server/chunks/ssr/src_presentation_web_06b6~lt._.js.map +0 -1
  479. package/web/.next/server/chunks/ssr/src_presentation_web_08fy2mf._.js +0 -3
  480. package/web/.next/server/chunks/ssr/src_presentation_web_08fy2mf._.js.map +0 -1
  481. package/web/.next/server/chunks/ssr/src_presentation_web_0f~udu1._.js +0 -3
  482. package/web/.next/server/chunks/ssr/src_presentation_web_0f~udu1._.js.map +0 -1
  483. package/web/.next/server/chunks/ssr/src_presentation_web_0qys821._.js +0 -5
  484. package/web/.next/server/chunks/ssr/src_presentation_web_0qys821._.js.map +0 -1
  485. package/web/.next/server/chunks/ssr/src_presentation_web_0q~dt0o._.js +0 -3
  486. package/web/.next/server/chunks/ssr/src_presentation_web_0q~dt0o._.js.map +0 -1
  487. package/web/.next/server/chunks/ssr/src_presentation_web_11jrkxt._.js +0 -3
  488. package/web/.next/server/chunks/ssr/src_presentation_web_11jrkxt._.js.map +0 -1
  489. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_1199d3x.js +0 -3
  490. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_1199d3x.js.map +0 -1
  491. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app__not-found_page_actions_0m2jqxx.js +0 -3
  492. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app__not-found_page_actions_0m2jqxx.js.map +0 -1
  493. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_version_page_actions_0krkh_0.js +0 -3
  494. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_version_page_actions_0krkh_0.js.map +0 -1
  495. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_load-settings_ts_0b8f3pf._.js +0 -3
  496. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_load-settings_ts_0b8f3pf._.js.map +0 -1
  497. package/web/.next/static/chunks/0-fy~80ui.5os.js +0 -7
  498. package/web/.next/static/chunks/039ic1ygq-to3.js +0 -1
  499. package/web/.next/static/chunks/07a4jt64wdipb.js +0 -1
  500. package/web/.next/static/chunks/0_imq4rg3q.fe.js +0 -3
  501. package/web/.next/static/chunks/0i084mozx131g.js +0 -1
  502. package/web/.next/static/chunks/0j_0i2qsrwh-c.js +0 -1
  503. package/web/.next/static/chunks/0r5dju6f1-i38.css +0 -1
  504. /package/web/.next/static/{ynyh_sSxbFA995FRvBUxs → GSG_c1emY-f_AA00vD56y}/_buildManifest.js +0 -0
  505. /package/web/.next/static/{ynyh_sSxbFA995FRvBUxs → GSG_c1emY-f_AA00vD56y}/_clientMiddlewareManifest.js +0 -0
  506. /package/web/.next/static/{ynyh_sSxbFA995FRvBUxs → GSG_c1emY-f_AA00vD56y}/_ssgManifest.js +0 -0
@@ -0,0 +1,3 @@
1
+ module.exports=[14937,a=>{"use strict";var b=a.i(23504),c=a.i(27900),d=a.i(12513),e=a.i(73101),f=a.i(54775),g=a.i(65324),h=a.i(94691),i=a.i(33841),j=a.i(46646),k=a.i(68670),l=a.i(85321);a.s([],96302),a.i(96302),a.s(["000e07b0fee197bbb9883c456356a27dd5a461fa0c",()=>f.listGitHubOrganizations,"0086c5b619a2c7688c2d770674d578f317e0551f3a",()=>b.getAllAgentModels,"00ea228127ac18606161ce9cb8812c4f137123b655",()=>d.pickFolder,"402d65513b1f6015d46a7c893966623bcf1c9a8c43",()=>h.getDeploymentLogs,"404b5999bc6f96926423c290ad57510ec557128832",()=>i.deployFeature,"404ef28f7033751ea5088eeb4eed9d603e6408c9ff",()=>e.listGitHubRepositories,"40e192a818a5b7bc1a5380b2a3a023ee6fa5bd962b",()=>l.getDeploymentStatus,"40e59c0a6c3e3a01829eb5f700ab316233fff8bf04",()=>j.deployRepository,"40edd08872ca1b2ff19b22b0c1da3d720f7133c7ab",()=>k.stopDeployment,"40f9f1c6b44ed613d89ca546ee32fc98aac07d88eb",()=>g.importGitHubRepository,"60e03e2b32b2e6ef0f3959da5f546f1829e41c0331",()=>c.updateAgentAndModel],14937)}];
2
+
3
+ //# sourceMappingURL=src_presentation_web__next-internal_server_app_skills_page_actions_05m2q~u.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../src/presentation/web/.next-internal/server/app/skills/page/actions.js%20%28server%20actions%20loader%29"],"sourcesContent":["export {getAllAgentModels as '0086c5b619a2c7688c2d770674d578f317e0551f3a'} from 'ACTIONS_MODULE0'\nexport {updateAgentAndModel as '60e03e2b32b2e6ef0f3959da5f546f1829e41c0331'} from 'ACTIONS_MODULE1'\nexport {pickFolder as '00ea228127ac18606161ce9cb8812c4f137123b655'} from 'ACTIONS_MODULE2'\nexport {listGitHubRepositories as '404ef28f7033751ea5088eeb4eed9d603e6408c9ff'} from 'ACTIONS_MODULE3'\nexport {listGitHubOrganizations as '000e07b0fee197bbb9883c456356a27dd5a461fa0c'} from 'ACTIONS_MODULE4'\nexport {importGitHubRepository as '40f9f1c6b44ed613d89ca546ee32fc98aac07d88eb'} from 'ACTIONS_MODULE5'\nexport {getDeploymentLogs as '402d65513b1f6015d46a7c893966623bcf1c9a8c43'} from 'ACTIONS_MODULE6'\nexport {deployFeature as '404b5999bc6f96926423c290ad57510ec557128832'} from 'ACTIONS_MODULE7'\nexport {deployRepository as '40e59c0a6c3e3a01829eb5f700ab316233fff8bf04'} from 'ACTIONS_MODULE8'\nexport {stopDeployment as '40edd08872ca1b2ff19b22b0c1da3d720f7133c7ab'} from 'ACTIONS_MODULE9'\nexport {getDeploymentStatus as '40e192a818a5b7bc1a5380b2a3a023ee6fa5bd962b'} from 'ACTIONS_MODULE10'\n"],"names":[],"mappings":"uCAAA,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA"}
@@ -0,0 +1,3 @@
1
+ module.exports=[21171,a=>{"use strict";var b=a.i(23504),c=a.i(27900),d=a.i(12513),e=a.i(73101),f=a.i(54775),g=a.i(65324),h=a.i(94691),i=a.i(33841),j=a.i(46646),k=a.i(68670),l=a.i(85321);a.s([],22977),a.i(22977),a.s(["000e07b0fee197bbb9883c456356a27dd5a461fa0c",()=>f.listGitHubOrganizations,"0086c5b619a2c7688c2d770674d578f317e0551f3a",()=>b.getAllAgentModels,"00ea228127ac18606161ce9cb8812c4f137123b655",()=>d.pickFolder,"402d65513b1f6015d46a7c893966623bcf1c9a8c43",()=>h.getDeploymentLogs,"404b5999bc6f96926423c290ad57510ec557128832",()=>i.deployFeature,"404ef28f7033751ea5088eeb4eed9d603e6408c9ff",()=>e.listGitHubRepositories,"40e192a818a5b7bc1a5380b2a3a023ee6fa5bd962b",()=>l.getDeploymentStatus,"40e59c0a6c3e3a01829eb5f700ab316233fff8bf04",()=>j.deployRepository,"40edd08872ca1b2ff19b22b0c1da3d720f7133c7ab",()=>k.stopDeployment,"40f9f1c6b44ed613d89ca546ee32fc98aac07d88eb",()=>g.importGitHubRepository,"60e03e2b32b2e6ef0f3959da5f546f1829e41c0331",()=>c.updateAgentAndModel],21171)}];
2
+
3
+ //# sourceMappingURL=src_presentation_web__next-internal_server_app_tools_page_actions_0.6zk.t.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../src/presentation/web/.next-internal/server/app/tools/page/actions.js%20%28server%20actions%20loader%29"],"sourcesContent":["export {getAllAgentModels as '0086c5b619a2c7688c2d770674d578f317e0551f3a'} from 'ACTIONS_MODULE0'\nexport {updateAgentAndModel as '60e03e2b32b2e6ef0f3959da5f546f1829e41c0331'} from 'ACTIONS_MODULE1'\nexport {pickFolder as '00ea228127ac18606161ce9cb8812c4f137123b655'} from 'ACTIONS_MODULE2'\nexport {listGitHubRepositories as '404ef28f7033751ea5088eeb4eed9d603e6408c9ff'} from 'ACTIONS_MODULE3'\nexport {listGitHubOrganizations as '000e07b0fee197bbb9883c456356a27dd5a461fa0c'} from 'ACTIONS_MODULE4'\nexport {importGitHubRepository as '40f9f1c6b44ed613d89ca546ee32fc98aac07d88eb'} from 'ACTIONS_MODULE5'\nexport {getDeploymentLogs as '402d65513b1f6015d46a7c893966623bcf1c9a8c43'} from 'ACTIONS_MODULE6'\nexport {deployFeature as '404b5999bc6f96926423c290ad57510ec557128832'} from 'ACTIONS_MODULE7'\nexport {deployRepository as '40e59c0a6c3e3a01829eb5f700ab316233fff8bf04'} from 'ACTIONS_MODULE8'\nexport {stopDeployment as '40edd08872ca1b2ff19b22b0c1da3d720f7133c7ab'} from 'ACTIONS_MODULE9'\nexport {getDeploymentStatus as '40e192a818a5b7bc1a5380b2a3a023ee6fa5bd962b'} from 'ACTIONS_MODULE10'\n"],"names":[],"mappings":"uCAAA,IAAA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA"}
@@ -1,3 +1,3 @@
1
- module.exports=[61402,76052,13008,74607,6542,73624,12104,70319,54433,59020,a=>{"use strict";var b=a.i(2211),c=a.i(96380),d=a.i(50961);async function e(a,b){if(!a.trim())return{approved:!1,error:"Feature id is required"};try{let d=(0,c.resolve)("IFeatureRepository"),e=await d.findById(a);if(!e)return{approved:!1,error:"Feature not found"};if(!e.agentRunId)return{approved:!1,error:"Feature has no agent run"};let f=(0,c.resolve)("ApproveAgentRunUseCase"),g=await f.execute(e.agentRunId,b);if(!g.approved)return{approved:!1,error:g.reason};return{approved:!0}}catch(a){return{approved:!1,error:a instanceof Error?a.message:"Failed to approve feature"}}}async function f(a,b,d){if(!a.trim())return{rejected:!1,error:"Feature id is required"};if(!b.trim())return{rejected:!1,error:"Feedback is required"};try{let e=(0,c.resolve)("IFeatureRepository"),f=await e.findById(a);if(!f)return{rejected:!1,error:"Feature not found"};if(!f.agentRunId)return{rejected:!1,error:"Feature has no agent run"};let g=(0,c.resolve)("RejectAgentRunUseCase"),h=await g.execute(f.agentRunId,b,d);if(!h.rejected)return{rejected:!1,error:h.reason};return{rejected:!0,iteration:h.iteration,iterationWarning:h.iterationWarning}}catch(a){return{rejected:!1,error:a instanceof Error?a.message:"Failed to reject feature"}}}async function g(a){if(!a.trim())return{error:"Feature id is required"};try{let b=(0,c.resolve)("GetFeatureArtifactUseCase"),d=await b.execute(a),e={question:"Goal",context:d.oneLiner,questions:d.openQuestions.map((a,b)=>({id:`q-${b}`,question:a.question,type:"select",options:(a.options??[]).map((a,c)=>({id:`q-${b}-opt-${c}`,label:a.option,rationale:a.description,...a.selected?{recommended:!0}:{}}))})),finalAction:{id:"approve-reqs",label:"Approve Requirements",description:"Finalize and lock the requirements for implementation"}},f={question:"Goal",context:d.oneLiner,questions:d.openQuestions.filter(a=>a.resolved).map(a=>{let b=a.options?.find(a=>a.selected);return{question:a.question,selectedOption:b?.option??a.answer??"N/A",rationale:a.selectionRationale??b?.description??"",wasRecommended:!1}})};return{questionnaire:e,productDecisions:f,artifact:d}}catch(a){return{error:a instanceof Error?a.message:"Failed to load feature artifact"}}}async function h(a){if(!a.trim())return{error:"Feature id is required"};try{var b;let d=(0,c.resolve)("GetResearchArtifactUseCase");return{techDecisions:{name:(b=await d.execute(a)).name,summary:b.summary,decisions:b.decisions,technologies:b.technologies}}}catch(a){return{error:a instanceof Error?a.message:"Failed to load research artifact"}}}(0,d.ensureServerEntryExports)([e]),(0,b.registerServerReference)(e,"60689dec393bb57eb8170127c394ab7f00e05019c5",null),a.s(["approveFeature",0,e],61402),(0,d.ensureServerEntryExports)([f]),(0,b.registerServerReference)(f,"70adbccc4c78ee69299a2bde00266139f0341860be",null),a.s(["rejectFeature",0,f],76052),(0,d.ensureServerEntryExports)([g]),(0,b.registerServerReference)(g,"40a83fa725c2f75508f2b9ba7d6816e13884c7659f",null),a.s(["getFeatureArtifact",0,g],13008),(0,d.ensureServerEntryExports)([h]),(0,b.registerServerReference)(h,"4050fd20d52031d9698bf1953fa5c10615821470c6",null),a.s(["getResearchArtifact",0,h],74607);var i=a.i(66680),j=a.i(2157),k=a.i(50227);function l(a){try{return(0,j.realpathSync)(a)}catch{return null}}function m(a,b){let c=b.replace(/\\/g,"/"),d=a.replace(/\\/g,"/");return d===c||d.startsWith(`${c}/`)}a.i(12714),a.i(1442);var n=a.i(29918),o=a.i(83771);async function p(a){if(!a.trim())return{error:"Feature id is required"};try{var b,d;let e,f,g=(0,c.resolve)("IFeatureRepository"),h=await g.findById(a);if(!h)return{error:"Feature not found"};let p=(0,c.resolve)("LoadSettingsUseCase"),{workflow:q}=await p.execute(),r=h.pr?{url:h.pr.url,number:h.pr.number,status:h.pr.status,commitHash:h.pr.commitHash,ciStatus:h.pr.ciStatus,mergeable:h.pr.mergeable}:void 0,s=h.worktreePath??(h.repositoryPath&&h.branch?(0,n.computeWorktreePath)(h.repositoryPath,h.branch):null),t=(0,c.resolve)("IGitPrService"),u=s??h.repositoryPath??null,v="main";if(u)try{v=await t.getDefaultBranch(u)}catch{}let w=h.branch?{source:h.branch,target:v}:void 0,x=h.repositoryPath?(b=h.repositoryPath,f=(0,i.createHash)("sha256").update(b).digest("hex").slice(0,16),(0,k.join)((0,o.getShipitAiHomeDir)(),"repos",f,"evidence",a).replace(/\\/g,"/")):s?(0,k.join)((0,k.dirname)((0,k.dirname)(s)),"evidence",a).replace(/\\/g,"/"):null;if(x)try{let a=l((0,o.getShipitAiHomeDir)()),b=l(x);if(a&&b&&m(b,a)){let a=l((0,k.join)(b,"manifest.json"));if(a&&m(a,b)){let b=(d=JSON.parse((0,j.readFileSync)(a,"utf-8")),d.map(a=>{if(a.relativePath.startsWith("/"))return a;let b=(0,k.basename)(a.relativePath),c=(0,k.join)(x,b).replace(/\\/g,"/");return{...a,relativePath:c}})),c=new Set;e=b.filter(a=>{let b=`${a.type}:${a.relativePath}`;return!c.has(b)&&(c.add(b),!0)})}}}catch{}if(!s)return{pr:r,branch:w,evidence:e,warning:r?void 0:"No PR or diff data available",hideCiStatus:q.hideCiStatus};try{let[a,b]=await Promise.all([t.getPrDiffSummary(s,v),t.getFileDiffs(s,v).catch(()=>void 0)]);return{pr:r,branch:w,diffSummary:a,fileDiffs:b,evidence:e,hideCiStatus:q.hideCiStatus}}catch{return{pr:r,branch:w,evidence:e,warning:"Diff statistics unavailable",hideCiStatus:q.hideCiStatus}}}catch(a){return{error:a instanceof Error?a.message:"Failed to load merge review data"}}}async function q(a){if(!a.trim())return{error:"Feature id is required"};try{let b=(0,c.resolve)("IPhaseTimingRepository"),d=(await b.findByFeatureId(a)).map(a=>({agentRunId:a.agentRunId,phase:a.phase,startedAt:a.startedAt.toISOString(),completedAt:a.completedAt?.toISOString(),durationMs:null!=a.durationMs?Number(a.durationMs):void 0,waitingApprovalAt:a.waitingApprovalAt?.toISOString(),approvalWaitMs:null!=a.approvalWaitMs?Number(a.approvalWaitMs):void 0,inputTokens:null!=a.inputTokens?Number(a.inputTokens):void 0,outputTokens:null!=a.outputTokens?Number(a.outputTokens):void 0,cacheCreationInputTokens:null!=a.cacheCreationInputTokens?Number(a.cacheCreationInputTokens):void 0,cacheReadInputTokens:null!=a.cacheReadInputTokens?Number(a.cacheReadInputTokens):void 0,costUsd:null!=a.costUsd?Number(a.costUsd):void 0,numTurns:a.numTurns??void 0,durationApiMs:null!=a.durationApiMs?Number(a.durationApiMs):void 0,exitCode:a.exitCode??void 0,errorMessage:a.errorMessage??void 0,prompt:a.prompt??void 0})),e=await r(a);return{timings:d,rejectionFeedback:e}}catch(a){return{error:a instanceof Error?a.message:"Failed to load phase timings"}}}async function r(b){try{let d=(0,c.resolve)("IFeatureRepository"),e=await d.findById(b);if(!e?.specPath)return[];let{readFileSync:f}=await a.A(6714),{join:g}=await a.A(11105),h=(await a.A(29718)).default,i=f(g(e.specPath,"spec.yaml"),"utf-8"),j=h.load(i);if(!Array.isArray(j?.rejectionFeedback))return[];return j.rejectionFeedback.map(a=>({iteration:Number(a.iteration??1),message:String(a.message??""),phase:a.phase?String(a.phase):void 0,timestamp:a.timestamp?String(a.timestamp):void 0,attachments:Array.isArray(a.attachments)?a.attachments.map(String):void 0}))}catch{return[]}}async function s(a){if(!a.trim())return{error:"Feature id is required"};try{let b=(0,c.resolve)("IFeatureRepository"),d=await b.findById(a);if(!d)return{error:"Feature not found"};if(!d.plan)return{plan:void 0};return{plan:{state:d.plan.state,overview:d.plan.overview,tasks:d.plan.tasks.map(a=>({title:a.title??"",description:a.description??"",state:a.state,actionItems:(a.actionItems??[]).map(a=>({name:a.name,description:a.description,acceptanceCriteria:(a.acceptanceCriteria??[]).map(a=>({description:a.description,verified:a.verified}))}))}))}}}catch(a){return{error:a instanceof Error?a.message:"Failed to load feature plan"}}}async function t(a){if(!a?.trim())return{success:!1,error:"Feature id is required"};try{let b=(0,c.resolve)("RebaseFeatureOnMainUseCase");return await b.execute(a),{success:!0}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to rebase feature"}}}(0,d.ensureServerEntryExports)([p]),(0,b.registerServerReference)(p,"40037ffafa5e4eb9ee0759209945d33ce90e13fec6",null),a.s(["getMergeReviewData",0,p],6542),(0,d.ensureServerEntryExports)([q]),(0,b.registerServerReference)(q,"409704dd26135c11b1ee535a5b0931db4a0671ee53",null),a.s(["getFeaturePhaseTimings",0,q],73624),(0,d.ensureServerEntryExports)([s]),(0,b.registerServerReference)(s,"404fdeb8fe6c6592d1a804ef02373bf3d1a61a304a",null),a.s(["getFeaturePlan",0,s],12104),(0,d.ensureServerEntryExports)([t]),(0,b.registerServerReference)(t,"404496b843a41bc21643f6b485b84215fd77c150ca",null),a.s(["rebaseFeature",0,t],70319);var u=a.i(31747);async function v(a){try{let b=(0,c.resolve)("IFeatureRepository"),d=(0,c.resolve)("IAgentRunRepository"),e=(0,c.resolve)("IRepositoryRepository"),f=(0,c.resolve)("IGitPrService"),g=(0,c.resolve)("GetFeatureArtifactUseCase"),h=await b.findById(a);if(!h)return null;let i=h.agentRunId?await d.findById(h.agentRunId):null,[j,k,l,m]=await Promise.all([e.findByPath(h.repositoryPath).catch(()=>null),f.getDefaultBranch(h.repositoryPath).catch(()=>"main"),g.execute(a).catch(()=>null),f.getRemoteUrl(h.repositoryPath).catch(()=>null)]),n=(0,c.resolve)("LoadSettingsUseCase"),{workflow:o}=await n.execute();return(0,u.buildFeatureNodeData)(h,i,{repositoryName:j?.name,baseBranch:k,oneLiner:l?.oneLiner,remoteUrl:m??void 0,enableEvidence:o.enableEvidence,commitEvidence:o.commitEvidence,hideCiStatus:o.hideCiStatus})}catch{return null}}async function w(a){if(!a?.trim())return{success:!1,error:"Feature id is required"};try{let b=(0,c.resolve)("GetBranchSyncStatusUseCase"),d=await b.execute(a);return{success:!0,data:{...d,checkedAt:new Date().toISOString()}}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to get branch sync status"}}}(0,d.ensureServerEntryExports)([v]),(0,b.registerServerReference)(v,"4062d5cf9c269e046e5423814b3253cc1631dafb7c",null),a.s(["getFeatureDrawerData",0,v],54433),(0,d.ensureServerEntryExports)([w]),(0,b.registerServerReference)(w,"4080d17ee3d972352038c8cf9aa734fa11727ba2f5",null),a.s(["getBranchSyncStatus",0,w],59020)}];
1
+ module.exports=[61402,76052,13008,74607,6542,73624,12104,70319,54433,59020,a=>{"use strict";var b=a.i(2211),c=a.i(96380),d=a.i(50961);async function e(a,b){if(!a.trim())return{approved:!1,error:"Feature id is required"};try{let d=(0,c.resolve)("IFeatureRepository"),e=await d.findById(a);if(!e)return{approved:!1,error:"Feature not found"};if(!e.agentRunId)return{approved:!1,error:"Feature has no agent run"};let f=(0,c.resolve)("ApproveAgentRunUseCase"),g=await f.execute(e.agentRunId,b);if(!g.approved)return{approved:!1,error:g.reason};return{approved:!0}}catch(a){return{approved:!1,error:a instanceof Error?a.message:"Failed to approve feature"}}}async function f(a,b,d){if(!a.trim())return{rejected:!1,error:"Feature id is required"};if(!b.trim())return{rejected:!1,error:"Feedback is required"};try{let e=(0,c.resolve)("IFeatureRepository"),f=await e.findById(a);if(!f)return{rejected:!1,error:"Feature not found"};if(!f.agentRunId)return{rejected:!1,error:"Feature has no agent run"};let g=(0,c.resolve)("RejectAgentRunUseCase"),h=await g.execute(f.agentRunId,b,d);if(!h.rejected)return{rejected:!1,error:h.reason};return{rejected:!0,iteration:h.iteration,iterationWarning:h.iterationWarning}}catch(a){return{rejected:!1,error:a instanceof Error?a.message:"Failed to reject feature"}}}async function g(a){if(!a.trim())return{error:"Feature id is required"};try{let b=(0,c.resolve)("GetFeatureArtifactUseCase"),d=await b.execute(a),e={question:"Goal",context:d.oneLiner,questions:d.openQuestions.map((a,b)=>({id:`q-${b}`,question:a.question,type:"select",options:(a.options??[]).map((a,c)=>({id:`q-${b}-opt-${c}`,label:a.option,rationale:a.description,...a.selected?{recommended:!0}:{}}))})),finalAction:{id:"approve-reqs",label:"Approve Requirements",description:"Finalize and lock the requirements for implementation"}},f={question:"Goal",context:d.oneLiner,questions:d.openQuestions.filter(a=>a.resolved).map(a=>{let b=a.options?.find(a=>a.selected);return{question:a.question,selectedOption:b?.option??a.answer??"N/A",rationale:a.selectionRationale??b?.description??"",wasRecommended:!1}})};return{questionnaire:e,productDecisions:f,artifact:d}}catch(a){return{error:a instanceof Error?a.message:"Failed to load feature artifact"}}}async function h(a){if(!a.trim())return{error:"Feature id is required"};try{var b;let d=(0,c.resolve)("GetResearchArtifactUseCase");return{techDecisions:{name:(b=await d.execute(a)).name,summary:b.summary,decisions:b.decisions,technologies:b.technologies}}}catch(a){return{error:a instanceof Error?a.message:"Failed to load research artifact"}}}(0,d.ensureServerEntryExports)([e]),(0,b.registerServerReference)(e,"60abd10dc8e5b4f83bf853f3f21fa9cccad2241971",null),a.s(["approveFeature",0,e],61402),(0,d.ensureServerEntryExports)([f]),(0,b.registerServerReference)(f,"70a1d4481d01fe36d34e84b6ef71b544f7c7ab721f",null),a.s(["rejectFeature",0,f],76052),(0,d.ensureServerEntryExports)([g]),(0,b.registerServerReference)(g,"40622e25d96a4251c71fbe074ba00eebf8991f8a09",null),a.s(["getFeatureArtifact",0,g],13008),(0,d.ensureServerEntryExports)([h]),(0,b.registerServerReference)(h,"40e686489c0aa1bbb1d260e2f5e75991aa10c7da00",null),a.s(["getResearchArtifact",0,h],74607);var i=a.i(66680),j=a.i(2157),k=a.i(50227);function l(a){try{return(0,j.realpathSync)(a)}catch{return null}}function m(a,b){let c=b.replace(/\\/g,"/"),d=a.replace(/\\/g,"/");return d===c||d.startsWith(`${c}/`)}a.i(12714),a.i(1442);var n=a.i(29918),o=a.i(83771);async function p(a){if(!a.trim())return{error:"Feature id is required"};try{var b,d;let e,f,g=(0,c.resolve)("IFeatureRepository"),h=await g.findById(a);if(!h)return{error:"Feature not found"};let p=(0,c.resolve)("LoadSettingsUseCase"),{workflow:q}=await p.execute(),r=h.pr?{url:h.pr.url,number:h.pr.number,status:h.pr.status,commitHash:h.pr.commitHash,ciStatus:h.pr.ciStatus,mergeable:h.pr.mergeable}:void 0,s=h.worktreePath??(h.repositoryPath&&h.branch?(0,n.computeWorktreePath)(h.repositoryPath,h.branch):null),t=(0,c.resolve)("IGitPrService"),u=s??h.repositoryPath??null,v="main";if(u)try{v=await t.getDefaultBranch(u)}catch{}let w=h.branch?{source:h.branch,target:v}:void 0,x=h.repositoryPath?(b=h.repositoryPath,f=(0,i.createHash)("sha256").update(b).digest("hex").slice(0,16),(0,k.join)((0,o.getShipitAiHomeDir)(),"repos",f,"evidence",a).replace(/\\/g,"/")):s?(0,k.join)((0,k.dirname)((0,k.dirname)(s)),"evidence",a).replace(/\\/g,"/"):null;if(x)try{let a=l((0,o.getShipitAiHomeDir)()),b=l(x);if(a&&b&&m(b,a)){let a=l((0,k.join)(b,"manifest.json"));if(a&&m(a,b)){let b=(d=JSON.parse((0,j.readFileSync)(a,"utf-8")),d.map(a=>{if(a.relativePath.startsWith("/"))return a;let b=(0,k.basename)(a.relativePath),c=(0,k.join)(x,b).replace(/\\/g,"/");return{...a,relativePath:c}})),c=new Set;e=b.filter(a=>{let b=`${a.type}:${a.relativePath}`;return!c.has(b)&&(c.add(b),!0)})}}}catch{}if(!s)return{pr:r,branch:w,evidence:e,warning:r?void 0:"No PR or diff data available",hideCiStatus:q.hideCiStatus};try{let[a,b]=await Promise.all([t.getPrDiffSummary(s,v),t.getFileDiffs(s,v).catch(()=>void 0)]);return{pr:r,branch:w,diffSummary:a,fileDiffs:b,evidence:e,hideCiStatus:q.hideCiStatus}}catch{return{pr:r,branch:w,evidence:e,warning:"Diff statistics unavailable",hideCiStatus:q.hideCiStatus}}}catch(a){return{error:a instanceof Error?a.message:"Failed to load merge review data"}}}async function q(a){if(!a.trim())return{error:"Feature id is required"};try{let b=(0,c.resolve)("IPhaseTimingRepository"),d=(await b.findByFeatureId(a)).map(a=>({agentRunId:a.agentRunId,phase:a.phase,startedAt:a.startedAt.toISOString(),completedAt:a.completedAt?.toISOString(),durationMs:null!=a.durationMs?Number(a.durationMs):void 0,waitingApprovalAt:a.waitingApprovalAt?.toISOString(),approvalWaitMs:null!=a.approvalWaitMs?Number(a.approvalWaitMs):void 0,inputTokens:null!=a.inputTokens?Number(a.inputTokens):void 0,outputTokens:null!=a.outputTokens?Number(a.outputTokens):void 0,cacheCreationInputTokens:null!=a.cacheCreationInputTokens?Number(a.cacheCreationInputTokens):void 0,cacheReadInputTokens:null!=a.cacheReadInputTokens?Number(a.cacheReadInputTokens):void 0,costUsd:null!=a.costUsd?Number(a.costUsd):void 0,numTurns:a.numTurns??void 0,durationApiMs:null!=a.durationApiMs?Number(a.durationApiMs):void 0,exitCode:a.exitCode??void 0,errorMessage:a.errorMessage??void 0,prompt:a.prompt??void 0})),e=await r(a);return{timings:d,rejectionFeedback:e}}catch(a){return{error:a instanceof Error?a.message:"Failed to load phase timings"}}}async function r(b){try{let d=(0,c.resolve)("IFeatureRepository"),e=await d.findById(b);if(!e?.specPath)return[];let{readFileSync:f}=await a.A(6714),{join:g}=await a.A(11105),h=(await a.A(29718)).default,i=f(g(e.specPath,"spec.yaml"),"utf-8"),j=h.load(i);if(!Array.isArray(j?.rejectionFeedback))return[];return j.rejectionFeedback.map(a=>({iteration:Number(a.iteration??1),message:String(a.message??""),phase:a.phase?String(a.phase):void 0,timestamp:a.timestamp?String(a.timestamp):void 0,attachments:Array.isArray(a.attachments)?a.attachments.map(String):void 0}))}catch{return[]}}async function s(a){if(!a.trim())return{error:"Feature id is required"};try{let b=(0,c.resolve)("IFeatureRepository"),d=await b.findById(a);if(!d)return{error:"Feature not found"};if(!d.plan)return{plan:void 0};return{plan:{state:d.plan.state,overview:d.plan.overview,tasks:d.plan.tasks.map(a=>({title:a.title??"",description:a.description??"",state:a.state,actionItems:(a.actionItems??[]).map(a=>({name:a.name,description:a.description,acceptanceCriteria:(a.acceptanceCriteria??[]).map(a=>({description:a.description,verified:a.verified}))}))}))}}}catch(a){return{error:a instanceof Error?a.message:"Failed to load feature plan"}}}async function t(a){if(!a?.trim())return{success:!1,error:"Feature id is required"};try{let b=(0,c.resolve)("RebaseFeatureOnMainUseCase");return await b.execute(a),{success:!0}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to rebase feature"}}}(0,d.ensureServerEntryExports)([p]),(0,b.registerServerReference)(p,"40676280ec04a8fb9911aed35526add3d5dcabceb5",null),a.s(["getMergeReviewData",0,p],6542),(0,d.ensureServerEntryExports)([q]),(0,b.registerServerReference)(q,"4059ed1e505eac67da32c3c78bbe4d6b1a03c745aa",null),a.s(["getFeaturePhaseTimings",0,q],73624),(0,d.ensureServerEntryExports)([s]),(0,b.registerServerReference)(s,"40264a0e8aa31093405bf11a13dc53f8246fcdcda8",null),a.s(["getFeaturePlan",0,s],12104),(0,d.ensureServerEntryExports)([t]),(0,b.registerServerReference)(t,"40b4c5ddade5ca3e5a4ed744a9be304f8878f61126",null),a.s(["rebaseFeature",0,t],70319);var u=a.i(31747);async function v(a){try{let b=(0,c.resolve)("IFeatureRepository"),d=(0,c.resolve)("IAgentRunRepository"),e=(0,c.resolve)("IRepositoryRepository"),f=(0,c.resolve)("IGitPrService"),g=(0,c.resolve)("GetFeatureArtifactUseCase"),h=await b.findById(a);if(!h)return null;let i=h.agentRunId?await d.findById(h.agentRunId):null,[j,k,l,m]=await Promise.all([e.findByPath(h.repositoryPath).catch(()=>null),f.getDefaultBranch(h.repositoryPath).catch(()=>"main"),g.execute(a).catch(()=>null),f.getRemoteUrl(h.repositoryPath).catch(()=>null)]),n=(0,c.resolve)("LoadSettingsUseCase"),{workflow:o}=await n.execute();return(0,u.buildFeatureNodeData)(h,i,{repositoryName:j?.name,baseBranch:k,oneLiner:l?.oneLiner,remoteUrl:m??void 0,enableEvidence:o.enableEvidence,commitEvidence:o.commitEvidence,hideCiStatus:o.hideCiStatus})}catch{return null}}async function w(a){if(!a?.trim())return{success:!1,error:"Feature id is required"};try{let b=(0,c.resolve)("GetBranchSyncStatusUseCase"),d=await b.execute(a);return{success:!0,data:{...d,checkedAt:new Date().toISOString()}}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to get branch sync status"}}}(0,d.ensureServerEntryExports)([v]),(0,b.registerServerReference)(v,"4092844beeec7e69b4215ca3d5e9572a3e5d9dee9a",null),a.s(["getFeatureDrawerData",0,v],54433),(0,d.ensureServerEntryExports)([w]),(0,b.registerServerReference)(w,"402a277279e72c3716df12ecb249365a389b42e49a",null),a.s(["getBranchSyncStatus",0,w],59020)}];
2
2
 
3
3
  //# sourceMappingURL=src_presentation_web_app_actions_approve-feature_ts_0pjb_re._.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../src/presentation/web/app/actions/approve-feature.ts","../../../../../../../src/presentation/web/app/actions/reject-feature.ts","../../../../../../../src/presentation/web/app/actions/get-feature-artifact.ts","../../../../../../../src/presentation/web/app/actions/get-research-artifact.ts","../../../../../../../src/presentation/web/app/actions/get-merge-review-data.ts","../../../../../../../src/presentation/web/lib/path-sanitizers.ts","../../../../../../../src/presentation/web/app/actions/get-feature-phase-timings.ts","../../../../../../../src/presentation/web/app/actions/get-feature-plan.ts","../../../../../../../src/presentation/web/app/actions/rebase-feature.ts","../../../../../../../src/presentation/web/app/actions/get-feature-drawer-data.ts","../../../../../../../src/presentation/web/app/actions/get-branch-sync-status.ts"],"sourcesContent":["'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { ApproveAgentRunUseCase } from '@shipit-ai/core/application/use-cases/agents/approve-agent-run.use-case';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\nimport type { PrdApprovalPayload } from '@shipit-ai/core/domain/generated/output';\n\nexport async function approveFeature(\n featureId: string,\n payload?: PrdApprovalPayload\n): Promise<{ approved: boolean; error?: string }> {\n if (!featureId.trim()) {\n return { approved: false, error: 'Feature id is required' };\n }\n\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await featureRepo.findById(featureId);\n\n if (!feature) {\n return { approved: false, error: 'Feature not found' };\n }\n\n if (!feature.agentRunId) {\n return { approved: false, error: 'Feature has no agent run' };\n }\n\n // Always use ApproveAgentRunUseCase — it handles waitingApproval, failed,\n // and interrupted statuses. This ensures approval is propagated via\n // Command({update: {_approvalAction: 'approved'}}) so the graph node\n // receives it on resume.\n const approveUseCase = resolve<ApproveAgentRunUseCase>('ApproveAgentRunUseCase');\n const result = await approveUseCase.execute(feature.agentRunId, payload);\n\n if (!result.approved) {\n return { approved: false, error: result.reason };\n }\n\n return { approved: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to approve feature';\n return { approved: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { RejectAgentRunUseCase } from '@shipit-ai/core/application/use-cases/agents/reject-agent-run.use-case';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\n\nexport async function rejectFeature(\n featureId: string,\n feedback: string,\n attachments?: string[]\n): Promise<{\n rejected: boolean;\n iteration?: number;\n iterationWarning?: boolean;\n error?: string;\n}> {\n if (!featureId.trim()) {\n return { rejected: false, error: 'Feature id is required' };\n }\n\n if (!feedback.trim()) {\n return { rejected: false, error: 'Feedback is required' };\n }\n\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await featureRepo.findById(featureId);\n\n if (!feature) {\n return { rejected: false, error: 'Feature not found' };\n }\n\n if (!feature.agentRunId) {\n return { rejected: false, error: 'Feature has no agent run' };\n }\n\n // Always use RejectAgentRunUseCase — it handles waitingApproval, failed,\n // and interrupted statuses. This ensures rejection feedback is propagated\n // via Command({update: {_approvalAction, _rejectionFeedback}}) so the\n // graph node receives the feedback on resume.\n const rejectUseCase = resolve<RejectAgentRunUseCase>('RejectAgentRunUseCase');\n const result = await rejectUseCase.execute(feature.agentRunId, feedback, attachments);\n\n if (!result.rejected) {\n return { rejected: false, error: result.reason };\n }\n\n return {\n rejected: true,\n iteration: result.iteration,\n iterationWarning: result.iterationWarning,\n };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to reject feature';\n return { rejected: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { GetFeatureArtifactUseCase } from '@shipit-ai/core/application/use-cases/features/get-feature-artifact.use-case';\nimport type { FeatureArtifact } from '@shipit-ai/core/domain/generated/output';\nimport type { PrdQuestionnaireData } from '@shipit-ai/core/domain/generated/output';\nimport type { ProductDecisionsSummaryData } from '@/components/common/product-decisions-summary';\n\ninterface GetFeatureArtifactResult {\n questionnaire?: PrdQuestionnaireData;\n productDecisions?: ProductDecisionsSummaryData;\n artifact?: FeatureArtifact;\n error?: string;\n}\n\n/**\n * Map FeatureArtifact openQuestions into the PrdQuestionnaireData shape\n * expected by the PrdQuestionnaireDrawer component.\n */\nfunction toQuestionnaireData(artifact: FeatureArtifact): PrdQuestionnaireData {\n return {\n question: 'Goal',\n context: artifact.oneLiner,\n questions: artifact.openQuestions.map((oq, idx) => ({\n id: `q-${idx}`,\n question: oq.question,\n type: 'select' as const,\n options: (oq.options ?? []).map((opt, optIdx) => ({\n id: `q-${idx}-opt-${optIdx}`,\n label: opt.option,\n rationale: opt.description,\n ...(opt.selected ? { recommended: true } : {}),\n })),\n })),\n finalAction: {\n id: 'approve-reqs',\n label: 'Approve Requirements',\n description: 'Finalize and lock the requirements for implementation',\n },\n };\n}\n\n/**\n * Map FeatureArtifact openQuestions into a read-only summary for the\n * Product Decisions tab in the tech review drawer.\n */\nfunction toProductDecisionsData(artifact: FeatureArtifact): ProductDecisionsSummaryData {\n return {\n question: 'Goal',\n context: artifact.oneLiner,\n questions: artifact.openQuestions\n .filter((oq) => oq.resolved)\n .map((oq) => {\n const selected = oq.options?.find((o) => o.selected);\n return {\n question: oq.question,\n selectedOption: selected?.option ?? oq.answer ?? 'N/A',\n rationale: oq.selectionRationale ?? selected?.description ?? '',\n wasRecommended: false,\n };\n }),\n };\n}\n\nexport async function getFeatureArtifact(featureId: string): Promise<GetFeatureArtifactResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<GetFeatureArtifactUseCase>('GetFeatureArtifactUseCase');\n const artifact = await useCase.execute(featureId);\n const questionnaire = toQuestionnaireData(artifact);\n const productDecisions = toProductDecisionsData(artifact);\n return { questionnaire, productDecisions, artifact };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load feature artifact';\n return { error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { GetResearchArtifactUseCase } from '@shipit-ai/core/application/use-cases/features/get-research-artifact.use-case';\nimport type { ResearchArtifact, TechDecision } from '@shipit-ai/core/domain/generated/output';\n\nexport interface TechDecisionsReviewData {\n name: string;\n summary: string;\n decisions: TechDecision[];\n technologies: string[];\n}\n\ninterface GetResearchArtifactResult {\n techDecisions?: TechDecisionsReviewData;\n error?: string;\n}\n\nfunction toTechDecisionsData(artifact: ResearchArtifact): TechDecisionsReviewData {\n return {\n name: artifact.name,\n summary: artifact.summary,\n decisions: artifact.decisions,\n technologies: artifact.technologies,\n };\n}\n\nexport async function getResearchArtifact(featureId: string): Promise<GetResearchArtifactResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<GetResearchArtifactUseCase>('GetResearchArtifactUseCase');\n const artifact = await useCase.execute(featureId);\n const techDecisions = toTechDecisionsData(artifact);\n return { techDecisions };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load research artifact';\n return { error: message };\n }\n}\n","'use server';\n\nimport { createHash } from 'node:crypto';\nimport { readFileSync } from 'node:fs';\nimport { basename, join, dirname } from 'node:path';\nimport { resolve } from '@/lib/server-container';\nimport { realpathOrNull, isWithinRoot } from '@/lib/path-sanitizers';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\nimport type { IGitPrService } from '@shipit-ai/core/application/ports/output/services/git-pr-service.interface';\nimport type {\n MergeReviewData,\n MergeReviewEvidence,\n} from '@/components/common/merge-review/merge-review-config';\nimport { computeWorktreePath, getShipitAiHomeDir } from '@/lib/core-utils';\nimport type { LoadSettingsUseCase } from '@shipit-ai/core/application/use-cases/settings/load-settings.use-case';\n\ntype GetMergeReviewDataResult = MergeReviewData | { error: string };\n\n/**\n * Compute the ShipIT evidence directory for a given repository and feature.\n * Path: ~/.shipit-ai/repos/<sha256-hash-prefix>/evidence/<featureId>/\n *\n * The sha256 hash of the repository path makes the resulting directory name\n * deterministic and hex-only, neutralizing any path-injection risk from the\n * repositoryPath input. The featureId is a UUID from the DB lookup.\n */\nfunction computeEvidenceDir(repositoryPath: string, featureId: string): string {\n const repoHash = createHash('sha256').update(repositoryPath).digest('hex').slice(0, 16);\n return join(getShipitAiHomeDir(), 'repos', repoHash, 'evidence', featureId).replace(/\\\\/g, '/');\n}\n\n/**\n * Normalize evidence paths so they all point to the ShipIT evidence directory.\n * When commitEvidence was enabled, the manifest may contain relative paths\n * (e.g. \"specs/066-feature/evidence/file.png\"). After merge the worktree is\n * deleted so those paths no longer resolve. The evidence files were also saved\n * to the ShipIT evidence dir with the same filename, so we map relative paths\n * to absolute paths there.\n *\n * IMPORTANT: the returned paths must remain in the SAME form as the\n * `/api/evidence` route expects (it uses `path.resolve` + `.startsWith`\n * against the unresolved `SHIPIT_AI_HOME/repos` root). Do not pass\n * realpath-resolved paths here, because on macOS `SHIPIT_AI_HOME=/tmp/...`\n * resolves to `/private/tmp/...` and the evidence route's prefix check\n * would reject the realpath'd form. Basename-only containment (strip any\n * directory traversal via `basename()` then `join()` with the known-safe\n * `evidenceDir`) is sufficient sanitization for this taint source because\n * `basename()` cannot return a path-traversal string.\n */\nfunction normalizeEvidencePaths(\n evidence: MergeReviewEvidence[],\n evidenceDir: string\n): MergeReviewEvidence[] {\n return evidence.map((e) => {\n // If the manifest path is absolute and already present on disk, keep\n // it verbatim — this preserves the original reference and matches the\n // pre-fix behavior for already-migrated evidence. We do NOT realpath\n // the result because the evidence route does not realpath its input,\n // and mismatching normalization forms would cause 404s.\n if (e.relativePath.startsWith('/')) {\n return e;\n }\n // Relative path — map to evidenceDir using basename() only. `basename`\n // strips any directory components including `..` sequences, so the\n // joined result is guaranteed to live directly inside evidenceDir\n // regardless of what the manifest file contained.\n const safeName = basename(e.relativePath);\n const target = join(evidenceDir, safeName).replace(/\\\\/g, '/');\n return { ...e, relativePath: target };\n });\n}\n\nexport async function getMergeReviewData(featureId: string): Promise<GetMergeReviewDataResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await featureRepo.findById(featureId);\n\n if (!feature) {\n return { error: 'Feature not found' };\n }\n\n const loadSettings = resolve<LoadSettingsUseCase>('LoadSettingsUseCase');\n const { workflow } = await loadSettings.execute();\n\n const pr = feature.pr\n ? {\n url: feature.pr.url,\n number: feature.pr.number,\n status: feature.pr.status,\n commitHash: feature.pr.commitHash,\n ciStatus: feature.pr.ciStatus,\n mergeable: feature.pr.mergeable,\n }\n : undefined;\n\n const worktreePath =\n feature.worktreePath ??\n (feature.repositoryPath && feature.branch\n ? computeWorktreePath(feature.repositoryPath, feature.branch)\n : null);\n\n // Detect the actual default branch (main, master, etc.) for diff comparison.\n const gitPrService = resolve<IGitPrService>('IGitPrService');\n const diffCwd = worktreePath ?? feature.repositoryPath ?? null;\n let defaultBranch = 'main';\n if (diffCwd) {\n try {\n defaultBranch = await gitPrService.getDefaultBranch(diffCwd);\n } catch {\n // Fall back to 'main' if detection fails\n }\n }\n\n const branch = feature.branch ? { source: feature.branch, target: defaultBranch } : undefined;\n\n // Load evidence manifest (best-effort).\n // Evidence is stored independently of the worktree at:\n // ~/.shipit-ai/repos/<hash>/evidence/<featureId>/manifest.json\n // We compute this path from repositoryPath so evidence is accessible\n // even after the worktree has been deleted post-merge.\n let evidence: MergeReviewEvidence[] | undefined;\n const evidenceDir = feature.repositoryPath\n ? computeEvidenceDir(feature.repositoryPath, featureId)\n : worktreePath\n ? join(dirname(dirname(worktreePath)), 'evidence', featureId).replace(/\\\\/g, '/')\n : null;\n\n if (evidenceDir) {\n try {\n // SECURITY: validate the manifest we're about to read lives inside\n // SHIPIT_AI_HOME. computeEvidenceDir() already hashes repositoryPath\n // to a hex directory name, but we still run a realpath containment\n // check because CodeQL's js/path-injection analysis recognizes the\n // realpathOrNull + isWithinRoot pair as a sanitizer chain.\n //\n // Resolve-once semantics: realpath the shipit home dir and the\n // evidence dir exactly once each, then reuse those resolved values\n // for every subsequent containment check. This avoids both the\n // extra syscalls and the TOCTOU window that a recursive resolve-\n // and-check helper would introduce.\n //\n // IMPORTANT: the resolved paths are used ONLY for the read-time\n // security check. The unresolved `evidenceDir` is what we pass to\n // normalizeEvidencePaths so the paths returned to the client match\n // what the /api/evidence route expects — see the comment on\n // normalizeEvidencePaths for the full rationale.\n const resolvedHome = realpathOrNull(getShipitAiHomeDir());\n const resolvedEvidenceDir = realpathOrNull(evidenceDir);\n if (\n resolvedHome &&\n resolvedEvidenceDir &&\n isWithinRoot(resolvedEvidenceDir, resolvedHome)\n ) {\n const resolvedManifest = realpathOrNull(join(resolvedEvidenceDir, 'manifest.json'));\n if (resolvedManifest && isWithinRoot(resolvedManifest, resolvedEvidenceDir)) {\n const raw: MergeReviewEvidence[] = JSON.parse(readFileSync(resolvedManifest, 'utf-8'));\n // Pass the UNRESOLVED evidenceDir so returned paths share the\n // same root form the evidence route's prefix check expects.\n const normalized = normalizeEvidencePaths(raw, evidenceDir);\n // Deduplicate: same type + relativePath means the same evidence entry\n const seen = new Set<string>();\n evidence = normalized.filter((e) => {\n const key = `${e.type}:${e.relativePath}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n }\n }\n } catch {\n // Evidence unavailable — not critical\n }\n }\n\n if (!worktreePath) {\n return {\n pr,\n branch,\n evidence,\n warning: pr ? undefined : 'No PR or diff data available',\n hideCiStatus: workflow.hideCiStatus,\n };\n }\n\n try {\n const [diffSummary, fileDiffs] = await Promise.all([\n gitPrService.getPrDiffSummary(worktreePath, defaultBranch),\n gitPrService.getFileDiffs(worktreePath, defaultBranch).catch(() => undefined),\n ]);\n return { pr, branch, diffSummary, fileDiffs, evidence, hideCiStatus: workflow.hideCiStatus };\n } catch {\n return {\n pr,\n branch,\n evidence,\n warning: 'Diff statistics unavailable',\n hideCiStatus: workflow.hideCiStatus,\n };\n }\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load merge review data';\n return { error: message };\n }\n}\n","/**\n * Path sanitization helpers for the web presentation layer.\n *\n * Provides the small set of primitives used by every route and server\n * action that touches a user-influenced filesystem path. Each helper\n * does one thing, is recognized by CodeQL's js/path-injection taint\n * analysis as a sanitizer, and is portable across macOS/Linux/Windows.\n *\n * Design principles:\n *\n * - `realpathOrNull(p)` resolves a path through `realpath` and returns\n * `null` on any error (missing file, permission denied, broken symlink).\n * Callers never have to care about the thrown error variants.\n *\n * - `isWithinRoot(candidate, root)` is a pure string containment check\n * that expects both arguments to already be realpath-resolved. It\n * normalizes backslash separators to forward slashes before comparing,\n * so Windows realpath output matches the forward-slash roots that\n * shipit uses throughout the codebase for persistence and comparison.\n *\n * - `realpathWithinAllowedRoots(candidate, roots)` combines the two:\n * resolves the candidate once, resolves each root once (with graceful\n * fallback to the unresolved form for the roots), then checks\n * containment. Returns the resolved candidate on success, `null` on\n * failure. Use this when a value must live under one of several\n * permitted directories (e.g. cwd OR home-dir for the uploads API).\n *\n * These helpers intentionally do NOT compose realpath with the\n * containment check into a single `realpathWithinRoot(candidate, root)`\n * function, because that composition re-resolves an already-resolved\n * root on every nested call and opens a TOCTOU window where filesystem\n * state can change between the resolve and the containment check. Keep\n * realpath and containment separate so the caller can resolve once and\n * validate many.\n */\nimport { realpathSync } from 'node:fs';\nimport { realpath } from 'node:fs/promises';\n\n/**\n * Resolve a path through `realpath` and return the resolved absolute path,\n * or `null` if the path is missing, unreadable, or cannot be canonicalized\n * for any other reason. Never throws.\n *\n * CodeQL recognizes `realpathSync` output as a sanitizer for\n * `js/path-injection`, so the returned value is safe to flow into `stat`,\n * `readFile`, `readdir`, `spawn`, and other filesystem sinks.\n */\nexport function realpathOrNull(p: string): string | null {\n try {\n return realpathSync(p);\n } catch {\n return null;\n }\n}\n\n/**\n * Pure string containment check: does `resolvedCandidate` live at or\n * beneath `resolvedRoot`? BOTH arguments are expected to already be\n * realpath-resolved absolute paths — this helper does NOT resolve them.\n * Separate the resolve step from the containment check so the caller can\n * resolve once and validate many times without redundant syscalls or\n * TOCTOU windows.\n *\n * Uses forward-slash normalization on both sides before comparing, which\n * is lossless on POSIX (separator is already `/`) and lossless on Windows\n * (where `/` cannot appear inside a path component). This makes the\n * helper safe to use across all three platforms.\n */\nexport function isWithinRoot(resolvedCandidate: string, resolvedRoot: string): boolean {\n const normRoot = resolvedRoot.replace(/\\\\/g, '/');\n const normCandidate = resolvedCandidate.replace(/\\\\/g, '/');\n return normCandidate === normRoot || normCandidate.startsWith(`${normRoot}/`);\n}\n\n/**\n * Resolve `candidate` through realpath and assert the result lives under\n * at least one of the provided `allowedRoots`. Returns the resolved\n * candidate path on success, or `null` if the candidate cannot be resolved\n * or does not fall under any allowed root.\n *\n * The roots are resolved once, up-front, with graceful fallback to the\n * unresolved form on failure (so a root that does not yet exist on disk\n * is still honored as a literal prefix — this matches the existing\n * behavior of the upload and directory-list routes). If the caller wants\n * strict resolution of the roots too, pre-resolve them with\n * `realpathOrNull` and filter out `null`s before calling this helper.\n */\nexport function realpathWithinAllowedRoots(\n candidate: string,\n allowedRoots: readonly string[]\n): string | null {\n const resolvedCandidate = realpathOrNull(candidate);\n if (!resolvedCandidate) return null;\n\n for (const root of allowedRoots) {\n const resolvedRoot = realpathOrNull(root) ?? root;\n if (isWithinRoot(resolvedCandidate, resolvedRoot)) {\n return resolvedCandidate;\n }\n }\n return null;\n}\n\n// ─── Async variants ─────────────────────────────────────────────────────\n//\n// Route handlers that already use async fs APIs should use these rather\n// than the sync variants so they don't block the event loop under\n// concurrent load. The async helpers mirror the sync ones exactly in\n// semantics — same null-on-error contract, same normalization, same\n// containment rules.\n\n/**\n * Async variant of `realpathOrNull`. See the sync version for semantics.\n */\nexport async function realpathOrNullAsync(p: string): Promise<string | null> {\n try {\n return await realpath(p);\n } catch {\n return null;\n }\n}\n\n/**\n * Async variant of `realpathWithinAllowedRoots`. See the sync version for\n * semantics. Resolves the candidate and each root concurrently via\n * `Promise.all` so the worst-case wall-clock time is a single realpath,\n * not N of them serialized.\n */\nexport async function realpathWithinAllowedRootsAsync(\n candidate: string,\n allowedRoots: readonly string[]\n): Promise<string | null> {\n const [resolvedCandidate, ...resolvedRoots] = await Promise.all([\n realpathOrNullAsync(candidate),\n ...allowedRoots.map((r) => realpathOrNullAsync(r)),\n ]);\n if (!resolvedCandidate) return null;\n\n for (let i = 0; i < resolvedRoots.length; i++) {\n const resolvedRoot = resolvedRoots[i] ?? allowedRoots[i];\n if (isWithinRoot(resolvedCandidate, resolvedRoot)) {\n return resolvedCandidate;\n }\n }\n return null;\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { IPhaseTimingRepository } from '@shipit-ai/core/application/ports/output/agents/phase-timing-repository.interface';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\n\nexport interface PhaseTimingData {\n agentRunId: string;\n phase: string;\n startedAt: string;\n completedAt?: string;\n durationMs?: number;\n waitingApprovalAt?: string;\n approvalWaitMs?: number;\n inputTokens?: number;\n outputTokens?: number;\n cacheCreationInputTokens?: number;\n cacheReadInputTokens?: number;\n costUsd?: number;\n numTurns?: number;\n durationApiMs?: number;\n exitCode?: string;\n errorMessage?: string;\n prompt?: string;\n}\n\nexport interface RejectionFeedbackData {\n iteration: number;\n message: string;\n phase?: string;\n timestamp?: string;\n attachments?: string[];\n}\n\ntype GetPhaseTimingsResult =\n | { timings: PhaseTimingData[]; rejectionFeedback: RejectionFeedbackData[] }\n | { error: string };\n\nexport async function getFeaturePhaseTimings(featureId: string): Promise<GetPhaseTimingsResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const repo = resolve<IPhaseTimingRepository>('IPhaseTimingRepository');\n const phaseTimings = await repo.findByFeatureId(featureId);\n\n const timings: PhaseTimingData[] = phaseTimings.map((t) => ({\n agentRunId: t.agentRunId,\n phase: t.phase,\n startedAt: t.startedAt.toISOString(),\n completedAt: t.completedAt?.toISOString(),\n durationMs: t.durationMs != null ? Number(t.durationMs) : undefined,\n waitingApprovalAt: t.waitingApprovalAt?.toISOString(),\n approvalWaitMs: t.approvalWaitMs != null ? Number(t.approvalWaitMs) : undefined,\n inputTokens: t.inputTokens != null ? Number(t.inputTokens) : undefined,\n outputTokens: t.outputTokens != null ? Number(t.outputTokens) : undefined,\n cacheCreationInputTokens:\n t.cacheCreationInputTokens != null ? Number(t.cacheCreationInputTokens) : undefined,\n cacheReadInputTokens:\n t.cacheReadInputTokens != null ? Number(t.cacheReadInputTokens) : undefined,\n costUsd: t.costUsd != null ? Number(t.costUsd) : undefined,\n numTurns: t.numTurns ?? undefined,\n durationApiMs: t.durationApiMs != null ? Number(t.durationApiMs) : undefined,\n exitCode: t.exitCode ?? undefined,\n errorMessage: t.errorMessage ?? undefined,\n prompt: t.prompt ?? undefined,\n }));\n\n // Read rejection feedback from spec.yaml\n const rejectionFeedback = await readRejectionFeedback(featureId);\n\n return { timings, rejectionFeedback };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load phase timings';\n return { error: message };\n }\n}\n\nasync function readRejectionFeedback(featureId: string): Promise<RejectionFeedbackData[]> {\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await featureRepo.findById(featureId);\n if (!feature?.specPath) return [];\n\n const { readFileSync } = await import('node:fs');\n const { join } = await import('node:path');\n const yaml = (await import('js-yaml')).default;\n\n const specContent = readFileSync(join(feature.specPath, 'spec.yaml'), 'utf-8');\n const spec = yaml.load(specContent) as Record<string, unknown>;\n\n if (!Array.isArray(spec?.rejectionFeedback)) return [];\n\n return (spec.rejectionFeedback as Record<string, unknown>[]).map((entry) => ({\n iteration: Number(entry.iteration ?? 1),\n message: String(entry.message ?? ''),\n phase: entry.phase ? String(entry.phase) : undefined,\n timestamp: entry.timestamp ? String(entry.timestamp) : undefined,\n attachments: Array.isArray(entry.attachments)\n ? (entry.attachments as unknown[]).map(String)\n : undefined,\n }));\n } catch {\n return [];\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\n\nexport interface AcceptanceCriterionData {\n description: string;\n verified: boolean;\n}\n\nexport interface ActionItemData {\n name: string;\n description: string;\n acceptanceCriteria: AcceptanceCriterionData[];\n}\n\nexport interface PlanTaskData {\n title: string;\n description: string;\n state: string;\n actionItems: ActionItemData[];\n}\n\nexport interface PlanData {\n state: string;\n overview: string;\n tasks: PlanTaskData[];\n}\n\ntype GetPlanResult = { plan: PlanData | undefined } | { error: string };\n\nexport async function getFeaturePlan(featureId: string): Promise<GetPlanResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const repo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await repo.findById(featureId);\n\n if (!feature) {\n return { error: 'Feature not found' };\n }\n\n if (!feature.plan) {\n return { plan: undefined };\n }\n\n const plan: PlanData = {\n state: feature.plan.state,\n overview: feature.plan.overview,\n tasks: feature.plan.tasks.map((t) => ({\n title: t.title ?? '',\n description: t.description ?? '',\n state: t.state,\n actionItems: (t.actionItems ?? []).map((ai) => ({\n name: ai.name,\n description: ai.description,\n acceptanceCriteria: (ai.acceptanceCriteria ?? []).map((ac) => ({\n description: ac.description,\n verified: ac.verified,\n })),\n })),\n })),\n };\n\n return { plan };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load feature plan';\n return { error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { RebaseFeatureOnMainUseCase } from '@shipit-ai/core/application/use-cases/features/rebase-feature-on-main.use-case';\n\nexport async function rebaseFeature(\n featureId: string\n): Promise<{ success: boolean; error?: string }> {\n if (!featureId?.trim()) {\n return { success: false, error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<RebaseFeatureOnMainUseCase>('RebaseFeatureOnMainUseCase');\n await useCase.execute(featureId);\n return { success: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to rebase feature';\n return { success: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\nimport type { IAgentRunRepository } from '@shipit-ai/core/application/ports/output/agents/agent-run-repository.interface';\nimport type { IRepositoryRepository } from '@shipit-ai/core/application/ports/output/repositories/repository-repository.interface';\nimport type { IGitPrService } from '@shipit-ai/core/application/ports/output/services/git-pr-service.interface';\nimport type { GetFeatureArtifactUseCase } from '@shipit-ai/core/application/use-cases/features/get-feature-artifact.use-case';\nimport type { LoadSettingsUseCase } from '@shipit-ai/core/application/use-cases/settings/load-settings.use-case';\nimport { buildFeatureNodeData } from '@/app/build-feature-node-data';\nimport type { FeatureNodeData } from '@/components/common/feature-node';\n\n/**\n * Fetches full FeatureNodeData for a given feature ID.\n * Used by the drawer for targeted data syncing without triggering\n * a full router.refresh() / server component re-render.\n *\n * CI status and mergeable status are read from the DB (already updated\n * by PrSyncWatcherService) instead of making duplicate GitHub API calls.\n */\nexport async function getFeatureDrawerData(featureId: string): Promise<FeatureNodeData | null> {\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const agentRunRepo = resolve<IAgentRunRepository>('IAgentRunRepository');\n const repoRepo = resolve<IRepositoryRepository>('IRepositoryRepository');\n const gitPrService = resolve<IGitPrService>('IGitPrService');\n const getArtifact = resolve<GetFeatureArtifactUseCase>('GetFeatureArtifactUseCase');\n\n const feature = await featureRepo.findById(featureId);\n if (!feature) return null;\n\n const run = feature.agentRunId ? await agentRunRepo.findById(feature.agentRunId) : null;\n\n // CI status and mergeable status are read from the feature record (updated by\n // PrSyncWatcherService every 30s) — no duplicate GitHub API calls needed.\n // Only getDefaultBranch and getRemoteUrl are kept as they are local git operations.\n const [repo, baseBranch, artifact, remoteUrl] = await Promise.all([\n repoRepo.findByPath(feature.repositoryPath).catch(() => null),\n gitPrService.getDefaultBranch(feature.repositoryPath).catch(() => 'main'),\n getArtifact.execute(featureId).catch(() => null),\n gitPrService.getRemoteUrl(feature.repositoryPath).catch(() => null),\n ]);\n\n const loadSettings = resolve<LoadSettingsUseCase>('LoadSettingsUseCase');\n const { workflow } = await loadSettings.execute();\n\n return buildFeatureNodeData(feature, run, {\n repositoryName: repo?.name,\n baseBranch,\n oneLiner: artifact?.oneLiner,\n remoteUrl: remoteUrl ?? undefined,\n enableEvidence: workflow.enableEvidence,\n commitEvidence: workflow.commitEvidence,\n hideCiStatus: workflow.hideCiStatus,\n });\n } catch {\n return null;\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { GetBranchSyncStatusUseCase } from '@shipit-ai/core/application/use-cases/features/get-branch-sync-status.use-case';\n\nexport async function getBranchSyncStatus(featureId: string): Promise<{\n success: boolean;\n data?: { ahead: number; behind: number; baseBranch: string; checkedAt: string };\n error?: string;\n}> {\n if (!featureId?.trim()) {\n return { success: false, error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<GetBranchSyncStatusUseCase>('GetBranchSyncStatusUseCase');\n const result = await useCase.execute(featureId);\n return {\n success: true,\n data: {\n ...result,\n checkedAt: new Date().toISOString(),\n },\n };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to get branch sync status';\n return { success: false, error: message };\n }\n}\n"],"names":["approveFeature","featureId","payload","trim","approved","error","featureRepo","feature","findById","agentRunId","approveUseCase","result","execute","reason","message","Error"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../../../../../src/presentation/web/app/actions/approve-feature.ts","../../../../../../../src/presentation/web/app/actions/reject-feature.ts","../../../../../../../src/presentation/web/app/actions/get-feature-artifact.ts","../../../../../../../src/presentation/web/app/actions/get-research-artifact.ts","../../../../../../../src/presentation/web/app/actions/get-merge-review-data.ts","../../../../../../../src/presentation/web/lib/path-sanitizers.ts","../../../../../../../src/presentation/web/app/actions/get-feature-phase-timings.ts","../../../../../../../src/presentation/web/app/actions/get-feature-plan.ts","../../../../../../../src/presentation/web/app/actions/rebase-feature.ts","../../../../../../../src/presentation/web/app/actions/get-feature-drawer-data.ts","../../../../../../../src/presentation/web/app/actions/get-branch-sync-status.ts"],"sourcesContent":["'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { ApproveAgentRunUseCase } from '@shipit-ai/core/application/use-cases/agents/approve-agent-run.use-case';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\nimport type { PrdApprovalPayload } from '@shipit-ai/core/domain/generated/output';\n\nexport async function approveFeature(\n featureId: string,\n payload?: PrdApprovalPayload\n): Promise<{ approved: boolean; error?: string }> {\n if (!featureId.trim()) {\n return { approved: false, error: 'Feature id is required' };\n }\n\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await featureRepo.findById(featureId);\n\n if (!feature) {\n return { approved: false, error: 'Feature not found' };\n }\n\n if (!feature.agentRunId) {\n return { approved: false, error: 'Feature has no agent run' };\n }\n\n // Always use ApproveAgentRunUseCase — it handles waitingApproval, failed,\n // and interrupted statuses. This ensures approval is propagated via\n // Command({update: {_approvalAction: 'approved'}}) so the graph node\n // receives it on resume.\n const approveUseCase = resolve<ApproveAgentRunUseCase>('ApproveAgentRunUseCase');\n const result = await approveUseCase.execute(feature.agentRunId, payload);\n\n if (!result.approved) {\n return { approved: false, error: result.reason };\n }\n\n return { approved: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to approve feature';\n return { approved: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { RejectAgentRunUseCase } from '@shipit-ai/core/application/use-cases/agents/reject-agent-run.use-case';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\n\nexport async function rejectFeature(\n featureId: string,\n feedback: string,\n attachments?: string[]\n): Promise<{\n rejected: boolean;\n iteration?: number;\n iterationWarning?: boolean;\n error?: string;\n}> {\n if (!featureId.trim()) {\n return { rejected: false, error: 'Feature id is required' };\n }\n\n if (!feedback.trim()) {\n return { rejected: false, error: 'Feedback is required' };\n }\n\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await featureRepo.findById(featureId);\n\n if (!feature) {\n return { rejected: false, error: 'Feature not found' };\n }\n\n if (!feature.agentRunId) {\n return { rejected: false, error: 'Feature has no agent run' };\n }\n\n // Always use RejectAgentRunUseCase — it handles waitingApproval, failed,\n // and interrupted statuses. This ensures rejection feedback is propagated\n // via Command({update: {_approvalAction, _rejectionFeedback}}) so the\n // graph node receives the feedback on resume.\n const rejectUseCase = resolve<RejectAgentRunUseCase>('RejectAgentRunUseCase');\n const result = await rejectUseCase.execute(feature.agentRunId, feedback, attachments);\n\n if (!result.rejected) {\n return { rejected: false, error: result.reason };\n }\n\n return {\n rejected: true,\n iteration: result.iteration,\n iterationWarning: result.iterationWarning,\n };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to reject feature';\n return { rejected: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { GetFeatureArtifactUseCase } from '@shipit-ai/core/application/use-cases/features/get-feature-artifact.use-case';\nimport type { FeatureArtifact } from '@shipit-ai/core/domain/generated/output';\nimport type { PrdQuestionnaireData } from '@shipit-ai/core/domain/generated/output';\nimport type { ProductDecisionsSummaryData } from '@/components/common/product-decisions-summary';\n\ninterface GetFeatureArtifactResult {\n questionnaire?: PrdQuestionnaireData;\n productDecisions?: ProductDecisionsSummaryData;\n artifact?: FeatureArtifact;\n error?: string;\n}\n\n/**\n * Map FeatureArtifact openQuestions into the PrdQuestionnaireData shape\n * expected by the PrdQuestionnaireDrawer component.\n */\nfunction toQuestionnaireData(artifact: FeatureArtifact): PrdQuestionnaireData {\n return {\n question: 'Goal',\n context: artifact.oneLiner,\n questions: artifact.openQuestions.map((oq, idx) => ({\n id: `q-${idx}`,\n question: oq.question,\n type: 'select' as const,\n options: (oq.options ?? []).map((opt, optIdx) => ({\n id: `q-${idx}-opt-${optIdx}`,\n label: opt.option,\n rationale: opt.description,\n ...(opt.selected ? { recommended: true } : {}),\n })),\n })),\n finalAction: {\n id: 'approve-reqs',\n label: 'Approve Requirements',\n description: 'Finalize and lock the requirements for implementation',\n },\n };\n}\n\n/**\n * Map FeatureArtifact openQuestions into a read-only summary for the\n * Product Decisions tab in the tech review drawer.\n */\nfunction toProductDecisionsData(artifact: FeatureArtifact): ProductDecisionsSummaryData {\n return {\n question: 'Goal',\n context: artifact.oneLiner,\n questions: artifact.openQuestions\n .filter((oq) => oq.resolved)\n .map((oq) => {\n const selected = oq.options?.find((o) => o.selected);\n return {\n question: oq.question,\n selectedOption: selected?.option ?? oq.answer ?? 'N/A',\n rationale: oq.selectionRationale ?? selected?.description ?? '',\n wasRecommended: false,\n };\n }),\n };\n}\n\nexport async function getFeatureArtifact(featureId: string): Promise<GetFeatureArtifactResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<GetFeatureArtifactUseCase>('GetFeatureArtifactUseCase');\n const artifact = await useCase.execute(featureId);\n const questionnaire = toQuestionnaireData(artifact);\n const productDecisions = toProductDecisionsData(artifact);\n return { questionnaire, productDecisions, artifact };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load feature artifact';\n return { error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { GetResearchArtifactUseCase } from '@shipit-ai/core/application/use-cases/features/get-research-artifact.use-case';\nimport type { ResearchArtifact, TechDecision } from '@shipit-ai/core/domain/generated/output';\n\nexport interface TechDecisionsReviewData {\n name: string;\n summary: string;\n decisions: TechDecision[];\n technologies: string[];\n}\n\ninterface GetResearchArtifactResult {\n techDecisions?: TechDecisionsReviewData;\n error?: string;\n}\n\nfunction toTechDecisionsData(artifact: ResearchArtifact): TechDecisionsReviewData {\n return {\n name: artifact.name,\n summary: artifact.summary,\n decisions: artifact.decisions,\n technologies: artifact.technologies,\n };\n}\n\nexport async function getResearchArtifact(featureId: string): Promise<GetResearchArtifactResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<GetResearchArtifactUseCase>('GetResearchArtifactUseCase');\n const artifact = await useCase.execute(featureId);\n const techDecisions = toTechDecisionsData(artifact);\n return { techDecisions };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load research artifact';\n return { error: message };\n }\n}\n","'use server';\n\nimport { createHash } from 'node:crypto';\nimport { readFileSync } from 'node:fs';\nimport { basename, join, dirname } from 'node:path';\nimport { resolve } from '@/lib/server-container';\nimport { realpathOrNull, isWithinRoot } from '@/lib/path-sanitizers';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\nimport type { IGitPrService } from '@shipit-ai/core/application/ports/output/services/git-pr-service.interface';\nimport type {\n MergeReviewData,\n MergeReviewEvidence,\n} from '@/components/common/merge-review/merge-review-config';\nimport { computeWorktreePath, getShipitAiHomeDir } from '@/lib/core-utils';\nimport type { LoadSettingsUseCase } from '@shipit-ai/core/application/use-cases/settings/load-settings.use-case';\n\ntype GetMergeReviewDataResult = MergeReviewData | { error: string };\n\n/**\n * Compute the ShipIT evidence directory for a given repository and feature.\n * Path: ~/.shipit-ai/repos/<sha256-hash-prefix>/evidence/<featureId>/\n *\n * The sha256 hash of the repository path makes the resulting directory name\n * deterministic and hex-only, neutralizing any path-injection risk from the\n * repositoryPath input. The featureId is a UUID from the DB lookup.\n */\nfunction computeEvidenceDir(repositoryPath: string, featureId: string): string {\n const repoHash = createHash('sha256').update(repositoryPath).digest('hex').slice(0, 16);\n return join(getShipitAiHomeDir(), 'repos', repoHash, 'evidence', featureId).replace(/\\\\/g, '/');\n}\n\n/**\n * Normalize evidence paths so they all point to the ShipIT evidence directory.\n * When commitEvidence was enabled, the manifest may contain relative paths\n * (e.g. \"specs/066-feature/evidence/file.png\"). After merge the worktree is\n * deleted so those paths no longer resolve. The evidence files were also saved\n * to the ShipIT evidence dir with the same filename, so we map relative paths\n * to absolute paths there.\n *\n * IMPORTANT: the returned paths must remain in the SAME form as the\n * `/api/evidence` route expects (it uses `path.resolve` + `.startsWith`\n * against the unresolved `SHIPIT_AI_HOME/repos` root). Do not pass\n * realpath-resolved paths here, because on macOS `SHIPIT_AI_HOME=/tmp/...`\n * resolves to `/private/tmp/...` and the evidence route's prefix check\n * would reject the realpath'd form. Basename-only containment (strip any\n * directory traversal via `basename()` then `join()` with the known-safe\n * `evidenceDir`) is sufficient sanitization for this taint source because\n * `basename()` cannot return a path-traversal string.\n */\nfunction normalizeEvidencePaths(\n evidence: MergeReviewEvidence[],\n evidenceDir: string\n): MergeReviewEvidence[] {\n return evidence.map((e) => {\n // If the manifest path is absolute and already present on disk, keep\n // it verbatim — this preserves the original reference and matches the\n // pre-fix behavior for already-migrated evidence. We do NOT realpath\n // the result because the evidence route does not realpath its input,\n // and mismatching normalization forms would cause 404s.\n if (e.relativePath.startsWith('/')) {\n return e;\n }\n // Relative path — map to evidenceDir using basename() only. `basename`\n // strips any directory components including `..` sequences, so the\n // joined result is guaranteed to live directly inside evidenceDir\n // regardless of what the manifest file contained.\n const safeName = basename(e.relativePath);\n const target = join(evidenceDir, safeName).replace(/\\\\/g, '/');\n return { ...e, relativePath: target };\n });\n}\n\nexport async function getMergeReviewData(featureId: string): Promise<GetMergeReviewDataResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await featureRepo.findById(featureId);\n\n if (!feature) {\n return { error: 'Feature not found' };\n }\n\n const loadSettings = resolve<LoadSettingsUseCase>('LoadSettingsUseCase');\n const { workflow } = await loadSettings.execute();\n\n const pr = feature.pr\n ? {\n url: feature.pr.url,\n number: feature.pr.number,\n status: feature.pr.status,\n commitHash: feature.pr.commitHash,\n ciStatus: feature.pr.ciStatus,\n mergeable: feature.pr.mergeable,\n }\n : undefined;\n\n const worktreePath =\n feature.worktreePath ??\n (feature.repositoryPath && feature.branch\n ? computeWorktreePath(feature.repositoryPath, feature.branch)\n : null);\n\n // Detect the actual default branch (main, master, etc.) for diff comparison.\n const gitPrService = resolve<IGitPrService>('IGitPrService');\n const diffCwd = worktreePath ?? feature.repositoryPath ?? null;\n let defaultBranch = 'main';\n if (diffCwd) {\n try {\n defaultBranch = await gitPrService.getDefaultBranch(diffCwd);\n } catch {\n // Fall back to 'main' if detection fails\n }\n }\n\n const branch = feature.branch ? { source: feature.branch, target: defaultBranch } : undefined;\n\n // Load evidence manifest (best-effort).\n // Evidence is stored independently of the worktree at:\n // ~/.shipit-ai/repos/<hash>/evidence/<featureId>/manifest.json\n // We compute this path from repositoryPath so evidence is accessible\n // even after the worktree has been deleted post-merge.\n let evidence: MergeReviewEvidence[] | undefined;\n const evidenceDir = feature.repositoryPath\n ? computeEvidenceDir(feature.repositoryPath, featureId)\n : worktreePath\n ? join(dirname(dirname(worktreePath)), 'evidence', featureId).replace(/\\\\/g, '/')\n : null;\n\n if (evidenceDir) {\n try {\n // SECURITY: validate the manifest we're about to read lives inside\n // SHIPIT_AI_HOME. computeEvidenceDir() already hashes repositoryPath\n // to a hex directory name, but we still run a realpath containment\n // check because CodeQL's js/path-injection analysis recognizes the\n // realpathOrNull + isWithinRoot pair as a sanitizer chain.\n //\n // Resolve-once semantics: realpath the shipit home dir and the\n // evidence dir exactly once each, then reuse those resolved values\n // for every subsequent containment check. This avoids both the\n // extra syscalls and the TOCTOU window that a recursive resolve-\n // and-check helper would introduce.\n //\n // IMPORTANT: the resolved paths are used ONLY for the read-time\n // security check. The unresolved `evidenceDir` is what we pass to\n // normalizeEvidencePaths so the paths returned to the client match\n // what the /api/evidence route expects — see the comment on\n // normalizeEvidencePaths for the full rationale.\n const resolvedHome = realpathOrNull(getShipitAiHomeDir());\n const resolvedEvidenceDir = realpathOrNull(evidenceDir);\n if (\n resolvedHome &&\n resolvedEvidenceDir &&\n isWithinRoot(resolvedEvidenceDir, resolvedHome)\n ) {\n const resolvedManifest = realpathOrNull(join(resolvedEvidenceDir, 'manifest.json'));\n if (resolvedManifest && isWithinRoot(resolvedManifest, resolvedEvidenceDir)) {\n // SECURITY: resolvedManifest validated by realpathOrNull + isWithinRoot\n // containment on line 159. featureId flows through SHA-256 hash in\n // computeEvidenceDir (hex-only output neutralizes injection). Double\n // containment check: home dir → evidence dir → manifest. Alert\n // js/path-injection #27 dismissed as false positive.\n const raw: MergeReviewEvidence[] = JSON.parse(readFileSync(resolvedManifest, 'utf-8'));\n // Pass the UNRESOLVED evidenceDir so returned paths share the\n // same root form the evidence route's prefix check expects.\n const normalized = normalizeEvidencePaths(raw, evidenceDir);\n // Deduplicate: same type + relativePath means the same evidence entry\n const seen = new Set<string>();\n evidence = normalized.filter((e) => {\n const key = `${e.type}:${e.relativePath}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n }\n }\n } catch {\n // Evidence unavailable — not critical\n }\n }\n\n if (!worktreePath) {\n return {\n pr,\n branch,\n evidence,\n warning: pr ? undefined : 'No PR or diff data available',\n hideCiStatus: workflow.hideCiStatus,\n };\n }\n\n try {\n const [diffSummary, fileDiffs] = await Promise.all([\n gitPrService.getPrDiffSummary(worktreePath, defaultBranch),\n gitPrService.getFileDiffs(worktreePath, defaultBranch).catch(() => undefined),\n ]);\n return { pr, branch, diffSummary, fileDiffs, evidence, hideCiStatus: workflow.hideCiStatus };\n } catch {\n return {\n pr,\n branch,\n evidence,\n warning: 'Diff statistics unavailable',\n hideCiStatus: workflow.hideCiStatus,\n };\n }\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load merge review data';\n return { error: message };\n }\n}\n","/**\n * Path sanitization helpers for the web presentation layer.\n *\n * Provides the small set of primitives used by every route and server\n * action that touches a user-influenced filesystem path. Each helper\n * does one thing, is recognized by CodeQL's js/path-injection taint\n * analysis as a sanitizer, and is portable across macOS/Linux/Windows.\n *\n * Design principles:\n *\n * - `realpathOrNull(p)` resolves a path through `realpath` and returns\n * `null` on any error (missing file, permission denied, broken symlink).\n * Callers never have to care about the thrown error variants.\n *\n * - `isWithinRoot(candidate, root)` is a pure string containment check\n * that expects both arguments to already be realpath-resolved. It\n * normalizes backslash separators to forward slashes before comparing,\n * so Windows realpath output matches the forward-slash roots that\n * shipit uses throughout the codebase for persistence and comparison.\n *\n * - `realpathWithinAllowedRoots(candidate, roots)` combines the two:\n * resolves the candidate once, resolves each root once (with graceful\n * fallback to the unresolved form for the roots), then checks\n * containment. Returns the resolved candidate on success, `null` on\n * failure. Use this when a value must live under one of several\n * permitted directories (e.g. cwd OR home-dir for the uploads API).\n *\n * These helpers intentionally do NOT compose realpath with the\n * containment check into a single `realpathWithinRoot(candidate, root)`\n * function, because that composition re-resolves an already-resolved\n * root on every nested call and opens a TOCTOU window where filesystem\n * state can change between the resolve and the containment check. Keep\n * realpath and containment separate so the caller can resolve once and\n * validate many.\n */\nimport { realpathSync } from 'node:fs';\nimport { realpath } from 'node:fs/promises';\n\n/**\n * Resolve a path through `realpath` and return the resolved absolute path,\n * or `null` if the path is missing, unreadable, or cannot be canonicalized\n * for any other reason. Never throws.\n *\n * CodeQL recognizes `realpathSync` output as a sanitizer for\n * `js/path-injection`, so the returned value is safe to flow into `stat`,\n * `readFile`, `readdir`, `spawn`, and other filesystem sinks.\n */\nexport function realpathOrNull(p: string): string | null {\n try {\n return realpathSync(p);\n } catch {\n return null;\n }\n}\n\n/**\n * Pure string containment check: does `resolvedCandidate` live at or\n * beneath `resolvedRoot`? BOTH arguments are expected to already be\n * realpath-resolved absolute paths — this helper does NOT resolve them.\n * Separate the resolve step from the containment check so the caller can\n * resolve once and validate many times without redundant syscalls or\n * TOCTOU windows.\n *\n * Uses forward-slash normalization on both sides before comparing, which\n * is lossless on POSIX (separator is already `/`) and lossless on Windows\n * (where `/` cannot appear inside a path component). This makes the\n * helper safe to use across all three platforms.\n */\nexport function isWithinRoot(resolvedCandidate: string, resolvedRoot: string): boolean {\n const normRoot = resolvedRoot.replace(/\\\\/g, '/');\n const normCandidate = resolvedCandidate.replace(/\\\\/g, '/');\n return normCandidate === normRoot || normCandidate.startsWith(`${normRoot}/`);\n}\n\n/**\n * Resolve `candidate` through realpath and assert the result lives under\n * at least one of the provided `allowedRoots`. Returns the resolved\n * candidate path on success, or `null` if the candidate cannot be resolved\n * or does not fall under any allowed root.\n *\n * The roots are resolved once, up-front, with graceful fallback to the\n * unresolved form on failure (so a root that does not yet exist on disk\n * is still honored as a literal prefix — this matches the existing\n * behavior of the upload and directory-list routes). If the caller wants\n * strict resolution of the roots too, pre-resolve them with\n * `realpathOrNull` and filter out `null`s before calling this helper.\n */\nexport function realpathWithinAllowedRoots(\n candidate: string,\n allowedRoots: readonly string[]\n): string | null {\n const resolvedCandidate = realpathOrNull(candidate);\n if (!resolvedCandidate) return null;\n\n for (const root of allowedRoots) {\n const resolvedRoot = realpathOrNull(root) ?? root;\n if (isWithinRoot(resolvedCandidate, resolvedRoot)) {\n return resolvedCandidate;\n }\n }\n return null;\n}\n\n// ─── Async variants ─────────────────────────────────────────────────────\n//\n// Route handlers that already use async fs APIs should use these rather\n// than the sync variants so they don't block the event loop under\n// concurrent load. The async helpers mirror the sync ones exactly in\n// semantics — same null-on-error contract, same normalization, same\n// containment rules.\n\n/**\n * Async variant of `realpathOrNull`. See the sync version for semantics.\n */\nexport async function realpathOrNullAsync(p: string): Promise<string | null> {\n try {\n // SECURITY: this function IS the sanitizer — realpath() is CodeQL's recommended\n // remediation for path injection. Callers gate access via isWithinRoot\n // containment checks on the resolved result. Alert js/path-injection #28\n // dismissed as false positive (CodeQL flagged the sanitizer itself due to\n // the try/catch null-return path).\n return await realpath(p);\n } catch {\n return null;\n }\n}\n\n/**\n * Async variant of `realpathWithinAllowedRoots`. See the sync version for\n * semantics. Resolves the candidate and each root concurrently via\n * `Promise.all` so the worst-case wall-clock time is a single realpath,\n * not N of them serialized.\n */\nexport async function realpathWithinAllowedRootsAsync(\n candidate: string,\n allowedRoots: readonly string[]\n): Promise<string | null> {\n const [resolvedCandidate, ...resolvedRoots] = await Promise.all([\n realpathOrNullAsync(candidate),\n ...allowedRoots.map((r) => realpathOrNullAsync(r)),\n ]);\n if (!resolvedCandidate) return null;\n\n for (let i = 0; i < resolvedRoots.length; i++) {\n const resolvedRoot = resolvedRoots[i] ?? allowedRoots[i];\n if (isWithinRoot(resolvedCandidate, resolvedRoot)) {\n return resolvedCandidate;\n }\n }\n return null;\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { IPhaseTimingRepository } from '@shipit-ai/core/application/ports/output/agents/phase-timing-repository.interface';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\n\nexport interface PhaseTimingData {\n agentRunId: string;\n phase: string;\n startedAt: string;\n completedAt?: string;\n durationMs?: number;\n waitingApprovalAt?: string;\n approvalWaitMs?: number;\n inputTokens?: number;\n outputTokens?: number;\n cacheCreationInputTokens?: number;\n cacheReadInputTokens?: number;\n costUsd?: number;\n numTurns?: number;\n durationApiMs?: number;\n exitCode?: string;\n errorMessage?: string;\n prompt?: string;\n}\n\nexport interface RejectionFeedbackData {\n iteration: number;\n message: string;\n phase?: string;\n timestamp?: string;\n attachments?: string[];\n}\n\ntype GetPhaseTimingsResult =\n | { timings: PhaseTimingData[]; rejectionFeedback: RejectionFeedbackData[] }\n | { error: string };\n\nexport async function getFeaturePhaseTimings(featureId: string): Promise<GetPhaseTimingsResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const repo = resolve<IPhaseTimingRepository>('IPhaseTimingRepository');\n const phaseTimings = await repo.findByFeatureId(featureId);\n\n const timings: PhaseTimingData[] = phaseTimings.map((t) => ({\n agentRunId: t.agentRunId,\n phase: t.phase,\n startedAt: t.startedAt.toISOString(),\n completedAt: t.completedAt?.toISOString(),\n durationMs: t.durationMs != null ? Number(t.durationMs) : undefined,\n waitingApprovalAt: t.waitingApprovalAt?.toISOString(),\n approvalWaitMs: t.approvalWaitMs != null ? Number(t.approvalWaitMs) : undefined,\n inputTokens: t.inputTokens != null ? Number(t.inputTokens) : undefined,\n outputTokens: t.outputTokens != null ? Number(t.outputTokens) : undefined,\n cacheCreationInputTokens:\n t.cacheCreationInputTokens != null ? Number(t.cacheCreationInputTokens) : undefined,\n cacheReadInputTokens:\n t.cacheReadInputTokens != null ? Number(t.cacheReadInputTokens) : undefined,\n costUsd: t.costUsd != null ? Number(t.costUsd) : undefined,\n numTurns: t.numTurns ?? undefined,\n durationApiMs: t.durationApiMs != null ? Number(t.durationApiMs) : undefined,\n exitCode: t.exitCode ?? undefined,\n errorMessage: t.errorMessage ?? undefined,\n prompt: t.prompt ?? undefined,\n }));\n\n // Read rejection feedback from spec.yaml\n const rejectionFeedback = await readRejectionFeedback(featureId);\n\n return { timings, rejectionFeedback };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load phase timings';\n return { error: message };\n }\n}\n\nasync function readRejectionFeedback(featureId: string): Promise<RejectionFeedbackData[]> {\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await featureRepo.findById(featureId);\n if (!feature?.specPath) return [];\n\n const { readFileSync } = await import('node:fs');\n const { join } = await import('node:path');\n const yaml = (await import('js-yaml')).default;\n\n const specContent = readFileSync(join(feature.specPath, 'spec.yaml'), 'utf-8');\n const spec = yaml.load(specContent) as Record<string, unknown>;\n\n if (!Array.isArray(spec?.rejectionFeedback)) return [];\n\n return (spec.rejectionFeedback as Record<string, unknown>[]).map((entry) => ({\n iteration: Number(entry.iteration ?? 1),\n message: String(entry.message ?? ''),\n phase: entry.phase ? String(entry.phase) : undefined,\n timestamp: entry.timestamp ? String(entry.timestamp) : undefined,\n attachments: Array.isArray(entry.attachments)\n ? (entry.attachments as unknown[]).map(String)\n : undefined,\n }));\n } catch {\n return [];\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\n\nexport interface AcceptanceCriterionData {\n description: string;\n verified: boolean;\n}\n\nexport interface ActionItemData {\n name: string;\n description: string;\n acceptanceCriteria: AcceptanceCriterionData[];\n}\n\nexport interface PlanTaskData {\n title: string;\n description: string;\n state: string;\n actionItems: ActionItemData[];\n}\n\nexport interface PlanData {\n state: string;\n overview: string;\n tasks: PlanTaskData[];\n}\n\ntype GetPlanResult = { plan: PlanData | undefined } | { error: string };\n\nexport async function getFeaturePlan(featureId: string): Promise<GetPlanResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const repo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await repo.findById(featureId);\n\n if (!feature) {\n return { error: 'Feature not found' };\n }\n\n if (!feature.plan) {\n return { plan: undefined };\n }\n\n const plan: PlanData = {\n state: feature.plan.state,\n overview: feature.plan.overview,\n tasks: feature.plan.tasks.map((t) => ({\n title: t.title ?? '',\n description: t.description ?? '',\n state: t.state,\n actionItems: (t.actionItems ?? []).map((ai) => ({\n name: ai.name,\n description: ai.description,\n acceptanceCriteria: (ai.acceptanceCriteria ?? []).map((ac) => ({\n description: ac.description,\n verified: ac.verified,\n })),\n })),\n })),\n };\n\n return { plan };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load feature plan';\n return { error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { RebaseFeatureOnMainUseCase } from '@shipit-ai/core/application/use-cases/features/rebase-feature-on-main.use-case';\n\nexport async function rebaseFeature(\n featureId: string\n): Promise<{ success: boolean; error?: string }> {\n if (!featureId?.trim()) {\n return { success: false, error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<RebaseFeatureOnMainUseCase>('RebaseFeatureOnMainUseCase');\n await useCase.execute(featureId);\n return { success: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to rebase feature';\n return { success: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\nimport type { IAgentRunRepository } from '@shipit-ai/core/application/ports/output/agents/agent-run-repository.interface';\nimport type { IRepositoryRepository } from '@shipit-ai/core/application/ports/output/repositories/repository-repository.interface';\nimport type { IGitPrService } from '@shipit-ai/core/application/ports/output/services/git-pr-service.interface';\nimport type { GetFeatureArtifactUseCase } from '@shipit-ai/core/application/use-cases/features/get-feature-artifact.use-case';\nimport type { LoadSettingsUseCase } from '@shipit-ai/core/application/use-cases/settings/load-settings.use-case';\nimport { buildFeatureNodeData } from '@/app/build-feature-node-data';\nimport type { FeatureNodeData } from '@/components/common/feature-node';\n\n/**\n * Fetches full FeatureNodeData for a given feature ID.\n * Used by the drawer for targeted data syncing without triggering\n * a full router.refresh() / server component re-render.\n *\n * CI status and mergeable status are read from the DB (already updated\n * by PrSyncWatcherService) instead of making duplicate GitHub API calls.\n */\nexport async function getFeatureDrawerData(featureId: string): Promise<FeatureNodeData | null> {\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const agentRunRepo = resolve<IAgentRunRepository>('IAgentRunRepository');\n const repoRepo = resolve<IRepositoryRepository>('IRepositoryRepository');\n const gitPrService = resolve<IGitPrService>('IGitPrService');\n const getArtifact = resolve<GetFeatureArtifactUseCase>('GetFeatureArtifactUseCase');\n\n const feature = await featureRepo.findById(featureId);\n if (!feature) return null;\n\n const run = feature.agentRunId ? await agentRunRepo.findById(feature.agentRunId) : null;\n\n // CI status and mergeable status are read from the feature record (updated by\n // PrSyncWatcherService every 30s) — no duplicate GitHub API calls needed.\n // Only getDefaultBranch and getRemoteUrl are kept as they are local git operations.\n const [repo, baseBranch, artifact, remoteUrl] = await Promise.all([\n repoRepo.findByPath(feature.repositoryPath).catch(() => null),\n gitPrService.getDefaultBranch(feature.repositoryPath).catch(() => 'main'),\n getArtifact.execute(featureId).catch(() => null),\n gitPrService.getRemoteUrl(feature.repositoryPath).catch(() => null),\n ]);\n\n const loadSettings = resolve<LoadSettingsUseCase>('LoadSettingsUseCase');\n const { workflow } = await loadSettings.execute();\n\n return buildFeatureNodeData(feature, run, {\n repositoryName: repo?.name,\n baseBranch,\n oneLiner: artifact?.oneLiner,\n remoteUrl: remoteUrl ?? undefined,\n enableEvidence: workflow.enableEvidence,\n commitEvidence: workflow.commitEvidence,\n hideCiStatus: workflow.hideCiStatus,\n });\n } catch {\n return null;\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { GetBranchSyncStatusUseCase } from '@shipit-ai/core/application/use-cases/features/get-branch-sync-status.use-case';\n\nexport async function getBranchSyncStatus(featureId: string): Promise<{\n success: boolean;\n data?: { ahead: number; behind: number; baseBranch: string; checkedAt: string };\n error?: string;\n}> {\n if (!featureId?.trim()) {\n return { success: false, error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<GetBranchSyncStatusUseCase>('GetBranchSyncStatusUseCase');\n const result = await useCase.execute(featureId);\n return {\n success: true,\n data: {\n ...result,\n checkedAt: new Date().toISOString(),\n },\n };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to get branch sync status';\n return { success: false, error: message };\n }\n}\n"],"names":["approveFeature","featureId","payload","trim","approved","error","featureRepo","feature","findById","agentRunId","approveUseCase","result","execute","reason","message","Error"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- module.exports=[84095,56799,80496,93225,41872,9959,79124,29207,10528,50845,26604,54723,18942,42886,49560,39353,a=>{"use strict";var b=a.i(2211),c=a.i(50227),d=a.i(96380),e=a.i(50961);async function f(a){let{repositoryPath:b,branch:e}=a;if(!b||!(0,c.isAbsolute)(b))return{success:!1,error:"repositoryPath must be an absolute path"};let f=(0,d.resolve)("LoadSettingsUseCase"),g=(await f.execute()).environment.defaultEditor,h=(0,d.resolve)("LaunchIdeUseCase"),i=await h.execute({editorId:g,repositoryPath:b,branch:e,checkAvailability:!0});return i.ok?{success:!0,editor:i.editorName,path:i.worktreePath}:{success:!1,error:i.message}}(0,e.ensureServerEntryExports)([f]),(0,b.registerServerReference)(f,"4007721bb168054f860a3df6cd060e0f3807aad0b7",null),a.s(["openIde",0,f],84095);var g=a.i(2157),h=a.i(60526),i=a.i(74533);a.i(1442);var j=a.i(29918);let k={darwin:{cmd:"open",args:a=>["-a","Terminal",a]},linux:{cmd:"x-terminal-emulator",args:a=>[`--working-directory=${a}`]},win32:{cmd:"cmd.exe",args:a=>["/c","start","powershell","-NoExit","-Command",`Set-Location "${a}"`]}};async function l(a){let{repositoryPath:b,branch:e}=a;if(!b||!(0,c.isAbsolute)(b))return{success:!1,error:"repositoryPath must be an absolute path"};try{let a=(0,d.resolve)("LoadSettingsUseCase"),c=await a.execute(),f=c.environment.shellPreference,l=c.environment.terminalPreference??"system",m=function(a,b){try{let c=b?(0,j.computeWorktreePath)(a,b):a;return(0,g.realpathSync)(c)}catch{return null}}(b,e);if(!m)return{success:!1,error:"Path does not exist"};if("system"!==l)try{let a=(0,d.resolve)("IToolInstallerService").getTerminalOpenConfig(l);if(a?.openDirectory.includes("{dir}")){if(a.shell){let b=`'${m.replace(/'/g,"'\\''")}'`,c=a.openDirectory.replaceAll("{dir}",b),d=(0,i.spawn)(c,[],{detached:!0,stdio:"ignore",shell:!0});d.on("error",()=>void 0),d.unref()}else{let b=a.openDirectory.split(/\s+/).filter(Boolean),c=b[0],d=b.slice(1).map(a=>a.replaceAll("{dir}",m)),e=(0,i.spawn)(c,d,{detached:!0,stdio:"ignore"});e.on("error",()=>void 0),e.unref()}return{success:!0,path:m,shell:f}}}catch{}let n=k[(0,h.platform)()];if(!n)return{success:!1,error:`Unsupported platform: ${(0,h.platform)()}`};let o=(0,i.spawn)(n.cmd,n.args(m),{detached:!0,stdio:"ignore"});return o.on("error",()=>void 0),o.unref(),{success:!0,path:m,shell:f}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to open shell"}}}(0,e.ensureServerEntryExports)([l]),(0,b.registerServerReference)(l,"4004781548c34747283fe284c8d195ca487357e06e",null),a.s(["openShell",0,l],56799);let m={darwin:{cmd:"open",args:a=>[a]},linux:{cmd:"xdg-open",args:a=>[a]},win32:{cmd:"explorer",args:a=>[a]}};async function n(a){if(!a||!(0,c.isAbsolute)(a))return{success:!1,error:"repositoryPath must be an absolute path"};try{let b;try{b=(0,g.realpathSync)(a)}catch{return{success:!1,error:"Directory not found"}}let d=m[(0,h.platform)()];if(!d)return{success:!1,error:`Unsupported platform: ${(0,h.platform)()}`};let e=(0,c.normalize)(b),f=(0,i.spawn)(d.cmd,d.args(e),{detached:!0,stdio:"ignore"});return f.on("error",()=>void 0),f.unref(),{success:!0,path:b}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to open folder"}}}async function o(a){if(!a?.trim())return{success:!1,error:"Repository id is required"};try{let b=(0,d.resolve)("SyncRepositoryMainUseCase");return await b.execute(a),{success:!0}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to sync repository"}}}async function p(){try{let a=(0,d.resolve)("LoadSettingsUseCase");return(await a.execute()).onboardingComplete}catch{return!1}}(0,e.ensureServerEntryExports)([n]),(0,b.registerServerReference)(n,"4079ba07e5d8c86c4880360723f3c69e3f51f09301",null),a.s(["openFolder",0,n],80496),(0,e.ensureServerEntryExports)([o]),(0,b.registerServerReference)(o,"40056e63d366d69696c57d7b5a4664d89f6b096689",null),a.s(["syncRepository",0,o],93225),(0,e.ensureServerEntryExports)([p]),(0,b.registerServerReference)(p,"004c1cd5bd750d92e24559b76d2d8a527b9fcb81f2",null),a.s(["isAgentSetupComplete",0,p],41872);var q=a.i(37512);let r={"claude-code":"Claude Code","codex-cli":"Codex CLI","copilot-cli":"GitHub Copilot CLI",cursor:"Cursor CLI","gemini-cli":"Gemini CLI","rovo-dev":"Rovo Dev CLI",aider:"Aider",continue:"Continue",dev:"Demo"},s={"claude-code":"claude-code","codex-cli":"codex-cli","copilot-cli":"copilot-cli",cursor:"cursor-cli","gemini-cli":"gemini-cli","rovo-dev":"rovo-dev"},t={"claude-code":"claude","codex-cli":"codex","copilot-cli":"copilot",cursor:"cursor-agent","gemini-cli":"gemini","rovo-dev":"acli"};function u(a,b){return new Promise(c=>{let d,e;switch(a){case"claude-code":d=b,e=["auth","status"];break;case"cursor":d=b,e=["status"];break;case"codex-cli":c(!1);return;case"copilot-cli":default:c(!0);return;case"rovo-dev":{let a=q.IS_WINDOWS?{timeout:5e3,windowsHide:!0}:{timeout:5e3};(0,i.execFile)("acli",["rovodev","auth","status"],a,a=>{c(!a)});return}}try{let a=q.IS_WINDOWS?{timeout:5e3,windowsHide:!0}:{timeout:5e3};(0,i.execFile)(d,e,a,a=>{c(!a)})}catch{c(!1)}})}async function v(){let a;try{let b=(0,d.resolve)("LoadSettingsUseCase");a=(await b.execute()).agent.type}catch{return{agentType:"unknown",installed:!1,authenticated:!1,label:"Unknown",binaryName:null,installCommand:null,authCommand:null}}let b=r[a]??a,e=s[a]??null,f=t[a]??null;if(!e)return{agentType:a,installed:!0,authenticated:!0,label:b,binaryName:null,installCommand:null,authCommand:null};let i=!1,j=null;try{let a=(0,d.resolve)("ListToolsUseCase"),b=(await a.execute()).find(a=>a.id===e);i=b?.status.status==="available",j=b?.installCommand??null}catch{i=!1}if(!i)return{agentType:a,installed:!1,authenticated:!1,label:b,binaryName:f,installCommand:j,authCommand:f?`Install ${b} first`:null};let k=function(a){let b=(0,h.homedir)();switch(a){case"claude-code":{if(process.env.ANTHROPIC_API_KEY||process.env.CLAUDE_CODE_USE_BEDROCK||process.env.CLAUDE_CODE_USE_VERTEX||process.env.CLAUDE_CODE_OAUTH_TOKEN)return"env-var";let a=(0,c.join)(b,".claude",".credentials.json");return!!(0,g.existsSync)(a)&&"file"}case"codex-cli":if(process.env.OPENAI_API_KEY)return"env-var";return!1;case"cursor":{if(process.env.CURSOR_API_KEY)return"env-var";let a=(0,c.join)(b,".cursor");return!!(0,g.existsSync)(a)&&"file"}case"gemini-cli":{if(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||process.env.GOOGLE_APPLICATION_CREDENTIALS)return"env-var";let a=(0,c.join)(b,".gemini","google_accounts.json");return!!(0,g.existsSync)(a)&&"file"}case"copilot-cli":{if(process.env.COPILOT_GITHUB_TOKEN||process.env.GH_TOKEN||process.env.GITHUB_TOKEN)return"env-var";let a=process.env.COPILOT_HOME?(0,c.join)(process.env.COPILOT_HOME,"config.json"):(0,c.join)(b,".copilot","config.json");return!!(0,g.existsSync)(a)&&"file"}case"rovo-dev":{if(process.env.ATLASSIAN_API_TOKEN)return"env-var";let a=(0,c.join)(b,".acli");return!!(0,g.existsSync)(a)&&"file"}default:return"env-var"}}(a);if("env-var"===k)return{agentType:a,installed:!0,authenticated:!0,label:b,binaryName:f,installCommand:j,authCommand:null};if("file"===k){let c=!0;return f&&(c=await u(a,f)),{agentType:a,installed:!0,authenticated:c,label:b,binaryName:f,installCommand:j,authCommand:c?null:f}}return f&&await u(a,f)?{agentType:a,installed:!0,authenticated:!0,label:b,binaryName:f,installCommand:j,authCommand:null}:{agentType:a,installed:!0,authenticated:!1,label:b,binaryName:f,installCommand:j,authCommand:f}}function w(a,b){return new Promise(c=>{try{let d=q.IS_WINDOWS?{timeout:5e3,windowsHide:!0}:{timeout:5e3};(0,i.execFile)(a,b,d,(a,b)=>{if(a)return void c({installed:!1,version:null});let d=b.match(/(\d+\.\d+(?:\.\d+)?)/);c({installed:!0,version:d?.[1]??null})})}catch{c({installed:!1,version:null})}})}async function x(){let[a,b,c]=await Promise.all([w("git",["--version"]),w("gh",["--version"]),(async()=>{try{let a=(0,d.resolve)("ListToolsUseCase");return await a.execute()}catch{return[]}})()]),e=c.find(a=>"git"===a.id),f=c.find(a=>"gh"===a.id);return{git:{...a,installCommand:e?.installCommand??null,installUrl:e?.website??"https://git-scm.com"},gh:{...b,installCommand:f?.installCommand??null,installUrl:f?.website??"https://cli.github.com"}}}async function y(a){let b=(0,d.resolve)("IFeatureRepository"),c=await b.findById(a);return c?{name:c.name,description:c.description}:null}async function z(a){if(!a?.trim())return{error:"id is required"};try{let b=(0,d.resolve)("ArchiveFeatureUseCase");return{feature:await b.execute(a)}}catch(a){return{error:a instanceof Error?a.message:"Failed to archive feature"}}}async function A(a,b,c,e){if(!a?.trim())return{error:"id is required"};try{let f=(0,d.resolve)("DeleteFeatureUseCase"),g={};return void 0!==b&&(g.cleanup=b),void 0!==c&&(g.cascadeDelete=c),void 0!==e&&(g.closePr=e),{feature:Object.keys(g).length>0?await f.execute(a,g):await f.execute(a)}}catch(a){return{error:a instanceof Error?a.message:"Failed to delete feature"}}}async function B(a){if(!a.trim())return{resumed:!1,error:"Feature id is required"};try{let b=(0,d.resolve)("ResumeFeatureUseCase");return await b.execute(a),{resumed:!0}}catch(a){return{resumed:!1,error:a instanceof Error?a.message:"Failed to resume feature"}}}async function C(a){if(!a.trim())return{started:!1,error:"Feature id is required"};try{let b=(0,d.resolve)("StartFeatureUseCase");return await b.execute(a),{started:!0}}catch(a){return{started:!1,error:a instanceof Error?a.message:"Failed to start feature"}}}async function D(a){if(!a.trim())return{stopped:!1,error:"Feature id is required"};try{let b=(0,d.resolve)("IAgentRunRepository"),c=(await b.list()).find(b=>b.featureId===a&&"completed"!==b.status&&"failed"!==b.status&&"interrupted"!==b.status&&"cancelled"!==b.status);if(!c)return{stopped:!1,error:"No active agent run found for this feature"};let e=(0,d.resolve)("StopAgentRunUseCase"),f=await e.execute(c.id);if(!f.stopped)return{stopped:!1,error:f.reason};return{stopped:!0}}catch(a){return{stopped:!1,error:a instanceof Error?a.message:"Failed to stop agent"}}}async function E(a){if(!a?.trim())return{error:"id is required"};try{let b=(0,d.resolve)("UnarchiveFeatureUseCase");return{feature:await b.execute(a)}}catch(a){return{error:a instanceof Error?a.message:"Failed to unarchive feature"}}}async function F(a){let{path:b,name:c}=a;if(!b?.trim())return{error:"path is required"};try{let a=(0,d.resolve)("AddRepositoryUseCase");return{repository:await a.execute({path:b,name:c})}}catch(a){return{error:a instanceof Error?a.message:"Failed to add repository"}}}async function G(a){if(!a?.trim())return{success:!1,error:"id is required"};try{let b=(0,d.resolve)("DeleteRepositoryUseCase");return await b.execute(a),{success:!0}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to delete repository"}}}(0,e.ensureServerEntryExports)([v]),(0,b.registerServerReference)(v,"008bb64e62c8da45930ed722f946b39495438d9fe4",null),a.s(["checkAgentAuth",0,v],9959),(0,e.ensureServerEntryExports)([x]),(0,b.registerServerReference)(x,"002809c4bbafc76cdc68bbb45f0e98f2c4f4a2c326",null),a.s(["checkToolStatus",0,x],79124),(0,e.ensureServerEntryExports)([y]),(0,b.registerServerReference)(y,"405c0161a824d7c6bfb099b9a201402629f9a809f4",null),a.s(["getFeatureMetadata",0,y],29207),(0,e.ensureServerEntryExports)([z]),(0,b.registerServerReference)(z,"40a85456a342184720e7bd43147ef6d61ed80fe86a",null),a.s(["archiveFeature",0,z],10528),(0,e.ensureServerEntryExports)([A]),(0,b.registerServerReference)(A,"7830a0050246cf0a7c64eb408158d03b581fa9fd2d",null),a.s(["deleteFeature",0,A],50845),(0,e.ensureServerEntryExports)([B]),(0,b.registerServerReference)(B,"40cc33d9eef0ed0ff39c963fb96616983a83d163c9",null),a.s(["resumeFeature",0,B],26604),(0,e.ensureServerEntryExports)([C]),(0,b.registerServerReference)(C,"409a12726d14b0171bed27175fc895f1737e25a59f",null),a.s(["startFeature",0,C],54723),(0,e.ensureServerEntryExports)([D]),(0,b.registerServerReference)(D,"409ca41fe22f43beef5f6007804d4ea4af1c742d6e",null),a.s(["stopFeature",0,D],18942),(0,e.ensureServerEntryExports)([E]),(0,b.registerServerReference)(E,"401724219fbd15d0044167e2ceadcb426a1b88b6f1",null),a.s(["unarchiveFeature",0,E],42886),(0,e.ensureServerEntryExports)([F]),(0,b.registerServerReference)(F,"40eabff44164a320ffdbb4d78762d986a3a08e9cb3",null),a.s(["addRepository",0,F],49560),(0,e.ensureServerEntryExports)([G]),(0,b.registerServerReference)(G,"4094b8bc3c9b9c623df2845c71dc8335b7bc03f8dc",null),a.s(["deleteRepository",0,G],39353)}];
1
+ module.exports=[84095,56799,80496,93225,41872,9959,79124,29207,10528,50845,26604,54723,18942,42886,49560,39353,a=>{"use strict";var b=a.i(2211),c=a.i(50227),d=a.i(96380),e=a.i(50961);async function f(a){let{repositoryPath:b,branch:e}=a;if(!b||!(0,c.isAbsolute)(b))return{success:!1,error:"repositoryPath must be an absolute path"};let f=(0,d.resolve)("LoadSettingsUseCase"),g=(await f.execute()).environment.defaultEditor,h=(0,d.resolve)("LaunchIdeUseCase"),i=await h.execute({editorId:g,repositoryPath:b,branch:e,checkAvailability:!0});return i.ok?{success:!0,editor:i.editorName,path:i.worktreePath}:{success:!1,error:i.message}}(0,e.ensureServerEntryExports)([f]),(0,b.registerServerReference)(f,"40bd95378f85d9fc8677f238428349adf4a666b28d",null),a.s(["openIde",0,f],84095);var g=a.i(2157),h=a.i(60526),i=a.i(74533);a.i(1442);var j=a.i(29918);let k={darwin:{cmd:"open",args:a=>["-a","Terminal",a]},linux:{cmd:"x-terminal-emulator",args:a=>[`--working-directory=${a}`]},win32:{cmd:"cmd.exe",args:a=>["/c","start","powershell","-NoExit","-Command",`Set-Location "${a}"`]}};async function l(a){let{repositoryPath:b,branch:e}=a;if(!b||!(0,c.isAbsolute)(b))return{success:!1,error:"repositoryPath must be an absolute path"};try{let a=(0,d.resolve)("LoadSettingsUseCase"),c=await a.execute(),f=c.environment.shellPreference,l=c.environment.terminalPreference??"system",m=function(a,b){try{let c=b?(0,j.computeWorktreePath)(a,b):a;return(0,g.realpathSync)(c)}catch{return null}}(b,e);if(!m)return{success:!1,error:"Path does not exist"};if("system"!==l)try{let a=(0,d.resolve)("IToolInstallerService").getTerminalOpenConfig(l);if(a?.openDirectory.includes("{dir}")){if(a.shell){let b=`'${m.replace(/'/g,"'\\''")}'`,c=a.openDirectory.replaceAll("{dir}",b),d=(0,i.spawn)(c,[],{detached:!0,stdio:"ignore",shell:!0});d.on("error",()=>void 0),d.unref()}else{let b=a.openDirectory.split(/\s+/).filter(Boolean),c=b[0],d=b.slice(1).map(a=>a.replaceAll("{dir}",m)),e=(0,i.spawn)(c,d,{detached:!0,stdio:"ignore"});e.on("error",()=>void 0),e.unref()}return{success:!0,path:m,shell:f}}}catch{}let n=k[(0,h.platform)()];if(!n)return{success:!1,error:`Unsupported platform: ${(0,h.platform)()}`};let o=(0,i.spawn)(n.cmd,n.args(m),{detached:!0,stdio:"ignore"});return o.on("error",()=>void 0),o.unref(),{success:!0,path:m,shell:f}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to open shell"}}}(0,e.ensureServerEntryExports)([l]),(0,b.registerServerReference)(l,"40eb980e322cab0e8eec73a5d80533863ac11b71f8",null),a.s(["openShell",0,l],56799);let m={darwin:{cmd:"open",args:a=>[a]},linux:{cmd:"xdg-open",args:a=>[a]},win32:{cmd:"explorer",args:a=>[a]}};async function n(a){if(!a||!(0,c.isAbsolute)(a))return{success:!1,error:"repositoryPath must be an absolute path"};try{let b;try{b=(0,g.realpathSync)(a)}catch{return{success:!1,error:"Directory not found"}}let d=m[(0,h.platform)()];if(!d)return{success:!1,error:`Unsupported platform: ${(0,h.platform)()}`};let e=(0,c.normalize)(b),f=(0,i.spawn)(d.cmd,d.args(e),{detached:!0,stdio:"ignore"});return f.on("error",()=>void 0),f.unref(),{success:!0,path:b}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to open folder"}}}async function o(a){if(!a?.trim())return{success:!1,error:"Repository id is required"};try{let b=(0,d.resolve)("SyncRepositoryMainUseCase");return await b.execute(a),{success:!0}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to sync repository"}}}async function p(){try{let a=(0,d.resolve)("LoadSettingsUseCase");return(await a.execute()).onboardingComplete}catch{return!1}}(0,e.ensureServerEntryExports)([n]),(0,b.registerServerReference)(n,"4008539e4d47c679220460e3e897439c27791e86f3",null),a.s(["openFolder",0,n],80496),(0,e.ensureServerEntryExports)([o]),(0,b.registerServerReference)(o,"40092b620bf789d5f068a5a6ca6ff5f9a9da65ad18",null),a.s(["syncRepository",0,o],93225),(0,e.ensureServerEntryExports)([p]),(0,b.registerServerReference)(p,"00330a8d9cee885d7bc3f693f2860bd1c8047adfda",null),a.s(["isAgentSetupComplete",0,p],41872);var q=a.i(37512);let r={"claude-code":"Claude Code","codex-cli":"Codex CLI","copilot-cli":"GitHub Copilot CLI",cursor:"Cursor CLI","gemini-cli":"Gemini CLI","rovo-dev":"Rovo Dev CLI"},s={"claude-code":"claude-code","codex-cli":"codex-cli","copilot-cli":"copilot-cli",cursor:"cursor-cli","gemini-cli":"gemini-cli","rovo-dev":"rovo-dev"},t={"claude-code":"claude","codex-cli":"codex","copilot-cli":"copilot",cursor:"cursor-agent","gemini-cli":"gemini","rovo-dev":"acli"};function u(a,b){return new Promise(c=>{let d,e;switch(a){case"claude-code":d=b,e=["auth","status"];break;case"cursor":d=b,e=["status"];break;case"codex-cli":c(!1);return;case"copilot-cli":default:c(!0);return;case"rovo-dev":{let a=q.IS_WINDOWS?{timeout:5e3,windowsHide:!0}:{timeout:5e3};(0,i.execFile)("acli",["rovodev","auth","status"],a,a=>{c(!a)});return}}try{let a=q.IS_WINDOWS?{timeout:5e3,windowsHide:!0}:{timeout:5e3};(0,i.execFile)(d,e,a,a=>{c(!a)})}catch{c(!1)}})}async function v(){let a;try{let b=(0,d.resolve)("LoadSettingsUseCase");a=(await b.execute()).agent.type}catch{return{agentType:"unknown",installed:!1,authenticated:!1,label:"Unknown",binaryName:null,installCommand:null,authCommand:null}}let b=r[a]??a,e=s[a]??null,f=t[a]??null;if(!e)return{agentType:a,installed:!0,authenticated:!0,label:b,binaryName:null,installCommand:null,authCommand:null};let i=!1,j=null;try{let a=(0,d.resolve)("ListToolsUseCase"),b=(await a.execute()).find(a=>a.id===e);i=b?.status.status==="available",j=b?.installCommand??null}catch{i=!1}if(!i)return{agentType:a,installed:!1,authenticated:!1,label:b,binaryName:f,installCommand:j,authCommand:f?`Install ${b} first`:null};let k=function(a){let b=(0,h.homedir)();switch(a){case"claude-code":{if(process.env.ANTHROPIC_API_KEY||process.env.CLAUDE_CODE_USE_BEDROCK||process.env.CLAUDE_CODE_USE_VERTEX||process.env.CLAUDE_CODE_OAUTH_TOKEN)return"env-var";let a=(0,c.join)(b,".claude",".credentials.json");return!!(0,g.existsSync)(a)&&"file"}case"codex-cli":if(process.env.OPENAI_API_KEY)return"env-var";return!1;case"cursor":{if(process.env.CURSOR_API_KEY)return"env-var";let a=(0,c.join)(b,".cursor");return!!(0,g.existsSync)(a)&&"file"}case"gemini-cli":{if(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||process.env.GOOGLE_APPLICATION_CREDENTIALS)return"env-var";let a=(0,c.join)(b,".gemini","google_accounts.json");return!!(0,g.existsSync)(a)&&"file"}case"copilot-cli":{if(process.env.COPILOT_GITHUB_TOKEN||process.env.GH_TOKEN||process.env.GITHUB_TOKEN)return"env-var";let a=process.env.COPILOT_HOME?(0,c.join)(process.env.COPILOT_HOME,"config.json"):(0,c.join)(b,".copilot","config.json");return!!(0,g.existsSync)(a)&&"file"}case"rovo-dev":{if(process.env.ATLASSIAN_API_TOKEN)return"env-var";let a=(0,c.join)(b,".acli");return!!(0,g.existsSync)(a)&&"file"}default:return"env-var"}}(a);if("env-var"===k)return{agentType:a,installed:!0,authenticated:!0,label:b,binaryName:f,installCommand:j,authCommand:null};if("file"===k){let c=!0;return f&&(c=await u(a,f)),{agentType:a,installed:!0,authenticated:c,label:b,binaryName:f,installCommand:j,authCommand:c?null:f}}return f&&await u(a,f)?{agentType:a,installed:!0,authenticated:!0,label:b,binaryName:f,installCommand:j,authCommand:null}:{agentType:a,installed:!0,authenticated:!1,label:b,binaryName:f,installCommand:j,authCommand:f}}function w(a,b){return new Promise(c=>{try{let d=q.IS_WINDOWS?{timeout:5e3,windowsHide:!0}:{timeout:5e3};(0,i.execFile)(a,b,d,(a,b)=>{if(a)return void c({installed:!1,version:null});let d=b.match(/(\d+\.\d+(?:\.\d+)?)/);c({installed:!0,version:d?.[1]??null})})}catch{c({installed:!1,version:null})}})}async function x(){let[a,b,c]=await Promise.all([w("git",["--version"]),w("gh",["--version"]),(async()=>{try{let a=(0,d.resolve)("ListToolsUseCase");return await a.execute()}catch{return[]}})()]),e=c.find(a=>"git"===a.id),f=c.find(a=>"gh"===a.id);return{git:{...a,installCommand:e?.installCommand??null,installUrl:e?.website??"https://git-scm.com"},gh:{...b,installCommand:f?.installCommand??null,installUrl:f?.website??"https://cli.github.com"}}}async function y(a){let b=(0,d.resolve)("IFeatureRepository"),c=await b.findById(a);return c?{name:c.name,description:c.description}:null}async function z(a){if(!a?.trim())return{error:"id is required"};try{let b=(0,d.resolve)("ArchiveFeatureUseCase");return{feature:await b.execute(a)}}catch(a){return{error:a instanceof Error?a.message:"Failed to archive feature"}}}async function A(a,b,c,e){if(!a?.trim())return{error:"id is required"};try{let f=(0,d.resolve)("DeleteFeatureUseCase"),g={};return void 0!==b&&(g.cleanup=b),void 0!==c&&(g.cascadeDelete=c),void 0!==e&&(g.closePr=e),{feature:Object.keys(g).length>0?await f.execute(a,g):await f.execute(a)}}catch(a){return{error:a instanceof Error?a.message:"Failed to delete feature"}}}async function B(a){if(!a.trim())return{resumed:!1,error:"Feature id is required"};try{let b=(0,d.resolve)("ResumeFeatureUseCase");return await b.execute(a),{resumed:!0}}catch(a){return{resumed:!1,error:a instanceof Error?a.message:"Failed to resume feature"}}}async function C(a){if(!a.trim())return{started:!1,error:"Feature id is required"};try{let b=(0,d.resolve)("StartFeatureUseCase");return await b.execute(a),{started:!0}}catch(a){return{started:!1,error:a instanceof Error?a.message:"Failed to start feature"}}}async function D(a){if(!a.trim())return{stopped:!1,error:"Feature id is required"};try{let b=(0,d.resolve)("IAgentRunRepository"),c=(await b.list()).find(b=>b.featureId===a&&"completed"!==b.status&&"failed"!==b.status&&"interrupted"!==b.status&&"cancelled"!==b.status);if(!c)return{stopped:!1,error:"No active agent run found for this feature"};let e=(0,d.resolve)("StopAgentRunUseCase"),f=await e.execute(c.id);if(!f.stopped)return{stopped:!1,error:f.reason};return{stopped:!0}}catch(a){return{stopped:!1,error:a instanceof Error?a.message:"Failed to stop agent"}}}async function E(a){if(!a?.trim())return{error:"id is required"};try{let b=(0,d.resolve)("UnarchiveFeatureUseCase");return{feature:await b.execute(a)}}catch(a){return{error:a instanceof Error?a.message:"Failed to unarchive feature"}}}async function F(a){let{path:b,name:c}=a;if(!b?.trim())return{error:"path is required"};try{let a=(0,d.resolve)("AddRepositoryUseCase");return{repository:await a.execute({path:b,name:c})}}catch(a){return{error:a instanceof Error?a.message:"Failed to add repository"}}}async function G(a){if(!a?.trim())return{success:!1,error:"id is required"};try{let b=(0,d.resolve)("DeleteRepositoryUseCase");return await b.execute(a),{success:!0}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to delete repository"}}}(0,e.ensureServerEntryExports)([v]),(0,b.registerServerReference)(v,"00d8d6691808e46f24a12aba9a772e135fabe25dc9",null),a.s(["checkAgentAuth",0,v],9959),(0,e.ensureServerEntryExports)([x]),(0,b.registerServerReference)(x,"001be5d686fc82310b2a13cd91f69f4763cd8a7179",null),a.s(["checkToolStatus",0,x],79124),(0,e.ensureServerEntryExports)([y]),(0,b.registerServerReference)(y,"404ca6022a436889616459953ffb37ff50f4e907ca",null),a.s(["getFeatureMetadata",0,y],29207),(0,e.ensureServerEntryExports)([z]),(0,b.registerServerReference)(z,"402b0d65d22ce49539f2d2f698460e94770f7e8b2d",null),a.s(["archiveFeature",0,z],10528),(0,e.ensureServerEntryExports)([A]),(0,b.registerServerReference)(A,"78905067eb607d1d1fee68a4dad95b6851ba1e358c",null),a.s(["deleteFeature",0,A],50845),(0,e.ensureServerEntryExports)([B]),(0,b.registerServerReference)(B,"40a8a21574a49332d0e088f4fb98d173266a767b8c",null),a.s(["resumeFeature",0,B],26604),(0,e.ensureServerEntryExports)([C]),(0,b.registerServerReference)(C,"40acd38b09e329a002b25937d82d210ce17904a8b5",null),a.s(["startFeature",0,C],54723),(0,e.ensureServerEntryExports)([D]),(0,b.registerServerReference)(D,"40362cbf555132f34944afb3ede38cbee4149319bb",null),a.s(["stopFeature",0,D],18942),(0,e.ensureServerEntryExports)([E]),(0,b.registerServerReference)(E,"406ce7604dcd3a981529cce29e8f800f01766b4619",null),a.s(["unarchiveFeature",0,E],42886),(0,e.ensureServerEntryExports)([F]),(0,b.registerServerReference)(F,"4066e37c6a9d686acc8b9b189bce05732045800364",null),a.s(["addRepository",0,F],49560),(0,e.ensureServerEntryExports)([G]),(0,b.registerServerReference)(G,"4041a5239db59b27ce7c01c1528406ce2fc3d85c95",null),a.s(["deleteRepository",0,G],39353)}];
2
2
 
3
3
  //# sourceMappingURL=src_presentation_web_app_actions_open-ide_ts_0w2wqvu._.js.map