@shepai/cli 1.75.0 → 1.76.0-pr237.a9ee7f9

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 (246) hide show
  1. package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts +1 -0
  2. package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/ports/output/services/spec-initializer.interface.d.ts +4 -1
  4. package/dist/packages/core/src/application/ports/output/services/spec-initializer.interface.d.ts.map +1 -1
  5. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  6. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +5 -2
  7. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +2 -0
  8. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
  9. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/fast-feature-agent-graph.d.ts +220 -0
  10. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/fast-feature-agent-graph.d.ts.map +1 -0
  11. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/fast-feature-agent-graph.js +66 -0
  12. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts +1 -0
  13. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts.map +1 -1
  14. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.js +3 -0
  15. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts +1 -0
  16. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
  17. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +10 -1
  18. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/lifecycle-context.d.ts.map +1 -1
  19. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/lifecycle-context.js +1 -0
  20. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.d.ts +21 -0
  21. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.d.ts.map +1 -0
  22. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/fast-implement.node.js +60 -0
  23. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/fast-implement.prompt.d.ts +25 -0
  24. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/fast-implement.prompt.d.ts.map +1 -0
  25. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/fast-implement.prompt.js +176 -0
  26. package/dist/packages/core/src/infrastructure/services/spec/spec-initializer.service.d.ts +1 -1
  27. package/dist/packages/core/src/infrastructure/services/spec/spec-initializer.service.d.ts.map +1 -1
  28. package/dist/packages/core/src/infrastructure/services/spec/spec-initializer.service.js +8 -3
  29. package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
  30. package/dist/src/presentation/cli/commands/feat/new.command.js +2 -0
  31. package/dist/src/presentation/web/app/actions/create-feature.d.ts +2 -0
  32. package/dist/src/presentation/web/app/actions/create-feature.d.ts.map +1 -1
  33. package/dist/src/presentation/web/app/actions/create-feature.js +3 -1
  34. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +2 -0
  35. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  36. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +5 -1
  37. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +18 -0
  38. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
  39. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +49 -0
  40. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  41. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +34 -5
  42. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +4 -1
  43. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  44. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +6 -3
  45. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts +5 -2
  46. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
  47. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +14 -5
  48. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.d.ts +3 -0
  49. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.d.ts.map +1 -1
  50. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.stories.js +85 -0
  51. package/dist/src/presentation/web/hooks/use-graph-state.d.ts +2 -0
  52. package/dist/src/presentation/web/hooks/use-graph-state.d.ts.map +1 -1
  53. package/dist/src/presentation/web/hooks/use-graph-state.js +4 -0
  54. package/dist/src/presentation/web/hooks/use-viewport-persistence.d.ts +12 -0
  55. package/dist/src/presentation/web/hooks/use-viewport-persistence.d.ts.map +1 -0
  56. package/dist/src/presentation/web/hooks/use-viewport-persistence.js +64 -0
  57. package/dist/tsconfig.build.tsbuildinfo +1 -1
  58. package/package.json +1 -1
  59. package/web/.next/BUILD_ID +1 -1
  60. package/web/.next/build-manifest.json +2 -2
  61. package/web/.next/cache/.previewinfo +1 -1
  62. package/web/.next/cache/.rscinfo +1 -1
  63. package/web/.next/cache/.tsbuildinfo +1 -1
  64. package/web/.next/cache/config.json +3 -3
  65. package/web/.next/fallback-build-manifest.json +2 -2
  66. package/web/.next/prerender-manifest.json +3 -3
  67. package/web/.next/required-server-files.js +1 -1
  68. package/web/.next/required-server-files.json +1 -1
  69. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +16 -16
  70. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  71. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  72. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +19 -19
  73. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  74. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  75. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
  76. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  77. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  78. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +16 -16
  79. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  80. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  81. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +19 -19
  82. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  83. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  84. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +14 -14
  85. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  86. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  87. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
  88. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  89. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  90. package/web/.next/server/app/_global-error.html +2 -2
  91. package/web/.next/server/app/_global-error.rsc +1 -1
  92. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  93. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  94. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  95. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  96. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  97. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  98. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  99. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  100. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  101. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  102. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  103. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  104. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  105. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  106. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  107. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  108. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  109. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js +1 -1
  110. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js.map +1 -1
  111. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js +1 -1
  112. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js.map +1 -1
  113. package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
  114. package/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js.map +1 -1
  115. package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  116. package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
  117. package/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js.map +1 -1
  118. package/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js +1 -1
  119. package/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js.map +1 -1
  120. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  121. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  122. package/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
  123. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  124. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  125. package/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js +1 -1
  126. package/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js.map +1 -1
  127. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
  128. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  129. package/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
  130. package/web/.next/server/chunks/ssr/_0e9d6bf7._.js.map +1 -1
  131. package/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
  132. package/web/.next/server/chunks/ssr/_61351ed3._.js.map +1 -1
  133. package/web/.next/server/chunks/ssr/{_fd351734._.js → _6367f121._.js} +3 -3
  134. package/web/.next/server/chunks/ssr/{_fd351734._.js.map → _6367f121._.js.map} +1 -1
  135. package/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
  136. package/web/.next/server/chunks/ssr/_8400c8bb._.js.map +1 -1
  137. package/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
  138. package/web/.next/server/chunks/ssr/_9f940437._.js.map +1 -1
  139. package/web/.next/server/chunks/ssr/src_presentation_web_163038ba._.js +2 -2
  140. package/web/.next/server/chunks/ssr/src_presentation_web_163038ba._.js.map +1 -1
  141. package/web/.next/server/chunks/ssr/src_presentation_web_30d7eeda._.js +1 -1
  142. package/web/.next/server/chunks/ssr/src_presentation_web_30d7eeda._.js.map +1 -1
  143. package/web/.next/server/chunks/ssr/src_presentation_web_459cb687._.js +2 -2
  144. package/web/.next/server/chunks/ssr/src_presentation_web_459cb687._.js.map +1 -1
  145. package/web/.next/server/chunks/ssr/src_presentation_web_565a14f8._.js +1 -1
  146. package/web/.next/server/chunks/ssr/src_presentation_web_565a14f8._.js.map +1 -1
  147. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js +1 -1
  148. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js.map +1 -1
  149. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  150. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  151. package/web/.next/server/pages/500.html +2 -2
  152. package/web/.next/server/server-reference-manifest.js +1 -1
  153. package/web/.next/server/server-reference-manifest.json +22 -22
  154. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  155. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
  156. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  157. package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
  158. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +16 -16
  159. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  160. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  161. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +19 -19
  162. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  163. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  164. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
  165. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  166. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  167. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +16 -16
  168. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  169. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  170. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +19 -19
  171. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  172. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  173. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +14 -14
  174. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  175. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  176. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
  177. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  178. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  179. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  180. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  181. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  182. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  183. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  184. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  185. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  186. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  187. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  188. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  189. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -1
  190. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  191. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  192. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -1
  193. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  194. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  195. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  196. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  197. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js +1 -1
  198. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js +1 -1
  199. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__17a611f0._.js +2 -2
  200. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  201. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__45dbf93d._.js +2 -2
  202. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6258349c._.js +1 -1
  203. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  204. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6cbc1149._.js +2 -2
  205. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  206. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__94a6d275._.js +1 -1
  207. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
  208. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_0e9d6bf7._.js +1 -1
  209. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_61351ed3._.js +1 -1
  210. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{_fd351734._.js → _6367f121._.js} +3 -3
  211. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_8400c8bb._.js +1 -1
  212. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_9f940437._.js +1 -1
  213. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_163038ba._.js +2 -2
  214. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_30d7eeda._.js +1 -1
  215. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_459cb687._.js +2 -2
  216. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_565a14f8._.js +1 -1
  217. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js +1 -1
  218. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  219. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  220. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  221. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +22 -22
  222. package/web/.next/standalone/src/presentation/web/app/actions/create-feature.ts +6 -1
  223. package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.tsx +57 -0
  224. package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx +21 -0
  225. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +50 -5
  226. package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +9 -4
  227. package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.stories.tsx +97 -0
  228. package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.tsx +32 -6
  229. package/web/.next/standalone/src/presentation/web/hooks/use-graph-state.ts +7 -0
  230. package/web/.next/standalone/src/presentation/web/hooks/use-viewport-persistence.ts +81 -0
  231. package/web/.next/standalone/src/presentation/web/server.js +1 -1
  232. package/web/.next/static/chunks/{7fc4ef147139e5d7.js → 072774c2765044bf.js} +1 -1
  233. package/web/.next/static/chunks/20125fd939c3ce89.js +1 -0
  234. package/web/.next/static/chunks/{09e8bde4c8c36032.js → 2941126385a2f3a8.js} +1 -1
  235. package/web/.next/static/chunks/{25c39fb56c1fb992.js → 348466ecc88d14c7.js} +1 -1
  236. package/web/.next/static/chunks/{d1c098005f96b0c2.js → 86086e9514b41925.js} +1 -1
  237. package/web/.next/static/chunks/{3ce5a1e5f4215598.js → e0c085f8d291f741.js} +2 -2
  238. package/web/.next/static/chunks/{409477e14c0251ad.js → e6ed236424ea54ee.js} +1 -1
  239. package/web/.next/static/chunks/{0351dfb1a2c04651.js → f37c98117e470fdb.js} +1 -1
  240. package/web/.next/static/chunks/{c98e709ebd484e56.js → fdc9568beabb0879.js} +1 -1
  241. package/web/.next/trace +1 -1
  242. package/web/.next/trace-build +1 -1
  243. package/web/.next/static/chunks/2a37d25332b5648b.js +0 -1
  244. /package/web/.next/static/{noYkP21cohTYVGvhHBqjY → Cl7-XnSRYD_VFoHQXNe9y}/_buildManifest.js +0 -0
  245. /package/web/.next/static/{noYkP21cohTYVGvhHBqjY → Cl7-XnSRYD_VFoHQXNe9y}/_clientMiddlewareManifest.json +0 -0
  246. /package/web/.next/static/{noYkP21cohTYVGvhHBqjY → Cl7-XnSRYD_VFoHQXNe9y}/_ssgManifest.js +0 -0
@@ -49,6 +49,8 @@ export interface FeatureCreatePayload {
49
49
  push: boolean;
50
50
  openPr: boolean;
51
51
  parentId?: string;
52
+ /** When true, skip SDLC phases and implement directly from the prompt. */
53
+ fast: boolean;
52
54
  }
53
55
 
54
56
  const AUTO_APPROVE_OPTIONS = [
@@ -97,6 +99,7 @@ export function FeatureCreateDrawer({
97
99
  const [push, setPush] = useState(defaultPush);
98
100
  const [openPr, setOpenPr] = useState(defaultOpenPr);
99
101
  const [parentId, setParentId] = useState<string | undefined>(undefined);
102
+ const [fast, setFast] = useState(false);
100
103
 
101
104
  // Sync state when workflowDefaults load asynchronously
102
105
  useEffect(() => {
@@ -121,6 +124,7 @@ export function FeatureCreateDrawer({
121
124
  setPush(defaultPush);
122
125
  setOpenPr(defaultOpenPr);
123
126
  setParentId(undefined);
127
+ setFast(false);
124
128
  }, [defaultGates, defaultPush, defaultOpenPr]);
125
129
 
126
130
  // Track whether the form has unsaved data
@@ -145,6 +149,7 @@ export function FeatureCreateDrawer({
145
149
  },
146
150
  push: push || openPr,
147
151
  openPr,
152
+ fast,
148
153
  ...(parentId ? { parentId } : {}),
149
154
  });
150
155
  resetForm();
@@ -157,6 +162,7 @@ export function FeatureCreateDrawer({
157
162
  onSubmit,
158
163
  push,
159
164
  openPr,
165
+ fast,
160
166
  parentId,
161
167
  createSound,
162
168
  resetForm,
@@ -258,6 +264,21 @@ export function FeatureCreateDrawer({
258
264
  </div>
259
265
  ) : null}
260
266
 
267
+ {/* Fast mode toggle */}
268
+ <div className="flex flex-col gap-1.5">
269
+ <Label className="text-muted-foreground text-xs font-semibold tracking-wider">
270
+ MODE
271
+ </Label>
272
+ <CheckboxGroupItem
273
+ id="fast-mode"
274
+ label="Fast Mode"
275
+ description="Skip SDLC phases and implement directly from your prompt."
276
+ checked={fast}
277
+ onCheckedChange={setFast}
278
+ disabled={isSubmitting}
279
+ />
280
+ </div>
281
+
261
282
  {/* Auto-approve checkboxes */}
262
283
  <div className="flex flex-col gap-1.5">
263
284
  <Label className="text-muted-foreground text-xs font-semibold tracking-wider">
@@ -1,8 +1,9 @@
1
1
  'use client';
2
2
 
3
- import { useCallback, useEffect, useMemo } from 'react';
3
+ import { useCallback, useEffect, useMemo, useRef } from 'react';
4
4
  import { useRouter, usePathname } from 'next/navigation';
5
- import type { Edge } from '@xyflow/react';
5
+ import type { Edge, Viewport } from '@xyflow/react';
6
+ import { useReactFlow } from '@xyflow/react';
6
7
  import { FeaturesCanvas } from '@/components/features/features-canvas';
7
8
  import type { CanvasNodeType } from '@/components/features/features-canvas';
8
9
  import type { FeatureNodeData } from '@/components/common/feature-node';
@@ -14,9 +15,18 @@ import {
14
15
  import { useSelectedFeatureId } from '@/hooks/use-selected-feature-id';
15
16
  import { useSoundAction } from '@/hooks/use-sound-action';
16
17
  import { useDrawerCloseGuard } from '@/hooks/drawer-close-guard';
18
+ import { useViewportPersistence } from '@/hooks/use-viewport-persistence';
17
19
  import { ControlCenterEmptyState } from './control-center-empty-state';
18
20
  import { useControlCenterState } from './use-control-center-state';
19
21
 
22
+ const AUTO_FOCUS_OPTIONS = {
23
+ maxZoom: 1.0,
24
+ padding: 0.5,
25
+ duration: 500,
26
+ } as const;
27
+
28
+ const AUTO_FOCUS_DRAWER_DELAY_MS = 600;
29
+
20
30
  interface ControlCenterInnerProps {
21
31
  initialNodes: CanvasNodeType[];
22
32
  initialEdges: Edge[];
@@ -28,6 +38,14 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
28
38
  const selectedFeatureId = useSelectedFeatureId();
29
39
  const clickSound = useSoundAction('click');
30
40
  const { guardedNavigate } = useDrawerCloseGuard();
41
+ const { fitView } = useReactFlow();
42
+ const drawerTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
43
+
44
+ const {
45
+ defaultViewport,
46
+ onMoveEnd: handleViewportChange,
47
+ resetViewport,
48
+ } = useViewportPersistence();
31
49
 
32
50
  const {
33
51
  nodes,
@@ -157,11 +175,28 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
157
175
  useEffect(() => {
158
176
  const handler = (e: Event) => {
159
177
  const path = (e as CustomEvent<{ path: string }>).detail.path;
160
- handleAddRepository(path);
178
+ const { wasEmpty, repoPath } = handleAddRepository(path);
179
+
180
+ if (wasEmpty) {
181
+ // Wait for next render so the repo node exists in the DOM, then auto-focus
182
+ setTimeout(() => {
183
+ fitView(AUTO_FOCUS_OPTIONS);
184
+
185
+ // Open the create-feature drawer after the fitView animation completes
186
+ drawerTimerRef.current = setTimeout(() => {
187
+ guardedNavigate(() => router.push(`/create?repo=${encodeURIComponent(repoPath)}`));
188
+ }, AUTO_FOCUS_DRAWER_DELAY_MS);
189
+ }, 0);
190
+ }
161
191
  };
162
192
  window.addEventListener('shep:add-repository', handler);
163
- return () => window.removeEventListener('shep:add-repository', handler);
164
- }, [handleAddRepository]);
193
+ return () => {
194
+ window.removeEventListener('shep:add-repository', handler);
195
+ if (drawerTimerRef.current != null) {
196
+ clearTimeout(drawerTimerRef.current);
197
+ }
198
+ };
199
+ }, [handleAddRepository, fitView, guardedNavigate, router]);
165
200
 
166
201
  // Listen for create events from the create drawer (with real feature ID from server)
167
202
  useEffect(() => {
@@ -231,6 +266,13 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
231
266
  handleDeleteRepository,
232
267
  ]);
233
268
 
269
+ const handleMoveEnd = useCallback(
270
+ (_event: unknown, viewport: Viewport) => {
271
+ handleViewportChange(viewport);
272
+ },
273
+ [handleViewportChange]
274
+ );
275
+
234
276
  const hasRepositories = nodes.some((n) => n.type === 'repositoryNode');
235
277
 
236
278
  if (!hasRepositories) {
@@ -242,11 +284,14 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
242
284
  nodes={nodes}
243
285
  edges={edges}
244
286
  selectedFeatureId={selectedFeatureId}
287
+ defaultViewport={defaultViewport}
245
288
  onNodesChange={onNodesChange}
246
289
  onConnect={handleConnect}
247
290
  onAddFeature={handleAddFeature}
248
291
  onNodeClick={handleNodeClick}
249
292
  onPaneClick={handleClearDrawers}
293
+ onMoveEnd={handleMoveEnd}
294
+ onResetViewport={resetViewport}
250
295
  emptyState={<ControlCenterEmptyState onRepositorySelect={handleAddRepository} />}
251
296
  />
252
297
  );
@@ -36,7 +36,7 @@ export interface ControlCenterState {
36
36
  edges: Edge[];
37
37
  onNodesChange: (changes: NodeChange<CanvasNodeType>[]) => void;
38
38
  handleConnect: (connection: Connection) => void;
39
- handleAddRepository: (path: string) => void;
39
+ handleAddRepository: (path: string) => { wasEmpty: boolean; repoPath: string };
40
40
  handleLayout: (direction: LayoutDirection) => void;
41
41
  handleDeleteFeature: (featureId: string) => void;
42
42
  handleDeleteRepository: (repositoryId: string) => Promise<void>;
@@ -57,6 +57,7 @@ export interface ControlCenterState {
57
57
  const METADATA_UPDATED_MESSAGE = 'Feature metadata updated';
58
58
 
59
59
  let nextFeatureId = 0;
60
+ let nextRepoTempId = 0;
60
61
 
61
62
  export function useControlCenterState(
62
63
  initialNodes: CanvasNodeType[],
@@ -79,6 +80,7 @@ export function useControlCenterState(
79
80
  replaceRepository,
80
81
  getFeatureRepositoryPath,
81
82
  getRepositoryData,
83
+ getRepoMapSize,
82
84
  setCallbacks,
83
85
  } = useGraphState(initialNodes, initialEdges);
84
86
 
@@ -384,8 +386,9 @@ export function useControlCenterState(
384
386
  );
385
387
 
386
388
  const handleAddRepository = useCallback(
387
- (path: string) => {
388
- const tempId = `repo-temp-${Date.now()}`;
389
+ (path: string): { wasEmpty: boolean; repoPath: string } => {
390
+ const wasEmpty = getRepoMapSize() === 0;
391
+ const tempId = `repo-temp-${++nextRepoTempId}`;
389
392
  const repoName =
390
393
  path
391
394
  .replace(/[\\/]+$/, '')
@@ -414,8 +417,10 @@ export function useControlCenterState(
414
417
  removeRepository(tempId);
415
418
  toast.error('Failed to add repository');
416
419
  });
420
+
421
+ return { wasEmpty, repoPath: path };
417
422
  },
418
- [addRepositoryToMap, removeRepository, replaceRepository, createSound]
423
+ [addRepositoryToMap, removeRepository, replaceRepository, createSound, getRepoMapSize]
419
424
  );
420
425
 
421
426
  return {
@@ -5,6 +5,7 @@ import type { CanvasNodeType } from './features-canvas';
5
5
  import type { FeatureNodeType } from '@/components/common/feature-node';
6
6
  import type { RepositoryNodeType } from '@/components/common/repository-node';
7
7
  import { layoutWithDagre } from '@/lib/layout-with-dagre';
8
+ import { DEFAULT_VIEWPORT } from '@/hooks/use-viewport-persistence';
8
9
 
9
10
  const meta: Meta<typeof FeaturesCanvas> = {
10
11
  title: 'Features/FeaturesCanvas',
@@ -560,3 +561,99 @@ export const InteractiveWithRepository: Story = {
560
561
  onAddFeature: () => undefined,
561
562
  },
562
563
  };
564
+
565
+ // --- Viewport Persistence Stories ---
566
+
567
+ export const WithSavedViewport: Story = {
568
+ args: {
569
+ nodes: repoFeatureNodes,
570
+ edges: repoFeatureEdges,
571
+ defaultViewport: { x: 200, y: 150, zoom: 1.0 },
572
+ onResetViewport: () => DEFAULT_VIEWPORT,
573
+ },
574
+ };
575
+
576
+ export const ZoomedOutViewport: Story = {
577
+ args: {
578
+ nodes: mixedLayoutedNodes,
579
+ edges: mixedLayoutedEdges,
580
+ defaultViewport: { x: 0, y: 0, zoom: 0.5 },
581
+ onResetViewport: () => DEFAULT_VIEWPORT,
582
+ },
583
+ };
584
+
585
+ // --- Fast-mode feature scenario ---
586
+
587
+ const fastModeNodesRaw: CanvasNodeType[] = [
588
+ {
589
+ id: 'repo-1',
590
+ type: 'repositoryNode',
591
+ position: { x: 0, y: 0 },
592
+ data: { name: 'shep-ai/cli' },
593
+ },
594
+ {
595
+ id: 'feat-fast-1',
596
+ type: 'featureNode',
597
+ position: { x: 0, y: 0 },
598
+ data: {
599
+ name: 'Quick Bug Fix',
600
+ description: 'Fast-mode feature — skips SDLC, starts at implementation',
601
+ featureId: '#ff1',
602
+ lifecycle: 'implementation',
603
+ state: 'running',
604
+ progress: 30,
605
+ repositoryPath: '/home/user/my-repo',
606
+ branch: 'feat/quick-bug-fix',
607
+ },
608
+ },
609
+ {
610
+ id: 'feat-full-1',
611
+ type: 'featureNode',
612
+ position: { x: 0, y: 0 },
613
+ data: {
614
+ name: 'Auth Module',
615
+ description: 'Full-pipeline feature — goes through all SDLC phases',
616
+ featureId: '#ff2',
617
+ lifecycle: 'requirements',
618
+ state: 'running',
619
+ progress: 15,
620
+ repositoryPath: '/home/user/my-repo',
621
+ branch: 'feat/auth-module',
622
+ },
623
+ },
624
+ {
625
+ id: 'feat-fast-2',
626
+ type: 'featureNode',
627
+ position: { x: 0, y: 0 },
628
+ data: {
629
+ name: 'Update README',
630
+ description: 'Fast-mode feature — already done',
631
+ featureId: '#ff3',
632
+ lifecycle: 'deploy',
633
+ state: 'done',
634
+ progress: 100,
635
+ repositoryPath: '/home/user/my-repo',
636
+ branch: 'feat/update-readme',
637
+ },
638
+ },
639
+ ];
640
+
641
+ const fastModeEdges: Edge[] = [
642
+ { id: 'e-r1-ff1', source: 'repo-1', target: 'feat-fast-1', ...dashedEdge },
643
+ { id: 'e-r1-ff2', source: 'repo-1', target: 'feat-full-1', ...dashedEdge },
644
+ { id: 'e-r1-ff3', source: 'repo-1', target: 'feat-fast-2', ...dashedEdge },
645
+ ];
646
+
647
+ const { nodes: fastModeLayoutedNodes, edges: fastModeLayoutedEdges } = layoutWithDagre(
648
+ fastModeNodesRaw,
649
+ fastModeEdges,
650
+ { direction: 'LR' }
651
+ );
652
+
653
+ export const FastModeFeatures: Story = {
654
+ name: 'Fast Mode Features (Mixed Pipeline)',
655
+ args: {
656
+ nodes: fastModeLayoutedNodes,
657
+ edges: fastModeLayoutedEdges,
658
+ },
659
+ };
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
 
3
- import { useMemo } from 'react';
4
- import { ReactFlow, Background, Controls } from '@xyflow/react';
5
- import type { Connection, Edge, NodeChange } from '@xyflow/react';
6
- import { Plus } from 'lucide-react';
3
+ import { useCallback, useMemo } from 'react';
4
+ import { ReactFlow, Background, Controls, ControlButton, useReactFlow } from '@xyflow/react';
5
+ import type { Connection, Edge, NodeChange, OnMoveEnd, Viewport } from '@xyflow/react';
6
+ import { Plus, RotateCcw } from 'lucide-react';
7
7
  import { Button } from '@/components/ui/button';
8
8
  import { EmptyState } from '@/components/common/empty-state';
9
9
  import { FeatureNode } from '@/components/common/feature-node';
@@ -18,26 +18,49 @@ export interface FeaturesCanvasProps {
18
18
  nodes: CanvasNodeType[];
19
19
  edges: Edge[];
20
20
  selectedFeatureId?: string | null;
21
+ defaultViewport?: Viewport;
21
22
  onNodesChange?: (changes: NodeChange<CanvasNodeType>[]) => void;
22
23
  onAddFeature?: () => void;
23
24
  onNodeClick?: (event: React.MouseEvent, node: CanvasNodeType) => void;
24
25
  onPaneClick?: (event: React.MouseEvent) => void;
25
26
  onConnect?: (connection: Connection) => void;
26
27
  onCanvasDrag?: () => void;
28
+ onMoveEnd?: OnMoveEnd;
29
+ onResetViewport?: () => Viewport;
27
30
  toolbar?: React.ReactNode;
28
31
  emptyState?: React.ReactNode;
29
32
  }
30
33
 
34
+ const FALLBACK_VIEWPORT: Viewport = { x: 30, y: 30, zoom: 0.85 };
35
+
36
+ function ResetButton({ onResetViewport }: { onResetViewport: () => Viewport }) {
37
+ const { setViewport } = useReactFlow();
38
+
39
+ const handleReset = useCallback(() => {
40
+ const viewport = onResetViewport();
41
+ setViewport(viewport, { duration: 400 });
42
+ }, [onResetViewport, setViewport]);
43
+
44
+ return (
45
+ <ControlButton onClick={handleReset} title="Reset view" aria-label="Reset view">
46
+ <RotateCcw style={{ fill: 'none' }} />
47
+ </ControlButton>
48
+ );
49
+ }
50
+
31
51
  export function FeaturesCanvas({
32
52
  nodes,
33
53
  edges,
34
54
  selectedFeatureId,
55
+ defaultViewport,
35
56
  onNodesChange,
36
57
  onAddFeature,
37
58
  onConnect,
38
59
  onNodeClick,
39
60
  onPaneClick,
40
61
  onCanvasDrag,
62
+ onMoveEnd,
63
+ onResetViewport,
41
64
  toolbar,
42
65
  emptyState,
43
66
  }: FeaturesCanvasProps) {
@@ -111,14 +134,17 @@ export function FeaturesCanvas({
111
134
  onNodeClick={onNodeClick}
112
135
  onPaneClick={onPaneClick}
113
136
  onMoveStart={onCanvasDrag}
114
- defaultViewport={{ x: 30, y: 30, zoom: 0.85 }}
137
+ onMoveEnd={onMoveEnd}
138
+ defaultViewport={defaultViewport ?? FALLBACK_VIEWPORT}
115
139
  nodesDraggable={false}
116
140
  nodesConnectable={false}
117
141
  elementsSelectable={false}
118
142
  proOptions={{ hideAttribution: true }}
119
143
  >
120
144
  <Background />
121
- <Controls />
145
+ <Controls showInteractive={false}>
146
+ {onResetViewport ? <ResetButton onResetViewport={onResetViewport} /> : null}
147
+ </Controls>
122
148
  {toolbar}
123
149
  </ReactFlow>
124
150
  </div>
@@ -45,6 +45,8 @@ export interface UseGraphStateReturn {
45
45
  getFeatureRepositoryPath: (featureNodeId: string) => string | undefined;
46
46
  /** Stable lookup: get repository node data by nodeId. */
47
47
  getRepositoryData: (nodeId: string) => RepositoryNodeData | undefined;
48
+ /** Stable lookup: get the current number of repositories in the domain Map. */
49
+ getRepoMapSize: () => number;
48
50
  /** Update callbacks injected into node data (does NOT trigger re-render). */
49
51
  setCallbacks: (callbacks: GraphCallbacks) => void;
50
52
  }
@@ -353,6 +355,10 @@ export function useGraphState(
353
355
  return repoMapRef.current.get(nodeId)?.data;
354
356
  }, []);
355
357
 
358
+ const getRepoMapSize = useCallback((): number => {
359
+ return repoMapRef.current.size;
360
+ }, []);
361
+
356
362
  const setCallbacks = useCallback((callbacks: GraphCallbacks) => {
357
363
  callbacksRef.current = callbacks;
358
364
  }, []);
@@ -371,6 +377,7 @@ export function useGraphState(
371
377
  replaceRepository,
372
378
  getFeatureRepositoryPath,
373
379
  getRepositoryData,
380
+ getRepoMapSize,
374
381
  setCallbacks,
375
382
  };
376
383
  }
@@ -0,0 +1,81 @@
1
+ 'use client';
2
+
3
+ import { useCallback, useEffect, useRef } from 'react';
4
+ import type { Viewport } from '@xyflow/react';
5
+
6
+ export type { Viewport } from '@xyflow/react';
7
+
8
+ export const STORAGE_KEY = 'shep-canvas-viewport';
9
+ export const DEBOUNCE_MS = 500;
10
+
11
+ export const DEFAULT_VIEWPORT: Viewport = { x: 30, y: 30, zoom: 0.85 };
12
+
13
+ export interface UseViewportPersistenceResult {
14
+ defaultViewport: Viewport;
15
+ onMoveEnd: (viewport: Viewport) => void;
16
+ resetViewport: () => Viewport;
17
+ }
18
+
19
+ function isValidViewport(value: unknown): value is Viewport {
20
+ if (value == null || typeof value !== 'object' || Array.isArray(value)) {
21
+ return false;
22
+ }
23
+ const v = value as Record<string, unknown>;
24
+ return (
25
+ typeof v.x === 'number' &&
26
+ typeof v.y === 'number' &&
27
+ typeof v.zoom === 'number' &&
28
+ Number.isFinite(v.x) &&
29
+ Number.isFinite(v.y) &&
30
+ Number.isFinite(v.zoom) &&
31
+ v.zoom > 0
32
+ );
33
+ }
34
+
35
+ function readViewport(): Viewport {
36
+ try {
37
+ const raw = localStorage.getItem(STORAGE_KEY);
38
+ if (raw == null) return DEFAULT_VIEWPORT;
39
+ const parsed: unknown = JSON.parse(raw);
40
+ return isValidViewport(parsed) ? parsed : DEFAULT_VIEWPORT;
41
+ } catch {
42
+ return DEFAULT_VIEWPORT;
43
+ }
44
+ }
45
+
46
+ export function useViewportPersistence(): UseViewportPersistenceResult {
47
+ const defaultViewport = useRef<Viewport>(readViewport()).current;
48
+ const timerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
49
+
50
+ useEffect(() => {
51
+ return () => {
52
+ if (timerRef.current != null) {
53
+ clearTimeout(timerRef.current);
54
+ }
55
+ };
56
+ }, []);
57
+
58
+ const onMoveEnd = useCallback((viewport: Viewport) => {
59
+ if (timerRef.current != null) {
60
+ clearTimeout(timerRef.current);
61
+ }
62
+ timerRef.current = setTimeout(() => {
63
+ try {
64
+ localStorage.setItem(STORAGE_KEY, JSON.stringify(viewport));
65
+ } catch {
66
+ // Silently ignore localStorage errors (quota exceeded, private browsing, etc.)
67
+ }
68
+ }, DEBOUNCE_MS);
69
+ }, []);
70
+
71
+ const resetViewport = useCallback((): Viewport => {
72
+ try {
73
+ localStorage.removeItem(STORAGE_KEY);
74
+ } catch {
75
+ // Silently ignore localStorage errors
76
+ }
77
+ return DEFAULT_VIEWPORT;
78
+ }, []);
79
+
80
+ return { defaultViewport, onMoveEnd, resetViewport };
81
+ }
@@ -15,7 +15,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
15
15
  const hostname = process.env.HOSTNAME || '0.0.0.0'
16
16
 
17
17
  let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
18
- const nextConfig = {"env":{"NEXT_PUBLIC_SHEP_VERSION":"1.74.0","NEXT_PUBLIC_SHEP_PACKAGE_NAME":"@shepai/cli","NEXT_PUBLIC_SHEP_DESCRIPTION":"Autonomous AI Native SDLC Platform - Automate the development cycle from idea to deploy"},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":true,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/cli/cli","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"dynamicOnHover":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":false,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":false,"lockDistDir":true,"isolatedDevBuild":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":false,"optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","turbopack":{"root":"/home/runner/work/cli/cli"},"serverExternalPackages":["tsyringe","reflect-metadata","better-sqlite3","node:os","node:child_process","node:fs"],"distDirRoot":".next"}
18
+ const nextConfig = {"env":{"NEXT_PUBLIC_SHEP_VERSION":"1.76.0","NEXT_PUBLIC_SHEP_PACKAGE_NAME":"@shepai/cli","NEXT_PUBLIC_SHEP_DESCRIPTION":"Autonomous AI Native SDLC Platform - Automate the development cycle from idea to deploy"},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":true,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/cli/cli","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"dynamicOnHover":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":false,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":false,"lockDistDir":true,"isolatedDevBuild":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":false,"optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","turbopack":{"root":"/home/runner/work/cli/cli"},"serverExternalPackages":["tsyringe","reflect-metadata","better-sqlite3","node:os","node:child_process","node:fs"],"distDirRoot":".next"}
19
19
 
20
20
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
21
21