@shepai/cli 1.46.0 → 1.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (177) hide show
  1. package/apis/json-schema/ApprovalGateDefaults.yaml +26 -0
  2. package/apis/json-schema/Feature.yaml +3 -0
  3. package/apis/json-schema/Repository.yaml +16 -0
  4. package/apis/json-schema/Settings.yaml +5 -0
  5. package/apis/json-schema/WorkflowConfig.yaml +4 -20
  6. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts +17 -0
  7. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -1
  8. package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts +11 -1
  9. package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts.map +1 -1
  10. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts +3 -1
  11. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  12. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +11 -4
  13. package/dist/packages/core/src/application/use-cases/features/get-plan-artifact.use-case.d.ts +19 -0
  14. package/dist/packages/core/src/application/use-cases/features/get-plan-artifact.use-case.d.ts.map +1 -0
  15. package/dist/packages/core/src/application/use-cases/features/get-plan-artifact.use-case.js +52 -0
  16. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  17. package/dist/packages/core/src/infrastructure/di/container.js +5 -0
  18. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
  19. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +2 -0
  20. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts +2 -0
  21. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts.map +1 -1
  22. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.js +10 -3
  23. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts.map +1 -1
  24. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.js +15 -7
  25. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +2 -0
  26. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
  27. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +41 -0
  28. package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts +2 -1
  29. package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts.map +1 -1
  30. package/dist/packages/core/src/infrastructure/services/git/worktree.service.js +29 -4
  31. package/dist/src/presentation/cli/ui/messages.d.ts.map +1 -1
  32. package/dist/src/presentation/cli/ui/messages.js +1 -7
  33. package/dist/src/presentation/web/app/actions/create-feature.d.ts +2 -0
  34. package/dist/src/presentation/web/app/actions/create-feature.d.ts.map +1 -1
  35. package/dist/src/presentation/web/app/actions/create-feature.js +3 -1
  36. package/dist/src/presentation/web/app/actions/get-merge-review-data.d.ts +7 -0
  37. package/dist/src/presentation/web/app/actions/get-merge-review-data.d.ts.map +1 -0
  38. package/dist/src/presentation/web/app/actions/get-merge-review-data.js +49 -0
  39. package/dist/src/presentation/web/app/actions/get-workflow-defaults.d.ts +11 -0
  40. package/dist/src/presentation/web/app/actions/get-workflow-defaults.d.ts.map +1 -0
  41. package/dist/src/presentation/web/app/actions/get-workflow-defaults.js +15 -0
  42. package/dist/src/presentation/web/app/page.d.ts.map +1 -1
  43. package/dist/src/presentation/web/app/page.js +1 -0
  44. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +5 -1
  45. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  46. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +25 -7
  47. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +17 -0
  48. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
  49. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +54 -2
  50. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  51. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +8 -1
  52. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +1 -0
  53. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
  54. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +22 -1
  55. package/dist/src/presentation/web/components/common/merge-review/index.d.ts +4 -0
  56. package/dist/src/presentation/web/components/common/merge-review/index.d.ts.map +1 -0
  57. package/dist/src/presentation/web/components/common/merge-review/index.js +2 -0
  58. package/dist/src/presentation/web/components/common/merge-review/merge-review-config.d.ts +75 -0
  59. package/dist/src/presentation/web/components/common/merge-review/merge-review-config.d.ts.map +1 -0
  60. package/dist/src/presentation/web/components/common/merge-review/merge-review-config.js +1 -0
  61. package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.d.ts +3 -0
  62. package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.d.ts.map +1 -0
  63. package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.js +7 -0
  64. package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts +3 -0
  65. package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts.map +1 -0
  66. package/dist/src/presentation/web/components/common/merge-review/merge-review.js +36 -0
  67. package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.d.ts +32 -0
  68. package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.d.ts.map +1 -0
  69. package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.js +165 -0
  70. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  71. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +66 -2
  72. package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts.map +1 -1
  73. package/dist/src/presentation/web/components/features/control-center/control-center.stories.js +15 -0
  74. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  75. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +37 -15
  76. package/dist/tsconfig.build.tsbuildinfo +1 -1
  77. package/package.json +1 -1
  78. package/web/.next/BUILD_ID +1 -1
  79. package/web/.next/build-manifest.json +2 -2
  80. package/web/.next/cache/.previewinfo +1 -1
  81. package/web/.next/cache/.rscinfo +1 -1
  82. package/web/.next/cache/.tsbuildinfo +1 -1
  83. package/web/.next/cache/config.json +3 -3
  84. package/web/.next/fallback-build-manifest.json +2 -2
  85. package/web/.next/prerender-manifest.json +3 -3
  86. package/web/.next/required-server-files.js +1 -1
  87. package/web/.next/required-server-files.json +1 -1
  88. package/web/.next/server/app/_global-error.html +2 -2
  89. package/web/.next/server/app/_global-error.rsc +1 -1
  90. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  91. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  92. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  93. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  94. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  95. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  96. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  97. package/web/.next/server/app/page/server-reference-manifest.json +52 -22
  98. package/web/.next/server/app/page.js +1 -1
  99. package/web/.next/server/app/page.js.nft.json +1 -1
  100. package/web/.next/server/app/page_client-reference-manifest.js +1 -1
  101. package/web/.next/server/app/version/page.js.nft.json +1 -1
  102. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  103. package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +4 -4
  104. package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js.map +1 -1
  105. package/web/.next/server/chunks/ssr/[root-of-the-server]__19d52794._.js +9 -0
  106. package/web/.next/server/chunks/ssr/[root-of-the-server]__19d52794._.js.map +1 -0
  107. package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  108. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/_3ac3601c._.js → server/chunks/ssr/_1fafa9db._.js} +2 -2
  109. package/web/.next/server/chunks/ssr/_1fafa9db._.js.map +1 -0
  110. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  111. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  112. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
  113. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js.map +1 -1
  114. package/web/.next/server/pages/500.html +2 -2
  115. package/web/.next/server/server-reference-manifest.js +1 -1
  116. package/web/.next/server/server-reference-manifest.json +53 -23
  117. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  118. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
  119. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  120. package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
  121. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  122. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  123. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  124. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  125. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  126. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  127. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  128. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  129. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  130. package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +52 -22
  131. package/web/.next/standalone/src/presentation/web/.next/server/app/page.js +1 -1
  132. package/web/.next/standalone/src/presentation/web/.next/server/app/page.js.nft.json +1 -1
  133. package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
  134. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js.nft.json +1 -1
  135. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  136. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +4 -4
  137. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__19d52794._.js +9 -0
  138. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  139. package/web/.next/{server/chunks/ssr/_3ac3601c._.js → standalone/src/presentation/web/.next/server/chunks/ssr/_1fafa9db._.js} +2 -2
  140. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  141. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
  142. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  143. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  144. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +53 -23
  145. package/web/.next/standalone/src/presentation/web/app/actions/create-feature.ts +5 -1
  146. package/web/.next/standalone/src/presentation/web/app/actions/get-merge-review-data.ts +64 -0
  147. package/web/.next/standalone/src/presentation/web/app/actions/get-workflow-defaults.ts +28 -0
  148. package/web/.next/standalone/src/presentation/web/app/page.tsx +1 -0
  149. package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.tsx +74 -1
  150. package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx +55 -5
  151. package/web/.next/standalone/src/presentation/web/components/common/feature-node/feature-node.stories.tsx +23 -1
  152. package/web/.next/standalone/src/presentation/web/components/common/feature-node/feature-node.tsx +6 -1
  153. package/web/.next/standalone/src/presentation/web/components/common/merge-review/index.ts +7 -0
  154. package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review-config.ts +81 -0
  155. package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review-drawer.tsx +34 -0
  156. package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review.stories.tsx +240 -0
  157. package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review.tsx +252 -0
  158. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +96 -1
  159. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center.stories.tsx +15 -0
  160. package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +47 -17
  161. package/web/.next/standalone/src/presentation/web/server.js +1 -1
  162. package/web/.next/static/chunks/{9f8e71029fb04681.js → 0da7a9860fa6ae05.js} +2 -2
  163. package/web/.next/static/chunks/22f30ce91a3c79c1.js +1 -0
  164. package/web/.next/static/chunks/66378a6c055c4e67.js +10 -0
  165. package/web/.next/static/chunks/8668962d3e682263.css +2 -0
  166. package/web/.next/trace +1 -1
  167. package/web/.next/trace-build +1 -1
  168. package/web/.next/server/chunks/ssr/[root-of-the-server]__4e8ca89c._.js +0 -9
  169. package/web/.next/server/chunks/ssr/[root-of-the-server]__4e8ca89c._.js.map +0 -1
  170. package/web/.next/server/chunks/ssr/_3ac3601c._.js.map +0 -1
  171. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__4e8ca89c._.js +0 -9
  172. package/web/.next/static/chunks/83ff3b6bbee54bce.js +0 -1
  173. package/web/.next/static/chunks/b7b7abe79e05b229.css +0 -2
  174. package/web/.next/static/chunks/ecf44fa8a155c854.js +0 -10
  175. /package/web/.next/static/{nM-uXIiW9k_0Z_GM_4bI4 → 1kZFDMQ0i-Y8dy1KkHlzv}/_buildManifest.js +0 -0
  176. /package/web/.next/static/{nM-uXIiW9k_0Z_GM_4bI4 → 1kZFDMQ0i-Y8dy1KkHlzv}/_clientMiddlewareManifest.json +0 -0
  177. /package/web/.next/static/{nM-uXIiW9k_0Z_GM_4bI4 → 1kZFDMQ0i-Y8dy1KkHlzv}/_ssgManifest.js +0 -0
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "node": {
3
- "40ec19e5dbcddd81282a5e566066b8fe1b310f1786": {
3
+ "405927de7a51b3fdbf3bce187705d5f3a33c599793": {
4
4
  "workers": {
5
5
  "app/page": {
6
- "moduleId": 23768,
6
+ "moduleId": 30953,
7
7
  "async": false,
8
8
  "exportedName": "approveFeature",
9
9
  "filename": "src/presentation/web/app/actions/approve-feature.ts"
@@ -15,10 +15,10 @@
15
15
  "filename": "src/presentation/web/app/actions/approve-feature.ts",
16
16
  "exportedName": "approveFeature"
17
17
  },
18
- "407ac719162649e3a92d1d66213136b4f3049706b1": {
18
+ "40bd05da6b59c64afa59bd767ea7563b23608711a0": {
19
19
  "workers": {
20
20
  "app/page": {
21
- "moduleId": 23768,
21
+ "moduleId": 30953,
22
22
  "async": false,
23
23
  "exportedName": "getFeatureArtifact",
24
24
  "filename": "src/presentation/web/app/actions/get-feature-artifact.ts"
@@ -30,10 +30,10 @@
30
30
  "filename": "src/presentation/web/app/actions/get-feature-artifact.ts",
31
31
  "exportedName": "getFeatureArtifact"
32
32
  },
33
- "404bd4c7e835b3c134b911ca855719ad0541728c9f": {
33
+ "4052167b4529af8c247a75b3051a28f058af8a0ac9": {
34
34
  "workers": {
35
35
  "app/page": {
36
- "moduleId": 23768,
36
+ "moduleId": 30953,
37
37
  "async": false,
38
38
  "exportedName": "getResearchArtifact",
39
39
  "filename": "src/presentation/web/app/actions/get-research-artifact.ts"
@@ -45,10 +45,40 @@
45
45
  "filename": "src/presentation/web/app/actions/get-research-artifact.ts",
46
46
  "exportedName": "getResearchArtifact"
47
47
  },
48
- "40ef4c3a7d8c17c97a759027453ae9fb2a674eb831": {
48
+ "00fd01b28bb7867f8544c9906f5037e63c7202fa8e": {
49
49
  "workers": {
50
50
  "app/page": {
51
- "moduleId": 23768,
51
+ "moduleId": 30953,
52
+ "async": false,
53
+ "exportedName": "getWorkflowDefaults",
54
+ "filename": "src/presentation/web/app/actions/get-workflow-defaults.ts"
55
+ }
56
+ },
57
+ "layer": {
58
+ "app/page": "action-browser"
59
+ },
60
+ "filename": "src/presentation/web/app/actions/get-workflow-defaults.ts",
61
+ "exportedName": "getWorkflowDefaults"
62
+ },
63
+ "40952da4050947a94de113924015351244089d8ffe": {
64
+ "workers": {
65
+ "app/page": {
66
+ "moduleId": 30953,
67
+ "async": false,
68
+ "exportedName": "getMergeReviewData",
69
+ "filename": "src/presentation/web/app/actions/get-merge-review-data.ts"
70
+ }
71
+ },
72
+ "layer": {
73
+ "app/page": "action-browser"
74
+ },
75
+ "filename": "src/presentation/web/app/actions/get-merge-review-data.ts",
76
+ "exportedName": "getMergeReviewData"
77
+ },
78
+ "40bfc128861432d76522cc52efd6249895ce00ab03": {
79
+ "workers": {
80
+ "app/page": {
81
+ "moduleId": 30953,
52
82
  "async": false,
53
83
  "exportedName": "openIde",
54
84
  "filename": "src/presentation/web/app/actions/open-ide.ts"
@@ -60,10 +90,10 @@
60
90
  "filename": "src/presentation/web/app/actions/open-ide.ts",
61
91
  "exportedName": "openIde"
62
92
  },
63
- "4083093b10c0bf2c4b635ab659b9047b7ee71f2eec": {
93
+ "4033b24b3695151d1f14d8d9b2df4db2ab821d1aa1": {
64
94
  "workers": {
65
95
  "app/page": {
66
- "moduleId": 23768,
96
+ "moduleId": 30953,
67
97
  "async": false,
68
98
  "exportedName": "openShell",
69
99
  "filename": "src/presentation/web/app/actions/open-shell.ts"
@@ -75,10 +105,10 @@
75
105
  "filename": "src/presentation/web/app/actions/open-shell.ts",
76
106
  "exportedName": "openShell"
77
107
  },
78
- "406b0905f6f16e1cbe4c3e457de80482ec1de3f298": {
108
+ "400805d5028779c5a42a1b209d0ccd103df6aae782": {
79
109
  "workers": {
80
110
  "app/page": {
81
- "moduleId": 23768,
111
+ "moduleId": 30953,
82
112
  "async": false,
83
113
  "exportedName": "openFolder",
84
114
  "filename": "src/presentation/web/app/actions/open-folder.ts"
@@ -90,10 +120,10 @@
90
120
  "filename": "src/presentation/web/app/actions/open-folder.ts",
91
121
  "exportedName": "openFolder"
92
122
  },
93
- "00e5fbd6452e1769c8d04f2f456d45281bef984172": {
123
+ "002086e55ab6adb498958985cc6b499caadb8efe8a": {
94
124
  "workers": {
95
125
  "app/page": {
96
- "moduleId": 23768,
126
+ "moduleId": 30953,
97
127
  "async": false,
98
128
  "exportedName": "pickFolder",
99
129
  "filename": "src/presentation/web/app/actions/pick-folder.ts"
@@ -105,10 +135,10 @@
105
135
  "filename": "src/presentation/web/app/actions/pick-folder.ts",
106
136
  "exportedName": "pickFolder"
107
137
  },
108
- "40ad939617f957f8c29d2c37c088433f000f3fa4df": {
138
+ "4070bbfbc7263457fbf281a0e0dcd7a43c12b30a17": {
109
139
  "workers": {
110
140
  "app/page": {
111
- "moduleId": 23768,
141
+ "moduleId": 30953,
112
142
  "async": false,
113
143
  "exportedName": "createFeature",
114
144
  "filename": "src/presentation/web/app/actions/create-feature.ts"
@@ -120,10 +150,10 @@
120
150
  "filename": "src/presentation/web/app/actions/create-feature.ts",
121
151
  "exportedName": "createFeature"
122
152
  },
123
- "40ef8320799551d45d3bc1579b90bf9e0e62a7ffa7": {
153
+ "4045ff41ea532f2c3e9970f8022b64a977da6e2eca": {
124
154
  "workers": {
125
155
  "app/page": {
126
- "moduleId": 23768,
156
+ "moduleId": 30953,
127
157
  "async": false,
128
158
  "exportedName": "deleteFeature",
129
159
  "filename": "src/presentation/web/app/actions/delete-feature.ts"
@@ -135,10 +165,10 @@
135
165
  "filename": "src/presentation/web/app/actions/delete-feature.ts",
136
166
  "exportedName": "deleteFeature"
137
167
  },
138
- "40b2dd613250d04133b76e2b6972c715bf57e4bd99": {
168
+ "40c7ab52e7389ec3d2f6a78fdd2b5686746b247b24": {
139
169
  "workers": {
140
170
  "app/page": {
141
- "moduleId": 23768,
171
+ "moduleId": 30953,
142
172
  "async": false,
143
173
  "exportedName": "addRepository",
144
174
  "filename": "src/presentation/web/app/actions/add-repository.ts"
@@ -150,10 +180,10 @@
150
180
  "filename": "src/presentation/web/app/actions/add-repository.ts",
151
181
  "exportedName": "addRepository"
152
182
  },
153
- "40eadea1d575abd2b4f8bffd4e55fa1411b42a8169": {
183
+ "406251232c435014ef64078d485da082110be0fb37": {
154
184
  "workers": {
155
185
  "app/page": {
156
- "moduleId": 23768,
186
+ "moduleId": 30953,
157
187
  "async": false,
158
188
  "exportedName": "deleteRepository",
159
189
  "filename": "src/presentation/web/app/actions/delete-repository.ts"
@@ -167,5 +197,5 @@
167
197
  }
168
198
  },
169
199
  "edge": {},
170
- "encryptionKey": "GgVq/PcpPblftJmrvtOlevtwRA1pxQYdoN2fEZDJXaI="
200
+ "encryptionKey": "hCzppyIeZCi6mpL+ZJ0dlbq42XLKa14KFhRtB9jR6iI="
171
201
  }
@@ -25,6 +25,8 @@ interface CreateFeatureInput {
25
25
  allowPlan: boolean;
26
26
  allowMerge?: boolean;
27
27
  };
28
+ push?: boolean;
29
+ openPr?: boolean;
28
30
  }
29
31
 
30
32
  function composeUserInput(
@@ -49,7 +51,7 @@ function composeUserInput(
49
51
  export async function createFeature(
50
52
  input: CreateFeatureInput
51
53
  ): Promise<{ feature?: Feature; error?: string }> {
52
- const { name, description, repositoryPath, attachments, approvalGates } = input;
54
+ const { name, description, repositoryPath, attachments, approvalGates, push, openPr } = input;
53
55
 
54
56
  if (!name?.trim()) {
55
57
  return { error: 'name is required' };
@@ -72,6 +74,8 @@ export async function createFeature(
72
74
  userInput,
73
75
  repositoryPath,
74
76
  approvalGates: gates,
77
+ push: push ?? false,
78
+ openPr: openPr ?? false,
75
79
  });
76
80
  return { feature: result.feature };
77
81
  } catch (error: unknown) {
@@ -0,0 +1,64 @@
1
+ 'use server';
2
+
3
+ import { resolve } from '@/lib/server-container';
4
+ import type { IFeatureRepository } from '@shepai/core/application/ports/output/repositories/feature-repository.interface';
5
+ import type { IGitPrService } from '@shepai/core/application/ports/output/services/git-pr-service.interface';
6
+ import type { GetPlanArtifactUseCase } from '@shepai/core/application/use-cases/features/get-plan-artifact.use-case';
7
+ import type {
8
+ MergeReviewData,
9
+ MergeReviewPhase,
10
+ } from '@/components/common/merge-review/merge-review-config';
11
+
12
+ type GetMergeReviewDataResult = MergeReviewData | { error: string };
13
+
14
+ export async function getMergeReviewData(featureId: string): Promise<GetMergeReviewDataResult> {
15
+ if (!featureId.trim()) {
16
+ return { error: 'Feature id is required' };
17
+ }
18
+
19
+ try {
20
+ const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');
21
+ const feature = await featureRepo.findById(featureId);
22
+
23
+ if (!feature) {
24
+ return { error: 'Feature not found' };
25
+ }
26
+
27
+ const pr = feature.pr
28
+ ? {
29
+ url: feature.pr.url,
30
+ number: feature.pr.number,
31
+ status: feature.pr.status,
32
+ commitHash: feature.pr.commitHash,
33
+ ciStatus: feature.pr.ciStatus,
34
+ }
35
+ : undefined;
36
+
37
+ const branch = feature.branch ? { source: feature.branch, target: 'main' } : undefined;
38
+
39
+ // Load plan phases (best-effort)
40
+ let phases: MergeReviewPhase[] | undefined;
41
+ try {
42
+ const planUseCase = resolve<GetPlanArtifactUseCase>('GetPlanArtifactUseCase');
43
+ const plan = await planUseCase.execute(featureId);
44
+ phases = plan.phases.map(({ id, name, description }) => ({ id, name, description }));
45
+ } catch {
46
+ // Plan unavailable — not critical
47
+ }
48
+
49
+ if (!feature.worktreePath) {
50
+ return { pr, branch, phases, warning: pr ? undefined : 'No PR or diff data available' };
51
+ }
52
+
53
+ try {
54
+ const gitPrService = resolve<IGitPrService>('IGitPrService');
55
+ const diffSummary = await gitPrService.getPrDiffSummary(feature.worktreePath, 'main');
56
+ return { pr, branch, phases, diffSummary };
57
+ } catch {
58
+ return { pr, branch, phases, warning: 'Diff statistics unavailable' };
59
+ }
60
+ } catch (error: unknown) {
61
+ const message = error instanceof Error ? error.message : 'Failed to load merge review data';
62
+ return { error: message };
63
+ }
64
+ }
@@ -0,0 +1,28 @@
1
+ 'use server';
2
+
3
+ import { getSettings } from '@shepai/core/infrastructure/services/settings.service';
4
+
5
+ export interface WorkflowDefaults {
6
+ approvalGates: {
7
+ allowPrd: boolean;
8
+ allowPlan: boolean;
9
+ allowMerge: boolean;
10
+ };
11
+ push: boolean;
12
+ openPr: boolean;
13
+ }
14
+
15
+ export async function getWorkflowDefaults(): Promise<WorkflowDefaults> {
16
+ const settings = getSettings();
17
+ const { workflow } = settings;
18
+
19
+ return {
20
+ approvalGates: {
21
+ allowPrd: workflow.approvalGateDefaults.allowPrd,
22
+ allowPlan: workflow.approvalGateDefaults.allowPlan,
23
+ allowMerge: workflow.approvalGateDefaults.allowMerge,
24
+ },
25
+ push: workflow.approvalGateDefaults.pushOnImplementationComplete,
26
+ openPr: workflow.openPrOnImplementationComplete,
27
+ };
28
+ }
@@ -32,6 +32,7 @@ const nodeToLifecyclePhase: Record<string, FeatureLifecyclePhase> = {
32
32
  research: 'research',
33
33
  plan: 'implementation',
34
34
  implement: 'implementation',
35
+ merge: 'review',
35
36
  };
36
37
 
37
38
  export default async function HomePage() {
@@ -3,6 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react';
3
3
  import { within, userEvent, fn } from '@storybook/test';
4
4
  import { FeatureCreateDrawer } from './feature-create-drawer';
5
5
  import type { FeatureCreatePayload } from './feature-create-drawer';
6
+ import type { WorkflowDefaults } from '@/app/actions/get-workflow-defaults';
6
7
  import { Button } from '@/components/ui/button';
7
8
 
8
9
  /* ---------------------------------------------------------------------------
@@ -81,7 +82,13 @@ const logClose = fn().mockName('onClose');
81
82
  * ------------------------------------------------------------------------- */
82
83
 
83
84
  /** Starts closed — click button to open. Actions are logged. */
84
- function CreateDrawerTrigger({ label = 'Open Create Feature' }: { label?: string }) {
85
+ function CreateDrawerTrigger({
86
+ label = 'Open Create Feature',
87
+ workflowDefaults,
88
+ }: {
89
+ label?: string;
90
+ workflowDefaults?: WorkflowDefaults;
91
+ }) {
85
92
  const [open, setOpen] = useState(false);
86
93
 
87
94
  return (
@@ -100,6 +107,7 @@ function CreateDrawerTrigger({ label = 'Open Create Feature' }: { label?: string
100
107
  setOpen(false);
101
108
  }}
102
109
  repositoryPath="/Users/dev/my-repo"
110
+ workflowDefaults={workflowDefaults}
103
111
  />
104
112
  </div>
105
113
  );
@@ -222,6 +230,71 @@ export const MergeOnly: Story = {
222
230
  },
223
231
  };
224
232
 
233
+ /* ---------------------------------------------------------------------------
234
+ * Git checkbox stories
235
+ * ------------------------------------------------------------------------- */
236
+
237
+ /**
238
+ * Push checkbox checked — the "Push" option is enabled so the branch will be
239
+ * pushed to remote after implementation. "Create PR" remains unchecked.
240
+ */
241
+ export const PushOnly: Story = {
242
+ render: () => <CreateDrawerTrigger label="Open (Push Only)" />,
243
+ play: async ({ canvasElement }) => {
244
+ const canvas = within(canvasElement);
245
+ await userEvent.click(canvas.getByRole('button', { name: 'Open (Push Only)' }));
246
+
247
+ const body = within(canvasElement.ownerDocument.body);
248
+ const pushCheckbox = await body.findByLabelText('Push');
249
+ await userEvent.click(pushCheckbox);
250
+ },
251
+ };
252
+
253
+ /**
254
+ * Create PR checked — checking "Create PR" auto-checks and disables "Push"
255
+ * because a PR cannot be created without pushing. Both checkboxes appear
256
+ * checked, but "Push" is non-interactive (disabled).
257
+ */
258
+ export const PrChecked: Story = {
259
+ render: () => <CreateDrawerTrigger label="Open (PR Checked)" />,
260
+ play: async ({ canvasElement }) => {
261
+ const canvas = within(canvasElement);
262
+ await userEvent.click(canvas.getByRole('button', { name: 'Open (PR Checked)' }));
263
+
264
+ const body = within(canvasElement.ownerDocument.body);
265
+ const prCheckbox = await body.findByLabelText('Create PR');
266
+ await userEvent.click(prCheckbox);
267
+ },
268
+ };
269
+
270
+ /* ---------------------------------------------------------------------------
271
+ * Workflow defaults stories
272
+ * ------------------------------------------------------------------------- */
273
+
274
+ const SAMPLE_WORKFLOW_DEFAULTS: WorkflowDefaults = {
275
+ approvalGates: { allowPrd: true, allowPlan: true, allowMerge: false },
276
+ push: true,
277
+ openPr: true,
278
+ };
279
+
280
+ /**
281
+ * Drawer pre-populated from workflow settings — PRD and Plan approval gates
282
+ * are checked, Push and Create PR are enabled. These values come from
283
+ * `shep settings workflow` and are read at mount time via `getWorkflowDefaults()`.
284
+ */
285
+ export const WithWorkflowDefaults: Story = {
286
+ render: () => (
287
+ <CreateDrawerTrigger
288
+ label="Open (Workflow Defaults)"
289
+ workflowDefaults={SAMPLE_WORKFLOW_DEFAULTS}
290
+ />
291
+ ),
292
+ play: async ({ canvasElement }) => {
293
+ const canvas = within(canvasElement);
294
+ await userEvent.click(canvas.getByRole('button', { name: 'Open (Workflow Defaults)' }));
295
+ },
296
+ };
297
+
225
298
  /* ---------------------------------------------------------------------------
226
299
  * Interactive story — full paths shown in submitted data panel
227
300
  * ------------------------------------------------------------------------- */
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { useState, useCallback } from 'react';
3
+ import { useState, useCallback, useEffect } from 'react';
4
4
  import type { LucideIcon } from 'lucide-react';
5
5
  import {
6
6
  XIcon,
@@ -25,9 +25,11 @@ import { Input } from '@/components/ui/input';
25
25
  import { Textarea } from '@/components/ui/textarea';
26
26
  import { Label } from '@/components/ui/label';
27
27
  import { CheckboxGroup } from '@/components/ui/checkbox-group';
28
+ import { CheckboxGroupItem } from '@/components/ui/checkbox-group-item';
28
29
  import { Separator } from '@/components/ui/separator';
29
30
  import { Badge } from '@/components/ui/badge';
30
31
  import type { FileAttachment } from '@shepai/core/infrastructure/services/file-dialog.service';
32
+ import type { WorkflowDefaults } from '@/app/actions/get-workflow-defaults';
31
33
  import { pickFiles } from './pick-files';
32
34
 
33
35
  export type { FileAttachment } from '@shepai/core/infrastructure/services/file-dialog.service';
@@ -42,6 +44,8 @@ export interface FeatureCreatePayload {
42
44
  allowPlan: boolean;
43
45
  allowMerge: boolean;
44
46
  };
47
+ push: boolean;
48
+ openPr: boolean;
45
49
  }
46
50
 
47
51
  const AUTO_APPROVE_OPTIONS = [
@@ -62,6 +66,7 @@ export interface FeatureCreateDrawerProps {
62
66
  onSubmit: (data: FeatureCreatePayload) => void;
63
67
  repositoryPath: string;
64
68
  isSubmitting?: boolean;
69
+ workflowDefaults?: WorkflowDefaults;
65
70
  }
66
71
 
67
72
  export function FeatureCreateDrawer({
@@ -70,18 +75,36 @@ export function FeatureCreateDrawer({
70
75
  onSubmit,
71
76
  repositoryPath,
72
77
  isSubmitting = false,
78
+ workflowDefaults,
73
79
  }: FeatureCreateDrawerProps) {
80
+ const defaultGates = workflowDefaults?.approvalGates ?? EMPTY_GATES;
81
+ const defaultPush = workflowDefaults?.push ?? false;
82
+ const defaultOpenPr = workflowDefaults?.openPr ?? false;
83
+
74
84
  const [name, setName] = useState('');
75
85
  const [description, setDescription] = useState('');
76
86
  const [attachments, setAttachments] = useState<FileAttachment[]>([]);
77
- const [approvalGates, setApprovalGates] = useState<Record<string, boolean>>({ ...EMPTY_GATES });
87
+ const [approvalGates, setApprovalGates] = useState<Record<string, boolean>>({ ...defaultGates });
88
+ const [push, setPush] = useState(defaultPush);
89
+ const [openPr, setOpenPr] = useState(defaultOpenPr);
90
+
91
+ // Sync state when workflowDefaults load asynchronously
92
+ useEffect(() => {
93
+ if (workflowDefaults) {
94
+ setApprovalGates({ ...workflowDefaults.approvalGates });
95
+ setPush(workflowDefaults.push);
96
+ setOpenPr(workflowDefaults.openPr);
97
+ }
98
+ }, [workflowDefaults]);
78
99
 
79
100
  const resetForm = useCallback(() => {
80
101
  setName('');
81
102
  setDescription('');
82
103
  setAttachments([]);
83
- setApprovalGates({ ...EMPTY_GATES });
84
- }, []);
104
+ setApprovalGates({ ...defaultGates });
105
+ setPush(defaultPush);
106
+ setOpenPr(defaultOpenPr);
107
+ }, [defaultGates, defaultPush, defaultOpenPr]);
85
108
 
86
109
  const handleOpenChange = useCallback(
87
110
  (nextOpen: boolean) => {
@@ -108,9 +131,11 @@ export function FeatureCreateDrawer({
108
131
  allowPlan: approvalGates.allowPlan ?? false,
109
132
  allowMerge: approvalGates.allowMerge ?? false,
110
133
  },
134
+ push: push || openPr,
135
+ openPr,
111
136
  });
112
137
  },
113
- [name, description, attachments, approvalGates, repositoryPath, onSubmit]
138
+ [name, description, attachments, approvalGates, repositoryPath, onSubmit, push, openPr]
114
139
  );
115
140
 
116
141
  const handleAddFiles = useCallback(async () => {
@@ -211,6 +236,31 @@ export function FeatureCreateDrawer({
211
236
  />
212
237
  </div>
213
238
 
239
+ {/* Git options */}
240
+ <div className="flex flex-col gap-1.5">
241
+ <Label className="text-muted-foreground text-xs font-semibold tracking-wider">
242
+ GIT
243
+ </Label>
244
+ <div className="flex flex-col gap-2">
245
+ <CheckboxGroupItem
246
+ id="push"
247
+ label="Push"
248
+ description="Push branch to remote after implementation."
249
+ checked={push || openPr}
250
+ onCheckedChange={setPush}
251
+ disabled={openPr || isSubmitting}
252
+ />
253
+ <CheckboxGroupItem
254
+ id="open-pr"
255
+ label="Create PR"
256
+ description="Open a pull request after pushing."
257
+ checked={openPr}
258
+ onCheckedChange={setOpenPr}
259
+ disabled={isSubmitting}
260
+ />
261
+ </div>
262
+ </div>
263
+
214
264
  {/* Attachments */}
215
265
  <div className="flex flex-col gap-2">
216
266
  <div className="flex items-center justify-between">
@@ -106,6 +106,16 @@ const allStatesData: FeatureNodeData[] = [
106
106
  repositoryPath: '/home/user/my-repo',
107
107
  branch: 'feat/data-pipeline',
108
108
  },
109
+ {
110
+ name: 'Merge Review',
111
+ description: 'PR ready for merge approval',
112
+ featureId: '#bi3',
113
+ lifecycle: 'review' as FeatureLifecyclePhase,
114
+ state: 'action-required',
115
+ progress: 90,
116
+ repositoryPath: '/home/user/my-repo',
117
+ branch: 'feat/merge-review',
118
+ },
109
119
  {
110
120
  name: 'Payment Gateway',
111
121
  description: 'Stripe integration for subscriptions',
@@ -145,7 +155,7 @@ export const AllStates: Story = {
145
155
  render: () => (
146
156
  <div className="flex flex-wrap gap-6">
147
157
  {allStatesData.map((data) => (
148
- <FeatureNodeCanvas key={data.state} style={{ width: 500, height: 350 }} data={data} />
158
+ <FeatureNodeCanvas key={data.featureId} style={{ width: 500, height: 350 }} data={data} />
149
159
  ))}
150
160
  </div>
151
161
  ),
@@ -316,6 +326,18 @@ export const Creating: Story = {
316
326
  render: (args) => <FeatureNodeCanvas data={args} />,
317
327
  };
318
328
 
329
+ export const MergeReviewActionRequired: Story = {
330
+ args: {
331
+ name: 'Merge Review',
332
+ description: 'PR ready for merge approval',
333
+ featureId: '#bi3',
334
+ lifecycle: 'review',
335
+ state: 'action-required',
336
+ progress: 90,
337
+ },
338
+ render: (args) => <FeatureNodeCanvas data={args} />,
339
+ };
340
+
319
341
  export const ErrorWithMessage: Story = {
320
342
  args: {
321
343
  name: 'Email Service',
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { Handle, Position } from '@xyflow/react';
4
- import { Settings, Plus, FileText, Wrench, type LucideIcon } from 'lucide-react';
4
+ import { Settings, Plus, FileText, Wrench, GitMerge, type LucideIcon } from 'lucide-react';
5
5
  import { cn } from '@/lib/utils';
6
6
  import {
7
7
  featureNodeStateConfig,
@@ -21,6 +21,7 @@ function getBadgeIcon(data: FeatureNodeData): LucideIcon {
21
21
  if (data.state === 'action-required') {
22
22
  if (data.lifecycle === 'requirements') return FileText;
23
23
  if (data.lifecycle === 'implementation') return Wrench;
24
+ if (data.lifecycle === 'review') return GitMerge;
24
25
  }
25
26
  return config.icon;
26
27
  }
@@ -34,6 +35,9 @@ function getActionRequiredBadgeClasses(data: FeatureNodeData): {
34
35
  if (data.lifecycle === 'implementation') {
35
36
  return { badgeClass: 'text-indigo-700', badgeBgClass: 'bg-indigo-50' };
36
37
  }
38
+ if (data.lifecycle === 'review') {
39
+ return { badgeClass: 'text-emerald-700', badgeBgClass: 'bg-emerald-50' };
40
+ }
37
41
  return null; // requirements stays amber (default)
38
42
  }
39
43
 
@@ -51,6 +55,7 @@ function getBadgeText(data: FeatureNodeData): string {
51
55
  case 'action-required':
52
56
  if (data.lifecycle === 'requirements') return 'Review Product Requirements';
53
57
  if (data.lifecycle === 'implementation') return 'Review Technical Planning';
58
+ if (data.lifecycle === 'review') return 'Review Merge Request';
54
59
  return config.label;
55
60
  case 'error':
56
61
  return data.errorMessage ?? 'Something went wrong';
@@ -0,0 +1,7 @@
1
+ export { MergeReview } from './merge-review';
2
+ export { MergeReviewDrawer } from './merge-review-drawer';
3
+ export type {
4
+ MergeReviewProps,
5
+ MergeReviewDrawerProps,
6
+ MergeReviewData,
7
+ } from './merge-review-config';