← Commit history

Migrate asset from Helium wiki

Kyle Bergstedt ·1c1fbc47c4 ·4mo ago ·parent 31aee7c
1 file changed +259
hd-bootstrap.shadded+259
@@ -0,0 +1,259 @@+#!/bin/bash+# Hydrogen Desktop Bootstrap Script+# HD downloads this from the wiki and runs it via:+#   docker exec -u adom hydrogen-workspace bash /tmp/hd-bootstrap.sh+#+# Each step prints a structured line that HD's frontend parses:+#   STEP|<status>|<command>|<message>+# status: run|done|skip|fail+# HD renders these as a terminal-style log in the Bootstrap panel.+#+# Order matters — install everything FIRST, reload ONCE, then activate.++set -euo pipefail++CODESERVER="/usr/lib/code-server/bin/code-server"+HD_HOST="host.docker.internal"++step() {+    local status="$1" cmd="$2" msg="$3"+    echo "STEP|${status}|${cmd}|${msg}"+}++# ── 1. adom-vscode binary (needed before extension install) ──+if ! command -v adom-vscode &>/dev/null; then+    step run "curl -fsSL .../adom-vscode -o /usr/local/bin/adom-vscode" "downloading binary..."+    curl -fsSL "https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-vscode/adom-vscode" -o /tmp/adom-vscode-dl+    chmod +x /tmp/adom-vscode-dl+    sudo mv /tmp/adom-vscode-dl /usr/local/bin/adom-vscode 2>/dev/null || mv /tmp/adom-vscode-dl /usr/local/bin/adom-vscode+    step done "curl -fsSL .../adom-vscode -o /usr/local/bin/adom-vscode" "binary installed"+else+    step skip "which adom-vscode" "binary already installed"+fi++# ── 2. adom-vscode VS Code extension + skill ──+step run "adom-vscode install" "installing extension + skill..."+/usr/local/bin/adom-vscode install 2>/dev/null || true+step done "adom-vscode install" "extension + skill deployed"++# ── 3. adom-vscode extension in code-server (the install command may use wrong path) ──+if ! $CODESERVER --list-extensions 2>/dev/null | grep -q "adom.adom-vscode"; then+    step run "$CODESERVER --install-extension /tmp/adom-vscode-0.1.0.vsix" "registering extension in code-server..."+    $CODESERVER --install-extension /tmp/adom-vscode-0.1.0.vsix 2>/dev/null || true+    step done "$CODESERVER --install-extension /tmp/adom-vscode-0.1.0.vsix" "registered"+else+    step skip "$CODESERVER --list-extensions | grep adom" "already registered"+fi++# ── 4. Claude Code Extension ──+if $CODESERVER --list-extensions 2>/dev/null | grep -q "anthropic.claude-code"; then+    step skip "$CODESERVER --list-extensions | grep claude-code" "already installed"+else+    step run "$CODESERVER --install-extension anthropic.claude-code" "installing Claude Code..."+    $CODESERVER --install-extension anthropic.claude-code 2>/dev/null || true+    step done "$CODESERVER --install-extension anthropic.claude-code" "installed"+fi++# ── 5. Claude Code CLI ──+if command -v claude &>/dev/null; then+    step skip "which claude" "CLI already installed"+else+    step run "curl -fsSL https://claude.ai/install.sh | bash" "installing Claude CLI..."+    curl -fsSL https://claude.ai/install.sh -o /tmp/claude-install.sh 2>/dev/null+    bash /tmp/claude-install.sh 2>/dev/null || true+    step done "curl -fsSL https://claude.ai/install.sh | bash" "CLI installed"+fi++# ── 6. Gallia Platform ──+if [ -f "$HOME/.claude/skills/adom/SKILL.md" ]; then+    step skip "test -f ~/.claude/skills/adom/SKILL.md" "gallia already installed"+else+    step run "curl -fsSL .../gallia-bundle.tar.gz | tar xz" "downloading gallia..."+    curl -fsSL "https://wiki-ufypy5dpx93o.adom.cloud/static/apps/gallia-bundle/gallia-bundle.tar.gz" -o /tmp/gallia-bundle.tar.gz+    tar xzf /tmp/gallia-bundle.tar.gz -C "$HOME/"+    step done "curl -fsSL .../gallia-bundle.tar.gz | tar xz" "extracted"++    step run "cd gallia && npm install && node install.mjs" "deploying skills..."+    cd "$HOME/gallia" && npm install --no-audit --no-fund 2>&1 | tail -3+    if node "$HOME/gallia/install.mjs" --project "$HOME/project" 2>&1 | tail -5; then+        step done "cd gallia && npm install && node install.mjs" "skills deployed"+    else+        step fail "cd gallia && npm install && node install.mjs" "install.mjs failed (non-fatal)"+    fi+fi++# ── 6b. Set ADOM_CARBON_URL to route adom-cli workspace commands to HD ──+CARBON_LINE="export ADOM_CARBON_URL=http://host.docker.internal:9000"+HYDROGEN_LINE="export ADOM_HYDROGEN_URL=http://host.docker.internal:9000"+if grep -q "ADOM_CARBON_URL" "$HOME/.bashrc" 2>/dev/null; then+    step skip "grep ADOM_CARBON_URL ~/.bashrc" "already set"+else+    step run "echo export ADOM_CARBON/HYDROGEN_URL >> ~/.bashrc" "routing adom-cli to HD..."+    echo "$CARBON_LINE" >> "$HOME/.bashrc"+    echo "$HYDROGEN_LINE" >> "$HOME/.bashrc"+    step done "echo export ADOM_CARBON/HYDROGEN_URL >> ~/.bashrc" "adom-cli routed to HD"+fi+export ADOM_CARBON_URL=http://host.docker.internal:9000+export ADOM_HYDROGEN_URL=http://host.docker.internal:9000++# ── 6c. Inject API key from HD (host has the session token) ──+if [ -f /var/run/adom/api-key ] && [ -s /var/run/adom/api-key ]; then+    step skip "test -f /var/run/adom/api-key" "API key already present"+else+    step run "inject api-key from HD" "fetching session token from host..."+    TOKEN=$(curl -sf http://host.docker.internal:9001/auth-token 2>/dev/null || echo "")+    if [ -n "$TOKEN" ]; then+        sudo mkdir -p /var/run/adom+        echo -n "$TOKEN" | sudo tee /var/run/adom/api-key > /dev/null+        sudo chmod 644 /var/run/adom/api-key+        step done "inject api-key from HD" "API key injected"+    else+        step fail "inject api-key from HD" "no token available from HD"+    fi+fi++# ── 7. VS Code Settings ──+step run "configure VS Code settings" "dark mode, Claude Code, trust..."+node -e "+const fs = require('fs');+const p = '$HOME/.local/share/code-server/User/settings.json';+let s = {}; try { s = JSON.parse(fs.readFileSync(p, 'utf8')) } catch(e) {}+Object.assign(s, {+    'security.workspace.trust.enabled': false,+    'workbench.startupEditor': 'none',+    'workbench.activityBar.visible': true,+    'workbench.colorTheme': 'Default Dark Modern',+    'workbench.statusBar.visible': false,+    'claudeCode.allowDangerouslySkipPermissions': true,+    'claudeCode.initialPermissionMode': 'bypassPermissions',+    'claudeCode.preferredLocation': 'panel',+    'github.copilot.chat.enabled': false,+    'github.copilot.enable': {'*': false},+    'security.trustedDomains': ['*'],+    'workbench.trustedDomains.promptInTrustedWorkspace': false,+    'remote.portsAttributes': {'*': {'onAutoForward': 'silent'}}+});+fs.mkdirSync(require('path').dirname(p), {recursive: true});+fs.writeFileSync(p, JSON.stringify(s, null, 2));+console.log('configured');+"+step done "configure VS Code settings" "settings applied"++# ── 7b. Patch workbench.html BEFORE reload so it loads with the page ──+step run "patch workbench.html" "making external links propagate to parent browser..."+WORKBENCH="/usr/lib/code-server/lib/vscode/out/vs/code/browser/workbench/workbench.html"+MARKER="__hdLinkPropagation"+if ! grep -q "$MARKER" "$WORKBENCH" 2>/dev/null; then+    sudo tee -a "$WORKBENCH" > /dev/null 2>&1 << 'LINKPATCH'+<script>+// Hydrogen Desktop: suppress "open external website?" dialog+// All URL interception is handled by WebView2's on_new_window + on_navigation+// in the Rust layer. This patch ONLY sets trusted domains in IndexedDB so+// code-server doesn't show its own confirmation dialog.+(function() {+    if (window.__hdLinkPropagation) return;+    window.__hdLinkPropagation = true;+    try {+        var req = indexedDB.open('vscode-web-state-db-global', 1);+        req.onupgradeneeded = function(e) {+            var db = e.target.result;+            if (!db.objectStoreNames.contains('ItemTable')) {+                db.createObjectStore('ItemTable');+            }+        };+        req.onsuccess = function(e) {+            var db = e.target.result;+            try {+                var tx = db.transaction('ItemTable', 'readwrite');+                var store = tx.objectStore('ItemTable');+                store.put(JSON.stringify(['*']), 'http.linkProtectionTrustedDomains');+                tx.oncomplete = function() { console.log('[hd] Trusted domains set to * in IndexedDB'); db.close(); };+            } catch(err) { db.close(); }+        };+    } catch(e) { console.error('[hd] Failed to set trusted domains:', e); }+    console.log('[hd] Trusted domains patch loaded');+})();+</script>+LINKPATCH+    step done "patch workbench.html" "trusted domains set"+else+    step skip "patch workbench.html" "already patched"+fi++# ── 8. Reload VS Code (ONCE — after all extensions + settings are in place) ──+step run "adom-vscode reload" "reloading VS Code to activate extensions..."+# First trigger HD iframe reload so the webview picks up changes+curl -sf -X POST "http://host.docker.internal:9001/reload-vscode" 2>/dev/null || true+sleep 3+# Then reload the code-server window so extension host restarts+/usr/local/bin/adom-vscode reload 2>/dev/null || true+step done "adom-vscode reload" "VS Code reloaded"++# ── 9. Wait for adom-vscode extension to activate ──+step run "curl -sf http://127.0.0.1:8821/health" "waiting for adom-vscode (up to 60s)..."+VSCODE_READY=false+for i in $(seq 1 20); do+    if curl -sf http://127.0.0.1:8821/health >/dev/null 2>&1; then+        VSCODE_READY=true+        break+    fi+    # Retry reload at 30s+    if [ "$i" = "10" ]; then+        /usr/local/bin/adom-vscode reload 2>/dev/null || true+    fi+    sleep 3+done++if [ "$VSCODE_READY" = true ]; then+    step done "curl -sf http://127.0.0.1:8821/health" "extension active on :8821"++    # ── 10. Clean VS Code layout (hide chrome, open Claude Code) ──+    step run "configure VS Code layout" "hiding sidebars, panel, status bar..."+    /usr/local/bin/adom-vscode sidebar hide 2>/dev/null || true+    /usr/local/bin/adom-vscode panel hide 2>/dev/null || true+    curl -sf -X POST http://127.0.0.1:8821/command \+        -H "Content-Type: application/json" \+        -d '{"command":"workbench.action.closeAuxiliaryBar"}' || true+    step done "configure VS Code layout" "clean layout ready"++    # ── 10b. Open Claude Code with countdown + auto-submit ──+    step run "open Claude Code" "launching Claude Code panel..."+    curl -sf -X POST http://127.0.0.1:8821/command \+        -H "Content-Type: application/json" \+        -d '{"command":"claude-vscode.editor.open"}' || true+    sleep 1+    curl -sf -X POST http://127.0.0.1:8821/command \+        -H "Content-Type: application/json" \+        -d '{"command":"claude-vscode.focus"}' || true+    step done "open Claude Code" "Claude Code panel open"++    step run "say hello to Claude" "3..."+    sleep 1+    step run "say hello to Claude" "2..."+    sleep 1+    step run "say hello to Claude" "1..."+    sleep 1+    SEED_MSG="hey, i'm here and ready to go. do you know who i am? and what can you do for me?"+    curl -sf -X POST http://127.0.0.1:8821/command \+        -H "Content-Type: application/json" \+        -d "{\"command\":\"claude-vscode.editor.open\",\"args\":[null,\"$SEED_MSG\"]}" || true+    step done "say hello to Claude" "message sent"+else+    step fail "curl -sf http://127.0.0.1:8821/health" "timed out after 60s"+fi++# ── 11. Start relay server ──+if curl -sf http://127.0.0.1:8766/health >/dev/null 2>&1; then+    step skip "curl -sf http://127.0.0.1:8766/health" "relay already running"+else+    step run "nohup adom-desktop serve &" "starting relay..."+    nohup adom-desktop serve > /tmp/adom-desktop-relay.log 2>&1 & disown+    sleep 2+    if curl -sf http://127.0.0.1:8766/health >/dev/null 2>&1; then+        step done "nohup adom-desktop serve &" "relay on :8765/:8766"+    else+        step fail "nohup adom-desktop serve &" "relay failed to start"+    fi+fi++echo "STEP|done|bootstrap|complete"