codeforge-dev 1.14.2 → 2.0.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.
Files changed (128) hide show
  1. package/{.devcontainer/config/defaults → .codeforge/config}/ccstatusline-settings.json +44 -6
  2. package/.codeforge/config/main-system-prompt.md +412 -0
  3. package/.codeforge/config/orchestrator-system-prompt.md +333 -0
  4. package/{.devcontainer/config/defaults → .codeforge/config}/settings.json +7 -2
  5. package/{.devcontainer/config → .codeforge}/file-manifest.json +15 -9
  6. package/{.devcontainer → .codeforge/scripts}/connect-external-terminal.sh +3 -1
  7. package/.devcontainer/.env.example +17 -5
  8. package/.devcontainer/.secrets.example +3 -0
  9. package/.devcontainer/CHANGELOG.md +215 -0
  10. package/.devcontainer/CLAUDE.md +26 -43
  11. package/.devcontainer/README.md +35 -20
  12. package/.devcontainer/devcontainer.json +36 -17
  13. package/.devcontainer/features/agent-browser/install.sh +3 -0
  14. package/.devcontainer/features/ast-grep/install.sh +3 -0
  15. package/.devcontainer/features/biome/install.sh +3 -0
  16. package/.devcontainer/features/ccburn/install.sh +2 -0
  17. package/.devcontainer/features/ccms/install.sh +2 -0
  18. package/.devcontainer/features/ccstatusline/README.md +7 -6
  19. package/.devcontainer/features/ccstatusline/install.sh +9 -4
  20. package/.devcontainer/features/ccusage/install.sh +2 -0
  21. package/.devcontainer/features/chromaterm/chromaterm.yml +2 -2
  22. package/.devcontainer/features/chromaterm/install.sh +2 -0
  23. package/.devcontainer/features/claude-code-native/README.md +47 -0
  24. package/.devcontainer/features/claude-code-native/devcontainer-feature.json +29 -0
  25. package/.devcontainer/features/claude-code-native/install.sh +131 -0
  26. package/.devcontainer/features/claude-monitor/install.sh +2 -0
  27. package/.devcontainer/features/claude-session-dashboard/README.md +2 -2
  28. package/.devcontainer/features/claude-session-dashboard/install.sh +3 -0
  29. package/.devcontainer/features/dprint/install.sh +2 -0
  30. package/.devcontainer/features/hadolint/install.sh +2 -0
  31. package/.devcontainer/features/kitty-terminfo/README.md +3 -1
  32. package/.devcontainer/features/kitty-terminfo/install.sh +2 -0
  33. package/.devcontainer/features/lsp-servers/install.sh +4 -0
  34. package/.devcontainer/features/mcp-qdrant/CHANGES.md +3 -3
  35. package/.devcontainer/features/mcp-qdrant/README.md +1 -0
  36. package/.devcontainer/features/mcp-qdrant/devcontainer-feature.json +1 -1
  37. package/.devcontainer/features/mcp-qdrant/install.sh +9 -2
  38. package/.devcontainer/features/mcp-qdrant/poststart-hook.sh +9 -2
  39. package/.devcontainer/features/notify-hook/devcontainer-feature.json +1 -1
  40. package/.devcontainer/features/notify-hook/install.sh +2 -0
  41. package/.devcontainer/features/ruff/install.sh +2 -0
  42. package/.devcontainer/features/shellcheck/install.sh +2 -0
  43. package/.devcontainer/features/shfmt/install.sh +2 -0
  44. package/.devcontainer/features/tmux/README.md +3 -3
  45. package/.devcontainer/features/tmux/install.sh +3 -1
  46. package/.devcontainer/features/tree-sitter/install.sh +4 -0
  47. package/.devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json +27 -11
  48. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/README.md +20 -6
  49. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/architect.md +182 -29
  50. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/bash-exec.md +9 -0
  51. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/claude-guide.md +13 -4
  52. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/debug-logs.md +24 -5
  53. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/dependency-analyst.md +16 -5
  54. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/documenter.md +412 -0
  55. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/explorer.md +18 -6
  56. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/generalist.md +36 -10
  57. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/git-archaeologist.md +10 -1
  58. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/implementer.md +260 -0
  59. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/investigator.md +262 -0
  60. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/migrator.md +10 -0
  61. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/perf-profiler.md +21 -5
  62. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/refactorer.md +18 -8
  63. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/researcher.md +23 -5
  64. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/security-auditor.md +20 -6
  65. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/spec-writer.md +12 -0
  66. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/statusline-config.md +12 -2
  67. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/test-writer.md +22 -7
  68. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/guard-readonly-bash.py +9 -5
  69. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/redirect-builtin-agents.py +2 -5
  70. package/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/README.md +1 -1
  71. package/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/scripts/advisory-test-runner.py +4 -2
  72. package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/README.md +3 -2
  73. package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/block-dangerous.py +89 -15
  74. package/.devcontainer/plugins/devs-marketplace/plugins/git-workflow/.claude-plugin/plugin.json +7 -0
  75. package/.devcontainer/plugins/devs-marketplace/plugins/git-workflow/README.md +125 -0
  76. package/.devcontainer/plugins/devs-marketplace/plugins/git-workflow/skills/pr-review/SKILL.md +325 -0
  77. package/.devcontainer/plugins/devs-marketplace/plugins/git-workflow/skills/ship/SKILL.md +314 -0
  78. package/.devcontainer/plugins/devs-marketplace/plugins/prompt-snippets/.claude-plugin/plugin.json +5 -0
  79. package/.devcontainer/plugins/devs-marketplace/plugins/prompt-snippets/README.md +52 -0
  80. package/.devcontainer/plugins/devs-marketplace/plugins/prompt-snippets/skills/ps/SKILL.md +37 -0
  81. package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/README.md +2 -2
  82. package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected-bash.py +80 -6
  83. package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected.py +4 -4
  84. package/.devcontainer/plugins/devs-marketplace/plugins/session-context/README.md +30 -14
  85. package/.devcontainer/plugins/devs-marketplace/plugins/session-context/hooks/hooks.json +13 -1
  86. package/.devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/collect-session-edits.py +44 -0
  87. package/.devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/commit-reminder.py +89 -10
  88. package/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/.claude-plugin/plugin.json +1 -1
  89. package/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/README.md +19 -11
  90. package/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/scripts/skill-suggester.py +476 -282
  91. package/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/team/SKILL.md +4 -4
  92. package/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/worktree/SKILL.md +227 -0
  93. package/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/worktree/references/manual-worktree-commands.md +238 -0
  94. package/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/worktree/references/parallel-workflow-patterns.md +228 -0
  95. package/.devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-build/SKILL.md +2 -2
  96. package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/scripts/ticket-linker.py +2 -2
  97. package/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/README.md +1 -1
  98. package/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/guard-workspace-scope.py +69 -31
  99. package/.devcontainer/scripts/check-setup.sh +5 -3
  100. package/.devcontainer/scripts/preflight.sh +113 -0
  101. package/.devcontainer/scripts/setup-aliases.sh +13 -8
  102. package/.devcontainer/scripts/setup-auth.sh +46 -0
  103. package/.devcontainer/scripts/setup-config.sh +29 -10
  104. package/.devcontainer/scripts/setup-migrate-claude.sh +80 -0
  105. package/.devcontainer/scripts/setup-migrate-codeforge.sh +60 -0
  106. package/.devcontainer/scripts/setup-plugins.sh +5 -5
  107. package/.devcontainer/scripts/setup-projects.sh +4 -2
  108. package/.devcontainer/scripts/setup-terminal.sh +3 -1
  109. package/.devcontainer/scripts/setup-update-claude.sh +22 -27
  110. package/.devcontainer/scripts/setup.sh +78 -5
  111. package/LICENSE.txt +14 -0
  112. package/README.md +82 -7
  113. package/package.json +4 -1
  114. package/setup.js +392 -21
  115. package/.devcontainer/config/defaults/main-system-prompt.md +0 -664
  116. package/.devcontainer/docs/configuration-reference.md +0 -93
  117. package/.devcontainer/docs/keybindings.md +0 -100
  118. package/.devcontainer/docs/optional-features.md +0 -64
  119. package/.devcontainer/docs/plugins.md +0 -176
  120. package/.devcontainer/docs/troubleshooting.md +0 -128
  121. package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/doc-writer.md +0 -334
  122. package/.devcontainer/scripts/setup-symlink-claude.sh +0 -36
  123. /package/{.devcontainer/config/defaults → .codeforge/config}/keybindings.json +0 -0
  124. /package/{.devcontainer/config/defaults → .codeforge/config}/rules/session-search.md +0 -0
  125. /package/{.devcontainer/config/defaults → .codeforge/config}/rules/spec-workflow.md +0 -0
  126. /package/{.devcontainer/config/defaults → .codeforge/config}/rules/workspace-scope.md +0 -0
  127. /package/{.devcontainer/config/defaults → .codeforge/config}/writing-system-prompt.md +0 -0
  128. /package/{.devcontainer → .codeforge/scripts}/connect-external-terminal.ps1 +0 -0
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  VERSION="${VERSION:-latest}"
@@ -56,6 +58,7 @@ npm install -g "${NPM_PACKAGE}" 2>/dev/null || {
56
58
  echo "[agent-browser] WARNING: Global install failed, trying user install"
57
59
  su - "${USERNAME}" -c "npm install -g ${NPM_PACKAGE}" 2>/dev/null || true
58
60
  }
61
+ npm cache clean --force 2>/dev/null || true
59
62
 
60
63
  # Download Chromium and install system dependencies
61
64
  echo "[agent-browser] Installing Chromium and system dependencies..."
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  VERSION="${VERSION:-latest}"
@@ -53,5 +55,6 @@ npm install -g "${NPM_PACKAGE}" 2>/dev/null || {
53
55
  echo "[ast-grep] WARNING: Global install failed, trying user install"
54
56
  su - "${USERNAME}" -c "npm install -g ${NPM_PACKAGE}" 2>/dev/null || true
55
57
  }
58
+ npm cache clean --force 2>/dev/null || true
56
59
 
57
60
  echo "[ast-grep] Installed: $(ast-grep --version 2>/dev/null || echo 'unknown')"
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  VERSION="${VERSION:-latest}"
@@ -31,6 +33,7 @@ if [ "${VERSION}" = "latest" ]; then
31
33
  else
32
34
  npm install -g "@biomejs/biome@${VERSION}"
33
35
  fi
36
+ npm cache clean --force 2>/dev/null || true
34
37
 
35
38
  # Verify installation
36
39
  biome --version
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  # === SETUP ===
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  # === SETUP ===
@@ -45,7 +45,7 @@ All widgets connected with powerline arrows (monokai theme).
45
45
 
46
46
  - **ccstatusline npm package**: Installed on-demand via `npx` (not globally)
47
47
  - **Configuration file**: `~/.config/ccstatusline/settings.json` with powerline theme
48
- - **Claude Code integration**: Automatically updates `.claude/settings.json`
48
+ - **Claude Code integration**: Automatically updates `~/.claude/settings.json`
49
49
  - **Disk Usage**: Minimal (~2MB when cached by npx)
50
50
 
51
51
  ## Requirements
@@ -75,9 +75,10 @@ The feature will validate these are present and exit with an error if missing.
75
75
  - ✅ **Session Resume**: Copyable `cc --resume {sessionId}` command via custom-command widget
76
76
  - ✅ **Burn Rate Tracking**: Live ccburn compact output showing pace indicators (🧊/🔥/🚨)
77
77
  - ✅ **ANSI Colors**: High-contrast colors optimized for dark terminals
78
- - ✅ **Automatic Integration**: Auto-configures `.claude/settings.json`
78
+ - ✅ **Automatic Integration**: Auto-configures `~/.claude/settings.json`
79
79
  - ✅ **Idempotent**: Safe to run multiple times
80
80
  - ✅ **Multi-user**: Automatically detects container user
81
+ - ✅ **Config-aware**: Respects `CLAUDE_CONFIG_DIR` environment variable (defaults to `~/.claude`)
81
82
 
82
83
  ## Post-Installation Steps
83
84
 
@@ -85,7 +86,7 @@ The feature will validate these are present and exit with an error if missing.
85
86
 
86
87
  This feature automatically:
87
88
  1. Creates `~/.config/ccstatusline/settings.json` with powerline configuration
88
- 2. Configures `.claude/settings.json` to use ccstatusline
89
+ 2. Configures `~/.claude/settings.json` to use ccstatusline
89
90
 
90
91
  **No manual steps required!**
91
92
 
@@ -105,7 +106,7 @@ You should see formatted output with powerline styling.
105
106
 
106
107
  **3. Check Claude Code integration:**
107
108
  ```bash
108
- cat /workspaces/.claude/settings.json | jq '.statusLine'
109
+ cat "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/settings.json" | jq '.statusLine'
109
110
  ```
110
111
 
111
112
  Should show:
@@ -204,7 +205,7 @@ cat ~/.config/ccstatusline/settings.json | jq .
204
205
  echo '{"model":{"display_name":"Test"}}' | npx -y ccstatusline@latest
205
206
 
206
207
  # 3. Check Claude Code settings
207
- cat /workspaces/.claude/settings.json | jq '.statusLine'
208
+ cat "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/settings.json" | jq '.statusLine'
208
209
 
209
210
  # 4. Manually run auto-config if needed
210
211
  configure-ccstatusline-auto
@@ -258,7 +259,7 @@ configure-ccstatusline-auto
258
259
  npm install -g ccstatusline@latest
259
260
  ```
260
261
 
261
- Then update `.claude/settings.json`:
262
+ Then update `${CLAUDE_CONFIG_DIR:-~/.claude}/settings.json`:
262
263
  ```json
263
264
  {
264
265
  "statusLine": {
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  # Cleanup on exit
@@ -67,7 +69,7 @@ else
67
69
  fi
68
70
 
69
71
  # Widget config is managed by file-manifest.json (deployed by setup-config.sh)
70
- # Source: .devcontainer/config/defaults/ccstatusline-settings.json
72
+ # Source: .codeforge/config/ccstatusline-settings.json
71
73
  # Deployed to: ~/.config/ccstatusline/settings.json (if-changed)
72
74
  # Template: /usr/local/share/ccstatusline/settings.template.json (always)
73
75
  echo "[ccstatusline] Widget config managed by file-manifest.json"
@@ -75,6 +77,7 @@ echo "[ccstatusline] Widget config managed by file-manifest.json"
75
77
  # Create directories so wrapper doesn't fail before first post-start
76
78
  mkdir -p "${USER_HOME}/.config/ccstatusline"
77
79
  mkdir -p /usr/local/share/ccstatusline
80
+ chown "${USERNAME}:${USERNAME}" /usr/local/share/ccstatusline
78
81
  chown "${USERNAME}:${USERNAME}" "${USER_HOME}/.config/ccstatusline" 2>/dev/null || true
79
82
 
80
83
  # Create session resume helper script for custom-command widget
@@ -190,9 +193,11 @@ if ! command -v jq &>/dev/null; then
190
193
  exit 1
191
194
  fi
192
195
 
193
- SETTINGS_FILE="${WORKSPACE_ROOT:-/workspaces}/.claude/settings.json"
194
196
  # Use SUDO_USER since _REMOTE_USER isn't set in post-start hooks
195
197
  USERNAME="${SUDO_USER:-vscode}"
198
+ _USER_HOME=$(getent passwd "$USERNAME" 2>/dev/null | cut -d: -f6)
199
+ _USER_HOME="${_USER_HOME:-/home/$USERNAME}"
200
+ SETTINGS_FILE="${CLAUDE_CONFIG_DIR:-${_USER_HOME}/.claude}/settings.json"
196
201
 
197
202
  # Ensure directory exists
198
203
  mkdir -p "$(dirname "${SETTINGS_FILE}")"
@@ -232,7 +237,7 @@ echo " ccstatusline Installation Complete"
232
237
  echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
233
238
  echo ""
234
239
  echo "Configuration:"
235
- echo " • Source: .devcontainer/config/defaults/ccstatusline-settings.json"
240
+ echo " • Source: .codeforge/config/ccstatusline-settings.json"
236
241
  echo " • Deployed to: ~/.config/ccstatusline/settings.json (by file-manifest)"
237
242
  echo " • Template: /usr/local/share/ccstatusline/settings.template.json"
238
243
  echo " • User: ${USERNAME}"
@@ -244,7 +249,7 @@ echo "━━━━━━━━━━━━━━━━━━━━━━━━
244
249
  echo ""
245
250
  echo "1. Widget config is deployed automatically on container start"
246
251
  echo ""
247
- echo "2. To customize: edit .devcontainer/config/defaults/ccstatusline-settings.json"
252
+ echo "2. To customize: edit .codeforge/config/ccstatusline-settings.json"
248
253
  echo " Changes deploy on next container start (if-changed)"
249
254
  echo ""
250
255
  echo "3. Test manually:"
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  # === SETUP ===
@@ -18,7 +18,7 @@ rules:
18
18
  # File paths with optional line numbers (e.g., src/main.py:42)
19
19
  # Covers common extensions for languages used in development
20
20
  - description: File paths with line numbers
21
- regex: '(?<=[\s(]|^)([a-zA-Z0-9_./-]+\.(py|ts|tsx|js|jsx|md|json|yml|yaml|toml|sh|rs|go|sql|css|html|svelte))(:(\d+))?'
21
+ regex: '(?:(?<=[\s(])|^)([a-zA-Z0-9_./-]+\.(py|ts|tsx|js|jsx|md|json|yml|yaml|toml|sh|rs|go|sql|css|html|svelte))(:(\d+))?'
22
22
  color:
23
23
  1: f.file_purple underline
24
24
  4: f.line_gray
@@ -31,5 +31,5 @@ rules:
31
31
 
32
32
  # Git short commit hashes (7-12 hex chars)
33
33
  - description: Git commit hashes
34
- regex: '(?<=commit |merge |pick |revert |fixup )[0-9a-f]{7,40}'
34
+ regex: '(?:(?<=commit )|(?<=merge )|(?<=pick )|(?<=revert )|(?<=fixup ))[0-9a-f]{7,40}'
35
35
  color: f.hash_yellow
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  # ==============================
@@ -0,0 +1,47 @@
1
+ # Claude Code CLI (Native Binary)
2
+
3
+ Installs [Claude Code](https://docs.anthropic.com/en/docs/claude-code) as a native binary using Anthropic's official installer.
4
+
5
+ Unlike the npm-based installation (`ghcr.io/anthropics/devcontainer-features/claude-code`), this feature installs the native binary directly to `~/.local/bin/claude`. The binary is owned by the container user, so the in-session auto-updater works without permission issues.
6
+
7
+ ## Options
8
+
9
+ | Option | Default | Description |
10
+ |--------|---------|-------------|
11
+ | `version` | `latest` | `latest`, `stable`, or a specific semver (e.g., `2.1.52`). Set to `none` to skip. |
12
+ | `username` | `automatic` | Container user to install for. `automatic` detects from `$_REMOTE_USER`. |
13
+
14
+ ## How it works
15
+
16
+ 1. Downloads the official installer from `https://claude.ai/install.sh`
17
+ 2. Runs it as the target user (not root)
18
+ 3. The installer handles platform detection, checksum verification, and binary placement
19
+ 4. Binary is installed to `~/.local/bin/claude` with versions stored in `~/.local/share/claude/versions/`
20
+
21
+ ## Usage
22
+
23
+ ```json
24
+ {
25
+ "features": {
26
+ "./features/claude-code-native": {}
27
+ }
28
+ }
29
+ ```
30
+
31
+ With version pinning:
32
+
33
+ ```json
34
+ {
35
+ "features": {
36
+ "./features/claude-code-native": {
37
+ "version": "2.1.52"
38
+ }
39
+ }
40
+ }
41
+ ```
42
+
43
+ ## Why native over npm?
44
+
45
+ The npm installation (`npm install -g @anthropic-ai/claude-code`) runs as root during the Docker build, creating a package owned by `root`. When the container user tries to auto-update Claude Code in-session, it fails with `EACCES` because it can't write to the root-owned package directory.
46
+
47
+ The native binary installs to `~/.local/` under the container user's ownership, so `claude update` works without elevated permissions.
@@ -0,0 +1,29 @@
1
+ {
2
+ "id": "claude-code-native",
3
+ "version": "1.0.0",
4
+ "name": "Claude Code CLI (Native Binary)",
5
+ "description": "Installs Claude Code CLI as a native binary via the official Anthropic installer",
6
+ "documentationURL": "https://docs.anthropic.com/en/docs/claude-code",
7
+ "options": {
8
+ "version": {
9
+ "type": "string",
10
+ "description": "Version to install: 'latest', 'stable', or a specific semver. Use 'none' to skip.",
11
+ "default": "latest"
12
+ },
13
+ "username": {
14
+ "type": "string",
15
+ "description": "Container user to install for",
16
+ "default": "automatic"
17
+ }
18
+ },
19
+ "customizations": {
20
+ "vscode": {
21
+ "extensions": [
22
+ "anthropic.claude-code"
23
+ ]
24
+ }
25
+ },
26
+ "installsAfter": [
27
+ "ghcr.io/devcontainers/features/common-utils:2"
28
+ ]
29
+ }
@@ -0,0 +1,131 @@
1
+ #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
4
+ set -euo pipefail
5
+
6
+ VERSION="${VERSION:-latest}"
7
+ USERNAME="${USERNAME:-automatic}"
8
+
9
+ # Skip installation if version is "none"
10
+ if [ "${VERSION}" = "none" ]; then
11
+ echo "[claude-code-native] Skipping installation (version=none)"
12
+ exit 0
13
+ fi
14
+
15
+ echo "[claude-code-native] Starting installation..."
16
+ echo "[claude-code-native] Version: ${VERSION}"
17
+
18
+ # === VALIDATE DEPENDENCIES ===
19
+ # The official installer (claude.ai/install.sh) requires curl internally
20
+ if ! command -v curl >/dev/null 2>&1; then
21
+ echo "[claude-code-native] ERROR: curl is required"
22
+ echo " Ensure common-utils feature is installed first"
23
+ exit 1
24
+ fi
25
+
26
+ # === DETECT USER ===
27
+ if [ "${USERNAME}" = "auto" ] || [ "${USERNAME}" = "automatic" ]; then
28
+ if [ -n "${_REMOTE_USER:-}" ]; then
29
+ USERNAME="${_REMOTE_USER}"
30
+ elif getent passwd vscode >/dev/null 2>&1; then
31
+ USERNAME="vscode"
32
+ elif getent passwd node >/dev/null 2>&1; then
33
+ USERNAME="node"
34
+ elif getent passwd codespace >/dev/null 2>&1; then
35
+ USERNAME="codespace"
36
+ else
37
+ USERNAME="root"
38
+ fi
39
+ fi
40
+
41
+ USER_HOME=$(getent passwd "${USERNAME}" | cut -d: -f6)
42
+ if [ -z "${USER_HOME}" ]; then
43
+ echo "[claude-code-native] ERROR: Could not determine home directory for ${USERNAME}"
44
+ exit 1
45
+ fi
46
+
47
+ echo "[claude-code-native] Installing for user: ${USERNAME} (home: ${USER_HOME})"
48
+
49
+ # === PREPARE DIRECTORIES ===
50
+ mkdir -p "${USER_HOME}/.local/bin"
51
+ mkdir -p "${USER_HOME}/.local/share/claude"
52
+ mkdir -p "${USER_HOME}/.local/state"
53
+ mkdir -p "${USER_HOME}/.claude"
54
+ chown -R "${USERNAME}:" "${USER_HOME}/.local" "${USER_HOME}/.claude"
55
+
56
+ # === DETERMINE TARGET ===
57
+ # The official installer accepts: stable, latest, or a specific semver
58
+ TARGET="${VERSION}"
59
+ if [ "${TARGET}" != "latest" ] && [ "${TARGET}" != "stable" ]; then
60
+ if ! echo "${TARGET}" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
61
+ echo "[claude-code-native] ERROR: Invalid version '${TARGET}'"
62
+ echo " Use 'latest', 'stable', or a semver (e.g., 2.1.52)"
63
+ exit 1
64
+ fi
65
+ fi
66
+
67
+ # === INSTALL ===
68
+ # The official Anthropic installer handles:
69
+ # - Platform detection (linux/darwin, x64/arm64, glibc/musl)
70
+ # - Manifest download and checksum verification
71
+ # - Binary download to ~/.local/bin/claude (symlink to ~/.local/share/claude/versions/*)
72
+ echo "[claude-code-native] Downloading official installer..."
73
+
74
+ if [ "${USERNAME}" = "root" ]; then
75
+ curl -fsSL https://claude.ai/install.sh | bash -s -- "${TARGET}"
76
+ else
77
+ su - "${USERNAME}" -c "curl -fsSL https://claude.ai/install.sh | bash -s -- \"${TARGET}\""
78
+ fi
79
+
80
+ # === VERIFICATION ===
81
+ CLAUDE_BIN="${USER_HOME}/.local/bin/claude"
82
+
83
+ if [ -x "${CLAUDE_BIN}" ]; then
84
+ INSTALLED_VERSION=$(su - "${USERNAME}" -c "${CLAUDE_BIN} --version 2>/dev/null" || echo "unknown")
85
+ echo "[claude-code-native] ✓ Claude Code installed: ${INSTALLED_VERSION}"
86
+ echo "[claude-code-native] Binary: ${CLAUDE_BIN}"
87
+ else
88
+ echo "[claude-code-native] ERROR: Installation failed — ${CLAUDE_BIN} not found or not executable"
89
+ echo "[claude-code-native] Expected binary at: ${CLAUDE_BIN}"
90
+ ls -la "${USER_HOME}/.local/bin/" 2>/dev/null || true
91
+ exit 1
92
+ fi
93
+
94
+ # === POST-START HOOK ===
95
+ # Ensures hasCompletedOnboarding is set when token auth is configured.
96
+ # Runs as the LAST post-start hook (99- prefix) to catch overwrites from
97
+ # Claude Code CLI/extension that may race with postStartCommand.
98
+ HOOK_DIR="/usr/local/devcontainer-poststart.d"
99
+ mkdir -p "$HOOK_DIR"
100
+ cat > "$HOOK_DIR/99-claude-onboarding.sh" << 'HOOK_EOF'
101
+ #!/bin/bash
102
+ # Ensure hasCompletedOnboarding: true in .claude.json when token auth exists.
103
+ # Runs after all setup scripts to catch any overwrites by Claude Code CLI/extension.
104
+ _USERNAME="${SUDO_USER:-${USER:-vscode}}"
105
+ _USER_HOME=$(getent passwd "$_USERNAME" 2>/dev/null | cut -d: -f6)
106
+ _USER_HOME="${_USER_HOME:-/home/$_USERNAME}"
107
+ CLAUDE_DIR="${CLAUDE_CONFIG_DIR:-${_USER_HOME}/.claude}"
108
+ CLAUDE_JSON="$CLAUDE_DIR/.claude.json"
109
+ CRED_FILE="$CLAUDE_DIR/.credentials.json"
110
+
111
+ # Only act when token auth is configured
112
+ [ -f "$CRED_FILE" ] || exit 0
113
+
114
+ if [ -f "$CLAUDE_JSON" ]; then
115
+ if ! grep -q '"hasCompletedOnboarding"' "$CLAUDE_JSON" 2>/dev/null; then
116
+ if command -v jq >/dev/null 2>&1; then
117
+ jq '. + {"hasCompletedOnboarding": true}' "$CLAUDE_JSON" > "${CLAUDE_JSON}.tmp" && \
118
+ mv "${CLAUDE_JSON}.tmp" "$CLAUDE_JSON"
119
+ else
120
+ sed -i '$ s/}$/,\n "hasCompletedOnboarding": true\n}/' "$CLAUDE_JSON"
121
+ fi
122
+ echo "[claude-onboarding] Injected hasCompletedOnboarding into .claude.json"
123
+ fi
124
+ else
125
+ printf '{\n "hasCompletedOnboarding": true\n}\n' > "$CLAUDE_JSON"
126
+ echo "[claude-onboarding] Created .claude.json with hasCompletedOnboarding"
127
+ fi
128
+ HOOK_EOF
129
+ chmod +x "$HOOK_DIR/99-claude-onboarding.sh"
130
+
131
+ echo "[claude-code-native] Installation complete"
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  # ==============================
@@ -33,8 +33,8 @@ claude-dashboard -p 8080
33
33
  claude-dashboard --help
34
34
  ```
35
35
 
36
- The dashboard reads session data from `~/.claude/projects/` (symlinked to `/workspaces/.claude/projects/` in this devcontainer).
36
+ The dashboard reads session data from `~/.claude/projects/`.
37
37
 
38
38
  ## How persistence works
39
39
 
40
- Dashboard settings and cache are stored at `~/.claude-dashboard/`. Since the home directory is ephemeral in devcontainers, a poststart hook symlinks `~/.claude-dashboard` → `/workspaces/.claude-dashboard/`, which is bind-mounted and survives rebuilds.
40
+ Dashboard settings and cache are stored at `~/.claude-dashboard/`. A poststart hook symlinks `~/.claude-dashboard` → `/workspaces/.claude-dashboard/`, which is bind-mounted and survives rebuilds.
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  # ==============================
@@ -74,6 +76,7 @@ echo "[claude-session-dashboard] Installing for user: ${USERNAME}"
74
76
  # === INSTALL VIA NPM ===
75
77
  echo "[claude-session-dashboard] Installing claude-session-dashboard@${DASHBOARD_VERSION} globally..."
76
78
  npm install -g "claude-session-dashboard@${DASHBOARD_VERSION}"
79
+ npm cache clean --force 2>/dev/null || true
77
80
 
78
81
  # === PERSISTENCE SYMLINK (POSTSTART HOOK) ===
79
82
  # Settings/cache live at ~/.claude-dashboard, which is ephemeral (/home/vscode).
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  # ==============================
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  # ==============================
@@ -14,7 +14,9 @@ Downloads and compiles the official kitty terminfo entry from the [Kitty termina
14
14
 
15
15
  ## Usage
16
16
 
17
- No configuration needed. Once installed, containers automatically recognize `TERM=xterm-kitty` and provide full capability support.
17
+ The container defaults to `TERM=xterm-256color` with `COLORTERM=truecolor`, which provides full 256-color and 24-bit truecolor support for all terminals.
18
+
19
+ For Kitty users: the `devcontainer.json` `remoteEnv` uses `${localEnv:TERM:xterm-256color}`, which forwards your host `TERM` into VS Code sessions. If your host sets `TERM=xterm-kitty`, the installed terminfo ensures full Kitty-specific capability support (correct `bce` behavior, status line, etc.). For non-VS Code entry points (tmux, `docker exec`, SSH), `setup-aliases.sh` upgrades `TERM=xterm` to `xterm-256color` but preserves any other value. If no Kitty TERM is forwarded, `xterm-256color` provides equivalent color rendering.
18
20
 
19
21
  ```bash
20
22
  # Verify installation
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  # ==============================
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  # LSP Servers for Claude Code
3
5
  # Installs pyright, typescript-language-server, and gopls binaries
4
6
 
@@ -82,6 +84,8 @@ install_npm_package "typescript" "typescript" "${TS_VERSION}"
82
84
  # Install TypeScript Language Server
83
85
  install_npm_package "typescript-language-server" "typescript-language-server" "${TSLSP_VERSION}"
84
86
 
87
+ npm cache clean --force 2>/dev/null || true
88
+
85
89
  # Install gopls (Go LSP) - uses go install since it's a Go package
86
90
  echo "[lsp-servers] Installing gopls..."
87
91
  if command -v go &>/dev/null; then
@@ -259,11 +259,11 @@ MCP_CONFIG_DIR="${USER_HOME}/.config/mcp"
259
259
 
260
260
  **Current Behavior:**
261
261
  - Feature creates: `~/.config/mcp/qdrant-config.json`
262
- - Helper script (`configure-qdrant-mcp`) can update: `/workspaces/.claude/settings.json`
262
+ - Helper script (`configure-qdrant-mcp`) can update: `~/.claude/settings.json`
263
263
  - User must manually run helper script
264
264
 
265
265
  **Not Implemented (by request):**
266
- - Automatic injection into `/workspaces/.claude/settings.json` during installation
266
+ - Automatic injection into `~/.claude/settings.json` during installation
267
267
  - This will be discussed separately
268
268
 
269
269
  ---
@@ -378,7 +378,7 @@ Based on comprehensive review, the following fixes were applied:
378
378
  2. ✅ Fixed credentials leak - Added cleanup trap, secure temp file handling
379
379
 
380
380
  ### High Priority Fixes
381
- 3. ✅ Removed unused config directory (~/.config/mcp) - Target is /workspaces/.claude/settings.json
381
+ 3. ✅ Removed unused config directory (~/.config/mcp) - Target is ~/.claude/settings.json
382
382
  4. ✅ Consolidated helper scripts - Removed duplicate manual helper, kept auto-config only
383
383
  5. ✅ Fixed redundant redirections - Changed `&>/dev/null 2>&1` to `&>/dev/null`
384
384
  6. ✅ Fixed hardcoded workspace paths - Now uses `${WORKSPACE_ROOT:-/workspaces}`
@@ -154,6 +154,7 @@ The feature will validate these are present and exit with an error if missing.
154
154
  - ✅ **Cloud or Local**: Supports both Qdrant Cloud and local instances
155
155
  - ✅ **Idempotent**: Safe to run multiple times
156
156
  - ✅ **Multi-user**: Automatically detects container user
157
+ - ✅ **Config-aware**: Respects `CLAUDE_CONFIG_DIR` environment variable (defaults to `~/.claude`)
157
158
  - ✅ **Native mcpServers**: Uses VS Code's native devcontainer mcpServers support (declarative configuration)
158
159
  - ✅ **Dynamic Configuration**: Environment variables loaded from `/workspaces/.qdrant-mcp.env` file
159
160
  - ✅ **Secure**: API keys protected with 600 permissions on env file
@@ -50,6 +50,6 @@
50
50
  "installsAfter": [
51
51
  "ghcr.io/devcontainers/features/python:1",
52
52
  "ghcr.io/devcontainers/features/common-utils:2",
53
- "ghcr.io/anthropics/devcontainer-features/claude-code:1"
53
+ "./features/claude-code-native"
54
54
  ]
55
55
  }
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  # Import options from devcontainer-feature.json
@@ -188,8 +190,13 @@ else
188
190
  QDRANT_LOCAL_PATH="${QDRANT_LOCAL_PATH:-/workspaces/.qdrant/storage}"
189
191
  fi
190
192
 
193
+ # Resolve target user's home (guards against $HOME=/root during feature install)
194
+ _USERNAME="${SUDO_USER:-${USER:-vscode}}"
195
+ _USER_HOME=$(getent passwd "$_USERNAME" 2>/dev/null | cut -d: -f6)
196
+ _USER_HOME="${_USER_HOME:-/home/$_USERNAME}"
197
+
191
198
  # Ensure settings.json exists
192
- SETTINGS_FILE="/workspaces/.claude/settings.json"
199
+ SETTINGS_FILE="${CLAUDE_CONFIG_DIR:-${_USER_HOME}/.claude}/settings.json"
193
200
  if [ ! -f "$SETTINGS_FILE" ]; then
194
201
  echo "[mcp-qdrant] ERROR: $SETTINGS_FILE not found"
195
202
  exit 1
@@ -257,7 +264,7 @@ fi
257
264
 
258
265
  # Set proper permissions
259
266
  chmod 644 "$SETTINGS_FILE"
260
- chown "$(id -un):$(id -gn)" "$SETTINGS_FILE" 2>/dev/null || true
267
+ chown "${_USERNAME}:${_USERNAME}" "$SETTINGS_FILE" 2>/dev/null || true
261
268
 
262
269
  echo "[mcp-qdrant] ✓ Configuration complete"
263
270
  HOOK_EOF
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  echo "[mcp-qdrant] Registering Qdrant MCP server with Claude Code..."
@@ -56,8 +58,13 @@ else
56
58
  QDRANT_LOCAL_PATH="${QDRANT_LOCAL_PATH:-/workspaces/.qdrant/storage}"
57
59
  fi
58
60
 
61
+ # Resolve target user's home (guards against $HOME=/root when hook runs as root)
62
+ _USERNAME="${SUDO_USER:-${USER:-vscode}}"
63
+ _USER_HOME=$(getent passwd "$_USERNAME" 2>/dev/null | cut -d: -f6)
64
+ _USER_HOME="${_USER_HOME:-/home/$_USERNAME}"
65
+
59
66
  # Ensure settings.json exists
60
- SETTINGS_FILE="/workspaces/.claude/settings.json"
67
+ SETTINGS_FILE="${CLAUDE_CONFIG_DIR:-${_USER_HOME}/.claude}/settings.json"
61
68
  if [ ! -f "$SETTINGS_FILE" ]; then
62
69
  echo "[mcp-qdrant] ERROR: $SETTINGS_FILE not found"
63
70
  exit 1
@@ -125,6 +132,6 @@ fi
125
132
 
126
133
  # Set proper permissions
127
134
  chmod 644 "$SETTINGS_FILE"
128
- chown vscode:vscode "$SETTINGS_FILE" 2>/dev/null || true
135
+ chown "${_USERNAME}:${_USERNAME}" "$SETTINGS_FILE" 2>/dev/null || true
129
136
 
130
137
  echo "[mcp-qdrant] ✓ Configuration complete"
@@ -23,6 +23,6 @@
23
23
  },
24
24
  "installsAfter": [
25
25
  "ghcr.io/devcontainers/features/common-utils:2",
26
- "ghcr.io/anthropics/devcontainer-features/claude-code:1"
26
+ "./features/claude-code-native"
27
27
  ]
28
28
  }
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  VERSION="${VERSION:-latest}"
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  # ==============================
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  # ==============================
@@ -1,4 +1,6 @@
1
1
  #!/bin/bash
2
+ # SPDX-License-Identifier: GPL-3.0-only
3
+ # Copyright (c) 2026 Marcus Krueger
2
4
  set -euo pipefail
3
5
 
4
6
  # ==============================