Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Changelog

## [0.1.1] - 2026-02-19

### Changed
- Install script now downloads from GitHub Releases instead of raw.githubusercontent.com
- README overhaul with demo GIF, badges, and restructured content

### Added
- CONTRIBUTING.md with development and architecture documentation
- CHANGELOG.md
- VHS demo tape for recording demo GIFs
- Launch materials

## [0.1.0] - 2026-02-16

### Added
- Workspace initialization (`mars init`)
- Repository management (`add`, `clone`, `list`)
- Git operations (`status`, `branch`, `checkout`, `sync`)
- Cross-repo command execution (`mars exec`)
- Tag-based filtering for all operations
- Parallel cloning (4 concurrent jobs)
- Shared Claude configuration (`claude.md`, `.claude/`)
- Clack-style terminal UI with Unicode/ASCII fallback
- Distribution via npm, Homebrew, and curl installer
130 changes: 130 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Contributing to Mars

## Development Setup

Clone the repo and run directly in development mode:

```bash
git clone https://github.com/dean0x/mars.git
cd mars
./mars init # Sources from lib/ directory
```

## Project Structure

```
mars/
├── mars # Main CLI entry point
├── lib/
│ ├── ui.sh # Terminal UI (colors, spinners, prompts, tables)
│ ├── yaml.sh # mars.yaml parser
│ ├── config.sh # Workspace detection and config loading
│ ├── git.sh # Git wrapper with output capture
│ └── commands/ # Command implementations
│ ├── init.sh
│ ├── clone.sh
│ ├── status.sh
│ ├── branch.sh
│ ├── checkout.sh
│ ├── sync.sh
│ ├── exec.sh
│ ├── add.sh
│ └── list.sh
├── build.sh # Build bundled distribution
├── install.sh # Curl installer
├── dist/ # Bundled distribution (committed)
└── test/ # Test suite
```

## Architecture

### Two Operating Modes

- **Development**: `./mars` sources files from `lib/` subdirectories
- **Distribution**: `dist/mars` is a single bundled file with all code inlined

### Key Patterns

**Output Capture** — Git operations capture output in globals:

```bash
GIT_OUTPUT=""
GIT_ERROR=""
if git_clone "$url" "$path"; then
# success: use GIT_OUTPUT
else
# failure: use GIT_ERROR
fi
```

**Bash 3.2 Compatibility** — No associative arrays; uses parallel indexed arrays:

```bash
YAML_REPO_URLS=()
YAML_REPO_PATHS=()
YAML_REPO_TAGS=()
```

**Tag Filtering** — Comma-separated tags with string matching:

```bash
[[ ",$tags," == *",$filter_tag,"* ]]
```

**Command Pattern** — Each command is `cmd_<name>()` in its own file under `lib/commands/`.

### Implementation Constraints

- Bash 3.2+ (macOS default) — no associative arrays, no `readarray`
- Return exit codes, never throw (bash has no exceptions)
- Avoid subshells where possible (breaks global variable updates)
- Check return codes explicitly and propagate errors
- Use `ui_step_error()`/`ui_step_done()` for user feedback
- Parallel operations limited to 4 concurrent jobs (`CLONE_PARALLEL_LIMIT`)

## Running Tests

```bash
bash test/test_yaml.sh
bash test/test_config.sh
bash test/test_integration.sh
```

Tests use `/tmp/claude/` for temporary files.

## Building

```bash
./build.sh # Output: dist/mars
```

**Important:** `dist/mars` is committed to the repo for easy installation. Always run `./build.sh` before committing changes to source files.

## Pull Requests

- Run all tests before submitting
- Run `./build.sh` and include the updated `dist/mars`
- Maintain bash 3.2 compatibility (test on macOS if possible)
- Follow existing code patterns (output capture, parallel arrays, command pattern)

## Release Process

1. Update version in `package.json`
2. Commit: `git commit -am "Bump version to X.Y.Z"`
3. Tag: `git tag vX.Y.Z`
4. Push: `git push origin main --tags`

CI automatically handles:

- Run tests
- Verify tag version matches `package.json`
- Create GitHub Release with `dist/mars` binary attached
- Publish to npm (`@dean0x/mars`)
- Update Homebrew formula (`dean0x/tap/mars`)

### Required Secrets (Maintainers)

| Secret | Repository | Purpose |
|--------|------------|---------|
| `NPM_TOKEN` | mars | npm publish access token |
| `HOMEBREW_TAP_TOKEN` | mars | PAT with repo scope for homebrew-tap workflow |
155 changes: 60 additions & 95 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,83 +1,46 @@
# Mars CLI
# Mars

Multi Agentic Repo workspace manager for git repositories with shared Claude configuration.
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![npm](https://img.shields.io/npm/v/@dean0x/mars)](https://www.npmjs.com/package/@dean0x/mars)
[![CI](https://github.com/dean0x/mars/actions/workflows/ci.yml/badge.svg)](https://github.com/dean0x/mars/actions/workflows/ci.yml)

## Features
Manage multiple Git repositories as one workspace.

- Manage multiple git repos as a unified workspace
- Shared `claude.md` and `.claude/` config across repos
- Tag-based repo filtering for targeted operations
- Parallel cloning with rate limiting
- Works with bash 3.2+ (macOS compatible)
Tag-based filtering, parallel operations, shared Claude configuration.

## Installation

### npm (recommended)

```bash
npm install -g @dean0x/mars
```

Or run without installing:

```bash
npx @dean0x/mars --help
```
<p align="center">
<img src="demo.gif" alt="Mars CLI demo" width="800" />
</p>

### Homebrew (macOS/Linux)
## Why Mars?

```bash
brew install dean0x/tap/mars
```
- **Polyrepo without the pain** — one CLI for status, branching, syncing across all repos
- **Tag-based filtering** — target subsets of repos (`--tag frontend`, `--tag backend`)
- **Shared Claude config** — `claude.md` and `.claude/` directory shared across repos
- **Zero dependencies** — pure bash 3.2+, works on macOS out of the box

### Shell Script
## Quick Install

```bash
curl -fsSL https://raw.githubusercontent.com/dean0x/mars/main/install.sh | bash
npm install -g @dean0x/mars
```

### Manual

```bash
git clone https://github.com/dean0x/mars.git
cd mars
./build.sh
cp dist/mars ~/.local/bin/ # or anywhere in PATH
```
See [all installation methods](#installation) for Homebrew, curl, and manual options.

## Quick Start

```bash
# Create a new workspace
mkdir my-project && cd my-project
mars init

# Add repositories
mars add git@github.com:org/frontend.git --tags frontend,web
mars add git@github.com:org/backend.git --tags backend,api
mars add git@github.com:org/shared.git --tags shared
mars add https://github.com/dean0x/mars-example-frontend.git --tags frontend,web
mars add https://github.com/dean0x/mars-example-backend.git --tags backend,api
mars add https://github.com/dean0x/mars-example-shared.git --tags shared

# Clone all repos
mars clone

# Check status
mars status
```

## Workspace Structure

```
my-project/
├── mars.yaml # Workspace configuration
├── claude.md # Shared Claude config (optional)
├── .claude/ # Shared Claude folder (optional)
├── .gitignore # Contains 'repos/'
└── repos/ # Cloned repositories (gitignored)
├── frontend/
├── backend/
└── shared/
```

## Commands

| Command | Description |
Expand Down Expand Up @@ -128,62 +91,64 @@ defaults:
branch: main
```

## Development

### Project Structure
## Workspace Structure

```
mars/
├── mars # Main CLI entry point
├── lib/
│ ├── ui.sh # Terminal UI components
│ ├── yaml.sh # YAML parser
│ ├── config.sh # Config management
│ ├── git.sh # Git operations
│ └── commands/ # Command implementations
├── build.sh # Build distribution
├── install.sh # Installer script
└── test/ # Test suite
my-project/
├── mars.yaml # Workspace configuration
├── claude.md # Shared Claude config (optional)
├── .claude/ # Shared Claude folder (optional)
├── .gitignore # Contains 'repos/'
└── repos/ # Cloned repositories (gitignored)
├── frontend/
├── backend/
└── shared/
```

## Installation

### npm (recommended)

```bash
npm install -g @dean0x/mars
```

### Running Tests
Or run without installing:

```bash
# Run all tests
bash test/test_yaml.sh
bash test/test_config.sh
bash test/test_integration.sh
npx @dean0x/mars --help
```

### Building
### Homebrew (macOS/Linux)

```bash
./build.sh # Output: dist/mars
brew install dean0x/tap/mars
```

**Important:** `dist/mars` is committed for easy installation. Always run `./build.sh` before committing changes to source files.
### Shell Script

```bash
curl -fsSL https://raw.githubusercontent.com/dean0x/mars/main/install.sh | bash
```

## Releasing
Install a specific version:

Releases are automated via GitHub Actions. To create a release:
```bash
MARS_VERSION=0.1.1 curl -fsSL https://raw.githubusercontent.com/dean0x/mars/main/install.sh | bash
```

1. Update version in `package.json`
2. Commit the change
3. Create and push a tag: `git tag v0.1.1 && git push origin v0.1.1`
### Manual

The CI will automatically:
- Run tests
- Verify the tag version matches `package.json`
- Create a GitHub Release with auto-generated notes
- Publish to npm
- Update the Homebrew formula
```bash
git clone https://github.com/dean0x/mars.git
cd mars
./build.sh
cp dist/mars ~/.local/bin/ # or anywhere in PATH
```

### Required Secrets (for maintainers)
## Contributing

| Secret | Repository | Purpose |
|--------|------------|---------|
| `NPM_TOKEN` | mars | npm publish access token |
| `HOMEBREW_TAP_TOKEN` | mars | PAT with repo scope to trigger homebrew-tap workflow |
See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, architecture, and release process.

## License

Expand Down
2 changes: 1 addition & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ cat > "$OUTPUT_FILE" << 'HEADER'

set -euo pipefail

MARS_VERSION="0.1.0"
MARS_VERSION="0.1.1"

HEADER

Expand Down
Loading