codeforge-dev 1.14.1 → 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.
- package/{.devcontainer/config/defaults → .codeforge/config}/ccstatusline-settings.json +44 -6
- package/.codeforge/config/main-system-prompt.md +412 -0
- package/.codeforge/config/orchestrator-system-prompt.md +333 -0
- package/{.devcontainer/config/defaults → .codeforge/config}/settings.json +7 -2
- package/{.devcontainer/config → .codeforge}/file-manifest.json +15 -9
- package/{.devcontainer → .codeforge/scripts}/connect-external-terminal.sh +3 -1
- package/.devcontainer/.env.example +17 -5
- package/.devcontainer/.secrets.example +3 -0
- package/.devcontainer/CHANGELOG.md +224 -3
- package/.devcontainer/CLAUDE.md +26 -43
- package/.devcontainer/README.md +35 -20
- package/.devcontainer/devcontainer.json +36 -17
- package/.devcontainer/features/agent-browser/install.sh +3 -0
- package/.devcontainer/features/ast-grep/install.sh +3 -0
- package/.devcontainer/features/biome/install.sh +3 -0
- package/.devcontainer/features/ccburn/devcontainer-feature.json +0 -5
- package/.devcontainer/features/ccburn/install.sh +2 -0
- package/.devcontainer/features/ccms/install.sh +2 -0
- package/.devcontainer/features/ccstatusline/README.md +7 -6
- package/.devcontainer/features/ccstatusline/install.sh +9 -4
- package/.devcontainer/features/ccusage/devcontainer-feature.json +0 -5
- package/.devcontainer/features/ccusage/install.sh +2 -0
- package/.devcontainer/features/chromaterm/chromaterm.yml +2 -2
- package/.devcontainer/features/chromaterm/install.sh +2 -0
- package/.devcontainer/features/claude-code-native/README.md +47 -0
- package/.devcontainer/features/claude-code-native/devcontainer-feature.json +29 -0
- package/.devcontainer/features/claude-code-native/install.sh +131 -0
- package/.devcontainer/features/claude-monitor/devcontainer-feature.json +0 -5
- package/.devcontainer/features/claude-monitor/install.sh +2 -0
- package/.devcontainer/features/claude-session-dashboard/README.md +2 -2
- package/.devcontainer/features/claude-session-dashboard/devcontainer-feature.json +1 -2
- package/.devcontainer/features/claude-session-dashboard/install.sh +3 -0
- package/.devcontainer/features/dprint/install.sh +2 -0
- package/.devcontainer/features/hadolint/install.sh +2 -0
- package/.devcontainer/features/kitty-terminfo/README.md +3 -1
- package/.devcontainer/features/kitty-terminfo/install.sh +2 -0
- package/.devcontainer/features/lsp-servers/install.sh +4 -0
- package/.devcontainer/features/mcp-qdrant/CHANGES.md +3 -3
- package/.devcontainer/features/mcp-qdrant/README.md +1 -0
- package/.devcontainer/features/mcp-qdrant/devcontainer-feature.json +1 -7
- package/.devcontainer/features/mcp-qdrant/install.sh +9 -2
- package/.devcontainer/features/mcp-qdrant/poststart-hook.sh +9 -2
- package/.devcontainer/features/notify-hook/devcontainer-feature.json +1 -1
- package/.devcontainer/features/notify-hook/install.sh +2 -0
- package/.devcontainer/features/ruff/install.sh +2 -0
- package/.devcontainer/features/shellcheck/install.sh +2 -0
- package/.devcontainer/features/shfmt/install.sh +2 -0
- package/.devcontainer/features/tmux/README.md +3 -3
- package/.devcontainer/features/tmux/install.sh +3 -1
- package/.devcontainer/features/tree-sitter/devcontainer-feature.json +0 -6
- package/.devcontainer/features/tree-sitter/install.sh +4 -0
- package/.devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json +27 -11
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/README.md +20 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/architect.md +182 -29
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/bash-exec.md +9 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/claude-guide.md +13 -4
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/debug-logs.md +24 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/dependency-analyst.md +16 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/documenter.md +412 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/explorer.md +18 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/generalist.md +36 -10
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/git-archaeologist.md +10 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/implementer.md +260 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/investigator.md +262 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/migrator.md +10 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/perf-profiler.md +21 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/refactorer.md +18 -8
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/researcher.md +23 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/security-auditor.md +20 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/spec-writer.md +12 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/statusline-config.md +12 -2
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/test-writer.md +22 -7
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/guard-readonly-bash.py +9 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/scripts/redirect-builtin-agents.py +2 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/README.md +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-code-quality/scripts/advisory-test-runner.py +4 -2
- package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/README.md +3 -2
- package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/block-dangerous.py +89 -15
- package/.devcontainer/plugins/devs-marketplace/plugins/git-workflow/.claude-plugin/plugin.json +7 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/git-workflow/README.md +125 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/git-workflow/skills/pr-review/SKILL.md +325 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/git-workflow/skills/ship/SKILL.md +314 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/prompt-snippets/.claude-plugin/plugin.json +5 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/prompt-snippets/README.md +52 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/prompt-snippets/skills/ps/SKILL.md +37 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/README.md +2 -2
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected-bash.py +80 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected.py +4 -4
- package/.devcontainer/plugins/devs-marketplace/plugins/session-context/README.md +30 -14
- package/.devcontainer/plugins/devs-marketplace/plugins/session-context/hooks/hooks.json +13 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/collect-session-edits.py +44 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/session-context/scripts/commit-reminder.py +89 -10
- package/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/.claude-plugin/plugin.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/README.md +19 -11
- package/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/scripts/skill-suggester.py +476 -282
- package/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/team/SKILL.md +4 -4
- package/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/worktree/SKILL.md +227 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/worktree/references/manual-worktree-commands.md +238 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/skill-engine/skills/worktree/references/parallel-workflow-patterns.md +228 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/spec-workflow/skills/spec-build/SKILL.md +2 -2
- package/.devcontainer/plugins/devs-marketplace/plugins/ticket-workflow/scripts/ticket-linker.py +2 -2
- package/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/README.md +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/workspace-scope-guard/scripts/guard-workspace-scope.py +69 -31
- package/.devcontainer/scripts/check-setup.sh +5 -3
- package/.devcontainer/scripts/preflight.sh +113 -0
- package/.devcontainer/scripts/setup-aliases.sh +13 -8
- package/.devcontainer/scripts/setup-auth.sh +46 -0
- package/.devcontainer/scripts/setup-config.sh +29 -10
- package/.devcontainer/scripts/setup-migrate-claude.sh +80 -0
- package/.devcontainer/scripts/setup-migrate-codeforge.sh +60 -0
- package/.devcontainer/scripts/setup-plugins.sh +5 -5
- package/.devcontainer/scripts/setup-projects.sh +4 -2
- package/.devcontainer/scripts/setup-terminal.sh +3 -1
- package/.devcontainer/scripts/setup-update-claude.sh +22 -27
- package/.devcontainer/scripts/setup.sh +78 -5
- package/LICENSE.txt +14 -0
- package/README.md +82 -7
- package/package.json +4 -1
- package/setup.js +392 -21
- package/.devcontainer/config/defaults/main-system-prompt.md +0 -664
- package/.devcontainer/docs/configuration-reference.md +0 -93
- package/.devcontainer/docs/keybindings.md +0 -100
- package/.devcontainer/docs/optional-features.md +0 -64
- package/.devcontainer/docs/plugins.md +0 -176
- package/.devcontainer/docs/troubleshooting.md +0 -128
- package/.devcontainer/plugins/devs-marketplace/plugins/agent-system/agents/doc-writer.md +0 -334
- package/.devcontainer/scripts/setup-symlink-claude.sh +0 -36
- /package/{.devcontainer/config/defaults → .codeforge/config}/keybindings.json +0 -0
- /package/{.devcontainer/config/defaults → .codeforge/config}/rules/session-search.md +0 -0
- /package/{.devcontainer/config/defaults → .codeforge/config}/rules/spec-workflow.md +0 -0
- /package/{.devcontainer/config/defaults → .codeforge/config}/rules/workspace-scope.md +0 -0
- /package/{.devcontainer/config/defaults → .codeforge/config}/writing-system-prompt.md +0 -0
- /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
|
# Configure Git (GitHub CLI) and NPM authentication from .secrets file or environment variables.
|
|
3
5
|
# Environment variables override .secrets values, supporting Codespaces secrets and localEnv.
|
|
4
6
|
# Auth failure should not block other setup steps, so set -e is intentionally omitted.
|
|
@@ -65,6 +67,50 @@ else
|
|
|
65
67
|
echo "[setup-auth] NPM_TOKEN not set, skipping NPM auth"
|
|
66
68
|
fi
|
|
67
69
|
|
|
70
|
+
# --- Claude auth token (from 'claude setup-token') ---
|
|
71
|
+
# Long-lived tokens only — generated via: claude setup-token
|
|
72
|
+
# Note: After unset, the token remains visible in /proc/<pid>/environ for the
|
|
73
|
+
# lifetime of this process. This is a platform limitation of environment variables.
|
|
74
|
+
_USERNAME="${SUDO_USER:-${USER:-vscode}}"
|
|
75
|
+
_USER_HOME=$(getent passwd "$_USERNAME" 2>/dev/null | cut -d: -f6)
|
|
76
|
+
_USER_HOME="${_USER_HOME:-/home/$_USERNAME}"
|
|
77
|
+
CLAUDE_CRED_DIR="${CLAUDE_CONFIG_DIR:-${_USER_HOME}/.claude}"
|
|
78
|
+
CLAUDE_CRED_FILE="$CLAUDE_CRED_DIR/.credentials.json"
|
|
79
|
+
if [ -n "$CLAUDE_AUTH_TOKEN" ]; then
|
|
80
|
+
# Validate token format (claude setup-token produces sk-ant-* tokens)
|
|
81
|
+
if [[ ! "$CLAUDE_AUTH_TOKEN" =~ ^sk-ant- ]]; then
|
|
82
|
+
echo "[setup-auth] WARNING: CLAUDE_AUTH_TOKEN doesn't match expected format (sk-ant-*), skipping"
|
|
83
|
+
elif [ -f "$CLAUDE_CRED_FILE" ]; then
|
|
84
|
+
echo "[setup-auth] .credentials.json already exists, skipping token injection"
|
|
85
|
+
# Verify permissions haven't been tampered with
|
|
86
|
+
perms=$(stat -c %a "$CLAUDE_CRED_FILE" 2>/dev/null)
|
|
87
|
+
if [ -n "$perms" ] && [ "$perms" != "600" ]; then
|
|
88
|
+
echo "[setup-auth] WARNING: .credentials.json has permissions $perms (expected 600), fixing"
|
|
89
|
+
chmod 600 "$CLAUDE_CRED_FILE"
|
|
90
|
+
fi
|
|
91
|
+
AUTH_CONFIGURED=true
|
|
92
|
+
else
|
|
93
|
+
echo "[setup-auth] Creating .credentials.json from CLAUDE_AUTH_TOKEN..."
|
|
94
|
+
# Create directory with restrictive permissions (matches credential file at 600)
|
|
95
|
+
( umask 077; mkdir -p "$CLAUDE_CRED_DIR" )
|
|
96
|
+
# Escape JSON-special characters in token value (defense against malformed JSON
|
|
97
|
+
# if a token ever contains " or \ — unlikely with sk-ant-* but closes the gap)
|
|
98
|
+
ESCAPED_TOKEN=$(printf '%s' "$CLAUDE_AUTH_TOKEN" | sed 's/\\/\\\\/g; s/"/\\"/g')
|
|
99
|
+
# Write credentials with restrictive permissions from the start (no race window).
|
|
100
|
+
# Uses printf '%s' to avoid shell expansion of token value (defense against
|
|
101
|
+
# metacharacters in the token string — backticks, $(), quotes).
|
|
102
|
+
if ( umask 077; printf '{\n "claudeAiOauth": {\n "accessToken": "%s",\n "refreshToken": "%s",\n "expiresAt": 9999999999999,\n "scopes": ["user:inference", "user:profile"]\n }\n}\n' "$ESCAPED_TOKEN" "$ESCAPED_TOKEN" > "$CLAUDE_CRED_FILE" ); then
|
|
103
|
+
echo "[setup-auth] Claude auth token configured"
|
|
104
|
+
AUTH_CONFIGURED=true
|
|
105
|
+
else
|
|
106
|
+
echo "[setup-auth] WARNING: Failed to write .credentials.json — check permissions on $CLAUDE_CRED_DIR"
|
|
107
|
+
fi
|
|
108
|
+
fi
|
|
109
|
+
unset CLAUDE_AUTH_TOKEN
|
|
110
|
+
else
|
|
111
|
+
echo "[setup-auth] CLAUDE_AUTH_TOKEN not set, skipping Claude auth"
|
|
112
|
+
fi
|
|
113
|
+
|
|
68
114
|
# --- Summary ---
|
|
69
115
|
if [ "$AUTH_CONFIGURED" = true ]; then
|
|
70
116
|
echo "[setup-auth] Auth configuration complete"
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-only
|
|
3
|
+
# Copyright (c) 2026 Marcus Krueger
|
|
2
4
|
# Copy configuration files to workspace based on file-manifest.json
|
|
3
5
|
|
|
4
|
-
CONFIG_DIR="${CONFIG_SOURCE_DIR:?CONFIG_SOURCE_DIR not set}"
|
|
5
|
-
MANIFEST="$CONFIG_DIR/file-manifest.json"
|
|
6
|
-
|
|
7
6
|
log() { echo "[setup-config] $*"; }
|
|
8
7
|
warn() { echo "[setup-config] WARNING: $*"; }
|
|
9
8
|
err() { echo "[setup-config] ERROR: $*" >&2; }
|
|
10
9
|
|
|
10
|
+
CODEFORGE_DIR="${CODEFORGE_DIR:-${WORKSPACE_ROOT:?}/.codeforge}"
|
|
11
|
+
CONFIG_DIR="$CODEFORGE_DIR"
|
|
12
|
+
MANIFEST="$CODEFORGE_DIR/file-manifest.json"
|
|
13
|
+
|
|
14
|
+
# Legacy fallback: if .codeforge/ doesn't exist but old config dir does, warn and use old path
|
|
15
|
+
if [ ! -d "$CODEFORGE_DIR" ] && [ -d "${WORKSPACE_ROOT}/.devcontainer/config/defaults" ]; then
|
|
16
|
+
warn ".codeforge/ not found — falling back to .devcontainer/config/defaults (deprecated)"
|
|
17
|
+
CONFIG_DIR="${WORKSPACE_ROOT}/.devcontainer/config"
|
|
18
|
+
MANIFEST="$CONFIG_DIR/file-manifest.json"
|
|
19
|
+
fi
|
|
20
|
+
|
|
11
21
|
# Deprecation notice if legacy OVERWRITE_CONFIG is still set
|
|
12
22
|
if [ -n "${OVERWRITE_CONFIG+x}" ]; then
|
|
13
23
|
warn "OVERWRITE_CONFIG is deprecated. Use per-file 'overwrite' in config/file-manifest.json instead."
|
|
@@ -18,7 +28,7 @@ legacy_copy() {
|
|
|
18
28
|
local target_dir="${CLAUDE_CONFIG_DIR:?CLAUDE_CONFIG_DIR not set}"
|
|
19
29
|
warn "file-manifest.json not found, falling back to legacy copy"
|
|
20
30
|
mkdir -p "$target_dir"
|
|
21
|
-
for file in
|
|
31
|
+
for file in config/settings.json config/keybindings.json config/main-system-prompt.md; do
|
|
22
32
|
if [ -f "$CONFIG_DIR/$file" ]; then
|
|
23
33
|
local basename="${file##*/}"
|
|
24
34
|
cp "$CONFIG_DIR/$file" "$target_dir/$basename"
|
|
@@ -96,21 +106,30 @@ jq -r '.[] | [.src, .dest, (.destFilename // "__NONE__"), (.enabled // true | to
|
|
|
96
106
|
# Apply overwrite strategy
|
|
97
107
|
case "$overwrite" in
|
|
98
108
|
always)
|
|
99
|
-
cp "$src_path" "$dest_path"
|
|
100
|
-
|
|
109
|
+
if cp "$src_path" "$dest_path" 2>/dev/null; then
|
|
110
|
+
log "Copied $src → $dest_path (always)"
|
|
111
|
+
else
|
|
112
|
+
warn "Failed to copy $src → $dest_path (permission denied?)"
|
|
113
|
+
fi
|
|
101
114
|
;;
|
|
102
115
|
never)
|
|
103
116
|
if [ ! -f "$dest_path" ]; then
|
|
104
|
-
cp "$src_path" "$dest_path"
|
|
105
|
-
|
|
117
|
+
if cp "$src_path" "$dest_path" 2>/dev/null; then
|
|
118
|
+
log "Copied $src → $dest_path (new)"
|
|
119
|
+
else
|
|
120
|
+
warn "Failed to copy $src → $dest_path (permission denied?)"
|
|
121
|
+
fi
|
|
106
122
|
else
|
|
107
123
|
log "Skipping $src (exists, overwrite=never)"
|
|
108
124
|
fi
|
|
109
125
|
;;
|
|
110
126
|
if-changed | *)
|
|
111
127
|
if should_copy "$src_path" "$dest_path"; then
|
|
112
|
-
cp "$src_path" "$dest_path"
|
|
113
|
-
|
|
128
|
+
if cp "$src_path" "$dest_path" 2>/dev/null; then
|
|
129
|
+
log "Copied $src → $dest_path (changed)"
|
|
130
|
+
else
|
|
131
|
+
warn "Failed to copy $src → $dest_path (permission denied?)"
|
|
132
|
+
fi
|
|
114
133
|
else
|
|
115
134
|
log "Skipping $src (unchanged)"
|
|
116
135
|
fi
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-only
|
|
3
|
+
# Copyright (c) 2026 Marcus Krueger
|
|
4
|
+
# One-time migration: /workspaces/.claude → $HOME/.claude
|
|
5
|
+
# Migrates config, credentials, and rules from the old bind-mount location
|
|
6
|
+
# to the new home directory (Docker named volume).
|
|
7
|
+
#
|
|
8
|
+
# Uses cp -a (archive) for a faithful copy that preserves permissions,
|
|
9
|
+
# timestamps, symlinks, and directory structure. Migration is one-time
|
|
10
|
+
# (marker-gated), so overwrite is safe — the old directory is authoritative.
|
|
11
|
+
|
|
12
|
+
OLD_DIR="/workspaces/.claude"
|
|
13
|
+
_USERNAME="${SUDO_USER:-${USER:-vscode}}"
|
|
14
|
+
_USER_HOME=$(getent passwd "$_USERNAME" 2>/dev/null | cut -d: -f6)
|
|
15
|
+
_USER_HOME="${_USER_HOME:-/home/$_USERNAME}"
|
|
16
|
+
NEW_DIR="${CLAUDE_CONFIG_DIR:-${_USER_HOME}/.claude}"
|
|
17
|
+
MARKER="$NEW_DIR/.migrated-from-workspaces"
|
|
18
|
+
CODEFORGE_MARKER="${CODEFORGE_DIR:-${WORKSPACE_ROOT:-/workspaces}/.codeforge}/.markers/v2-migrated"
|
|
19
|
+
|
|
20
|
+
# Nothing to migrate if old directory doesn't exist
|
|
21
|
+
if [ ! -d "$OLD_DIR" ]; then
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
# Skip if old directory is empty (nothing worth migrating)
|
|
26
|
+
if [ -z "$(ls -A "$OLD_DIR" 2>/dev/null)" ]; then
|
|
27
|
+
exit 0
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Idempotency: skip if migration already completed (check both old and new markers)
|
|
31
|
+
if [ -f "$MARKER" ] || [ -f "$CODEFORGE_MARKER" ]; then
|
|
32
|
+
exit 0
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# Symlink protection: verify OLD_DIR itself is a real directory, not a symlink
|
|
36
|
+
if [ -L "$OLD_DIR" ]; then
|
|
37
|
+
echo "[setup-migrate] WARNING: /workspaces/.claude is a symlink, skipping migration for safety"
|
|
38
|
+
exit 0
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
echo "[setup-migrate] Migrating /workspaces/.claude → $NEW_DIR ..."
|
|
42
|
+
mkdir -p "$NEW_DIR"
|
|
43
|
+
|
|
44
|
+
# -a: archive mode (-dR --preserve=all) — preserves permissions, timestamps,
|
|
45
|
+
# symlinks, ownership, and directory structure faithfully.
|
|
46
|
+
# Errors logged explicitly (no 2>/dev/null) so failures are visible.
|
|
47
|
+
if cp -a "$OLD_DIR/." "$NEW_DIR/"; then
|
|
48
|
+
# Fix ownership — source files may be owned by a different uid from a
|
|
49
|
+
# previous container lifecycle. chown everything to the current user.
|
|
50
|
+
chown -R "$(id -un):$(id -gn)" "$NEW_DIR/" 2>/dev/null || true
|
|
51
|
+
|
|
52
|
+
# Verify critical files arrived
|
|
53
|
+
MISSING=""
|
|
54
|
+
[ ! -f "$NEW_DIR/.claude.json" ] && [ -f "$OLD_DIR/.claude.json" ] && MISSING="$MISSING .claude.json"
|
|
55
|
+
[ ! -d "$NEW_DIR/plugins" ] && [ -d "$OLD_DIR/plugins" ] && MISSING="$MISSING plugins/"
|
|
56
|
+
[ ! -f "$NEW_DIR/.credentials.json" ] && [ -f "$OLD_DIR/.credentials.json" ] && MISSING="$MISSING .credentials.json"
|
|
57
|
+
if [ -n "$MISSING" ]; then
|
|
58
|
+
echo "[setup-migrate] WARNING: Migration incomplete — missing:$MISSING"
|
|
59
|
+
echo "[setup-migrate] Old directory preserved at $OLD_DIR for manual recovery"
|
|
60
|
+
exit 1
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# Mark migration complete (write to both old and new marker locations)
|
|
64
|
+
date -Iseconds > "$MARKER"
|
|
65
|
+
_codeforge_markers_dir="$(dirname "$CODEFORGE_MARKER")"
|
|
66
|
+
if [ -d "$_codeforge_markers_dir" ] || mkdir -p "$_codeforge_markers_dir" 2>/dev/null; then
|
|
67
|
+
date -Iseconds > "$CODEFORGE_MARKER"
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
# Rename old directory to .bak
|
|
71
|
+
if mv "$OLD_DIR" "${OLD_DIR}.bak" 2>/dev/null; then
|
|
72
|
+
echo "[setup-migrate] Migration complete. Old directory moved to ${OLD_DIR}.bak"
|
|
73
|
+
else
|
|
74
|
+
echo "[setup-migrate] Migration complete. Could not rename old directory — remove /workspaces/.claude/ manually"
|
|
75
|
+
fi
|
|
76
|
+
else
|
|
77
|
+
echo "[setup-migrate] ERROR: cp failed — check output above for details"
|
|
78
|
+
echo "[setup-migrate] Old directory preserved at $OLD_DIR"
|
|
79
|
+
exit 1
|
|
80
|
+
fi
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-only
|
|
3
|
+
# Copyright (c) 2026 Marcus Krueger
|
|
4
|
+
# One-time migration: .devcontainer/config/ → .codeforge/
|
|
5
|
+
# Migrates config files, manifest, and terminal scripts from the legacy
|
|
6
|
+
# .devcontainer/config/ layout to the new .codeforge/ directory structure.
|
|
7
|
+
|
|
8
|
+
WORKSPACE_ROOT="${WORKSPACE_ROOT:?WORKSPACE_ROOT not set}"
|
|
9
|
+
CODEFORGE_DIR="${CODEFORGE_DIR:-${WORKSPACE_ROOT}/.codeforge}"
|
|
10
|
+
OLD_CONFIG_DIR="${WORKSPACE_ROOT}/.devcontainer/config"
|
|
11
|
+
OLD_DEFAULTS_DIR="${OLD_CONFIG_DIR}/defaults"
|
|
12
|
+
MARKER="$CODEFORGE_DIR/.markers/v2-migrated"
|
|
13
|
+
|
|
14
|
+
log() { echo "[setup-migrate-codeforge] $*"; }
|
|
15
|
+
warn() { echo "[setup-migrate-codeforge] WARNING: $*"; }
|
|
16
|
+
|
|
17
|
+
# Already migrated — skip
|
|
18
|
+
if [ -d "$CODEFORGE_DIR" ]; then
|
|
19
|
+
log ".codeforge/ already exists — skipping migration"
|
|
20
|
+
exit 0
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
# Nothing to migrate if old defaults dir doesn't exist
|
|
24
|
+
if [ ! -d "$OLD_DEFAULTS_DIR" ]; then
|
|
25
|
+
log "No legacy .devcontainer/config/defaults/ found — skipping migration"
|
|
26
|
+
exit 0
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
log "Migrating .devcontainer/config/ → .codeforge/ ..."
|
|
30
|
+
|
|
31
|
+
# Create directory structure
|
|
32
|
+
mkdir -p "$CODEFORGE_DIR/config/rules" \
|
|
33
|
+
"$CODEFORGE_DIR/scripts" \
|
|
34
|
+
"$CODEFORGE_DIR/.markers" \
|
|
35
|
+
"$CODEFORGE_DIR/.checksums"
|
|
36
|
+
|
|
37
|
+
# Copy config files from .devcontainer/config/defaults/ → .codeforge/config/
|
|
38
|
+
if [ -d "$OLD_DEFAULTS_DIR" ]; then
|
|
39
|
+
cp -a "$OLD_DEFAULTS_DIR/." "$CODEFORGE_DIR/config/"
|
|
40
|
+
log "Copied config files from defaults/ → .codeforge/config/"
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Copy file-manifest.json, rewriting src paths from defaults/ to config/
|
|
44
|
+
if [ -f "$OLD_CONFIG_DIR/file-manifest.json" ]; then
|
|
45
|
+
sed 's|"defaults/|"config/|g' "$OLD_CONFIG_DIR/file-manifest.json" > "$CODEFORGE_DIR/file-manifest.json"
|
|
46
|
+
log "Copied file-manifest.json (rewrote defaults/ → config/)"
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# Copy terminal scripts from .devcontainer/ → .codeforge/scripts/
|
|
50
|
+
for script in connect-external-terminal.sh connect-external-terminal.ps1; do
|
|
51
|
+
if [ -f "${WORKSPACE_ROOT}/.devcontainer/${script}" ]; then
|
|
52
|
+
cp "${WORKSPACE_ROOT}/.devcontainer/${script}" "$CODEFORGE_DIR/scripts/${script}"
|
|
53
|
+
log "Copied ${script} → .codeforge/scripts/"
|
|
54
|
+
fi
|
|
55
|
+
done
|
|
56
|
+
|
|
57
|
+
# Write migration marker
|
|
58
|
+
date -Iseconds > "$MARKER"
|
|
59
|
+
|
|
60
|
+
log "Migration complete — .codeforge/ is ready"
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-only
|
|
3
|
+
# Copyright (c) 2026 Marcus Krueger
|
|
2
4
|
# Install plugins: official Anthropic + local devs-marketplace registration
|
|
3
5
|
#
|
|
4
6
|
# Individual marketplace plugins are enabled via enabledPlugins in settings.json.
|
|
@@ -20,10 +22,8 @@ fi
|
|
|
20
22
|
echo "[setup-plugins] Installing plugins..."
|
|
21
23
|
|
|
22
24
|
# --- Official Anthropic Plugins ---
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"svelte@sveltejs/mcp"
|
|
26
|
-
)
|
|
25
|
+
DEFAULT_OFFICIAL_PLUGINS="frontend-design@anthropics/claude-code code-review@anthropics/claude-code feature-dev@anthropics/claude-code pr-review-toolkit@anthropics/claude-code svelte@sveltejs/mcp"
|
|
26
|
+
IFS=' ' read -ra OFFICIAL_PLUGINS <<< "${OFFICIAL_PLUGINS:-$DEFAULT_OFFICIAL_PLUGINS}"
|
|
27
27
|
|
|
28
28
|
for plugin in "${OFFICIAL_PLUGINS[@]}"; do
|
|
29
29
|
echo "[setup-plugins] Installing $plugin..."
|
|
@@ -57,7 +57,7 @@ if [ -d "$MARKETPLACE_PATH/plugins" ]; then
|
|
|
57
57
|
plugin_name=$(basename "$plugin_dir")
|
|
58
58
|
|
|
59
59
|
# Skip blacklisted plugins
|
|
60
|
-
if echo ",$PLUGIN_BLACKLIST," | grep -q ",$plugin_name,"; then
|
|
60
|
+
if echo ",${PLUGIN_BLACKLIST}," | grep -q ",$plugin_name,"; then
|
|
61
61
|
echo "[setup-plugins] Skipping $plugin_name (blacklisted)"
|
|
62
62
|
continue
|
|
63
63
|
fi
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-only
|
|
3
|
+
# Copyright (c) 2026 Marcus Krueger
|
|
2
4
|
# Auto-detect projects under /workspaces/ and register them in Project Manager's projects.json.
|
|
3
5
|
# Runs an initial scan synchronously, then starts an inotifywait background watcher
|
|
4
6
|
# that updates the project list instantly when directories are created or removed.
|
|
@@ -12,7 +14,7 @@ PID_FILE="/tmp/project-watcher.pid"
|
|
|
12
14
|
LOG_PREFIX="[setup-projects]"
|
|
13
15
|
|
|
14
16
|
# Directories to exclude from project detection (hidden/config dirs)
|
|
15
|
-
EXCLUDED_DIRS="
|
|
17
|
+
EXCLUDED_DIRS="${PROJECT_EXCLUDE_DIRS:-.claude .gh .tmp .devcontainer .config node_modules .git}"
|
|
16
18
|
|
|
17
19
|
# --- Helpers ---
|
|
18
20
|
|
|
@@ -176,7 +178,7 @@ start_watcher() {
|
|
|
176
178
|
fi
|
|
177
179
|
|
|
178
180
|
# Check if inotifywait is available (installed by tmux feature at build time)
|
|
179
|
-
if ! command -v inotifywait
|
|
181
|
+
if ! command -v inotifywait >/dev/null 2>&1; then
|
|
180
182
|
echo "$LOG_PREFIX WARNING: inotify-tools not installed, watcher disabled"
|
|
181
183
|
return 1
|
|
182
184
|
fi
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-only
|
|
3
|
+
# Copyright (c) 2026 Marcus Krueger
|
|
2
4
|
# Configure VS Code Shift+Enter → newline for Claude Code terminal input
|
|
3
5
|
# Writes to ~/.config/Code/User/keybindings.json (same path /terminal-setup uses)
|
|
4
6
|
|
|
@@ -19,7 +21,7 @@ fi
|
|
|
19
21
|
# === Merge or create keybindings ===
|
|
20
22
|
BINDING='{"key":"shift+enter","command":"workbench.action.terminal.sendSequence","args":{"text":"\\u001b\\r"},"when":"terminalFocus"}'
|
|
21
23
|
|
|
22
|
-
if [ -f "$KEYBINDINGS_FILE" ] && command -v jq
|
|
24
|
+
if [ -f "$KEYBINDINGS_FILE" ] && command -v jq >/dev/null 2>&1; then
|
|
23
25
|
# Merge into existing keybindings
|
|
24
26
|
if jq empty "$KEYBINDINGS_FILE" 2>/dev/null; then
|
|
25
27
|
jq ". + [$BINDING]" "$KEYBINDINGS_FILE" >"$KEYBINDINGS_FILE.tmp" &&
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-only
|
|
3
|
+
# Copyright (c) 2026 Marcus Krueger
|
|
2
4
|
# Update Claude Code CLI to the latest version (native binary only)
|
|
3
5
|
# Runs non-blocking in background by default via setup.sh
|
|
4
6
|
# All failures are warnings — this script never blocks container startup
|
|
@@ -25,46 +27,39 @@ fi
|
|
|
25
27
|
|
|
26
28
|
# === CLEANUP TRAP ===
|
|
27
29
|
cleanup() {
|
|
28
|
-
rm -f "${_TMPDIR}/claude-update" 2>/dev/null || true
|
|
29
|
-
rm -f "${_TMPDIR}/claude-update-manifest.json" 2>/dev/null || true
|
|
30
30
|
rm -rf "$LOCK_FILE" 2>/dev/null || true
|
|
31
31
|
}
|
|
32
32
|
trap cleanup EXIT
|
|
33
33
|
|
|
34
|
-
# ===
|
|
35
|
-
|
|
36
|
-
log "Claude Code not found, skipping update"
|
|
37
|
-
exit 0
|
|
38
|
-
fi
|
|
34
|
+
# === NATIVE BINARY ===
|
|
35
|
+
NATIVE_BIN="$HOME/.local/bin/claude"
|
|
39
36
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
elif [ -x "/usr/local/bin/claude" ]; then
|
|
46
|
-
NATIVE_BIN="/usr/local/bin/claude"
|
|
47
|
-
else
|
|
48
|
-
NATIVE_BIN=""
|
|
37
|
+
if [ ! -x "$NATIVE_BIN" ]; then
|
|
38
|
+
log "ERROR: Native binary not found at ${NATIVE_BIN}"
|
|
39
|
+
log " The claude-code-native feature should install this during container build."
|
|
40
|
+
log " Try rebuilding the container or running: curl -fsSL https://claude.ai/install.sh | sh"
|
|
41
|
+
exit 1
|
|
49
42
|
fi
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
43
|
+
|
|
44
|
+
# === TRANSITIONAL: Remove leftover npm installation ===
|
|
45
|
+
NPM_CLAUDE="$(npm config get prefix 2>/dev/null)/lib/node_modules/@anthropic-ai/claude-code"
|
|
46
|
+
if [ -d "$NPM_CLAUDE" ]; then
|
|
47
|
+
log "Removing leftover npm installation at ${NPM_CLAUDE}..."
|
|
48
|
+
if sudo npm uninstall -g @anthropic-ai/claude-code 2>/dev/null; then
|
|
49
|
+
log "Removed leftover npm installation"
|
|
54
50
|
else
|
|
55
|
-
log "WARNING:
|
|
56
|
-
exit 0
|
|
51
|
+
log "WARNING: Could not remove npm installation (non-blocking)"
|
|
57
52
|
fi
|
|
58
|
-
# Skip update check on first install — next start will handle it
|
|
59
|
-
exit 0
|
|
60
53
|
fi
|
|
61
54
|
|
|
62
55
|
# === CHECK FOR UPDATES ===
|
|
63
56
|
CURRENT_VERSION=$("$NATIVE_BIN" --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "unknown")
|
|
64
57
|
log "Current version: ${CURRENT_VERSION}"
|
|
65
58
|
|
|
66
|
-
# Use the official update command (handles download, verification, and versioned install)
|
|
67
|
-
|
|
59
|
+
# Use the official update command with timeout (handles download, verification, and versioned install)
|
|
60
|
+
timeout 60 "$NATIVE_BIN" update 2>&1 | tee -a "$LOG_FILE"
|
|
61
|
+
UPDATE_STATUS=${PIPESTATUS[0]}
|
|
62
|
+
if [ "$UPDATE_STATUS" -eq 0 ]; then
|
|
68
63
|
UPDATED_VERSION=$("$NATIVE_BIN" --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "unknown")
|
|
69
64
|
if [ "$CURRENT_VERSION" != "$UPDATED_VERSION" ]; then
|
|
70
65
|
log "Updated Claude Code: ${CURRENT_VERSION} → ${UPDATED_VERSION}"
|
|
@@ -72,5 +67,5 @@ if "$NATIVE_BIN" update 2>&1 | tee -a "$LOG_FILE"; then
|
|
|
72
67
|
log "Already up to date (${CURRENT_VERSION})"
|
|
73
68
|
fi
|
|
74
69
|
else
|
|
75
|
-
log "WARNING: 'claude update' failed
|
|
70
|
+
log "WARNING: 'claude update' failed or timed out (exit ${UPDATE_STATUS})"
|
|
76
71
|
fi
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
+
# SPDX-License-Identifier: GPL-3.0-only
|
|
3
|
+
# Copyright (c) 2026 Marcus Krueger
|
|
2
4
|
# Master setup script for CodeForge devcontainer
|
|
3
5
|
|
|
4
6
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
@@ -12,9 +14,50 @@ if [ -f "$ENV_FILE" ]; then
|
|
|
12
14
|
set +a
|
|
13
15
|
fi
|
|
14
16
|
|
|
17
|
+
# Deprecation guard: .env may still set CLAUDE_CONFIG_DIR=/workspaces/.claude
|
|
18
|
+
# (pre-v2.0 default). Since .env is gitignored, PR updates can't fix it.
|
|
19
|
+
# Override with warning so all child scripts use the correct home location.
|
|
20
|
+
if [ "$CLAUDE_CONFIG_DIR" = "/workspaces/.claude" ]; then
|
|
21
|
+
echo "[setup] WARNING: CLAUDE_CONFIG_DIR=/workspaces/.claude is deprecated (moved to home dir in v2.0)"
|
|
22
|
+
echo "[setup] Updating .devcontainer/.env automatically."
|
|
23
|
+
CLAUDE_CONFIG_DIR="$HOME/.claude"
|
|
24
|
+
# Fix the file on disk so subsequent restarts don't trigger this guard
|
|
25
|
+
if [ -f "$ENV_FILE" ]; then
|
|
26
|
+
sed -i 's|^CLAUDE_CONFIG_DIR=.*/workspaces/\.claude.*|# CLAUDE_CONFIG_DIR removed (v2.0: now uses $HOME/.claude)|' "$ENV_FILE"
|
|
27
|
+
echo "[setup] .env updated — CLAUDE_CONFIG_DIR line commented out."
|
|
28
|
+
fi
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Deprecation guard: CONFIG_SOURCE_DIR may still point to /workspaces/.claude
|
|
32
|
+
# (pre-v2.0 default was to keep config source in workspace .claude dir).
|
|
33
|
+
# Override with correct path.
|
|
34
|
+
if [ "$CONFIG_SOURCE_DIR" = "/workspaces/.claude" ]; then
|
|
35
|
+
echo "[setup] WARNING: CONFIG_SOURCE_DIR=/workspaces/.claude is deprecated (moved to .devcontainer/config in v2.0)"
|
|
36
|
+
echo "[setup] Updating .devcontainer/.env automatically."
|
|
37
|
+
CONFIG_SOURCE_DIR="$DEVCONTAINER_DIR/config"
|
|
38
|
+
if [ -f "$ENV_FILE" ]; then
|
|
39
|
+
sed -i 's|^CONFIG_SOURCE_DIR=.*/workspaces/\.claude.*|# CONFIG_SOURCE_DIR removed (v2.0: now uses .devcontainer/config)|' "$ENV_FILE"
|
|
40
|
+
echo "[setup] .env updated — CONFIG_SOURCE_DIR line commented out."
|
|
41
|
+
fi
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
# Deprecation guard: CONFIG_SOURCE_DIR may still point to .devcontainer/config
|
|
45
|
+
# (pre-v2.0 default). Redirect to .codeforge.
|
|
46
|
+
if [ "$CONFIG_SOURCE_DIR" = "$DEVCONTAINER_DIR/config" ] || [ "$CONFIG_SOURCE_DIR" = "/workspaces/.devcontainer/config" ]; then
|
|
47
|
+
echo "[setup] WARNING: CONFIG_SOURCE_DIR pointing to .devcontainer/config is deprecated (moved to .codeforge in v2.0)"
|
|
48
|
+
echo "[setup] Redirecting to .codeforge."
|
|
49
|
+
: "${CODEFORGE_DIR:=${WORKSPACE_ROOT:?}/.codeforge}"
|
|
50
|
+
unset CONFIG_SOURCE_DIR
|
|
51
|
+
if [ -f "$ENV_FILE" ]; then
|
|
52
|
+
sed -i 's|^CONFIG_SOURCE_DIR=.*\.devcontainer/config.*|# CONFIG_SOURCE_DIR removed (v2.0: now uses .codeforge)|' "$ENV_FILE"
|
|
53
|
+
echo "[setup] .env updated — CONFIG_SOURCE_DIR line commented out."
|
|
54
|
+
fi
|
|
55
|
+
fi
|
|
56
|
+
|
|
15
57
|
# Apply defaults for any unset variables
|
|
16
|
-
: "${CLAUDE_CONFIG_DIR
|
|
17
|
-
: "${
|
|
58
|
+
: "${CLAUDE_CONFIG_DIR:=$HOME/.claude}"
|
|
59
|
+
: "${CODEFORGE_DIR:=${WORKSPACE_ROOT:?}/.codeforge}"
|
|
60
|
+
: "${CONFIG_SOURCE_DIR:=$CODEFORGE_DIR}"
|
|
18
61
|
: "${SETUP_CONFIG:=true}"
|
|
19
62
|
: "${SETUP_ALIASES:=true}"
|
|
20
63
|
: "${SETUP_AUTH:=true}"
|
|
@@ -24,7 +67,13 @@ fi
|
|
|
24
67
|
: "${SETUP_TERMINAL:=true}"
|
|
25
68
|
: "${SETUP_POSTSTART:=true}"
|
|
26
69
|
|
|
27
|
-
export CLAUDE_CONFIG_DIR CONFIG_SOURCE_DIR SETUP_CONFIG SETUP_ALIASES SETUP_AUTH SETUP_PLUGINS SETUP_UPDATE_CLAUDE SETUP_PROJECTS SETUP_TERMINAL SETUP_POSTSTART
|
|
70
|
+
export CLAUDE_CONFIG_DIR CONFIG_SOURCE_DIR CODEFORGE_DIR SETUP_CONFIG SETUP_ALIASES SETUP_AUTH SETUP_PLUGINS SETUP_UPDATE_CLAUDE SETUP_PROJECTS SETUP_TERMINAL SETUP_POSTSTART
|
|
71
|
+
|
|
72
|
+
# Fix named volume ownership — Docker creates named volumes as root:root
|
|
73
|
+
# regardless of remoteUser. This is the only setup script requiring sudo.
|
|
74
|
+
if ! sudo chown "$(id -un):$(id -gn)" "$HOME/.claude" 2>/dev/null; then
|
|
75
|
+
echo "[setup] WARNING: Could not fix volume ownership on $HOME/.claude — subsequent scripts may fail"
|
|
76
|
+
fi
|
|
28
77
|
|
|
29
78
|
SETUP_START=$(date +%s)
|
|
30
79
|
SETUP_RESULTS=()
|
|
@@ -88,7 +137,8 @@ run_poststart_hooks() {
|
|
|
88
137
|
fi
|
|
89
138
|
}
|
|
90
139
|
|
|
91
|
-
run_script "$SCRIPT_DIR/setup-
|
|
140
|
+
run_script "$SCRIPT_DIR/setup-migrate-claude.sh" "true"
|
|
141
|
+
run_script "$SCRIPT_DIR/setup-migrate-codeforge.sh" "true"
|
|
92
142
|
run_script "$SCRIPT_DIR/setup-auth.sh" "$SETUP_AUTH"
|
|
93
143
|
run_script "$SCRIPT_DIR/setup-config.sh" "$SETUP_CONFIG"
|
|
94
144
|
run_script "$SCRIPT_DIR/setup-aliases.sh" "$SETUP_ALIASES"
|
|
@@ -98,7 +148,9 @@ run_script "$SCRIPT_DIR/setup-terminal.sh" "$SETUP_TERMINAL"
|
|
|
98
148
|
|
|
99
149
|
# Background the update to avoid blocking container start
|
|
100
150
|
if [ "$SETUP_UPDATE_CLAUDE" = "true" ] && [ -f "$SCRIPT_DIR/setup-update-claude.sh" ]; then
|
|
101
|
-
|
|
151
|
+
CLAUDE_UPDATE_LOG="${CLAUDE_UPDATE_LOG:-/workspaces/.tmp/claude-update.log}"
|
|
152
|
+
mkdir -p "$(dirname "$CLAUDE_UPDATE_LOG")"
|
|
153
|
+
bash "$SCRIPT_DIR/setup-update-claude.sh" >>"$CLAUDE_UPDATE_LOG" 2>&1 &
|
|
102
154
|
disown
|
|
103
155
|
SETUP_RESULTS+=("setup-update-claude:background")
|
|
104
156
|
else
|
|
@@ -110,6 +162,27 @@ if [ "$SETUP_POSTSTART" = "true" ]; then
|
|
|
110
162
|
run_poststart_hooks
|
|
111
163
|
fi
|
|
112
164
|
|
|
165
|
+
# Fix Bun PATH — external feature only adds to ~/.bashrc (misses non-interactive shells)
|
|
166
|
+
if [ -d "$HOME/.bun/bin" ]; then
|
|
167
|
+
# Symlink bun binaries into /usr/local/bin for non-login, non-interactive shells (bash -c, exec)
|
|
168
|
+
for bin in bun bunx; do
|
|
169
|
+
if [ -x "$HOME/.bun/bin/$bin" ] && [ ! -e "/usr/local/bin/$bin" ]; then
|
|
170
|
+
sudo ln -sf "$HOME/.bun/bin/$bin" "/usr/local/bin/$bin"
|
|
171
|
+
fi
|
|
172
|
+
done
|
|
173
|
+
# Profile script sets BUN_INSTALL for login/interactive shells (content-idempotent)
|
|
174
|
+
if [ ! -f /etc/profile.d/bun.sh ] || ! grep -q 'BUN_INSTALL="\$HOME/.bun"' /etc/profile.d/bun.sh; then
|
|
175
|
+
sudo tee /etc/profile.d/bun.sh > /dev/null <<'BUNEOF'
|
|
176
|
+
export BUN_INSTALL="$HOME/.bun"
|
|
177
|
+
case ":${PATH}:" in
|
|
178
|
+
*:"${BUN_INSTALL}/bin":*) ;;
|
|
179
|
+
*) export PATH="${BUN_INSTALL}/bin:${PATH}" ;;
|
|
180
|
+
esac
|
|
181
|
+
BUNEOF
|
|
182
|
+
sudo chmod 0644 /etc/profile.d/bun.sh
|
|
183
|
+
fi
|
|
184
|
+
fi
|
|
185
|
+
|
|
113
186
|
echo ""
|
|
114
187
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
115
188
|
echo " Setup Summary"
|
package/LICENSE.txt
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
CodeForge — Copyright (c) 2026 Marcus Krueger (AnExiledDev)
|
|
2
|
+
|
|
3
|
+
This software is dual-licensed:
|
|
4
|
+
|
|
5
|
+
1. GNU General Public License v3.0 (see below) — for open source use
|
|
6
|
+
2. Commercial License — available upon request for proprietary use
|
|
7
|
+
|
|
8
|
+
For commercial licensing inquiries, contact:
|
|
9
|
+
696222+AnExiledDev@users.noreply.github.com
|
|
10
|
+
|
|
11
|
+
SPDX-License-Identifier: GPL-3.0-only
|
|
12
|
+
|
|
13
|
+
────────────────────────────────────────────────────────────────────────
|
|
14
|
+
|
|
1
15
|
GNU GENERAL PUBLIC LICENSE
|
|
2
16
|
Version 3, 29 June 2007
|
|
3
17
|
|