Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ This is the **Claude on Foundry Starter Kit** ([`Azure-Samples/claude`](https://
| `CLAUDE_MODEL_NAME` | no | `claude-sonnet-4-6` | **Legacy** single-deployment fallback (only used when all three `CLAUDE_*_MODEL` are empty) |
| `ASSIGN_RBAC` | no | `false` | `true` grants Foundry User + Foundry Project Manager to `AZURE_PRINCIPAL_ID` |
| `CLAUDE_CODE_AUTO_INSTALL` | no | `false` | `true` installs the Claude Code CLI in the postprovision hook |
| `CLAUDE_SKIP_VSCODE_SETTINGS` | no | `false` | `true` skips the `.vscode/settings.json` write in the postprovision hook (use when you don't have the Claude Code VS Code extension) |

Always set vars with `azd env set <VAR> <VALUE>` from inside the chosen variant folder.

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ After `azd up` succeeds, the **postprovision** hook ([`scripts/configure-claude-
- `ANTHROPIC_FOUNDRY_RESOURCE=<your-foundry-account-name>`
- One `ANTHROPIC_DEFAULT_<FAMILY>_MODEL=<deployment-name>` per deployed family (`HAIKU` / `SONNET` / `OPUS`). Only the families you actually deployed get a line.
- **`AZURE_CONFIG_DIR=<repo>/.azure-cli`** &mdash; scopes `az login` (and `azd`) to this workspace only. See [Workspace-scoped `az login`](#workspace-scoped-az-login) below.
2. Writes (or merges into) `.vscode/settings.json` with `claudeCode.environmentVariables` (the array-of-`{name,value}` schema the extension actually reads &mdash; the display name in the Settings UI is *"Claude Code: Environment Variables"*) and `claudeCode.disableLoginPrompt: true` so the [Claude Code VS Code extension](https://marketplace.visualstudio.com/items?itemName=anthropic.claude-code) skips the Anthropic-account login and uses your Foundry deployment via Entra ID. It also sets `terminal.integrated.env.{windows,linux,osx}.AZURE_CONFIG_DIR` so every terminal VS Code spawns in this workspace inherits the scoped Azure config automatically &mdash; you don't even have to source the activator first.
2. Writes (or merges into) `.vscode/settings.json` with `claudeCode.environmentVariables` (the array-of-`{name,value}` schema the extension actually reads &mdash; the display name in the Settings UI is *"Claude Code: Environment Variables"*) and `claudeCode.disableLoginPrompt: true` so the [Claude Code VS Code extension](https://marketplace.visualstudio.com/items?itemName=anthropic.claude-code) skips the Anthropic-account login and uses your Foundry deployment via Entra ID. It also sets `terminal.integrated.env.{windows,linux,osx}.AZURE_CONFIG_DIR` so every terminal VS Code spawns in this workspace inherits the scoped Azure config automatically &mdash; you don't even have to source the activator first. **Not using the Claude Code extension?** Opt out before `azd up` with `azd env set CLAUDE_SKIP_VSCODE_SETTINGS 1` (or pass `-SkipVsCodeSettings` / `--skip-vscode-settings` when running the script standalone) and the hook leaves `.vscode/settings.json` alone. The activator at step 1 still works for sourced shells.
3. Writes (or merges into) `.claude/settings.json` at the repo root with `{ "model": "<family>" }` pinned to a deployed family (sonnet &gt; opus &gt; haiku priority). This is the **workspace-level** Claude Code config and overrides whatever is in your user-global `~/.claude/settings.json` &mdash; so bare `claude` / `claude -p` resolves to a family you actually deployed, even if your global default points elsewhere.
4. Checks whether `claude` is on PATH. If not, prints the platform-appropriate one-liner install command. Set `CLAUDE_CODE_AUTO_INSTALL=true` *before* `azd up` to run [the official installer](https://claude.ai/install.ps1) automatically.

Expand Down
14 changes: 13 additions & 1 deletion scripts/configure-claude-code.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ param(

$ErrorActionPreference = 'Stop'

# Env-var opt-out so the postprovision hook can honor it without having to
# pass -SkipVsCodeSettings on the command line:
# azd env set CLAUDE_SKIP_VSCODE_SETTINGS 1
if (-not $SkipVsCodeSettings) {
$skipEnv = $env:CLAUDE_SKIP_VSCODE_SETTINGS
if ($skipEnv -and $skipEnv -match '^(1|true|yes|on)$') {
$SkipVsCodeSettings = $true
}
}

function Fail([int]$code, [string]$message) {
Write-Host ""
Write-Host "ERROR: $message" -ForegroundColor Red
Expand Down Expand Up @@ -177,7 +187,9 @@ Write-Host "Wrote activator: $shPath"
# ---------------------------------------------------------------------------
# 2. Write / merge `.vscode/settings.json` for the Claude Code VS Code extension.
# ---------------------------------------------------------------------------
if (-not $SkipVsCodeSettings) {
if ($SkipVsCodeSettings) {
Write-Host "Skipping .vscode/settings.json (CLAUDE_SKIP_VSCODE_SETTINGS / -SkipVsCodeSettings set). The activator above still wires up sourced shells."
} else {
$vscodeDir = Join-Path $RepoRoot '.vscode'
$settingsPath = Join-Path $vscodeDir 'settings.json'
if (-not (Test-Path $vscodeDir)) {
Expand Down
14 changes: 12 additions & 2 deletions scripts/configure-claude-code.sh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,15 @@ fail() {

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="${REPO_ROOT:-$(cd "$SCRIPT_DIR/.." && pwd)}"
SKIP_VSCODE_SETTINGS="${SKIP_VSCODE_SETTINGS:-0}"

# Skip flag from env. Prefer the CLAUDE_-namespaced name (matches the rest of
# the env-var contract); keep the un-prefixed name as a deprecated alias.
# Set via: azd env set CLAUDE_SKIP_VSCODE_SETTINGS 1
SKIP_VSCODE_SETTINGS="${CLAUDE_SKIP_VSCODE_SETTINGS:-${SKIP_VSCODE_SETTINGS:-0}}"
case "$SKIP_VSCODE_SETTINGS" in
1|true|TRUE|yes|YES|on|ON) SKIP_VSCODE_SETTINGS=1 ;;
*) SKIP_VSCODE_SETTINGS=0 ;;
esac

while [[ $# -gt 0 ]]; do
case "$1" in
Expand Down Expand Up @@ -153,7 +161,9 @@ for cand in python python3; do
if command -v "$cand" >/dev/null 2>&1; then PYTHON_BIN="$cand"; break; fi
done

if [ "${SKIP_VSCODE_SETTINGS:-}" != "1" ] && [ -n "$PYTHON_BIN" ]; then
if [ "${SKIP_VSCODE_SETTINGS:-}" = "1" ]; then
echo "Skipping .vscode/settings.json (CLAUDE_SKIP_VSCODE_SETTINGS / --skip-vscode-settings set). The activator above still wires up sourced shells."
elif [ -n "$PYTHON_BIN" ]; then
VSCODE_DIR="$REPO_ROOT/.vscode"
mkdir -p "$VSCODE_DIR"
SETTINGS_PATH="$VSCODE_DIR/settings.json"
Expand Down
1 change: 1 addition & 0 deletions skills/claude-on-foundry/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ claude # interactive REPL; try /status and /mode
| **Switch region** | `azd env new <name-region>` in the same variant folder, then redo the [DEPLOY](#deploy--running-azd-up) flow. **Don't** try to mutate `AZURE_LOCATION` on an existing env — the account is region-stamped. |
| **Switch variants (Bicep ↔ Terraform)** | They produce equivalent infra but with different `azd` env state. Create a new env in the other folder: `cd infra-terraform && azd env new <name> && ...`. |
| **Refresh Claude Code wiring** | `pwsh -File scripts/configure-claude-code.ps1` (or the `.sh` variant). Idempotent — runs without re-deploying. |
| **Skip the `.vscode/settings.json` write** | `azd env set CLAUDE_SKIP_VSCODE_SETTINGS 1` (then re-run `azd provision` or the configure script). For customers who don't use the Claude Code VS Code extension and don't want workspace settings touched. The activator at the repo root still wires up sourced shells. |
| **Convert to long-running auth** | Replace `Anthropic(auth_token=...)` with `AnthropicIdentity(azure_ad_token_provider=...)` from [`src/hello_claude_token_refresh.py`](../../src/hello_claude_token_refresh.py). |

---
Expand Down
Loading