Dev: 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/screenshots
The DROPBOX_* stubs are needed because $CLAUDE_ENV_FILE (which
setup-web.sh would 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) or
claude-profile: fetched claude-resources tarball (fallback) — followed by
web profile installed into ....
Step 2: Committed hook (--committed, optional top-up)
!! Team-repo safety !! A committed .claude/settings.json affects
everyone in the repo: on a teammate's web session it would overwrite
their ~/.claude and 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.sh and chmod +x it.
If --self-only was passed: uncomment the CLAUDE_WEB_PROFILE_OPT_IN gate
inside the copy, and tell the user to set CLAUDE_WEB_PROFILE_OPT_IN=1
in 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 an
existing 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 /commits) 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 target codeload.github.com) for the tarball tier.
Tier 1 clone: Takazudo/claude-settings should 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_REMOTE is not guaranteed pre-launch: setup-web.sh exits 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-source
after 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 -l in the container reveals
it): out-of-scope git clone used 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 with
git ls-remote --exit-code https://github.com/Takazudo/claude-settings HEAD
(expect a hash, not 403).
settings.local.json is not an option — git-ignored, never reaches the
web container.
setup-web.sh sources from its own location, so it installs the downloaded
profile's config, not the consumer project's.
1---2name: dev-setup-webenv3description: (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 environment or account needs the Setup script re-applied. Runs LOCALLY (Mac/terminal) — prints the canonical env setup script (PRIMARY: per-account, pre-launch, covers multi-repo sessions) and/or commits a single-repo SessionStart top-up hook from the bundled template.4---56# Dev: Set up / re-apply the Web Environment78Web sessions boot with the shared profile via two loaders:910| Loader | When it runs | Coverage |11|---|---|---|12| **Env Setup script** (`--env-script`, default) | pre-launch, per-account environment | every session, including multi-repo — the primary loader |13| **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 |1415This skill runs on the **local terminal**; the download and install happen16later, inside the web container. When neither flag is passed, apply17`--env-script` — it is safe everywhere.1819**Never put positional parameters (dollar sign + digit) anywhere in this20file** — skill argument substitution replaces them with invocation args and21corrupts embedded snippets. That is why the hook template lives in `assets/`22and the env script is read from disk instead of being embedded here.2324## Step 1: Env setup script (`--env-script`, default)25261. Read `$HOME/.claude/web/env-setup-script.sh` (the canonical copy; the2728 mirror ships it to the web container too) and print its contents verbatim29 for the user to paste into **claude.ai/code → Environment → Setup script**.30312. Tell the user to also fill the environment's **Environment variables**3233 field:3435 ```36 CLAUDE_WEB_PROFILE_OPT_IN=137 DROPBOX_CCLOGS_DIR=/tmp/cclogs38 DROPBOX_SCREENSHOTS_DIR=/tmp/screenshots39 ```4041 The `DROPBOX_*` stubs are needed because `$CLAUDE_ENV_FILE` (which42 `setup-web.sh` would otherwise write them to) may not exist pre-launch;43 the opt-in var feeds committed self-only hooks.44453. First-run check: the environment's setup output shows which tier worked —4647 `claude-profile: cloned claude-settings` (tier 1, private clone) or48 `claude-profile: fetched claude-resources tarball` (fallback) — followed by49 `web profile installed into ...`.5051## Step 2: Committed hook (`--committed`, optional top-up)5253> **!! Team-repo safety !!** A committed `.claude/settings.json` affects54> **everyone** in the repo: on a teammate's web session it would overwrite55> their `~/.claude` and disable their permission prompts (web settings run in56> auto mode). Solo repos only, or get the owner's agreement — and prefer57> `--self-only`.5859> **Single-repo sessions only.** Multi-repo web sessions never register60> repo-level settings hooks — this hook silently does nothing there. It is a61> top-up alongside Step 1, never the only loader.62631. Copy `assets/web-bootstrap.template.sh` (bundled in this skill's directory)6465 to `<project>/.claude/web-bootstrap.sh` and `chmod +x` it.66672. If `--self-only` was passed: uncomment the `CLAUDE_WEB_PROFILE_OPT_IN` gate6869 inside the copy, and **tell the user to set `CLAUDE_WEB_PROFILE_OPT_IN=1`70 in their per-account web environment variables** (already included in the71 Step 1 block) — without it the gate skips every session. The gate keys on a72 per-account env var — never on a committed email/identity (breaks on73 account switch; the harness email var is unreliable on web).74753. Register the hook in `<project>/.claude/settings.json` — **merge** into an7677 existing file rather than overwriting:7879 ```json80 {81 "$schema": "https://json.schemastore.org/claude-code-settings.json",82 "hooks": {83 "SessionStart": [84 {85 "hooks": [86 {87 "type": "command",88 "command": "/bin/bash \"$CLAUDE_PROJECT_DIR/.claude/web-bootstrap.sh\""89 }90 ]91 }92 ]93 }94 }95 ```96974. Commit both files (use `/commits`) and push. In the report, always mention9899 the single-repo-sessions-only limitation so a silent multi-repo skip is not100 mistaken for breakage.101102## Prerequisites103104- The public mirror must carry the web profile (`web/` +105106 `scripts/setup-web.sh`) — publish with `/claude-resources-share`.107108- Network policy must allow plain HTTPS egress to `github.com` (and its109110 redirect target `codeload.github.com`) for the tarball tier.111112- Tier 1 clone: `Takazudo/claude-settings` should be within the GitHub app's113114 allowed repo scope. Optional — the tarball fallback covers a rejected clone.115116## Gotchas (hard-won; do not re-litigate)117118- **Multi-repo sessions never register repo-level settings hooks** (verified119120 in-container): project dir is `/home/user`, repos are subdirectories;121 CLAUDE.md and skills load, hooks don't. Launcher-level hooks still fire, so122 "hooks work" is not evidence the repo hook ran. Only the env setup script123 covers these sessions.124125- **`CLAUDE_CODE_REMOTE` is not guaranteed pre-launch**: `setup-web.sh` exits 0126127 without it. The env script exports it explicitly — without that, the download128 succeeds and the install silently no-ops ("fetched fine, nothing installed").129130- **Sentinel interplay**: the env script writes `~/.claude/.web-profile-source`131132 after a successful install; the hook template skips when it is present, so a133 tier-1 private-clone profile is never clobbered by the hook's public-mirror134 tarball.135136- **Scoped git proxy history** (mechanism: `gitConfigInjection` — the rewrite137138 arrives via injected git config; `git config -l` in the container reveals139 it): out-of-scope `git clone` used to 403140 unconditionally; containers observed 2026-07 clone the user's own repos —141 but only post-boot (SessionStart context) was observed, and behavior has142 shifted once already. Every path keeps the tarball fallback. Verify from a143 web session with144 `git ls-remote --exit-code https://github.com/Takazudo/claude-settings HEAD`145 (expect a hash, not 403).146147- `settings.local.json` is **not** an option — git-ignored, never reaches the148149 web container.150151- `setup-web.sh` sources from its own location, so it installs the downloaded152153 profile's config, not the consumer project's.