@shepai/cli 1.46.0 → 1.48.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/apis/json-schema/ApprovalGateDefaults.yaml +26 -0
- package/apis/json-schema/Feature.yaml +3 -0
- package/apis/json-schema/Repository.yaml +16 -0
- package/apis/json-schema/Settings.yaml +5 -0
- package/apis/json-schema/WorkflowConfig.yaml +4 -20
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts +17 -0
- package/dist/packages/core/src/application/ports/output/services/git-pr-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts +11 -1
- package/dist/packages/core/src/application/ports/output/services/worktree-service.interface.d.ts.map +1 -1
- package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts +3 -1
- 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 +11 -4
- package/dist/packages/core/src/application/use-cases/features/get-plan-artifact.use-case.d.ts +19 -0
- package/dist/packages/core/src/application/use-cases/features/get-plan-artifact.use-case.d.ts.map +1 -0
- package/dist/packages/core/src/application/use-cases/features/get-plan-artifact.use-case.js +52 -0
- package/dist/packages/core/src/infrastructure/di/container.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/di/container.js +5 -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 +2 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts +2 -0
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/merge.node.js +10 -3
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/agents/feature-agent/nodes/prompts/merge-prompts.js +15 -7
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts +2 -0
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/git/git-pr.service.js +41 -0
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts +2 -1
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.d.ts.map +1 -1
- package/dist/packages/core/src/infrastructure/services/git/worktree.service.js +29 -4
- package/dist/src/presentation/cli/ui/messages.d.ts.map +1 -1
- package/dist/src/presentation/cli/ui/messages.js +1 -7
- package/dist/src/presentation/web/app/actions/create-feature.d.ts +2 -0
- package/dist/src/presentation/web/app/actions/create-feature.d.ts.map +1 -1
- package/dist/src/presentation/web/app/actions/create-feature.js +3 -1
- package/dist/src/presentation/web/app/actions/get-merge-review-data.d.ts +7 -0
- package/dist/src/presentation/web/app/actions/get-merge-review-data.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/get-merge-review-data.js +49 -0
- package/dist/src/presentation/web/app/actions/get-workflow-defaults.d.ts +11 -0
- package/dist/src/presentation/web/app/actions/get-workflow-defaults.d.ts.map +1 -0
- package/dist/src/presentation/web/app/actions/get-workflow-defaults.js +15 -0
- package/dist/src/presentation/web/app/page.d.ts.map +1 -1
- package/dist/src/presentation/web/app/page.js +1 -0
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +5 -1
- 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 +25 -7
- package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +17 -0
- 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 +54 -2
- 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 +8 -1
- 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 +22 -1
- package/dist/src/presentation/web/components/common/merge-review/index.d.ts +4 -0
- package/dist/src/presentation/web/components/common/merge-review/index.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/merge-review/index.js +2 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review-config.d.ts +75 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review-config.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review-config.js +1 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.d.ts +3 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review-drawer.js +7 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts +3 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review.js +36 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.d.ts +32 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.d.ts.map +1 -0
- package/dist/src/presentation/web/components/common/merge-review/merge-review.stories.js +165 -0
- 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 +66 -2
- package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center.stories.js +15 -0
- 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 +37 -15
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- 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.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/page/server-reference-manifest.json +52 -22
- package/web/.next/server/app/page.js +1 -1
- package/web/.next/server/app/page.js.nft.json +1 -1
- package/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +4 -4
- package/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__19d52794._.js +9 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__19d52794._.js.map +1 -0
- package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
- package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/_3ac3601c._.js → server/chunks/ssr/_1fafa9db._.js} +2 -2
- package/web/.next/server/chunks/ssr/_1fafa9db._.js.map +1 -0
- 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/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +53 -23
- package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +52 -22
- package/web/.next/standalone/src/presentation/web/.next/server/app/page.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__03a0dba7._.js +4 -4
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__19d52794._.js +9 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
- package/web/.next/{server/chunks/ssr/_3ac3601c._.js → standalone/src/presentation/web/.next/server/chunks/ssr/_1fafa9db._.js} +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_ed0934e5._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +53 -23
- package/web/.next/standalone/src/presentation/web/app/actions/create-feature.ts +5 -1
- package/web/.next/standalone/src/presentation/web/app/actions/get-merge-review-data.ts +64 -0
- package/web/.next/standalone/src/presentation/web/app/actions/get-workflow-defaults.ts +28 -0
- package/web/.next/standalone/src/presentation/web/app/page.tsx +1 -0
- package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.tsx +74 -1
- package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx +55 -5
- package/web/.next/standalone/src/presentation/web/components/common/feature-node/feature-node.stories.tsx +23 -1
- package/web/.next/standalone/src/presentation/web/components/common/feature-node/feature-node.tsx +6 -1
- package/web/.next/standalone/src/presentation/web/components/common/merge-review/index.ts +7 -0
- package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review-config.ts +81 -0
- package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review-drawer.tsx +34 -0
- package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review.stories.tsx +240 -0
- package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review.tsx +252 -0
- package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +96 -1
- package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center.stories.tsx +15 -0
- package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +47 -17
- package/web/.next/standalone/src/presentation/web/server.js +1 -1
- package/web/.next/static/chunks/{9f8e71029fb04681.js → 0da7a9860fa6ae05.js} +2 -2
- package/web/.next/static/chunks/22f30ce91a3c79c1.js +1 -0
- package/web/.next/static/chunks/66378a6c055c4e67.js +10 -0
- package/web/.next/static/chunks/8668962d3e682263.css +2 -0
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__4e8ca89c._.js +0 -9
- package/web/.next/server/chunks/ssr/[root-of-the-server]__4e8ca89c._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_3ac3601c._.js.map +0 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__4e8ca89c._.js +0 -9
- package/web/.next/static/chunks/83ff3b6bbee54bce.js +0 -1
- package/web/.next/static/chunks/b7b7abe79e05b229.css +0 -2
- package/web/.next/static/chunks/ecf44fa8a155c854.js +0 -10
- /package/web/.next/static/{nM-uXIiW9k_0Z_GM_4bI4 → 1kZFDMQ0i-Y8dy1KkHlzv}/_buildManifest.js +0 -0
- /package/web/.next/static/{nM-uXIiW9k_0Z_GM_4bI4 → 1kZFDMQ0i-Y8dy1KkHlzv}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{nM-uXIiW9k_0Z_GM_4bI4 → 1kZFDMQ0i-Y8dy1KkHlzv}/_ssgManifest.js +0 -0
|
@@ -6,13 +6,18 @@ import { toast } from 'sonner';
|
|
|
6
6
|
import { approveFeature } from '@/app/actions/approve-feature';
|
|
7
7
|
import { getFeatureArtifact } from '@/app/actions/get-feature-artifact';
|
|
8
8
|
import { getResearchArtifact } from '@/app/actions/get-research-artifact';
|
|
9
|
+
import { getWorkflowDefaults } from '@/app/actions/get-workflow-defaults';
|
|
10
|
+
import type { WorkflowDefaults } from '@/app/actions/get-workflow-defaults';
|
|
11
|
+
import { getMergeReviewData } from '@/app/actions/get-merge-review-data';
|
|
9
12
|
import type { TechDecisionsReviewData } from '@/components/common/tech-decisions-review';
|
|
13
|
+
import type { MergeReviewData } from '@/components/common/merge-review';
|
|
10
14
|
import { FeaturesCanvas } from '@/components/features/features-canvas';
|
|
11
15
|
import type { CanvasNodeType } from '@/components/features/features-canvas';
|
|
12
16
|
import { FeatureDrawer, FeatureCreateDrawer } from '@/components/common';
|
|
13
17
|
import { PrdQuestionnaireDrawer } from '@/components/common/prd-questionnaire';
|
|
14
18
|
import type { PrdQuestionnaireData } from '@/components/common/prd-questionnaire';
|
|
15
19
|
import { TechDecisionsDrawer } from '@/components/common/tech-decisions-review';
|
|
20
|
+
import { MergeReviewDrawer } from '@/components/common/merge-review';
|
|
16
21
|
import { NotificationPermissionBanner } from '@/components/common/notification-permission-banner';
|
|
17
22
|
import { ControlCenterEmptyState } from './control-center-empty-state';
|
|
18
23
|
import { useControlCenterState } from './use-control-center-state';
|
|
@@ -44,6 +49,16 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
|
|
|
44
49
|
closeCreateDrawer,
|
|
45
50
|
} = useControlCenterState(initialNodes, initialEdges);
|
|
46
51
|
|
|
52
|
+
// Workflow defaults for the create-feature drawer
|
|
53
|
+
const [workflowDefaults, setWorkflowDefaults] = useState<WorkflowDefaults | undefined>();
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
getWorkflowDefaults()
|
|
56
|
+
.then(setWorkflowDefaults)
|
|
57
|
+
.catch(() => {
|
|
58
|
+
// Settings unavailable — drawer falls back to all-false defaults
|
|
59
|
+
});
|
|
60
|
+
}, []);
|
|
61
|
+
|
|
47
62
|
// PRD questionnaire drawer state
|
|
48
63
|
const [prdSelections, setPrdSelections] = useState<Record<string, string>>({});
|
|
49
64
|
const [isPrdProcessing, setIsPrdProcessing] = useState(false);
|
|
@@ -54,12 +69,19 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
|
|
|
54
69
|
const [techDecisionsData, setTechDecisionsData] = useState<TechDecisionsReviewData | null>(null);
|
|
55
70
|
const [isLoadingTechDecisions, setIsLoadingTechDecisions] = useState(false);
|
|
56
71
|
|
|
72
|
+
// Merge review drawer state
|
|
73
|
+
const [mergeReviewData, setMergeReviewData] = useState<MergeReviewData | null>(null);
|
|
74
|
+
const [isLoadingMergeReview, setIsLoadingMergeReview] = useState(false);
|
|
75
|
+
|
|
57
76
|
const showPrdDrawer =
|
|
58
77
|
selectedNode?.lifecycle === 'requirements' && selectedNode?.state === 'action-required';
|
|
59
78
|
|
|
60
79
|
const showTechDecisionsDrawer =
|
|
61
80
|
selectedNode?.lifecycle === 'implementation' && selectedNode?.state === 'action-required';
|
|
62
81
|
|
|
82
|
+
const showMergeReviewDrawer =
|
|
83
|
+
selectedNode?.lifecycle === 'review' && selectedNode?.state === 'action-required';
|
|
84
|
+
|
|
63
85
|
const handlePrdSelect = useCallback((questionId: string, optionId: string) => {
|
|
64
86
|
setPrdSelections((prev) => ({ ...prev, [questionId]: optionId }));
|
|
65
87
|
}, []);
|
|
@@ -113,6 +135,28 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
|
|
|
113
135
|
clearSelection();
|
|
114
136
|
}, [selectedNode?.featureId, clearSelection]);
|
|
115
137
|
|
|
138
|
+
const handleMergeApprove = useCallback(async () => {
|
|
139
|
+
const featureId = selectedNode?.featureId;
|
|
140
|
+
if (!featureId) return;
|
|
141
|
+
|
|
142
|
+
const result = await approveFeature(featureId);
|
|
143
|
+
|
|
144
|
+
if (!result.approved) {
|
|
145
|
+
toast.error(result.error ?? 'Failed to approve merge');
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
toast.success('Merge approved — agent resuming');
|
|
150
|
+
clearSelection();
|
|
151
|
+
}, [selectedNode?.featureId, clearSelection]);
|
|
152
|
+
|
|
153
|
+
const handleMergeRefine = useCallback(async (_text: string) => {
|
|
154
|
+
setIsLoadingMergeReview(true);
|
|
155
|
+
// TODO: Call API to refine merge
|
|
156
|
+
await new Promise((resolve) => setTimeout(resolve, 1500));
|
|
157
|
+
setIsLoadingMergeReview(false);
|
|
158
|
+
}, []);
|
|
159
|
+
|
|
116
160
|
// Fetch questionnaire data and reset selections when a different feature is selected
|
|
117
161
|
const prdFeatureId = showPrdDrawer ? selectedNode?.featureId : null;
|
|
118
162
|
useEffect(() => {
|
|
@@ -185,6 +229,36 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
|
|
|
185
229
|
};
|
|
186
230
|
}, [techDecisionsFeatureId]);
|
|
187
231
|
|
|
232
|
+
// Fetch merge review data when a feature is in review + action-required
|
|
233
|
+
const mergeFeatureId = showMergeReviewDrawer ? selectedNode?.featureId : null;
|
|
234
|
+
useEffect(() => {
|
|
235
|
+
setMergeReviewData(null);
|
|
236
|
+
|
|
237
|
+
if (!mergeFeatureId) return;
|
|
238
|
+
|
|
239
|
+
let cancelled = false;
|
|
240
|
+
setIsLoadingMergeReview(true);
|
|
241
|
+
getMergeReviewData(mergeFeatureId)
|
|
242
|
+
.then((result) => {
|
|
243
|
+
if (cancelled) return;
|
|
244
|
+
if ('error' in result) {
|
|
245
|
+
toast.error(result.error);
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
setMergeReviewData(result);
|
|
249
|
+
})
|
|
250
|
+
.catch(() => {
|
|
251
|
+
if (!cancelled) toast.error('Failed to load merge review data');
|
|
252
|
+
})
|
|
253
|
+
.finally(() => {
|
|
254
|
+
if (!cancelled) setIsLoadingMergeReview(false);
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
return () => {
|
|
258
|
+
cancelled = true;
|
|
259
|
+
};
|
|
260
|
+
}, [mergeFeatureId]);
|
|
261
|
+
|
|
188
262
|
const hasRepositories = nodes.some((n) => n.type === 'repositoryNode');
|
|
189
263
|
|
|
190
264
|
// Listen for global "open create drawer" events from the sidebar
|
|
@@ -204,6 +278,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
|
|
|
204
278
|
onClose={closeCreateDrawer}
|
|
205
279
|
onSubmit={handleCreateFeatureSubmit}
|
|
206
280
|
repositoryPath={pendingRepositoryPath}
|
|
281
|
+
workflowDefaults={workflowDefaults}
|
|
207
282
|
/>
|
|
208
283
|
</>
|
|
209
284
|
);
|
|
@@ -227,7 +302,9 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
|
|
|
227
302
|
emptyState={<ControlCenterEmptyState onRepositorySelect={handleAddRepository} />}
|
|
228
303
|
/>
|
|
229
304
|
<FeatureDrawer
|
|
230
|
-
selectedNode={
|
|
305
|
+
selectedNode={
|
|
306
|
+
showPrdDrawer || showTechDecisionsDrawer || showMergeReviewDrawer ? null : selectedNode
|
|
307
|
+
}
|
|
231
308
|
onClose={clearSelection}
|
|
232
309
|
onDelete={handleDeleteFeature}
|
|
233
310
|
isDeleting={isDeleting}
|
|
@@ -269,11 +346,29 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
|
|
|
269
346
|
isProcessing={isLoadingTechDecisions}
|
|
270
347
|
/>
|
|
271
348
|
) : null}
|
|
349
|
+
{mergeReviewData ? (
|
|
350
|
+
<MergeReviewDrawer
|
|
351
|
+
open={showMergeReviewDrawer}
|
|
352
|
+
onClose={clearSelection}
|
|
353
|
+
featureName={selectedNode?.name ?? ''}
|
|
354
|
+
featureId={selectedNode?.featureId}
|
|
355
|
+
repositoryPath={selectedNode?.repositoryPath}
|
|
356
|
+
branch={selectedNode?.branch}
|
|
357
|
+
specPath={selectedNode?.specPath}
|
|
358
|
+
data={mergeReviewData}
|
|
359
|
+
onApprove={handleMergeApprove}
|
|
360
|
+
onRefine={handleMergeRefine}
|
|
361
|
+
onDelete={handleDeleteFeature}
|
|
362
|
+
isDeleting={isDeleting}
|
|
363
|
+
isProcessing={isLoadingMergeReview}
|
|
364
|
+
/>
|
|
365
|
+
) : null}
|
|
272
366
|
<FeatureCreateDrawer
|
|
273
367
|
open={isCreateDrawerOpen}
|
|
274
368
|
onClose={closeCreateDrawer}
|
|
275
369
|
onSubmit={handleCreateFeatureSubmit}
|
|
276
370
|
repositoryPath={pendingRepositoryPath}
|
|
371
|
+
workflowDefaults={workflowDefaults}
|
|
277
372
|
/>
|
|
278
373
|
</>
|
|
279
374
|
);
|
|
@@ -75,6 +75,21 @@ const featureNodes: FeatureNodeType[] = [
|
|
|
75
75
|
branch: 'feat/api-gateway',
|
|
76
76
|
},
|
|
77
77
|
},
|
|
78
|
+
{
|
|
79
|
+
id: 'feat-4',
|
|
80
|
+
type: 'featureNode',
|
|
81
|
+
position: { x: 800, y: 345 },
|
|
82
|
+
data: {
|
|
83
|
+
name: 'Merge Review',
|
|
84
|
+
description: 'PR ready for merge approval',
|
|
85
|
+
featureId: '#f4',
|
|
86
|
+
lifecycle: 'review',
|
|
87
|
+
state: 'action-required',
|
|
88
|
+
progress: 90,
|
|
89
|
+
repositoryPath: '/home/user/my-repo',
|
|
90
|
+
branch: 'feat/merge-review',
|
|
91
|
+
},
|
|
92
|
+
},
|
|
78
93
|
];
|
|
79
94
|
|
|
80
95
|
const repoNode: RepositoryNodeType = {
|
|
@@ -351,8 +351,19 @@ export function useControlCenterState(
|
|
|
351
351
|
}
|
|
352
352
|
|
|
353
353
|
setSelectedNode(null);
|
|
354
|
-
setNodes((
|
|
355
|
-
|
|
354
|
+
setNodes((currentNodes) => {
|
|
355
|
+
const remainingNodes = currentNodes.filter((n) => n.id !== featureId);
|
|
356
|
+
const remainingEdges = edges.filter(
|
|
357
|
+
(e) => e.source !== featureId && e.target !== featureId
|
|
358
|
+
);
|
|
359
|
+
const result = layoutWithDagre(remainingNodes, remainingEdges, {
|
|
360
|
+
direction: 'LR',
|
|
361
|
+
ranksep: 200,
|
|
362
|
+
nodesep: 60,
|
|
363
|
+
});
|
|
364
|
+
setEdges(result.edges);
|
|
365
|
+
return result.nodes;
|
|
366
|
+
});
|
|
356
367
|
toast.success('Feature deleted successfully');
|
|
357
368
|
router.refresh();
|
|
358
369
|
} catch {
|
|
@@ -361,7 +372,7 @@ export function useControlCenterState(
|
|
|
361
372
|
setIsDeleting(false);
|
|
362
373
|
}
|
|
363
374
|
},
|
|
364
|
-
[router]
|
|
375
|
+
[router, edges]
|
|
365
376
|
);
|
|
366
377
|
|
|
367
378
|
const handleDeleteRepository = useCallback(
|
|
@@ -430,23 +441,23 @@ export function useControlCenterState(
|
|
|
430
441
|
.pop() ?? path;
|
|
431
442
|
|
|
432
443
|
// Optimistic UI: add node immediately
|
|
444
|
+
let savedAddRepoY = 0;
|
|
433
445
|
setNodes((currentNodes) => {
|
|
434
446
|
const repoNodes = currentNodes.filter((n) => n.type === 'repositoryNode');
|
|
435
447
|
const addRepoNode = currentNodes.find((n) => n.type === 'addRepositoryNode');
|
|
436
448
|
|
|
437
|
-
//
|
|
449
|
+
// Save addRepoNode's original Y for rollback on error
|
|
450
|
+
if (addRepoNode) savedAddRepoY = addRepoNode.position.y;
|
|
451
|
+
|
|
452
|
+
// Place in the repo column, at the addRepoNode's current position
|
|
438
453
|
const repoX = repoNodes[0]?.position.x ?? addRepoNode?.position.x ?? 50;
|
|
439
454
|
const repoHeight = 50; // repositoryNode height
|
|
440
455
|
const gap = 15; // match dagre nodesep
|
|
441
456
|
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
? addRepoNode.position.y
|
|
447
|
-
: 0;
|
|
448
|
-
|
|
449
|
-
const position = { x: repoX, y: lastRepoBottomY + gap };
|
|
457
|
+
const position = {
|
|
458
|
+
x: repoX,
|
|
459
|
+
y: addRepoNode ? addRepoNode.position.y : 0,
|
|
460
|
+
};
|
|
450
461
|
|
|
451
462
|
const newNode = {
|
|
452
463
|
id: tempId,
|
|
@@ -455,8 +466,10 @@ export function useControlCenterState(
|
|
|
455
466
|
data: { name: repoName, repositoryPath: path, id: tempId },
|
|
456
467
|
} as CanvasNodeType;
|
|
457
468
|
|
|
458
|
-
//
|
|
459
|
-
const addRepoY =
|
|
469
|
+
// Shift addRepo button down by exactly one slot
|
|
470
|
+
const addRepoY = addRepoNode
|
|
471
|
+
? addRepoNode.position.y + repoHeight + gap
|
|
472
|
+
: position.y + repoHeight + gap;
|
|
460
473
|
|
|
461
474
|
return currentNodes
|
|
462
475
|
.map((n) =>
|
|
@@ -469,8 +482,16 @@ export function useControlCenterState(
|
|
|
469
482
|
addRepository({ path, name: repoName })
|
|
470
483
|
.then((result) => {
|
|
471
484
|
if (result.error) {
|
|
472
|
-
// Rollback optimistic node
|
|
473
|
-
setNodes((prev) =>
|
|
485
|
+
// Rollback optimistic node and restore addRepoNode position
|
|
486
|
+
setNodes((prev) =>
|
|
487
|
+
prev
|
|
488
|
+
.filter((n) => n.id !== tempId)
|
|
489
|
+
.map((n) =>
|
|
490
|
+
n.type === 'addRepositoryNode'
|
|
491
|
+
? { ...n, position: { ...n.position, y: savedAddRepoY } }
|
|
492
|
+
: n
|
|
493
|
+
)
|
|
494
|
+
);
|
|
474
495
|
toast.error(result.error);
|
|
475
496
|
return;
|
|
476
497
|
}
|
|
@@ -501,7 +522,16 @@ export function useControlCenterState(
|
|
|
501
522
|
router.refresh();
|
|
502
523
|
})
|
|
503
524
|
.catch(() => {
|
|
504
|
-
|
|
525
|
+
// Rollback optimistic node and restore addRepoNode position
|
|
526
|
+
setNodes((prev) =>
|
|
527
|
+
prev
|
|
528
|
+
.filter((n) => n.id !== tempId)
|
|
529
|
+
.map((n) =>
|
|
530
|
+
n.type === 'addRepositoryNode'
|
|
531
|
+
? { ...n, position: { ...n.position, y: savedAddRepoY } }
|
|
532
|
+
: n
|
|
533
|
+
)
|
|
534
|
+
);
|
|
505
535
|
toast.error('Failed to add repository');
|
|
506
536
|
});
|
|
507
537
|
},
|
|
@@ -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.
|
|
18
|
+
const nextConfig = {"env":{"NEXT_PUBLIC_SHEP_VERSION":"1.47.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"],"distDirRoot":".next"}
|
|
19
19
|
|
|
20
20
|
process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
|
|
21
21
|
|