@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.
- package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts +4 -0
- package/dist/packages/core/src/application/ports/output/agents/feature-agent-process.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts +165 -0
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -0
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.js +34 -0
- package/dist/packages/core/src/application/ports/output/services/index.d.ts +2 -0
- package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/index.js +1 -0
- package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +5 -0
- package/dist/packages/core/src/application/use-cases/features/create/types.d.ts +2 -0
- package/dist/packages/core/src/application/use-cases/features/create/types.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/resume-feature.use-case.js +3 -0
- package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts.map +1 -1
- package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +5 -0
- package/dist/packages/core/src/domain/generated/output.d.ts +70 -1
- package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
- package/dist/packages/core/src/domain/generated/output.js +15 -1
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +2 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts +10 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/feature.mapper.js +24 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +2 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +10 -0
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations.js +27 -0
- package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/repositories/sqlite-feature.repository.js +18 -2
- package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.js +7 -3
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.js +5 -0
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/common/executors/cursor-executor.service.js +4 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts +148 -3
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-graph.js +20 -5
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts +4 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-process.service.js +12 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts +4 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +29 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts +27 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.js +146 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts +5 -2
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/node-helpers.js +9 -3
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/pr-yaml-generator.d.ts +17 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/pr-yaml-generator.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/pr-yaml-generator.js +43 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge.prompt.d.ts +17 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge.prompt.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge.prompt.js +42 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts +8 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/state.js +33 -0
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +28 -0
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -0
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +182 -0
- package/dist/src/presentation/cli/commands/feat/new.command.d.ts.map +1 -1
- package/dist/src/presentation/cli/commands/feat/new.command.js +33 -2
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +13 -2
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +4 -13
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +4 -10
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +7 -19
- package/dist/src/presentation/web/components/common/feature-create-drawer/index.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-create-drawer/index.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.stories.js +11 -0
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.js +10 -0
- package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.js +4 -2
- package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +1 -0
- package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +21 -0
- package/dist/src/presentation/web/components/common/index.d.ts +1 -1
- package/dist/src/presentation/web/components/common/index.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/index.js +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +2 -2
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +3 -3
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +76 -23
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +2 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -3
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/cache/.previewinfo +1 -1
- package/web/.next/cache/.rscinfo +1 -1
- package/web/.next/cache/.tsbuildinfo +1 -1
- package/web/.next/cache/config.json +3 -3
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +1 -1
- package/web/.next/required-server-files.json +1 -1
- package/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_not-found.html +2 -2
- package/web/.next/server/app/_not-found.rsc +10 -10
- package/web/.next/server/app/_not-found.segments/_full.segment.rsc +10 -10
- package/web/.next/server/app/_not-found.segments/_head.segment.rsc +3 -3
- package/web/.next/server/app/_not-found.segments/_index.segment.rsc +6 -6
- package/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
- package/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
- package/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version.html +2 -2
- package/web/.next/server/app/version.rsc +5 -5
- package/web/.next/server/app/version.segments/_full.segment.rsc +5 -5
- package/web/.next/server/app/version.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/version.segments/_index.segment.rsc +4 -4
- package/web/.next/server/app/version.segments/_tree.segment.rsc +2 -2
- package/web/.next/server/app/version.segments/version/__PAGE__.segment.rsc +2 -2
- package/web/.next/server/app/version.segments/version.segment.rsc +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_12059e3e.js +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_12059e3e.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__f12b60be._.js +1 -1
- package/web/.next/server/chunks/ssr/_09afa42a._.js +2 -7
- package/web/.next/server/chunks/ssr/_09afa42a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js.map +1 -1
- package/web/.next/server/pages/404.html +2 -2
- package/web/.next/server/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +1 -1
- package/web/.next/static/chunks/{daacb9d30e4fc428.js → 48b2cea957bfe6ab.js} +2 -7
- package/web/.next/static/chunks/9993505b2a26c454.js +1 -0
- package/web/.next/static/chunks/{fd816afd85fd9a19.css → b98242e5ef2a1bd3.css} +1 -1
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/web/.next/static/chunks/b32b17f102226f32.js +0 -1
- /package/web/.next/static/{C_QsuOPQWDrYc18EOtMAm → 9kF5HqLN2Pcx3uc1dCFjr}/_buildManifest.js +0 -0
- /package/web/.next/static/{C_QsuOPQWDrYc18EOtMAm → 9kF5HqLN2Pcx3uc1dCFjr}/_clientMiddlewareManifest.json +0 -0
- /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,
|
|
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';
|
package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map
CHANGED
|
@@ -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,
|
|
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"}
|
package/dist/src/presentation/web/components/features/control-center/control-center-inner.js
CHANGED
|
@@ -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,
|
|
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
|
|
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
|
}
|
package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts
CHANGED
|
@@ -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 {
|
|
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:
|
|
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,
|
|
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"}
|
package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js
CHANGED
|
@@ -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(
|
|
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
|
-
|
|
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(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|
package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map
CHANGED
|
@@ -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,
|
|
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
|
}),
|