@shepai/cli 1.68.1 → 1.69.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/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts +2 -0
- package/dist/src/presentation/web/components/common/feature-node/feature-node-state-config.d.ts.map +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 +32 -0
- package/dist/src/presentation/web/components/layouts/app-shell/app-shell.d.ts.map +1 -1
- package/dist/src/presentation/web/components/layouts/app-shell/app-shell.js +7 -2
- package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts +3 -3
- package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
- package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +1 -1
- package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.stories.js +36 -11
- package/dist/src/presentation/web/hooks/sidebar-features-context.d.ts +26 -0
- package/dist/src/presentation/web/hooks/sidebar-features-context.d.ts.map +1 -0
- package/dist/src/presentation/web/hooks/sidebar-features-context.js +34 -0
- 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/server-reference-manifest.json +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 +18 -18
- 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/skills/page/server-reference-manifest.json +5 -5
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +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]__08ba9bd3._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e41b5eec._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e41b5eec._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_49bf495c._.js +1 -1
- package/web/.next/server/chunks/ssr/_49bf495c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_68b5e0de._.js +6 -0
- package/web/.next/server/chunks/ssr/_68b5e0de._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_725584e5._.js +1 -1
- package/web/.next/server/chunks/ssr/_725584e5._.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/pages/500.html +2 -2
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +19 -19
- 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/server-reference-manifest.json +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 +18 -18
- 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/skills/page/server-reference-manifest.json +5 -5
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +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]__08ba9bd3._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__551fb7e1._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__e41b5eec._.js +2 -2
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_49bf495c._.js +1 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_68b5e0de._.js +6 -0
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_725584e5._.js +1 -1
- 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/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 +19 -19
- package/web/.next/standalone/src/presentation/web/components/common/feature-node/feature-node-state-config.ts +2 -0
- package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +44 -0
- package/web/.next/standalone/src/presentation/web/components/layouts/app-shell/app-shell.tsx +18 -2
- package/web/.next/standalone/src/presentation/web/components/layouts/app-sidebar/app-sidebar.stories.tsx +36 -11
- package/web/.next/standalone/src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx +7 -4
- package/web/.next/standalone/src/presentation/web/hooks/sidebar-features-context.tsx +69 -0
- package/web/.next/standalone/src/presentation/web/server.js +1 -1
- package/web/.next/static/chunks/{ac9971b036d46eca.js → 2da52289a4a8f9e2.js} +1 -1
- package/web/.next/static/chunks/{caa2e7e1618e2179.js → 51c94a563ecc565d.js} +1 -1
- package/web/.next/static/chunks/5bc5d426870feb7e.js +1 -0
- package/web/.next/static/chunks/{babbd238fc276df2.js → 5ef9d8b7401f2f1f.js} +2 -2
- package/web/.next/static/chunks/{7b56cca1fa91c197.js → faf8ad4c823884d7.js} +1 -1
- package/web/.next/trace +1 -1
- package/web/.next/trace-build +1 -1
- package/web/.next/server/chunks/ssr/_23c92688._.js +0 -6
- package/web/.next/server/chunks/ssr/_23c92688._.js.map +0 -1
- package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_23c92688._.js +0 -6
- package/web/.next/static/chunks/eaf9699a447461e1.js +0 -1
- /package/web/.next/static/{VcKnu_EsfkBbSZnJoevS7 → 7ktIn83yR3rYLLF00uLSx}/_buildManifest.js +0 -0
- /package/web/.next/static/{VcKnu_EsfkBbSZnJoevS7 → 7ktIn83yR3rYLLF00uLSx}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{VcKnu_EsfkBbSZnJoevS7 → 7ktIn83yR3rYLLF00uLSx}/_ssgManifest.js +0 -0
package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"node": {
|
|
3
|
-
"
|
|
3
|
+
"0047c870d719162f2116e56b9cb492d37d546502e6": {
|
|
4
4
|
"workers": {
|
|
5
5
|
"app/_not-found/page": {
|
|
6
6
|
"moduleId": 66973,
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"filename": "src/presentation/web/app/actions/pick-folder.ts",
|
|
44
44
|
"exportedName": "pickFolder"
|
|
45
45
|
},
|
|
46
|
-
"
|
|
46
|
+
"40bbd46af81361e4188c140ffcb4ec4230c1f5ede1": {
|
|
47
47
|
"workers": {
|
|
48
48
|
"app/page": {
|
|
49
49
|
"moduleId": 80894,
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"filename": "src/presentation/web/app/actions/deploy-feature.ts",
|
|
66
66
|
"exportedName": "deployFeature"
|
|
67
67
|
},
|
|
68
|
-
"
|
|
68
|
+
"402d63b563a07e93686b59fb9cf228c2bff903df52": {
|
|
69
69
|
"workers": {
|
|
70
70
|
"app/page": {
|
|
71
71
|
"moduleId": 80894,
|
|
@@ -87,7 +87,7 @@
|
|
|
87
87
|
"filename": "src/presentation/web/app/actions/deploy-repository.ts",
|
|
88
88
|
"exportedName": "deployRepository"
|
|
89
89
|
},
|
|
90
|
-
"
|
|
90
|
+
"40d0994666333c500668bb580f7fe12f156f447549": {
|
|
91
91
|
"workers": {
|
|
92
92
|
"app/page": {
|
|
93
93
|
"moduleId": 80894,
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"filename": "src/presentation/web/app/actions/stop-deployment.ts",
|
|
110
110
|
"exportedName": "stopDeployment"
|
|
111
111
|
},
|
|
112
|
-
"
|
|
112
|
+
"400abe699c44fba3a3c251e3a249db94a84ea9375f": {
|
|
113
113
|
"workers": {
|
|
114
114
|
"app/page": {
|
|
115
115
|
"moduleId": 80894,
|
|
@@ -131,7 +131,7 @@
|
|
|
131
131
|
"filename": "src/presentation/web/app/actions/get-deployment-status.ts",
|
|
132
132
|
"exportedName": "getDeploymentStatus"
|
|
133
133
|
},
|
|
134
|
-
"
|
|
134
|
+
"40c8357881b7209754173b264c064e68dc1fccc6c5": {
|
|
135
135
|
"workers": {
|
|
136
136
|
"app/page": {
|
|
137
137
|
"moduleId": 80894,
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"filename": "src/presentation/web/app/actions/open-ide.ts",
|
|
147
147
|
"exportedName": "openIde"
|
|
148
148
|
},
|
|
149
|
-
"
|
|
149
|
+
"40df943127843d139f09ef0c15e7af7962c1163a3c": {
|
|
150
150
|
"workers": {
|
|
151
151
|
"app/page": {
|
|
152
152
|
"moduleId": 80894,
|
|
@@ -161,7 +161,7 @@
|
|
|
161
161
|
"filename": "src/presentation/web/app/actions/open-shell.ts",
|
|
162
162
|
"exportedName": "openShell"
|
|
163
163
|
},
|
|
164
|
-
"
|
|
164
|
+
"403aacc3b063b935fc97c13a4ddc2e39d5248cfce7": {
|
|
165
165
|
"workers": {
|
|
166
166
|
"app/page": {
|
|
167
167
|
"moduleId": 80894,
|
|
@@ -176,7 +176,7 @@
|
|
|
176
176
|
"filename": "src/presentation/web/app/actions/open-folder.ts",
|
|
177
177
|
"exportedName": "openFolder"
|
|
178
178
|
},
|
|
179
|
-
"
|
|
179
|
+
"609912b2e71530227bd971713e722e2ddae870c834": {
|
|
180
180
|
"workers": {
|
|
181
181
|
"app/page": {
|
|
182
182
|
"moduleId": 80894,
|
|
@@ -191,7 +191,7 @@
|
|
|
191
191
|
"filename": "src/presentation/web/app/actions/approve-feature.ts",
|
|
192
192
|
"exportedName": "approveFeature"
|
|
193
193
|
},
|
|
194
|
-
"
|
|
194
|
+
"6056c8091c66cb6e17e1dc88724cdb36ef658aaa8b": {
|
|
195
195
|
"workers": {
|
|
196
196
|
"app/page": {
|
|
197
197
|
"moduleId": 80894,
|
|
@@ -206,7 +206,7 @@
|
|
|
206
206
|
"filename": "src/presentation/web/app/actions/reject-feature.ts",
|
|
207
207
|
"exportedName": "rejectFeature"
|
|
208
208
|
},
|
|
209
|
-
"
|
|
209
|
+
"403b2febb379fc46c91085af13c602491d955b01e2": {
|
|
210
210
|
"workers": {
|
|
211
211
|
"app/page": {
|
|
212
212
|
"moduleId": 80894,
|
|
@@ -221,7 +221,7 @@
|
|
|
221
221
|
"filename": "src/presentation/web/app/actions/get-feature-artifact.ts",
|
|
222
222
|
"exportedName": "getFeatureArtifact"
|
|
223
223
|
},
|
|
224
|
-
"
|
|
224
|
+
"40ab7b59ff7a66389f880a241d232f328f3926f2fe": {
|
|
225
225
|
"workers": {
|
|
226
226
|
"app/page": {
|
|
227
227
|
"moduleId": 80894,
|
|
@@ -236,7 +236,7 @@
|
|
|
236
236
|
"filename": "src/presentation/web/app/actions/get-research-artifact.ts",
|
|
237
237
|
"exportedName": "getResearchArtifact"
|
|
238
238
|
},
|
|
239
|
-
"
|
|
239
|
+
"40ba6de692514b18656ea1b43673e1bffa26a02bf4": {
|
|
240
240
|
"workers": {
|
|
241
241
|
"app/page": {
|
|
242
242
|
"moduleId": 80894,
|
|
@@ -251,7 +251,7 @@
|
|
|
251
251
|
"filename": "src/presentation/web/app/actions/get-merge-review-data.ts",
|
|
252
252
|
"exportedName": "getMergeReviewData"
|
|
253
253
|
},
|
|
254
|
-
"
|
|
254
|
+
"007efbf78a113f3482394b5e8f8001bde6bdc43bc9": {
|
|
255
255
|
"workers": {
|
|
256
256
|
"app/page": {
|
|
257
257
|
"moduleId": 80894,
|
|
@@ -266,7 +266,7 @@
|
|
|
266
266
|
"filename": "src/presentation/web/app/actions/get-workflow-defaults.ts",
|
|
267
267
|
"exportedName": "getWorkflowDefaults"
|
|
268
268
|
},
|
|
269
|
-
"
|
|
269
|
+
"406caff046f96b31ff916a2d7a56b00e4e0ba42969": {
|
|
270
270
|
"workers": {
|
|
271
271
|
"app/page": {
|
|
272
272
|
"moduleId": 80894,
|
|
@@ -281,7 +281,7 @@
|
|
|
281
281
|
"filename": "src/presentation/web/app/actions/create-feature.ts",
|
|
282
282
|
"exportedName": "createFeature"
|
|
283
283
|
},
|
|
284
|
-
"
|
|
284
|
+
"403d314dfbfa9e924edf1541ef2abe8b817e113d71": {
|
|
285
285
|
"workers": {
|
|
286
286
|
"app/page": {
|
|
287
287
|
"moduleId": 80894,
|
|
@@ -296,7 +296,7 @@
|
|
|
296
296
|
"filename": "src/presentation/web/app/actions/delete-feature.ts",
|
|
297
297
|
"exportedName": "deleteFeature"
|
|
298
298
|
},
|
|
299
|
-
"
|
|
299
|
+
"40cbce1b9c3b4e574ec0572abcf20fed0c5625fa87": {
|
|
300
300
|
"workers": {
|
|
301
301
|
"app/page": {
|
|
302
302
|
"moduleId": 80894,
|
|
@@ -311,7 +311,7 @@
|
|
|
311
311
|
"filename": "src/presentation/web/app/actions/add-repository.ts",
|
|
312
312
|
"exportedName": "addRepository"
|
|
313
313
|
},
|
|
314
|
-
"
|
|
314
|
+
"40f04206c40969efebf2da1c4c41ba53b053aace88": {
|
|
315
315
|
"workers": {
|
|
316
316
|
"app/page": {
|
|
317
317
|
"moduleId": 80894,
|
|
@@ -328,5 +328,5 @@
|
|
|
328
328
|
}
|
|
329
329
|
},
|
|
330
330
|
"edge": {},
|
|
331
|
-
"encryptionKey": "
|
|
331
|
+
"encryptionKey": "KmY8H5oInrxtJtzBQaPPrAIroKymKKDWe5g41Yx3TA8="
|
|
332
332
|
}
|
|
@@ -53,6 +53,8 @@ export interface FeatureNodeData {
|
|
|
53
53
|
branch: string;
|
|
54
54
|
/** Absolute path to the specs folder on disk */
|
|
55
55
|
specPath?: string;
|
|
56
|
+
/** Epoch ms when the current agent run started (for elapsed-time in sidebar) */
|
|
57
|
+
startedAt?: number;
|
|
56
58
|
/** Human-readable runtime for done state (e.g. "2h 15m") */
|
|
57
59
|
runtime?: string;
|
|
58
60
|
/** Feature name this node is blocked by */
|
|
@@ -10,6 +10,10 @@ import type { RepositoryNodeData } from '@/components/common/repository-node';
|
|
|
10
10
|
import { NotificationPermissionBanner } from '@/components/common/notification-permission-banner';
|
|
11
11
|
import { getWorkflowDefaults } from '@/app/actions/get-workflow-defaults';
|
|
12
12
|
import type { WorkflowDefaults } from '@/app/actions/get-workflow-defaults';
|
|
13
|
+
import {
|
|
14
|
+
useSidebarFeaturesContext,
|
|
15
|
+
mapNodeStateToSidebarStatus,
|
|
16
|
+
} from '@/hooks/sidebar-features-context';
|
|
13
17
|
import { ControlCenterEmptyState } from './control-center-empty-state';
|
|
14
18
|
import { useControlCenterState } from './use-control-center-state';
|
|
15
19
|
|
|
@@ -42,6 +46,46 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
|
|
|
42
46
|
pendingParentFeatureId,
|
|
43
47
|
} = useControlCenterState(initialNodes, initialEdges);
|
|
44
48
|
|
|
49
|
+
// Publish sidebar features to context whenever feature node data changes
|
|
50
|
+
const { setFeatures: setSidebarFeatures } = useSidebarFeaturesContext();
|
|
51
|
+
|
|
52
|
+
const sidebarKey = useMemo(() => {
|
|
53
|
+
return nodes
|
|
54
|
+
.filter((n) => n.type === 'featureNode')
|
|
55
|
+
.map((n) => {
|
|
56
|
+
const d = n.data as FeatureNodeData;
|
|
57
|
+
return `${d.featureId}:${d.state}:${d.runtime ?? ''}:${d.startedAt ?? ''}`;
|
|
58
|
+
})
|
|
59
|
+
.sort()
|
|
60
|
+
.join(',');
|
|
61
|
+
}, [nodes]);
|
|
62
|
+
|
|
63
|
+
useEffect(() => {
|
|
64
|
+
const sidebarItems = nodes
|
|
65
|
+
.filter((n) => n.type === 'featureNode')
|
|
66
|
+
.map((n) => {
|
|
67
|
+
const d = n.data as FeatureNodeData;
|
|
68
|
+
const status = mapNodeStateToSidebarStatus(d.state);
|
|
69
|
+
if (!status) return null;
|
|
70
|
+
return {
|
|
71
|
+
featureId: d.featureId,
|
|
72
|
+
name: d.name,
|
|
73
|
+
status,
|
|
74
|
+
...(d.startedAt != null && { startedAt: d.startedAt }),
|
|
75
|
+
...(d.runtime != null && { duration: d.runtime }),
|
|
76
|
+
};
|
|
77
|
+
})
|
|
78
|
+
.filter(Boolean) as {
|
|
79
|
+
featureId: string;
|
|
80
|
+
name: string;
|
|
81
|
+
status: 'action-needed' | 'in-progress' | 'done';
|
|
82
|
+
startedAt?: number;
|
|
83
|
+
duration?: string;
|
|
84
|
+
}[];
|
|
85
|
+
|
|
86
|
+
setSidebarFeatures(sidebarItems);
|
|
87
|
+
}, [sidebarKey, nodes, setSidebarFeatures]);
|
|
88
|
+
|
|
45
89
|
// Feature list for the parent selector in the create drawer
|
|
46
90
|
const featureOptions = useMemo(
|
|
47
91
|
() =>
|
package/web/.next/standalone/src/presentation/web/components/layouts/app-shell/app-shell.tsx
CHANGED
|
@@ -7,6 +7,10 @@ import { AddRepositoryButton } from '@/components/common/add-repository-node';
|
|
|
7
7
|
import { ThemeToggle } from '@/components/common/theme-toggle';
|
|
8
8
|
import { SoundToggle } from '@/components/common/sound-toggle';
|
|
9
9
|
import { AgentEventsProvider } from '@/hooks/agent-events-provider';
|
|
10
|
+
import {
|
|
11
|
+
SidebarFeaturesProvider,
|
|
12
|
+
useSidebarFeaturesContext,
|
|
13
|
+
} from '@/hooks/sidebar-features-context';
|
|
10
14
|
import { useNotifications } from '@/hooks/use-notifications';
|
|
11
15
|
|
|
12
16
|
interface AppShellProps {
|
|
@@ -18,17 +22,27 @@ function AppShellInner({ children }: AppShellProps) {
|
|
|
18
22
|
// Subscribe to agent lifecycle events and dispatch toast/browser notifications
|
|
19
23
|
useNotifications();
|
|
20
24
|
|
|
25
|
+
const { features } = useSidebarFeaturesContext();
|
|
26
|
+
|
|
21
27
|
const handleNewFeature = useCallback(() => {
|
|
22
28
|
window.dispatchEvent(new CustomEvent('shep:open-create-drawer'));
|
|
23
29
|
}, []);
|
|
24
30
|
|
|
31
|
+
const handleFeatureClick = useCallback((featureId: string) => {
|
|
32
|
+
window.dispatchEvent(new CustomEvent('shep:select-feature', { detail: { featureId } }));
|
|
33
|
+
}, []);
|
|
34
|
+
|
|
25
35
|
const handleRepositorySelect = useCallback((path: string) => {
|
|
26
36
|
window.dispatchEvent(new CustomEvent('shep:add-repository', { detail: { path } }));
|
|
27
37
|
}, []);
|
|
28
38
|
|
|
29
39
|
return (
|
|
30
40
|
<SidebarProvider>
|
|
31
|
-
<AppSidebar
|
|
41
|
+
<AppSidebar
|
|
42
|
+
features={features}
|
|
43
|
+
onNewFeature={handleNewFeature}
|
|
44
|
+
onFeatureClick={handleFeatureClick}
|
|
45
|
+
/>
|
|
32
46
|
<SidebarInset>
|
|
33
47
|
<div className="relative h-full">
|
|
34
48
|
<div className="absolute top-3 right-3 z-50 flex gap-1">
|
|
@@ -46,7 +60,9 @@ function AppShellInner({ children }: AppShellProps) {
|
|
|
46
60
|
export function AppShell({ children }: AppShellProps) {
|
|
47
61
|
return (
|
|
48
62
|
<AgentEventsProvider>
|
|
49
|
-
<
|
|
63
|
+
<SidebarFeaturesProvider>
|
|
64
|
+
<AppShellInner>{children}</AppShellInner>
|
|
65
|
+
</SidebarFeaturesProvider>
|
|
50
66
|
</AgentEventsProvider>
|
|
51
67
|
);
|
|
52
68
|
}
|
|
@@ -34,12 +34,27 @@ export default meta;
|
|
|
34
34
|
type Story = StoryObj<typeof meta>;
|
|
35
35
|
|
|
36
36
|
const mockFeatures = [
|
|
37
|
-
{ name: 'Auth Module', status: 'action-needed' as const },
|
|
38
|
-
{ name: 'Payment Flow', status: 'action-needed' as const },
|
|
39
|
-
{
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
{ featureId: 'feat-auth-001', name: 'Auth Module', status: 'action-needed' as const },
|
|
38
|
+
{ featureId: 'feat-payment-002', name: 'Payment Flow', status: 'action-needed' as const },
|
|
39
|
+
{
|
|
40
|
+
featureId: 'feat-dashboard-003',
|
|
41
|
+
name: 'Dashboard',
|
|
42
|
+
status: 'in-progress' as const,
|
|
43
|
+
startedAt: Date.now() - 330_000,
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
featureId: 'feat-api-004',
|
|
47
|
+
name: 'API Gateway',
|
|
48
|
+
status: 'in-progress' as const,
|
|
49
|
+
startedAt: Date.now() - 60_000,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
featureId: 'feat-settings-005',
|
|
53
|
+
name: 'Settings Page',
|
|
54
|
+
status: 'done' as const,
|
|
55
|
+
duration: '2h',
|
|
56
|
+
},
|
|
57
|
+
{ featureId: 'feat-profile-006', name: 'User Profile', status: 'done' as const, duration: '1h' },
|
|
43
58
|
];
|
|
44
59
|
|
|
45
60
|
export const Default: Story = {
|
|
@@ -66,8 +81,18 @@ export const Empty: Story = {
|
|
|
66
81
|
export const AllInProgress: Story = {
|
|
67
82
|
args: {
|
|
68
83
|
features: [
|
|
69
|
-
{
|
|
70
|
-
|
|
84
|
+
{
|
|
85
|
+
featureId: 'feat-a-001',
|
|
86
|
+
name: 'Feature A',
|
|
87
|
+
status: 'in-progress' as const,
|
|
88
|
+
startedAt: Date.now() - 120_000,
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
featureId: 'feat-b-002',
|
|
92
|
+
name: 'Feature B',
|
|
93
|
+
status: 'in-progress' as const,
|
|
94
|
+
startedAt: Date.now() - 600_000,
|
|
95
|
+
},
|
|
71
96
|
],
|
|
72
97
|
},
|
|
73
98
|
};
|
|
@@ -75,9 +100,9 @@ export const AllInProgress: Story = {
|
|
|
75
100
|
export const AllDone: Story = {
|
|
76
101
|
args: {
|
|
77
102
|
features: [
|
|
78
|
-
{ name: 'Feature A', status: 'done' as const, duration: '30m' },
|
|
79
|
-
{ name: 'Feature B', status: 'done' as const, duration: '1h' },
|
|
80
|
-
{ name: 'Feature C', status: 'done' as const, duration: '3h' },
|
|
103
|
+
{ featureId: 'feat-a-001', name: 'Feature A', status: 'done' as const, duration: '30m' },
|
|
104
|
+
{ featureId: 'feat-b-002', name: 'Feature B', status: 'done' as const, duration: '1h' },
|
|
105
|
+
{ featureId: 'feat-c-003', name: 'Feature C', status: 'done' as const, duration: '3h' },
|
|
81
106
|
],
|
|
82
107
|
},
|
|
83
108
|
};
|
package/web/.next/standalone/src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx
CHANGED
|
@@ -25,7 +25,8 @@ import type { FeatureStatus } from '@/components/common/feature-status-config';
|
|
|
25
25
|
import { useDeferredMount } from '@/hooks/use-deferred-mount';
|
|
26
26
|
import { featureFlags } from '@/lib/feature-flags';
|
|
27
27
|
|
|
28
|
-
interface FeatureItem {
|
|
28
|
+
export interface FeatureItem {
|
|
29
|
+
featureId: string;
|
|
29
30
|
name: string;
|
|
30
31
|
status: FeatureStatus;
|
|
31
32
|
startedAt?: number;
|
|
@@ -35,7 +36,7 @@ interface FeatureItem {
|
|
|
35
36
|
export interface AppSidebarProps {
|
|
36
37
|
features: FeatureItem[];
|
|
37
38
|
onNewFeature?: () => void;
|
|
38
|
-
onFeatureClick?: (
|
|
39
|
+
onFeatureClick?: (featureId: string) => void;
|
|
39
40
|
onFeaturesFolderClick?: () => void;
|
|
40
41
|
onFeaturesMenuClick?: () => void;
|
|
41
42
|
}
|
|
@@ -119,12 +120,14 @@ export function AppSidebar({
|
|
|
119
120
|
<FeatureStatusGroup key={key} label={label} count={items.length}>
|
|
120
121
|
{items.map((feature) => (
|
|
121
122
|
<FeatureListItem
|
|
122
|
-
key={feature.
|
|
123
|
+
key={feature.featureId}
|
|
123
124
|
name={feature.name}
|
|
124
125
|
status={feature.status}
|
|
125
126
|
startedAt={feature.startedAt}
|
|
126
127
|
duration={feature.duration}
|
|
127
|
-
onClick={
|
|
128
|
+
onClick={
|
|
129
|
+
onFeatureClick ? () => onFeatureClick(feature.featureId) : undefined
|
|
130
|
+
}
|
|
128
131
|
/>
|
|
129
132
|
))}
|
|
130
133
|
</FeatureStatusGroup>
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { createContext, useContext, useState, useMemo, type ReactNode } from 'react';
|
|
4
|
+
import type { FeatureNodeState } from '@/components/common/feature-node/feature-node-state-config';
|
|
5
|
+
import type { FeatureStatus } from '@/components/common/feature-status-config';
|
|
6
|
+
|
|
7
|
+
// Re-export the FeatureItem type so consumers can import from one place.
|
|
8
|
+
// This will gain `featureId` in a later phase.
|
|
9
|
+
export interface SidebarFeatureItem {
|
|
10
|
+
name: string;
|
|
11
|
+
status: FeatureStatus;
|
|
12
|
+
featureId: string;
|
|
13
|
+
startedAt?: number;
|
|
14
|
+
duration?: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// Pure mapping: FeatureNodeState (6-state) → FeatureStatus (3-state) | null
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
const stateMapping: Record<FeatureNodeState, FeatureStatus | null> = {
|
|
22
|
+
'action-required': 'action-needed',
|
|
23
|
+
running: 'in-progress',
|
|
24
|
+
done: 'done',
|
|
25
|
+
blocked: 'in-progress',
|
|
26
|
+
error: 'in-progress',
|
|
27
|
+
creating: null,
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Maps a canvas FeatureNodeState to the sidebar's 3-state FeatureStatus.
|
|
32
|
+
* Returns `null` for `creating` (optimistic UI) — these should be excluded from the sidebar.
|
|
33
|
+
*/
|
|
34
|
+
export function mapNodeStateToSidebarStatus(state: FeatureNodeState): FeatureStatus | null {
|
|
35
|
+
return stateMapping[state];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// SidebarFeaturesContext
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
interface SidebarFeaturesContextValue {
|
|
43
|
+
features: SidebarFeatureItem[];
|
|
44
|
+
setFeatures: (features: SidebarFeatureItem[]) => void;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const SidebarFeaturesContext = createContext<SidebarFeaturesContextValue | null>(null);
|
|
48
|
+
|
|
49
|
+
interface SidebarFeaturesProviderProps {
|
|
50
|
+
children: ReactNode;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function SidebarFeaturesProvider({ children }: SidebarFeaturesProviderProps) {
|
|
54
|
+
const [features, setFeatures] = useState<SidebarFeatureItem[]>([]);
|
|
55
|
+
|
|
56
|
+
const value = useMemo<SidebarFeaturesContextValue>(() => ({ features, setFeatures }), [features]);
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<SidebarFeaturesContext.Provider value={value}>{children}</SidebarFeaturesContext.Provider>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function useSidebarFeaturesContext(): SidebarFeaturesContextValue {
|
|
64
|
+
const ctx = useContext(SidebarFeaturesContext);
|
|
65
|
+
if (!ctx) {
|
|
66
|
+
throw new Error('useSidebarFeaturesContext must be used within a <SidebarFeaturesProvider>');
|
|
67
|
+
}
|
|
68
|
+
return ctx;
|
|
69
|
+
}
|
|
@@ -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.68.
|
|
18
|
+
const nextConfig = {"env":{"NEXT_PUBLIC_SHEP_VERSION":"1.68.1","NEXT_PUBLIC_SHEP_PACKAGE_NAME":"@shepai/cli","NEXT_PUBLIC_SHEP_DESCRIPTION":"Autonomous AI Native SDLC Platform - Automate the development cycle from idea to deploy"},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":true,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/cli/cli","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"dynamicOnHover":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":false,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":false,"lockDistDir":true,"isolatedDevBuild":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":false,"optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","turbopack":{"root":"/home/runner/work/cli/cli"},"serverExternalPackages":["tsyringe","reflect-metadata","better-sqlite3","node:os","node:child_process","node:fs"],"distDirRoot":".next"}
|
|
19
19
|
|
|
20
20
|
process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
|
|
21
21
|
|