Repository navigation
Expand file tree
/
Copy pathinit-plugins.sh
More file actions
executable file
·135 lines (122 loc) · 6.28 KB
/
Copy pathinit-plugins.sh
File metadata and controls
executable file
·135 lines (122 loc) · 6.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/bin/bash
# Claude Code plugin initialization. Idempotent — safe to run multiple times;
# each run also updates plugins to latest.
#
# Sandbox variant: runs from postCreateCommand, before the firewall comes up.
# Default variant: run `bash .devcontainer/init-plugins.sh` after signing in, and to
# update plugins — from postCreateCommand it races the extension's OAuth sign-in (#58).
set -euo pipefail
# Mark onboarding complete so claude CLI doesn't hang on interactive prompts
if [ -f "$HOME/.claude/.claude.json" ]; then
jq '.hasCompletedOnboarding = true' "$HOME/.claude/.claude.json" > /tmp/.claude.json \
&& mv /tmp/.claude.json "$HOME/.claude/.claude.json"
else
mkdir -p "$HOME/.claude"
echo '{"hasCompletedOnboarding":true}' > "$HOME/.claude/.claude.json"
fi
# ── Claude Code marketplaces ────────────────────────────────────────────────
# The official marketplace is auto-configured on first interactive launch, but
# postCreateCommand runs before that — register explicitly so plugin install works.
MARKETPLACES=(
"anthropics/claude-plugins-official"
"umputun/ralphex"
"GoogleChrome/modern-web-guidance"
"AgriciDaniel/claude-seo"
"cloudflare/skills"
"rubberduck-studio/typescript-native-lsp"
)
for marketplace in "${MARKETPLACES[@]}"; do
if claude plugin marketplace add "$marketplace" 2>&1; then
echo "✔ Marketplace added: $marketplace"
else
echo "⚠ Failed to add marketplace: $marketplace" >&2
fi
done
# ── Claude Code plugins ─────────────────────────────────────────────────────
# Customize this list — remove plugins you don't use.
PLUGINS=(
"frontend-design@claude-plugins-official"
"code-review@claude-plugins-official"
"code-simplifier@claude-plugins-official"
"playwright@claude-plugins-official"
"superpowers@claude-plugins-official"
"explanatory-output-style@claude-plugins-official"
"claude-md-management@claude-plugins-official"
"claude-code-setup@claude-plugins-official"
"posthog@claude-plugins-official"
# Both need python3 (baked into the image). security-guidance reviews every
# edit, turn and commit; claude-security runs on-demand /claude-security scans.
"security-guidance@claude-plugins-official"
"claude-security@claude-plugins-official"
# cloudflare/skills is Cloudflare's own marketplace: current skills + MCP server.
# (The claude-plugins-official copy is a stale snapshot.) wrangler <4.126 also
# auto-installed a 3rd copy into ~/.claude/skills after any command; run
# `wrangler types` with CI=true in postinstall scripts to keep that quiet.
"cloudflare@cloudflare"
"ralphex@ralphex"
"modern-web-guidance@googlechrome"
"claude-seo@agricidaniel-claude-seo"
# Replaces typescript-lsp@claude-plugins-official, which wraps tsserver and fails
# every request on TypeScript 7 (no tsserver.js). Runs `tsc --lsp` on TS 7+ and
# falls back to typescript-language-server on TS 6 and older (#194).
"typescript-native-lsp@typescript-native-lsp"
)
for plugin in "${PLUGINS[@]}"; do
if claude plugin install "$plugin" 2>&1; then
echo "✔ Installed: $plugin"
else
echo "⚠ Failed to install: $plugin" >&2
fi
done
# ── Conflicting plugins ─────────────────────────────────────────────────────
# Plugins that claim the same file extensions as one in PLUGINS: Claude Code
# starts only whichever registers first. Not installed above, but a persistent
# ~/.claude volume may still hold them from an older run — disable if enabled.
DISABLED_PLUGINS=(
"typescript-lsp@claude-plugins-official" # superseded by typescript-native-lsp
)
for plugin in "${DISABLED_PLUGINS[@]}"; do
if claude plugin list --json 2>/dev/null \
| jq -e --arg id "$plugin" 'any(.[]; .id == $id and .enabled)' >/dev/null; then
if claude plugin disable "$plugin" 2>&1; then
echo "✔ Disabled: $plugin"
else
echo "⚠ Failed to disable: $plugin" >&2
fi
fi
done
# ~/.claude is a persistent volume, so `install` no-ops after the first run.
# Refresh marketplace indexes first — `plugin update` resolves against the cache.
if claude plugin marketplace update 2>&1; then
echo "✔ Marketplaces refreshed"
else
echo "⚠ Failed to refresh marketplaces" >&2
fi
for plugin in "${PLUGINS[@]}"; do
if claude plugin update "$plugin" 2>&1; then
echo "✔ Up to date: $plugin"
else
echo "⚠ Failed to update: $plugin" >&2
fi
done
# ── Playwright MCP: route every cached .mcp.json to system chromium ─────────
# Universal across arches (no Chrome stable binary in either default or sandbox).
# The patch binary is baked into the image (see Dockerfile #87) and also runs
# from postStartCommand (#85) and a Claude Code SessionStart hook (#98) — the
# hook is what closes the gap when the plugin auto-updates mid-container-run.
/usr/local/bin/patch-playwright-mcp
# ── rtk init (token-optimized CLI proxy) ────────────────────────────────────
# Global hook-first mode: installs only the PreToolUse rewrite hook to ~/.claude/,
# no workspace artifacts (CLAUDE.md, .rtk/). Safe to run multiple times.
# Telemetry consent prompt: RTK_TELEMETRY_DISABLED=1 opts out (rtk-ai/rtk#2477),
# closed stdin defeats the pseudo-TTY postCreateCommand hands us, and timeout
# backstops any other init-time hang.
if command -v rtk &>/dev/null; then
RTK_TELEMETRY_DISABLED=1 timeout 10 rtk init -g --hook-only --auto-patch < /dev/null 2>/dev/null || true
fi
# ── agent-browser skill ─────────────────────────────────────────────────────
# Installs the agent-browser Claude Code skill for headless browser automation.
# agent-browser CLI is pre-installed in the default devcontainer image (not sandbox).
if command -v agent-browser &>/dev/null; then
agent-browser install-skill 2>/dev/null || true
fi