Run multiple Cloud Foundry CLI sessions and targets in parallel without
CF_HOME conflicts.
The official cf CLI keeps its active API, organization, space, and
authentication state in $HOME/.cf, so changing the target in one terminal
changes it everywhere. cfs gives each project or Git worktree an isolated
CF_HOME while preserving the normal cf command. Optional named contexts let
one project use several targets without a shared current selection.
The demo runs the real cfs shim with a local, credential-free CF fixture.
View the source.
Already using environment variables or another context manager?
Compare cfs with manual CF_HOME, cf-targets-plugin, and cfctx.
Install the official CF CLI, then install
cfs with Go 1.26.8+:
go install github.com/zongqichen/cloud-foundry-cli-contexts/cmd/cfs@latest
cfs setupPrebuilt binaries support Linux and macOS on x86-64 and arm64. Put the shim
directory printed by cfs setup first on PATH, open a new shell, and run
cfs doctor.
Now log in normally from each project:
cd ~/work/orders
cf login --sso -a https://api.example.com -o commerce -s development
cf appsAnother project or Git worktree receives a separate context automatically. Terminals and agents in the same worktree intentionally share its default context.
Check for a newer published release without changing the installed binary:
cfs updateFor scripts and coding agents, use cfs update --json. When an update is
available, follow the printed command or update through the same installation
channel. A Go installation can be updated with:
go install github.com/zongqichen/cloud-foundry-cli-contexts/cmd/cfs@latest
cfs setup
cfs doctorSuccessful interactive cfs control commands check at most once every 24 hours
and show one notice per new version. Checks never run from the transparent cf
shim, JSON output, CI, or non-interactive processes. Set
CFS_NO_UPDATE_CHECK=1 to disable notices. Version checks contact only the public
GitHub Releases API and send no Cloud Foundry or workspace data.
The normal cf command always uses the workspace's default context. Create a
named context only when the same workspace needs another independent target:
cfs context create prod
cfs -c prod login --sso -a https://api.example.com -o commerce -s production
cfs -c prod appsEach name has its own CF_HOME and lock. Names are workspace-local and selected
per command; there is no mutable current context to race over. Inspect them
with cfs context list or cfs context status prod --json --redact. Unknown
names fail without creating state.
To copy your current global CF target into a workspace once:
cd ~/work/orders
CFS_DISABLE=1 cf target
cfs importTo import into a named context instead:
cfs context create prod
cfs import --context prodThe import is a private snapshot, not a link. It may contain active credentials.
Use cfs import --yes in non-interactive automation and --force only when you
intend to replace an existing workspace target. cfs never imports credentials
silently.
No agent integration is required. Start Codex, Claude Code, or an IDE agent in
its project or worktree and let it run ordinary cf commands. Give an agent an
exact named command such as cfs -c prod apps when it needs a non-default
target. For diagnostics safe to attach to agent logs, use:
cfs status --json --redact
cfs context status prod --json --redactThe optional cfs Agent Skill teaches agents to discover existing contexts, fail closed on ambiguity, and preserve user authorization. Install it for Codex, Claude Code, or another supported agent:
npx skills add zongqichen/cloud-foundry-cli-contexts --skill cfsTo make invocation explicit, add Use $cfs for Cloud Foundry context selection. to AGENTS.md, or Use /cfs for Cloud Foundry context selection.
to CLAUDE.md.
cf command -> cfs shim -> workspace default CF_HOME -> official cf CLI
cfs -c NAME ... -> cfs -> workspace named CF_HOME -> official cf CLI
cfs setup places a transparent cf shim on PATH. For each invocation, the
shim resolves the current workspace, selects its private state, and delegates to
the official CLI. Named commands take the same path with an explicit context.
Authentication, token refresh, plugins, API calls, signals, and exit codes
remain the official CLI's responsibility.
Git worktrees are detected automatically. For a directory that is not a Git worktree, create this marker at its root:
version = 1Alternatively, select a workspace for one command:
CFS_WORKSPACE_ROOT=/workspace cf appscfs setup Install the transparent cf shim
cfs status Show the current workspace and target
cfs context Create, list, inspect, or remove named contexts
cfs import Import the global context into default or a named context
cfs doctor Diagnose the installation and workspace
cfs reset Move this workspace's state to trash
cfs gc Find stale workspace state
cfs uninstall Remove the shim without deleting state
cfs version Print version information
cfs update Check for a newer published release
cfs help [command] Show help
Run cfs help context for the named-context commands.
Use CFS_DISABLE=1 cf ... to bypass isolation for one command. cfs collects no
telemetry. Workspace state and recoverable trash can contain active tokens; see
Security.
make check
make security
make release-check
make smoke
make agent-smoke
CFS_REAL_CF=/path/to/official/cf make e2eSee testing, design, the changelog, and the release guide. Contributions are welcome; read CONTRIBUTING.md. Licensed under Apache-2.0, like the official CF CLI.
