@shepai/cli 1.113.0-pr309.76f9cf0 → 1.113.0-pr361.ed7b589
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-drawer-tabs/log-tab.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.js +2 -10
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.stories.d.ts +3 -5
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.stories.js +9 -92
- 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 +11 -1
- package/dist/src/presentation/web/hooks/use-viewport-persistence.d.ts +2 -0
- package/dist/src/presentation/web/hooks/use-viewport-persistence.d.ts.map +1 -1
- package/dist/src/presentation/web/hooks/use-viewport-persistence.js +9 -5
- package/dist/src/presentation/web/lib/layout-with-dagre.d.ts.map +1 -1
- package/dist/src/presentation/web/lib/layout-with-dagre.js +11 -2
- 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/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/(dashboard)/@drawer/create/page/server-reference-manifest.json +20 -20
- 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 +26 -26
- 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 +26 -26
- 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 +18 -18
- 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 +20 -20
- 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 +26 -26
- 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 +26 -26
- 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 +18 -18
- 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 +18 -18
- 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 +1 -1
- 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/cli-upgrade/route.js +2 -2
- package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
- package/web/.next/server/app/settings/page/server-reference-manifest.json +5 -5
- 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 +6 -6
- 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 +6 -6
- 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_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
- package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__d2c18946._.js +2 -2
- 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/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_a1104008.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_a1104008.js.map +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_92642200.js +1 -1
- package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_92642200.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__039967e3._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__039967e3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__07a39ff2._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__24dd0927._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2773312c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__2773312c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6367aea0._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__6367aea0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__89e8a5cc._.js +2 -2
- package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
- 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]__cbd8062c._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__cbd8062c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__d91fdd51._.js +3 -0
- package/web/.next/server/chunks/ssr/{[root-of-the-server]__b1e68e34._.js.map → [root-of-the-server]__d91fdd51._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e70c5627._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__e70c5627._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
- package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_897c57ac._.js → _6c52da30._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_897c57ac._.js.map → _6c52da30._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_a7ff3878._.js → _7a9d917c._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_a7ff3878._.js.map → _7a9d917c._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
- package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
- package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_39570a51._.js → _e4b4dd4b._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_39570a51._.js.map → _e4b4dd4b._.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__next-internal_server_app_(dashboard)_page_actions_888633e1.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_888633e1.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ca99d62d._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_ce7cbc3c._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_ce7cbc3c._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +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/chunks/ssr/src_presentation_web_e2604413._.js +2 -2
- package/web/.next/server/chunks/ssr/src_presentation_web_e2604413._.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 +31 -31
- package/web/.next/static/chunks/07b853e29af1e5f2.js +1 -0
- package/web/.next/static/chunks/178be4a9b9d51b47.js +1 -0
- package/web/.next/static/chunks/{5a546eda32b1b530.js → 592b616fd042c298.js} +1 -1
- package/web/.next/static/chunks/{8bfc1f72ce3f19b2.js → 5b1d3da9be6ced0b.js} +1 -1
- package/web/.next/static/chunks/694fc9a1173043d8.css +1 -0
- package/web/.next/static/chunks/{4e5c35d0e3aed631.js → 76af16a44b9b75d1.js} +1 -1
- package/web/.next/static/chunks/822bcf5757f9d8ba.js +2 -0
- package/web/.next/static/chunks/{83f10a2e368d785d.js → 9895b21d8cef7b75.js} +1 -1
- package/web/.next/static/chunks/{af35a042a950cfd6.js → bfbac0d053d899eb.js} +1 -1
- package/web/.next/static/chunks/{33b919cdde4468b2.js → f1127f107f719d88.js} +1 -1
- package/web/.next/static/chunks/{65454cdc30efb7f7.js → f7ad04843e26ef97.js} +2 -2
- package/web/.next/static/chunks/fb03f61a98bc0c1d.js +1 -0
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.d.ts +0 -5
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.js +0 -115
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.stories.d.ts +0 -18
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.stories.d.ts.map +0 -1
- package/dist/src/presentation/web/components/common/feature-drawer-tabs/event-log-viewer.stories.js +0 -88
- package/dist/src/presentation/web/lib/parse-log-line.d.ts +0 -49
- package/dist/src/presentation/web/lib/parse-log-line.d.ts.map +0 -1
- package/dist/src/presentation/web/lib/parse-log-line.js +0 -126
- package/web/.next/server/chunks/ssr/[root-of-the-server]__b1e68e34._.js +0 -3
- package/web/.next/static/chunks/57b45edf86522369.css +0 -1
- package/web/.next/static/chunks/b1f3c0e8e9872ef8.js +0 -1
- package/web/.next/static/chunks/dc5a2644d7805efa.js +0 -2
- package/web/.next/static/chunks/fb4a0a3574465a2e.js +0 -1
- package/web/.next/static/chunks/fe1bb1a0468200b6.js +0 -1
- /package/web/.next/static/{9jG0SOdIZ8g5fjjAGQhze → zSQaq5pEt-ygslhi_OFVS}/_buildManifest.js +0 -0
- /package/web/.next/static/{9jG0SOdIZ8g5fjjAGQhze → zSQaq5pEt-ygslhi_OFVS}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{9jG0SOdIZ8g5fjjAGQhze → zSQaq5pEt-ygslhi_OFVS}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/log-tab.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"log-tab.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/log-tab.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,wBAAgB,MAAM,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,EAAE,WAAW,2CA6ElE"}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useRef, useEffect, useState, useCallback } from 'react';
|
|
4
|
-
import { AlertCircle, Terminal, ArrowDown
|
|
5
|
-
import { EventLogViewer } from './event-log-viewer.js';
|
|
4
|
+
import { AlertCircle, Terminal, ArrowDown } from 'lucide-react';
|
|
6
5
|
export function LogTab({ content, isConnected, error }) {
|
|
7
6
|
const containerRef = useRef(null);
|
|
8
7
|
const [autoScroll, setAutoScroll] = useState(true);
|
|
9
|
-
const [viewMode, setViewMode] = useState('structured');
|
|
10
8
|
const handleScroll = useCallback(() => {
|
|
11
9
|
const el = containerRef.current;
|
|
12
10
|
if (!el)
|
|
@@ -33,11 +31,5 @@ export function LogTab({ content, isConnected, error }) {
|
|
|
33
31
|
if (!content) {
|
|
34
32
|
return (_jsxs("div", { className: "flex flex-col items-center justify-center gap-2 p-8", children: [_jsx(Terminal, { className: "text-muted-foreground h-8 w-8" }), _jsx("p", { className: "text-muted-foreground text-sm", children: "No log output yet" }), isConnected ? (_jsx("p", { className: "text-muted-foreground text-xs", children: "Waiting for log data..." })) : null] }));
|
|
35
33
|
}
|
|
36
|
-
return (_jsxs("div", { className: "flex h-full flex-col", "data-testid": "log-tab", children: [_jsxs("div", { className: "flex items-center gap-2 border-b px-3 py-1.5", children: [_jsx("span", { className: `h-2 w-2 rounded-full ${isConnected ? 'bg-emerald-500' : 'bg-zinc-400'}` }), _jsx("span", { className: "text-muted-foreground text-xs", children: isConnected ? 'Live' : 'Disconnected' }), _jsxs("
|
|
37
|
-
? 'bg-muted text-foreground'
|
|
38
|
-
: 'text-muted-foreground hover:text-foreground'}`, title: "Structured view", children: _jsx(FileText, { className: "h-3.5 w-3.5" }) }), _jsx("button", { type: "button", onClick: () => setViewMode('raw'), className: `rounded p-1 transition-colors ${viewMode === 'raw'
|
|
39
|
-
? 'bg-muted text-foreground'
|
|
40
|
-
: 'text-muted-foreground hover:text-foreground'}`, title: "Raw view", children: _jsx(Code, { className: "h-3.5 w-3.5" }) }), !autoScroll ? (_jsxs("button", { type: "button", onClick: jumpToBottom, className: "text-muted-foreground hover:text-foreground ml-1 flex items-center gap-1 text-xs", children: [_jsx(ArrowDown, { className: "h-3 w-3" }), "Jump to bottom"] })) : null] })] }), _jsx("div", { ref: containerRef, onScroll: handleScroll, className: `flex-1 overflow-y-auto ${viewMode === 'raw'
|
|
41
|
-
? 'bg-zinc-950 p-3 font-mono text-xs leading-relaxed break-all whitespace-pre-wrap text-zinc-300'
|
|
42
|
-
: 'bg-background'}`, children: viewMode === 'structured' ? _jsx(EventLogViewer, { content: content }) : content })] }));
|
|
34
|
+
return (_jsxs("div", { className: "flex h-full flex-col", "data-testid": "log-tab", children: [_jsxs("div", { className: "flex items-center gap-2 border-b px-3 py-1.5", children: [_jsx("span", { className: `h-2 w-2 rounded-full ${isConnected ? 'bg-emerald-500' : 'bg-zinc-400'}` }), _jsx("span", { className: "text-muted-foreground text-xs", children: isConnected ? 'Live' : 'Disconnected' }), !autoScroll ? (_jsxs("button", { type: "button", onClick: jumpToBottom, className: "text-muted-foreground hover:text-foreground ml-auto flex items-center gap-1 text-xs", children: [_jsx(ArrowDown, { className: "h-3 w-3" }), "Jump to bottom"] })) : null] }), _jsx("div", { ref: containerRef, onScroll: handleScroll, className: "flex-1 overflow-y-auto bg-zinc-950 p-3 font-mono text-xs leading-relaxed break-all whitespace-pre-wrap text-zinc-300", children: content })] }));
|
|
43
35
|
}
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.stories.d.ts
CHANGED
|
@@ -3,12 +3,10 @@ import { LogTab } from './log-tab.js';
|
|
|
3
3
|
declare const meta: Meta<typeof LogTab>;
|
|
4
4
|
export default meta;
|
|
5
5
|
type Story = StoryObj<typeof LogTab>;
|
|
6
|
-
/** Default —
|
|
6
|
+
/** Default — typical agent log output with live connection. */
|
|
7
7
|
export declare const Default: Story;
|
|
8
|
-
/**
|
|
9
|
-
export declare const
|
|
10
|
-
/** RawFallback — unstructured log content falls back gracefully. */
|
|
11
|
-
export declare const RawFallback: Story;
|
|
8
|
+
/** LongLog — 200 lines of log output to test scrolling behavior. */
|
|
9
|
+
export declare const LongLog: Story;
|
|
12
10
|
/** Disconnected — log content present but connection is lost. */
|
|
13
11
|
export declare const Disconnected: Story;
|
|
14
12
|
/** Empty — no log content yet, connected and waiting. */
|
package/dist/src/presentation/web/components/common/feature-drawer-tabs/log-tab.stories.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"log-tab.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/log-tab.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,MAAM,CAc7B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"log-tab.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-drawer-tabs/log-tab.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,MAAM,CAc7B,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,MAAM,CAAC,CAAC;AAqCrC,+DAA+D;AAC/D,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,oEAAoE;AACpE,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,iEAAiE;AACjE,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF,yDAAyD;AACzD,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,iBAAiB,EAAE,KAM/B,CAAC;AAEF,6DAA6D;AAC7D,eAAO,MAAM,KAAK,EAAE,KAMnB,CAAC"}
|
|
@@ -8,61 +8,14 @@ const meta = {
|
|
|
8
8
|
layout: 'fullscreen',
|
|
9
9
|
},
|
|
10
10
|
decorators: [
|
|
11
|
-
(Story) => (_jsx("div", { style: { height: '600px', width: '
|
|
11
|
+
(Story) => (_jsx("div", { style: { height: '600px', width: '400px', border: '1px solid var(--color-border)' }, children: _jsx(Story, {}) })),
|
|
12
12
|
],
|
|
13
13
|
};
|
|
14
14
|
export default meta;
|
|
15
15
|
/* ---------------------------------------------------------------------------
|
|
16
16
|
* Data fixtures
|
|
17
17
|
* ------------------------------------------------------------------------- */
|
|
18
|
-
const
|
|
19
|
-
[2026-03-08T10:00:01.001Z] [claude-code|claude-sonnet-4-6] [WORKER] feature-agent-worker --feature-id auth-module --run-id run-123 --repo /home/user/myproject --agent-type claude-code --model claude-sonnet-4-6
|
|
20
|
-
[2026-03-08T10:00:01.010Z] [claude-code|claude-sonnet-4-6] [WORKER] Initializing container...
|
|
21
|
-
[2026-03-08T10:00:01.050Z] [claude-code|claude-sonnet-4-6] [WORKER] Creating executor from pinned agent type: claude-code
|
|
22
|
-
[2026-03-08T10:00:01.100Z] [claude-code|claude-sonnet-4-6] [WORKER] Updating status to running (PID 54321)...
|
|
23
|
-
[2026-03-08T10:00:01.110Z] [claude-code|claude-sonnet-4-6] [WORKER] Starting graph invocation...
|
|
24
|
-
[2026-03-08T10:00:05.000Z] [requirements] [claude-code|claude-sonnet-4-6] Starting...
|
|
25
|
-
[2026-03-08T10:00:05.010Z] [requirements] [claude-code|claude-sonnet-4-6] Executing agent at cwd=/home/user/myproject
|
|
26
|
-
[2026-03-08T10:00:05.020Z] [requirements] [claude-code|claude-sonnet-4-6] Prompt length: 2847 chars
|
|
27
|
-
[2026-03-08T10:00:05.100Z] [requirements] [claude-code|claude-sonnet-4-6] Spawning: claude -p "Analyze this project..." --output-format stream-json --verbose
|
|
28
|
-
[2026-03-08T10:00:05.102Z] [requirements] [claude-code|claude-sonnet-4-6] Subprocess PID: 54322
|
|
29
|
-
[2026-03-08T10:00:08.234Z] [requirements] [claude-code|claude-sonnet-4-6] [tool] Read {"file_path": "src/main.ts"}
|
|
30
|
-
[2026-03-08T10:00:10.345Z] [requirements] [claude-code|claude-sonnet-4-6] [text] Analyzing the codebase structure and identifying key entry points for the authentication module
|
|
31
|
-
[2026-03-08T10:00:12.567Z] [requirements] [claude-code|claude-sonnet-4-6] [tool] Glob {"pattern": "src/**/*.ts"}
|
|
32
|
-
[2026-03-08T10:00:14.789Z] [requirements] [claude-code|claude-sonnet-4-6] [tool] Read {"file_path": "src/auth/providers.ts"}
|
|
33
|
-
[2026-03-08T10:00:16.012Z] [requirements] [claude-code|claude-sonnet-4-6] [tool] Grep {"pattern": "interface.*Auth", "path": "src/"}
|
|
34
|
-
[2026-03-08T10:00:18.234Z] [requirements] [claude-code|claude-sonnet-4-6] [text] The project uses a clean architecture pattern with dependency injection. I can see the auth interfaces are defined in the domain layer
|
|
35
|
-
[2026-03-08T10:00:20.456Z] [requirements] [claude-code|claude-sonnet-4-6] [tool] Bash {"command": "find src -name '*.test.ts' | wc -l"}
|
|
36
|
-
[2026-03-08T10:00:45.789Z] [requirements] [claude-code|claude-sonnet-4-6] [result] 8920 chars, session=sess-abc123def456
|
|
37
|
-
[2026-03-08T10:00:45.790Z] [requirements] [claude-code|claude-sonnet-4-6] [tokens] 2450 in / 4560 out
|
|
38
|
-
[2026-03-08T10:00:45.791Z] [requirements] [claude-code|claude-sonnet-4-6] Process closed with code 0, result=8920 chars
|
|
39
|
-
[2026-03-08T10:00:45.800Z] [requirements] [claude-code|claude-sonnet-4-6] Complete (8920 chars, 40.8s)
|
|
40
|
-
[2026-03-08T10:00:45.900Z] [requirements] [claude-code|claude-sonnet-4-6] Interrupting for human approval
|
|
41
|
-
[2026-03-08T10:02:30.000Z] [requirements] [claude-code|claude-sonnet-4-6] Phase approved, skipping re-execution
|
|
42
|
-
[2026-03-08T10:02:30.100Z] [plan] [claude-code|claude-sonnet-4-6] Starting...
|
|
43
|
-
[2026-03-08T10:02:30.110Z] [plan] [claude-code|claude-sonnet-4-6] Executing agent at cwd=/home/user/myproject
|
|
44
|
-
[2026-03-08T10:02:30.120Z] [plan] [claude-code|claude-sonnet-4-6] Prompt length: 15234 chars
|
|
45
|
-
[2026-03-08T10:02:35.100Z] [plan] [claude-code|claude-sonnet-4-6] [tool] Read {"file_path": "CLAUDE.md"}
|
|
46
|
-
[2026-03-08T10:02:38.200Z] [plan] [claude-code|claude-sonnet-4-6] [text] Creating implementation plan with TDD approach as required by project conventions
|
|
47
|
-
[2026-03-08T10:02:42.300Z] [plan] [claude-code|claude-sonnet-4-6] [tool] Write {"file_path": "specs/001-auth/plan.yaml"}
|
|
48
|
-
[2026-03-08T10:02:45.400Z] [plan] [claude-code|claude-sonnet-4-6] [text] Plan includes 3 phases: scaffold auth module, implement OAuth2 providers, add tests and documentation
|
|
49
|
-
[2026-03-08T10:03:15.234Z] [plan] [claude-code|claude-sonnet-4-6] [result] 12345 chars, session=sess-abc123def456
|
|
50
|
-
[2026-03-08T10:03:15.235Z] [plan] [claude-code|claude-sonnet-4-6] [tokens] 8900 in / 3456 out
|
|
51
|
-
[2026-03-08T10:03:15.300Z] [plan] [claude-code|claude-sonnet-4-6] Complete (12345 chars, 45.1s)
|
|
52
|
-
[2026-03-08T10:05:00.000Z] [implement] [claude-code|claude-sonnet-4-6] Starting...
|
|
53
|
-
[2026-03-08T10:05:01.000Z] [implement] [claude-code|claude-sonnet-4-6] [tool] Write {"file_path": "src/auth/oauth-provider.ts"}
|
|
54
|
-
[2026-03-08T10:05:03.000Z] [implement] [claude-code|claude-sonnet-4-6] [tool] Write {"file_path": "src/auth/token-manager.ts"}
|
|
55
|
-
[2026-03-08T10:05:05.000Z] [implement] [claude-code|claude-sonnet-4-6] [tool] Edit {"file_path": "src/auth/index.ts"}
|
|
56
|
-
[2026-03-08T10:05:07.000Z] [implement] [claude-code|claude-sonnet-4-6] [tool] Bash {"command": "pnpm test:unit"}
|
|
57
|
-
[2026-03-08T10:05:30.000Z] [implement] [claude-code|claude-sonnet-4-6] [text] All 14 unit tests passing. Moving to integration tests
|
|
58
|
-
[2026-03-08T10:05:35.000Z] [implement] [claude-code|claude-sonnet-4-6] [tool] Bash {"command": "pnpm test:int"}
|
|
59
|
-
[2026-03-08T10:05:55.000Z] [implement] [claude-code|claude-sonnet-4-6] [result] 24560 chars, session=sess-abc123def456
|
|
60
|
-
[2026-03-08T10:05:55.001Z] [implement] [claude-code|claude-sonnet-4-6] [tokens] 15200 in / 9360 out
|
|
61
|
-
[2026-03-08T10:05:55.100Z] [implement] [claude-code|claude-sonnet-4-6] Complete (24560 chars, 54.1s)
|
|
62
|
-
[2026-03-08T10:06:00.000Z] [claude-code|claude-sonnet-4-6] [WORKER] Graph invocation completed. Error: none
|
|
63
|
-
[2026-03-08T10:06:00.100Z] [claude-code|claude-sonnet-4-6] [WORKER] Run marked as completed
|
|
64
|
-
[2026-03-08T10:06:00.200Z] [claude-code|claude-sonnet-4-6] [WORKER] Worker completed successfully, exiting.`;
|
|
65
|
-
const rawLogContent = `[2026-03-08T10:00:01.123Z] Starting agent run for feature "auth-module"
|
|
18
|
+
const typicalLogContent = `[2026-03-08T10:00:01.123Z] Starting agent run for feature "auth-module"
|
|
66
19
|
[2026-03-08T10:00:02.789Z] Agent started — analyzing codebase
|
|
67
20
|
[2026-03-08T10:00:03.456Z] Scanning repository structure...
|
|
68
21
|
[2026-03-08T10:00:04.012Z] Found 127 source files across 14 packages
|
|
@@ -82,58 +35,22 @@ const rawLogContent = `[2026-03-08T10:00:01.123Z] Starting agent run for feature
|
|
|
82
35
|
[2026-03-08T10:00:24.789Z] Phase 3: add tests and documentation
|
|
83
36
|
[2026-03-08T10:00:26.456Z] Generating test suite...
|
|
84
37
|
[2026-03-08T10:00:28.012Z] All phases complete — feature "auth-module" ready for review`;
|
|
85
|
-
const
|
|
86
|
-
const min = String(Math.floor(i / 60)).padStart(2, '0');
|
|
87
|
-
const sec = String(i % 60).padStart(2, '0');
|
|
88
|
-
const ms = String((i * 7) % 1000).padStart(3, '0');
|
|
89
|
-
const ts = `2026-03-08T10:${min}:${sec}.${ms}Z`;
|
|
90
|
-
const phase = ['requirements', 'research', 'plan', 'implement'][i % 4];
|
|
91
|
-
const tags = ['[tool]', '[text]', '[tool]', '[text]', '[result]', '[tokens]'];
|
|
92
|
-
const tag = tags[i % tags.length];
|
|
93
|
-
const messages = {
|
|
94
|
-
'[tool]': [
|
|
95
|
-
'Read {"file_path": "src/components/button.tsx"}',
|
|
96
|
-
'Bash {"command": "pnpm test:unit"}',
|
|
97
|
-
'Grep {"pattern": "export function", "path": "src/"}',
|
|
98
|
-
'Write {"file_path": "src/new-file.ts"}',
|
|
99
|
-
'Glob {"pattern": "**/*.test.ts"}',
|
|
100
|
-
],
|
|
101
|
-
'[text]': [
|
|
102
|
-
'Analyzing the component structure for potential improvements',
|
|
103
|
-
'The test suite is comprehensive with good coverage',
|
|
104
|
-
'Implementing the authentication flow with OAuth2 providers',
|
|
105
|
-
'Refactoring to use dependency injection pattern',
|
|
106
|
-
],
|
|
107
|
-
'[result]': ['4520 chars, session=sess-xyz789'],
|
|
108
|
-
'[tokens]': ['3200 in / 1800 out'],
|
|
109
|
-
};
|
|
110
|
-
const msgList = messages[tag] ?? messages['[text]'];
|
|
111
|
-
const msg = msgList[i % msgList.length];
|
|
112
|
-
return `[${ts}] [${phase}] [claude-code|claude-sonnet-4-6] ${tag} ${msg}`;
|
|
113
|
-
}).join('\n');
|
|
38
|
+
const longLogContent = Array.from({ length: 200 }, (_, i) => `[2026-03-08T10:${String(Math.floor(i / 60)).padStart(2, '0')}:${String(i % 60).padStart(2, '0')}.${String((i * 7) % 1000).padStart(3, '0')}Z] Step ${i + 1}: processing task batch ${Math.floor(i / 10) + 1} — file ${i + 1} of 200`).join('\n');
|
|
114
39
|
/* ---------------------------------------------------------------------------
|
|
115
40
|
* Stories
|
|
116
41
|
* ------------------------------------------------------------------------- */
|
|
117
|
-
/** Default —
|
|
42
|
+
/** Default — typical agent log output with live connection. */
|
|
118
43
|
export const Default = {
|
|
119
44
|
args: {
|
|
120
|
-
content:
|
|
45
|
+
content: typicalLogContent,
|
|
121
46
|
isConnected: true,
|
|
122
47
|
error: null,
|
|
123
48
|
},
|
|
124
49
|
};
|
|
125
|
-
/**
|
|
126
|
-
export const
|
|
50
|
+
/** LongLog — 200 lines of log output to test scrolling behavior. */
|
|
51
|
+
export const LongLog = {
|
|
127
52
|
args: {
|
|
128
|
-
content:
|
|
129
|
-
isConnected: true,
|
|
130
|
-
error: null,
|
|
131
|
-
},
|
|
132
|
-
};
|
|
133
|
-
/** RawFallback — unstructured log content falls back gracefully. */
|
|
134
|
-
export const RawFallback = {
|
|
135
|
-
args: {
|
|
136
|
-
content: rawLogContent,
|
|
53
|
+
content: longLogContent,
|
|
137
54
|
isConnected: true,
|
|
138
55
|
error: null,
|
|
139
56
|
},
|
|
@@ -141,7 +58,7 @@ export const RawFallback = {
|
|
|
141
58
|
/** Disconnected — log content present but connection is lost. */
|
|
142
59
|
export const Disconnected = {
|
|
143
60
|
args: {
|
|
144
|
-
content:
|
|
61
|
+
content: typicalLogContent,
|
|
145
62
|
isConnected: false,
|
|
146
63
|
error: null,
|
|
147
64
|
},
|
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;AAGpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAuB5E,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;AAGpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAuB5E,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,2CAgVzF"}
|
package/dist/src/presentation/web/components/features/control-center/control-center-inner.js
CHANGED
|
@@ -25,7 +25,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
25
25
|
const { guardedNavigate } = useDrawerCloseGuard();
|
|
26
26
|
const { fitView } = useReactFlow();
|
|
27
27
|
const drawerTimerRef = useRef(null);
|
|
28
|
-
const { defaultViewport, onMoveEnd: handleViewportChange, resetViewport, } = useViewportPersistence();
|
|
28
|
+
const { defaultViewport, hasSavedViewport, onMoveEnd: handleViewportChange, resetViewport, } = useViewportPersistence();
|
|
29
29
|
const { nodes, edges, onNodesChange, handleConnect, handleAddRepository, handleDeleteFeature, handleRetryFeature, handleDeleteRepository, createFeatureNode, setCallbacks, } = useControlCenterState(initialNodes, initialEdges);
|
|
30
30
|
// Publish sidebar features to context whenever feature node data changes
|
|
31
31
|
const { setFeatures: setSidebarFeatures } = useSidebarFeaturesContext();
|
|
@@ -204,6 +204,16 @@ export function ControlCenterInner({ initialNodes, initialEdges }) {
|
|
|
204
204
|
handleRepositoryClick,
|
|
205
205
|
handleDeleteRepository,
|
|
206
206
|
]);
|
|
207
|
+
// Auto-center on initial load when there's no saved viewport and nodes exist.
|
|
208
|
+
// This ensures the first repo is visible instead of being stuck in the top-left corner.
|
|
209
|
+
const didInitialFitRef = useRef(false);
|
|
210
|
+
useEffect(() => {
|
|
211
|
+
if (didInitialFitRef.current || hasSavedViewport || nodes.length === 0)
|
|
212
|
+
return;
|
|
213
|
+
didInitialFitRef.current = true;
|
|
214
|
+
// Yield to React so nodes are rendered in the DOM before fitView calculates bounds.
|
|
215
|
+
setTimeout(() => fitView(AUTO_FOCUS_OPTIONS), 0);
|
|
216
|
+
}, [hasSavedViewport, nodes.length, fitView]);
|
|
207
217
|
const handleMoveEnd = useCallback((_event, viewport) => {
|
|
208
218
|
handleViewportChange(viewport);
|
|
209
219
|
}, [handleViewportChange]);
|
|
@@ -5,6 +5,8 @@ export declare const DEBOUNCE_MS = 500;
|
|
|
5
5
|
export declare const DEFAULT_VIEWPORT: Viewport;
|
|
6
6
|
export interface UseViewportPersistenceResult {
|
|
7
7
|
defaultViewport: Viewport;
|
|
8
|
+
/** True when a valid viewport was restored from localStorage. */
|
|
9
|
+
hasSavedViewport: boolean;
|
|
8
10
|
onMoveEnd: (viewport: Viewport) => void;
|
|
9
11
|
resetViewport: () => Viewport;
|
|
10
12
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-viewport-persistence.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-viewport-persistence.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,eAAO,MAAM,WAAW,yBAAyB,CAAC;AAClD,eAAO,MAAM,WAAW,MAAM,CAAC;AAE/B,eAAO,MAAM,gBAAgB,EAAE,QAAuC,CAAC;AAEvE,MAAM,WAAW,4BAA4B;IAC3C,eAAe,EAAE,QAAQ,CAAC;IAC1B,SAAS,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACxC,aAAa,EAAE,MAAM,QAAQ,CAAC;CAC/B;
|
|
1
|
+
{"version":3,"file":"use-viewport-persistence.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/hooks/use-viewport-persistence.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAE9C,eAAO,MAAM,WAAW,yBAAyB,CAAC;AAClD,eAAO,MAAM,WAAW,MAAM,CAAC;AAE/B,eAAO,MAAM,gBAAgB,EAAE,QAAuC,CAAC;AAEvE,MAAM,WAAW,4BAA4B;IAC3C,eAAe,EAAE,QAAQ,CAAC;IAC1B,iEAAiE;IACjE,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACxC,aAAa,EAAE,MAAM,QAAQ,CAAC;CAC/B;AA8BD,wBAAgB,sBAAsB,IAAI,4BAA4B,CAqCrE"}
|
|
@@ -20,16 +20,20 @@ function readViewport() {
|
|
|
20
20
|
try {
|
|
21
21
|
const raw = localStorage.getItem(STORAGE_KEY);
|
|
22
22
|
if (raw == null)
|
|
23
|
-
return DEFAULT_VIEWPORT;
|
|
23
|
+
return { viewport: DEFAULT_VIEWPORT, fromStorage: false };
|
|
24
24
|
const parsed = JSON.parse(raw);
|
|
25
|
-
|
|
25
|
+
if (isValidViewport(parsed))
|
|
26
|
+
return { viewport: parsed, fromStorage: true };
|
|
27
|
+
return { viewport: DEFAULT_VIEWPORT, fromStorage: false };
|
|
26
28
|
}
|
|
27
29
|
catch {
|
|
28
|
-
return DEFAULT_VIEWPORT;
|
|
30
|
+
return { viewport: DEFAULT_VIEWPORT, fromStorage: false };
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
33
|
export function useViewportPersistence() {
|
|
32
|
-
const
|
|
34
|
+
const stored = useRef(readViewport()).current;
|
|
35
|
+
const defaultViewport = stored.viewport;
|
|
36
|
+
const hasSavedViewport = stored.fromStorage;
|
|
33
37
|
const timerRef = useRef(null);
|
|
34
38
|
useEffect(() => {
|
|
35
39
|
return () => {
|
|
@@ -60,5 +64,5 @@ export function useViewportPersistence() {
|
|
|
60
64
|
}
|
|
61
65
|
return DEFAULT_VIEWPORT;
|
|
62
66
|
}, []);
|
|
63
|
-
return { defaultViewport, onMoveEnd, resetViewport };
|
|
67
|
+
return { defaultViewport, hasSavedViewport, onMoveEnd, resetViewport };
|
|
64
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layout-with-dagre.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/layout-with-dagre.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+DAA+D;AAC/D,eAAO,MAAM,sBAAsB,EAAE,aAIpC,CAAC;AAkCF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,IAAI,EAC5C,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,IAAI,EAAE,EACb,IAAI,GAAE,aAAkB,GACvB;IAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"layout-with-dagre.d.ts","sourceRoot":"","sources":["../../../../../src/presentation/web/lib/layout-with-dagre.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhD,MAAM,MAAM,eAAe,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,iEAAiE;IACjE,SAAS,CAAC,EAAE,eAAe,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,qDAAqD;IACrD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+DAA+D;AAC/D,eAAO,MAAM,sBAAsB,EAAE,aAIpC,CAAC;AAkCF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,IAAI,EAC5C,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,IAAI,EAAE,EACb,IAAI,GAAE,aAAkB,GACvB;IAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CA8L/B"}
|
|
@@ -78,6 +78,10 @@ export function layoutWithDagre(nodes, edges, opts = {}) {
|
|
|
78
78
|
// Add disconnected nodes to centerMap so they participate in root positioning.
|
|
79
79
|
// Use the same primary-axis position as connected roots (rank 0) so they align
|
|
80
80
|
// visually with repos that have features attached.
|
|
81
|
+
// When there are NO connected nodes (e.g. repos with no features), use half the
|
|
82
|
+
// node's own dimension so the leading edge sits at the canvas origin — preventing
|
|
83
|
+
// nodes from rendering off-screen with the default viewport.
|
|
84
|
+
const hasCenterMap = centerMap.size > 0;
|
|
81
85
|
let rootPrimaryAxis = 0;
|
|
82
86
|
for (const c of centerMap.values()) {
|
|
83
87
|
rootPrimaryAxis = isHorizontal ? c.cx : c.cy;
|
|
@@ -85,9 +89,14 @@ export function layoutWithDagre(nodes, edges, opts = {}) {
|
|
|
85
89
|
}
|
|
86
90
|
for (const node of disconnectedNodes) {
|
|
87
91
|
const size = getNodeSize(node, nodeSize);
|
|
92
|
+
const primaryAxisCenter = hasCenterMap
|
|
93
|
+
? rootPrimaryAxis
|
|
94
|
+
: isHorizontal
|
|
95
|
+
? size.width / 2
|
|
96
|
+
: size.height / 2;
|
|
88
97
|
centerMap.set(node.id, {
|
|
89
|
-
cx: isHorizontal ?
|
|
90
|
-
cy: isHorizontal ? 0 :
|
|
98
|
+
cx: isHorizontal ? primaryAxisCenter : 0,
|
|
99
|
+
cy: isHorizontal ? 0 : primaryAxisCenter,
|
|
91
100
|
w: size.width,
|
|
92
101
|
h: size.height,
|
|
93
102
|
});
|