codeforge-dev 1.5.8 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.devcontainer/.env +4 -5
- package/.devcontainer/.env.example +29 -0
- package/.devcontainer/.gitignore +8 -0
- package/.devcontainer/.secrets.example +12 -0
- package/.devcontainer/CHANGELOG.md +186 -0
- package/.devcontainer/CLAUDE.md +108 -21
- package/.devcontainer/README.md +173 -57
- package/.devcontainer/config/defaults/keybindings.json +5 -0
- package/.devcontainer/config/{main-system-prompt.md → defaults/main-system-prompt.md} +135 -2
- package/.devcontainer/config/{settings.json → defaults/settings.json} +25 -6
- package/.devcontainer/config/file-manifest.json +20 -0
- package/.devcontainer/devcontainer.json +38 -2
- package/.devcontainer/docs/configuration-reference.md +90 -0
- package/.devcontainer/docs/keybindings.md +100 -0
- package/.devcontainer/docs/optional-features.md +129 -0
- package/.devcontainer/docs/plugins.md +154 -0
- package/.devcontainer/docs/troubleshooting.md +128 -0
- package/.devcontainer/features/README.md +21 -7
- package/.devcontainer/features/agent-browser/install.sh +6 -0
- package/.devcontainer/features/ast-grep/install.sh +6 -0
- package/.devcontainer/features/biome/README.md +27 -0
- package/.devcontainer/features/biome/install.sh +6 -0
- package/.devcontainer/features/ccburn/README.md +60 -0
- package/.devcontainer/features/ccburn/devcontainer-feature.json +38 -0
- package/.devcontainer/features/ccburn/install.sh +180 -0
- package/.devcontainer/features/ccstatusline/README.md +22 -21
- package/.devcontainer/features/ccstatusline/devcontainer-feature.json +6 -1
- package/.devcontainer/features/ccstatusline/install.sh +55 -16
- package/.devcontainer/features/ccusage/install.sh +6 -0
- package/.devcontainer/features/claude-monitor/install.sh +6 -0
- package/.devcontainer/features/dprint/README.md +30 -0
- package/.devcontainer/features/dprint/devcontainer-feature.json +18 -0
- package/.devcontainer/features/dprint/install.sh +131 -0
- package/.devcontainer/features/hadolint/README.md +35 -0
- package/.devcontainer/features/hadolint/devcontainer-feature.json +13 -0
- package/.devcontainer/features/hadolint/install.sh +86 -0
- package/.devcontainer/features/lsp-servers/devcontainer-feature.json +5 -0
- package/.devcontainer/features/lsp-servers/install.sh +7 -0
- package/.devcontainer/features/mcp-qdrant/devcontainer-feature.json +6 -1
- package/.devcontainer/features/mcp-qdrant/install.sh +13 -6
- package/.devcontainer/features/mcp-reasoner/devcontainer-feature.json +6 -1
- package/.devcontainer/features/mcp-reasoner/install.sh +8 -1
- package/.devcontainer/features/notify-hook/devcontainer-feature.json +5 -0
- package/.devcontainer/features/notify-hook/install.sh +7 -0
- package/.devcontainer/features/ruff/README.md +26 -0
- package/.devcontainer/features/ruff/devcontainer-feature.json +21 -0
- package/.devcontainer/features/ruff/install.sh +74 -0
- package/.devcontainer/features/shellcheck/README.md +38 -0
- package/.devcontainer/features/shellcheck/devcontainer-feature.json +13 -0
- package/.devcontainer/features/shellcheck/install.sh +24 -0
- package/.devcontainer/features/shfmt/README.md +37 -0
- package/.devcontainer/features/shfmt/devcontainer-feature.json +13 -0
- package/.devcontainer/features/shfmt/install.sh +85 -0
- package/.devcontainer/features/splitrail/devcontainer-feature.json +5 -0
- package/.devcontainer/features/splitrail/install.sh +7 -0
- package/.devcontainer/features/tmux/install.sh +8 -0
- package/.devcontainer/features/tree-sitter/install.sh +6 -0
- package/.devcontainer/plugins/devs-marketplace/.claude-plugin/marketplace.json +3 -10
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/.claude-plugin/plugin.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/__pycache__/format-on-stop.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-formatter/scripts/format-on-stop.py +133 -13
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/.claude-plugin/plugin.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/hooks/hooks.json +4 -5
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/__pycache__/lint-file.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/auto-linter/scripts/lint-file.py +477 -78
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/.claude-plugin/plugin.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/AGENT-REDIRECTION.md +226 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/REVIEW-RUBRIC.md +440 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/architect.md +207 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/bash-exec.md +173 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/claude-guide.md +146 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/debug-logs.md +2 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/dependency-analyst.md +250 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/doc-writer.md +246 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/explorer.md +237 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/generalist.md +134 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/git-archaeologist.md +242 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/migrator.md +201 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/perf-profiler.md +265 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/refactorer.md +213 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/researcher.md +195 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/security-auditor.md +289 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/spec-writer.md +297 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/statusline-config.md +188 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/agents/test-writer.md +248 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/hooks/hooks.json +51 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/advisory-test-runner.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/collect-edited-files.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/commit-reminder.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/git-state-injector.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/guard-readonly-bash.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/redirect-builtin-agents.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/skill-suggester.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/syntax-validator.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/ticket-linker.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/todo-harvester.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/verify-no-regression.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/__pycache__/verify-tests-pass.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/advisory-test-runner.py +174 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/collect-edited-files.py +8 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/commit-reminder.py +90 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/git-state-injector.py +114 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/guard-readonly-bash.py +611 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/redirect-builtin-agents.py +83 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/skill-suggester.py +146 -2
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/syntax-validator.py +9 -4
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/ticket-linker.py +137 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/todo-harvester.py +130 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/verify-no-regression.py +221 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/scripts/verify-tests-pass.py +176 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/SKILL.md +224 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/references/error-handling.md +166 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/api-design/references/rest-conventions.md +215 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/ast-grep-patterns/SKILL.md +211 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/ast-grep-patterns/references/language-patterns.md +327 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/claude-agent-sdk/SKILL.md +599 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/claude-agent-sdk/references/sdk-typescript-reference.md +954 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/SKILL.md +134 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/references/ecosystem-commands.md +264 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/dependency-management/references/license-compliance.md +80 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/SKILL.md +153 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/references/api-doc-templates.md +221 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/documentation-patterns/references/docstring-formats.md +296 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/git-forensics/SKILL.md +276 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/git-forensics/references/advanced-commands.md +332 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/git-forensics/references/investigation-playbooks.md +319 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/SKILL.md +150 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/references/javascript-migrations.md +179 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/migration-patterns/references/python-migrations.md +141 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/performance-profiling/SKILL.md +341 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/performance-profiling/references/interpreting-results.md +235 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/performance-profiling/references/tool-commands.md +395 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/refactoring-patterns/SKILL.md +344 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/refactoring-patterns/references/safe-transformations.md +247 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/refactoring-patterns/references/smell-catalog.md +332 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/security-checklist/SKILL.md +277 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/security-checklist/references/owasp-patterns.md +269 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/security-checklist/references/secrets-patterns.md +253 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/SKILL.md +320 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/references/criteria-patterns.md +245 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/code-directive/skills/specification-writing/references/ears-templates.md +239 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/dangerous-command-blocker/scripts/__pycache__/block-dangerous.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/notify-hook/hooks/hooks.json +1 -1
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/__pycache__/guard-protected.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/protected-files-guard/scripts/guard-protected.py +40 -39
- package/.devcontainer/scripts/check-setup.sh +72 -0
- package/.devcontainer/scripts/setup-aliases.sh +51 -6
- package/.devcontainer/scripts/setup-auth.sh +74 -0
- package/.devcontainer/scripts/setup-config.sh +112 -20
- package/.devcontainer/scripts/setup-plugins.sh +38 -46
- package/.devcontainer/scripts/setup-projects.sh +175 -0
- package/.devcontainer/scripts/setup-symlink-claude.sh +36 -0
- package/.devcontainer/scripts/setup-update-claude.sh +19 -8
- package/.devcontainer/scripts/setup.sh +49 -14
- package/README.md +23 -190
- package/package.json +1 -1
- package/setup.js +245 -71
- package/.devcontainer/features/claude-code/README.md +0 -498
- package/.devcontainer/features/claude-code/config/settings.json +0 -36
- package/.devcontainer/features/claude-code/config/system-prompt.md +0 -118
- package/.devcontainer/features/claude-code/config/world-building-sp.md +0 -1432
- package/.devcontainer/features/claude-code/devcontainer-feature.json +0 -42
- package/.devcontainer/features/claude-code/install.sh +0 -466
- package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/.claude-plugin/plugin.json +0 -7
- package/.devcontainer/plugins/devs-marketplace/plugins/planning-reminder/hooks/hooks.json +0 -17
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/.claude-plugin/plugin.json +0 -6
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/config/planning-instructions.md +0 -14
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/functional-conjuring-map.md +0 -989
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/hooks/hooks.json +0 -33
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/__pycache__/post-enhance-task.cpython-314.pyc +0 -0
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhance-planning.py +0 -71
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-plan.sh +0 -68
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/enhancers/enhance-task.sh +0 -120
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-plan.py +0 -133
- package/.devcontainer/plugins/devs-marketplace/plugins/workflow-enhancer/scripts/post-enhance-task.py +0 -253
- package/.devcontainer/scripts/setup-irie-claude.sh +0 -32
|
@@ -1,28 +1,120 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# Copy
|
|
2
|
+
# Copy configuration files to workspace based on file-manifest.json
|
|
3
3
|
|
|
4
4
|
CONFIG_DIR="${CONFIG_SOURCE_DIR:?CONFIG_SOURCE_DIR not set}"
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
echo "[setup-config]
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
5
|
+
MANIFEST="$CONFIG_DIR/file-manifest.json"
|
|
6
|
+
|
|
7
|
+
log() { echo "[setup-config] $*"; }
|
|
8
|
+
warn() { echo "[setup-config] WARNING: $*"; }
|
|
9
|
+
err() { echo "[setup-config] ERROR: $*" >&2; }
|
|
10
|
+
|
|
11
|
+
# Deprecation notice if legacy OVERWRITE_CONFIG is still set
|
|
12
|
+
if [ -n "${OVERWRITE_CONFIG+x}" ]; then
|
|
13
|
+
warn "OVERWRITE_CONFIG is deprecated. Use per-file 'overwrite' in config/file-manifest.json instead."
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
# ── Legacy fallback ──────────────────────────────────────────────
|
|
17
|
+
legacy_copy() {
|
|
18
|
+
local target_dir="${CLAUDE_CONFIG_DIR:?CLAUDE_CONFIG_DIR not set}"
|
|
19
|
+
warn "file-manifest.json not found, falling back to legacy copy"
|
|
20
|
+
mkdir -p "$target_dir"
|
|
21
|
+
for file in defaults/settings.json defaults/keybindings.json defaults/main-system-prompt.md; do
|
|
22
|
+
if [ -f "$CONFIG_DIR/$file" ]; then
|
|
23
|
+
local basename="${file##*/}"
|
|
24
|
+
cp "$CONFIG_DIR/$file" "$target_dir/$basename"
|
|
25
|
+
chown "$(id -un):$(id -gn)" "$target_dir/$basename" 2>/dev/null || true
|
|
26
|
+
log "Copied $basename (legacy)"
|
|
21
27
|
fi
|
|
28
|
+
done
|
|
29
|
+
log "Configuration complete (legacy)"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if [ ! -f "$MANIFEST" ]; then
|
|
33
|
+
legacy_copy
|
|
34
|
+
exit 0
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# ── Validate manifest JSON ──────────────────────────────────────
|
|
38
|
+
if ! jq empty "$MANIFEST" 2>/dev/null; then
|
|
39
|
+
err "Invalid JSON in file-manifest.json"
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# ── Variable expansion ───────────────────────────────────────────
|
|
44
|
+
expand_vars() {
|
|
45
|
+
local val="$1"
|
|
46
|
+
val="${val//\$\{CLAUDE_CONFIG_DIR\}/$CLAUDE_CONFIG_DIR}"
|
|
47
|
+
val="${val//\$\{WORKSPACE_ROOT\}/$WORKSPACE_ROOT}"
|
|
48
|
+
# Warn on any remaining unresolved ${...} tokens
|
|
49
|
+
if [[ "$val" =~ \$\{[^}]+\} ]]; then
|
|
50
|
+
warn "Unresolved variable in: $val"
|
|
22
51
|
fi
|
|
52
|
+
echo "$val"
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
# ── Change detection ─────────────────────────────────────────────
|
|
56
|
+
should_copy() {
|
|
57
|
+
local src="$1" dest="$2"
|
|
58
|
+
[ ! -f "$dest" ] && return 0
|
|
59
|
+
local src_hash dest_hash
|
|
60
|
+
src_hash=$(sha256sum "$src" | cut -d' ' -f1)
|
|
61
|
+
dest_hash=$(sha256sum "$dest" | cut -d' ' -f1)
|
|
62
|
+
[ "$src_hash" != "$dest_hash" ]
|
|
23
63
|
}
|
|
24
64
|
|
|
25
|
-
|
|
26
|
-
|
|
65
|
+
# ── Process manifest ─────────────────────────────────────────────
|
|
66
|
+
log "Copying configuration files..."
|
|
67
|
+
|
|
68
|
+
# Single jq invocation to extract all fields (reduces N×5 subprocess calls to 1)
|
|
69
|
+
jq -r '.[] | [.src, .dest, (.destFilename // ""), (.enabled // true | tostring), (.overwrite // "if-changed")] | @tsv' "$MANIFEST" |
|
|
70
|
+
while IFS=$'\t' read -r src dest dest_filename enabled overwrite; do
|
|
71
|
+
# Skip disabled entries
|
|
72
|
+
if [ "$enabled" = "false" ]; then
|
|
73
|
+
log "Skipping $src (disabled)"
|
|
74
|
+
continue
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# Resolve paths
|
|
78
|
+
src_path="$CONFIG_DIR/$src"
|
|
79
|
+
dest_dir=$(expand_vars "$dest")
|
|
80
|
+
filename="${dest_filename:-${src##*/}}"
|
|
81
|
+
dest_path="$dest_dir/$filename"
|
|
82
|
+
|
|
83
|
+
# Validate source exists
|
|
84
|
+
if [ ! -f "$src_path" ]; then
|
|
85
|
+
warn "$src not found in config dir, skipping"
|
|
86
|
+
continue
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
# Ensure destination directory exists
|
|
90
|
+
mkdir -p "$dest_dir"
|
|
91
|
+
|
|
92
|
+
# Apply overwrite strategy
|
|
93
|
+
case "$overwrite" in
|
|
94
|
+
always)
|
|
95
|
+
cp "$src_path" "$dest_path"
|
|
96
|
+
log "Copied $src → $dest_path (always)"
|
|
97
|
+
;;
|
|
98
|
+
never)
|
|
99
|
+
if [ ! -f "$dest_path" ]; then
|
|
100
|
+
cp "$src_path" "$dest_path"
|
|
101
|
+
log "Copied $src → $dest_path (new)"
|
|
102
|
+
else
|
|
103
|
+
log "Skipping $src (exists, overwrite=never)"
|
|
104
|
+
fi
|
|
105
|
+
;;
|
|
106
|
+
if-changed|*)
|
|
107
|
+
if should_copy "$src_path" "$dest_path"; then
|
|
108
|
+
cp "$src_path" "$dest_path"
|
|
109
|
+
log "Copied $src → $dest_path (changed)"
|
|
110
|
+
else
|
|
111
|
+
log "Skipping $src (unchanged)"
|
|
112
|
+
fi
|
|
113
|
+
;;
|
|
114
|
+
esac
|
|
115
|
+
|
|
116
|
+
# Fix ownership
|
|
117
|
+
chown "$(id -un):$(id -gn)" "$dest_path" 2>/dev/null || true
|
|
118
|
+
done
|
|
27
119
|
|
|
28
|
-
|
|
120
|
+
log "Configuration complete"
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
|
-
# Install plugins: official Anthropic + local devs-marketplace
|
|
2
|
+
# Install plugins: official Anthropic + local devs-marketplace registration
|
|
3
|
+
#
|
|
4
|
+
# Individual marketplace plugins are enabled via enabledPlugins in settings.json.
|
|
5
|
+
# This script only handles:
|
|
6
|
+
# 1. Official Anthropic plugin installs (not managed by enabledPlugins)
|
|
7
|
+
# 2. Local marketplace registration (so Claude Code can discover devs-marketplace)
|
|
8
|
+
|
|
9
|
+
# Source .env for PLUGIN_BLACKLIST if not already set (e.g., standalone invocation)
|
|
10
|
+
if [ -z "${PLUGIN_BLACKLIST+x}" ]; then
|
|
11
|
+
SCRIPT_DIR_INIT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
12
|
+
ENV_FILE="${SCRIPT_DIR_INIT}/../.env"
|
|
13
|
+
if [ -f "$ENV_FILE" ]; then
|
|
14
|
+
set -a
|
|
15
|
+
source "$ENV_FILE"
|
|
16
|
+
set +a
|
|
17
|
+
fi
|
|
18
|
+
fi
|
|
3
19
|
|
|
4
20
|
echo "[setup-plugins] Installing plugins..."
|
|
5
21
|
|
|
@@ -18,33 +34,13 @@ for plugin in "${OFFICIAL_PLUGINS[@]}"; do
|
|
|
18
34
|
fi
|
|
19
35
|
done
|
|
20
36
|
|
|
21
|
-
# --- Local Marketplace
|
|
37
|
+
# --- Local Marketplace Registration ---
|
|
22
38
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
23
39
|
MARKETPLACE_PATH="${SCRIPT_DIR}/../plugins/devs-marketplace"
|
|
24
40
|
|
|
25
|
-
# Load PLUGIN_BLACKLIST from .env if not already set in environment
|
|
26
|
-
ENV_FILE="${SCRIPT_DIR}/../.env"
|
|
27
|
-
if [ -z "${PLUGIN_BLACKLIST+x}" ] && [ -f "$ENV_FILE" ]; then
|
|
28
|
-
PLUGIN_BLACKLIST=$(grep -E '^PLUGIN_BLACKLIST=' "$ENV_FILE" | cut -d'=' -f2- | tr -d '"')
|
|
29
|
-
fi
|
|
30
|
-
|
|
31
|
-
# Parse blacklist into array
|
|
32
|
-
IFS=',' read -ra BLACKLIST <<< "${PLUGIN_BLACKLIST:-}"
|
|
33
|
-
|
|
34
|
-
# Helper function to check if plugin is blacklisted
|
|
35
|
-
is_blacklisted() {
|
|
36
|
-
local plugin_name="$1"
|
|
37
|
-
for blocked in "${BLACKLIST[@]}"; do
|
|
38
|
-
# Trim whitespace and compare
|
|
39
|
-
blocked="${blocked// /}"
|
|
40
|
-
if [ "$plugin_name" = "$blocked" ]; then
|
|
41
|
-
return 0
|
|
42
|
-
fi
|
|
43
|
-
done
|
|
44
|
-
return 1
|
|
45
|
-
}
|
|
46
|
-
|
|
47
41
|
# Add local marketplace (if not already added)
|
|
42
|
+
# This is still needed so Claude Code can discover devs-marketplace plugins
|
|
43
|
+
# listed in enabledPlugins in settings.json
|
|
48
44
|
if ! claude plugin marketplace list 2>/dev/null | grep -q "devs-marketplace"; then
|
|
49
45
|
echo "[setup-plugins] Adding devs-marketplace..."
|
|
50
46
|
claude plugin marketplace add "$MARKETPLACE_PATH" 2>/dev/null || {
|
|
@@ -52,29 +48,25 @@ if ! claude plugin marketplace list 2>/dev/null | grep -q "devs-marketplace"; th
|
|
|
52
48
|
}
|
|
53
49
|
fi
|
|
54
50
|
|
|
55
|
-
# Install
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
# --- Install/Update devs-marketplace plugins (syncs cache from source) ---
|
|
52
|
+
# enabledPlugins in settings.json controls enabled/disabled state, but plugins
|
|
53
|
+
# must be explicitly installed to populate the cache. This loop ensures the
|
|
54
|
+
# cache stays in sync with the source directory on every container start.
|
|
55
|
+
if [ -d "$MARKETPLACE_PATH/plugins" ]; then
|
|
56
|
+
for plugin_dir in "$MARKETPLACE_PATH"/plugins/*/; do
|
|
57
|
+
plugin_name=$(basename "$plugin_dir")
|
|
59
58
|
|
|
60
|
-
|
|
61
|
-
echo "
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
echo "[setup-plugins]
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
else
|
|
72
|
-
echo "[setup-plugins] WARNING: Failed to install $plugin (may already be installed)"
|
|
73
|
-
fi
|
|
74
|
-
done
|
|
75
|
-
fi
|
|
76
|
-
else
|
|
77
|
-
echo "[setup-plugins] WARNING: marketplace.json not found at $MARKETPLACE_JSON"
|
|
59
|
+
# Skip blacklisted plugins
|
|
60
|
+
if echo ",$PLUGIN_BLACKLIST," | grep -q ",$plugin_name,"; then
|
|
61
|
+
echo "[setup-plugins] Skipping $plugin_name (blacklisted)"
|
|
62
|
+
continue
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
echo "[setup-plugins] Installing $plugin_name@devs-marketplace..."
|
|
66
|
+
claude plugin install "$plugin_name@devs-marketplace" 2>/dev/null || {
|
|
67
|
+
echo "[setup-plugins] Warning: Failed to install $plugin_name"
|
|
68
|
+
}
|
|
69
|
+
done
|
|
78
70
|
fi
|
|
79
71
|
|
|
80
72
|
echo "[setup-plugins] Plugin installation complete"
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Auto-detect projects under /workspaces/ and register them in Project Manager's projects.json.
|
|
3
|
+
# Runs an initial scan synchronously, then starts an inotifywait background watcher
|
|
4
|
+
# that updates the project list instantly when directories are created or removed.
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
WORKSPACE_ROOT="${WORKSPACE_ROOT:-/workspaces}"
|
|
9
|
+
PROJECTS_DIR="${WORKSPACE_ROOT}/.config/project-manager"
|
|
10
|
+
PROJECTS_FILE="${PROJECTS_DIR}/projects.json"
|
|
11
|
+
PID_FILE="/tmp/project-watcher.pid"
|
|
12
|
+
LOG_PREFIX="[setup-projects]"
|
|
13
|
+
|
|
14
|
+
# Directories to exclude from project detection (hidden/config dirs)
|
|
15
|
+
EXCLUDED_DIRS=".claude .gh .tmp .devcontainer .config node_modules .git"
|
|
16
|
+
|
|
17
|
+
# --- Helpers ---
|
|
18
|
+
|
|
19
|
+
is_excluded() {
|
|
20
|
+
local name="$1"
|
|
21
|
+
# Skip hidden directories (start with .)
|
|
22
|
+
[[ "$name" == .* ]] && return 0
|
|
23
|
+
# Skip explicitly excluded names
|
|
24
|
+
for excluded in $EXCLUDED_DIRS; do
|
|
25
|
+
[[ "$name" == "$excluded" ]] && return 0
|
|
26
|
+
done
|
|
27
|
+
return 1
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
detect_tags() {
|
|
31
|
+
local dir="$1"
|
|
32
|
+
local tags=()
|
|
33
|
+
|
|
34
|
+
[ -d "$dir/.git" ] && tags+=("git")
|
|
35
|
+
[ -f "$dir/package.json" ] && tags+=("node")
|
|
36
|
+
[ -f "$dir/pyproject.toml" ] && tags+=("python")
|
|
37
|
+
[ -f "$dir/Cargo.toml" ] && tags+=("rust")
|
|
38
|
+
[ -f "$dir/go.mod" ] && tags+=("go")
|
|
39
|
+
[ -f "$dir/deno.json" ] && tags+=("deno")
|
|
40
|
+
[ -f "$dir/Makefile" ] && tags+=("make")
|
|
41
|
+
[ -f "$dir/CLAUDE.md" ] && tags+=("claude")
|
|
42
|
+
|
|
43
|
+
# Always add "auto" tag to mark as script-managed
|
|
44
|
+
tags+=("auto")
|
|
45
|
+
|
|
46
|
+
# If no markers found (only "auto"), add "folder" tag
|
|
47
|
+
if [ ${#tags[@]} -eq 1 ]; then
|
|
48
|
+
tags=("folder" "${tags[@]}")
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
# Output as JSON array
|
|
52
|
+
printf '%s\n' "${tags[@]}" | jq -R . | jq -s .
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
scan_and_update() {
|
|
56
|
+
# Build the new auto-detected projects array
|
|
57
|
+
local new_projects="[]"
|
|
58
|
+
|
|
59
|
+
for dir in "$WORKSPACE_ROOT"/*/; do
|
|
60
|
+
[ -d "$dir" ] || continue
|
|
61
|
+
local name
|
|
62
|
+
name=$(basename "$dir")
|
|
63
|
+
|
|
64
|
+
is_excluded "$name" && continue
|
|
65
|
+
|
|
66
|
+
local tags
|
|
67
|
+
tags=$(detect_tags "$dir")
|
|
68
|
+
|
|
69
|
+
new_projects=$(echo "$new_projects" | jq \
|
|
70
|
+
--arg name "$name" \
|
|
71
|
+
--arg path "$dir" \
|
|
72
|
+
--argjson tags "$tags" \
|
|
73
|
+
'. += [{"name": $name, "rootPath": ($path | rtrimstr("/")), "tags": $tags, "enabled": true}]')
|
|
74
|
+
done
|
|
75
|
+
|
|
76
|
+
# Read existing projects.json (or empty array if missing/invalid)
|
|
77
|
+
local existing="[]"
|
|
78
|
+
if [ -f "$PROJECTS_FILE" ] && jq empty "$PROJECTS_FILE" 2>/dev/null; then
|
|
79
|
+
existing=$(cat "$PROJECTS_FILE")
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
# Separate user entries (no "auto" tag) from auto entries
|
|
83
|
+
local user_entries
|
|
84
|
+
user_entries=$(echo "$existing" | jq '[.[] | select(.tags | index("auto") | not)]')
|
|
85
|
+
|
|
86
|
+
# Merge: user entries + new auto-detected entries
|
|
87
|
+
local merged
|
|
88
|
+
merged=$(jq -n --argjson user "$user_entries" --argjson auto "$new_projects" '$user + $auto')
|
|
89
|
+
|
|
90
|
+
# Only write if content changed (avoid unnecessary file writes that trigger Project Manager reloads)
|
|
91
|
+
local current_hash new_hash
|
|
92
|
+
current_hash=""
|
|
93
|
+
[ -f "$PROJECTS_FILE" ] && current_hash=$(md5sum "$PROJECTS_FILE" 2>/dev/null | cut -d' ' -f1)
|
|
94
|
+
|
|
95
|
+
local tmp_file
|
|
96
|
+
tmp_file=$(mktemp)
|
|
97
|
+
echo "$merged" | jq '.' > "$tmp_file"
|
|
98
|
+
new_hash=$(md5sum "$tmp_file" | cut -d' ' -f1)
|
|
99
|
+
|
|
100
|
+
if [ "$current_hash" != "$new_hash" ]; then
|
|
101
|
+
mv "$tmp_file" "$PROJECTS_FILE"
|
|
102
|
+
chmod 644 "$PROJECTS_FILE"
|
|
103
|
+
local count
|
|
104
|
+
count=$(echo "$merged" | jq 'length')
|
|
105
|
+
echo "$LOG_PREFIX Updated projects.json ($count projects)"
|
|
106
|
+
else
|
|
107
|
+
rm -f "$tmp_file"
|
|
108
|
+
fi
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
start_watcher() {
|
|
112
|
+
# Guard: don't start if already running
|
|
113
|
+
if [ -f "$PID_FILE" ]; then
|
|
114
|
+
local old_pid
|
|
115
|
+
old_pid=$(cat "$PID_FILE" 2>/dev/null)
|
|
116
|
+
if [ -n "$old_pid" ] && kill -0 "$old_pid" 2>/dev/null; then
|
|
117
|
+
echo "$LOG_PREFIX Watcher already running (PID $old_pid), skipping"
|
|
118
|
+
return 0
|
|
119
|
+
fi
|
|
120
|
+
# Stale PID file — clean up
|
|
121
|
+
rm -f "$PID_FILE"
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
# Check if inotifywait is available
|
|
125
|
+
if ! command -v inotifywait &>/dev/null; then
|
|
126
|
+
echo "$LOG_PREFIX Installing inotify-tools..."
|
|
127
|
+
if command -v sudo &>/dev/null; then
|
|
128
|
+
sudo apt-get update -qq && sudo apt-get install -y -qq inotify-tools >/dev/null 2>&1
|
|
129
|
+
else
|
|
130
|
+
apt-get update -qq && apt-get install -y -qq inotify-tools >/dev/null 2>&1
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
if ! command -v inotifywait &>/dev/null; then
|
|
134
|
+
echo "$LOG_PREFIX WARNING: Could not install inotify-tools, watcher disabled"
|
|
135
|
+
return 1
|
|
136
|
+
fi
|
|
137
|
+
echo "$LOG_PREFIX inotify-tools installed"
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
# Fork background watcher
|
|
141
|
+
(
|
|
142
|
+
# Watch for directory create/delete/move events in /workspaces/
|
|
143
|
+
# --quiet suppresses header, --monitor keeps watching indefinitely
|
|
144
|
+
inotifywait -m -q -e create,delete,moved_to,moved_from \
|
|
145
|
+
--format '%f %e' "$WORKSPACE_ROOT" 2>/dev/null |
|
|
146
|
+
while read -r name event; do
|
|
147
|
+
# Small delay to let filesystem settle (e.g., move operations)
|
|
148
|
+
sleep 1
|
|
149
|
+
scan_and_update
|
|
150
|
+
done
|
|
151
|
+
|
|
152
|
+
# Cleanup on exit
|
|
153
|
+
rm -f "$PID_FILE"
|
|
154
|
+
) &
|
|
155
|
+
local watcher_pid=$!
|
|
156
|
+
echo "$watcher_pid" > "$PID_FILE"
|
|
157
|
+
disown
|
|
158
|
+
|
|
159
|
+
echo "$LOG_PREFIX Background watcher started (PID $watcher_pid)"
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
# --- Main ---
|
|
163
|
+
|
|
164
|
+
echo "$LOG_PREFIX Configuring Project Manager auto-detection..."
|
|
165
|
+
|
|
166
|
+
# Ensure projects directory exists
|
|
167
|
+
mkdir -p "$PROJECTS_DIR"
|
|
168
|
+
|
|
169
|
+
# Initial scan (synchronous — runs in <1 second)
|
|
170
|
+
scan_and_update
|
|
171
|
+
|
|
172
|
+
# Start background watcher
|
|
173
|
+
start_watcher
|
|
174
|
+
|
|
175
|
+
echo "$LOG_PREFIX Done"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Symlink $HOME/.claude → $CLAUDE_CONFIG_DIR so third-party tools
|
|
3
|
+
# (ccburn, ccusage, etc.) that hardcode ~/.claude can find auth and config.
|
|
4
|
+
|
|
5
|
+
CLAUDE_DIR="${CLAUDE_CONFIG_DIR:=/workspaces/.claude}"
|
|
6
|
+
HOME_CLAUDE="$HOME/.claude"
|
|
7
|
+
|
|
8
|
+
echo "[setup-symlink] Ensuring $HOME_CLAUDE → $CLAUDE_DIR ..."
|
|
9
|
+
|
|
10
|
+
# Already a correct symlink — nothing to do
|
|
11
|
+
if [ -L "$HOME_CLAUDE" ]; then
|
|
12
|
+
CURRENT_TARGET="$(readlink "$HOME_CLAUDE")"
|
|
13
|
+
if [ "$CURRENT_TARGET" = "$CLAUDE_DIR" ]; then
|
|
14
|
+
echo "[setup-symlink] Symlink already correct, skipping"
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
17
|
+
# Points somewhere else — remove stale symlink
|
|
18
|
+
echo "[setup-symlink] Removing stale symlink ($CURRENT_TARGET)"
|
|
19
|
+
rm "$HOME_CLAUDE"
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Real directory exists — merge contents into target, then remove
|
|
23
|
+
if [ -d "$HOME_CLAUDE" ]; then
|
|
24
|
+
echo "[setup-symlink] Moving existing $HOME_CLAUDE contents into $CLAUDE_DIR"
|
|
25
|
+
mkdir -p "$CLAUDE_DIR"
|
|
26
|
+
# Copy contents preserving attributes; skip files that already exist in target
|
|
27
|
+
cp -rn "$HOME_CLAUDE/." "$CLAUDE_DIR/" 2>/dev/null || true
|
|
28
|
+
rm -rf "$HOME_CLAUDE"
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Ensure target exists
|
|
32
|
+
mkdir -p "$CLAUDE_DIR"
|
|
33
|
+
|
|
34
|
+
# Create symlink
|
|
35
|
+
ln -s "$CLAUDE_DIR" "$HOME_CLAUDE"
|
|
36
|
+
echo "[setup-symlink] Created symlink: $HOME_CLAUDE → $CLAUDE_DIR"
|
|
@@ -5,10 +5,21 @@
|
|
|
5
5
|
|
|
6
6
|
echo "[update-claude] Checking for Claude Code updates..."
|
|
7
7
|
|
|
8
|
+
# === TMPDIR ===
|
|
9
|
+
_TMPDIR="${TMPDIR:-/tmp}"
|
|
10
|
+
|
|
11
|
+
# === LOCK FILE (prevent concurrent updates) ===
|
|
12
|
+
LOCK_FILE="${_TMPDIR}/claude-update.lock"
|
|
13
|
+
if ! mkdir "$LOCK_FILE" 2>/dev/null; then
|
|
14
|
+
echo "[update-claude] Another update is already running, skipping"
|
|
15
|
+
exit 0
|
|
16
|
+
fi
|
|
17
|
+
|
|
8
18
|
# === CLEANUP TRAP ===
|
|
9
19
|
cleanup() {
|
|
10
|
-
rm -f /
|
|
11
|
-
rm -f /
|
|
20
|
+
rm -f "${_TMPDIR}/claude-update" 2>/dev/null || true
|
|
21
|
+
rm -f "${_TMPDIR}/claude-update-manifest.json" 2>/dev/null || true
|
|
22
|
+
rm -rf "$LOCK_FILE" 2>/dev/null || true
|
|
12
23
|
}
|
|
13
24
|
trap cleanup EXIT
|
|
14
25
|
|
|
@@ -81,13 +92,13 @@ echo "[update-claude] Platform: ${PLATFORM}"
|
|
|
81
92
|
# === DOWNLOAD MANIFEST ===
|
|
82
93
|
MANIFEST_URL="${BASE_URL}/${LATEST_VERSION}/manifest.json"
|
|
83
94
|
|
|
84
|
-
if ! curl -fsSL "${MANIFEST_URL}" -o /
|
|
95
|
+
if ! curl -fsSL "${MANIFEST_URL}" -o ${_TMPDIR}/claude-update-manifest.json 2>/dev/null; then
|
|
85
96
|
echo "[update-claude] WARNING: Failed to download manifest, skipping"
|
|
86
97
|
exit 0
|
|
87
98
|
fi
|
|
88
99
|
|
|
89
100
|
# === EXTRACT AND VERIFY CHECKSUM ===
|
|
90
|
-
EXPECTED_CHECKSUM=$(jq -r ".platforms.\"${PLATFORM}\".checksum" /
|
|
101
|
+
EXPECTED_CHECKSUM=$(jq -r ".platforms.\"${PLATFORM}\".checksum" ${_TMPDIR}/claude-update-manifest.json)
|
|
91
102
|
if [ -z "${EXPECTED_CHECKSUM}" ] || [ "${EXPECTED_CHECKSUM}" = "null" ]; then
|
|
92
103
|
echo "[update-claude] WARNING: Platform ${PLATFORM} not found in manifest, skipping"
|
|
93
104
|
exit 0
|
|
@@ -96,13 +107,13 @@ fi
|
|
|
96
107
|
# === DOWNLOAD BINARY ===
|
|
97
108
|
BINARY_URL="${BASE_URL}/${LATEST_VERSION}/${PLATFORM}/claude"
|
|
98
109
|
|
|
99
|
-
if ! curl -fsSL "${BINARY_URL}" -o /
|
|
110
|
+
if ! curl -fsSL "${BINARY_URL}" -o ${_TMPDIR}/claude-update 2>/dev/null; then
|
|
100
111
|
echo "[update-claude] WARNING: Failed to download binary, skipping"
|
|
101
112
|
exit 0
|
|
102
113
|
fi
|
|
103
114
|
|
|
104
115
|
# === VERIFY CHECKSUM ===
|
|
105
|
-
ACTUAL_CHECKSUM=$(sha256sum /
|
|
116
|
+
ACTUAL_CHECKSUM=$(sha256sum ${_TMPDIR}/claude-update | cut -d' ' -f1)
|
|
106
117
|
|
|
107
118
|
if [ "${ACTUAL_CHECKSUM}" != "${EXPECTED_CHECKSUM}" ]; then
|
|
108
119
|
echo "[update-claude] WARNING: Checksum verification failed, skipping"
|
|
@@ -112,8 +123,8 @@ if [ "${ACTUAL_CHECKSUM}" != "${EXPECTED_CHECKSUM}" ]; then
|
|
|
112
123
|
fi
|
|
113
124
|
|
|
114
125
|
# === INSTALL (atomic replace) ===
|
|
115
|
-
chmod +x /
|
|
116
|
-
if ! sudo mv /
|
|
126
|
+
chmod +x ${_TMPDIR}/claude-update
|
|
127
|
+
if ! sudo mv ${_TMPDIR}/claude-update /usr/local/bin/claude; then
|
|
117
128
|
echo "[update-claude] WARNING: Failed to install update (sudo mv failed), skipping"
|
|
118
129
|
exit 0
|
|
119
130
|
fi
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# Master setup script for CodeForge devcontainer
|
|
3
3
|
|
|
4
|
-
set -e
|
|
5
|
-
|
|
6
4
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
7
5
|
DEVCONTAINER_DIR="$(dirname "$SCRIPT_DIR")"
|
|
8
6
|
ENV_FILE="$DEVCONTAINER_DIR/.env"
|
|
@@ -19,12 +17,15 @@ fi
|
|
|
19
17
|
: "${CONFIG_SOURCE_DIR:=$DEVCONTAINER_DIR/config}"
|
|
20
18
|
: "${SETUP_CONFIG:=true}"
|
|
21
19
|
: "${SETUP_ALIASES:=true}"
|
|
22
|
-
: "${
|
|
20
|
+
: "${SETUP_AUTH:=true}"
|
|
23
21
|
: "${SETUP_PLUGINS:=true}"
|
|
24
22
|
: "${SETUP_UPDATE_CLAUDE:=true}"
|
|
23
|
+
: "${SETUP_PROJECTS:=true}"
|
|
25
24
|
|
|
26
|
-
export CLAUDE_CONFIG_DIR CONFIG_SOURCE_DIR SETUP_CONFIG SETUP_ALIASES
|
|
25
|
+
export CLAUDE_CONFIG_DIR CONFIG_SOURCE_DIR SETUP_CONFIG SETUP_ALIASES SETUP_AUTH SETUP_PLUGINS SETUP_UPDATE_CLAUDE SETUP_PROJECTS
|
|
27
26
|
|
|
27
|
+
SETUP_START=$(date +%s)
|
|
28
|
+
SETUP_RESULTS=()
|
|
28
29
|
|
|
29
30
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
30
31
|
echo " CodeForge Setup"
|
|
@@ -34,37 +35,71 @@ echo ""
|
|
|
34
35
|
run_script() {
|
|
35
36
|
local script="$1"
|
|
36
37
|
local enabled="$2"
|
|
37
|
-
local name
|
|
38
|
+
local name
|
|
39
|
+
name="$(basename "$script" .sh)"
|
|
38
40
|
|
|
39
41
|
if [ "$enabled" = "true" ]; then
|
|
40
42
|
if [ -f "$script" ]; then
|
|
41
|
-
|
|
42
|
-
bash "$script"
|
|
43
|
-
|
|
43
|
+
printf " %-30s" "$name..."
|
|
44
|
+
if bash "$script" 2>&1; then
|
|
45
|
+
echo "done"
|
|
46
|
+
SETUP_RESULTS+=("$name:ok")
|
|
47
|
+
else
|
|
48
|
+
echo "FAILED (exit $?)"
|
|
49
|
+
SETUP_RESULTS+=("$name:failed")
|
|
50
|
+
fi
|
|
44
51
|
else
|
|
45
|
-
echo "
|
|
52
|
+
echo " $name... not found, skipping"
|
|
53
|
+
SETUP_RESULTS+=("$name:missing")
|
|
46
54
|
fi
|
|
47
55
|
else
|
|
48
|
-
echo "
|
|
56
|
+
echo " $name... skipped (disabled)"
|
|
57
|
+
SETUP_RESULTS+=("$name:disabled")
|
|
49
58
|
fi
|
|
50
59
|
}
|
|
51
60
|
|
|
61
|
+
run_script "$SCRIPT_DIR/setup-symlink-claude.sh" "true"
|
|
62
|
+
run_script "$SCRIPT_DIR/setup-auth.sh" "$SETUP_AUTH"
|
|
52
63
|
run_script "$SCRIPT_DIR/setup-config.sh" "$SETUP_CONFIG"
|
|
53
64
|
run_script "$SCRIPT_DIR/setup-aliases.sh" "$SETUP_ALIASES"
|
|
54
65
|
run_script "$SCRIPT_DIR/setup-plugins.sh" "$SETUP_PLUGINS"
|
|
55
|
-
run_script "$SCRIPT_DIR/setup-
|
|
66
|
+
run_script "$SCRIPT_DIR/setup-projects.sh" "$SETUP_PROJECTS"
|
|
56
67
|
|
|
57
68
|
# Non-blocking: check for Claude Code updates in background
|
|
58
69
|
if [ "$SETUP_UPDATE_CLAUDE" = "true" ]; then
|
|
59
70
|
if [ -f "$SCRIPT_DIR/setup-update-claude.sh" ]; then
|
|
60
|
-
echo "
|
|
71
|
+
echo " Claude Code update checking in background..."
|
|
72
|
+
echo " (If 'claude' fails, wait a moment and retry)"
|
|
61
73
|
bash "$SCRIPT_DIR/setup-update-claude.sh" &
|
|
62
74
|
disown
|
|
75
|
+
SETUP_RESULTS+=("setup-update-claude:ok")
|
|
76
|
+
else
|
|
77
|
+
SETUP_RESULTS+=("setup-update-claude:missing")
|
|
63
78
|
fi
|
|
64
79
|
else
|
|
65
|
-
echo "
|
|
80
|
+
echo " setup-update-claude... skipped (disabled)"
|
|
81
|
+
SETUP_RESULTS+=("setup-update-claude:disabled")
|
|
66
82
|
fi
|
|
67
83
|
|
|
84
|
+
echo ""
|
|
68
85
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
69
|
-
echo " Setup
|
|
86
|
+
echo " Setup Summary"
|
|
87
|
+
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
88
|
+
FAILURES=0
|
|
89
|
+
for result in "${SETUP_RESULTS[@]}"; do
|
|
90
|
+
name="${result%%:*}"
|
|
91
|
+
status="${result##*:}"
|
|
92
|
+
case "$status" in
|
|
93
|
+
ok) printf " ✓ %s\n" "$name" ;;
|
|
94
|
+
failed) printf " ✗ %s (FAILED)\n" "$name"; FAILURES=$((FAILURES + 1)) ;;
|
|
95
|
+
disabled) printf " - %s (disabled)\n" "$name" ;;
|
|
96
|
+
missing) printf " ? %s (not found)\n" "$name" ;;
|
|
97
|
+
esac
|
|
98
|
+
done
|
|
99
|
+
ELAPSED=$(( $(date +%s) - SETUP_START ))
|
|
100
|
+
echo ""
|
|
101
|
+
if [ $FAILURES -gt 0 ]; then
|
|
102
|
+
echo " $FAILURES step(s) failed. Check output above for details."
|
|
103
|
+
fi
|
|
104
|
+
echo " Completed in ${ELAPSED}s"
|
|
70
105
|
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|