@atercates/claude-deck 0.2.1
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/LICENSE +21 -0
- package/README.md +123 -0
- package/app/api/claude/hidden/route.ts +66 -0
- package/app/api/claude/projects/[name]/sessions/route.ts +71 -0
- package/app/api/claude/projects/route.ts +44 -0
- package/app/api/code-search/available/route.ts +12 -0
- package/app/api/code-search/route.ts +47 -0
- package/app/api/dev-servers/[id]/logs/route.ts +23 -0
- package/app/api/dev-servers/[id]/restart/route.ts +20 -0
- package/app/api/dev-servers/[id]/route.ts +51 -0
- package/app/api/dev-servers/[id]/stop/route.ts +20 -0
- package/app/api/dev-servers/detect/route.ts +39 -0
- package/app/api/dev-servers/route.ts +48 -0
- package/app/api/exec/route.ts +60 -0
- package/app/api/files/content/route.ts +76 -0
- package/app/api/files/route.ts +37 -0
- package/app/api/files/upload-temp/route.ts +41 -0
- package/app/api/git/check/route.ts +54 -0
- package/app/api/git/clone/route.ts +99 -0
- package/app/api/git/commit/route.ts +75 -0
- package/app/api/git/discard/route.ts +38 -0
- package/app/api/git/file-content/route.ts +64 -0
- package/app/api/git/history/[hash]/diff/route.ts +38 -0
- package/app/api/git/history/[hash]/route.ts +34 -0
- package/app/api/git/history/route.ts +27 -0
- package/app/api/git/multi-status/route.ts +46 -0
- package/app/api/git/pr/route.ts +164 -0
- package/app/api/git/push/route.ts +64 -0
- package/app/api/git/stage/route.ts +40 -0
- package/app/api/git/status/route.ts +51 -0
- package/app/api/git/unstage/route.ts +46 -0
- package/app/api/groups/[...path]/route.ts +136 -0
- package/app/api/groups/route.ts +93 -0
- package/app/api/orchestrate/spawn/route.ts +45 -0
- package/app/api/orchestrate/workers/[id]/route.ts +89 -0
- package/app/api/orchestrate/workers/route.ts +31 -0
- package/app/api/projects/[id]/detect/route.ts +27 -0
- package/app/api/projects/[id]/dev-servers/[dsId]/route.ts +66 -0
- package/app/api/projects/[id]/dev-servers/route.ts +51 -0
- package/app/api/projects/[id]/repositories/[repoId]/route.ts +67 -0
- package/app/api/projects/[id]/repositories/route.ts +74 -0
- package/app/api/projects/[id]/route.ts +108 -0
- package/app/api/projects/detect/route.ts +33 -0
- package/app/api/projects/route.ts +59 -0
- package/app/api/sessions/[id]/claude-session/route.ts +42 -0
- package/app/api/sessions/[id]/fork/route.ts +74 -0
- package/app/api/sessions/[id]/mcp-config/route.ts +34 -0
- package/app/api/sessions/[id]/messages/route.ts +60 -0
- package/app/api/sessions/[id]/pr/route.ts +188 -0
- package/app/api/sessions/[id]/preview/route.ts +42 -0
- package/app/api/sessions/[id]/route.ts +229 -0
- package/app/api/sessions/[id]/send-keys/route.ts +119 -0
- package/app/api/sessions/[id]/summarize/route.ts +331 -0
- package/app/api/sessions/init-script/route.ts +84 -0
- package/app/api/sessions/route.ts +209 -0
- package/app/api/sessions/status/route.ts +237 -0
- package/app/api/system/route.ts +9 -0
- package/app/api/tmux/kill-all/route.ts +57 -0
- package/app/api/tmux/rename/route.ts +30 -0
- package/app/globals.css +174 -0
- package/app/icon.svg +11 -0
- package/app/layout.tsx +122 -0
- package/app/page.tsx +629 -0
- package/components/ChatMessage.tsx +65 -0
- package/components/ChatView.tsx +276 -0
- package/components/ClaudeProjects/ClaudeProjectCard.tsx +195 -0
- package/components/ClaudeProjects/ClaudeProjectsSection.tsx +89 -0
- package/components/ClaudeProjects/ClaudeSessionCard.tsx +100 -0
- package/components/ClaudeProjects/index.ts +1 -0
- package/components/CodeSearch/CodeSearchResults.tsx +177 -0
- package/components/ConductorPanel.tsx +256 -0
- package/components/DevServers/DevServerCard.tsx +311 -0
- package/components/DevServers/DevServersSection.tsx +91 -0
- package/components/DevServers/ServerLogsModal.tsx +151 -0
- package/components/DevServers/StartServerDialog.tsx +359 -0
- package/components/DevServers/index.ts +4 -0
- package/components/DiffViewer/DiffModal.tsx +151 -0
- package/components/DiffViewer/UnifiedDiff.tsx +185 -0
- package/components/DiffViewer/index.tsx +2 -0
- package/components/DirectoryPicker.tsx +355 -0
- package/components/FileExplorer/FileEditor.tsx +276 -0
- package/components/FileExplorer/FileTabs.tsx +118 -0
- package/components/FileExplorer/FileTree.tsx +214 -0
- package/components/FileExplorer/HtmlRenderer.tsx +16 -0
- package/components/FileExplorer/MarkdownRenderer.tsx +18 -0
- package/components/FileExplorer/index.tsx +520 -0
- package/components/FilePicker.tsx +339 -0
- package/components/FolderPicker.tsx +201 -0
- package/components/GitDrawer/FileEditDialog.tsx +400 -0
- package/components/GitDrawer/index.tsx +464 -0
- package/components/GitPanel/CommitForm.tsx +205 -0
- package/components/GitPanel/CommitHistory.tsx +174 -0
- package/components/GitPanel/CommitItem.tsx +196 -0
- package/components/GitPanel/FileChanges.tsx +414 -0
- package/components/GitPanel/GitPanelTabs.tsx +39 -0
- package/components/GitPanel/index.tsx +817 -0
- package/components/MessageInput.tsx +82 -0
- package/components/NewClaudeSessionDialog.tsx +166 -0
- package/components/NewSessionDialog/AdvancedSettings.tsx +78 -0
- package/components/NewSessionDialog/AgentSelector.tsx +37 -0
- package/components/NewSessionDialog/CreatingOverlay.tsx +94 -0
- package/components/NewSessionDialog/NewSessionDialog.types.ts +136 -0
- package/components/NewSessionDialog/ProjectSelector.tsx +146 -0
- package/components/NewSessionDialog/WorkingDirectoryInput.tsx +55 -0
- package/components/NewSessionDialog/WorktreeSection.tsx +92 -0
- package/components/NewSessionDialog/hooks/useNewSessionForm.ts +370 -0
- package/components/NewSessionDialog/index.tsx +106 -0
- package/components/NotificationSettings.tsx +127 -0
- package/components/PRCreationModal.tsx +272 -0
- package/components/Pane/DesktopTabBar.tsx +353 -0
- package/components/Pane/MobileTabBar.tsx +210 -0
- package/components/Pane/OpenInVSCode.tsx +69 -0
- package/components/Pane/PaneSkeletons.tsx +57 -0
- package/components/Pane/index.tsx +558 -0
- package/components/PaneLayout.tsx +60 -0
- package/components/Projects/DevServersSection.tsx +140 -0
- package/components/Projects/DirectoryField.tsx +92 -0
- package/components/Projects/NewProjectDialog.tsx +188 -0
- package/components/Projects/NewProjectDialog.types.ts +46 -0
- package/components/Projects/ProjectCard.tsx +276 -0
- package/components/Projects/ProjectSettingsDialog.tsx +811 -0
- package/components/Projects/hooks/useNewProjectForm.ts +249 -0
- package/components/Projects/index.ts +3 -0
- package/components/Providers.tsx +49 -0
- package/components/QuickSwitcher.tsx +306 -0
- package/components/SessionList/KillAllConfirm.tsx +46 -0
- package/components/SessionList/SelectionToolbar.tsx +164 -0
- package/components/SessionList/SessionList.types.ts +37 -0
- package/components/SessionList/SessionListHeader.tsx +71 -0
- package/components/SessionList/hooks/useSessionListMutations.ts +269 -0
- package/components/SessionList/index.tsx +189 -0
- package/components/ShellDrawer/index.tsx +106 -0
- package/components/SidebarFooter.tsx +55 -0
- package/components/Terminal/KeybarToggleButton.tsx +45 -0
- package/components/Terminal/ScrollToBottomButton.tsx +32 -0
- package/components/Terminal/SearchBar.tsx +71 -0
- package/components/Terminal/TerminalToolbar.tsx +551 -0
- package/components/Terminal/VirtualKeyboard.tsx +711 -0
- package/components/Terminal/constants.ts +20 -0
- package/components/Terminal/hooks/index.ts +5 -0
- package/components/Terminal/hooks/resize-handlers.ts +140 -0
- package/components/Terminal/hooks/terminal-init.ts +151 -0
- package/components/Terminal/hooks/touch-scroll.ts +155 -0
- package/components/Terminal/hooks/useTerminalConnection.ts +282 -0
- package/components/Terminal/hooks/useTerminalConnection.types.ts +39 -0
- package/components/Terminal/hooks/useTerminalSearch.ts +103 -0
- package/components/Terminal/hooks/websocket-connection.ts +274 -0
- package/components/Terminal/index.tsx +320 -0
- package/components/ThemeToggle.tsx +168 -0
- package/components/TmuxSessions.tsx +132 -0
- package/components/ToolCallDisplay.tsx +71 -0
- package/components/WorkerCard.tsx +245 -0
- package/components/a/ABadge.tsx +115 -0
- package/components/a/AButton.tsx +163 -0
- package/components/a/ADialog.tsx +93 -0
- package/components/a/ADropdownMenu.tsx +279 -0
- package/components/a/AIconButton.tsx +190 -0
- package/components/a/ASheet.tsx +150 -0
- package/components/a/ATooltip.tsx +77 -0
- package/components/a/index.ts +64 -0
- package/components/mobile/SwipeSidebar.tsx +122 -0
- package/components/ui/badge.tsx +41 -0
- package/components/ui/button.tsx +60 -0
- package/components/ui/context-menu.tsx +197 -0
- package/components/ui/dialog.tsx +143 -0
- package/components/ui/dropdown-menu.tsx +257 -0
- package/components/ui/input.tsx +21 -0
- package/components/ui/scroll-area.tsx +52 -0
- package/components/ui/select.tsx +159 -0
- package/components/ui/skeleton.tsx +111 -0
- package/components/ui/switch.tsx +31 -0
- package/components/ui/textarea.tsx +21 -0
- package/components/ui/tooltip.tsx +32 -0
- package/components/views/DesktopView.tsx +244 -0
- package/components/views/MobileView.tsx +110 -0
- package/components/views/types.ts +75 -0
- package/contexts/PaneContext.tsx +336 -0
- package/data/claude/index.ts +9 -0
- package/data/claude/keys.ts +6 -0
- package/data/claude/queries.ts +120 -0
- package/data/claude/useClaudeUpdates.ts +37 -0
- package/data/code-search/index.ts +2 -0
- package/data/code-search/keys.ts +7 -0
- package/data/code-search/queries.ts +61 -0
- package/data/dev-servers/index.ts +8 -0
- package/data/dev-servers/keys.ts +4 -0
- package/data/dev-servers/queries.ts +104 -0
- package/data/files/index.ts +3 -0
- package/data/files/keys.ts +4 -0
- package/data/files/queries.ts +25 -0
- package/data/git/keys.ts +15 -0
- package/data/git/queries.ts +395 -0
- package/data/groups/index.ts +1 -0
- package/data/groups/mutations.ts +95 -0
- package/data/projects/index.ts +10 -0
- package/data/projects/keys.ts +4 -0
- package/data/projects/queries.ts +193 -0
- package/data/repositories/index.ts +7 -0
- package/data/repositories/keys.ts +5 -0
- package/data/repositories/queries.ts +122 -0
- package/data/sessions/index.ts +12 -0
- package/data/sessions/keys.ts +8 -0
- package/data/sessions/queries.ts +218 -0
- package/data/statuses/index.ts +1 -0
- package/data/statuses/queries.ts +69 -0
- package/hooks/useCopyToClipboard.ts +48 -0
- package/hooks/useDevServersManager.ts +73 -0
- package/hooks/useDirectoryBrowser.ts +90 -0
- package/hooks/useDrawerAnimation.ts +27 -0
- package/hooks/useFileDrop.ts +87 -0
- package/hooks/useFileEditor.ts +184 -0
- package/hooks/useGroups.ts +37 -0
- package/hooks/useHomePath.ts +34 -0
- package/hooks/useKeyRepeat.ts +55 -0
- package/hooks/useKeybarVisibility.ts +42 -0
- package/hooks/useNotifications.ts +257 -0
- package/hooks/useProjects.ts +53 -0
- package/hooks/useSessionStatuses.ts +30 -0
- package/hooks/useSessions.ts +86 -0
- package/hooks/useSpeechRecognition.ts +124 -0
- package/hooks/useViewport.ts +32 -0
- package/hooks/useViewportHeight.ts +50 -0
- package/lib/async-operations.ts +35 -0
- package/lib/banner.ts +81 -0
- package/lib/claude/jsonl-cache.ts +86 -0
- package/lib/claude/jsonl-reader.ts +271 -0
- package/lib/claude/process-manager.ts +278 -0
- package/lib/claude/stream-parser.ts +173 -0
- package/lib/claude/types.ts +154 -0
- package/lib/claude/watcher.ts +71 -0
- package/lib/client/session-registry.ts +111 -0
- package/lib/code-search.ts +121 -0
- package/lib/db/index.ts +48 -0
- package/lib/db/migrations.ts +45 -0
- package/lib/db/queries.ts +460 -0
- package/lib/db/schema.ts +114 -0
- package/lib/db/types.ts +92 -0
- package/lib/db.ts +2 -0
- package/lib/dev-servers.ts +509 -0
- package/lib/diff-parser.ts +221 -0
- package/lib/env-setup.ts +285 -0
- package/lib/file-upload.ts +34 -0
- package/lib/file-utils.ts +50 -0
- package/lib/files.ts +207 -0
- package/lib/git-history.ts +294 -0
- package/lib/git-status.ts +391 -0
- package/lib/git.ts +257 -0
- package/lib/mcp-config.ts +81 -0
- package/lib/multi-repo-git.ts +179 -0
- package/lib/notifications.ts +219 -0
- package/lib/orchestration.ts +448 -0
- package/lib/panes.ts +232 -0
- package/lib/ports.ts +97 -0
- package/lib/pr-generation.ts +307 -0
- package/lib/pr.ts +234 -0
- package/lib/projects.ts +578 -0
- package/lib/providers/registry.ts +70 -0
- package/lib/providers.ts +121 -0
- package/lib/query-client.ts +14 -0
- package/lib/rangeSelectionUtils.ts +65 -0
- package/lib/status-detector.ts +375 -0
- package/lib/terminal-themes.ts +265 -0
- package/lib/theme-config.ts +327 -0
- package/lib/utils.ts +6 -0
- package/lib/worktrees.ts +262 -0
- package/mcp/orchestration-server.ts +438 -0
- package/package.json +139 -0
- package/postcss.config.mjs +7 -0
- package/public/icon.svg +10 -0
- package/public/icons/icon-128x128.png +0 -0
- package/public/icons/icon-144x144.png +0 -0
- package/public/icons/icon-152x152.png +0 -0
- package/public/icons/icon-192x192.png +0 -0
- package/public/icons/icon-384x384.png +0 -0
- package/public/icons/icon-512x512.png +0 -0
- package/public/icons/icon-72x72.png +0 -0
- package/public/icons/icon-96x96.png +0 -0
- package/public/manifest.json +61 -0
- package/public/sw.js +64 -0
- package/scripts/agent-os +91 -0
- package/scripts/install.sh +48 -0
- package/scripts/lib/ai-clis.sh +132 -0
- package/scripts/lib/commands.sh +487 -0
- package/scripts/lib/common.sh +89 -0
- package/scripts/lib/prerequisites.sh +462 -0
- package/scripts/setup.sh +134 -0
- package/server.ts +155 -0
- package/stores/fileOpen.ts +26 -0
- package/stores/index.ts +1 -0
- package/stores/initialPrompt.ts +24 -0
- package/stores/sessionSelection.ts +48 -0
- package/styles/themes.css +603 -0
- package/tsconfig.json +33 -0
|
@@ -0,0 +1,462 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Prerequisite installation for claude-deck
|
|
3
|
+
|
|
4
|
+
# Attempt to source common Node.js version managers
|
|
5
|
+
# This ensures we detect Node even if it's not in the current PATH
|
|
6
|
+
source_node_managers() {
|
|
7
|
+
# nvm
|
|
8
|
+
if [[ -s "$HOME/.nvm/nvm.sh" ]]; then
|
|
9
|
+
source "$HOME/.nvm/nvm.sh" 2>/dev/null || true
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
# fnm
|
|
13
|
+
if [[ -d "$HOME/.local/share/fnm" ]]; then
|
|
14
|
+
export PATH="$HOME/.local/share/fnm:$PATH"
|
|
15
|
+
eval "$(fnm env --use-on-cd 2>/dev/null || true)"
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
# asdf
|
|
19
|
+
if [[ -f "$HOME/.asdf/asdf.sh" ]]; then
|
|
20
|
+
source "$HOME/.asdf/asdf.sh" 2>/dev/null || true
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
# volta
|
|
24
|
+
if [[ -d "$HOME/.volta" ]]; then
|
|
25
|
+
export VOLTA_HOME="$HOME/.volta"
|
|
26
|
+
export PATH="$VOLTA_HOME/bin:$PATH"
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# Homebrew (if not already in PATH)
|
|
30
|
+
if [[ "$OS" == "macos" ]]; then
|
|
31
|
+
if [[ -f /opt/homebrew/bin/brew ]]; then
|
|
32
|
+
eval "$(/opt/homebrew/bin/brew shellenv 2>/dev/null || true)"
|
|
33
|
+
elif [[ -f /usr/local/bin/brew ]]; then
|
|
34
|
+
eval "$(/usr/local/bin/brew shellenv 2>/dev/null || true)"
|
|
35
|
+
fi
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# ~/.local/bin (common for user-installed binaries)
|
|
39
|
+
if [[ -d "$HOME/.local/bin" ]]; then
|
|
40
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
41
|
+
fi
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
# Check if Node.js is available (trying multiple sources)
|
|
45
|
+
check_node() {
|
|
46
|
+
# Try direct command first
|
|
47
|
+
if command -v node &> /dev/null; then
|
|
48
|
+
local version
|
|
49
|
+
version=$(node -v | sed 's/v//' | cut -d. -f1)
|
|
50
|
+
if [[ "$version" -ge 20 ]]; then
|
|
51
|
+
local node_path=$(command -v node)
|
|
52
|
+
log_success "Found Node.js v$(node -v | sed 's/v//') at $node_path"
|
|
53
|
+
return 0
|
|
54
|
+
fi
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# Source version managers and try again
|
|
58
|
+
source_node_managers
|
|
59
|
+
|
|
60
|
+
if command -v node &> /dev/null; then
|
|
61
|
+
local version
|
|
62
|
+
version=$(node -v | sed 's/v//' | cut -d. -f1)
|
|
63
|
+
if [[ "$version" -ge 20 ]]; then
|
|
64
|
+
local node_path=$(command -v node)
|
|
65
|
+
local manager=""
|
|
66
|
+
|
|
67
|
+
# Detect which manager provided it
|
|
68
|
+
if [[ "$node_path" == *"nvm"* ]]; then
|
|
69
|
+
manager=" (via nvm)"
|
|
70
|
+
elif [[ "$node_path" == *"fnm"* ]]; then
|
|
71
|
+
manager=" (via fnm)"
|
|
72
|
+
elif [[ "$node_path" == *"asdf"* ]]; then
|
|
73
|
+
manager=" (via asdf)"
|
|
74
|
+
elif [[ "$node_path" == *"volta"* ]]; then
|
|
75
|
+
manager=" (via volta)"
|
|
76
|
+
elif [[ "$node_path" == *"homebrew"* ]] || [[ "$node_path" == "/opt/homebrew"* ]] || [[ "$node_path" == "/usr/local"* ]]; then
|
|
77
|
+
manager=" (via Homebrew)"
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
log_success "Found Node.js v$(node -v | sed 's/v//')$manager at $node_path"
|
|
81
|
+
return 0
|
|
82
|
+
fi
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
return 1
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
# Check if ripgrep is available
|
|
89
|
+
check_ripgrep() {
|
|
90
|
+
if command -v rg &> /dev/null; then
|
|
91
|
+
local rg_path=$(command -v rg)
|
|
92
|
+
local rg_version=$(rg --version 2>/dev/null | head -n1 | awk '{print $2}' || echo "unknown")
|
|
93
|
+
log_success "Found ripgrep $rg_version at $rg_path"
|
|
94
|
+
return 0
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
# Source common paths
|
|
98
|
+
source_node_managers
|
|
99
|
+
|
|
100
|
+
if command -v rg &> /dev/null; then
|
|
101
|
+
local rg_path=$(command -v rg)
|
|
102
|
+
local rg_version=$(rg --version 2>/dev/null | head -n1 | awk '{print $2}' || echo "unknown")
|
|
103
|
+
log_success "Found ripgrep $rg_version at $rg_path"
|
|
104
|
+
return 0
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
return 1
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
# Check if git is available
|
|
111
|
+
check_git() {
|
|
112
|
+
if command -v git &> /dev/null; then
|
|
113
|
+
local git_path=$(command -v git)
|
|
114
|
+
local git_version=$(git --version 2>/dev/null | awk '{print $3}' || echo "unknown")
|
|
115
|
+
log_success "Found git $git_version at $git_path"
|
|
116
|
+
return 0
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# Check common locations
|
|
120
|
+
for git_path in /usr/bin/git /usr/local/bin/git /opt/homebrew/bin/git; do
|
|
121
|
+
if [[ -x "$git_path" ]]; then
|
|
122
|
+
export PATH="$(dirname "$git_path"):$PATH"
|
|
123
|
+
local git_version=$(git --version 2>/dev/null | awk '{print $3}' || echo "unknown")
|
|
124
|
+
log_success "Found git $git_version at $git_path"
|
|
125
|
+
return 0
|
|
126
|
+
fi
|
|
127
|
+
done
|
|
128
|
+
|
|
129
|
+
return 1
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
# Check if tmux is available
|
|
133
|
+
check_tmux() {
|
|
134
|
+
if command -v tmux &> /dev/null; then
|
|
135
|
+
local tmux_path=$(command -v tmux)
|
|
136
|
+
local tmux_version=$(tmux -V 2>/dev/null | awk '{print $2}' || echo "unknown")
|
|
137
|
+
log_success "Found tmux $tmux_version at $tmux_path"
|
|
138
|
+
return 0
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
# Source common paths and check again
|
|
142
|
+
source_node_managers
|
|
143
|
+
|
|
144
|
+
if command -v tmux &> /dev/null; then
|
|
145
|
+
local tmux_path=$(command -v tmux)
|
|
146
|
+
local tmux_version=$(tmux -V 2>/dev/null | awk '{print $2}' || echo "unknown")
|
|
147
|
+
log_success "Found tmux $tmux_version at $tmux_path"
|
|
148
|
+
return 0
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
return 1
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
install_homebrew() {
|
|
155
|
+
if command -v brew &> /dev/null; then
|
|
156
|
+
return 0
|
|
157
|
+
fi
|
|
158
|
+
|
|
159
|
+
log_info "Installing Homebrew..."
|
|
160
|
+
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
|
161
|
+
|
|
162
|
+
# Add to path for current session
|
|
163
|
+
if [[ -f /opt/homebrew/bin/brew ]]; then
|
|
164
|
+
eval "$(/opt/homebrew/bin/brew shellenv)"
|
|
165
|
+
elif [[ -f /usr/local/bin/brew ]]; then
|
|
166
|
+
eval "$(/usr/local/bin/brew shellenv)"
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
# Add to shell profile so it's available in future sessions
|
|
170
|
+
local shell_profile=""
|
|
171
|
+
if [[ -n "$ZSH_VERSION" ]] && [[ -f "$HOME/.zshrc" ]]; then
|
|
172
|
+
shell_profile="$HOME/.zshrc"
|
|
173
|
+
elif [[ -n "$BASH_VERSION" ]] && [[ -f "$HOME/.bashrc" ]]; then
|
|
174
|
+
shell_profile="$HOME/.bashrc"
|
|
175
|
+
elif [[ -f "$HOME/.bash_profile" ]]; then
|
|
176
|
+
shell_profile="$HOME/.bash_profile"
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
if [[ -n "$shell_profile" ]]; then
|
|
180
|
+
if ! grep -q "brew shellenv" "$shell_profile"; then
|
|
181
|
+
echo '' >> "$shell_profile"
|
|
182
|
+
echo '# Homebrew' >> "$shell_profile"
|
|
183
|
+
if [[ -f /opt/homebrew/bin/brew ]]; then
|
|
184
|
+
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> "$shell_profile"
|
|
185
|
+
elif [[ -f /usr/local/bin/brew ]]; then
|
|
186
|
+
echo 'eval "$(/usr/local/bin/brew shellenv)"' >> "$shell_profile"
|
|
187
|
+
fi
|
|
188
|
+
fi
|
|
189
|
+
fi
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
install_node() {
|
|
193
|
+
if command -v node &> /dev/null; then
|
|
194
|
+
local version
|
|
195
|
+
version=$(node -v | sed 's/v//' | cut -d. -f1)
|
|
196
|
+
if [[ "$version" -ge 20 ]]; then
|
|
197
|
+
return 0
|
|
198
|
+
fi
|
|
199
|
+
log_warn "Node.js $version found, but 20+ required"
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
log_info "Installing Node.js..."
|
|
203
|
+
|
|
204
|
+
case "$OS" in
|
|
205
|
+
macos)
|
|
206
|
+
# Check if user is admin - if not, use fnm (user-space install)
|
|
207
|
+
if ! groups | grep -q admin; then
|
|
208
|
+
log_info "Non-admin user detected - using fnm (Fast Node Manager)"
|
|
209
|
+
log_info "This installs Node.js to your home directory (no sudo needed)"
|
|
210
|
+
|
|
211
|
+
# Install fnm
|
|
212
|
+
curl -fsSL https://fnm.vercel.app/install | bash -s -- --skip-shell
|
|
213
|
+
|
|
214
|
+
# Add fnm to path for current session
|
|
215
|
+
export PATH="$HOME/.local/share/fnm:$PATH"
|
|
216
|
+
eval "$(fnm env --use-on-cd)"
|
|
217
|
+
|
|
218
|
+
# Install and use Node.js 20
|
|
219
|
+
fnm install 20
|
|
220
|
+
fnm use 20
|
|
221
|
+
|
|
222
|
+
# Add fnm to shell profile
|
|
223
|
+
local shell_profile=""
|
|
224
|
+
if [[ -f "$HOME/.zshrc" ]]; then
|
|
225
|
+
shell_profile="$HOME/.zshrc"
|
|
226
|
+
elif [[ -f "$HOME/.bashrc" ]]; then
|
|
227
|
+
shell_profile="$HOME/.bashrc"
|
|
228
|
+
elif [[ -f "$HOME/.bash_profile" ]]; then
|
|
229
|
+
shell_profile="$HOME/.bash_profile"
|
|
230
|
+
fi
|
|
231
|
+
|
|
232
|
+
if [[ -n "$shell_profile" ]]; then
|
|
233
|
+
if ! grep -q "fnm env" "$shell_profile"; then
|
|
234
|
+
echo '' >> "$shell_profile"
|
|
235
|
+
echo '# fnm (Fast Node Manager)' >> "$shell_profile"
|
|
236
|
+
echo 'eval "$(fnm env --use-on-cd)"' >> "$shell_profile"
|
|
237
|
+
log_info "Added fnm to $shell_profile"
|
|
238
|
+
fi
|
|
239
|
+
fi
|
|
240
|
+
else
|
|
241
|
+
# Admin user - use Homebrew
|
|
242
|
+
install_homebrew
|
|
243
|
+
brew install node
|
|
244
|
+
fi
|
|
245
|
+
;;
|
|
246
|
+
debian)
|
|
247
|
+
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
|
|
248
|
+
sudo apt-get install -y nodejs
|
|
249
|
+
;;
|
|
250
|
+
redhat)
|
|
251
|
+
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
|
|
252
|
+
sudo yum install -y nodejs
|
|
253
|
+
;;
|
|
254
|
+
*)
|
|
255
|
+
log_error "Please install Node.js 20+ manually: https://nodejs.org"
|
|
256
|
+
exit 1
|
|
257
|
+
;;
|
|
258
|
+
esac
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
install_git() {
|
|
262
|
+
if command -v git &> /dev/null; then
|
|
263
|
+
return 0
|
|
264
|
+
fi
|
|
265
|
+
|
|
266
|
+
log_info "Installing git..."
|
|
267
|
+
|
|
268
|
+
case "$OS" in
|
|
269
|
+
macos)
|
|
270
|
+
xcode-select --install 2>/dev/null || true
|
|
271
|
+
until command -v git &> /dev/null; do
|
|
272
|
+
sleep 5
|
|
273
|
+
done
|
|
274
|
+
;;
|
|
275
|
+
debian)
|
|
276
|
+
sudo apt-get update
|
|
277
|
+
sudo apt-get install -y git
|
|
278
|
+
;;
|
|
279
|
+
redhat)
|
|
280
|
+
sudo yum install -y git
|
|
281
|
+
;;
|
|
282
|
+
esac
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
install_tmux() {
|
|
286
|
+
if command -v tmux &> /dev/null; then
|
|
287
|
+
return 0
|
|
288
|
+
fi
|
|
289
|
+
|
|
290
|
+
log_info "Installing tmux..."
|
|
291
|
+
|
|
292
|
+
case "$OS" in
|
|
293
|
+
macos)
|
|
294
|
+
# Check if user is admin
|
|
295
|
+
if ! groups | grep -q admin; then
|
|
296
|
+
log_error "tmux requires admin privileges to install via Homebrew."
|
|
297
|
+
log_error ""
|
|
298
|
+
log_error "Option 1: Ask your administrator to run: brew install tmux"
|
|
299
|
+
log_error "Option 2: Make yourself an admin:"
|
|
300
|
+
log_error " - Open System Settings → Users & Groups"
|
|
301
|
+
log_error " - Unlock and check 'Allow user to administer this computer'"
|
|
302
|
+
exit 1
|
|
303
|
+
else
|
|
304
|
+
install_homebrew
|
|
305
|
+
brew install tmux
|
|
306
|
+
fi
|
|
307
|
+
;;
|
|
308
|
+
debian)
|
|
309
|
+
sudo apt-get update
|
|
310
|
+
sudo apt-get install -y tmux
|
|
311
|
+
;;
|
|
312
|
+
redhat)
|
|
313
|
+
sudo yum install -y tmux
|
|
314
|
+
;;
|
|
315
|
+
esac
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
install_ripgrep() {
|
|
319
|
+
if command -v rg &> /dev/null; then
|
|
320
|
+
return 0
|
|
321
|
+
fi
|
|
322
|
+
|
|
323
|
+
log_info "Installing ripgrep..."
|
|
324
|
+
|
|
325
|
+
case "$OS" in
|
|
326
|
+
macos)
|
|
327
|
+
# Check if user is admin
|
|
328
|
+
if ! groups | grep -q admin; then
|
|
329
|
+
# Non-admin: download pre-built binary from GitHub
|
|
330
|
+
log_info "Non-admin user - downloading pre-built ripgrep binary"
|
|
331
|
+
|
|
332
|
+
local arch
|
|
333
|
+
arch=$(uname -m)
|
|
334
|
+
local target
|
|
335
|
+
if [[ "$arch" == "arm64" ]]; then
|
|
336
|
+
target="aarch64-apple-darwin"
|
|
337
|
+
else
|
|
338
|
+
target="x86_64-apple-darwin"
|
|
339
|
+
fi
|
|
340
|
+
|
|
341
|
+
local version="14.1.0"
|
|
342
|
+
local url="https://github.com/BurntSushi/ripgrep/releases/download/${version}/ripgrep-${version}-${target}.tar.gz"
|
|
343
|
+
local tmp_dir="/tmp/ripgrep-install"
|
|
344
|
+
|
|
345
|
+
mkdir -p "$tmp_dir"
|
|
346
|
+
mkdir -p "$HOME/.local/bin"
|
|
347
|
+
|
|
348
|
+
curl -fsSL "$url" | tar -xz -C "$tmp_dir"
|
|
349
|
+
mv "$tmp_dir/ripgrep-${version}-${target}/rg" "$HOME/.local/bin/rg"
|
|
350
|
+
chmod +x "$HOME/.local/bin/rg"
|
|
351
|
+
rm -rf "$tmp_dir"
|
|
352
|
+
|
|
353
|
+
# Add to PATH if not already there
|
|
354
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
355
|
+
|
|
356
|
+
# Add to shell profile
|
|
357
|
+
local shell_profile=""
|
|
358
|
+
if [[ -f "$HOME/.zshrc" ]]; then
|
|
359
|
+
shell_profile="$HOME/.zshrc"
|
|
360
|
+
elif [[ -f "$HOME/.bashrc" ]]; then
|
|
361
|
+
shell_profile="$HOME/.bashrc"
|
|
362
|
+
elif [[ -f "$HOME/.bash_profile" ]]; then
|
|
363
|
+
shell_profile="$HOME/.bash_profile"
|
|
364
|
+
fi
|
|
365
|
+
|
|
366
|
+
if [[ -n "$shell_profile" ]]; then
|
|
367
|
+
if ! grep -q '.local/bin' "$shell_profile"; then
|
|
368
|
+
echo '' >> "$shell_profile"
|
|
369
|
+
echo '# Add local bin to PATH' >> "$shell_profile"
|
|
370
|
+
echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$shell_profile"
|
|
371
|
+
fi
|
|
372
|
+
fi
|
|
373
|
+
|
|
374
|
+
log_success "ripgrep installed to ~/.local/bin/rg"
|
|
375
|
+
else
|
|
376
|
+
# Admin user - use Homebrew
|
|
377
|
+
install_homebrew
|
|
378
|
+
brew install ripgrep
|
|
379
|
+
fi
|
|
380
|
+
;;
|
|
381
|
+
debian)
|
|
382
|
+
sudo apt-get update
|
|
383
|
+
sudo apt-get install -y ripgrep
|
|
384
|
+
;;
|
|
385
|
+
redhat)
|
|
386
|
+
sudo yum install -y ripgrep
|
|
387
|
+
;;
|
|
388
|
+
esac
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
check_and_install_prerequisites() {
|
|
392
|
+
log_info "Checking prerequisites..."
|
|
393
|
+
|
|
394
|
+
local missing=()
|
|
395
|
+
|
|
396
|
+
# Check Node.js (with version manager detection)
|
|
397
|
+
if ! check_node; then
|
|
398
|
+
missing+=("node")
|
|
399
|
+
fi
|
|
400
|
+
|
|
401
|
+
# Check git (with path detection)
|
|
402
|
+
if ! check_git; then
|
|
403
|
+
missing+=("git")
|
|
404
|
+
fi
|
|
405
|
+
|
|
406
|
+
# Check tmux (with path detection)
|
|
407
|
+
if ! check_tmux; then
|
|
408
|
+
missing+=("tmux")
|
|
409
|
+
fi
|
|
410
|
+
|
|
411
|
+
# Check ripgrep (with path detection)
|
|
412
|
+
if ! check_ripgrep; then
|
|
413
|
+
missing+=("ripgrep")
|
|
414
|
+
fi
|
|
415
|
+
|
|
416
|
+
if [[ ${#missing[@]} -eq 0 ]]; then
|
|
417
|
+
log_success "All prerequisites met"
|
|
418
|
+
return 0
|
|
419
|
+
fi
|
|
420
|
+
|
|
421
|
+
log_warn "Missing prerequisites: ${missing[*]}"
|
|
422
|
+
|
|
423
|
+
if is_interactive; then
|
|
424
|
+
if ! prompt_yn "Install missing prerequisites?"; then
|
|
425
|
+
log_error "Please install manually: ${missing[*]}"
|
|
426
|
+
exit 1
|
|
427
|
+
fi
|
|
428
|
+
fi
|
|
429
|
+
|
|
430
|
+
for dep in "${missing[@]}"; do
|
|
431
|
+
case "$dep" in
|
|
432
|
+
node) install_node ;;
|
|
433
|
+
git) install_git ;;
|
|
434
|
+
tmux) install_tmux ;;
|
|
435
|
+
ripgrep) install_ripgrep ;;
|
|
436
|
+
esac
|
|
437
|
+
done
|
|
438
|
+
|
|
439
|
+
log_success "Prerequisites installed"
|
|
440
|
+
|
|
441
|
+
configure_tmux
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
configure_tmux() {
|
|
445
|
+
local tmux_conf="$HOME/.tmux.conf"
|
|
446
|
+
if [ ! -f "$tmux_conf" ] || ! grep -q "mouse on" "$tmux_conf" 2>/dev/null; then
|
|
447
|
+
log_info "Configuring tmux for ClaudeDeck..."
|
|
448
|
+
cat >> "$tmux_conf" << 'TMUX'
|
|
449
|
+
|
|
450
|
+
# ClaudeDeck: enable mouse for scroll support in web terminal
|
|
451
|
+
set -g mouse on
|
|
452
|
+
set -g history-limit 50000
|
|
453
|
+
set -g default-terminal "xterm-256color"
|
|
454
|
+
set -ga terminal-overrides ",xterm-256color:Tc"
|
|
455
|
+
TMUX
|
|
456
|
+
log_success "tmux configured (mouse on, 50k history)"
|
|
457
|
+
fi
|
|
458
|
+
|
|
459
|
+
if tmux list-sessions &>/dev/null; then
|
|
460
|
+
tmux set -g mouse on 2>/dev/null || true
|
|
461
|
+
fi
|
|
462
|
+
}
|
package/scripts/setup.sh
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -e
|
|
3
|
+
|
|
4
|
+
echo "ClaudeDeck Setup"
|
|
5
|
+
echo "=============="
|
|
6
|
+
echo ""
|
|
7
|
+
|
|
8
|
+
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
|
|
9
|
+
|
|
10
|
+
# ── Node.js ──────────────────────────────────────────────
|
|
11
|
+
if ! command -v node &> /dev/null; then
|
|
12
|
+
echo "Error: Node.js is not installed"
|
|
13
|
+
echo "Install Node.js 20+ from https://nodejs.org"
|
|
14
|
+
exit 1
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
|
|
18
|
+
if [ "$NODE_VERSION" -lt 20 ]; then
|
|
19
|
+
echo "Error: Node.js 20+ required (found v$NODE_VERSION)"
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
echo "✓ Node.js: $(node -v)"
|
|
23
|
+
|
|
24
|
+
# ── pnpm ─────────────────────────────────────────────────
|
|
25
|
+
if ! command -v pnpm &> /dev/null; then
|
|
26
|
+
echo "Installing pnpm..."
|
|
27
|
+
npm install -g pnpm
|
|
28
|
+
fi
|
|
29
|
+
echo "✓ pnpm: $(pnpm -v)"
|
|
30
|
+
|
|
31
|
+
# ── Build tools (for native modules: node-pty, better-sqlite3) ──
|
|
32
|
+
if [[ "$OS" == "linux" ]]; then
|
|
33
|
+
if ! dpkg -s build-essential &> /dev/null 2>&1; then
|
|
34
|
+
echo "Installing build tools..."
|
|
35
|
+
sudo apt-get update -qq
|
|
36
|
+
sudo apt-get install -y -qq build-essential python3
|
|
37
|
+
fi
|
|
38
|
+
echo "✓ Build tools: installed"
|
|
39
|
+
elif [[ "$OS" == "darwin" ]]; then
|
|
40
|
+
if ! xcode-select -p &> /dev/null 2>&1; then
|
|
41
|
+
echo "Installing Xcode Command Line Tools..."
|
|
42
|
+
xcode-select --install
|
|
43
|
+
echo "Re-run this script after installation completes."
|
|
44
|
+
exit 0
|
|
45
|
+
fi
|
|
46
|
+
echo "✓ Xcode CLT: installed"
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# ── tmux ─────────────────────────────────────────────────
|
|
50
|
+
if ! command -v tmux &> /dev/null; then
|
|
51
|
+
echo "Installing tmux..."
|
|
52
|
+
if [[ "$OS" == "linux" ]]; then
|
|
53
|
+
sudo apt-get install -y -qq tmux
|
|
54
|
+
elif [[ "$OS" == "darwin" ]]; then
|
|
55
|
+
brew install tmux
|
|
56
|
+
else
|
|
57
|
+
echo "Error: Install tmux manually"
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
60
|
+
fi
|
|
61
|
+
echo "✓ tmux: $(tmux -V)"
|
|
62
|
+
|
|
63
|
+
# ── tmux configuration ──────────────────────────────────
|
|
64
|
+
TMUX_CONF="$HOME/.tmux.conf"
|
|
65
|
+
if [ ! -f "$TMUX_CONF" ] || ! grep -q "mouse on" "$TMUX_CONF" 2>/dev/null; then
|
|
66
|
+
echo "Configuring tmux (mouse on for scroll support)..."
|
|
67
|
+
cat >> "$TMUX_CONF" << 'TMUX'
|
|
68
|
+
|
|
69
|
+
# ClaudeDeck: enable mouse for scroll support in web terminal
|
|
70
|
+
set -g mouse on
|
|
71
|
+
set -g history-limit 50000
|
|
72
|
+
set -g default-terminal "xterm-256color"
|
|
73
|
+
set -ga terminal-overrides ",xterm-256color:Tc"
|
|
74
|
+
TMUX
|
|
75
|
+
fi
|
|
76
|
+
echo "✓ tmux: mouse on configured"
|
|
77
|
+
|
|
78
|
+
# ── git ──────────────────────────────────────────────────
|
|
79
|
+
if ! command -v git &> /dev/null; then
|
|
80
|
+
echo "Error: git is not installed"
|
|
81
|
+
exit 1
|
|
82
|
+
fi
|
|
83
|
+
echo "✓ git: $(git --version | awk '{print $3}')"
|
|
84
|
+
|
|
85
|
+
# ── ripgrep (for code search) ────────────────────────────
|
|
86
|
+
if ! command -v rg &> /dev/null; then
|
|
87
|
+
echo "Installing ripgrep..."
|
|
88
|
+
if [[ "$OS" == "linux" ]]; then
|
|
89
|
+
sudo apt-get install -y -qq ripgrep
|
|
90
|
+
elif [[ "$OS" == "darwin" ]]; then
|
|
91
|
+
brew install ripgrep
|
|
92
|
+
fi
|
|
93
|
+
fi
|
|
94
|
+
if command -v rg &> /dev/null; then
|
|
95
|
+
echo "✓ ripgrep: $(rg --version | head -1 | awk '{print $2}')"
|
|
96
|
+
else
|
|
97
|
+
echo "⚠ ripgrep: not found (code search will be disabled)"
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# ── Claude Code CLI ──────────────────────────────────────
|
|
101
|
+
if ! command -v claude &> /dev/null; then
|
|
102
|
+
echo ""
|
|
103
|
+
echo "Claude Code CLI not found. Install with:"
|
|
104
|
+
echo " npm install -g @anthropic-ai/claude-code"
|
|
105
|
+
echo ""
|
|
106
|
+
echo "⚠ ClaudeDeck requires at least one AI CLI to function."
|
|
107
|
+
else
|
|
108
|
+
echo "✓ Claude CLI: installed"
|
|
109
|
+
fi
|
|
110
|
+
|
|
111
|
+
# ── Environment ──────────────────────────────────────────
|
|
112
|
+
if [ ! -f .env ]; then
|
|
113
|
+
if [ -f .env.example ]; then
|
|
114
|
+
cp .env.example .env
|
|
115
|
+
echo "✓ Created .env from .env.example"
|
|
116
|
+
fi
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
# ── Data directory ───────────────────────────────────────
|
|
120
|
+
mkdir -p "$HOME/.claude-deck"
|
|
121
|
+
echo "✓ Data dir: ~/.claude-deck/"
|
|
122
|
+
|
|
123
|
+
# ── Install dependencies ────────────────────────────────
|
|
124
|
+
echo ""
|
|
125
|
+
echo "Installing dependencies..."
|
|
126
|
+
pnpm install
|
|
127
|
+
|
|
128
|
+
echo ""
|
|
129
|
+
echo "✓ Setup complete!"
|
|
130
|
+
echo ""
|
|
131
|
+
echo " Development: pnpm dev"
|
|
132
|
+
echo " Production: pnpm start"
|
|
133
|
+
echo " Port: ${PORT:-3011}"
|
|
134
|
+
echo ""
|