Skip to content

Workspaces

A workspace is a saved configuration that tells jackin’ how to mount your project directories into an agent container. Instead of typing long mount paths every time, you save a project boundary once and reference it by name.

A workspace is not the same thing as a role:

  • workspace = which project files are available
  • role = which tools, plugins, and defaults are installed

That means one workspace can be reused with multiple roles when the file access should stay the same but the runtime profile should differ.

In practice, that is one of the main reasons workspaces exist. They let you preserve the same file boundary while swapping in the role that best matches the work.

The simplest way to use jackin’ is from your project directory:

Terminal window
cd ~/Projects/my-app
jackin load agent-smith

This creates a current-directory workspace that mounts the current directory (~/Projects/my-app) into the container at the same absolute path. The agent sees the exact same directory layout you do.

Loading the current directory is perfect when you are already standing in the project and only need a simple one-directory mount.

Saved workspaces become useful when you want that setup to be reusable and predictable.

They let you:

  • name a project boundary once and launch it from anywhere
  • keep extra mounts consistent across sessions
  • reuse the same project boundary with different specialized roles
  • let the operator console (jackin console) auto-detect and preselect the project
  • set a default role or restrict which roles may use the workspace
  • set a default agent such as claude, codex, amp, kimi, or opencode

If you regularly work on the same project, a saved workspace turns your mount layout into durable operator configuration instead of something you rebuild from memory each time.

For projects you work on regularly, save a workspace:

Terminal window
jackin workspace create my-app --workdir ~/Projects/my-app --mount ~/Projects/my-app

Now you can load agents into it from anywhere:

Terminal window
jackin load agent-smith my-app

Or load a different role into the same workspace:

Terminal window
jackin load the-architect my-app

This is the key pattern to keep in mind: the workspace stays the same because the project boundary stays the same, but the role changes because the job changes. You might use chainargos/frontend-engineer for UI work in the morning and chainargos/backend-engineer for API work in the afternoon, both against the same saved workspace.

The --workdir path sets the container’s cwd when the agent starts. It does not mount anything by itself.

Workspaces can include additional directories beyond the workdir:

Terminal window
jackin workspace create my-app \
--workdir ~/Projects/my-app \
--mount ~/Projects/my-app \
--mount ~/cache:/cache:ro \
--mount ~/shared-libs:/libs:ro

If you need the container layout to differ from your host:

Terminal window
jackin workspace create monorepo \
--workdir /workspace \
--mount ~/src:/workspace

Here, /workspace is the container start path and ~/src:/workspace is the explicit mount that makes it available.

By default, every workspace mount is shared — the host directory is bind-mounted as-is, and any agent that loads the workspace edits the same files you do on the host. That is the right default for most workflows, but it stops working as soon as you want two agents to work on the same project at the same time without stepping on each other.

Setting a mount’s isolation to worktree tells jackin’ to create a per-container git worktree of the host repo and mount that instead of the original directory. Each container gets its own checkout, its own scratch branch, and its own working tree — so concurrent agents no longer share a .git directory.

ModeBehavior
shared (default)Host path bind-mounted as-is.
worktreeA per-container git worktree is created from the host repo. The container sees its own checkout on a scratch branch; refs are still shared with the host repo, so branches the agent creates are visible to you immediately.
cloneA per-container git clone --local is created from the host repo’s current branch. The container has its own .git/ and independent refs; when the host repo has an origin, pushes from the container publish to that remote rather than creating local branches in your host checkout.

Use worktree when you want immediate host-side branch visibility and you trust the agent with the host repo’s .git/. Use clone when you want the same starting branch as the host checkout, but with refs isolated until the agent explicitly pushes.

The --mount-isolation <dst>=<type> flag (repeatable) on jackin workspace create and jackin workspace edit sets isolation per mount destination:

Terminal window
jackin workspace create jackin \
--workdir /workspace/jackin \
--mount ~/projects/jackin:/workspace/jackin \
--mount ~/.cache/jackin/target:/workspace/jackin/target \
--mount-isolation /workspace/jackin=worktree

The agent sees an isolated checkout at /workspace/jackin while target/ is backed by a shared host cache. jackin’ arranges the mounts so the cache mount overlays the corresponding path inside the isolated worktree — the cache then survives across agents even when each agent has its own checkout.

When you exit an agent that was using an isolated mount, jackin’ looks at the per-container checkout and decides what to do automatically:

  • Everything is wrapped up — your work is committed and pushed (or merged on the remote and the branch was deleted), with no stray edits left behind. jackin’ deletes the per-container checkout for you. There is nothing to remember.
  • There is still work to deal with — you have uncommitted edits, or commits that never made it to the remote. jackin’ keeps the checkout exactly as it was and asks what to do: go back into the agent, leave it preserved so you can return later with jackin hardline, or throw the work away.

If you exited non-interactively (no terminal to ask), jackin’ always preserves the checkout and tells you the path on disk plus how to return, inspect it, or discard it.

If a container crashed or was terminated unexpectedly, jackin’ also keeps everything in place — jackin hardline can restart the container so you continue where the agent left off.

For the exact safety policy (which branches count as safe, how the squash-merged-and-pruned case is detected, what the per-mount state file records), see Foreground session finalization in the internals section.

worktree and clone mounts have a few preconditions enforced before materialization:

  • The mount source must be a git repository root (not a subdirectory).
  • The host repo must not be mid-rebase, mid-merge, or mid-cherry-pick.
  • Read-only is not allowed for an isolated mount — a forked working copy must be writable.
  • Sensitive paths (~/.ssh, ~/.aws, etc.) are rejected.
  • Two isolated mounts whose destinations nest (one inside the other) are rejected.

If a precondition is not met, the command fails with a clear error pointing at the offending mount.

To inspect what’s been materialized for a container, use jackin workspace show <name> (the Isolation column shows the effective mode for every mount) or git worktree list on the host repo. If you need the on-disk layout details, see Architecture in the internals section.

Terminal window
jackin workspace list
Terminal window
jackin workspace show my-app
Terminal window
# Change the workdir
jackin workspace edit my-app --workdir ~/Projects/my-app-v2
# Add a mount
jackin workspace edit my-app --mount ~/data:/data:ro
# Remove a mount by its container destination
jackin workspace edit my-app --remove-destination /old-mount
Terminal window
jackin workspace remove my-app

You can limit which roles are allowed to use a workspace:

Terminal window
jackin workspace create secure-api \
--workdir ~/Projects/secure-api \
--allowed-role agent-smith \
--default-role agent-smith
  • --allowed-role — only these roles can load this workspace (repeatable)
  • --default-role — role highlighted first in the operator console picker, and used automatically by CLI context loading when no role is passed
  • --default-agent — default agent used by jackin load unless --agent is passed for that launch; when unset, a single-agent role uses its only runtime and a multi-agent role asks

This is especially useful when one workspace should only be used with a very specific tool profile, such as a production-infra role or a security-review role.

Terminal window
# Grant access to another role
jackin workspace edit secure-api --allowed-role the-architect
# Revoke access
jackin workspace edit secure-api --remove-allowed-role the-architect
# Change default role
jackin workspace edit secure-api --default-role neo
# Clear the default role
jackin workspace edit secure-api --clear-default-role
# Change default agent
jackin workspace edit secure-api --default-agent codex
# Clear default agent back to role-based launch resolution
jackin workspace edit secure-api --clear-default-agent

Long-running agent work — large builds, test suites, dataset pulls — can outlast your screen-saver and the host’s idle-sleep timer. macOS will then suspend the machine and the agent stops making progress until you wake it up.

Workspaces can opt in to a per-workspace keep-awake reconciler that prevents this. While any agent in any keep-awake workspace is running, jackin’ keeps a single caffeinate -imsu process alive in the background; when the last keep-awake agent stops, jackin’ releases it.

Other workspaces (those without the flag) are unaffected: their containers do not contribute to the keep-awake count, and the host is free to sleep if no opted-in agent is running.

You can opt in (or out) from the CLI or the operator console.

CLI — paired flags on workspace create and workspace edit:

Terminal window
# Opt in at creation time
jackin workspace create my-app --workdir ~/Projects/my-app --mount ~/Projects/my-app --keep-awake
# Toggle on an existing workspace
jackin workspace edit my-app --keep-awake
jackin workspace edit my-app --no-keep-awake

--keep-awake and --no-keep-awake are mutually exclusive. Omit both for “no change.”

Operator console — the General tab of the workspace editor has a Keep awake row. Press Space to toggle it; the change persists when you save the workspace.

jackin workspace show <name> surfaces a Keep Awake: enabled (macOS only) row when the flag is on, so you can confirm at a glance which workspaces are holding power assertions.

When you open a workspace, your local branches may have drifted behind their remotes. The git-pull-on-entry toggle runs git pull on every mounted git repository from the host before the agent container starts — so the agent always sees the latest committed code without you needing to remember a manual pull first.

Failures are non-fatal: if a pull fails (offline, uncommitted changes, protected branch, etc.) jackin’ prints a warning and continues the launch. The workspace remains fully usable — the toggle is a convenience, not a gate.

CLI — paired flags on workspace create and workspace edit:

Terminal window
# Opt in at creation time
jackin workspace create my-app --workdir ~/Projects/my-app --mount ~/Projects/my-app --git-pull
# Toggle on an existing workspace
jackin workspace edit my-app --git-pull
jackin workspace edit my-app --no-git-pull

--git-pull and --no-git-pull are mutually exclusive. Omit both for “no change.”

Operator console — the General tab of the workspace editor has a Git pull row. Press Space to toggle it; the change persists when you save the workspace.

jackin workspace show <name> surfaces a Git Pull: on entry row when the flag is on.

When you open the operator console (jackin console), it checks whether your current directory falls under a saved workspace’s host workdir or one of its mounted host paths. If it does, that workspace is preselected — saving you a selection step and reinforcing the value of naming project boundaries once. Container-only workdir values like /workspace can still be auto-detected as long as one of the workspace’s mounted host paths contains your current directory. You can always override the preselection by choosing a different workspace or “Current directory.”