dev-setup-webenv
(Re)apply the Claude Code on the web profile setup. Use when: (1) User says '/dev-setup-webenv', 'set up web env', 'enable my skills on web', (2) A web session boots without the profile, (3) A new web
SKILL.mdskills/dev-setup-webenv/SKILL.md
GitHubDev: Set up / re-apply the Web Environment
Web sessions boot with the shared profile via two loaders:
| Loader | When it runs | Coverage |
|---|---|---|
Env Setup script (--env-script, default) |
pre-launch, per-account environment | every session, including multi-repo — the primary loader |
Committed hook (--committed) |
SessionStart, per-repo | single-repo sessions only — a redundancy fallback (fetches the mirror's default branch; skips when the env script already installed), never the only loader |
This skill runs on the local terminal; the download and install happen
later, inside the web container. When neither flag is passed, apply
--env-script — it is safe everywhere.
Never put positional parameters (dollar sign + digit) anywhere in this
file — skill argument substitution replaces them with invocation args and
corrupts embedded snippets. That is why the hook template lives in assets/
and the env script is read from disk instead of being embedded here.
Step 1: Env setup script (--env-script, default)
Read
$HOME/.claude/web/env-setup-script.sh(the canonical copy; the mirror ships it to the web container too) and print its contents verbatim for the user to paste into claude.ai/code → Environment → Setup script.Tell the user to also fill the environment's Environment variables
field:
CLAUDE_WEB_PROFILE_OPT_IN=1 DROPBOX_CCLOGS_DIR=/tmp/cclogs DROPBOX_SCREENSHOTS_DIR=/tmp/screenshotsThe
DROPBOX_*stubs are needed because$CLAUDE_ENV_FILE(whichsetup-web.shwould otherwise write them to) may not exist pre-launch; the opt-in var feeds committed self-only hooks.First-run check: the environment's setup output shows which tier worked —
claude-profile: cloned claude-settings(tier 1, private clone) orclaude-profile: fetched claude-resources tarball(fallback) — followed byweb profile installed into ....
Step 2: Committed hook (--committed, optional top-up)
!! Team-repo safety !! A committed
.claude/settings.jsonaffects everyone in the repo: on a teammate's web session it would overwrite their~/.claudeand disable their permission prompts (web settings run in auto mode). Solo repos only, or get the owner's agreement — and prefer--self-only.
Single-repo sessions only. Multi-repo web sessions never register repo-level settings hooks — this hook silently does nothing there. It is a top-up alongside Step 1, never the only loader.
Copy
assets/web-bootstrap.template.sh(bundled in this skill's directory) to<project>/.claude/web-bootstrap.shandchmod +xit.If
--self-onlywas passed: uncomment theCLAUDE_WEB_PROFILE_OPT_INgate inside the copy, and tell the user to setCLAUDE_WEB_PROFILE_OPT_IN=1in their per-account web environment variables (already included in the Step 1 block) — without it the gate skips every session. The gate keys on a per-account env var — never on a committed email/identity (breaks on account switch; the harness email var is unreliable on web).Register the hook in
<project>/.claude/settings.json— merge into anexisting file rather than overwriting:
{ "$schema": "https://json.schemastore.org/claude-code-settings.json", "hooks": { "SessionStart": [ { "hooks": [ { "type": "command", "command": "/bin/bash \"$CLAUDE_PROJECT_DIR/.claude/web-bootstrap.sh\"" } ] } ] } }Commit both files (use
/co) and push. In the report, always mention the single-repo-sessions-only limitation so a silent multi-repo skip is not mistaken for breakage.
Prerequisites
- The public mirror must carry the web profile (
web/+scripts/setup-web.sh) — publish with/claude-resources-share. - Network policy must allow plain HTTPS egress to
github.com(and its redirect targetcodeload.github.com) for the tarball tier. - Tier 1 clone:
Takazudo/claude-settingsshould be within the GitHub app's allowed repo scope. Optional — the tarball fallback covers a rejected clone.
Gotchas (hard-won; do not re-litigate)
- Multi-repo sessions never register repo-level settings hooks (verified
in-container): project dir is
/home/user, repos are subdirectories; CLAUDE.md and skills load, hooks don't. Launcher-level hooks still fire, so "hooks work" is not evidence the repo hook ran. Only the env setup script covers these sessions. CLAUDE_CODE_REMOTEis not guaranteed pre-launch:setup-web.shexits 0 without it. The env script exports it explicitly — without that, the download succeeds and the install silently no-ops ("fetched fine, nothing installed").- Sentinel interplay: the env script writes
~/.claude/.web-profile-sourceafter a successful install; the hook template skips when it is present, so a tier-1 private-clone profile is never clobbered by the hook's public-mirror tarball. - Scoped git proxy history (mechanism:
gitConfigInjection— the rewrite arrives via injected git config;git config -lin the container reveals it): out-of-scopegit cloneused to 403 unconditionally; containers observed 2026-07 clone the user's own repos — but only post-boot (SessionStart context) was observed, and behavior has shifted once already. Every path keeps the tarball fallback. Verify from a web session withgit ls-remote --exit-code https://github.com/Takazudo/claude-settings HEAD(expect a hash, not 403). - The Setup script result is cached as an environment snapshot (docs:
cached when it finishes in
5 min). Sessions then boot the frozen `/.claude— a skill deleted/renamed upstream (e.g. old/pr-complete) lingers. Two guards:setup-web.shprunes non-symlink skills/agents/commands missing from the source, and the user-level SessionStart hook inweb/settings.web.jsonrunsscripts/web-refresh-profile.sheach session (pull~/.claude-srcor re-fetch the mirror, re-runsetup-web.shwithCLAUDE_WEB_SKIP_WISDOM=1). To rebuild the snapshot itself, bump theloader-rev` line and re-paste the script. - Cloud sessions never read the Mac's
~/.claude— only claude.ai account-enabled skills, the repo's.claude/skills/, and whatever the Setup script installs into the container's~/.claude. A skill appearing on web that no source has is either a stale snapshot or an account-level skill (claude.ai → Settings → Capabilities). settings.local.jsonis not an option — git-ignored, never reaches the web container.setup-web.shsources from its own location, so it installs the downloaded profile's config, not the consumer project's.