claudedesk 4.3.1 → 4.4.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 (124) hide show
  1. package/.github/workflows/ci.yml +44 -2
  2. package/CLAUDE.md +36 -3
  3. package/PHASE_1_IMPLEMENTATION.md +313 -0
  4. package/PHASE_2_PARTIAL_IMPLEMENTATION.md +286 -0
  5. package/dist/main/cli-manager.js +67 -2
  6. package/dist/main/command-registry.js +196 -0
  7. package/dist/main/git-manager.js +841 -0
  8. package/dist/main/index.js +25 -1
  9. package/dist/main/ipc-handlers.js +347 -3
  10. package/dist/main/layout-presets-manager.js +233 -0
  11. package/dist/main/model-history-manager.js +187 -0
  12. package/dist/main/session-manager.js +83 -26
  13. package/dist/main/session-persistence.js +1 -0
  14. package/dist/main/session-pool.js +40 -9
  15. package/dist/main/settings-persistence.js +67 -12
  16. package/dist/renderer/assets/index-BNeYLqV4.css +32 -0
  17. package/dist/renderer/assets/index-D5O5Ljoo.js +17189 -0
  18. package/dist/renderer/index.html +2 -2
  19. package/dist/shared/ipc-contract.js +79 -0
  20. package/dist/shared/model-detector.js +83 -0
  21. package/dist/shared/types/command-types.js +5 -0
  22. package/dist/shared/types/git-types.js +2 -0
  23. package/dist/types/layout-presets.js +11 -0
  24. package/docs/git-integration-implementation-tasks.md +974 -0
  25. package/docs/git-integration-product-spec.md +916 -0
  26. package/docs/git-integration-ui-spec.md +1464 -0
  27. package/docs/repo-index.md +83 -8
  28. package/e2e/app-launch.spec.ts +31 -0
  29. package/e2e/fixtures/electron.ts +34 -0
  30. package/e2e/keyboard-shortcuts.spec.ts +50 -0
  31. package/e2e/session.spec.ts +34 -0
  32. package/e2e/split-view.spec.ts +21 -0
  33. package/package.json +16 -3
  34. package/playwright.config.ts +15 -0
  35. package/src/main/cli-manager.ts +74 -3
  36. package/src/main/command-registry.ts +221 -0
  37. package/src/main/git-manager.test.ts +374 -0
  38. package/src/main/git-manager.ts +909 -0
  39. package/src/main/index.ts +31 -1
  40. package/src/main/ipc-emitter.test.ts +60 -0
  41. package/src/main/ipc-handlers.ts +295 -3
  42. package/src/main/ipc-registry.test.ts +75 -0
  43. package/src/main/layout-presets-manager.ts +268 -0
  44. package/src/main/model-history-manager.ts +196 -0
  45. package/src/main/session-manager.ts +102 -30
  46. package/src/main/session-persistence.test.ts +215 -0
  47. package/src/main/session-persistence.ts +1 -0
  48. package/src/main/session-pool.ts +31 -9
  49. package/src/main/settings-persistence.ts +74 -12
  50. package/src/renderer/App.tsx +215 -43
  51. package/src/renderer/components/CustomLayoutBuilder.tsx +143 -0
  52. package/src/renderer/components/GitPanel.test.tsx +181 -0
  53. package/src/renderer/components/GitPanel.tsx +1407 -0
  54. package/src/renderer/components/LayoutPicker.tsx +182 -0
  55. package/src/renderer/components/LayoutPreviewCard.tsx +175 -0
  56. package/src/renderer/components/ModelHistoryPanel.tsx +435 -0
  57. package/src/renderer/components/PaneHeader.test.tsx +96 -0
  58. package/src/renderer/components/PaneHeader.tsx +28 -0
  59. package/src/renderer/components/SplitLayout.test.tsx +153 -0
  60. package/src/renderer/components/SplitLayout.tsx +36 -1
  61. package/src/renderer/components/Terminal.tsx +10 -10
  62. package/src/renderer/components/WelcomeWizard.tsx +143 -0
  63. package/src/renderer/components/WizardStepper.tsx +135 -0
  64. package/src/renderer/components/ui/ClaudeReadinessProgress.tsx +168 -0
  65. package/src/renderer/components/ui/CommitDialog.test.tsx +134 -0
  66. package/src/renderer/components/ui/CommitDialog.tsx +464 -0
  67. package/src/renderer/components/ui/EmptyState.test.tsx +87 -0
  68. package/src/renderer/components/ui/EmptyState.tsx +115 -86
  69. package/src/renderer/components/ui/FeatureShowcase.tsx +187 -0
  70. package/src/renderer/components/ui/FuelGaugeBar.tsx +59 -0
  71. package/src/renderer/components/ui/FuelStatusIndicator.tsx +358 -0
  72. package/src/renderer/components/ui/FuelTooltip.tsx +267 -0
  73. package/src/renderer/components/ui/HelpButton.tsx +43 -0
  74. package/src/renderer/components/ui/ModelBadge.tsx +72 -0
  75. package/src/renderer/components/ui/ModelSwitcher.tsx +180 -0
  76. package/src/renderer/components/ui/PanelFooter.tsx +90 -0
  77. package/src/renderer/components/ui/PanelHeader.tsx +87 -0
  78. package/src/renderer/components/ui/PanelHelpOverlay.tsx +274 -0
  79. package/src/renderer/components/ui/QuickActionCard.tsx +103 -0
  80. package/src/renderer/components/ui/RecentSessionsList.tsx +154 -0
  81. package/src/renderer/components/ui/SessionStatusIndicator.tsx +104 -0
  82. package/src/renderer/components/ui/SettingsDialog.tsx +94 -0
  83. package/src/renderer/components/ui/ShortcutsPanel.tsx +433 -0
  84. package/src/renderer/components/ui/StatusPopover.tsx +344 -0
  85. package/src/renderer/components/ui/TabBar.test.tsx +124 -0
  86. package/src/renderer/components/ui/TabBar.tsx +152 -168
  87. package/src/renderer/components/ui/ToolbarDropdown.tsx +227 -0
  88. package/src/renderer/components/ui/ToolsDropdown.tsx +119 -0
  89. package/src/renderer/components/ui/TooltipCoach.tsx +217 -0
  90. package/src/renderer/components/ui/WelcomeHero.tsx +85 -0
  91. package/src/renderer/components/ui/index.ts +5 -0
  92. package/src/renderer/components/wizard/Step1_Welcome.tsx +166 -0
  93. package/src/renderer/components/wizard/Step2_LayoutPicker.tsx +246 -0
  94. package/src/renderer/components/wizard/Step3_Features.tsx +278 -0
  95. package/src/renderer/components/wizard/Step4_Ready.tsx +279 -0
  96. package/src/renderer/hooks/useGit.test.ts +140 -0
  97. package/src/renderer/hooks/useGit.ts +395 -0
  98. package/src/renderer/hooks/useLayoutPicker.ts +77 -0
  99. package/src/renderer/hooks/useModelHistory.ts +69 -0
  100. package/src/renderer/hooks/useSessionManager.test.ts +146 -0
  101. package/src/renderer/hooks/useSessionManager.ts +5 -0
  102. package/src/renderer/hooks/useSplitView.test.ts +168 -0
  103. package/src/renderer/hooks/useSplitView.ts +126 -128
  104. package/src/renderer/styles/globals.css +505 -0
  105. package/src/renderer/utils/fuzzy-search.test.ts +121 -0
  106. package/src/renderer/utils/layout-tree.test.ts +310 -0
  107. package/src/renderer/utils/layout-tree.ts +170 -0
  108. package/src/renderer/utils/variable-resolver.test.ts +102 -0
  109. package/src/shared/ipc-contract.ts +157 -0
  110. package/src/shared/ipc-types.ts +52 -1
  111. package/src/shared/message-parser.test.ts +79 -0
  112. package/src/shared/model-detector.test.ts +90 -0
  113. package/src/shared/model-detector.ts +97 -0
  114. package/src/shared/types/command-types.ts +26 -0
  115. package/src/shared/types/git-types.ts +126 -0
  116. package/src/types/layout-presets.ts +22 -0
  117. package/test/helpers/electron-api-mock.ts +52 -0
  118. package/test/setup-main.ts +61 -0
  119. package/test/setup-renderer.ts +8 -0
  120. package/tsconfig.json +1 -0
  121. package/tsconfig.main.json +2 -1
  122. package/vitest.workspace.ts +37 -0
  123. package/dist/renderer/assets/index-CR22a7j2.css +0 -32
  124. package/dist/renderer/assets/index-Dp-eceNq.js +0 -13915
@@ -0,0 +1,119 @@
1
+ import { ToolbarDropdown, DropdownItem } from './ToolbarDropdown';
2
+
3
+ interface ToolsDropdownProps {
4
+ onOpenAtlas?: () => void;
5
+ onOpenLayoutPicker?: () => void;
6
+ onOpenTeams?: () => void;
7
+ onOpenGit?: () => void;
8
+ onOpenHistory?: () => void;
9
+ teamCount?: number;
10
+ gitStagedCount?: number;
11
+ }
12
+
13
+ export function ToolsDropdown({
14
+ onOpenAtlas,
15
+ onOpenLayoutPicker,
16
+ onOpenTeams,
17
+ onOpenGit,
18
+ onOpenHistory,
19
+ teamCount = 0,
20
+ gitStagedCount = 0,
21
+ }: ToolsDropdownProps) {
22
+ const items: DropdownItem[] = [];
23
+
24
+ if (onOpenAtlas) {
25
+ items.push({
26
+ id: 'atlas',
27
+ label: 'Repository Atlas',
28
+ icon: (
29
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
30
+ <polygon points="1 6 1 22 8 18 16 22 23 18 23 2 16 6 8 2 1 6" />
31
+ <line x1="8" y1="2" x2="8" y2="18" />
32
+ <line x1="16" y1="6" x2="16" y2="22" />
33
+ </svg>
34
+ ),
35
+ onClick: onOpenAtlas,
36
+ });
37
+ }
38
+
39
+ if (onOpenLayoutPicker) {
40
+ items.push({
41
+ id: 'layout',
42
+ label: 'Workspace Layouts',
43
+ shortcut: 'Ctrl+Shift+L',
44
+ icon: (
45
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
46
+ <rect x="3" y="3" width="7" height="7" />
47
+ <rect x="14" y="3" width="7" height="7" />
48
+ <rect x="3" y="14" width="7" height="7" />
49
+ <rect x="14" y="14" width="7" height="7" />
50
+ </svg>
51
+ ),
52
+ onClick: onOpenLayoutPicker,
53
+ });
54
+ }
55
+
56
+ if (onOpenGit) {
57
+ items.push({
58
+ id: 'git',
59
+ label: 'Git Integration',
60
+ shortcut: 'Ctrl+Shift+G',
61
+ badge: gitStagedCount > 0 ? gitStagedCount : undefined,
62
+ icon: (
63
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
64
+ <line x1="6" y1="3" x2="6" y2="15" />
65
+ <circle cx="18" cy="6" r="3" />
66
+ <circle cx="6" cy="18" r="3" />
67
+ <path d="M18 9a9 9 0 01-9 9" />
68
+ </svg>
69
+ ),
70
+ onClick: onOpenGit,
71
+ });
72
+ }
73
+
74
+ if (onOpenTeams) {
75
+ items.push({
76
+ id: 'teams',
77
+ label: 'Agent Teams',
78
+ badge: teamCount > 0 ? teamCount : undefined,
79
+ icon: (
80
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
81
+ <path d="M17 21v-2a4 4 0 00-4-4H5a4 4 0 00-4 4v2" />
82
+ <circle cx="9" cy="7" r="4" />
83
+ <path d="M23 21v-2a4 4 0 00-3-3.87M16 3.13a4 4 0 010 7.75" />
84
+ </svg>
85
+ ),
86
+ onClick: onOpenTeams,
87
+ });
88
+ }
89
+
90
+ if (onOpenHistory) {
91
+ items.push({
92
+ id: 'history',
93
+ label: 'Session History',
94
+ shortcut: 'Ctrl+Shift+H',
95
+ icon: (
96
+ <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
97
+ <circle cx="12" cy="12" r="10" />
98
+ <polyline points="12 6 12 12 16 14" />
99
+ </svg>
100
+ ),
101
+ onClick: onOpenHistory,
102
+ });
103
+ }
104
+
105
+ if (items.length === 0) return null;
106
+
107
+ return (
108
+ <ToolbarDropdown
109
+ icon={
110
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
111
+ <path d="M14.7 6.3a1 1 0 000 1.4l1.6 1.6a1 1 0 001.4 0l3.77-3.77a6 6 0 01-7.94 7.94l-6.91 6.91a2.12 2.12 0 01-3-3l6.91-6.91a6 6 0 017.94-7.94l-3.76 3.76z" />
112
+ </svg>
113
+ }
114
+ label="Tools"
115
+ items={items}
116
+ title="Tools - Quick access to workspace features"
117
+ />
118
+ );
119
+ }
@@ -0,0 +1,217 @@
1
+ import { useState, useEffect, useRef } from 'react';
2
+
3
+ interface TooltipCoachProps {
4
+ id: string; // Unique ID for this tooltip (e.g., "atlas-button")
5
+ children: React.ReactNode; // The element to wrap
6
+ title: string;
7
+ description: string;
8
+ position?: 'top' | 'bottom' | 'left' | 'right';
9
+ disabled?: boolean;
10
+ }
11
+
12
+ export function TooltipCoach({
13
+ id,
14
+ children,
15
+ title,
16
+ description,
17
+ position = 'bottom',
18
+ disabled = false,
19
+ }: TooltipCoachProps) {
20
+ const [isVisible, setIsVisible] = useState(false);
21
+ const [isDismissed, setIsDismissed] = useState(false);
22
+ const [hasShownInSession, setHasShownInSession] = useState(false);
23
+ const wrapperRef = useRef<HTMLDivElement>(null);
24
+ const tooltipRef = useRef<HTMLDivElement>(null);
25
+
26
+ // Check if this tooltip has been dismissed
27
+ useEffect(() => {
28
+ const dismissed = localStorage.getItem(`tooltipCoach:${id}`) === 'true';
29
+ setIsDismissed(dismissed);
30
+ }, [id]);
31
+
32
+ // Handle showing tooltip on hover (only if not dismissed and not shown in this session)
33
+ const handleMouseEnter = () => {
34
+ if (disabled || isDismissed || hasShownInSession) return;
35
+ setIsVisible(true);
36
+ setHasShownInSession(true); // Only show once per session
37
+ };
38
+
39
+ const handleMouseLeave = () => {
40
+ // Don't auto-hide - user must click "Got it"
41
+ };
42
+
43
+ const handleGotIt = (e: React.MouseEvent) => {
44
+ e.stopPropagation();
45
+ localStorage.setItem(`tooltipCoach:${id}`, 'true');
46
+ setIsDismissed(true);
47
+ setIsVisible(false);
48
+ };
49
+
50
+ if (isDismissed || disabled) {
51
+ return <>{children}</>;
52
+ }
53
+
54
+ return (
55
+ <div
56
+ ref={wrapperRef}
57
+ className="tooltip-coach-wrapper"
58
+ onMouseEnter={handleMouseEnter}
59
+ onMouseLeave={handleMouseLeave}
60
+ >
61
+ {children}
62
+
63
+ {isVisible && (
64
+ <div ref={tooltipRef} className={`tooltip-coach tooltip-coach-${position}`}>
65
+ <div className="tooltip-coach-content">
66
+ <h4 className="tooltip-coach-title">{title}</h4>
67
+ <p className="tooltip-coach-description">{description}</p>
68
+ <button className="tooltip-coach-btn" onClick={handleGotIt}>
69
+ Got it!
70
+ </button>
71
+ </div>
72
+ <div className={`tooltip-coach-arrow tooltip-coach-arrow-${position}`} />
73
+
74
+ <style>{`
75
+ .tooltip-coach-wrapper {
76
+ position: relative;
77
+ display: inline-block;
78
+ }
79
+
80
+ .tooltip-coach {
81
+ position: absolute;
82
+ z-index: 10000;
83
+ background: #1f2335;
84
+ border: 2px solid #7aa2f7;
85
+ border-radius: 10px;
86
+ padding: 16px;
87
+ min-width: 280px;
88
+ max-width: 320px;
89
+ box-shadow: 0 12px 48px rgba(122, 162, 247, 0.3);
90
+ font-family: 'JetBrains Mono', monospace;
91
+ animation: tooltip-coach-fade-in 0.3s ease;
92
+ }
93
+
94
+ @keyframes tooltip-coach-fade-in {
95
+ from {
96
+ opacity: 0;
97
+ transform: translateY(-8px) scale(0.95);
98
+ }
99
+ to {
100
+ opacity: 1;
101
+ transform: translateY(0) scale(1);
102
+ }
103
+ }
104
+
105
+ .tooltip-coach-bottom {
106
+ top: calc(100% + 12px);
107
+ left: 50%;
108
+ transform: translateX(-50%);
109
+ }
110
+
111
+ .tooltip-coach-top {
112
+ bottom: calc(100% + 12px);
113
+ left: 50%;
114
+ transform: translateX(-50%);
115
+ }
116
+
117
+ .tooltip-coach-left {
118
+ right: calc(100% + 12px);
119
+ top: 50%;
120
+ transform: translateY(-50%);
121
+ }
122
+
123
+ .tooltip-coach-right {
124
+ left: calc(100% + 12px);
125
+ top: 50%;
126
+ transform: translateY(-50%);
127
+ }
128
+
129
+ .tooltip-coach-content {
130
+ display: flex;
131
+ flex-direction: column;
132
+ gap: 12px;
133
+ }
134
+
135
+ .tooltip-coach-title {
136
+ font-size: 14px;
137
+ font-weight: 600;
138
+ color: #7aa2f7;
139
+ margin: 0;
140
+ }
141
+
142
+ .tooltip-coach-description {
143
+ font-size: 12px;
144
+ color: #a9b1d6;
145
+ margin: 0;
146
+ line-height: 1.5;
147
+ }
148
+
149
+ .tooltip-coach-btn {
150
+ padding: 8px 16px;
151
+ background: linear-gradient(135deg, #7aa2f7, #7dcfff);
152
+ border: none;
153
+ border-radius: 6px;
154
+ color: #1a1b26;
155
+ font-size: 12px;
156
+ font-weight: 600;
157
+ font-family: inherit;
158
+ cursor: pointer;
159
+ transition: all 0.2s ease;
160
+ align-self: flex-start;
161
+ }
162
+
163
+ .tooltip-coach-btn:hover {
164
+ transform: translateY(-1px);
165
+ box-shadow: 0 4px 16px rgba(122, 162, 247, 0.4);
166
+ }
167
+
168
+ .tooltip-coach-btn:active {
169
+ transform: translateY(0);
170
+ }
171
+
172
+ .tooltip-coach-arrow {
173
+ position: absolute;
174
+ width: 12px;
175
+ height: 12px;
176
+ background: #1f2335;
177
+ border: 2px solid #7aa2f7;
178
+ transform: rotate(45deg);
179
+ }
180
+
181
+ .tooltip-coach-arrow-bottom {
182
+ top: -7px;
183
+ left: 50%;
184
+ margin-left: -6px;
185
+ border-bottom: none;
186
+ border-right: none;
187
+ }
188
+
189
+ .tooltip-coach-arrow-top {
190
+ bottom: -7px;
191
+ left: 50%;
192
+ margin-left: -6px;
193
+ border-top: none;
194
+ border-left: none;
195
+ }
196
+
197
+ .tooltip-coach-arrow-left {
198
+ right: -7px;
199
+ top: 50%;
200
+ margin-top: -6px;
201
+ border-left: none;
202
+ border-bottom: none;
203
+ }
204
+
205
+ .tooltip-coach-arrow-right {
206
+ left: -7px;
207
+ top: 50%;
208
+ margin-top: -6px;
209
+ border-right: none;
210
+ border-top: none;
211
+ }
212
+ `}</style>
213
+ </div>
214
+ )}
215
+ </div>
216
+ );
217
+ }
@@ -0,0 +1,85 @@
1
+ interface WelcomeHeroProps {
2
+ version: string;
3
+ }
4
+
5
+ export function WelcomeHero({ version }: WelcomeHeroProps) {
6
+ return (
7
+ <div className="welcome-hero">
8
+ <div className="hero-logo">
9
+ <svg width="64" height="64" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
10
+ <rect x="3" y="3" width="18" height="18" rx="2" ry="2" strokeLinecap="round" strokeLinejoin="round" />
11
+ <path d="M9 3v18" strokeLinecap="round" strokeLinejoin="round" />
12
+ <path d="M14 8l-5 5l5 5" strokeLinecap="round" strokeLinejoin="round" />
13
+ </svg>
14
+ </div>
15
+
16
+ <h1 className="hero-title">ClaudeDesk</h1>
17
+ <p className="hero-tagline">
18
+ Multi-session terminal workspace for Claude Code CLI
19
+ </p>
20
+ <div className="hero-version">v{version}</div>
21
+
22
+ <style>{`
23
+ .welcome-hero {
24
+ display: flex;
25
+ flex-direction: column;
26
+ align-items: center;
27
+ margin-bottom: 48px;
28
+ animation: hero-fade-in 0.5s ease;
29
+ }
30
+
31
+ @keyframes hero-fade-in {
32
+ from {
33
+ opacity: 0;
34
+ transform: translateY(-10px);
35
+ }
36
+ to {
37
+ opacity: 1;
38
+ transform: translateY(0);
39
+ }
40
+ }
41
+
42
+ .hero-logo {
43
+ width: 96px;
44
+ height: 96px;
45
+ display: flex;
46
+ align-items: center;
47
+ justify-content: center;
48
+ background: linear-gradient(135deg, rgba(122, 162, 247, 0.15), rgba(125, 207, 255, 0.1));
49
+ border: 2px solid #3d4458;
50
+ border-radius: 24px;
51
+ margin-bottom: 24px;
52
+ color: #7aa2f7;
53
+ box-shadow: 0 8px 32px rgba(122, 162, 247, 0.15);
54
+ }
55
+
56
+ .hero-title {
57
+ font-size: 32px;
58
+ font-weight: 700;
59
+ color: #e9e9ea;
60
+ margin: 0 0 8px 0;
61
+ letter-spacing: -0.5px;
62
+ }
63
+
64
+ .hero-tagline {
65
+ font-size: 14px;
66
+ color: #a9b1d6;
67
+ margin: 0 0 12px 0;
68
+ text-align: center;
69
+ max-width: 400px;
70
+ line-height: 1.5;
71
+ }
72
+
73
+ .hero-version {
74
+ font-size: 11px;
75
+ color: #565f89;
76
+ font-weight: 500;
77
+ padding: 4px 12px;
78
+ background: #1f2335;
79
+ border: 1px solid #3d4458;
80
+ border-radius: 12px;
81
+ }
82
+ `}</style>
83
+ </div>
84
+ );
85
+ }
@@ -11,6 +11,11 @@ export { ContextMenu } from './ContextMenu';
11
11
  export { ConfirmDialog } from './ConfirmDialog';
12
12
  export { CheckpointDialog } from './CheckpointDialog';
13
13
  export { EmptyState } from './EmptyState';
14
+ export { FuelStatusIndicator } from './FuelStatusIndicator';
15
+ export type { FuelStatusIndicatorProps } from './FuelStatusIndicator';
16
+ export { FuelGaugeBar } from './FuelGaugeBar';
17
+ export { ToolsDropdown } from './ToolsDropdown';
18
+ export { FuelTooltip } from './FuelTooltip';
14
19
  // Re-export quota types from shared
15
20
  export type { ClaudeUsageQuota, BurnRateData, QuotaBucket } from '../../../shared/ipc-types';
16
21
  // Export prompt template components (from parent directory)
@@ -0,0 +1,166 @@
1
+ interface Step1WelcomeProps {
2
+ onNext: () => void;
3
+ }
4
+
5
+ export function Step1Welcome({ onNext }: Step1WelcomeProps) {
6
+ return (
7
+ <div className="wizard-step-content">
8
+ <div className="welcome-icon">
9
+ <svg width="80" height="80" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
10
+ <rect x="3" y="3" width="18" height="18" rx="2" ry="2" strokeLinecap="round" strokeLinejoin="round" />
11
+ <path d="M9 3v18" strokeLinecap="round" strokeLinejoin="round" />
12
+ <path d="M14 8l-5 5l5 5" strokeLinecap="round" strokeLinejoin="round" />
13
+ </svg>
14
+ </div>
15
+
16
+ <h1 className="welcome-title">Welcome to ClaudeDesk</h1>
17
+ <p className="welcome-subtitle">
18
+ Your multi-session terminal workspace for Claude Code CLI
19
+ </p>
20
+
21
+ <div className="welcome-features">
22
+ <div className="feature-item">
23
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
24
+ <polyline points="20 6 9 17 4 12" strokeLinecap="round" strokeLinejoin="round" />
25
+ </svg>
26
+ <span>Work with up to 4 terminal sessions simultaneously</span>
27
+ </div>
28
+ <div className="feature-item">
29
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
30
+ <polyline points="20 6 9 17 4 12" strokeLinecap="round" strokeLinejoin="round" />
31
+ </svg>
32
+ <span>Visualize and coordinate multiple AI agent teams</span>
33
+ </div>
34
+ <div className="feature-item">
35
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
36
+ <polyline points="20 6 9 17 4 12" strokeLinecap="round" strokeLinejoin="round" />
37
+ </svg>
38
+ <span>Generate AI-powered repository maps for navigation</span>
39
+ </div>
40
+ <div className="feature-item">
41
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
42
+ <polyline points="20 6 9 17 4 12" strokeLinecap="round" strokeLinejoin="round" />
43
+ </svg>
44
+ <span>Save and restore conversation checkpoints</span>
45
+ </div>
46
+ </div>
47
+
48
+ <button className="wizard-next-btn" onClick={onNext}>
49
+ Get Started
50
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
51
+ <polyline points="9 18 15 12 9 6" strokeLinecap="round" strokeLinejoin="round" />
52
+ </svg>
53
+ </button>
54
+
55
+ <style>{`
56
+ .wizard-step-content {
57
+ display: flex;
58
+ flex-direction: column;
59
+ align-items: center;
60
+ animation: step-fade-in 0.4s ease;
61
+ }
62
+
63
+ @keyframes step-fade-in {
64
+ from {
65
+ opacity: 0;
66
+ transform: translateY(10px);
67
+ }
68
+ to {
69
+ opacity: 1;
70
+ transform: translateY(0);
71
+ }
72
+ }
73
+
74
+ .welcome-icon {
75
+ width: 120px;
76
+ height: 120px;
77
+ display: flex;
78
+ align-items: center;
79
+ justify-content: center;
80
+ background: linear-gradient(135deg, rgba(122, 162, 247, 0.15), rgba(125, 207, 255, 0.1));
81
+ border: 2px solid #3d4458;
82
+ border-radius: 28px;
83
+ margin-bottom: 32px;
84
+ color: #7aa2f7;
85
+ box-shadow: 0 12px 48px rgba(122, 162, 247, 0.2);
86
+ }
87
+
88
+ .welcome-title {
89
+ font-size: 32px;
90
+ font-weight: 700;
91
+ color: #e9e9ea;
92
+ margin: 0 0 12px 0;
93
+ letter-spacing: -0.5px;
94
+ }
95
+
96
+ .welcome-subtitle {
97
+ font-size: 15px;
98
+ color: #a9b1d6;
99
+ margin: 0 0 48px 0;
100
+ text-align: center;
101
+ max-width: 500px;
102
+ line-height: 1.6;
103
+ }
104
+
105
+ .welcome-features {
106
+ display: flex;
107
+ flex-direction: column;
108
+ gap: 16px;
109
+ margin-bottom: 48px;
110
+ width: 100%;
111
+ max-width: 480px;
112
+ }
113
+
114
+ .feature-item {
115
+ display: flex;
116
+ align-items: center;
117
+ gap: 12px;
118
+ padding: 16px;
119
+ background: #1f2335;
120
+ border: 1px solid #3d4458;
121
+ border-radius: 10px;
122
+ color: #a9b1d6;
123
+ font-size: 14px;
124
+ line-height: 1.5;
125
+ transition: all 0.2s ease;
126
+ }
127
+
128
+ .feature-item:hover {
129
+ transform: translateX(4px);
130
+ border-color: #7aa2f7;
131
+ }
132
+
133
+ .feature-item svg {
134
+ color: #7aa2f7;
135
+ flex-shrink: 0;
136
+ }
137
+
138
+ .wizard-next-btn {
139
+ display: flex;
140
+ align-items: center;
141
+ gap: 8px;
142
+ padding: 14px 32px;
143
+ background: linear-gradient(135deg, #7aa2f7, #7dcfff);
144
+ border: none;
145
+ border-radius: 10px;
146
+ color: #1a1b26;
147
+ font-size: 14px;
148
+ font-weight: 600;
149
+ font-family: 'JetBrains Mono', monospace;
150
+ cursor: pointer;
151
+ transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);
152
+ box-shadow: 0 4px 16px rgba(122, 162, 247, 0.3);
153
+ }
154
+
155
+ .wizard-next-btn:hover {
156
+ transform: translateY(-2px);
157
+ box-shadow: 0 8px 24px rgba(122, 162, 247, 0.4);
158
+ }
159
+
160
+ .wizard-next-btn:active {
161
+ transform: translateY(0);
162
+ }
163
+ `}</style>
164
+ </div>
165
+ );
166
+ }