@shepai/cli 1.138.0 → 1.139.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.
Files changed (151) hide show
  1. package/dist/src/presentation/web/components/common/feature-node/feature-node.d.ts.map +1 -1
  2. package/dist/src/presentation/web/components/common/feature-node/feature-node.js +8 -6
  3. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts +2 -0
  4. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.d.ts.map +1 -1
  5. package/dist/src/presentation/web/components/common/feature-node/feature-node.stories.js +61 -1
  6. package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts +0 -10
  7. package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts.map +1 -1
  8. package/dist/src/presentation/web/components/features/control-center/control-center.stories.js +273 -166
  9. package/dist/tsconfig.build.tsbuildinfo +1 -1
  10. package/package.json +1 -1
  11. package/web/.next/BUILD_ID +1 -1
  12. package/web/.next/build-manifest.json +2 -2
  13. package/web/.next/fallback-build-manifest.json +2 -2
  14. package/web/.next/prerender-manifest.json +3 -3
  15. package/web/.next/required-server-files.js +2 -2
  16. package/web/.next/required-server-files.json +2 -2
  17. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +28 -28
  18. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  19. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  20. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +28 -28
  21. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  22. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  23. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  24. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  25. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  26. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +36 -36
  27. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  28. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  29. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  30. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  31. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  32. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +28 -28
  33. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  34. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  35. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  36. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  37. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  38. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +36 -36
  39. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  40. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  41. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +26 -26
  42. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  43. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  44. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  45. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  46. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  47. package/web/.next/server/app/_global-error.html +2 -2
  48. package/web/.next/server/app/_global-error.rsc +1 -1
  49. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  50. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  51. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  52. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  53. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  54. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +3 -3
  55. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  56. package/web/.next/server/app/settings/page/server-reference-manifest.json +8 -8
  57. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  58. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  59. package/web/.next/server/app/skills/page/server-reference-manifest.json +8 -8
  60. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  61. package/web/.next/server/app/tools/page/server-reference-manifest.json +8 -8
  62. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  63. package/web/.next/server/app/version/page/server-reference-manifest.json +3 -3
  64. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  65. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  66. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  67. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  68. package/web/.next/server/chunks/ssr/[root-of-the-server]__2c703b78._.js +1 -1
  69. package/web/.next/server/chunks/ssr/[root-of-the-server]__2c703b78._.js.map +1 -1
  70. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  71. package/web/.next/server/chunks/ssr/[root-of-the-server]__3ef34e4c._.js +1 -1
  72. package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js +1 -1
  73. package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js.map +1 -1
  74. package/web/.next/server/chunks/ssr/[root-of-the-server]__59a3897b._.js +1 -1
  75. package/web/.next/server/chunks/ssr/[root-of-the-server]__59a3897b._.js.map +1 -1
  76. package/web/.next/server/chunks/ssr/[root-of-the-server]__78aecdd5._.js +1 -1
  77. package/web/.next/server/chunks/ssr/[root-of-the-server]__78aecdd5._.js.map +1 -1
  78. package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js +1 -1
  79. package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js.map +1 -1
  80. package/web/.next/server/chunks/ssr/[root-of-the-server]__a5f9c6e5._.js +2 -2
  81. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +2 -2
  82. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  83. package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js +1 -1
  84. package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js.map +1 -1
  85. package/web/.next/server/chunks/ssr/[root-of-the-server]__f222995d._.js +1 -1
  86. package/web/.next/server/chunks/ssr/[root-of-the-server]__f222995d._.js.map +1 -1
  87. package/web/.next/server/chunks/ssr/_02ec1aea._.js +1 -1
  88. package/web/.next/server/chunks/ssr/_02ec1aea._.js.map +1 -1
  89. package/web/.next/server/chunks/ssr/_0c5f56e3._.js +2 -2
  90. package/web/.next/server/chunks/ssr/_0c5f56e3._.js.map +1 -1
  91. package/web/.next/server/chunks/ssr/_1b719e7f._.js +1 -1
  92. package/web/.next/server/chunks/ssr/_1b719e7f._.js.map +1 -1
  93. package/web/.next/server/chunks/ssr/_37e8548b._.js +1 -1
  94. package/web/.next/server/chunks/ssr/_37e8548b._.js.map +1 -1
  95. package/web/.next/server/chunks/ssr/_55d763e2._.js +1 -1
  96. package/web/.next/server/chunks/ssr/_55d763e2._.js.map +1 -1
  97. package/web/.next/server/chunks/ssr/_64bdfc6f._.js +2 -2
  98. package/web/.next/server/chunks/ssr/_64bdfc6f._.js.map +1 -1
  99. package/web/.next/server/chunks/ssr/_7dca1882._.js +1 -1
  100. package/web/.next/server/chunks/ssr/_7dca1882._.js.map +1 -1
  101. package/web/.next/server/chunks/ssr/{_1c296899._.js → _a3a344a8._.js} +2 -2
  102. package/web/.next/server/chunks/ssr/{_1c296899._.js.map → _a3a344a8._.js.map} +1 -1
  103. package/web/.next/server/chunks/ssr/_a9f57758._.js +1 -1
  104. package/web/.next/server/chunks/ssr/_a9f57758._.js.map +1 -1
  105. package/web/.next/server/chunks/ssr/_b71645b4._.js +1 -1
  106. package/web/.next/server/chunks/ssr/_b71645b4._.js.map +1 -1
  107. package/web/.next/server/chunks/ssr/_d8575088._.js +1 -1
  108. package/web/.next/server/chunks/ssr/_d8575088._.js.map +1 -1
  109. package/web/.next/server/chunks/ssr/_ebd0ef7f._.js +3 -0
  110. package/web/.next/server/chunks/ssr/{_2119691d._.js.map → _ebd0ef7f._.js.map} +1 -1
  111. package/web/.next/server/chunks/ssr/_f39a1adb._.js +1 -1
  112. package/web/.next/server/chunks/ssr/_f39a1adb._.js.map +1 -1
  113. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  114. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  115. package/web/.next/server/chunks/ssr/src_presentation_web_582e5037._.js +3 -0
  116. package/web/.next/server/chunks/ssr/{src_presentation_web_844c9657._.js.map → src_presentation_web_582e5037._.js.map} +1 -1
  117. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js +1 -1
  118. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js.map +1 -1
  119. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js +1 -1
  120. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js.map +1 -1
  121. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  122. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  123. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  124. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  125. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  126. package/web/.next/server/pages/500.html +2 -2
  127. package/web/.next/server/server-reference-manifest.js +1 -1
  128. package/web/.next/server/server-reference-manifest.json +44 -44
  129. package/web/.next/static/chunks/{6c097d096a289e07.js → 13451dd1c5eb854a.js} +1 -1
  130. package/web/.next/static/chunks/{ec01c627aae92366.js → 1a46d832fb5dbb4d.js} +1 -1
  131. package/web/.next/static/chunks/{a2a9cfdc7ff45d62.js → 26f8c1dc8e8d3a85.js} +1 -1
  132. package/web/.next/static/chunks/284bdcf374b23190.js +1 -0
  133. package/web/.next/static/chunks/{c581e1010c5c217e.js → 2a318598dee02204.js} +1 -1
  134. package/web/.next/static/chunks/4d521e80c86070db.js +1 -0
  135. package/web/.next/static/chunks/{4c760047d0972f96.js → 5aac1b0e10edc3d4.js} +2 -2
  136. package/web/.next/static/chunks/7d4461c2f06d2cb9.js +1 -0
  137. package/web/.next/static/chunks/{ad74ee85368e7d04.js → 9d59552a1eb58b20.js} +1 -1
  138. package/web/.next/static/chunks/{f15f1f16948e7263.js → add583b93a6e62ef.js} +1 -1
  139. package/web/.next/static/chunks/ba967f7de77cd5ee.css +1 -0
  140. package/web/.next/static/chunks/c4c3d56eac00b6a3.js +2 -0
  141. package/web/.next/static/chunks/{2e9491b73bcb5948.js → d14b401b9ac6b439.js} +1 -1
  142. package/web/.next/server/chunks/ssr/_2119691d._.js +0 -3
  143. package/web/.next/server/chunks/ssr/src_presentation_web_844c9657._.js +0 -3
  144. package/web/.next/static/chunks/0e9ca746aadf6c8d.js +0 -1
  145. package/web/.next/static/chunks/3722a9f53d9069d1.js +0 -2
  146. package/web/.next/static/chunks/47ae402c9d3ad1ca.js +0 -1
  147. package/web/.next/static/chunks/ce8197531c98b4ea.js +0 -1
  148. package/web/.next/static/chunks/eb35e98c31806836.css +0 -1
  149. /package/web/.next/static/{0zlf5ntHpnR5YfkgEsA-1 → dDoTmkPtcr9knH6GiOhGo}/_buildManifest.js +0 -0
  150. /package/web/.next/static/{0zlf5ntHpnR5YfkgEsA-1 → dDoTmkPtcr9knH6GiOhGo}/_clientMiddlewareManifest.json +0 -0
  151. /package/web/.next/static/{0zlf5ntHpnR5YfkgEsA-1 → dDoTmkPtcr9knH6GiOhGo}/_ssgManifest.js +0 -0
@@ -3,6 +3,12 @@ import { ControlCenter } from './control-center.js';
3
3
  import { layoutWithDagre } from '../../../lib/layout-with-dagre.js';
4
4
  import { AgentEventsProvider } from '../../../hooks/agent-events-provider.js';
5
5
  import { DrawerCloseGuardProvider } from '../../../hooks/drawer-close-guard.js';
6
+ import { SidebarFeaturesProvider } from '../../../hooks/sidebar-features-context.js';
7
+ import { DeploymentState, PrStatus, CiStatus } from '../../../../../../packages/core/src/domain/generated/output.js';
8
+ // eslint-disable-next-line @typescript-eslint/no-empty-function -- storybook noop callbacks
9
+ const noop = () => { };
10
+ // eslint-disable-next-line @typescript-eslint/no-empty-function -- storybook noop callbacks
11
+ const noopId = (_id) => { };
6
12
  const meta = {
7
13
  title: 'Features/ControlCenter',
8
14
  component: ControlCenter,
@@ -11,238 +17,339 @@ const meta = {
11
17
  layout: 'fullscreen',
12
18
  },
13
19
  decorators: [
14
- (Story) => (_jsx(AgentEventsProvider, { children: _jsx(DrawerCloseGuardProvider, { children: _jsx("div", { style: { height: '100vh' }, children: _jsx(Story, {}) }) }) })),
20
+ (Story) => (_jsx(AgentEventsProvider, { children: _jsx(SidebarFeaturesProvider, { children: _jsx(DrawerCloseGuardProvider, { children: _jsx("div", { style: { height: '100vh' }, children: _jsx(Story, {}) }) }) }) })),
15
21
  ],
16
22
  };
17
23
  export default meta;
18
- const featureNodes = [
24
+ // ---------------------------------------------------------------------------
25
+ // Shared helpers
26
+ // ---------------------------------------------------------------------------
27
+ const dashedEdge = { style: { strokeDasharray: '5 5' } };
28
+ // ---------------------------------------------------------------------------
29
+ // FullSpectrum — realistic multi-repo workspace with every state represented
30
+ // ---------------------------------------------------------------------------
31
+ const fullSpectrumRepos = [
19
32
  {
20
- id: 'feat-1',
21
- type: 'featureNode',
22
- position: { x: 400, y: 0 },
23
- data: {
24
- name: 'Auth Module',
25
- description: 'OAuth2 authentication flow',
26
- featureId: '#f1',
27
- lifecycle: 'implementation',
28
- state: 'running',
29
- progress: 65,
30
- repositoryPath: '/home/user/my-repo',
31
- branch: 'feat/auth-module',
32
- },
33
+ id: 'repo-backend',
34
+ type: 'repositoryNode',
35
+ position: { x: 0, y: 0 },
36
+ data: { name: 'acme/backend' },
37
+ },
38
+ {
39
+ id: 'repo-frontend',
40
+ type: 'repositoryNode',
41
+ position: { x: 0, y: 0 },
42
+ data: { name: 'acme/frontend' },
33
43
  },
34
44
  {
35
- id: 'feat-2',
45
+ id: 'repo-infra',
46
+ type: 'repositoryNode',
47
+ position: { x: 0, y: 0 },
48
+ data: { name: 'acme/infra' },
49
+ },
50
+ ];
51
+ const fullSpectrumFeatures = [
52
+ // --- backend features ---
53
+ {
54
+ id: 'feat-payment',
36
55
  type: 'featureNode',
37
- position: { x: 400, y: 230 },
56
+ position: { x: 0, y: 0 },
38
57
  data: {
39
- name: 'User Dashboard',
40
- description: 'Main dashboard layout and widgets',
41
- featureId: '#f2',
42
- lifecycle: 'research',
58
+ name: 'Payment Processing',
59
+ description: 'Stripe integration with webhook handling, idempotency keys, and retry logic for failed charges',
60
+ featureId: 'e2c8d4',
61
+ lifecycle: 'requirements',
43
62
  state: 'action-required',
44
- progress: 20,
45
- repositoryPath: '/home/user/my-repo',
46
- branch: 'feat/user-dashboard',
63
+ progress: 15,
64
+ repositoryPath: '/home/user/acme/backend',
65
+ branch: 'feat/payment-processing',
66
+ agentType: 'claude-code',
67
+ startedAt: Date.now() - 12 * 60_000,
68
+ showHandles: true,
69
+ onDelete: noop,
70
+ onAction: noop,
71
+ hasAgentRun: true,
72
+ pr: undefined,
47
73
  },
48
74
  },
49
75
  {
50
- id: 'feat-3',
76
+ id: 'feat-graphql',
51
77
  type: 'featureNode',
52
- position: { x: 800, y: 115 },
78
+ position: { x: 0, y: 0 },
53
79
  data: {
54
- name: 'API Gateway',
55
- description: 'Rate limiting and routing',
56
- featureId: '#f3',
57
- lifecycle: 'deploy',
58
- state: 'done',
59
- progress: 100,
60
- repositoryPath: '/home/user/my-repo',
61
- branch: 'feat/api-gateway',
80
+ name: 'GraphQL API Layer',
81
+ description: 'Replace REST endpoints with GraphQL schema, resolvers, and client-side codegen for type-safe queries',
82
+ featureId: 'c4a6b8',
83
+ lifecycle: 'implementation',
84
+ state: 'running',
85
+ progress: 47,
86
+ repositoryPath: '/home/user/acme/backend',
87
+ branch: 'feat/graphql-api',
88
+ agentType: 'claude-code',
89
+ startedAt: Date.now() - 38 * 60_000,
90
+ showHandles: true,
91
+ onDelete: noop,
92
+ onAction: noop,
93
+ hasAgentRun: true,
94
+ hasPlan: true,
62
95
  },
63
96
  },
64
97
  {
65
- id: 'feat-4',
98
+ id: 'feat-rate-limiter',
66
99
  type: 'featureNode',
67
- position: { x: 800, y: 345 },
100
+ position: { x: 0, y: 0 },
68
101
  data: {
69
- name: 'Merge Review',
70
- description: 'PR ready for merge approval',
71
- featureId: '#f4',
102
+ name: 'Rate Limiter',
103
+ description: 'Sliding window rate limiting with Redis backing store and per-tenant quotas',
104
+ featureId: '3b5d7f',
72
105
  lifecycle: 'review',
73
106
  state: 'action-required',
74
- progress: 90,
75
- repositoryPath: '/home/user/my-repo',
76
- branch: 'feat/merge-review',
107
+ progress: 92,
108
+ repositoryPath: '/home/user/acme/backend',
109
+ branch: 'feat/rate-limiter',
110
+ agentType: 'claude-code',
111
+ showHandles: true,
112
+ onDelete: noop,
113
+ onAction: noop,
114
+ hasAgentRun: true,
115
+ hasPlan: true,
116
+ deployment: {
117
+ status: DeploymentState.Ready,
118
+ url: 'https://feat-rate-limiter.preview.acme.dev',
119
+ },
120
+ pr: {
121
+ url: 'https://github.com/acme/backend/pull/142',
122
+ number: 142,
123
+ status: PrStatus.Open,
124
+ ciStatus: CiStatus.Success,
125
+ mergeable: true,
126
+ },
77
127
  },
78
128
  },
79
- ];
80
- const repoNode = {
81
- id: 'repo-1',
82
- type: 'repositoryNode',
83
- position: { x: 50, y: 115 },
84
- data: { name: 'shep-ai/cli' },
85
- };
86
- const dashedEdge = { style: { strokeDasharray: '5 5' } };
87
- export const Empty = {
88
- args: {
89
- initialNodes: [],
90
- initialEdges: [],
91
- },
92
- };
93
- export const WithFeatures = {
94
- args: {
95
- initialNodes: featureNodes,
96
- initialEdges: [
97
- { id: 'e1-3', source: 'feat-1', target: 'feat-3' },
98
- { id: 'e2-3', source: 'feat-2', target: 'feat-3' },
99
- ],
100
- },
101
- };
102
- export const WithToolbar = {
103
- args: {
104
- initialNodes: [featureNodes[0], featureNodes[1]],
105
- initialEdges: [],
106
- },
107
- };
108
- export const WithNodeActions = {
109
- args: {
110
- initialNodes: [repoNode, ...featureNodes],
111
- initialEdges: [
112
- { id: 'e-repo-f1', source: 'repo-1', target: 'feat-1', ...dashedEdge },
113
- { id: 'e-repo-f2', source: 'repo-1', target: 'feat-2', ...dashedEdge },
114
- { id: 'e1-3', source: 'feat-1', target: 'feat-3' },
115
- ],
129
+ {
130
+ id: 'feat-webhooks',
131
+ type: 'featureNode',
132
+ position: { x: 0, y: 0 },
133
+ data: {
134
+ name: 'Webhook Delivery System',
135
+ description: 'Reliable webhook delivery with exponential backoff, dead letter queue, and delivery dashboard',
136
+ featureId: 'a1f3c9',
137
+ lifecycle: 'implementation',
138
+ state: 'blocked',
139
+ progress: 30,
140
+ blockedBy: 'GraphQL API Layer',
141
+ repositoryPath: '/home/user/acme/backend',
142
+ branch: 'feat/webhooks',
143
+ agentType: 'cursor',
144
+ showHandles: true,
145
+ onDelete: noop,
146
+ hasAgentRun: true,
147
+ hasPlan: true,
148
+ },
116
149
  },
117
- };
118
- // --- Dagre-layouted story: multiple repos with feature trees ---
119
- const dagreRepoNodes = [
120
150
  {
121
- id: 'repo-cli',
122
- type: 'repositoryNode',
151
+ id: 'feat-audit-log',
152
+ type: 'featureNode',
123
153
  position: { x: 0, y: 0 },
124
- data: { name: 'shep-ai/cli' },
154
+ data: {
155
+ name: 'Audit Log',
156
+ description: 'Immutable audit trail for all mutations with structured event schema and compliance export',
157
+ featureId: 'd8e2a1',
158
+ lifecycle: 'research',
159
+ state: 'running',
160
+ progress: 22,
161
+ repositoryPath: '/home/user/acme/backend',
162
+ branch: 'feat/audit-log',
163
+ agentType: 'gemini-cli',
164
+ startedAt: Date.now() - 5 * 60_000,
165
+ showHandles: true,
166
+ onDelete: noop,
167
+ onAction: noop,
168
+ hasAgentRun: true,
169
+ },
125
170
  },
171
+ // --- frontend features ---
126
172
  {
127
- id: 'repo-web',
128
- type: 'repositoryNode',
173
+ id: 'feat-dashboard',
174
+ type: 'featureNode',
129
175
  position: { x: 0, y: 0 },
130
- data: { name: 'shep-ai/web' },
176
+ data: {
177
+ name: 'User Dashboard',
178
+ description: 'Analytics dashboard with real-time charts, filterable data tables, and CSV export',
179
+ featureId: '5e7a9c',
180
+ lifecycle: 'maintain',
181
+ state: 'done',
182
+ progress: 100,
183
+ runtime: '2h 15m',
184
+ repositoryPath: '/home/user/acme/frontend',
185
+ branch: 'feat/user-dashboard',
186
+ agentType: 'claude-code',
187
+ showHandles: true,
188
+ onDelete: noop,
189
+ hasAgentRun: true,
190
+ hasPlan: true,
191
+ deployment: { status: DeploymentState.Ready, url: 'https://feat-dashboard.preview.acme.dev' },
192
+ pr: {
193
+ url: 'https://github.com/acme/frontend/pull/87',
194
+ number: 87,
195
+ status: PrStatus.Merged,
196
+ ciStatus: CiStatus.Success,
197
+ },
198
+ },
131
199
  },
132
- ];
133
- const dagreFeatureNodes = [
134
200
  {
135
- id: 'feat-auth',
201
+ id: 'feat-onboarding',
136
202
  type: 'featureNode',
137
203
  position: { x: 0, y: 0 },
138
204
  data: {
139
- name: 'Auth Module',
140
- description: 'OAuth2 authentication flow',
141
- featureId: '#f1',
205
+ name: 'Onboarding Flow',
206
+ description: 'Multi-step wizard with progress tracking, field validation, and email verification',
207
+ featureId: 'b4c6d2',
142
208
  lifecycle: 'implementation',
143
- state: 'running',
144
- progress: 65,
145
- repositoryPath: '/home/user/my-repo',
146
- branch: 'feat/auth-module',
209
+ state: 'error',
210
+ progress: 55,
211
+ errorMessage: 'Build failed: Cannot find module @acme/shared-ui',
212
+ repositoryPath: '/home/user/acme/frontend',
213
+ branch: 'feat/onboarding',
214
+ agentType: 'claude-code',
215
+ showHandles: true,
216
+ onDelete: noop,
217
+ onRetry: noopId,
218
+ hasAgentRun: true,
219
+ hasPlan: true,
147
220
  },
148
221
  },
149
222
  {
150
- id: 'feat-sso',
223
+ id: 'feat-notifications',
151
224
  type: 'featureNode',
152
225
  position: { x: 0, y: 0 },
153
226
  data: {
154
- name: 'SSO Integration',
155
- description: 'Single sign-on across services',
156
- featureId: '#f2',
157
- lifecycle: 'research',
158
- state: 'action-required',
159
- progress: 20,
160
- repositoryPath: '/home/user/my-repo',
161
- branch: 'feat/sso-integration',
227
+ name: 'Push Notifications',
228
+ description: 'Browser push notifications with service worker, permission prompts, and preference center',
229
+ featureId: 'f2a8e5',
230
+ lifecycle: 'pending',
231
+ state: 'pending',
232
+ progress: 0,
233
+ repositoryPath: '/home/user/acme/frontend',
234
+ branch: 'feat/push-notifications',
235
+ showHandles: true,
236
+ onDelete: noop,
237
+ onStart: noopId,
162
238
  },
163
239
  },
164
240
  {
165
- id: 'feat-dashboard',
241
+ id: 'feat-readme',
166
242
  type: 'featureNode',
167
243
  position: { x: 0, y: 0 },
168
244
  data: {
169
- name: 'User Dashboard',
170
- description: 'Main dashboard layout and widgets',
171
- featureId: '#f3',
172
- lifecycle: 'requirements',
173
- state: 'running',
174
- progress: 10,
175
- repositoryPath: '/home/user/my-repo',
176
- branch: 'feat/user-dashboard',
245
+ name: 'Update README',
246
+ description: 'Rewrite developer docs with setup guide, API reference, and architecture diagrams',
247
+ featureId: '1a3b5c',
248
+ lifecycle: 'maintain',
249
+ state: 'done',
250
+ progress: 100,
251
+ runtime: '8m',
252
+ repositoryPath: '/home/user/acme/frontend',
253
+ branch: 'feat/update-readme',
254
+ agentType: 'claude-code',
255
+ fastMode: true,
256
+ showHandles: true,
257
+ onDelete: noop,
258
+ hasAgentRun: true,
259
+ deployment: { status: DeploymentState.Ready, url: 'https://feat-readme.preview.acme.dev' },
260
+ pr: {
261
+ url: 'https://github.com/acme/frontend/pull/91',
262
+ number: 91,
263
+ status: PrStatus.Merged,
264
+ ciStatus: CiStatus.Success,
265
+ },
177
266
  },
178
267
  },
268
+ // --- infra features ---
179
269
  {
180
- id: 'feat-gateway',
270
+ id: 'feat-ci',
181
271
  type: 'featureNode',
182
272
  position: { x: 0, y: 0 },
183
273
  data: {
184
- name: 'API Gateway',
185
- description: 'Rate limiting and routing',
186
- featureId: '#f4',
187
- lifecycle: 'deploy',
274
+ name: 'CI Pipeline Setup',
275
+ description: 'GitHub Actions CI/CD with matrix builds, caching, and automatic preview deployments',
276
+ featureId: '7c9e1a',
277
+ lifecycle: 'maintain',
188
278
  state: 'done',
189
279
  progress: 100,
190
- repositoryPath: '/home/user/my-repo',
191
- branch: 'feat/api-gateway',
280
+ runtime: '45m',
281
+ repositoryPath: '/home/user/acme/infra',
282
+ branch: 'feat/ci-pipeline',
283
+ agentType: 'claude-code',
284
+ showHandles: true,
285
+ onDelete: noop,
286
+ hasAgentRun: true,
287
+ hasPlan: true,
288
+ pr: {
289
+ url: 'https://github.com/acme/infra/pull/34',
290
+ number: 34,
291
+ status: PrStatus.Merged,
292
+ ciStatus: CiStatus.Success,
293
+ },
192
294
  },
193
295
  },
194
296
  {
195
- id: 'feat-admin',
297
+ id: 'feat-terraform',
196
298
  type: 'featureNode',
197
299
  position: { x: 0, y: 0 },
198
300
  data: {
199
- name: 'Admin Panel',
200
- description: 'Internal admin tools',
201
- featureId: '#f5',
202
- lifecycle: 'review',
203
- state: 'blocked',
204
- progress: 40,
205
- blockedBy: 'API Gateway',
206
- repositoryPath: '/home/user/my-repo',
207
- branch: 'feat/admin-panel',
301
+ name: 'Terraform Modules',
302
+ description: 'Reusable Terraform modules for VPC, ECS, RDS, and ElastiCache with multi-region support',
303
+ featureId: '9d1f3b',
304
+ lifecycle: 'implementation',
305
+ state: 'running',
306
+ progress: 71,
307
+ repositoryPath: '/home/user/acme/infra',
308
+ branch: 'feat/terraform-modules',
309
+ agentType: 'aider',
310
+ startedAt: Date.now() - 22 * 60_000,
311
+ showHandles: true,
312
+ onDelete: noop,
313
+ onAction: noop,
314
+ hasAgentRun: true,
315
+ hasPlan: true,
316
+ deployment: { status: DeploymentState.Booting },
208
317
  },
209
318
  },
210
319
  ];
211
- const dagreNodesRaw = [...dagreRepoNodes, ...dagreFeatureNodes];
212
- const dagreEdges = [
213
- // cli repo Auth, SSO
214
- { id: 'e-cli-auth', source: 'repo-cli', target: 'feat-auth', style: { strokeDasharray: '5 5' } },
215
- { id: 'e-cli-sso', source: 'repo-cli', target: 'feat-sso', style: { strokeDasharray: '5 5' } },
216
- // web repo Dashboard, Admin
217
- {
218
- id: 'e-web-dash',
219
- source: 'repo-web',
220
- target: 'feat-dashboard',
221
- style: { strokeDasharray: '5 5' },
222
- },
223
- {
224
- id: 'e-web-admin',
225
- source: 'repo-web',
226
- target: 'feat-admin',
227
- style: { strokeDasharray: '5 5' },
228
- },
229
- // Feature dependencies: Auth → Gateway, SSO → Gateway, Gateway → Admin
230
- { id: 'e-auth-gw', source: 'feat-auth', target: 'feat-gateway' },
231
- { id: 'e-sso-gw', source: 'feat-sso', target: 'feat-gateway' },
232
- { id: 'e-gw-admin', source: 'feat-gateway', target: 'feat-admin' },
320
+ const fullSpectrumEdges = [
321
+ // repo feature edges
322
+ { id: 'e-be-payment', source: 'repo-backend', target: 'feat-payment', ...dashedEdge },
323
+ { id: 'e-be-graphql', source: 'repo-backend', target: 'feat-graphql', ...dashedEdge },
324
+ { id: 'e-be-rate', source: 'repo-backend', target: 'feat-rate-limiter', ...dashedEdge },
325
+ { id: 'e-be-webhooks', source: 'repo-backend', target: 'feat-webhooks', ...dashedEdge },
326
+ { id: 'e-be-audit', source: 'repo-backend', target: 'feat-audit-log', ...dashedEdge },
327
+ { id: 'e-fe-dash', source: 'repo-frontend', target: 'feat-dashboard', ...dashedEdge },
328
+ { id: 'e-fe-onboard', source: 'repo-frontend', target: 'feat-onboarding', ...dashedEdge },
329
+ { id: 'e-fe-notif', source: 'repo-frontend', target: 'feat-notifications', ...dashedEdge },
330
+ { id: 'e-fe-readme', source: 'repo-frontend', target: 'feat-readme', ...dashedEdge },
331
+ { id: 'e-infra-ci', source: 'repo-infra', target: 'feat-ci', ...dashedEdge },
332
+ { id: 'e-infra-tf', source: 'repo-infra', target: 'feat-terraform', ...dashedEdge },
333
+ // dependency edges
334
+ { id: 'e-graphql-webhooks', source: 'feat-graphql', target: 'feat-webhooks' },
335
+ { id: 'e-graphql-rate', source: 'feat-graphql', target: 'feat-rate-limiter' },
336
+ { id: 'e-payment-dashboard', source: 'feat-payment', target: 'feat-dashboard' },
337
+ { id: 'e-ci-terraform', source: 'feat-ci', target: 'feat-terraform' },
233
338
  ];
234
- const { nodes: dagreLayoutedNodes, edges: dagreLayoutedEdges } = layoutWithDagre(dagreNodesRaw, dagreEdges, { direction: 'LR' });
235
- /**
236
- * Dagre auto-layout story — two repositories with interconnected feature trees.
237
- *
238
- * Demonstrates the Vertical / Horizontal toolbar buttons that re-layout the graph.
239
- * Initial layout is LR (horizontal). Click "Vertical" to switch to TB, or
240
- * "Horizontal" to switch back.
241
- */
242
- export const DagreLayout = {
339
+ const { nodes: fullSpectrumNodes, edges: fullSpectrumLayoutedEdges } = layoutWithDagre([...fullSpectrumRepos, ...fullSpectrumFeatures], fullSpectrumEdges, { direction: 'LR' });
340
+ // ---------------------------------------------------------------------------
341
+ // Stories
342
+ // ---------------------------------------------------------------------------
343
+ export const Empty = {
344
+ args: {
345
+ initialNodes: [],
346
+ initialEdges: [],
347
+ },
348
+ };
349
+ export const WithFeatures = {
243
350
  args: {
244
- initialNodes: dagreLayoutedNodes,
245
- initialEdges: dagreLayoutedEdges,
351
+ initialNodes: fullSpectrumNodes,
352
+ initialEdges: fullSpectrumLayoutedEdges,
246
353
  },
247
354
  };
248
355
  // --- Archive toggle stories ---