GitSpace has been renamed and moved to a new home:
Please use the new repository for:
- Installation
- Issues and bug reports
- Pull requests and contributions
- Documentation
# Install from the new repo
npm install -g gitspaceOriginal README (archived)
A powerful CLI tool for managing GitHub repository workspaces using git worktrees and optional Linear integration. Work on multiple features/tasks simultaneously, each in its own isolated workspace. Features an interactive TUI and support for repo config bundles for team onboarding.
- Interactive TUI: Beautiful terminal interface for managing projects and workspaces
- Git Worktrees: Work on multiple branches simultaneously without stashing
- Linear Integration: Create workspaces directly from Linear issues with automatic markdown documentation
- Smart Branch Management: Automatic detection of remote branches
- Workspace Status: Track uncommitted changes, stale workspaces, and more
- Custom Scripts: Convention-based scripts for setup, select, pre-setup, and removal phases
- Repo Config Bundles: Share onboarding configurations with your team, including scripts and setup steps
- Secure Secrets: Store sensitive values in OS keychain via Bun.secrets
The following tools must be installed and available in your PATH:
- GitHub CLI (
gh) - for listing repositories - Git - for worktree management
- jq - for JSON processing
- Bun - runtime for the CLI
GitHub Authentication: You must authenticate the GitHub CLI before using Spaces:
gh auth loginbun install -g https://github.com/bradleat/spaces
# Verify installation
spaces --versionSimply run spaces with no arguments to launch the interactive TUI:
spacesThe TUI provides a two-panel interface:
- Left panel: Your projects
- Right panel: Workspaces in the selected project
Key Bindings:
| Key | Action |
|---|---|
Enter |
Select project / Open workspace |
Tab |
Switch between panels |
n |
New project / workspace |
d |
Delete selected item |
? |
Show help |
q |
Quit |
You can also use traditional CLI commands:
spaces add projectSelect a GitHub repository, and Spaces will:
- Clone the repository to
~/spaces/<project-name>/base - Detect the default branch
- Run onboarding steps if a bundle is present
- Create project configuration
# Create a workspace from a Linear issue (if configured)
spaces add
# Or create a workspace with a custom name
spaces add my-feature# Interactive selection
spaces switch
# Switch to a specific workspace
spaces switch my-featureRepo config bundles allow repository owners to share onboarding configurations with their team. When someone clones a project that contains a bundle, they'll be guided through setup steps and have scripts automatically installed.
A bundle is a directory (typically .spaces-config/) containing:
.spaces-config/
├── spaces-bundle.json # Bundle manifest with onboarding steps
├── pre/ # Scripts to run before setup
│ └── 01-copy-env.sh
├── setup/ # Scripts to run on first workspace creation
│ └── 01-install-deps.sh
├── select/ # Scripts to run every time workspace is opened
│ └── 01-status.sh
└── remove/ # Scripts to run before workspace deletion
└── 01-cleanup.sh
{
"version": "1.0",
"name": "my-app-bundle",
"description": "Setup bundle for my-app",
"onboarding": [
{
"id": "welcome",
"type": "info",
"title": "Welcome",
"description": "Let's get you set up!"
},
{
"id": "node",
"type": "confirm",
"title": "Node.js",
"description": "Node.js 18+ is required",
"checkCommand": "node",
"installUrl": "https://nodejs.org"
},
{
"id": "api-key",
"type": "secret",
"title": "API Key",
"description": "Enter your API key",
"configKey": "apiKey"
},
{
"id": "team-name",
"type": "input",
"title": "Team Name",
"description": "Enter your team name",
"configKey": "teamName",
"defaultValue": "engineering"
}
]
}| Type | Purpose | Storage |
|---|---|---|
info |
Display information | N/A |
confirm |
Verify installation (can check command in PATH) | N/A |
secret |
Collect sensitive values (masked input) | OS Keychain |
input |
Collect plain text values | Project config |
Bundle values are passed to scripts as environment variables:
SPACE_VALUE_<KEY>- Regular values from input stepsSPACE_SECRET_<KEY>- Secret values from secret steps (fetched from OS keychain)
Example script:
#!/bin/bash
# .spaces-config/select/01-status.sh
WORKSPACE_NAME=$1
REPOSITORY=$2
# Access bundle values
if [ -n "$SPACE_VALUE_TEAMNAME" ]; then
echo "Welcome, $SPACE_VALUE_TEAMNAME team!"
fi
# Access secrets (stored securely in OS keychain)
if [ -n "$SPACE_SECRET_APIKEY" ]; then
echo "API Key configured"
fiBundles can be loaded from:
- In-repo (automatic):
.spaces-config/,spaces-config/, or.spaces/in the cloned repository - Local path:
spaces add project --bundle-path /path/to/bundle/ - Remote URL:
spaces add project --bundle-url https://example.com/bundle.zip
Launch the interactive terminal UI.
Add a new project from GitHub.
spaces add project [options]
Options:
--bundle-url <url> Load bundle from remote URL (zip archive)
--bundle-path <path> Load bundle from local directory
--skip-bundle Skip bundle detection and onboarding
--no-clone Create project structure without cloning
--org <org> Filter repos to specific organization
--linear-key <key> Provide Linear API key via flagCreate a new workspace in the current project.
spaces add [workspace-name] [options]
Options:
--branch <name> Specify different branch name from workspace name
--from <branch> Create from specific branch instead of base
--no-setup Skip setup commandsSwitch to a workspace in the current project.
spaces switch [workspace-name]
# Alias: spaces swSwitch to a different project.
List projects or workspaces.
spaces list [subcommand] [options]
# Alias: spaces ls
Subcommands:
projects List all projects
workspaces List workspaces in current project (default)
Options:
--json Output in JSON format
--verbose Show additional detailsRemove a workspace.
spaces remove workspace [workspace-name] [options]
# Alias: spaces rm workspace
Options:
--force Skip confirmation prompts
--keep-branch Don't delete git branch when removing workspaceRemove a project.
spaces remove project [project-name] [options]
# Alias: spaces rm project
Options:
--force Skip confirmation promptsPrint the current project directory path.
spaces directory
# Alias: spaces dirLocated at ~/spaces/.config.json:
{
"currentProject": "my-app",
"projectsDir": "/Users/username/spaces",
"defaultBaseBranch": "main",
"staleDays": 30
}Located at ~/spaces/<project-name>/.config.json:
{
"name": "my-app",
"repository": "myorg/my-app",
"baseBranch": "main",
"linearApiKey": "lin_api_...",
"linearTeamKey": "ENG",
"bundleValues": {
"teamName": "engineering"
},
"bundleSecretKeys": ["apiKey"],
"appliedBundle": {
"name": "my-app-bundle",
"version": "1.0",
"source": "/path/to/bundle",
"appliedAt": "2025-01-01T00:00:00Z"
}
}bundleValues: Values collected from input steps during onboardingbundleSecretKeys: Keys of secrets stored in OS keychain (values are NOT stored in config)appliedBundle: Information about the bundle that was applied
Spaces uses convention over configuration for custom scripts:
~/spaces/<project-name>/scripts/
├── pre/ # Run before setup (terminal)
├── setup/ # Run once on workspace creation
├── select/ # Run every time workspace is opened
└── remove/ # Run before workspace deletion
- Scripts must be executable (
chmod +x) - Scripts run alphabetically (use
01-,02-prefixes) - Working directory: The workspace directory
- Arguments:
$1= workspace name,$2= repository name - Environment: Bundle values available as
SPACE_VALUE_*andSPACE_SECRET_*
| Phase | When | Use Case |
|---|---|---|
pre/ |
Once, before setup | Copy .env files, create directories |
setup/ |
Once, on workspace creation | Install dependencies, initial build |
select/ |
Every workspace open | Git fetch, status checks |
remove/ |
Before deletion | Cleanup, notifications |
# Set the current project (overrides global config)
export SPACES_CURRENT_PROJECT="my-app"
# Available in scripts (from bundle onboarding):
# SPACE_VALUE_<KEY> - Regular values
# SPACE_SECRET_<KEY> - Secret values (from OS keychain)~/spaces/
├── .config.json # Global configuration
├── <project-name>/
│ ├── .config.json # Project configuration
│ ├── base/ # Base repository clone
│ ├── workspaces/ # Git worktrees
│ │ └── <workspace-name>/
│ │ ├── .spaces-setup # Setup completion marker
│ │ └── .prompt/ # Linear issue details (if applicable)
│ │ └── issue.md
│ └── scripts/ # Custom scripts
│ ├── pre/
│ ├── setup/
│ ├── select/
│ └── remove/
Error: GitHub CLI is not authenticated
Solution: Run gh auth login and follow the prompts.
Solution: Install the missing dependencies using the provided URLs in the error message.
If SPACE_SECRET_* variables are empty, ensure:
- You completed the onboarding secret steps
- Your OS keychain service is running (libsecret on Linux, Keychain on macOS)
# Install dependencies
bun install
# Development mode
bun run dev
# Type checking
bun run typecheck
# Run linter
bun run lintMIT
Contributions are welcome! Please feel free to submit a Pull Request.