claudepod 1.1.1 → 1.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/.devcontainer/.env +18 -0
- package/.devcontainer/CHANGELOG.md +68 -0
- package/.devcontainer/CLAUDE.md +100 -0
- package/.devcontainer/README.md +220 -0
- package/.devcontainer/config/main-system-prompt.md +118 -0
- package/.devcontainer/config/settings.json +41 -0
- package/.devcontainer/devcontainer.json +71 -113
- package/.devcontainer/features/README.md +113 -0
- package/.devcontainer/features/ast-grep/README.md +24 -0
- package/.devcontainer/features/ast-grep/devcontainer-feature.json +24 -0
- package/.devcontainer/features/ast-grep/install.sh +51 -0
- package/.devcontainer/features/ccstatusline/README.md +296 -0
- package/.devcontainer/features/ccstatusline/devcontainer-feature.json +19 -0
- package/.devcontainer/features/ccstatusline/install.sh +290 -0
- package/.devcontainer/features/ccusage/README.md +205 -0
- package/.devcontainer/features/ccusage/devcontainer-feature.json +38 -0
- package/.devcontainer/features/ccusage/install.sh +132 -0
- package/.devcontainer/features/claude-code/README.md +498 -0
- package/.devcontainer/features/claude-code/config/settings.json +36 -0
- package/.devcontainer/features/claude-code/config/system-prompt.md +118 -0
- package/.devcontainer/features/claude-code/config/world-building-sp.md +1432 -0
- package/.devcontainer/features/claude-code/devcontainer-feature.json +42 -0
- package/.devcontainer/features/claude-code/install.sh +466 -0
- package/.devcontainer/features/claude-monitor/README.md +74 -0
- package/.devcontainer/features/claude-monitor/devcontainer-feature.json +38 -0
- package/.devcontainer/features/claude-monitor/install.sh +99 -0
- package/.devcontainer/features/lsp-servers/README.md +85 -0
- package/.devcontainer/features/lsp-servers/devcontainer-feature.json +34 -0
- package/.devcontainer/features/lsp-servers/install.sh +92 -0
- package/.devcontainer/features/mcp-qdrant/CHANGES.md +399 -0
- package/.devcontainer/features/mcp-qdrant/README.md +474 -0
- package/.devcontainer/features/mcp-qdrant/devcontainer-feature.json +57 -0
- package/.devcontainer/features/mcp-qdrant/install.sh +295 -0
- package/.devcontainer/features/mcp-qdrant/poststart-hook.sh +129 -0
- package/.devcontainer/features/mcp-reasoner/README.md +177 -0
- package/.devcontainer/features/mcp-reasoner/devcontainer-feature.json +20 -0
- package/.devcontainer/features/mcp-reasoner/install.sh +177 -0
- package/.devcontainer/features/mcp-reasoner/poststart-hook.sh +67 -0
- package/.devcontainer/features/splitrail/README.md +140 -0
- package/.devcontainer/features/splitrail/devcontainer-feature.json +34 -0
- package/.devcontainer/features/splitrail/install.sh +129 -0
- package/.devcontainer/features/tree-sitter/README.md +138 -0
- package/.devcontainer/features/tree-sitter/devcontainer-feature.json +52 -0
- package/.devcontainer/features/tree-sitter/install.sh +173 -0
- package/.devcontainer/scripts/setup-aliases.sh +52 -0
- package/.devcontainer/scripts/setup-config.sh +28 -0
- package/.devcontainer/scripts/setup-irie-claude.sh +32 -0
- package/.devcontainer/scripts/setup-lsp.sh +20 -0
- package/.devcontainer/scripts/setup-plugins.sh +31 -0
- package/.devcontainer/scripts/setup.sh +60 -0
- package/README.md +163 -177
- package/package.json +5 -9
- package/setup.js +2 -2
- package/.devcontainer/config/claude/mcp.json +0 -77
- package/.devcontainer/config/claude/mcp.json.backup +0 -77
- package/.devcontainer/config/claude/mcp.json.template +0 -118
- package/.devcontainer/config/claude/output-styles/strict-development.md +0 -158
- package/.devcontainer/config/claude/settings.json +0 -10
- package/.devcontainer/config/claude/system-prompt.md +0 -3
- package/.devcontainer/config/searxng/ods_config.json +0 -16
- package/.devcontainer/config/searxng/searxng_env_template +0 -71
- package/.devcontainer/config/serena/serena_config.yml +0 -72
- package/.devcontainer/config/taskmaster/config.json +0 -37
- package/.devcontainer/ods_config.json +0 -21
- package/.devcontainer/post-create.sh +0 -1077
- package/.devcontainer/post-start.sh +0 -551
- package/.devcontainer/sanitize-system-prompt.sh +0 -31
- package/.devcontainer/scripts/config/claude-core.sh +0 -210
- package/.devcontainer/scripts/config/searxng.sh +0 -252
- package/.devcontainer/scripts/config/serena.sh +0 -47
- package/.devcontainer/scripts/config/taskmaster.sh +0 -41
- package/.devcontainer/scripts/generate-mcp-config.js +0 -205
- package/.devcontainer/scripts/install/claude-code.sh +0 -112
- package/.devcontainer/scripts/shell/zsh-config.sh +0 -271
- package/.devcontainer/scripts/utils.sh +0 -44
- package/.devcontainer/setup-zsh.sh +0 -234
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "claude-code",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"name": "Claude Code CLI",
|
|
5
|
+
"description": "Installs Claude Code CLI for AI-powered coding assistance",
|
|
6
|
+
"maintainer": "AnExiledDev",
|
|
7
|
+
"documentationURL": "https://docs.anthropic.com/en/docs/claude-code",
|
|
8
|
+
|
|
9
|
+
"options": {
|
|
10
|
+
"installMethod": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "Installation method: npm or native",
|
|
13
|
+
"default": "native",
|
|
14
|
+
"enum": ["npm", "native"],
|
|
15
|
+
"proposals": ["npm", "native"]
|
|
16
|
+
},
|
|
17
|
+
"version": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"description": "Claude Code version (latest, or specific version like 2.0.42)",
|
|
20
|
+
"default": "latest"
|
|
21
|
+
},
|
|
22
|
+
"username": {
|
|
23
|
+
"type": "string",
|
|
24
|
+
"description": "Container user to install for (npm method only; native installs globally)",
|
|
25
|
+
"default": "automatic"
|
|
26
|
+
},
|
|
27
|
+
"overwriteSettings": {
|
|
28
|
+
"type": "boolean",
|
|
29
|
+
"description": "Overwrite existing settings.json in .claude directory",
|
|
30
|
+
"default": false
|
|
31
|
+
},
|
|
32
|
+
"overwriteSystemPrompt": {
|
|
33
|
+
"type": "boolean",
|
|
34
|
+
"description": "Overwrite existing system-prompt.md in .claude directory",
|
|
35
|
+
"default": false
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
|
|
39
|
+
"installsAfter": [
|
|
40
|
+
"ghcr.io/devcontainers/features/common-utils:2"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
5
|
+
# Claude Code CLI Installation Script
|
|
6
|
+
# Supports both native binary (default) and npm installation methods
|
|
7
|
+
#━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
8
|
+
|
|
9
|
+
# === SECTION 1: CLEANUP TRAP ===
|
|
10
|
+
cleanup() {
|
|
11
|
+
rm -f /tmp/claude 2>/dev/null || true
|
|
12
|
+
rm -f /tmp/claude-manifest.json 2>/dev/null || true
|
|
13
|
+
}
|
|
14
|
+
trap cleanup EXIT
|
|
15
|
+
|
|
16
|
+
# === SECTION 2: IMPORT OPTIONS ===
|
|
17
|
+
# NOTE: DevContainer converts camelCase to UPPERCASE without underscores
|
|
18
|
+
INSTALL_METHOD="${INSTALLMETHOD:-native}"
|
|
19
|
+
VERSION="${VERSION:-latest}"
|
|
20
|
+
USERNAME="${USERNAME:-automatic}"
|
|
21
|
+
OVERWRITE_SETTINGS="${OVERWRITESETTINGS:-false}"
|
|
22
|
+
OVERWRITE_SYSTEM_PROMPT="${OVERWRITESYSTEMPROMPT:-false}"
|
|
23
|
+
|
|
24
|
+
echo "[claude-code] Starting Claude Code CLI installation..."
|
|
25
|
+
echo "[claude-code] Install method: ${INSTALL_METHOD}"
|
|
26
|
+
echo "[claude-code] Version: ${VERSION}"
|
|
27
|
+
|
|
28
|
+
# === SECTION 3: VALIDATE DEPENDENCIES ===
|
|
29
|
+
echo "[claude-code] Validating dependencies..."
|
|
30
|
+
|
|
31
|
+
# Source NVM if using npm install method (Node is installed via NVM by the node feature)
|
|
32
|
+
if [ "${INSTALL_METHOD}" = "npm" ]; then
|
|
33
|
+
if [ -f /usr/local/share/nvm/nvm.sh ]; then
|
|
34
|
+
source /usr/local/share/nvm/nvm.sh
|
|
35
|
+
fi
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# jq is always required (for manifest parsing or other JSON ops)
|
|
39
|
+
if ! command -v jq &>/dev/null; then
|
|
40
|
+
echo "[claude-code] ERROR: jq not available"
|
|
41
|
+
echo " Install common-utils feature: ghcr.io/devcontainers/features/common-utils:2"
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Method-specific validation
|
|
46
|
+
if [ "${INSTALL_METHOD}" = "npm" ]; then
|
|
47
|
+
if ! command -v npm &>/dev/null; then
|
|
48
|
+
echo "[claude-code] ERROR: npm not available for npm installation"
|
|
49
|
+
echo " Add feature: ghcr.io/devcontainers/features/node:1"
|
|
50
|
+
echo " NVM path: /usr/local/share/nvm/nvm.sh"
|
|
51
|
+
exit 1
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
if [ ! -f /usr/local/share/nvm/nvm.sh ]; then
|
|
55
|
+
echo "[claude-code] ERROR: NVM not found at /usr/local/share/nvm/nvm.sh"
|
|
56
|
+
echo " Ensure node feature installed with nvmInstallPath set to /usr/local/share/nvm"
|
|
57
|
+
exit 1
|
|
58
|
+
fi
|
|
59
|
+
elif [ "${INSTALL_METHOD}" = "native" ]; then
|
|
60
|
+
# Validate we have curl for downloading
|
|
61
|
+
if ! command -v curl &>/dev/null; then
|
|
62
|
+
echo "[claude-code] ERROR: curl not available for native installation"
|
|
63
|
+
echo " Install via: apt-get install -y curl"
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# Validate we have sha256sum for checksum verification
|
|
68
|
+
if ! command -v sha256sum &>/dev/null; then
|
|
69
|
+
echo "[claude-code] ERROR: sha256sum not available for checksum verification"
|
|
70
|
+
echo " Install via: apt-get install -y coreutils"
|
|
71
|
+
exit 1
|
|
72
|
+
fi
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# === SECTION 4: VALIDATE INPUT ===
|
|
76
|
+
# Validate install method
|
|
77
|
+
if [[ "${INSTALL_METHOD}" != "npm" ]] && [[ "${INSTALL_METHOD}" != "native" ]]; then
|
|
78
|
+
echo "[claude-code] ERROR: installMethod must be 'npm' or 'native'"
|
|
79
|
+
echo " Provided: ${INSTALL_METHOD}"
|
|
80
|
+
exit 1
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# === SECTION 5: DETECT USER (for npm method) ===
|
|
84
|
+
if [ "${INSTALL_METHOD}" = "npm" ]; then
|
|
85
|
+
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
|
|
86
|
+
USERNAME=""
|
|
87
|
+
for CURRENT_USER in vscode node codespace; do
|
|
88
|
+
if id -u "${CURRENT_USER}" >/dev/null 2>&1; then
|
|
89
|
+
USERNAME=${CURRENT_USER}
|
|
90
|
+
break
|
|
91
|
+
fi
|
|
92
|
+
done
|
|
93
|
+
[ -z "${USERNAME}" ] && USERNAME=root
|
|
94
|
+
elif [ "${USERNAME}" = "none" ] || ! id -u "${USERNAME}" >/dev/null 2>&1; then
|
|
95
|
+
USERNAME=root
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
echo "[claude-code] Installing for user: ${USERNAME}"
|
|
99
|
+
else
|
|
100
|
+
echo "[claude-code] Native installation (global to /usr/local/bin)"
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
# === SECTION 6: INSTALL CLAUDE CODE ===
|
|
104
|
+
if [ "${INSTALL_METHOD}" = "native" ]; then
|
|
105
|
+
echo "[claude-code] Using native installation method..."
|
|
106
|
+
|
|
107
|
+
# Base URL for Claude Code distribution
|
|
108
|
+
BASE_URL="https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases"
|
|
109
|
+
|
|
110
|
+
# Resolve "latest" to actual version number BEFORE skip check
|
|
111
|
+
if [ "${VERSION}" = "latest" ]; then
|
|
112
|
+
echo "[claude-code] Fetching latest version..."
|
|
113
|
+
VERSION=$(curl -fsSL "${BASE_URL}/stable")
|
|
114
|
+
if [ -z "${VERSION}" ]; then
|
|
115
|
+
echo "[claude-code] ERROR: Failed to fetch latest version"
|
|
116
|
+
exit 1
|
|
117
|
+
fi
|
|
118
|
+
echo "[claude-code] Latest version: ${VERSION}"
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
# Check if already installed with same version
|
|
122
|
+
if command -v claude &>/dev/null; then
|
|
123
|
+
CURRENT_VERSION=$(claude --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "unknown")
|
|
124
|
+
echo "[claude-code] Claude Code already installed: ${CURRENT_VERSION}"
|
|
125
|
+
|
|
126
|
+
if [ "${CURRENT_VERSION}" = "${VERSION}" ]; then
|
|
127
|
+
echo "[claude-code] Version ${VERSION} already installed, skipping..."
|
|
128
|
+
exit 0
|
|
129
|
+
else
|
|
130
|
+
echo "[claude-code] Updating from ${CURRENT_VERSION} to ${VERSION}..."
|
|
131
|
+
fi
|
|
132
|
+
fi
|
|
133
|
+
|
|
134
|
+
echo "[claude-code] Installing native Claude Code CLI..."
|
|
135
|
+
|
|
136
|
+
# Detect platform
|
|
137
|
+
ARCH=$(uname -m)
|
|
138
|
+
case "${ARCH}" in
|
|
139
|
+
x86_64)
|
|
140
|
+
PLATFORM="linux-x64"
|
|
141
|
+
;;
|
|
142
|
+
aarch64|arm64)
|
|
143
|
+
PLATFORM="linux-arm64"
|
|
144
|
+
;;
|
|
145
|
+
*)
|
|
146
|
+
echo "[claude-code] ERROR: Unsupported architecture: ${ARCH}"
|
|
147
|
+
echo " Supported: x86_64, aarch64, arm64"
|
|
148
|
+
exit 1
|
|
149
|
+
;;
|
|
150
|
+
esac
|
|
151
|
+
|
|
152
|
+
# Detect musl (Alpine Linux)
|
|
153
|
+
if ldd --version 2>&1 | grep -qi musl; then
|
|
154
|
+
echo "[claude-code] Detected musl libc (Alpine)"
|
|
155
|
+
PLATFORM="${PLATFORM}-musl"
|
|
156
|
+
fi
|
|
157
|
+
|
|
158
|
+
echo "[claude-code] Platform: ${PLATFORM}"
|
|
159
|
+
|
|
160
|
+
# Fetch manifest
|
|
161
|
+
MANIFEST_URL="${BASE_URL}/${VERSION}/manifest.json"
|
|
162
|
+
echo "[claude-code] Fetching manifest from ${MANIFEST_URL}..."
|
|
163
|
+
|
|
164
|
+
if ! curl -fsSL "${MANIFEST_URL}" -o /tmp/claude-manifest.json; then
|
|
165
|
+
echo "[claude-code] ERROR: Failed to download manifest"
|
|
166
|
+
echo " URL: ${MANIFEST_URL}"
|
|
167
|
+
exit 1
|
|
168
|
+
fi
|
|
169
|
+
|
|
170
|
+
# Extract checksum for platform
|
|
171
|
+
EXPECTED_CHECKSUM=$(jq -r ".platforms.\"${PLATFORM}\".checksum" /tmp/claude-manifest.json)
|
|
172
|
+
if [ -z "${EXPECTED_CHECKSUM}" ] || [ "${EXPECTED_CHECKSUM}" = "null" ]; then
|
|
173
|
+
echo "[claude-code] ERROR: Platform ${PLATFORM} not found in manifest"
|
|
174
|
+
echo " Available platforms:"
|
|
175
|
+
jq -r '.platforms | keys[]' /tmp/claude-manifest.json
|
|
176
|
+
exit 1
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
echo "[claude-code] Expected SHA256: ${EXPECTED_CHECKSUM}"
|
|
180
|
+
|
|
181
|
+
# Download binary
|
|
182
|
+
BINARY_URL="${BASE_URL}/${VERSION}/${PLATFORM}/claude"
|
|
183
|
+
echo "[claude-code] Downloading from ${BINARY_URL}..."
|
|
184
|
+
|
|
185
|
+
if ! curl -fsSL "${BINARY_URL}" -o /tmp/claude; then
|
|
186
|
+
echo "[claude-code] ERROR: Failed to download binary"
|
|
187
|
+
echo " URL: ${BINARY_URL}"
|
|
188
|
+
exit 1
|
|
189
|
+
fi
|
|
190
|
+
|
|
191
|
+
# Verify checksum
|
|
192
|
+
echo "[claude-code] Verifying checksum..."
|
|
193
|
+
ACTUAL_CHECKSUM=$(sha256sum /tmp/claude | cut -d' ' -f1)
|
|
194
|
+
|
|
195
|
+
if [ "${ACTUAL_CHECKSUM}" != "${EXPECTED_CHECKSUM}" ]; then
|
|
196
|
+
echo "[claude-code] ERROR: Checksum verification failed"
|
|
197
|
+
echo " Expected: ${EXPECTED_CHECKSUM}"
|
|
198
|
+
echo " Actual: ${ACTUAL_CHECKSUM}"
|
|
199
|
+
exit 1
|
|
200
|
+
fi
|
|
201
|
+
|
|
202
|
+
echo "[claude-code] ✓ Checksum verified"
|
|
203
|
+
|
|
204
|
+
# Install to /usr/local/bin
|
|
205
|
+
chmod +x /tmp/claude
|
|
206
|
+
mv /tmp/claude /usr/local/bin/claude
|
|
207
|
+
|
|
208
|
+
# Verify installation
|
|
209
|
+
if ! command -v claude &>/dev/null; then
|
|
210
|
+
echo "[claude-code] ERROR: Installation failed - claude command not found"
|
|
211
|
+
exit 1
|
|
212
|
+
fi
|
|
213
|
+
|
|
214
|
+
INSTALLED_VERSION=$(claude --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "unknown")
|
|
215
|
+
echo "[claude-code] ✓ Claude Code ${INSTALLED_VERSION} installed (native)"
|
|
216
|
+
|
|
217
|
+
elif [ "${INSTALL_METHOD}" = "npm" ]; then
|
|
218
|
+
echo "[claude-code] Using npm installation method..."
|
|
219
|
+
|
|
220
|
+
# Resolve "latest" to actual version number BEFORE skip check
|
|
221
|
+
if [ "${VERSION}" = "latest" ]; then
|
|
222
|
+
echo "[claude-code] Fetching latest version from npm registry..."
|
|
223
|
+
VERSION=$(curl -fsSL "https://registry.npmjs.org/@anthropic-ai/claude-code/latest" | jq -r '.version')
|
|
224
|
+
if [ -z "${VERSION}" ] || [ "${VERSION}" = "null" ]; then
|
|
225
|
+
echo "[claude-code] ERROR: Failed to fetch latest version from npm"
|
|
226
|
+
exit 1
|
|
227
|
+
fi
|
|
228
|
+
echo "[claude-code] Latest version: ${VERSION}"
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
# Check if already installed with same version
|
|
232
|
+
if sudo -u "${USERNAME}" bash -c 'command -v claude' &>/dev/null; then
|
|
233
|
+
CURRENT_VERSION=$(sudo -u "${USERNAME}" bash -c 'claude --version 2>/dev/null | grep -oE "[0-9]+\.[0-9]+\.[0-9]+" | head -1' || echo "unknown")
|
|
234
|
+
echo "[claude-code] Claude Code already installed: ${CURRENT_VERSION}"
|
|
235
|
+
|
|
236
|
+
if [ "${CURRENT_VERSION}" = "${VERSION}" ]; then
|
|
237
|
+
echo "[claude-code] Version ${VERSION} already installed, skipping..."
|
|
238
|
+
exit 0
|
|
239
|
+
else
|
|
240
|
+
echo "[claude-code] Updating from ${CURRENT_VERSION} to ${VERSION}..."
|
|
241
|
+
fi
|
|
242
|
+
fi
|
|
243
|
+
|
|
244
|
+
echo "[claude-code] Installing Claude Code CLI via npm..."
|
|
245
|
+
|
|
246
|
+
INSTALL_CMD="@anthropic-ai/claude-code@${VERSION}"
|
|
247
|
+
|
|
248
|
+
echo "[claude-code] Installing: ${INSTALL_CMD}"
|
|
249
|
+
|
|
250
|
+
sudo -u "${USERNAME}" bash -c "
|
|
251
|
+
source /usr/local/share/nvm/nvm.sh
|
|
252
|
+
npm install -g --prefix ~/.npm-global ${INSTALL_CMD}
|
|
253
|
+
"
|
|
254
|
+
|
|
255
|
+
# Verify installation
|
|
256
|
+
if [[ ! -f "/home/${USERNAME}/.npm-global/bin/claude" ]]; then
|
|
257
|
+
echo "[claude-code] ERROR: Installation failed"
|
|
258
|
+
echo " Expected: /home/${USERNAME}/.npm-global/bin/claude"
|
|
259
|
+
exit 1
|
|
260
|
+
fi
|
|
261
|
+
|
|
262
|
+
INSTALLED_VERSION=$(sudo -u "${USERNAME}" bash -c 'source /usr/local/share/nvm/nvm.sh && claude --version 2>/dev/null | grep -oE "[0-9]+\.[0-9]+\.[0-9]+" | head -1' || echo "unknown")
|
|
263
|
+
echo "[claude-code] ✓ Claude Code ${INSTALLED_VERSION} installed (npm)"
|
|
264
|
+
|
|
265
|
+
# === SECTION 7: CONFIGURE PATH (NPM ONLY) ===
|
|
266
|
+
echo "[claude-code] Configuring PATH for npm installation..."
|
|
267
|
+
|
|
268
|
+
PATH_EXPORT='export PATH="$HOME/.npm-global/bin:$PATH"'
|
|
269
|
+
|
|
270
|
+
for SHELL_RC in .bashrc .zshrc; do
|
|
271
|
+
RC_FILE="/home/${USERNAME}/${SHELL_RC}"
|
|
272
|
+
if [ -f "${RC_FILE}" ]; then
|
|
273
|
+
if ! grep -q ".npm-global/bin" "${RC_FILE}"; then
|
|
274
|
+
echo "${PATH_EXPORT}" >> "${RC_FILE}"
|
|
275
|
+
echo "[claude-code] ✓ Added to ${SHELL_RC}"
|
|
276
|
+
else
|
|
277
|
+
echo "[claude-code] PATH already configured in ${SHELL_RC}"
|
|
278
|
+
fi
|
|
279
|
+
fi
|
|
280
|
+
done
|
|
281
|
+
fi
|
|
282
|
+
|
|
283
|
+
# === SECTION 7: CREATE POST-START HOOK FOR CONFIGURATION ===
|
|
284
|
+
echo "[claude-code] Creating post-start hook for configuration..."
|
|
285
|
+
|
|
286
|
+
# Get feature directory (where this script is located)
|
|
287
|
+
FEATURE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
288
|
+
|
|
289
|
+
# Create post-start hook directory (standard pattern for DevContainer features)
|
|
290
|
+
mkdir -p /usr/local/devcontainer-poststart.d
|
|
291
|
+
|
|
292
|
+
# Create post-start hook script for configuration and alias
|
|
293
|
+
# Runs on EVERY container start to ensure configs are copied and alias is set
|
|
294
|
+
# Note: Uses prefix 40 to run before MCP servers (50-51)
|
|
295
|
+
cat > /usr/local/devcontainer-poststart.d/40-claude-code.sh <<'HOOK_EOF'
|
|
296
|
+
#!/bin/bash
|
|
297
|
+
set -euo pipefail
|
|
298
|
+
|
|
299
|
+
echo "[claude-code] Auto-configuring Claude Code..."
|
|
300
|
+
|
|
301
|
+
# Get feature directory
|
|
302
|
+
FEATURE_DIR="/usr/local/share/claude-code"
|
|
303
|
+
|
|
304
|
+
# Determine user - use SUDO_USER since _REMOTE_USER isn't set in post-start hooks
|
|
305
|
+
# This hook runs as the remoteUser, so SUDO_USER will be set to the actual user
|
|
306
|
+
USERNAME="${SUDO_USER:-vscode}"
|
|
307
|
+
if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
|
|
308
|
+
# Auto-detect user if needed
|
|
309
|
+
USERNAME=""
|
|
310
|
+
for CURRENT_USER in vscode node codespace; do
|
|
311
|
+
if id -u "${CURRENT_USER}" >/dev/null 2>&1; then
|
|
312
|
+
USERNAME=${CURRENT_USER}
|
|
313
|
+
break
|
|
314
|
+
fi
|
|
315
|
+
done
|
|
316
|
+
[ -z "${USERNAME}" ] && USERNAME=root
|
|
317
|
+
elif [ "${USERNAME}" = "none" ] || ! id -u "${USERNAME}" >/dev/null 2>&1; then
|
|
318
|
+
USERNAME=root
|
|
319
|
+
fi
|
|
320
|
+
|
|
321
|
+
# Ensure .claude directory exists in workspace
|
|
322
|
+
mkdir -p /workspaces/.claude
|
|
323
|
+
mkdir -p /workspaces/.claude/commands
|
|
324
|
+
mkdir -p /workspaces/.claude/hooks
|
|
325
|
+
mkdir -p /workspaces/.claude/output-styles
|
|
326
|
+
|
|
327
|
+
# Copy settings.json (respect OVERWRITE_SETTINGS env var, default false)
|
|
328
|
+
OVERWRITE_SETTINGS="${OVERWRITE_SETTINGS:-false}"
|
|
329
|
+
if [ -f "${FEATURE_DIR}/settings.json" ]; then
|
|
330
|
+
if [ ! -f "/workspaces/.claude/settings.json" ] || [ "${OVERWRITE_SETTINGS}" = "true" ]; then
|
|
331
|
+
cp "${FEATURE_DIR}/settings.json" /workspaces/.claude/settings.json
|
|
332
|
+
chmod 644 /workspaces/.claude/settings.json
|
|
333
|
+
chown "${USERNAME}:${USERNAME}" /workspaces/.claude/settings.json 2>/dev/null || true
|
|
334
|
+
if [ "${OVERWRITE_SETTINGS}" = "true" ]; then
|
|
335
|
+
echo "[claude-code] ✓ Overwritten settings.json"
|
|
336
|
+
else
|
|
337
|
+
echo "[claude-code] ✓ Copied settings.json"
|
|
338
|
+
fi
|
|
339
|
+
else
|
|
340
|
+
echo "[claude-code] Skipped settings.json (exists, overwriteSettings=false)"
|
|
341
|
+
fi
|
|
342
|
+
fi
|
|
343
|
+
|
|
344
|
+
# Copy system-prompt.md (respect OVERWRITE_SYSTEM_PROMPT env var, default false)
|
|
345
|
+
OVERWRITE_SYSTEM_PROMPT="${OVERWRITE_SYSTEM_PROMPT:-false}"
|
|
346
|
+
if [ -f "${FEATURE_DIR}/system-prompt.md" ]; then
|
|
347
|
+
if [ ! -f "/workspaces/.claude/system-prompt.md" ] || [ "${OVERWRITE_SYSTEM_PROMPT}" = "true" ]; then
|
|
348
|
+
cp "${FEATURE_DIR}/system-prompt.md" /workspaces/.claude/system-prompt.md
|
|
349
|
+
chmod 644 /workspaces/.claude/system-prompt.md
|
|
350
|
+
chown "${USERNAME}:${USERNAME}" /workspaces/.claude/system-prompt.md 2>/dev/null || true
|
|
351
|
+
if [ "${OVERWRITE_SYSTEM_PROMPT}" = "true" ]; then
|
|
352
|
+
echo "[claude-code] ✓ Overwritten system-prompt.md"
|
|
353
|
+
else
|
|
354
|
+
echo "[claude-code] ✓ Copied system-prompt.md"
|
|
355
|
+
fi
|
|
356
|
+
else
|
|
357
|
+
echo "[claude-code] Skipped system-prompt.md (exists, overwriteSystemPrompt=false)"
|
|
358
|
+
fi
|
|
359
|
+
fi
|
|
360
|
+
|
|
361
|
+
# Ensure proper ownership
|
|
362
|
+
chown -R "${USERNAME}:${USERNAME}" /workspaces/.claude 2>/dev/null || true
|
|
363
|
+
|
|
364
|
+
# Create claude alias
|
|
365
|
+
echo "[claude-code] Setting up claude alias..."
|
|
366
|
+
|
|
367
|
+
# Determine prompt flag based on CLAUDE_PROMPT_MODE environment variable
|
|
368
|
+
if [ "${CLAUDE_PROMPT_MODE:-system}" = "append" ]; then
|
|
369
|
+
PROMPT_FLAG="--append-system-prompt-file"
|
|
370
|
+
else
|
|
371
|
+
PROMPT_FLAG="--system-prompt-file"
|
|
372
|
+
fi
|
|
373
|
+
|
|
374
|
+
# Create alias command
|
|
375
|
+
ALIAS_CMD="alias claude='claude --dangerously-skip-permissions ${PROMPT_FLAG} \"/workspaces/.claude/system-prompt.md\"'"
|
|
376
|
+
|
|
377
|
+
# Add to shell config files - use $HOME for better portability
|
|
378
|
+
for SHELL_RC in .bashrc .zshrc; do
|
|
379
|
+
RC_FILE="$HOME/${SHELL_RC}"
|
|
380
|
+
if [ -f "${RC_FILE}" ]; then
|
|
381
|
+
if ! grep -q "claude --dangerously-skip-permissions" "${RC_FILE}" 2>/dev/null; then
|
|
382
|
+
echo "${ALIAS_CMD}" >> "${RC_FILE}"
|
|
383
|
+
echo "[claude-code] ✓ Added alias to ${SHELL_RC}"
|
|
384
|
+
else
|
|
385
|
+
echo "[claude-code] Alias already in ${SHELL_RC}"
|
|
386
|
+
fi
|
|
387
|
+
fi
|
|
388
|
+
done
|
|
389
|
+
|
|
390
|
+
# Run claude install as the vscode user
|
|
391
|
+
# echo "[claude-code] Running claude install..."
|
|
392
|
+
# if su - ${USERNAME} -c "claude install" 2>&1; then
|
|
393
|
+
# echo "[claude-code] ✓ claude install completed"
|
|
394
|
+
# else
|
|
395
|
+
# echo "[claude-code] WARNING: claude install failed (may be harmless)"
|
|
396
|
+
# fi
|
|
397
|
+
|
|
398
|
+
echo "[claude-code] ✓ Configuration complete"
|
|
399
|
+
HOOK_EOF
|
|
400
|
+
|
|
401
|
+
chmod +x /usr/local/devcontainer-poststart.d/40-claude-code.sh
|
|
402
|
+
|
|
403
|
+
# Copy config files to system location for post-start hook to access
|
|
404
|
+
mkdir -p /usr/local/share/claude-code
|
|
405
|
+
if [ -f "${FEATURE_DIR}/config/settings.json" ]; then
|
|
406
|
+
cp "${FEATURE_DIR}/config/settings.json" /usr/local/share/claude-code/settings.json
|
|
407
|
+
chmod 644 /usr/local/share/claude-code/settings.json
|
|
408
|
+
echo "[claude-code] ✓ Config files staged for post-start hook"
|
|
409
|
+
else
|
|
410
|
+
echo "[claude-code] WARNING: settings.json not found at ${FEATURE_DIR}/config/settings.json"
|
|
411
|
+
fi
|
|
412
|
+
|
|
413
|
+
if [ -f "${FEATURE_DIR}/config/system-prompt.md" ]; then
|
|
414
|
+
cp "${FEATURE_DIR}/config/system-prompt.md" /usr/local/share/claude-code/system-prompt.md
|
|
415
|
+
chmod 644 /usr/local/share/claude-code/system-prompt.md
|
|
416
|
+
else
|
|
417
|
+
echo "[claude-code] WARNING: system-prompt.md not found at ${FEATURE_DIR}/config/system-prompt.md"
|
|
418
|
+
fi
|
|
419
|
+
|
|
420
|
+
echo "[claude-code] ✓ Post-start hook created at /usr/local/devcontainer-poststart.d/40-claude-code.sh"
|
|
421
|
+
|
|
422
|
+
# === SECTION 8: SUMMARY ===
|
|
423
|
+
echo ""
|
|
424
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
425
|
+
echo " Claude Code CLI Installation Complete"
|
|
426
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
427
|
+
echo ""
|
|
428
|
+
echo "Configuration:"
|
|
429
|
+
echo " • Method: ${INSTALL_METHOD}"
|
|
430
|
+
echo " • Version: ${INSTALLED_VERSION:-${VERSION}}"
|
|
431
|
+
|
|
432
|
+
if [ "${INSTALL_METHOD}" = "native" ]; then
|
|
433
|
+
echo " • Binary: /usr/local/bin/claude"
|
|
434
|
+
echo " • Platform: ${PLATFORM}"
|
|
435
|
+
else
|
|
436
|
+
echo " • Binary: /home/${USERNAME}/.npm-global/bin/claude"
|
|
437
|
+
echo " • User: ${USERNAME}"
|
|
438
|
+
fi
|
|
439
|
+
|
|
440
|
+
echo ""
|
|
441
|
+
echo "Post-Start Configuration:"
|
|
442
|
+
echo " • Hook: /usr/local/devcontainer-poststart.d/40-claude-code.sh"
|
|
443
|
+
echo " • Will copy settings.json and system-prompt.md on container start"
|
|
444
|
+
echo " • Will create claude alias with system prompt integration"
|
|
445
|
+
echo ""
|
|
446
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
447
|
+
echo " Next Steps"
|
|
448
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
449
|
+
echo ""
|
|
450
|
+
echo "1. Container will auto-configure on start (postStartCommand)"
|
|
451
|
+
echo ""
|
|
452
|
+
echo "2. After container starts, verify:"
|
|
453
|
+
echo " claude --version"
|
|
454
|
+
echo " ls /workspaces/.claude/system-prompt.md"
|
|
455
|
+
echo " alias | grep claude"
|
|
456
|
+
echo ""
|
|
457
|
+
echo "3. Authenticate:"
|
|
458
|
+
echo " claude auth login"
|
|
459
|
+
echo ""
|
|
460
|
+
echo "4. Use Claude Code (alias includes system prompt):"
|
|
461
|
+
echo " claude"
|
|
462
|
+
echo ""
|
|
463
|
+
echo "5. Customize system prompt:"
|
|
464
|
+
echo " Edit /workspaces/.claude/system-prompt.md"
|
|
465
|
+
echo ""
|
|
466
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Claude Monitor Feature
|
|
2
|
+
|
|
3
|
+
Installs [Claude Code Usage Monitor](https://github.com/Maciek-roboblog/Claude-Code-Usage-Monitor) - a real-time terminal application for tracking Claude Code token consumption.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Real-time monitoring** with configurable refresh rates (0.1-20 Hz)
|
|
8
|
+
- **Multiple views**: realtime, daily, monthly usage reports
|
|
9
|
+
- **ML-based predictions** using P90 percentile for limit forecasting
|
|
10
|
+
- **Cost tracking** with automatic plan detection
|
|
11
|
+
- **Rich terminal UI** with WCAG-compliant progress displays
|
|
12
|
+
|
|
13
|
+
## Options
|
|
14
|
+
|
|
15
|
+
| Option | Type | Default | Description |
|
|
16
|
+
|--------|------|---------|-------------|
|
|
17
|
+
| `version` | string | `latest` | Version to install |
|
|
18
|
+
| `installer` | string | `uv` | Package installer (`uv`, `pipx`, or `pip`) |
|
|
19
|
+
| `username` | string | `automatic` | Container user to install for |
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
"features": {
|
|
25
|
+
"./features/claude-monitor": {
|
|
26
|
+
"version": "latest",
|
|
27
|
+
"installer": "uv",
|
|
28
|
+
"username": "automatic"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Commands
|
|
34
|
+
|
|
35
|
+
After installation, these commands are available:
|
|
36
|
+
|
|
37
|
+
| Command | Description |
|
|
38
|
+
|---------|-------------|
|
|
39
|
+
| `claude-monitor` | Full command name |
|
|
40
|
+
| `cmonitor` | Short alias |
|
|
41
|
+
| `ccmonitor` | Alternative alias |
|
|
42
|
+
| `ccm` | Shortest alias |
|
|
43
|
+
|
|
44
|
+
## Examples
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
# Real-time monitoring (default)
|
|
48
|
+
claude-monitor
|
|
49
|
+
|
|
50
|
+
# Daily usage report
|
|
51
|
+
claude-monitor --daily
|
|
52
|
+
|
|
53
|
+
# Monthly usage report
|
|
54
|
+
claude-monitor --monthly
|
|
55
|
+
|
|
56
|
+
# Custom refresh rate (Hz)
|
|
57
|
+
claude-monitor --refresh 5
|
|
58
|
+
|
|
59
|
+
# Help and options
|
|
60
|
+
claude-monitor --help
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Requirements
|
|
64
|
+
|
|
65
|
+
- Python 3.9+ (provided by base image)
|
|
66
|
+
- Network access for package installation
|
|
67
|
+
|
|
68
|
+
## Related Tools
|
|
69
|
+
|
|
70
|
+
- [ccusage](https://github.com/ryoppippi/ccusage) - Token usage analyzer (Node.js-based, also available as a feature)
|
|
71
|
+
|
|
72
|
+
## License
|
|
73
|
+
|
|
74
|
+
MIT
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "claude-monitor",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"name": "Claude Monitor - Real-time Usage Tracker",
|
|
5
|
+
"description": "Installs claude-monitor for real-time Claude Code token usage monitoring with ML-based predictions",
|
|
6
|
+
"maintainer": "AnExiledDev",
|
|
7
|
+
"documentationURL": "https://github.com/Maciek-roboblog/Claude-Code-Usage-Monitor",
|
|
8
|
+
"options": {
|
|
9
|
+
"version": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"description": "claude-monitor version to install (e.g., 'latest', '1.2.0')",
|
|
12
|
+
"default": "latest"
|
|
13
|
+
},
|
|
14
|
+
"installer": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"description": "Package installer to use",
|
|
17
|
+
"default": "uv",
|
|
18
|
+
"enum": [
|
|
19
|
+
"uv",
|
|
20
|
+
"pipx",
|
|
21
|
+
"pip"
|
|
22
|
+
],
|
|
23
|
+
"proposals": [
|
|
24
|
+
"uv",
|
|
25
|
+
"pipx",
|
|
26
|
+
"pip"
|
|
27
|
+
]
|
|
28
|
+
},
|
|
29
|
+
"username": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"description": "Container user to install for",
|
|
32
|
+
"default": "automatic"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"installsAfter": [
|
|
36
|
+
"ghcr.io/devcontainers/features/python"
|
|
37
|
+
]
|
|
38
|
+
}
|