Skip to content

Commit faab429

Browse files
authored
Switch from FOUNDRY_FF_ENHANCED_UI to FOUNDRY_UI_HEADLESS_MODE (#5)
* Switch from FOUNDRY_FF_ENHANCED_UI to FOUNDRY_UI_HEADLESS_MODE Per Josh Marlow (Foundry CLI team), FOUNDRY_FF_ENHANCED_UI is a temporary feature flag that will be removed. FOUNDRY_UI_HEADLESS_MODE=true is the correct long-term env var for disabling TUI features in headless/CI environments. Updated hook, tests (171 passing), skills, use cases, and scripts. * Add SessionStart hook to auto-inject FOUNDRY_UI_HEADLESS_MODE The plugin now sets FOUNDRY_UI_HEADLESS_MODE=true automatically at session start via CLAUDE_ENV_FILE, so users never need to prefix deploy/release/list-deployments commands manually. - New hooks/set-foundry-env.sh (SessionStart hook) - Updated hooks.json with SessionStart entry - Removed FOUNDRY_UI_HEADLESS_MODE=true prefix from all docs/examples - Guard hook kept as fallback for edge cases - 174 hook tests passing (3 new for SessionStart) - A/B tested: 5/5 deployed
1 parent 03b9c85 commit faab429

12 files changed

Lines changed: 152 additions & 70 deletions

File tree

CLAUDE.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@ foundry profile activate --name <name> # Switch between environments
157157
# App Development Lifecycle
158158
foundry apps create --name "X" --no-prompt --no-git # Create new app
159159
foundry apps run # Start full app locally in dev mode
160-
FOUNDRY_FF_ENHANCED_UI=false foundry apps deploy --change-type Patch --change-log "msg" --no-prompt # Deploy to cloud
161-
FOUNDRY_FF_ENHANCED_UI=false foundry apps release --change-type Patch --deployment-id <id> --notes "notes" # Release to app catalog
160+
foundry apps deploy --change-type Patch --change-log "msg" --no-prompt # Deploy to cloud
161+
foundry apps release --change-type Patch --deployment-id <id> --notes "notes" # Release to app catalog
162162
foundry ui run # Local UI development server
163163

164164
# Scaffolding Commands (ALWAYS use --no-prompt)

hooks/foundry-cli-guard.sh

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@
1111
# 2. Running ui extensions create without --sockets (interactive picker hangs)
1212
# 3. Using mkdir/touch to create app structure (causes invalid manifests)
1313
# 4. Creating resources without user confirmation of the name
14-
# 5. Running deploy/release/list-deployments without FOUNDRY_FF_ENHANCED_UI=false (TUI hangs)
14+
# 5. Running deploy/release/list-deployments without FOUNDRY_UI_HEADLESS_MODE=true (TUI hangs)
15+
# Note: The SessionStart hook (set-foundry-env.sh) sets this env var automatically.
16+
# This guard is a fallback for edge cases where the env var isn't set.
1517
#
1618
# Receives JSON on stdin with hook_event_name and tool-specific fields.
1719
# Outputs JSON with additionalContext (advisory nudge, not blocking).
@@ -94,16 +96,16 @@ if echo "$COMMAND" | grep -qE 'foundry\s+ui\s+extensions\b.*\bcreate\b'; then
9496
fi
9597
fi
9698

97-
# Check for foundry apps deploy/release/list-deployments without FOUNDRY_FF_ENHANCED_UI=false
99+
# Check for foundry apps deploy/release/list-deployments without FOUNDRY_UI_HEADLESS_MODE=true
100+
# Normally the SessionStart hook sets this env var, but this guard catches edge cases.
98101
# The enhanced UI (TUI progress monitor) requires a TTY and hangs in non-interactive environments.
99-
# Some developers set FOUNDRY_FF_ENHANCED_UI=true; future CLI versions may default to true.
100-
# Skip advisory only when the env var is explicitly "false" — unset or "true" both need the prefix.
102+
# Skip advisory only when the env var is explicitly "true" — unset or "false" both need the prefix.
101103
if echo "$COMMAND" | grep -qE 'foundry\s+apps\s+(deploy|release|list-deployments)\b'; then
102-
if [ "${FOUNDRY_FF_ENHANCED_UI:-}" != "false" ] && ! echo "$COMMAND" | grep -qF 'FOUNDRY_FF_ENHANCED_UI=false'; then
104+
if [ "${FOUNDRY_UI_HEADLESS_MODE:-}" != "true" ] && ! echo "$COMMAND" | grep -qF 'FOUNDRY_UI_HEADLESS_MODE=true'; then
103105
jq -n '{
104106
hookSpecificOutput: {
105107
hookEventName: "PreToolUse",
106-
additionalContext: "The command is missing FOUNDRY_FF_ENHANCED_UI=false. The enhanced UI (TUI progress monitor) requires a TTY and will hang in Claude Code. Prepend FOUNDRY_FF_ENHANCED_UI=false to the command. Example: FOUNDRY_FF_ENHANCED_UI=false foundry apps deploy --change-type Patch --change-log \"msg\""
108+
additionalContext: "The command is missing FOUNDRY_UI_HEADLESS_MODE=true. The enhanced UI (TUI progress monitor) requires a TTY and will hang in Claude Code. Prepend FOUNDRY_UI_HEADLESS_MODE=true to the command. Example: FOUNDRY_UI_HEADLESS_MODE=true foundry apps deploy --change-type Patch --change-log \"msg\""
107109
}
108110
}'
109111
exit 0

hooks/hooks.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
{
22
"hooks": {
3+
"SessionStart": [
4+
{
5+
"hooks": [
6+
{
7+
"type": "command",
8+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/set-foundry-env.sh",
9+
"timeout": 5
10+
}
11+
]
12+
}
13+
],
314
"UserPromptSubmit": [
415
{
516
"hooks": [

hooks/set-foundry-env.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env bash
2+
#
3+
# set-foundry-env.sh — SessionStart hook
4+
#
5+
# Sets FOUNDRY_UI_HEADLESS_MODE=true for the entire session so that
6+
# deploy, release, and list-deployments commands work without a TTY.
7+
# This eliminates the need to prefix each command manually.
8+
#
9+
set -euo pipefail
10+
11+
if [ -n "${CLAUDE_ENV_FILE:-}" ]; then
12+
echo 'export FOUNDRY_UI_HEADLESS_MODE=true' >> "$CLAUDE_ENV_FILE"
13+
fi
14+
15+
exit 0

skills/foundry-development-workflow/SKILL.md

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,8 @@ metadata:
3030
>
3131
> **CRITICAL: `--no-prompt` is supported by nearly all commands.** Always add `--no-prompt` to prevent interactive prompts that cause `Error: EOF` in non-interactive environments. Supported commands include: `apps create`, `apps deploy`, `apps release`, `apps delete` (also needs `--force-delete`, but may still prompt interactively in some CLI versions — delete via Falcon App Manager UI if it hangs), `functions create`, `collections create`, `ui pages create`, `ui extensions create`, `rtr-scripts create`, `profile create`, `workflows create`, and `api-integrations create`. When unsure, run `foundry <command> --help` to check. When a CLI command fails, MUST NOT fall back to `mkdir` — fix the command and retry.
3232
>
33-
> **CRITICAL: `FOUNDRY_FF_ENHANCED_UI=false` is required for non-TTY environments.**
34-
> The enhanced UI (TUI progress monitor) requires a TTY and will hang or fail in Claude Code, CI/CD pipelines, and headless environments. **Always prepend `FOUNDRY_FF_ENHANCED_UI=false` to these commands:**
35-
> - `foundry apps deploy`
36-
> - `foundry apps release`
37-
> - `foundry apps list-deployments`
38-
>
39-
> Example: `FOUNDRY_FF_ENHANCED_UI=false foundry apps deploy --change-type Patch --change-log "msg"`
33+
> **NOTE: `FOUNDRY_UI_HEADLESS_MODE=true` is set automatically** by the plugin's SessionStart hook.
34+
> You do not need to prefix `deploy`, `release`, or `list-deployments` commands with it.
4035
>
4136
> **Superpowers skills MAY supplement** (TDD discipline, code review) but MUST NOT replace this workflow.
4237
@@ -127,7 +122,7 @@ foundry api-integrations create --name "MyApi" --description "desc" --spec /tmp/
127122
foundry collections create --name "my_col" --schema /tmp/my_schema.json --description "desc" --no-prompt
128123

129124
# 3. DEPLOY EARLY — fail fast if specs or schemas are bad
130-
FOUNDRY_FF_ENHANCED_UI=false foundry apps deploy --no-prompt --change-type Patch --change-log "Backend capabilities"
125+
foundry apps deploy --no-prompt --change-type Patch --change-log "Backend capabilities"
131126
# Poll with list-deployments — if still in progress, sleep 5 and retry
132127
# If deploy fails, STOP. Fix the spec/schema — do not build UI on a broken backend.
133128
# The adapt script should handle spec issues. If it didn't, improve the script.
@@ -166,12 +161,12 @@ The CLI scaffolds structure but cannot generate app logic. Delegate to sub-skill
166161
cd ui/pages/my-page && npm install && npm run build && cd ../../..
167162

168163
# Final deploy (run ONCE, never re-deploy to check status)
169-
FOUNDRY_FF_ENHANCED_UI=false foundry apps deploy --no-prompt --change-type Patch --change-log "Complete app"
164+
foundry apps deploy --no-prompt --change-type Patch --change-log "Complete app"
170165

171166
# Poll deployment status — run immediately, do NOT prepend sleep
172-
FOUNDRY_FF_ENHANCED_UI=false foundry apps list-deployments
167+
foundry apps list-deployments
173168
# If still in progress, wait 5s then poll again:
174-
# sleep 5 && FOUNDRY_FF_ENHANCED_UI=false foundry apps list-deployments
169+
# sleep 5 && foundry apps list-deployments
175170

176171
# Local UI development (deploy first if UI calls backend capabilities)
177172
foundry ui run
@@ -181,7 +176,7 @@ foundry ui run
181176

182177
```bash
183178
# Release (run ONCE after deploy succeeds)
184-
FOUNDRY_FF_ENHANCED_UI=false foundry apps release --change-type Patch --deployment-id <id> --notes "Release notes"
179+
foundry apps release --change-type Patch --deployment-id <id> --notes "Release notes"
185180
```
186181

187182
**Note:** There is no `list-releases` command. After `release`, check status via the App Manager URL printed in the output, or wait ~30s and proceed to testing.
@@ -215,7 +210,7 @@ To deploy the same app to multiple clouds (US-1, US-2, EU-1, etc.):
215210

216211
When `manifest.yml` already exists, work is primarily editing existing files. Use CLI only for:
217212
- `foundry apps run` / `foundry ui run` — local development
218-
- `FOUNDRY_FF_ENHANCED_UI=false foundry apps deploy` / `FOUNDRY_FF_ENHANCED_UI=false foundry apps release` — deployment
213+
- `foundry apps deploy` / `foundry apps release` — deployment
219214
- `foundry api-integrations create` etc. — adding new capabilities
220215

221216
## Testing an Existing App Locally
@@ -225,11 +220,11 @@ When running e2e tests against an existing app:
225220
1. **Update manifest name** if needed (to match `APP_NAME` in `e2e/.env`)
226221
2. **Deploy and release:**
227222
```bash
228-
FOUNDRY_FF_ENHANCED_UI=false foundry apps deploy --change-type patch --change-log "e2e testing" --no-prompt
223+
foundry apps deploy --change-type patch --change-log "e2e testing" --no-prompt
229224
# Poll until successful
230-
FOUNDRY_FF_ENHANCED_UI=false foundry apps list-deployments
225+
foundry apps list-deployments
231226
# Release
232-
FOUNDRY_FF_ENHANCED_UI=false foundry apps release --deployment-id <id> --change-type patch --notes "e2e testing" --no-prompt
227+
foundry apps release --deployment-id <id> --change-type patch --notes "e2e testing" --no-prompt
233228
```
234229
3. **Run tests:** `cd e2e && npx playwright test`
235230
4. **Revert manifest:** `git checkout manifest.yml` (deploy writes IDs into the manifest)

skills/foundry-development-workflow/references/headless-operation.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ Commands that prompt for user input support `--no-prompt` to suppress prompts an
5555
|---------|---------------------|
5656
| `foundry apps create` | `foundry apps create --name "app" --description "desc" --no-prompt --no-git` |
5757
| `foundry apps delete` | `foundry apps delete --force-delete --no-prompt` |
58-
| `foundry apps deploy` | `FOUNDRY_FF_ENHANCED_UI=false foundry apps deploy --change-type minor --change-log "description" --no-prompt` |
59-
| `foundry apps release` | `FOUNDRY_FF_ENHANCED_UI=false foundry apps release --deployment-id <id> --change-type minor --notes "notes"` |
58+
| `foundry apps deploy` | `foundry apps deploy --change-type minor --change-log "description" --no-prompt` |
59+
| `foundry apps release` | `foundry apps release --deployment-id <id> --change-type minor --notes "notes"` |
6060
| `foundry profile create` | `foundry profile create --name <n> --api-client-id <id> --api-client-secret <s> --cid <c> --cloud-region <r> --no-prompt` |
6161
| `foundry profile activate` | `foundry profile activate --name "profile-name"` |
6262
| `foundry profile delete` | `foundry profile delete --name "profile-name" --no-prompt` |
@@ -85,12 +85,12 @@ Error: could not open a new TTY: open /dev/tty: device not configured
8585

8686
or hang and produce garbled output.
8787

88-
**Fix: Always prepend `FOUNDRY_FF_ENHANCED_UI=false`** to commands that trigger the TUI:
88+
**Fix:** The plugin's SessionStart hook sets `FOUNDRY_UI_HEADLESS_MODE=true` automatically for all Bash commands. If running outside the plugin (CI/CD, scripts), set the env var manually:
8989

9090
```bash
91-
FOUNDRY_FF_ENHANCED_UI=false foundry apps deploy --change-type Patch --change-log "description"
92-
FOUNDRY_FF_ENHANCED_UI=false foundry apps release --deployment-id <id> --change-type Patch --notes "notes"
93-
FOUNDRY_FF_ENHANCED_UI=false foundry apps list-deployments
91+
foundry apps deploy --change-type Patch --change-log "description"
92+
foundry apps release --deployment-id <id> --change-type Patch --notes "notes"
93+
foundry apps list-deployments
9494
```
9595

9696
This disables the TUI progress monitor and falls back to plain text output suitable for non-interactive environments.
@@ -115,7 +115,7 @@ When operating as a CLI agent:
115115
3. **Never run `foundry login` without user confirmation:** The browser flow will hang in headless environments
116116
4. **Always pass all required flags:** Never rely on interactive prompts — always include `--no-prompt` where supported
117117
5. **Use `--no-git` on `foundry apps create`:** Prevents git init prompts in environments where git may not be configured
118-
6. **Prepend `FOUNDRY_FF_ENHANCED_UI=false`** to `deploy`, `release`, and `list-deployments` commands to disable the TUI progress monitor
118+
6. **`FOUNDRY_UI_HEADLESS_MODE=true`** is set automatically by the plugin's SessionStart hook. For standalone scripts/CI, export it manually.
119119

120120
## Counter-Rationalizations for Interactive Mode
121121

skills/foundry-ui-development/references/advanced-patterns.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040

4141
```bash
4242
# For apps with backend dependencies: deploy first, then iterate on UI
43-
FOUNDRY_FF_ENHANCED_UI=false foundry apps deploy --change-type Patch --change-log "Initial deployment" --no-prompt
43+
foundry apps deploy --change-type Patch --change-log "Initial deployment" --no-prompt
4444
foundry ui run
4545

4646
# For pure UI work (no API integration/collection/function calls): no deploy needed

0 commit comments

Comments
 (0)