@shepai/cli 1.30.0 → 1.32.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 (154) hide show
  1. package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts +4 -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/git-pr-service.interface.d.ts +165 -0
  4. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -0
  5. package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.js +34 -0
  6. package/dist/packages/core/src/application/ports/output/services/index.d.ts +2 -0
  7. package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
  8. package/dist/packages/core/src/application/ports/output/services/index.js +1 -0
  9. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  10. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +5 -0
  11. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +2 -0
  12. package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
  13. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.d.ts.map +1 -1
  14. package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.js +3 -0
  15. package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts.map +1 -1
  16. package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +5 -0
  17. package/dist/packages/core/src/domain/generated/output.d.ts +70 -1
  18. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  19. package/dist/packages/core/src/domain/generated/output.js +15 -1
  20. package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
  21. package/dist/packages/core/src/infrastructure/di/container.js +2 -0
  22. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts +10 -0
  23. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts.map +1 -1
  24. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.js +24 -0
  25. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +2 -0
  26. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
  27. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +10 -0
  28. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts.map +1 -1
  29. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.js +27 -0
  30. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.d.ts.map +1 -1
  31. package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +18 -2
  32. package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.d.ts.map +1 -1
  33. package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.js +7 -3
  34. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts.map +1 -1
  35. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.js +5 -0
  36. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts.map +1 -1
  37. package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.js +4 -0
  38. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts +148 -3
  39. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts.map +1 -1
  40. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.js +20 -5
  41. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts +4 -0
  42. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts.map +1 -1
  43. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.js +12 -0
  44. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts +4 -0
  45. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
  46. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +29 -1
  47. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts +27 -0
  48. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts.map +1 -0
  49. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.js +146 -0
  50. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts +5 -2
  51. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts.map +1 -1
  52. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +9 -3
  53. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/pr-yaml-generator.d.ts +17 -0
  54. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/pr-yaml-generator.d.ts.map +1 -0
  55. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/pr-yaml-generator.js +43 -0
  56. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge.prompt.d.ts +17 -0
  57. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge.prompt.d.ts.map +1 -0
  58. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge.prompt.js +42 -0
  59. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts +8 -0
  60. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts.map +1 -1
  61. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.js +33 -0
  62. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +28 -0
  63. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -0
  64. package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +182 -0
  65. package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
  66. package/dist/src/presentation/cli/commands/feat/new.command.js +33 -2
  67. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +13 -2
  68. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  69. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +4 -13
  70. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +4 -10
  71. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
  72. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +7 -19
  73. package/dist/src/presentation/web/components/common/feature-create-drawer/index.d.ts +1 -1
  74. package/dist/src/presentation/web/components/common/feature-create-drawer/index.d.ts.map +1 -1
  75. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.d.ts.map +1 -1
  76. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.js +11 -0
  77. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +1 -1
  78. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
  79. package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.js +10 -0
  80. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  81. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +4 -2
  82. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +1 -0
  83. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
  84. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +21 -0
  85. package/dist/src/presentation/web/components/common/index.d.ts +1 -1
  86. package/dist/src/presentation/web/components/common/index.d.ts.map +1 -1
  87. package/dist/src/presentation/web/components/common/index.js +1 -1
  88. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  89. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +2 -2
  90. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +3 -3
  91. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  92. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +76 -23
  93. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
  94. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +2 -1
  95. package/dist/tsconfig.build.tsbuildinfo +1 -1
  96. package/package.json +5 -3
  97. package/web/.next/BUILD_ID +1 -1
  98. package/web/.next/build-manifest.json +2 -2
  99. package/web/.next/cache/.previewinfo +1 -1
  100. package/web/.next/cache/.rscinfo +1 -1
  101. package/web/.next/cache/.tsbuildinfo +1 -1
  102. package/web/.next/cache/config.json +3 -3
  103. package/web/.next/fallback-build-manifest.json +2 -2
  104. package/web/.next/prerender-manifest.json +3 -3
  105. package/web/.next/required-server-files.js +1 -1
  106. package/web/.next/required-server-files.json +1 -1
  107. package/web/.next/server/app/_global-error.html +2 -2
  108. package/web/.next/server/app/_global-error.rsc +1 -1
  109. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  110. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  111. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  112. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  113. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  114. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  115. package/web/.next/server/app/_not-found.html +2 -2
  116. package/web/.next/server/app/_not-found.rsc +10 -10
  117. package/web/.next/server/app/_not-found.segments/_full.segment.rsc +10 -10
  118. package/web/.next/server/app/_not-found.segments/_head.segment.rsc +3 -3
  119. package/web/.next/server/app/_not-found.segments/_index.segment.rsc +6 -6
  120. package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  121. package/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  122. package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  123. package/web/.next/server/app/page_client-reference-manifest.js +1 -1
  124. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  125. package/web/.next/server/app/version.html +2 -2
  126. package/web/.next/server/app/version.rsc +5 -5
  127. package/web/.next/server/app/version.segments/_full.segment.rsc +5 -5
  128. package/web/.next/server/app/version.segments/_head.segment.rsc +1 -1
  129. package/web/.next/server/app/version.segments/_index.segment.rsc +4 -4
  130. package/web/.next/server/app/version.segments/_tree.segment.rsc +2 -2
  131. package/web/.next/server/app/version.segments/version/__PAGE__.segment.rsc +2 -2
  132. package/web/.next/server/app/version.segments/version.segment.rsc +1 -1
  133. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_12059e3e.js +1 -1
  134. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_12059e3e.js.map +1 -1
  135. package/web/.next/server/chunks/ssr/[root-of-the-server]__f12b60be._.js +1 -1
  136. package/web/.next/server/chunks/ssr/_09afa42a._.js +2 -7
  137. package/web/.next/server/chunks/ssr/_09afa42a._.js.map +1 -1
  138. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  139. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  140. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
  141. package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js.map +1 -1
  142. package/web/.next/server/pages/404.html +2 -2
  143. package/web/.next/server/pages/500.html +2 -2
  144. package/web/.next/server/server-reference-manifest.js +1 -1
  145. package/web/.next/server/server-reference-manifest.json +1 -1
  146. package/web/.next/static/chunks/{daacb9d30e4fc428.js → 48b2cea957bfe6ab.js} +2 -7
  147. package/web/.next/static/chunks/9993505b2a26c454.js +1 -0
  148. package/web/.next/static/chunks/{fd816afd85fd9a19.css → b98242e5ef2a1bd3.css} +1 -1
  149. package/web/.next/trace +1 -1
  150. package/web/.next/trace-build +1 -1
  151. package/web/.next/static/chunks/b32b17f102226f32.js +0 -1
  152. /package/web/.next/static/{C_QsuOPQWDrYc18EOtMAm → 9kF5HqLN2Pcx3uc1dCFjr}/_buildManifest.js +0 -0
  153. /package/web/.next/static/{C_QsuOPQWDrYc18EOtMAm → 9kF5HqLN2Pcx3uc1dCFjr}/_clientMiddlewareManifest.json +0 -0
  154. /package/web/.next/static/{C_QsuOPQWDrYc18EOtMAm → 9kF5HqLN2Pcx3uc1dCFjr}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/common/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAC7F,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EACL,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,WAAW,EACX,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,sBAAsB,GAC5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAC7F,OAAO,EAAE,kBAAkB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,KAAK,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/components/common/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,EACL,mBAAmB,EACnB,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,GAC1B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACjF,OAAO,EACL,iBAAiB,EACjB,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EACL,WAAW,EACX,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,sBAAsB,GAC5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAC7F,OAAO,EAAE,kBAAkB,EAAE,KAAK,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAC1F,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,GACxB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,KAAK,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AACnG,OAAO,EAAE,cAAc,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,OAAO,EAAE,oBAAoB,EAAE,KAAK,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
@@ -1,7 +1,7 @@
1
1
  export { AddRepositoryNode, } from './add-repository-node/index.js';
2
2
  export { ElapsedTime, formatElapsed } from './elapsed-time/index.js';
3
3
  export { EmptyState } from './empty-state/index.js';
4
- export { FeatureCreateDrawer } from './feature-create-drawer/index.js';
4
+ export { FeatureCreateDrawer, } from './feature-create-drawer/index.js';
5
5
  export { FeatureDrawer } from './feature-drawer/index.js';
6
6
  export { FeatureListItem } from './feature-list-item/index.js';
7
7
  export { useFeatureActions, } from './feature-drawer/use-feature-actions.js';
@@ -1 +1 @@
1
- {"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAK5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,2CA2DzF"}
1
+ {"version":3,"file":"control-center-inner.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center-inner.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAK5E,UAAU,uBAAuB;IAC/B,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;CACtB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,EAAE,uBAAuB,2CAyDzF"}
@@ -6,12 +6,12 @@ import { FeatureDrawer, FeatureCreateDrawer } from '../../common/index.js';
6
6
  import { ControlCenterEmptyState } from './control-center-empty-state.js';
7
7
  import { useControlCenterState } from './use-control-center-state.js';
8
8
  export function ControlCenterInner({ initialNodes, initialEdges }) {
9
- const { nodes, edges, selectedNode, isCreateDrawerOpen, isSubmitting, isDeleting, pendingRepositoryPath, onNodesChange, handleConnect, handleAddFeature, handleAddFeatureToRepo, handleAddFeatureToFeature, handleAddRepository, handleNodeClick, clearSelection, handleCreateFeatureSubmit, handleDeleteFeature, closeCreateDrawer, } = useControlCenterState(initialNodes, initialEdges);
9
+ const { nodes, edges, selectedNode, isCreateDrawerOpen, isDeleting, pendingRepositoryPath, onNodesChange, handleConnect, handleAddFeature, handleAddFeatureToRepo, handleAddFeatureToFeature, handleAddRepository, handleNodeClick, clearSelection, handleCreateFeatureSubmit, handleDeleteFeature, closeCreateDrawer, } = useControlCenterState(initialNodes, initialEdges);
10
10
  // Listen for global "open create drawer" events from the sidebar
11
11
  useEffect(() => {
12
12
  const handler = () => handleAddFeature();
13
13
  window.addEventListener('shep:open-create-drawer', handler);
14
14
  return () => window.removeEventListener('shep:open-create-drawer', handler);
15
15
  }, [handleAddFeature]);
16
- return (_jsxs(_Fragment, { children: [_jsx(FeaturesCanvas, { nodes: nodes, edges: edges, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeAction: handleAddFeatureToFeature, onNodeClick: handleNodeClick, onPaneClick: clearSelection, onRepositoryAdd: handleAddFeatureToRepo, onRepositorySelect: handleAddRepository, emptyState: _jsx(ControlCenterEmptyState, { onRepositorySelect: handleAddRepository }) }), _jsx(FeatureDrawer, { selectedNode: selectedNode, onClose: clearSelection, onDelete: handleDeleteFeature, isDeleting: isDeleting }), _jsx(FeatureCreateDrawer, { open: isCreateDrawerOpen, onClose: closeCreateDrawer, onSubmit: handleCreateFeatureSubmit, repositoryPath: pendingRepositoryPath, isSubmitting: isSubmitting })] }));
16
+ return (_jsxs(_Fragment, { children: [_jsx(FeaturesCanvas, { nodes: nodes, edges: edges, onNodesChange: onNodesChange, onConnect: handleConnect, onAddFeature: handleAddFeature, onNodeAction: handleAddFeatureToFeature, onNodeClick: handleNodeClick, onPaneClick: clearSelection, onRepositoryAdd: handleAddFeatureToRepo, onRepositorySelect: handleAddRepository, emptyState: _jsx(ControlCenterEmptyState, { onRepositorySelect: handleAddRepository }) }), _jsx(FeatureDrawer, { selectedNode: selectedNode, onClose: clearSelection, onDelete: handleDeleteFeature, isDeleting: isDeleting }), _jsx(FeatureCreateDrawer, { open: isCreateDrawerOpen, onClose: closeCreateDrawer, onSubmit: handleCreateFeatureSubmit, repositoryPath: pendingRepositoryPath })] }));
17
17
  }
@@ -1,6 +1,6 @@
1
1
  import type { Connection, Edge, NodeChange } from '@xyflow/react';
2
2
  import type { FeatureNodeData } from '../../common/feature-node/index.js';
3
- import type { CreateFeatureInput } from '../../../../../../packages/core/src/application/use-cases/features/create/types.js';
3
+ import type { FeatureCreatePayload } from '../../common/feature-create-drawer/index.js';
4
4
  import type { CanvasNodeType } from '../../features/features-canvas/index.js';
5
5
  import { type LayoutDirection } from '../../../lib/layout-with-dagre.js';
6
6
  export interface ControlCenterState {
@@ -8,7 +8,6 @@ export interface ControlCenterState {
8
8
  edges: Edge[];
9
9
  selectedNode: FeatureNodeData | null;
10
10
  isCreateDrawerOpen: boolean;
11
- isSubmitting: boolean;
12
11
  pendingRepositoryPath: string;
13
12
  onNodesChange: (changes: NodeChange<CanvasNodeType>[]) => void;
14
13
  handleConnect: (connection: Connection) => void;
@@ -19,10 +18,11 @@ export interface ControlCenterState {
19
18
  handleAddFeatureToFeature: (featureNodeId: string) => void;
20
19
  handleAddRepository: (path: string) => void;
21
20
  handleLayout: (direction: LayoutDirection) => void;
22
- handleCreateFeatureSubmit: (data: CreateFeatureInput) => void;
21
+ handleCreateFeatureSubmit: (data: FeatureCreatePayload) => void;
23
22
  closeCreateDrawer: () => void;
24
23
  handleDeleteFeature: (featureId: string) => Promise<void>;
25
24
  isDeleting: boolean;
25
+ createFeatureNode: (sourceNodeId: string | null, dataOverride?: Partial<FeatureNodeData>) => string;
26
26
  }
27
27
  export declare function useControlCenterState(initialNodes: CanvasNodeType[], initialEdges: Edge[]): ControlCenterState;
28
28
  //# sourceMappingURL=use-control-center-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0DAA0D,CAAC;AACnG,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEhF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,YAAY,EAAE,OAAO,CAAC;IACtB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,eAAe,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACzE,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,sBAAsB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,yBAAyB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,yBAAyB,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,IAAI,CAAC;IAC9D,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,UAAU,EAAE,OAAO,CAAC;CACrB;AAID,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CA2UpB"}
1
+ {"version":3,"file":"use-control-center-state.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/use-control-center-state.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAEhF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,YAAY,EAAE,eAAe,GAAG,IAAI,CAAC;IACrC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAC/D,aAAa,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAChD,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,eAAe,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACzE,gBAAgB,EAAE,MAAM,IAAI,CAAC;IAC7B,sBAAsB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IACrD,yBAAyB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,yBAAyB,EAAE,CAAC,IAAI,EAAE,oBAAoB,KAAK,IAAI,CAAC;IAChE,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,UAAU,EAAE,OAAO,CAAC;IACpB,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,KACpC,MAAM,CAAC;CACb;AAID,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CA6YpB"}
@@ -11,9 +11,46 @@ export function useControlCenterState(initialNodes, initialEdges) {
11
11
  const [edges, setEdges] = useState(initialEdges);
12
12
  const [selectedNode, setSelectedNode] = useState(null);
13
13
  const [isCreateDrawerOpen, setIsCreateDrawerOpen] = useState(false);
14
- const [isSubmitting, setIsSubmitting] = useState(false);
15
14
  const [isDeleting, setIsDeleting] = useState(false);
16
15
  const [pendingRepoNodeId, setPendingRepoNodeId] = useState(null);
16
+ // Sync server props into local state when router.refresh() delivers new data
17
+ const initialNodeKey = initialNodes
18
+ .map((n) => n.id)
19
+ .sort()
20
+ .join(',');
21
+ const initialEdgeKey = initialEdges
22
+ .map((e) => e.id)
23
+ .sort()
24
+ .join(',');
25
+ useEffect(() => {
26
+ setNodes((currentNodes) => {
27
+ // Build a lookup of current node positions by ID
28
+ const currentById = new Map(currentNodes.map((n) => [n.id, n]));
29
+ // Identify optimistic "creating" nodes (they have temp IDs not in server data)
30
+ const serverIds = new Set(initialNodes.map((n) => n.id));
31
+ const creatingNodes = currentNodes.filter((n) => n.type === 'featureNode' &&
32
+ n.data.state === 'creating' &&
33
+ !serverIds.has(n.id));
34
+ // Merge server nodes with client positions
35
+ return initialNodes.map((serverNode) => {
36
+ // Node already exists on canvas — keep its position, update data
37
+ const existing = currentById.get(serverNode.id);
38
+ if (existing) {
39
+ return { ...serverNode, position: existing.position };
40
+ }
41
+ // New server node — inherit position from an optimistic creating node if available
42
+ if (serverNode.type === 'featureNode' && creatingNodes.length > 0) {
43
+ const donor = creatingNodes.shift();
44
+ return { ...serverNode, position: donor.position };
45
+ }
46
+ // Truly new node with no optimistic counterpart — use server position
47
+ return serverNode;
48
+ });
49
+ });
50
+ }, [initialNodeKey]); // eslint-disable-line react-hooks/exhaustive-deps
51
+ useEffect(() => {
52
+ setEdges(initialEdges);
53
+ }, [initialEdgeKey]); // eslint-disable-line react-hooks/exhaustive-deps
17
54
  const onNodesChange = useCallback((changes) => {
18
55
  setNodes((ns) => applyNodeChanges(changes, ns));
19
56
  }, []);
@@ -22,8 +59,11 @@ export function useControlCenterState(initialNodes, initialEdges) {
22
59
  }, []);
23
60
  const handleNodeClick = useCallback((_event, node) => {
24
61
  if (node.type === 'featureNode') {
62
+ const data = node.data;
63
+ if (data.state === 'creating')
64
+ return;
25
65
  setIsCreateDrawerOpen(false);
26
- setSelectedNode(node.data);
66
+ setSelectedNode(data);
27
67
  }
28
68
  }, []);
29
69
  // Keyboard shortcut: Escape to deselect
@@ -71,7 +111,7 @@ export function useControlCenterState(initialNodes, initialEdges) {
71
111
  description: dataOverride?.description ?? 'Describe what this feature does',
72
112
  featureId: `#${id.slice(-4)}`,
73
113
  lifecycle: 'requirements',
74
- state: 'running',
114
+ state: dataOverride?.state ?? 'running',
75
115
  progress: 0,
76
116
  repositoryPath: dataOverride?.repositoryPath ?? '',
77
117
  branch: dataOverride?.branch ?? '',
@@ -163,37 +203,50 @@ export function useControlCenterState(initialNodes, initialEdges) {
163
203
  },
164
204
  ]);
165
205
  }
166
- setSelectedNode(newFeatureData);
206
+ if (newFeatureData.state !== 'creating') {
207
+ setSelectedNode(newFeatureData);
208
+ }
209
+ return id;
167
210
  }, [edges]);
168
211
  const handleAddFeature = useCallback(() => {
169
212
  setSelectedNode(null);
170
213
  setIsCreateDrawerOpen(true);
171
214
  }, []);
172
- const handleCreateFeatureSubmit = useCallback(async (data) => {
173
- setIsSubmitting(true);
174
- try {
175
- const response = await fetch('/api/features/create', {
176
- method: 'POST',
177
- headers: { 'Content-Type': 'application/json' },
178
- body: JSON.stringify(data),
179
- });
215
+ const handleCreateFeatureSubmit = useCallback((data) => {
216
+ // 1. Insert optimistic node instantly
217
+ const tempId = createFeatureNode(pendingRepoNodeId, {
218
+ state: 'creating',
219
+ name: data.name,
220
+ description: data.description,
221
+ repositoryPath: data.repositoryPath,
222
+ });
223
+ // 2. Close drawer and clear pending state immediately
224
+ setIsCreateDrawerOpen(false);
225
+ setPendingRepoNodeId(null);
226
+ // 3. Fire API call in the background
227
+ fetch('/api/features/create', {
228
+ method: 'POST',
229
+ headers: { 'Content-Type': 'application/json' },
230
+ body: JSON.stringify(data),
231
+ })
232
+ .then(async (response) => {
180
233
  if (!response.ok) {
181
234
  const body = await response.json();
235
+ // Rollback: remove optimistic node and edge
236
+ setNodes((prev) => prev.filter((n) => n.id !== tempId));
237
+ setEdges((prev) => prev.filter((e) => e.target !== tempId));
182
238
  toast.error(body.error ?? 'Failed to create feature');
183
239
  return;
184
240
  }
185
- setIsCreateDrawerOpen(false);
186
- setPendingRepoNodeId(null);
187
- toast.success('Feature created successfully');
188
241
  router.refresh();
189
- }
190
- catch {
242
+ })
243
+ .catch(() => {
244
+ // Rollback: remove optimistic node and edge
245
+ setNodes((prev) => prev.filter((n) => n.id !== tempId));
246
+ setEdges((prev) => prev.filter((e) => e.target !== tempId));
191
247
  toast.error('Failed to create feature');
192
- }
193
- finally {
194
- setIsSubmitting(false);
195
- }
196
- }, [router]);
248
+ });
249
+ }, [router, createFeatureNode, pendingRepoNodeId]);
197
250
  const closeCreateDrawer = useCallback(() => {
198
251
  setIsCreateDrawerOpen(false);
199
252
  }, []);
@@ -273,7 +326,6 @@ export function useControlCenterState(initialNodes, initialEdges) {
273
326
  edges,
274
327
  selectedNode,
275
328
  isCreateDrawerOpen,
276
- isSubmitting,
277
329
  pendingRepositoryPath,
278
330
  onNodesChange,
279
331
  handleConnect,
@@ -288,5 +340,6 @@ export function useControlCenterState(initialNodes, initialEdges) {
288
340
  closeCreateDrawer,
289
341
  handleDeleteFeature,
290
342
  isDeleting,
343
+ createFeatureNode,
291
344
  };
292
345
  }
@@ -1 +1 @@
1
- {"version":3,"file":"features-canvas.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAKlE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAExE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAE9E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAErF,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,kBAAkB,GAAG,qBAAqB,CAAC;AAE1F,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAChE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACtE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAChD,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,SAAS,EACT,WAAW,EACX,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,OAAO,EACP,UAAU,GACX,EAAE,mBAAmB,2CAgGrB"}
1
+ {"version":3,"file":"features-canvas.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/features-canvas/features-canvas.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAKlE,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,kCAAkC,CAAC;AAEzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAE9E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yCAAyC,CAAC;AAErF,MAAM,MAAM,cAAc,GAAG,eAAe,GAAG,kBAAkB,GAAG,qBAAqB,CAAC;AAE1F,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,cAAc,CAAC,EAAE,KAAK,IAAI,CAAC;IAChE,YAAY,CAAC,EAAE,MAAM,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,IAAI,EAAE,cAAc,KAAK,IAAI,CAAC;IACtE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAChD,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,UAAU,KAAK,IAAI,CAAC;IAC7C,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC9B;AAED,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,KAAK,EACL,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,SAAS,EACT,WAAW,EACX,WAAW,EACX,eAAe,EACf,kBAAkB,EAClB,OAAO,EACP,UAAU,GACX,EAAE,mBAAmB,2CAiGrB"}
@@ -30,7 +30,8 @@ export function FeaturesCanvas({ nodes, edges, onNodesChange, onAddFeature, onNo
30
30
  data: {
31
31
  ...node.data,
32
32
  showHandles: edges.length > 0,
33
- ...(node.type === 'featureNode' && {
33
+ ...(node.type === 'featureNode' &&
34
+ node.data.state !== 'creating' && {
34
35
  onAction: onNodeAction ? () => onNodeAction(node.id) : undefined,
35
36
  onSettings: onNodeSettings ? () => onNodeSettings(node.id) : undefined,
36
37
  }),