Coding agents are great at taking a feature end to end inside a single repo. But most real projects aren't one repo. You've got a frontend, a few backend services, maybe a shared lib and some infra. A feature that touches all of them means coordinated branches, shared context for the agent, and some way to verify across the stack.
This post covers the workspace setup we use to make that work.
The problem
When a feature touches multiple repos, you need three things:
- The agent needs to understand the architecture across all of them. How services connect, coding standards, what depends on what.
- Coordinated branches. The same feature branch in every repo that's part of the change.
- Cross-repo verification. Run tests, check status, validate across the stack, not just within one checkout.
In a single repo, agents handle all of this naturally. Across repos, you're manually configuring context per repo, creating branches one at a time, and switching between terminals to verify.
The workspace structure
Mars creates a workspace where all repos live under one tree:
workspace/
├── .claude/ # or .cursor/, .aider.conf
├── CLAUDE.md # shared context: architecture, standards, patterns
├── mars.yaml # workspace definition
└── repos/
├── backend-api/
├── frontend-app/
├── shared-lib/
└── infra/
Agent config at the workspace root gets inherited by every repo. You configure your agent once and every repo gets that context automatically. No per-repo duplication.
What a day looks like
Morning sync:
mars sync # pull latest across all repos
mars status # one table: every repo's branch, dirty state, ahead/behind
Starting a feature:
mars branch feature-auth --tag backend # coordinated branch across backend repos
The agent already has full architectural context from the workspace-level config. It knows how the services relate and what patterns to follow, across all repos.
The agent implements the feature across repos on the same branch, seeing shared config and understanding how things connect.
Verification:
mars exec "npm test" --tag frontend # targeted tests
mars status # which repos changed? any drift?
Review and merge using standard git/GitHub tooling. Mars coordinates the workspace. The rest of the workflow is unchanged.
The workspace repo pattern
Something that falls out of this structure naturally: the workspace itself can be a git repo.
git clone git@github.com:org/platform-workspace.git
cd platform-workspace
mars clone # clones all repos defined in mars.yaml
# done
You version-control mars.yaml and your agent config together. Push it to GitHub. Any developer or CI job clones that one repo, runs mars clone, and has the full workspace in two commands.
- Team onboarding: new developer is productive in minutes, not hours.
- CI environments: same two commands to set up cross-repo verification.
- Standardization: one source of truth for which repos belong together and how agents should operate across them. Reviewed through normal PRs.
You get the shared context and reproducibility of a monorepo without coupling git histories, CI pipelines, or release cycles.
Tag-based filtering
Every repo in mars.yaml gets tags:
repos:
- url: git@github.com:org/frontend.git
tags: [frontend, web]
- url: git@github.com:org/backend-api.git
tags: [backend, api, payments]
- url: git@github.com:org/shared-lib.git
tags: [shared, backend, frontend]
Every command supports --tag to target subsets:
mars branch feature-x --tag backend # branch only backend repos
mars exec "npm test" --tag frontend # test only frontend repos
mars status --tag payments # status for payments-related repos
Multiple tags per repo enable cross-cutting operations. A repo tagged [backend, payments] shows up in both --tag backend and --tag payments queries. Tag by function, by team, by deployment group, whatever matches how your team thinks about the codebase.
How it compares to existing tools
Mars isn't the first multi-repo tool:
| Tool | Language | Config | Approach |
|---|---|---|---|
| git submodules | git-native | .gitmodules | Couples repos at git level, tracks specific commits |
| gita | Python | CLI-based | Group and manage repos, requires Python |
| myrepos | Perl | .mrconfig | Config-file driven, powerful but complex |
| meta | Node | meta.json | JSON config, plugin system |
| Mars | Bash | mars.yaml | Tag-based filtering, zero deps, workspace-as-agent-config |
Mars trades extensibility and plugin systems for zero dependencies. The main differentiator is design intent: Mars creates a workspace structure where agent config sharing is a natural property of the layout. Other tools manage repos. Mars creates a workspace that agents can work in.
Under the hood
Mars targets bash 3.2+ because macOS still ships bash 3.2 (GPLv2, Apple won't upgrade to GPLv3). This means zero install friction on any Mac, but it comes with real constraints.
No associative arrays. Bash 3.2 doesn't have declare -A. Mars uses parallel indexed arrays instead:
YAML_REPO_URLS[0]="git@github.com:org/frontend.git"
YAML_REPO_PATHS[0]="frontend"
YAML_REPO_TAGS[0]="frontend,web"
YAML_REPO_URLS[1]="git@github.com:org/backend.git"
YAML_REPO_PATHS[1]="api"
YAML_REPO_TAGS[1]="backend,api"
Index 0 across all arrays is one "record." It's ugly, but it works without any bash 4+ features.
Tag filtering uses string matching on comma-separated values:
[[ ",$tags," == *",$filter_tag,"* ]]
Simple, handles every real-world case. The comma wrapping avoids partial matches.
Terminal UI does Clack-style Unicode spinners (◒◐◓◑), box drawing characters (┌│└), and color output with an ASCII fallback. All in pure bash.
Parallel operations use bash job control (& and wait -n), capped at 4 concurrent jobs.
Single-file distribution: a build script concatenates 13 source files (~1200 lines) from lib/ into one executable. Install with curl, no build step needed.
Getting started
# Install
npm install -g @dean0x/mars
# Or: brew install dean0x/tap/mars
# Or: curl -fsSL https://raw.githubusercontent.com/dean0x/mars/main/install.sh | bash
# Create a workspace
mars init
mars add https://github.com/org/frontend.git --tags frontend
mars add https://github.com/org/backend.git --tags backend
mars clone
mars status
Full docs on GitHub: github.com/dean0x/mars
Website: dean0x.github.io/x/mars
Wrapping up
Mars is for teams that want independent repos but need a coherent workspace for feature development with coding agents. It creates the structure, coordinates git operations, and gets out of the way.
When to reach for it: multiple repos, coding agents in your workflow, need for shared context and coordinated operations.
When not to: tightly coupled repos (use submodules), single repo (just use git), need Windows support.
Open source, MIT licensed. Would love to hear how others are setting up workspaces for coding agents across repos.
Top comments (2)
The context file idea changed everything for me. Wish I'd started doing this a year ago instead of fighting the model.
Yeah configuring your agent takes things to the next level, same here.