Skip to content

About

Run multiple Cloud Foundry CLI sessions and targets in parallel without CF_HOME conflicts. Isolate API, org, space, and auth per project or Git worktree.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

cfs: isolated Cloud Foundry CLI contexts

CI Release License

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.

Two projects keeping independent Cloud Foundry targets

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.

Quick start

Install the official CF CLI, then install cfs with Go 1.26.10+:

go install github.com/zongqichen/cloud-foundry-cli-contexts/cmd/cfs@latest
cfs setup

Prebuilt 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.

From a project, log in normally if you do not have a saved global login:

cd ~/work/orders
cf login --sso -a https://api.example.com -o commerce -s development
cf apps

Another project or Git worktree receives a separate context automatically. Terminals and agents in the same worktree intentionally share its default context. A fresh default context can reuse your existing login.

Updating

Check for a newer published release without changing the installed binary:

cfs update

For 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 doctor

Successful 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.

Multiple targets in one project

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 apps

Each 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.

Existing login

An ordinary managed cf command can copy your saved global API and authentication configuration into the workspace's fresh default context without prompting. This happens only when its managed .cf/config.json is absent while the shim holds the context lock and the global configuration has a nonblank API Target. The copy clears the organization and space, so choose them in the workspace:

cd ~/work/orders
cf target -o commerce -s development

The shim skips automatic copying if it finds an existing workspace configuration while holding the context lock, even if the configuration has no API target. Named invocations such as cfs -c prod ... require explicit import or login.

To copy the global organization and space as well, run cfs import in the workspace. To import into a named context, create the context first:

cfs context create prod
cfs import --context prod

Explicit import requires confirmation or --yes for non-interactive automation. Use --force to replace an existing target. Unset CF_HOME before importing. Both modes require a valid, private global configuration file and leave it unchanged. Each copy is an independent snapshot that may contain credentials. Token refreshes and later target changes do not synchronize between contexts. A saved API target does not establish that the copied login is still valid.

Coding agents

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. To pin the workspace regardless of the agent's working directory, set CFS_WORKSPACE_ROOT; to run one command against the global target, use cfs global <cf ...>. For diagnostics safe to attach to agent logs, use:

cfs describe --json
cfs status --json --redact
cfs context status prod --json --redact

cfs describe --json is the one-call self-discovery surface: version, exit-code contract, environment variables, workspace resolution, and the contexts in the current workspace. It never invokes cf. The state-changing commands (cfs context create / remove, cfs import, cfs reset) also accept --json and print a structured result for the agent to parse. cfs context list --targets --json lists every context with its api/org/space in one call. For throwaway or parallel work, cfs context create --ephemeral mints a uniquely named context that cfs gc reaps once it has been idle past CFS_EPHEMERAL_TTL (default 24h).

The 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 cfs

To 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.

How it works

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 = 1

Alternatively, select a workspace for one command:

CFS_WORKSPACE_ROOT=/workspace cf apps

An explicit CF_HOME bypasses workspace management unless CFS_WORKSPACE_ROOT is set. Without a workspace or an explicit bypass, cfs refuses to fall back to the global CF home.

Commands

cfs setup           Install the transparent cf shim
cfs status          Show the current workspace and target
cfs describe        Print the cfs contract (version, exit codes, env, contexts)
cfs context         Create, list, inspect, or remove named contexts
cfs global          Run one cf command against the global target
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. cfs doctor checks local configuration and workspace state. It does not verify a live CF login.

Entered the wrong workspace, or need to log in somewhere else for a moment? Run one command against the global target without leaving the directory:

cfs global login --sso
cfs global target

This is the discoverable form of CFS_DISABLE=1 cf .... cfs collects no telemetry. Workspace state and recoverable trash can contain active tokens; see Security.

Development

make check
make security
make release-check
make smoke
make agent-smoke
CFS_REAL_CF=/path/to/official/cf make e2e

See testing, design, the changelog, and the release guide. Contributions are welcome; read CONTRIBUTING.md. Licensed under Apache-2.0, like the official CF CLI.

About

Run multiple Cloud Foundry CLI sessions and targets in parallel without CF_HOME conflicts. Isolate API, org, space, and auth per project or Git worktree.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages