@shepai/cli 1.148.0 → 1.149.0-pr464.a84e893
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/app/api/agent-events/route.js +1 -1
- package/dist/src/presentation/web/app/api/sessions/route.d.ts.map +1 -1
- package/dist/src/presentation/web/app/api/sessions/route.js +2 -268
- package/dist/src/presentation/web/app/api/sessions-batch/route.d.ts +17 -0
- package/dist/src/presentation/web/app/api/sessions-batch/route.d.ts.map +1 -0
- package/dist/src/presentation/web/app/api/sessions-batch/route.js +61 -0
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +18 -2
- package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.d.ts +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.js +15 -73
- package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-node/feature-sessions-dropdown.stories.js +18 -17
- 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 +18 -0
- package/dist/src/presentation/web/components/features/control-center/control-center.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/control-center/control-center.js +2 -1
- 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 +4 -1
- 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 +32 -33
- package/dist/src/presentation/web/hooks/sessions-provider.d.ts +12 -0
- package/dist/src/presentation/web/hooks/sessions-provider.d.ts.map +1 -0
- package/dist/src/presentation/web/hooks/sessions-provider.js +57 -0
- package/dist/src/presentation/web/hooks/use-deploy-action.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-deploy-action.js +8 -54
- package/dist/src/presentation/web/lib/session-scanner.d.ts +27 -0
- package/dist/src/presentation/web/lib/session-scanner.d.ts.map +1 -0
- package/dist/src/presentation/web/lib/session-scanner.js +255 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/app-path-routes-manifest.json +1 -0
- package/web/.next/build-manifest.json +2 -2
- package/web/.next/fallback-build-manifest.json +2 -2
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +3 -3
- package/web/.next/required-server-files.json +3 -3
- package/web/.next/routes-manifest.json +6 -0
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +36 -36
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +36 -36
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +26 -26
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +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 +3 -3
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
- package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
- package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
- package/web/.next/server/app/api/sessions/route.js +2 -3
- package/web/.next/server/app/api/sessions/route.js.nft.json +1 -1
- package/web/.next/server/app/api/sessions-batch/route/app-paths-manifest.json +3 -0
- package/web/.next/server/app/api/sessions-batch/route/build-manifest.json +11 -0
- package/web/.next/server/app/api/sessions-batch/route/server-reference-manifest.json +4 -0
- package/web/.next/server/app/api/sessions-batch/route.js +7 -0
- package/web/.next/server/app/api/sessions-batch/route.js.map +5 -0
- package/web/.next/server/app/api/sessions-batch/route.js.nft.json +1 -0
- package/web/.next/server/app/api/sessions-batch/route_client-reference-manifest.js +2 -0
- package/web/.next/server/app/settings/page/server-reference-manifest.json +8 -8
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +8 -8
- 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 +8 -8
- 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 +3 -3
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app-paths-manifest.json +1 -0
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -1
- package/web/.next/server/chunks/744ca_web__next-internal_server_app_api_sessions-batch_route_actions_4859f283.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__0d33c29e._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__0d33c29e._.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__2f61738a._.js +3 -0
- package/web/.next/server/chunks/[root-of-the-server]__2f61738a._.js.map +1 -0
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
- package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2138fa7e._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__29580090._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__29580090._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__3ef34e4c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +3 -3
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c094882b._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__c094882b._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__dac5dbf1._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__dac5dbf1._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fae8b355._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fae8b355._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
- package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0c5f56e3._.js +2 -2
- package/web/.next/server/chunks/ssr/_0c5f56e3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
- package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_1b719e7f._.js +1 -1
- package/web/.next/server/chunks/ssr/_1b719e7f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_37e8548b._.js +1 -1
- package/web/.next/server/chunks/ssr/_37e8548b._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_55d763e2._.js +1 -1
- package/web/.next/server/chunks/ssr/_55d763e2._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_6256a985._.js +1 -1
- package/web/.next/server/chunks/ssr/_6256a985._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_64bdfc6f._.js +2 -2
- package/web/.next/server/chunks/ssr/_64bdfc6f._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_8c875922._.js +4 -0
- package/web/.next/server/chunks/ssr/_8c875922._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_8fcc39d4._.js +1 -1
- package/web/.next/server/chunks/ssr/_b06fea81._.js +3 -0
- package/web/.next/server/chunks/ssr/{_fe63a7f9._.js.map → _b06fea81._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_b71645b4._.js +1 -1
- package/web/.next/server/chunks/ssr/_b71645b4._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_d8575088._.js +1 -1
- package/web/.next/server/chunks/ssr/_d8575088._.js.map +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
- package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{src_presentation_web_7b2fda40._.js → src_presentation_web_3095acd1._.js} +2 -2
- package/web/.next/server/chunks/ssr/{src_presentation_web_7b2fda40._.js.map → src_presentation_web_3095acd1._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +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_components_features_control-center_7ac3562e._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.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 +44 -44
- package/web/.next/static/chunks/{04869f1d3f5d9071.js → 1b1f15f424679455.js} +1 -1
- package/web/.next/static/chunks/{9dad6769d10a32df.js → 23c3e86ce0e24e00.js} +1 -1
- package/web/.next/static/chunks/36e2fd941864a90e.js +1 -0
- package/web/.next/static/chunks/{c731682077fbac4f.js → 3a4705f59cfd89a9.js} +1 -1
- package/web/.next/static/chunks/{6f76e63ead3fac2e.js → 51dee46741af1e4b.js} +1 -1
- package/web/.next/static/chunks/{48850e202dd814ac.js → 55683e8c2c1639b7.js} +1 -1
- package/web/.next/static/chunks/616c959907e661c9.js +1 -0
- package/web/.next/static/chunks/{21e82fee1a7e1668.js → 62501e23f82d4115.js} +1 -1
- package/web/.next/static/chunks/{7c5131e33516a325.js → 862d6fa007e83cb5.js} +1 -1
- package/web/.next/static/chunks/8e2039e569c81a6d.js +1 -0
- package/web/.next/static/chunks/a26e8c3319a6b723.js +5 -0
- package/web/.next/static/chunks/f946e2a33ee3b18e.js +2 -0
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_ff60e4a5.js +0 -3
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_ff60e4a5.js.map +0 -1
- package/web/.next/server/chunks/[externals]__448264a3._.js +0 -3
- package/web/.next/server/chunks/ssr/_4533d6f8._.js +0 -4
- package/web/.next/server/chunks/ssr/_4533d6f8._.js.map +0 -1
- package/web/.next/server/chunks/ssr/_fe63a7f9._.js +0 -3
- package/web/.next/static/chunks/0137d4850cab3c45.js +0 -5
- package/web/.next/static/chunks/063a24b49d9818a0.js +0 -1
- package/web/.next/static/chunks/682563e4503cbd58.js +0 -1
- package/web/.next/static/chunks/683b1d85e789c2eb.js +0 -2
- package/web/.next/static/chunks/d62ae5e449d87057.js +0 -1
- /package/web/.next/server/chunks/{[externals]__448264a3._.js.map → 744ca_web__next-internal_server_app_api_sessions-batch_route_actions_4859f283.js.map} +0 -0
- /package/web/.next/static/{zYKuE1zbe1UWwAJv5EVwg → QdGWt290JhTjWmj28lHyG}/_buildManifest.js +0 -0
- /package/web/.next/static/{zYKuE1zbe1UWwAJv5EVwg → QdGWt290JhTjWmj28lHyG}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{zYKuE1zbe1UWwAJv5EVwg → QdGWt290JhTjWmj28lHyG}/_ssgManifest.js +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { FeatureSessionsDropdown } from './feature-sessions-dropdown.js';
|
|
3
|
+
import { SessionsProvider } from '../../../hooks/sessions-provider.js';
|
|
4
|
+
const REPO_PATH = '/home/user/workspaces/my-project';
|
|
3
5
|
const mockSessions = [
|
|
4
6
|
{
|
|
5
7
|
id: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
|
|
@@ -8,7 +10,7 @@ const mockSessions = [
|
|
|
8
10
|
firstMessageAt: new Date(Date.now() - 3_600_000).toISOString(),
|
|
9
11
|
lastMessageAt: new Date(Date.now() - 1_800_000).toISOString(),
|
|
10
12
|
createdAt: new Date(Date.now() - 3_600_000).toISOString(),
|
|
11
|
-
projectPath:
|
|
13
|
+
projectPath: REPO_PATH,
|
|
12
14
|
},
|
|
13
15
|
{
|
|
14
16
|
id: 'b2c3d4e5-f6a7-8901-bcde-f12345678901',
|
|
@@ -17,7 +19,7 @@ const mockSessions = [
|
|
|
17
19
|
firstMessageAt: new Date(Date.now() - 86_400_000).toISOString(),
|
|
18
20
|
lastMessageAt: new Date(Date.now() - 82_800_000).toISOString(),
|
|
19
21
|
createdAt: new Date(Date.now() - 86_400_000).toISOString(),
|
|
20
|
-
projectPath:
|
|
22
|
+
projectPath: REPO_PATH,
|
|
21
23
|
},
|
|
22
24
|
{
|
|
23
25
|
id: 'c3d4e5f6-a7b8-9012-cdef-123456789012',
|
|
@@ -26,7 +28,7 @@ const mockSessions = [
|
|
|
26
28
|
firstMessageAt: new Date(Date.now() - 172_800_000).toISOString(),
|
|
27
29
|
lastMessageAt: new Date(Date.now() - 169_200_000).toISOString(),
|
|
28
30
|
createdAt: new Date(Date.now() - 172_800_000).toISOString(),
|
|
29
|
-
projectPath:
|
|
31
|
+
projectPath: REPO_PATH,
|
|
30
32
|
},
|
|
31
33
|
];
|
|
32
34
|
const mockActiveSession = {
|
|
@@ -36,42 +38,41 @@ const mockActiveSession = {
|
|
|
36
38
|
firstMessageAt: new Date(Date.now() - 180_000).toISOString(),
|
|
37
39
|
lastMessageAt: new Date(Date.now() - 60_000).toISOString(), // 1 min ago — active
|
|
38
40
|
createdAt: new Date(Date.now() - 180_000).toISOString(),
|
|
39
|
-
projectPath:
|
|
41
|
+
projectPath: REPO_PATH,
|
|
40
42
|
};
|
|
41
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Mock fetch for /api/sessions-batch, then wrap with SessionsProvider.
|
|
45
|
+
*/
|
|
46
|
+
function createSessionsMock(sessions) {
|
|
42
47
|
return (Story) => {
|
|
43
48
|
const originalFetch = window.fetch;
|
|
44
49
|
window.fetch = (async (input, init) => {
|
|
45
50
|
const url = typeof input === 'string' ? input : input instanceof URL ? input.href : input.url;
|
|
46
|
-
if (url.includes('/api/sessions')) {
|
|
47
|
-
return new Response(JSON.stringify({ sessions }), {
|
|
51
|
+
if (url.includes('/api/sessions-batch')) {
|
|
52
|
+
return new Response(JSON.stringify({ sessionsByPath: sessions }), {
|
|
48
53
|
status: 200,
|
|
49
54
|
headers: { 'Content-Type': 'application/json' },
|
|
50
55
|
});
|
|
51
56
|
}
|
|
52
57
|
return originalFetch(input, init);
|
|
53
58
|
});
|
|
54
|
-
return _jsx(Story, {});
|
|
59
|
+
return (_jsx(SessionsProvider, { children: _jsx(Story, {}) }));
|
|
55
60
|
};
|
|
56
61
|
}
|
|
57
62
|
const meta = {
|
|
58
63
|
title: 'Composed/FeatureSessionsDropdown',
|
|
59
64
|
component: FeatureSessionsDropdown,
|
|
60
65
|
tags: ['autodocs'],
|
|
61
|
-
parameters: {
|
|
62
|
-
|
|
63
|
-
},
|
|
64
|
-
args: {
|
|
65
|
-
repositoryPath: '/home/user/workspaces/my-project',
|
|
66
|
-
},
|
|
66
|
+
parameters: { layout: 'centered' },
|
|
67
|
+
args: { repositoryPath: REPO_PATH },
|
|
67
68
|
};
|
|
68
69
|
export default meta;
|
|
69
70
|
export const WithSessions = {
|
|
70
|
-
decorators: [
|
|
71
|
+
decorators: [createSessionsMock({ [REPO_PATH]: mockSessions })],
|
|
71
72
|
};
|
|
72
73
|
export const WithActiveSessions = {
|
|
73
|
-
decorators: [
|
|
74
|
+
decorators: [createSessionsMock({ [REPO_PATH]: [mockActiveSession, ...mockSessions] })],
|
|
74
75
|
};
|
|
75
76
|
export const Empty = {
|
|
76
|
-
decorators: [
|
|
77
|
+
decorators: [createSessionsMock({ [REPO_PATH]: [] })],
|
|
77
78
|
};
|
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":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAKpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAwB5E,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":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAY,MAAM,eAAe,CAAC;AAKpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAwB5E,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,2CA0ZzF"}
|
package/dist/src/presentation/web/components/features/control-center/control-center-inner.js
CHANGED
|
@@ -197,6 +197,24 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
197
197
|
window.addEventListener('shep:feature-delete-requested', handler);
|
|
198
198
|
return () => window.removeEventListener('shep:feature-delete-requested', handler);
|
|
199
199
|
}, [handleDeleteFeature]);
|
|
200
|
+
// Listen for archive requests from the feature drawer.
|
|
201
|
+
useEffect(() => {
|
|
202
|
+
const handler = (e) => {
|
|
203
|
+
const { featureId } = e.detail;
|
|
204
|
+
handleArchiveFeature(featureId);
|
|
205
|
+
};
|
|
206
|
+
window.addEventListener('shep:feature-archive-requested', handler);
|
|
207
|
+
return () => window.removeEventListener('shep:feature-archive-requested', handler);
|
|
208
|
+
}, [handleArchiveFeature]);
|
|
209
|
+
// Listen for unarchive requests from the feature drawer.
|
|
210
|
+
useEffect(() => {
|
|
211
|
+
const handler = (e) => {
|
|
212
|
+
const { featureId } = e.detail;
|
|
213
|
+
handleUnarchiveFeature(featureId);
|
|
214
|
+
};
|
|
215
|
+
window.addEventListener('shep:feature-unarchive-requested', handler);
|
|
216
|
+
return () => window.removeEventListener('shep:feature-unarchive-requested', handler);
|
|
217
|
+
}, [handleUnarchiveFeature]);
|
|
200
218
|
// Wire callbacks into derived node data (via ref — no re-render).
|
|
201
219
|
useEffect(() => {
|
|
202
220
|
setCallbacks({
|
package/dist/src/presentation/web/components/features/control-center/control-center.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control-center.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;
|
|
1
|
+
{"version":3,"file":"control-center.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/control-center/control-center.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAI5E,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,cAAc,EAAE,CAAC;IAC/B,YAAY,EAAE,IAAI,EAAE,CAAC;IACrB,kEAAkE;IAClE,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,wBAAgB,aAAa,CAAC,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,EAAE,EAAE,kBAAkB,2CAWvF"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { ReactFlowProvider } from '@xyflow/react';
|
|
4
|
+
import { SessionsProvider } from '../../../hooks/sessions-provider.js';
|
|
4
5
|
import { ControlCenterInner } from './control-center-inner.js';
|
|
5
6
|
export function ControlCenter({ initialNodes, initialEdges, drawer }) {
|
|
6
|
-
return (_jsxs("div", { "data-testid": "control-center", className: "h-full w-full", children: [_jsx(ReactFlowProvider, { children: _jsx(ControlCenterInner, { initialNodes: initialNodes, initialEdges: initialEdges }) }), _jsx("div", { children: drawer }, "drawer")] }));
|
|
7
|
+
return (_jsxs("div", { "data-testid": "control-center", className: "h-full w-full", children: [_jsx(SessionsProvider, { children: _jsx(ReactFlowProvider, { children: _jsx(ControlCenterInner, { initialNodes: initialNodes, initialEdges: initialEdges }) }) }), _jsx("div", { children: drawer }, "drawer")] }));
|
|
7
8
|
}
|
|
@@ -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":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAkBjC,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAM7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,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,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/E,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,mBAAmB,EAAE,CACnB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAC;IACV,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,sBAAsB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,sBAAsB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EACvC,QAAQ,CAAC,EAAE,MAAM,KACd,MAAM,CAAC;IACZ,yDAAyD;IACzD,YAAY,EAAE,OAAO,CAAC;IACtB,0CAA0C;IAC1C,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,wDAAwD;IACxD,wBAAwB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,gDAAgD;IAChD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAC;IACtE,0EAA0E;IAC1E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAQD,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,
|
|
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":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qCAAqC,CAAC;AAC9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAC5E,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,yBAAyB,CAAC;AAkBjC,OAAO,EAAiB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAM7E,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,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,mBAAmB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/E,YAAY,EAAE,CAAC,SAAS,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,oBAAoB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,mBAAmB,EAAE,CACnB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,OAAO,EACjB,aAAa,CAAC,EAAE,OAAO,EACvB,OAAO,CAAC,EAAE,OAAO,KACd,IAAI,CAAC;IACV,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,sBAAsB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACpD,sBAAsB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,iBAAiB,EAAE,CACjB,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,YAAY,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,EACvC,QAAQ,CAAC,EAAE,MAAM,KACd,MAAM,CAAC;IACZ,yDAAyD;IACzD,YAAY,EAAE,OAAO,CAAC;IACtB,0CAA0C;IAC1C,eAAe,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,wDAAwD;IACxD,wBAAwB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;IACxE,gDAAgD;IAChD,iBAAiB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,GAAG,SAAS,CAAC;IACtE,0EAA0E;IAC1E,YAAY,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAQD,wBAAgB,qBAAqB,CACnC,YAAY,EAAE,cAAc,EAAE,EAC9B,YAAY,EAAE,IAAI,EAAE,GACnB,kBAAkB,CAilBpB"}
|
package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js
CHANGED
|
@@ -18,7 +18,7 @@ import { createLogger } from '../../../lib/logger.js';
|
|
|
18
18
|
import { mapEventTypeToState, resolveSseEventUpdates, } from '../../common/feature-node/derive-feature-state.js';
|
|
19
19
|
import { useGraphState } from '../../../hooks/use-graph-state.js';
|
|
20
20
|
const log = createLogger('[Polling]');
|
|
21
|
-
const POLL_INTERVAL_MS =
|
|
21
|
+
const POLL_INTERVAL_MS = 15_000;
|
|
22
22
|
/** Must match the message string emitted by the SSE route in agent-events/route.ts */
|
|
23
23
|
const METADATA_UPDATED_MESSAGE = 'Feature metadata updated';
|
|
24
24
|
let nextFeatureId = 0;
|
|
@@ -175,6 +175,9 @@ export function useControlCenterState(initialNodes, initialEdges) {
|
|
|
175
175
|
useEffect(() => {
|
|
176
176
|
log.debug(`polling enabled (${POLL_INTERVAL_MS}ms interval)`);
|
|
177
177
|
const timer = setInterval(async () => {
|
|
178
|
+
// Skip when tab is hidden — no point polling for a user who isn't looking.
|
|
179
|
+
if (document.hidden)
|
|
180
|
+
return;
|
|
178
181
|
// Skip fetch entirely while a mutation is in-flight — the response
|
|
179
182
|
// would contain pre-mutation data that reconcile would discard anyway.
|
|
180
183
|
if (isMutating())
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-sidebar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"app-sidebar.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAI/E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE7D,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,WAAW,EAAE,CAAC;IACxB,YAAY,EAAE,iBAAiB,CAAC;IAEhC,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,wBAAgB,UAAU,CAAC,EACzB,QAAQ,EACR,YAAY,EAEZ,cAAc,GACf,EAAE,eAAe,2CAoMjB"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { usePathname } from 'next/navigation';
|
|
4
|
-
import Link from 'next/link';
|
|
5
4
|
import { Home, Moon, Sun, Volume2, VolumeOff, Wrench, Puzzle, Settings } from 'lucide-react';
|
|
6
5
|
import { Sidebar, SidebarHeader, SidebarContent, SidebarFooter, SidebarMenu, SidebarMenuItem, SidebarMenuButton, SidebarRail, useSidebar, } from '../../ui/sidebar.js';
|
|
7
6
|
import { ScrollArea } from '../../ui/scroll-area.js';
|
|
@@ -39,39 +38,39 @@ export function AppSidebar({ features, featureFlags, onFeatureClick, }) {
|
|
|
39
38
|
'flex min-w-0 flex-1 items-center gap-2 overflow-hidden px-2',
|
|
40
39
|
'transition-opacity duration-200 ease-out',
|
|
41
40
|
expandedVisible ? 'opacity-100' : 'opacity-0',
|
|
42
|
-
].join(' '), "aria-hidden": !expandedVisible, children: [_jsx(ShepLogo, { className: "shrink-0", size: 20, variant: versionData.isDev ? 'dev' : 'default' }), _jsx("span", { className: "truncate text-sm font-semibold tracking-tight", children: "Shep" }), _jsx(VersionBadge, { version: versionData.version, branch: versionData.branch || undefined, commitHash: versionData.commitHash || undefined, isDev: versionData.isDev, packageName: versionData.packageName, description: versionData.description, instancePath: versionData.instancePath || undefined })] })) : null, _jsx(SidebarCollapseToggle, { className: "shrink-0 transition-all duration-200" })] }) }), _jsx(SidebarNavItem, { icon: Home, label: "Control Center", href: "/", active: pathname === '/' }), _jsx(SidebarNavItem, { icon: Wrench, label: "Tools", href: "/tools", active: pathname === '/tools' }), featureFlags.skills ? (_jsx(SidebarNavItem, { icon: Puzzle, label: "Skills", href: "/skills", active: pathname === '/skills' })) : null] }) }), _jsx(SidebarContent, { children: showExpanded ? (_jsxs("div", { className: [
|
|
41
|
+
].join(' '), "aria-hidden": !expandedVisible, children: [_jsx(ShepLogo, { className: "shrink-0", size: 20, variant: versionData.isDev ? 'dev' : 'default' }), _jsx("span", { className: "truncate text-sm font-semibold tracking-tight", children: "Shep" }), _jsx(VersionBadge, { version: versionData.version, branch: versionData.branch || undefined, commitHash: versionData.commitHash || undefined, isDev: versionData.isDev, packageName: versionData.packageName, description: versionData.description, instancePath: versionData.instancePath || undefined })] })) : null, _jsx(SidebarCollapseToggle, { className: "shrink-0 transition-all duration-200" })] }) }), _jsx(SidebarNavItem, { icon: Home, label: "Control Center", href: "/", active: pathname === '/' }), _jsx(SidebarNavItem, { icon: Wrench, label: "Tools", href: "/tools", active: pathname === '/tools' }), featureFlags.skills ? (_jsx(SidebarNavItem, { icon: Puzzle, label: "Skills", href: "/skills", active: pathname === '/skills' })) : null, _jsx(SidebarNavItem, { icon: Settings, label: "Settings", href: "/settings", active: pathname === '/settings' })] }) }), _jsx(SidebarContent, { children: showExpanded ? (_jsxs("div", { className: [
|
|
43
42
|
'flex min-h-0 flex-1 flex-col overflow-hidden transition-opacity duration-200 ease-out',
|
|
44
43
|
'[&_[data-sidebar=group-label]]:!mt-0 [&_[data-sidebar=group-label]]:!opacity-100 [&_[data-sidebar=group-label]]:!transition-none',
|
|
45
44
|
expandedVisible ? 'opacity-100' : 'opacity-0',
|
|
46
|
-
].join(' '), children: [_jsx(SidebarSectionHeader, { label: "Features" }), _jsx(ScrollArea, { className: "min-h-0 flex-1", children: grouped.map(({ key, label, items }) => items.length > 0 ? (_jsx(FeatureStatusGroup, { label: label, count: items.length, children: items.map((feature) => (_jsx(FeatureListItem, { name: feature.name, status: feature.status, startedAt: feature.startedAt, duration: feature.duration, agentType: feature.agentType, modelId: feature.modelId, onClick: onFeatureClick ? () => onFeatureClick(feature.featureId) : undefined }, feature.featureId))) }, key)) : null) })] })) : null }), _jsx(SidebarFooter, { className: "border-t p-2", children: _jsx(SidebarMenu, { children: _jsx(SidebarMenuItem, { children:
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
45
|
+
].join(' '), children: [_jsx(SidebarSectionHeader, { label: "Features" }), _jsx(ScrollArea, { className: "min-h-0 flex-1", children: grouped.map(({ key, label, items }) => items.length > 0 ? (_jsx(FeatureStatusGroup, { label: label, count: items.length, children: items.map((feature) => (_jsx(FeatureListItem, { name: feature.name, status: feature.status, startedAt: feature.startedAt, duration: feature.duration, agentType: feature.agentType, modelId: feature.modelId, onClick: onFeatureClick ? () => onFeatureClick(feature.featureId) : undefined }, feature.featureId))) }, key)) : null) })] })) : null }), _jsx(SidebarFooter, { className: "border-t p-2", children: _jsx(SidebarMenu, { children: _jsx(SidebarMenuItem, { children: _jsx("div", { className: "flex items-center gap-1", children: _jsxs(TooltipProvider, { children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs(SidebarMenuButton, { className: "w-auto flex-none", onClick: (e) => {
|
|
46
|
+
const currentResolved = theme === 'system' ? resolvedTheme : theme;
|
|
47
|
+
const goingToDark = currentResolved !== 'dark';
|
|
48
|
+
const newTheme = theme === 'system'
|
|
49
|
+
? resolvedTheme === 'dark'
|
|
50
|
+
? 'light'
|
|
51
|
+
: 'dark'
|
|
52
|
+
: theme === 'dark'
|
|
53
|
+
? 'light'
|
|
54
|
+
: 'dark';
|
|
55
|
+
if (goingToDark) {
|
|
56
|
+
toggleOnSound.play();
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
toggleOffSound.play();
|
|
60
|
+
}
|
|
61
|
+
const prefersReducedMotion = typeof window !== 'undefined' &&
|
|
62
|
+
window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
63
|
+
if (!('startViewTransition' in document) || prefersReducedMotion) {
|
|
64
|
+
setTheme(newTheme);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
document.documentElement.style.setProperty('--x', `${e.clientX}px`);
|
|
68
|
+
document.documentElement.style.setProperty('--y', `${e.clientY}px`);
|
|
69
|
+
document.startViewTransition(() => {
|
|
70
|
+
setTheme(newTheme);
|
|
71
|
+
});
|
|
72
|
+
}, "aria-label": `Switch to ${resolvedTheme === 'dark' ? 'light' : 'dark'} mode`, children: [_jsx(Sun, { className: "h-4 w-4 scale-100 rotate-0 transition-all dark:scale-0 dark:-rotate-90" }), _jsx(Moon, { className: "absolute h-4 w-4 scale-0 rotate-90 transition-all dark:scale-100 dark:rotate-0" })] }) }), _jsx(TooltipContent, { side: "top", children: resolvedTheme === 'dark' ? 'Light mode' : 'Dark mode' })] }), !collapsed && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(SidebarMenuButton, { className: "w-auto flex-none", onClick: () => {
|
|
73
|
+
clickSound.play();
|
|
74
|
+
toggleSound();
|
|
75
|
+
}, "aria-label": soundEnabled ? 'Mute sounds' : 'Unmute sounds', children: soundEnabled ? (_jsx(Volume2, { className: "h-4 w-4" })) : (_jsx(VolumeOff, { className: "h-4 w-4" })) }) }), _jsx(TooltipContent, { side: "top", children: soundEnabled ? 'Mute sounds' : 'Unmute sounds' })] }))] }) }) }) }) }), _jsx(SidebarRail, {})] }));
|
|
77
76
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
2
|
+
import type { SessionSummary } from '../components/common/feature-node/feature-sessions-dropdown.js';
|
|
3
|
+
interface SessionsContextValue {
|
|
4
|
+
getSessionsForPath: (path: string) => SessionSummary[];
|
|
5
|
+
hasActiveSessions: (path: string) => boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare function SessionsProvider({ children }: {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export declare function useSessionsContext(): SessionsContextValue;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=sessions-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions-provider.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/sessions-provider.tsx"],"names":[],"mappings":"AAEA,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4DAA4D,CAAC;AAOjG,UAAU,oBAAoB;IAC5B,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,cAAc,EAAE,CAAC;IACvD,iBAAiB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CAC9C;AAMD,wBAAgB,gBAAgB,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,SAAS,CAAA;CAAE,2CAoDrE;AAID,wBAAgB,kBAAkB,IAAI,oBAAoB,CAMzD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from 'react';
|
|
4
|
+
const POLL_INTERVAL_MS = 30_000;
|
|
5
|
+
const ACTIVE_THRESHOLD_MS = 5 * 60 * 1000; // 5 minutes
|
|
6
|
+
const SessionsContext = createContext(null);
|
|
7
|
+
// ── Provider component ────────────────────────────────────────────────
|
|
8
|
+
export function SessionsProvider({ children }) {
|
|
9
|
+
const [sessionsByPath, setSessionsByPath] = useState(new Map());
|
|
10
|
+
const sessionsByPathRef = useRef(sessionsByPath);
|
|
11
|
+
sessionsByPathRef.current = sessionsByPath;
|
|
12
|
+
const fetchSessions = useCallback(async () => {
|
|
13
|
+
if (document.hidden)
|
|
14
|
+
return;
|
|
15
|
+
try {
|
|
16
|
+
const res = await fetch('/api/sessions-batch');
|
|
17
|
+
if (!res.ok)
|
|
18
|
+
return;
|
|
19
|
+
const data = (await res.json());
|
|
20
|
+
const next = new Map();
|
|
21
|
+
for (const [path, sessions] of Object.entries(data.sessionsByPath)) {
|
|
22
|
+
next.set(path, sessions);
|
|
23
|
+
}
|
|
24
|
+
setSessionsByPath(next);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Silent — stale data is better than no data
|
|
28
|
+
}
|
|
29
|
+
}, []);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
void fetchSessions();
|
|
32
|
+
const timer = setInterval(() => void fetchSessions(), POLL_INTERVAL_MS);
|
|
33
|
+
return () => clearInterval(timer);
|
|
34
|
+
}, [fetchSessions]);
|
|
35
|
+
const getSessionsForPath = useCallback((path) => sessionsByPathRef.current.get(path) ?? [],
|
|
36
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
37
|
+
[sessionsByPath]);
|
|
38
|
+
const hasActiveSessions = useCallback((path) => {
|
|
39
|
+
const sessions = sessionsByPathRef.current.get(path);
|
|
40
|
+
if (!sessions)
|
|
41
|
+
return false;
|
|
42
|
+
const now = Date.now();
|
|
43
|
+
return sessions.some((s) => s.lastMessageAt && now - new Date(s.lastMessageAt).getTime() < ACTIVE_THRESHOLD_MS);
|
|
44
|
+
},
|
|
45
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
46
|
+
[sessionsByPath]);
|
|
47
|
+
const value = useMemo(() => ({ getSessionsForPath, hasActiveSessions }), [getSessionsForPath, hasActiveSessions]);
|
|
48
|
+
return _jsx(SessionsContext.Provider, { value: value, children: children });
|
|
49
|
+
}
|
|
50
|
+
// ── Consumer hook ─────────────────────────────────────────────────────
|
|
51
|
+
export function useSessionsContext() {
|
|
52
|
+
const ctx = useContext(SessionsContext);
|
|
53
|
+
if (!ctx) {
|
|
54
|
+
return { getSessionsForPath: () => [], hasActiveSessions: () => false };
|
|
55
|
+
}
|
|
56
|
+
return ctx;
|
|
57
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-deploy-action.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-deploy-action.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAM5E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,SAAS,GAAG,YAAY,CAAC;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAMD,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,iBAAiB,
|
|
1
|
+
{"version":3,"file":"use-deploy-action.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-deploy-action.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sCAAsC,CAAC;AAM5E,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,SAAS,GAAG,YAAY,CAAC;IACrC,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,aAAa,EAAE,OAAO,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAMD,wBAAgB,eAAe,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,iBAAiB,CAwLlF"}
|
|
@@ -27,34 +27,9 @@ export function useDeployAction(input) {
|
|
|
27
27
|
mountedRef.current = false;
|
|
28
28
|
};
|
|
29
29
|
}, []);
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return;
|
|
34
|
-
let cancelled = false;
|
|
35
|
-
(async () => {
|
|
36
|
-
try {
|
|
37
|
-
const result = await getDeploymentStatus(input.targetId);
|
|
38
|
-
if (cancelled || !mountedRef.current)
|
|
39
|
-
return;
|
|
40
|
-
if (result && result.state !== 'Stopped') {
|
|
41
|
-
log.info(`mount recovery: "${input.targetId}" state=${result.state}, url=${result.url}`);
|
|
42
|
-
setStatus(result.state);
|
|
43
|
-
setUrl(result.url);
|
|
44
|
-
startPolling(input.targetId);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
catch {
|
|
48
|
-
// Server container may not be available (e.g., in tests)
|
|
49
|
-
log.debug(`mount recovery failed for "${input.targetId}" — ignoring`);
|
|
50
|
-
}
|
|
51
|
-
})();
|
|
52
|
-
return () => {
|
|
53
|
-
cancelled = true;
|
|
54
|
-
};
|
|
55
|
-
// Only run on mount (input identity is stable from the caller)
|
|
56
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
57
|
-
}, [input?.targetId]);
|
|
30
|
+
// Mount recovery removed — getGraphData() already enriches nodes with
|
|
31
|
+
// deployment status (get-graph-data.ts lines 180-200). No need to call
|
|
32
|
+
// a server action per node on every mount.
|
|
58
33
|
// Cleanup on unmount
|
|
59
34
|
useEffect(() => {
|
|
60
35
|
return () => {
|
|
@@ -108,32 +83,11 @@ export function useDeployAction(input) {
|
|
|
108
83
|
}
|
|
109
84
|
}, POLL_INTERVAL);
|
|
110
85
|
}, [stopPolling]);
|
|
111
|
-
// Idle poll —
|
|
112
|
-
//
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return;
|
|
117
|
-
const timer = setInterval(async () => {
|
|
118
|
-
if (!mountedRef.current)
|
|
119
|
-
return;
|
|
120
|
-
try {
|
|
121
|
-
const result = await getDeploymentStatus(input.targetId);
|
|
122
|
-
if (!mountedRef.current)
|
|
123
|
-
return;
|
|
124
|
-
if (result && result.state !== 'Stopped') {
|
|
125
|
-
log.info(`idle poll: "${input.targetId}" state=${result.state}, url=${result.url}`);
|
|
126
|
-
setStatus(result.state);
|
|
127
|
-
setUrl(result.url);
|
|
128
|
-
startPolling(input.targetId);
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
catch {
|
|
132
|
-
// ignore
|
|
133
|
-
}
|
|
134
|
-
}, IDLE_POLL_INTERVAL);
|
|
135
|
-
return () => clearInterval(timer);
|
|
136
|
-
}, [input, status, startPolling]);
|
|
86
|
+
// Idle poll removed — it was calling getDeploymentStatus every 5s for EVERY
|
|
87
|
+
// node on the canvas (~25 nodes = ~5 server action calls/sec). The mount
|
|
88
|
+
// recovery effect above (line 57) already checks on mount. Deployments
|
|
89
|
+
// started externally (e.g., from the drawer) should update the node via
|
|
90
|
+
// reconcile from the graph-data poll instead.
|
|
137
91
|
const handleDeploy = useCallback(async () => {
|
|
138
92
|
if (!input) {
|
|
139
93
|
log.warn('deploy() called but input is null — no-op');
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared session scanning logic used by both /api/sessions and /api/sessions-batch.
|
|
3
|
+
*
|
|
4
|
+
* Scans Claude Code and Cursor session directories for JSONL session files,
|
|
5
|
+
* parsing headers to extract preview, message count, and timestamps.
|
|
6
|
+
*/
|
|
7
|
+
export interface SessionResult {
|
|
8
|
+
id: string;
|
|
9
|
+
agentType: string;
|
|
10
|
+
preview: string | null;
|
|
11
|
+
messageCount: number;
|
|
12
|
+
firstMessageAt: string | null;
|
|
13
|
+
lastMessageAt: string | null;
|
|
14
|
+
createdAt: string | null;
|
|
15
|
+
projectPath: string;
|
|
16
|
+
filePath: string;
|
|
17
|
+
/** mtime for sorting — not sent to client */
|
|
18
|
+
_mtime: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function scanClaudeSessions(repositoryPath: string, limit: number, includeWorktrees?: boolean): Promise<SessionResult[]>;
|
|
21
|
+
export declare function scanCursorSessions(repositoryPath: string, limit: number): Promise<SessionResult[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Scan sessions for a single repository path from all providers.
|
|
24
|
+
* Merges and sorts by recency.
|
|
25
|
+
*/
|
|
26
|
+
export declare function scanSessionsForPath(repositoryPath: string, limit: number, includeWorktrees?: boolean): Promise<SessionResult[]>;
|
|
27
|
+
//# sourceMappingURL=session-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-scanner.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/session-scanner.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;CAChB;AAsID,wBAAsB,kBAAkB,CACtC,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,MAAM,EACb,gBAAgB,UAAQ,GACvB,OAAO,CAAC,aAAa,EAAE,CAAC,CA2C1B;AAiED,wBAAsB,kBAAkB,CACtC,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,aAAa,EAAE,CAAC,CA6D1B;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,cAAc,EAAE,MAAM,EACtB,KAAK,EAAE,MAAM,EACb,gBAAgB,UAAQ,GACvB,OAAO,CAAC,aAAa,EAAE,CAAC,CAS1B"}
|