claudepod 1.0.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.
- package/.devcontainer/config/claude/settings.json +179 -0
- package/.devcontainer/devcontainer.json +110 -0
- package/.devcontainer/post-create.sh +400 -0
- package/.devcontainer/post-start.sh +370 -0
- package/.devcontainer/setup-zsh.sh +385 -0
- package/README.md +189 -0
- package/package.json +39 -0
- package/setup.js +75 -0
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
{
|
|
2
|
+
"includeCoAuthoredBy": false,
|
|
3
|
+
"model": "claude-sonnet-4-0",
|
|
4
|
+
"forceLoginMethod": "claudeai",
|
|
5
|
+
"permissions": {
|
|
6
|
+
"allow": [
|
|
7
|
+
"Bash",
|
|
8
|
+
"Write",
|
|
9
|
+
"TodoWrite",
|
|
10
|
+
"mcp__serena__find_file",
|
|
11
|
+
"mcp__serena__list_dir",
|
|
12
|
+
"mcp__serena__search_for_pattern",
|
|
13
|
+
"mcp__serena__replace_regex",
|
|
14
|
+
"mcp__serena__get_symbols_overview",
|
|
15
|
+
"mcp__serena__find_symbol",
|
|
16
|
+
"mcp__serena__find_referencing_symbols",
|
|
17
|
+
"mcp__serena__replace_symbol_body",
|
|
18
|
+
"mcp__serena__insert_after_symbol",
|
|
19
|
+
"mcp__serena__insert_before_symbol",
|
|
20
|
+
"mcp__serena__read_memory",
|
|
21
|
+
"mcp__serena__write_memory",
|
|
22
|
+
"mcp__serena__list_memories",
|
|
23
|
+
"mcp__serena__delete_memory",
|
|
24
|
+
"mcp__serena__restart_language_server",
|
|
25
|
+
"mcp__serena__onboarding",
|
|
26
|
+
"mcp__serena__check_onboarding_performed",
|
|
27
|
+
"mcp__serena__think_about_collected_information",
|
|
28
|
+
"mcp__serena__think_about_task_adherence",
|
|
29
|
+
"mcp__serena__think_about_whether_you_are_done",
|
|
30
|
+
"mcp__tavily-search__tavily_search",
|
|
31
|
+
"mcp__tavily-search__tavily_extract",
|
|
32
|
+
"mcp__tavily-search__tavily_crawl",
|
|
33
|
+
"mcp__tavily-search__tavily_map",
|
|
34
|
+
"mcp__ide__getDiagnostics",
|
|
35
|
+
"mcp__ide__executeCode",
|
|
36
|
+
"ListMcpResourcesTool",
|
|
37
|
+
"ReadMcpResourceTool",
|
|
38
|
+
"mcp__ref-tools__search",
|
|
39
|
+
"mcp__ref-tools__get_document",
|
|
40
|
+
"mcp__ref-tools__get_page_content",
|
|
41
|
+
"mcp__ref-tools__search_docs",
|
|
42
|
+
"mcp__ref-tools__get_api_reference",
|
|
43
|
+
"mcp__taskmaster-ai__get_tasks",
|
|
44
|
+
"mcp__taskmaster-ai__next_task",
|
|
45
|
+
"mcp__taskmaster-ai__get_task",
|
|
46
|
+
"mcp__taskmaster-ai__set_task_status",
|
|
47
|
+
"mcp__taskmaster-ai__add_task",
|
|
48
|
+
"mcp__taskmaster-ai__update_task",
|
|
49
|
+
"mcp__taskmaster-ai__expand_task",
|
|
50
|
+
"mcp__taskmaster-ai__parse_prd",
|
|
51
|
+
"mcp__taskmaster-ai__initialize_project",
|
|
52
|
+
"mcp__taskmaster-ai__expand_all",
|
|
53
|
+
"mcp__taskmaster-ai__update_subtask",
|
|
54
|
+
"mcp__taskmaster-ai__models",
|
|
55
|
+
"mcp__taskmaster-ai__analyze_project_complexity",
|
|
56
|
+
"mcp__taskmaster-ai__research",
|
|
57
|
+
"mcp__github__get_me",
|
|
58
|
+
"mcp__github__get_file_contents",
|
|
59
|
+
"mcp__github__create_or_update_file",
|
|
60
|
+
"mcp__github__delete_file",
|
|
61
|
+
"mcp__github__list_branches",
|
|
62
|
+
"mcp__github__create_branch",
|
|
63
|
+
"mcp__github__get_pull_request",
|
|
64
|
+
"mcp__github__create_pull_request",
|
|
65
|
+
"mcp__github__list_pull_requests",
|
|
66
|
+
"mcp__github__get_pull_request_diff",
|
|
67
|
+
"mcp__github__get_issue",
|
|
68
|
+
"mcp__github__create_issue",
|
|
69
|
+
"mcp__github__list_issues",
|
|
70
|
+
"mcp__github__add_issue_comment",
|
|
71
|
+
"mcp__github__push_files",
|
|
72
|
+
"mcp__github__get_pull_request_files",
|
|
73
|
+
"mcp__github__get_pull_request_comments",
|
|
74
|
+
"mcp__github__merge_pull_request",
|
|
75
|
+
"mcp__github__list_commits",
|
|
76
|
+
"mcp__github__get_commit",
|
|
77
|
+
"mcp__github__update_pull_request",
|
|
78
|
+
"mcp__github__get_issue_comments",
|
|
79
|
+
"mcp__github__search_repositories",
|
|
80
|
+
"mcp__github__search_code",
|
|
81
|
+
"mcp__github__fork_repository",
|
|
82
|
+
"mcp__github__create_repository",
|
|
83
|
+
"mcp__github__list_tags",
|
|
84
|
+
"mcp__ccusage__daily",
|
|
85
|
+
"mcp__ccusage__session"
|
|
86
|
+
],
|
|
87
|
+
"deny": [
|
|
88
|
+
"Read",
|
|
89
|
+
"Edit",
|
|
90
|
+
"MultiEdit",
|
|
91
|
+
"Glob",
|
|
92
|
+
"Grep",
|
|
93
|
+
"LS",
|
|
94
|
+
"Task",
|
|
95
|
+
"ExitPlanMode",
|
|
96
|
+
"NotebookEdit",
|
|
97
|
+
"WebFetch",
|
|
98
|
+
"WebSearch",
|
|
99
|
+
"mcp__deepwiki__read_wiki_structure",
|
|
100
|
+
"mcp__deepwiki__read_wiki_contents",
|
|
101
|
+
"mcp__deepwiki__ask_question",
|
|
102
|
+
"mcp__taskmaster-ai__rules",
|
|
103
|
+
"mcp__taskmaster-ai__scope_up_task",
|
|
104
|
+
"mcp__taskmaster-ai__scope_down_task",
|
|
105
|
+
"mcp__taskmaster-ai__complexity_report",
|
|
106
|
+
"mcp__taskmaster-ai__generate",
|
|
107
|
+
"mcp__taskmaster-ai__add_subtask",
|
|
108
|
+
"mcp__taskmaster-ai__update",
|
|
109
|
+
"mcp__taskmaster-ai__remove_task",
|
|
110
|
+
"mcp__taskmaster-ai__remove_subtask",
|
|
111
|
+
"mcp__taskmaster-ai__clear_subtasks",
|
|
112
|
+
"mcp__taskmaster-ai__move_task",
|
|
113
|
+
"mcp__taskmaster-ai__add_dependency",
|
|
114
|
+
"mcp__taskmaster-ai__remove_dependency",
|
|
115
|
+
"mcp__taskmaster-ai__validate_dependencies",
|
|
116
|
+
"mcp__taskmaster-ai__fix_dependencies",
|
|
117
|
+
"mcp__taskmaster-ai__response-language",
|
|
118
|
+
"mcp__taskmaster-ai__list_tags",
|
|
119
|
+
"mcp__taskmaster-ai__add_tag",
|
|
120
|
+
"mcp__taskmaster-ai__delete_tag",
|
|
121
|
+
"mcp__taskmaster-ai__use_tag",
|
|
122
|
+
"mcp__taskmaster-ai__rename_tag",
|
|
123
|
+
"mcp__taskmaster-ai__copy_tag",
|
|
124
|
+
"mcp__github__add_comment_to_pending_review",
|
|
125
|
+
"mcp__github__add_sub_issue",
|
|
126
|
+
"mcp__github__assign_copilot_to_issue",
|
|
127
|
+
"mcp__github__cancel_workflow_run",
|
|
128
|
+
"mcp__github__create_and_submit_pull_request_review",
|
|
129
|
+
"mcp__github__create_gist",
|
|
130
|
+
"mcp__github__create_pending_pull_request_review",
|
|
131
|
+
"mcp__github__delete_pending_pull_request_review",
|
|
132
|
+
"mcp__github__delete_workflow_run_logs",
|
|
133
|
+
"mcp__github__dismiss_notification",
|
|
134
|
+
"mcp__github__download_workflow_run_artifact",
|
|
135
|
+
"mcp__github__get_code_scanning_alert",
|
|
136
|
+
"mcp__github__get_dependabot_alert",
|
|
137
|
+
"mcp__github__get_discussion",
|
|
138
|
+
"mcp__github__get_discussion_comments",
|
|
139
|
+
"mcp__github__get_job_logs",
|
|
140
|
+
"mcp__github__get_notification_details",
|
|
141
|
+
"mcp__github__get_pull_request_reviews",
|
|
142
|
+
"mcp__github__get_pull_request_status",
|
|
143
|
+
"mcp__github__get_secret_scanning_alert",
|
|
144
|
+
"mcp__github__get_tag",
|
|
145
|
+
"mcp__github__get_workflow_run",
|
|
146
|
+
"mcp__github__get_workflow_run_logs",
|
|
147
|
+
"mcp__github__get_workflow_run_usage",
|
|
148
|
+
"mcp__github__list_code_scanning_alerts",
|
|
149
|
+
"mcp__github__list_dependabot_alerts",
|
|
150
|
+
"mcp__github__list_discussion_categories",
|
|
151
|
+
"mcp__github__list_discussions",
|
|
152
|
+
"mcp__github__list_gists",
|
|
153
|
+
"mcp__github__list_notifications",
|
|
154
|
+
"mcp__github__list_secret_scanning_alerts",
|
|
155
|
+
"mcp__github__list_sub_issues",
|
|
156
|
+
"mcp__github__list_workflow_jobs",
|
|
157
|
+
"mcp__github__list_workflow_run_artifacts",
|
|
158
|
+
"mcp__github__list_workflow_runs",
|
|
159
|
+
"mcp__github__list_workflows",
|
|
160
|
+
"mcp__github__manage_notification_subscription",
|
|
161
|
+
"mcp__github__manage_repository_notification_subscription",
|
|
162
|
+
"mcp__github__mark_all_notifications_read",
|
|
163
|
+
"mcp__github__remove_sub_issue",
|
|
164
|
+
"mcp__github__reprioritize_sub_issue",
|
|
165
|
+
"mcp__github__request_copilot_review",
|
|
166
|
+
"mcp__github__rerun_failed_jobs",
|
|
167
|
+
"mcp__github__rerun_workflow_run",
|
|
168
|
+
"mcp__github__run_workflow",
|
|
169
|
+
"mcp__github__search_issues",
|
|
170
|
+
"mcp__github__search_orgs",
|
|
171
|
+
"mcp__github__search_pull_requests",
|
|
172
|
+
"mcp__github__search_users",
|
|
173
|
+
"mcp__github__submit_pending_pull_request_review",
|
|
174
|
+
"mcp__github__update_gist",
|
|
175
|
+
"mcp__github__update_issue",
|
|
176
|
+
"mcp__github__update_pull_request_branch"
|
|
177
|
+
]
|
|
178
|
+
}
|
|
179
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ClaudePod Development Environment",
|
|
3
|
+
"image": "mcr.microsoft.com/vscode/devcontainers/base:ubuntu-22.04",
|
|
4
|
+
|
|
5
|
+
"features": {
|
|
6
|
+
"ghcr.io/devcontainers/features/common-utils:2": {
|
|
7
|
+
"installZsh": true,
|
|
8
|
+
"installOhMyZsh": true,
|
|
9
|
+
"username": "node",
|
|
10
|
+
"uid": 1000,
|
|
11
|
+
"gid": 1000,
|
|
12
|
+
"upgradePackages": true
|
|
13
|
+
},
|
|
14
|
+
"ghcr.io/devcontainers/features/node:1": {
|
|
15
|
+
"nodeGypDependencies": true,
|
|
16
|
+
"version": "20"
|
|
17
|
+
},
|
|
18
|
+
"ghcr.io/devcontainers/features/python:1": {
|
|
19
|
+
"version": "3.13",
|
|
20
|
+
"installTools": true,
|
|
21
|
+
"toolsToInstall": "flake8,autopep8,black,yapf,mypy,pydocstyle,pycodestyle,bandit,pipenv,virtualenv,pytest,pylint"
|
|
22
|
+
},
|
|
23
|
+
"ghcr.io/devcontainers/features/git:1": {
|
|
24
|
+
"version": "latest",
|
|
25
|
+
"ppa": false
|
|
26
|
+
},
|
|
27
|
+
"ghcr.io/devcontainers/features/github-cli:1": {
|
|
28
|
+
"version": "latest"
|
|
29
|
+
},
|
|
30
|
+
"ghcr.io/devcontainers/features/docker-in-docker:2": {
|
|
31
|
+
"version": "latest",
|
|
32
|
+
"dockerDashComposeVersion": "v2"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
"containerEnv": {
|
|
37
|
+
"CLAUDE_CONFIG_DIR": "/home/node/.claude",
|
|
38
|
+
"DEVCONTAINER": "true",
|
|
39
|
+
"TAVILY_API_KEY": "${localEnv:TAVILY_API_KEY}",
|
|
40
|
+
"REF_TOOLS_API_KEY": "${localEnv:REF_TOOLS_API_KEY}",
|
|
41
|
+
"GITHUB_PERSONAL_ACCESS_TOKEN": "${localEnv:GITHUB_PERSONAL_ACCESS_TOKEN}",
|
|
42
|
+
"GITHUB_API_URL": "${localEnv:GITHUB_API_URL}",
|
|
43
|
+
"GITHUB_TOOLSET": "${localEnv:GITHUB_TOOLSET}"
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
"mounts": [
|
|
47
|
+
"source=${localWorkspaceFolder}/.claude,target=/home/node/.claude,type=bind,consistency=cached",
|
|
48
|
+
"source=${localWorkspaceFolder}/.serena,target=/home/node/.serena,type=bind,consistency=cached",
|
|
49
|
+
"source=claudepod-bash-history,target=/home/node/.bash_history,type=volume",
|
|
50
|
+
"source=claudepod-zsh-history,target=/home/node/.zsh_history,type=volume",
|
|
51
|
+
"source=claudepod-npm-cache,target=/home/node/.npm,type=volume",
|
|
52
|
+
"source=claudepod-npm-config,target=/home/node/.config,type=volume",
|
|
53
|
+
"source=claudepod-npm-global,target=/home/node/.local,type=volume"
|
|
54
|
+
],
|
|
55
|
+
|
|
56
|
+
"postCreateCommand": "sudo -E /bin/bash .devcontainer/post-create.sh",
|
|
57
|
+
"postStartCommand": "/bin/bash .devcontainer/post-start.sh",
|
|
58
|
+
|
|
59
|
+
"forwardPorts": [],
|
|
60
|
+
"portsAttributes": {
|
|
61
|
+
"*": {
|
|
62
|
+
"onAutoForward": "openBrowserOnce"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"otherPortsAttributes": {
|
|
66
|
+
"onAutoForward": "openBrowser"
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
"customizations": {
|
|
70
|
+
"vscode": {
|
|
71
|
+
"extensions": [
|
|
72
|
+
"ms-vscode-remote.remote-containers",
|
|
73
|
+
"ms-vscode-remote.remote-ssh",
|
|
74
|
+
"ms-vscode-remote.remote-ssh-edit",
|
|
75
|
+
"ms-vscode.remote-explorer",
|
|
76
|
+
"ms-vscode-remote.vscode-remote-extensionpack",
|
|
77
|
+
"ms-python.python",
|
|
78
|
+
"ms-python.vscode-pylance",
|
|
79
|
+
"dbaeumer.vscode-eslint",
|
|
80
|
+
"esbenp.prettier-vscode",
|
|
81
|
+
"GitHub.vscode-pull-request-github",
|
|
82
|
+
"eamodio.gitlens"
|
|
83
|
+
],
|
|
84
|
+
"settings": {
|
|
85
|
+
"remote.SSH.defaultExtensions": [
|
|
86
|
+
"ms-vscode-remote.remote-ssh-edit"
|
|
87
|
+
],
|
|
88
|
+
"terminal.integrated.defaultProfile.linux": "zsh",
|
|
89
|
+
"terminal.integrated.profiles.linux": {
|
|
90
|
+
"zsh": {
|
|
91
|
+
"path": "/usr/bin/zsh",
|
|
92
|
+
"args": ["-l"]
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
"terminal.integrated.shell.linux": "/usr/bin/zsh",
|
|
96
|
+
"terminal.integrated.shellArgs.linux": ["-l"],
|
|
97
|
+
"terminal.integrated.fontFamily": "MesloLGS NF, 'Courier New', monospace",
|
|
98
|
+
"terminal.integrated.fontSize": 14
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
|
|
103
|
+
"remoteUser": "node",
|
|
104
|
+
"containerUser": "node",
|
|
105
|
+
|
|
106
|
+
"workspaceFolder": "/workspace",
|
|
107
|
+
"workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached",
|
|
108
|
+
|
|
109
|
+
"postAttachCommand": "sudo chown -R node:node /workspace"
|
|
110
|
+
}
|
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# ClaudePod Post-Create Script - Phases 2 & 4
|
|
5
|
+
# This script handles Claude Code installation, configuration, and development tools
|
|
6
|
+
|
|
7
|
+
echo "🚀 Starting ClaudePod post-create setup..."
|
|
8
|
+
|
|
9
|
+
# Source NVM to make npm available
|
|
10
|
+
# The Node.js feature installs via NVM at /usr/local/share/nvm
|
|
11
|
+
export NVM_DIR="/usr/local/share/nvm"
|
|
12
|
+
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
|
13
|
+
|
|
14
|
+
# Retry function for resilient installations
|
|
15
|
+
retry_command() {
|
|
16
|
+
local max_attempts=${1:-3}
|
|
17
|
+
local delay=${2:-5}
|
|
18
|
+
shift 2
|
|
19
|
+
local attempt=1
|
|
20
|
+
|
|
21
|
+
while [ $attempt -le $max_attempts ]; do
|
|
22
|
+
if "$@"; then
|
|
23
|
+
return 0
|
|
24
|
+
fi
|
|
25
|
+
echo "⚠️ Command failed (attempt $attempt/$max_attempts): $*"
|
|
26
|
+
if [ $attempt -lt $max_attempts ]; then
|
|
27
|
+
echo " Retrying in ${delay}s..."
|
|
28
|
+
sleep $delay
|
|
29
|
+
fi
|
|
30
|
+
((attempt++))
|
|
31
|
+
done
|
|
32
|
+
return 1
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# Function to install Claude Code
|
|
36
|
+
install_claude_code() {
|
|
37
|
+
echo "📦 Installing Claude Code..."
|
|
38
|
+
|
|
39
|
+
# Ensure PATH includes npm global bin directory
|
|
40
|
+
export PATH="/home/node/.local/bin:$PATH"
|
|
41
|
+
|
|
42
|
+
# Install Claude Code globally with retry logic
|
|
43
|
+
if retry_command 3 5 npm install -g @anthropic-ai/claude-code; then
|
|
44
|
+
echo "✅ Claude Code installed successfully"
|
|
45
|
+
|
|
46
|
+
# Verify installation with updated PATH
|
|
47
|
+
if command -v claude &> /dev/null || [ -f "/home/node/.local/bin/claude" ]; then
|
|
48
|
+
local version=$(/home/node/.local/bin/claude --version 2>/dev/null || echo "installed")
|
|
49
|
+
echo "📌 Claude Code version: $version"
|
|
50
|
+
return 0
|
|
51
|
+
else
|
|
52
|
+
echo "⚠️ Claude Code installed but 'claude' command not found"
|
|
53
|
+
echo "📍 Checking installation location..."
|
|
54
|
+
find /home/node/.local -name "claude" -type f 2>/dev/null || echo " No claude binary found"
|
|
55
|
+
return 1
|
|
56
|
+
fi
|
|
57
|
+
else
|
|
58
|
+
echo "❌ Failed to install Claude Code after multiple attempts"
|
|
59
|
+
return 1
|
|
60
|
+
fi
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# Function to setup workspace directories for bind mounts
|
|
64
|
+
setup_workspace_directories() {
|
|
65
|
+
echo "🔧 Setting up workspace configuration directories..."
|
|
66
|
+
|
|
67
|
+
# Create workspace directories for bind mounts
|
|
68
|
+
local workspace_dirs=(
|
|
69
|
+
"/workspace/.claude"
|
|
70
|
+
"/workspace/.serena"
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
for dir in "${workspace_dirs[@]}"; do
|
|
74
|
+
if [ ! -d "$dir" ]; then
|
|
75
|
+
mkdir -p "$dir"
|
|
76
|
+
echo "📁 Created workspace directory: $dir"
|
|
77
|
+
fi
|
|
78
|
+
# Set proper permissions
|
|
79
|
+
chown -R node:node "$dir"
|
|
80
|
+
chmod -R 755 "$dir"
|
|
81
|
+
done
|
|
82
|
+
|
|
83
|
+
# Setup Serena configuration if it doesn't exist
|
|
84
|
+
setup_serena_config
|
|
85
|
+
|
|
86
|
+
echo "✅ Workspace configuration directories ready"
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# Function to setup Serena configuration
|
|
90
|
+
setup_serena_config() {
|
|
91
|
+
local serena_config="/workspace/.serena/serena_config.yml"
|
|
92
|
+
|
|
93
|
+
if [ ! -f "$serena_config" ]; then
|
|
94
|
+
echo "📝 Creating Serena configuration..."
|
|
95
|
+
|
|
96
|
+
cat > "$serena_config" << 'EOF'
|
|
97
|
+
gui_log_window: False
|
|
98
|
+
# whether to open a graphical window with Serena's logs.
|
|
99
|
+
|
|
100
|
+
web_dashboard: True
|
|
101
|
+
# whether to open the Serena web dashboard (accessible through your web browser)
|
|
102
|
+
|
|
103
|
+
web_dashboard_open_on_launch: False
|
|
104
|
+
# whether to open a browser window with the web dashboard when Serena starts
|
|
105
|
+
# If set to False, you can still open the dashboard manually by navigating to
|
|
106
|
+
# http://localhost:24282/dashboard/ in your web browser
|
|
107
|
+
|
|
108
|
+
log_level: 20
|
|
109
|
+
# the minimum log level for the GUI log window and the dashboard (10 = debug, 20 = info, 30 = warning, 40 = error)
|
|
110
|
+
|
|
111
|
+
trace_lsp_communication: False
|
|
112
|
+
# whether to trace the communication between Serena and the language servers.
|
|
113
|
+
|
|
114
|
+
tool_timeout: 240
|
|
115
|
+
# timeout, in seconds, after which tool executions are terminated
|
|
116
|
+
|
|
117
|
+
excluded_tools: []
|
|
118
|
+
# list of tools to be globally excluded
|
|
119
|
+
|
|
120
|
+
included_optional_tools: []
|
|
121
|
+
# list of optional tools (which are disabled by default) to be included
|
|
122
|
+
|
|
123
|
+
jetbrains: False
|
|
124
|
+
# whether to enable JetBrains mode
|
|
125
|
+
|
|
126
|
+
record_tool_usage_stats: False
|
|
127
|
+
# whether to record tool usage statistics
|
|
128
|
+
|
|
129
|
+
token_count_estimator: TIKTOKEN_GPT4O
|
|
130
|
+
# token count estimator to use for tool usage statistics
|
|
131
|
+
|
|
132
|
+
# MANAGED BY SERENA, KEEP AT THE BOTTOM OF THE YAML AND DON'T EDIT WITHOUT NEED
|
|
133
|
+
# The list of registered projects.
|
|
134
|
+
projects: []
|
|
135
|
+
EOF
|
|
136
|
+
|
|
137
|
+
# Set proper ownership
|
|
138
|
+
chown node:node "$serena_config"
|
|
139
|
+
chmod 644 "$serena_config"
|
|
140
|
+
|
|
141
|
+
echo "✅ Serena configuration created with dashboard auto-open disabled"
|
|
142
|
+
else
|
|
143
|
+
echo "📁 Serena configuration already exists"
|
|
144
|
+
fi
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
# Function to setup Claude configuration directory
|
|
148
|
+
setup_claude_config() {
|
|
149
|
+
echo "🔧 Setting up Claude configuration..."
|
|
150
|
+
|
|
151
|
+
# Claude Code uses multiple possible config locations
|
|
152
|
+
local claude_dirs=(
|
|
153
|
+
"/home/node/.claude"
|
|
154
|
+
"/home/node/.config/claude"
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
for dir in "${claude_dirs[@]}"; do
|
|
158
|
+
if [ ! -d "$dir" ]; then
|
|
159
|
+
mkdir -p "$dir"
|
|
160
|
+
echo "📁 Created configuration directory: $dir"
|
|
161
|
+
fi
|
|
162
|
+
# Set proper permissions
|
|
163
|
+
chown -R node:node "$dir"
|
|
164
|
+
chmod -R 700 "$dir"
|
|
165
|
+
done
|
|
166
|
+
|
|
167
|
+
# Copy optimized settings.json from devcontainer config
|
|
168
|
+
local settings_source="/workspace/.devcontainer/config/claude/settings.json"
|
|
169
|
+
local settings_target="/home/node/.claude/settings.json"
|
|
170
|
+
|
|
171
|
+
if [ -f "$settings_source" ]; then
|
|
172
|
+
cp "$settings_source" "$settings_target"
|
|
173
|
+
chown node:node "$settings_target"
|
|
174
|
+
chmod 600 "$settings_target"
|
|
175
|
+
echo "📋 Copied optimized Claude settings (79 tools allowed)"
|
|
176
|
+
else
|
|
177
|
+
echo "⚠️ Claude settings template not found, using defaults"
|
|
178
|
+
fi
|
|
179
|
+
|
|
180
|
+
echo "✅ Claude configuration directories ready"
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
# Function to install ccusage CLI tool
|
|
184
|
+
install_ccusage() {
|
|
185
|
+
echo "📊 Installing ccusage..."
|
|
186
|
+
|
|
187
|
+
if retry_command 3 5 npm install -g ccusage; then
|
|
188
|
+
echo "✅ ccusage installed successfully"
|
|
189
|
+
|
|
190
|
+
# Verify installation
|
|
191
|
+
if [ -f "/home/node/.local/bin/ccusage" ] || command -v ccusage &> /dev/null; then
|
|
192
|
+
local version=$(/home/node/.local/bin/ccusage --version 2>/dev/null || echo "installed")
|
|
193
|
+
echo "📌 ccusage version: $version"
|
|
194
|
+
return 0
|
|
195
|
+
else
|
|
196
|
+
echo "⚠️ ccusage installed but command not found"
|
|
197
|
+
return 1
|
|
198
|
+
fi
|
|
199
|
+
else
|
|
200
|
+
echo "❌ Failed to install ccusage"
|
|
201
|
+
return 1
|
|
202
|
+
fi
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
# Function to install development tools
|
|
206
|
+
install_dev_tools() {
|
|
207
|
+
echo "🛠️ Installing additional development tools..."
|
|
208
|
+
|
|
209
|
+
# Install git-delta for better git diffs
|
|
210
|
+
echo "📦 Installing git-delta..."
|
|
211
|
+
if command -v cargo &> /dev/null; then
|
|
212
|
+
# If cargo is available, use it
|
|
213
|
+
cargo install git-delta
|
|
214
|
+
else
|
|
215
|
+
# Otherwise, download the binary
|
|
216
|
+
local delta_version="0.18.2"
|
|
217
|
+
local delta_url="https://github.com/dandavison/delta/releases/download/${delta_version}/delta-${delta_version}-x86_64-unknown-linux-musl.tar.gz"
|
|
218
|
+
|
|
219
|
+
if retry_command 2 5 wget -q -O /tmp/delta.tar.gz "$delta_url"; then
|
|
220
|
+
sudo tar -xzf /tmp/delta.tar.gz -C /usr/local/bin delta-${delta_version}-x86_64-unknown-linux-musl/delta --strip-components=1
|
|
221
|
+
sudo chmod +x /usr/local/bin/delta
|
|
222
|
+
rm -f /tmp/delta.tar.gz
|
|
223
|
+
echo "✅ git-delta installed successfully"
|
|
224
|
+
|
|
225
|
+
# Configure git to use delta
|
|
226
|
+
git config --global core.pager "delta"
|
|
227
|
+
git config --global interactive.diffFilter "delta --color-only"
|
|
228
|
+
git config --global delta.navigate true
|
|
229
|
+
git config --global delta.light false
|
|
230
|
+
git config --global delta.side-by-side true
|
|
231
|
+
else
|
|
232
|
+
echo "⚠️ Failed to install git-delta"
|
|
233
|
+
fi
|
|
234
|
+
fi
|
|
235
|
+
|
|
236
|
+
# Setup basic shell enhancements
|
|
237
|
+
setup_shell_config
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
# Function to setup enhanced ZSH configuration
|
|
241
|
+
setup_shell_config() {
|
|
242
|
+
echo "🐚 Setting up enhanced shell configuration..."
|
|
243
|
+
|
|
244
|
+
# Add PATH configuration to shell files
|
|
245
|
+
local shell_files=(
|
|
246
|
+
"/home/node/.bashrc"
|
|
247
|
+
"/home/node/.zshrc"
|
|
248
|
+
"/home/node/.profile"
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
for shell_file in "${shell_files[@]}"; do
|
|
252
|
+
# Ensure the shell file exists
|
|
253
|
+
touch "$shell_file"
|
|
254
|
+
|
|
255
|
+
# Add PATH and aliases if not already present
|
|
256
|
+
if ! grep -q "# ClaudePod custom configuration" "$shell_file" 2>/dev/null; then
|
|
257
|
+
cat >> "$shell_file" << 'EOF'
|
|
258
|
+
|
|
259
|
+
# ClaudePod custom configuration
|
|
260
|
+
export PATH="$HOME/.local/bin:$PATH"
|
|
261
|
+
|
|
262
|
+
# Git aliases
|
|
263
|
+
alias gs='git status'
|
|
264
|
+
alias gd='git diff'
|
|
265
|
+
alias gc='git commit'
|
|
266
|
+
alias gp='git push'
|
|
267
|
+
alias gl='git log --oneline --graph --decorate'
|
|
268
|
+
|
|
269
|
+
# Claude Code alias with permissions flag
|
|
270
|
+
alias claude='claude --model sonnet --dangerously-skip-permissions'
|
|
271
|
+
|
|
272
|
+
# List aliases
|
|
273
|
+
alias ll='ls -alF'
|
|
274
|
+
alias la='ls -A'
|
|
275
|
+
alias l='ls -CF'
|
|
276
|
+
EOF
|
|
277
|
+
fi
|
|
278
|
+
|
|
279
|
+
# Set proper ownership
|
|
280
|
+
chown node:node "$shell_file"
|
|
281
|
+
chmod 644 "$shell_file"
|
|
282
|
+
done
|
|
283
|
+
|
|
284
|
+
# Run ZSH enhancement setup as the node user if available
|
|
285
|
+
if [ -f ".devcontainer/setup-zsh.sh" ]; then
|
|
286
|
+
sudo -u node -E bash .devcontainer/setup-zsh.sh 2>/dev/null || {
|
|
287
|
+
echo "⚠️ ZSH setup encountered some non-critical errors, continuing..."
|
|
288
|
+
}
|
|
289
|
+
echo "✅ Enhanced ZSH configuration completed"
|
|
290
|
+
else
|
|
291
|
+
echo "✅ Basic shell configuration completed"
|
|
292
|
+
fi
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
# Function to display setup completion message
|
|
296
|
+
display_completion_message() {
|
|
297
|
+
echo ""
|
|
298
|
+
echo "════════════════════════════════════════════════════════════════"
|
|
299
|
+
echo "✅ ClaudePod setup complete!"
|
|
300
|
+
echo "════════════════════════════════════════════════════════════════"
|
|
301
|
+
echo ""
|
|
302
|
+
echo "🔑 Next steps:"
|
|
303
|
+
echo " 1. Run 'claude' to start using Claude Code"
|
|
304
|
+
echo " 2. Authentication will be handled on first use"
|
|
305
|
+
echo " 3. Your configuration will persist in the mounted volumes"
|
|
306
|
+
echo ""
|
|
307
|
+
echo "🛠️ Installed tools:"
|
|
308
|
+
echo " - Claude Code CLI"
|
|
309
|
+
echo " - ccusage (Claude Code usage analytics)"
|
|
310
|
+
echo " - git-delta (better git diffs)"
|
|
311
|
+
echo " - Shell aliases (gs, gd, gc, gp, gl)"
|
|
312
|
+
echo ""
|
|
313
|
+
echo "💡 Tip: Claude Code is now available globally as 'claude'"
|
|
314
|
+
echo "════════════════════════════════════════════════════════════════"
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
# Function to setup npm directories and permissions
|
|
318
|
+
setup_npm_permissions() {
|
|
319
|
+
echo "🔧 Setting up npm directories and permissions..."
|
|
320
|
+
|
|
321
|
+
# Create npm directories with correct ownership
|
|
322
|
+
local npm_dirs=(
|
|
323
|
+
"/home/node/.npm"
|
|
324
|
+
"/home/node/.npm/_cacache"
|
|
325
|
+
"/home/node/.npm/_logs"
|
|
326
|
+
"/home/node/.config"
|
|
327
|
+
"/home/node/.local"
|
|
328
|
+
"/home/node/.local/bin"
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
for dir in "${npm_dirs[@]}"; do
|
|
332
|
+
mkdir -p "$dir"
|
|
333
|
+
chown -R node:node "$dir"
|
|
334
|
+
chmod -R 755 "$dir"
|
|
335
|
+
done
|
|
336
|
+
|
|
337
|
+
# Remove any existing .npmrc directory/file and create .npmrc file
|
|
338
|
+
rm -rf /home/node/.npmrc
|
|
339
|
+
cat > /home/node/.npmrc << 'EOF'
|
|
340
|
+
cache=/home/node/.npm/_cacache
|
|
341
|
+
prefix=/home/node/.local
|
|
342
|
+
update-notifier=false
|
|
343
|
+
EOF
|
|
344
|
+
|
|
345
|
+
# Set proper ownership for .npmrc
|
|
346
|
+
chown node:node /home/node/.npmrc
|
|
347
|
+
chmod 644 /home/node/.npmrc
|
|
348
|
+
|
|
349
|
+
echo "✅ npm directories and permissions configured"
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
# Main execution
|
|
353
|
+
main() {
|
|
354
|
+
echo "════════════════════════════════════════════════════════════════"
|
|
355
|
+
echo "🐳 ClaudePod Post-Create Setup - Phases 2 & 4"
|
|
356
|
+
echo "════════════════════════════════════════════════════════════════"
|
|
357
|
+
|
|
358
|
+
# Source NVM and ensure PATH is set correctly for the entire script
|
|
359
|
+
export NVM_DIR="/usr/local/share/nvm"
|
|
360
|
+
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
|
361
|
+
export PATH="/home/node/.local/bin:$PATH"
|
|
362
|
+
|
|
363
|
+
# Fix workspace permissions
|
|
364
|
+
echo "🔧 Setting workspace permissions..."
|
|
365
|
+
sudo chown -R node:node /workspace
|
|
366
|
+
sudo chmod -R u+rwX,g+rwX /workspace
|
|
367
|
+
|
|
368
|
+
# Setup workspace directories for bind mounts (Claude and Serena)
|
|
369
|
+
setup_workspace_directories
|
|
370
|
+
|
|
371
|
+
# Setup npm permissions and directories
|
|
372
|
+
setup_npm_permissions
|
|
373
|
+
|
|
374
|
+
# Add node user to docker group for Docker socket access
|
|
375
|
+
echo "🐳 Adding node user to docker group..."
|
|
376
|
+
sudo usermod -aG docker node
|
|
377
|
+
echo "✅ Node user added to docker group"
|
|
378
|
+
|
|
379
|
+
# Install Claude Code
|
|
380
|
+
if install_claude_code; then
|
|
381
|
+
# Setup configuration directory
|
|
382
|
+
setup_claude_config
|
|
383
|
+
|
|
384
|
+
# Install ccusage CLI tool
|
|
385
|
+
install_ccusage || echo "⚠️ Continuing without ccusage..."
|
|
386
|
+
|
|
387
|
+
# Install development tools
|
|
388
|
+
install_dev_tools
|
|
389
|
+
|
|
390
|
+
# Display completion message
|
|
391
|
+
display_completion_message
|
|
392
|
+
else
|
|
393
|
+
echo "⚠️ Setup completed with errors. Claude Code installation failed."
|
|
394
|
+
echo " You can try installing manually with: npm install -g @anthropic-ai/claude-code"
|
|
395
|
+
exit 1
|
|
396
|
+
fi
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
# Execute main function
|
|
400
|
+
main
|