1515 echo " WARNING: Failed to download Claude Code installer, skipping"
1616fi
1717
18- echo " Installing OpenCode..."
19- if curl -fsSL -o " $TMPDIR /opencode-install.sh" https://opencode.ai/install; then
20- bash " $TMPDIR /opencode-install.sh"
21- else
22- echo " WARNING: Failed to download OpenCode installer, skipping"
23- fi
18+ # ---------------------------------------------------------------------------
19+ # Sync host's global Claude Code configuration (if available)
20+ # ---------------------------------------------------------------------------
21+ sync_host_claude_config () {
22+ local HOST_CONFIG=" /host-claude-config"
23+ local USER_CONFIG=" $HOME /.claude"
24+
25+ if [ ! -d " $HOST_CONFIG " ] || [ -z " $( ls -A " $HOST_CONFIG " 2> /dev/null) " ]; then
26+ echo " No host Claude config found, skipping sync"
27+ return 0
28+ fi
29+
30+ echo " Syncing host Claude Code configuration..."
31+ mkdir -p " $USER_CONFIG "
32+
33+ # Copy portable single files
34+ for file in CLAUDE.md keybindings.json; do
35+ if [ -f " $HOST_CONFIG /$file " ]; then
36+ echo " Copying $file "
37+ cp " $HOST_CONFIG /$file " " $USER_CONFIG /$file "
38+ fi
39+ done
40+
41+ # Copy portable directories
42+ for dir in agents commands skills; do
43+ if [ -d " $HOST_CONFIG /$dir " ] && [ -n " $( ls -A " $HOST_CONFIG /$dir " 2> /dev/null) " ]; then
44+ echo " Copying $dir /"
45+ cp -r " $HOST_CONFIG /$dir " " $USER_CONFIG /"
46+ fi
47+ done
48+
49+ # Copy plugins (selective — skip marketplaces which are ~300MB of git repos)
50+ if [ -d " $HOST_CONFIG /plugins" ]; then
51+ echo " Syncing plugins..."
52+ mkdir -p " $USER_CONFIG /plugins"
53+
54+ # Copy small metadata files
55+ for file in config.json blocklist.json; do
56+ if [ -f " $HOST_CONFIG /plugins/$file " ]; then
57+ cp " $HOST_CONFIG /plugins/$file " " $USER_CONFIG /plugins/$file "
58+ fi
59+ done
60+
61+ # Copy and rewrite installed_plugins.json (fix host-specific paths)
62+ if [ -f " $HOST_CONFIG /plugins/installed_plugins.json" ]; then
63+ node -e "
64+ const fs = require('fs');
65+ const data = JSON.parse(fs.readFileSync('$HOST_CONFIG /plugins/installed_plugins.json', 'utf8'));
66+ if (data.plugins) {
67+ for (const entries of Object.values(data.plugins)) {
68+ for (const entry of entries) {
69+ if (entry.installPath) {
70+ entry.installPath = entry.installPath.replace(/^\/home\/[^/]+\/.claude/, '$USER_CONFIG ');
71+ }
72+ }
73+ }
74+ }
75+ fs.writeFileSync('$USER_CONFIG /plugins/installed_plugins.json', JSON.stringify(data, null, 2));
76+ "
77+ fi
78+
79+ # Copy and rewrite known_marketplaces.json (fix host-specific paths)
80+ if [ -f " $HOST_CONFIG /plugins/known_marketplaces.json" ]; then
81+ node -e "
82+ const fs = require('fs');
83+ const data = JSON.parse(fs.readFileSync('$HOST_CONFIG /plugins/known_marketplaces.json', 'utf8'));
84+ for (const marketplace of Object.values(data)) {
85+ if (marketplace.installLocation) {
86+ marketplace.installLocation = marketplace.installLocation.replace(/^\/home\/[^/]+\/.claude/, '$USER_CONFIG ');
87+ }
88+ }
89+ fs.writeFileSync('$USER_CONFIG /plugins/known_marketplaces.json', JSON.stringify(data, null, 2));
90+ "
91+ fi
2492
93+ # Copy plugin subdirectories (cache and local plugins, skip large marketplaces)
94+ for dir in cache local data; do
95+ if [ -d " $HOST_CONFIG /plugins/$dir " ] && [ -n " $( ls -A " $HOST_CONFIG /plugins/$dir " 2> /dev/null) " ]; then
96+ echo " Copying plugins/$dir /"
97+ cp -r " $HOST_CONFIG /plugins/$dir " " $USER_CONFIG /plugins/"
98+ fi
99+ done
100+ fi
101+
102+ echo " Host config sync complete."
103+ }
104+
105+ sync_host_claude_config
106+
107+ # ---------------------------------------------------------------------------
108+ # Configure MCP servers
109+ # ---------------------------------------------------------------------------
25110if command -v claude & > /dev/null; then
26111 echo " Configuring Chrome DevTools MCP server..."
27112 claude mcp remove chrome-devtools 2> /dev/null || true
@@ -30,19 +115,48 @@ else
30115 echo " WARNING: claude CLI not found, skipping MCP configuration"
31116fi
32117
33- echo " Enabling remote control for all sessions..."
118+ # ---------------------------------------------------------------------------
119+ # Merge settings.json (host settings + container overrides)
120+ # ---------------------------------------------------------------------------
121+ echo " Configuring settings.json..."
34122mkdir -p ~ /.claude
35123SETTINGS_FILE=" $HOME /.claude/settings.json"
36- if [ -f " $SETTINGS_FILE " ] ; then
37- # Merge preferRemoteControl into existing settings using node (available in the container)
38- node -e "
124+ HOST_SETTINGS= " /host-claude-config/settings.json "
125+
126+ node -e "
39127 const fs = require('fs');
40- const s = JSON.parse(fs.readFileSync('$SETTINGS_FILE ', 'utf8'));
41- s.preferRemoteControl = true;
42- fs.writeFileSync('$SETTINGS_FILE ', JSON.stringify(s, null, 2));
43- "
44- else
45- echo ' {"preferRemoteControl": true}' > " $SETTINGS_FILE "
46- fi
128+ let settings = {};
129+
130+ // Layer 1: Host settings (portable subset)
131+ if (fs.existsSync('$HOST_SETTINGS ')) {
132+ try {
133+ settings = JSON.parse(fs.readFileSync('$HOST_SETTINGS ', 'utf8'));
134+ // Remove keys that reference host-specific file paths
135+ delete settings.hooks;
136+ delete settings.statusLine;
137+ console.log(' Merged host settings.json');
138+ } catch (e) {
139+ console.error(' WARNING: Failed to parse host settings.json:', e.message);
140+ settings = {};
141+ }
142+ }
143+
144+ // Layer 2: Existing container settings (from previous setup/rebuild)
145+ if (fs.existsSync('$SETTINGS_FILE ')) {
146+ try {
147+ const existing = JSON.parse(fs.readFileSync('$SETTINGS_FILE ', 'utf8'));
148+ settings = { ...settings, ...existing };
149+ console.log(' Merged existing container settings.json');
150+ } catch (e) {
151+ console.error(' WARNING: Failed to parse existing settings.json:', e.message);
152+ }
153+ }
154+
155+ // Layer 3: Container-required settings
156+ settings.preferRemoteControl = true;
157+
158+ fs.writeFileSync('$SETTINGS_FILE ', JSON.stringify(settings, null, 2));
159+ console.log(' Wrote merged settings.json');
160+ "
47161
48- echo " Claude Code and OpenCode setup complete."
162+ echo " Claude Code setup complete."
0 commit comments