Skip to content
Open
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
144 changes: 136 additions & 8 deletions docs/cli/repos.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,13 @@ Manage per-repo installations across multiple orgs via a declarative `repos.yaml
| Command | Description |
|---------|-------------|
| `fullsend repos init <org\|owner/repo>` | Generate a repos.yaml manifest by discovering existing installations |
| `fullsend repos install` | Install fullsend on uninstalled manifest repos |
| `fullsend repos install [repos...]` | Install fullsend on uninstalled manifest repos |
| `fullsend repos add <repos...>` | Add repo entries to a repos.yaml manifest |
| `fullsend repos remove <repos...>` | Remove repo entries from a repos.yaml manifest |
| `fullsend repos uninstall <repos...>` | Tear down fullsend from specific repos |
| `fullsend repos status` | Compare manifest against actual repo state |
| `fullsend repos diff` | Show configuration drift between manifest and actual state |
| `fullsend repos sync` | Reconcile configuration drift for installed repos |

## `repos init`

Expand Down Expand Up @@ -73,17 +78,18 @@ Runs in three phases:
```bash
fullsend repos install -f repos.yaml
fullsend repos install --dry-run
fullsend repos install --repo acme/api --repo acme/web
fullsend repos install --direct --concurrency 8
fullsend repos install acme/api acme/web
fullsend repos install "acme/*" --direct --concurrency 8
```

When repos are specified as positional arguments, only those repos are installed. Glob patterns (e.g. `acme/*`) are matched against manifest entries. When no repos are specified, all manifest repos are installed.

### Flags

| Flag | Default | Description |
|------|---------|-------------|
| `-f`, `--manifest` | `repos.yaml` | Path or URL to repos.yaml manifest |
| `--dry-run` | `false` | Preview what would be installed without making changes |
| `--repo` | (all) | Install specific repos only (repeatable) |
| `--skip-mint-check` | `false` | Skip mint URL discovery and org registration (EnsureOrgInMint). Use when orgs are already registered in the mint. |
| `--concurrency` | `4` | Max parallel operations (1-32) |
| `--roles` | `triage,coder,review,fix,retro,prioritize` | Agent roles to install |
Expand All @@ -106,7 +112,7 @@ fullsend repos install -f repos.yaml --dry-run
Install specific repos (orgs already registered):

```bash
fullsend repos install --repo acme/api --repo acme/web --skip-mint-check
fullsend repos install acme/api acme/web --skip-mint-check
```

> **Note:** Without `--skip-mint-check`, `repos install` will register any new
Expand All @@ -121,17 +127,17 @@ Read-only comparison of the `repos.yaml` manifest against actual forge state. Re
```bash
fullsend repos status
fullsend repos status -f path/to/repos.yaml
fullsend repos status --repo owner/repo1 --repo owner/repo2
fullsend repos status --json
fullsend repos status --repo acme/api --repo acme/web
fullsend repos status --repo "acme/*" --json
```

### Flags

| Flag | Short | Default | Description |
|------|-------|---------|-------------|
| `--manifest` | `-f` | `repos.yaml` | Path or HTTPS URL to manifest file |
| `--repo` | | | Filter to specific repos (repeatable, supports globs) |
| `--json` | | `false` | Emit JSON output instead of table |
| `--repo` | | | Filter to specific repos (repeatable) |
| `--concurrency` | | `8` | Max parallel API calls |

### Output
Expand All @@ -153,6 +159,128 @@ The command returns a non-zero exit code when any repo has drift, is not install

Requires a GitHub token via `GH_TOKEN`, `GITHUB_TOKEN`, or `gh auth token`.

## `repos add`

Add one or more repo entries to the `repos.yaml` manifest file, editing it in place. Use `--install` to also install fullsend on the added repos after updating the manifest.

```bash
fullsend repos add acme/new-api acme/new-web
fullsend repos add acme/new-api --install --direct
fullsend repos add acme/new-api --dry-run
```

### Flags

| Flag | Default | Description |
|------|---------|-------------|
| `-f`, `--manifest` | `repos.yaml` | Path to repos.yaml manifest |
| `--dry-run` | `false` | Preview what would be added without making changes |
| `--install` | `false` | Also install fullsend on the added repos |
| `--concurrency` | `4` | Max parallel operations (1-32, used with `--install`) |
| `--direct` | `false` | Push scaffold directly to default branch (used with `--install`) |

Duplicate entries are silently skipped. Glob patterns (e.g. `acme/*`) are allowed as manifest entries.

## `repos remove`

Remove one or more repo entries from the `repos.yaml` manifest file, editing it in place. Glob patterns are matched against manifest entries and prompt for confirmation unless `--yes` is set.

Use `--uninstall` to tear down fullsend from the repos before removing them from the manifest (deletes workflow, variables, secrets, and WIF).

```bash
fullsend repos remove acme/old-api
fullsend repos remove "acme/*" --yes
fullsend repos remove acme/old-api --uninstall
fullsend repos remove acme/old-api --uninstall --skip-wif-cleanup
```

### Flags

| Flag | Default | Description |
|------|---------|-------------|
| `-f`, `--manifest` | `repos.yaml` | Path to repos.yaml manifest |
| `--dry-run` | `false` | Preview what would be removed without making changes |
| `--uninstall` | `false` | Tear down fullsend from repos before removing from manifest |
| `--yes` | `false` | Skip confirmation prompt for glob patterns |
| `--skip-wif-cleanup` | `false` | Skip GCP WIF provider deletion (only with `--uninstall`) |
| `--concurrency` | `4` | Max parallel operations (1-32, used with `--uninstall`) |

## `repos uninstall`

Tear down fullsend from the specified repos by deleting workflow files, variables, secrets, and WIF infrastructure. Does **not** modify `repos.yaml` — use `repos remove` for that.

Glob patterns are matched against manifest entries and prompt for confirmation unless `--yes` is set.

Runs in two phases:
1. **Parallel per-repo cleanup** — delete workflow, variables, secrets (concurrent)
2. **Sequential WIF deregistration** — deregister from mint and delete WIF provider

```bash
fullsend repos uninstall acme/old-api
fullsend repos uninstall "acme/*" --yes
fullsend repos uninstall acme/old-api --skip-wif-cleanup
fullsend repos uninstall acme/old-api --dry-run
```

### Flags

| Flag | Default | Description |
|------|---------|-------------|
| `-f`, `--manifest` | `repos.yaml` | Path to repos.yaml manifest |
| `--dry-run` | `false` | Preview what would be uninstalled without making changes |
| `--yes` | `false` | Skip confirmation prompt for glob patterns |
| `--skip-wif-cleanup` | `false` | Skip GCP WIF provider deletion |
| `--concurrency` | `4` | Max parallel operations (1-32) |

## `repos diff`

Show configuration drift between the `repos.yaml` manifest and actual forge state. Only examines repos that are already installed (guard variable is `"true"`).

```bash
fullsend repos diff
fullsend repos diff -f path/to/repos.yaml
fullsend repos diff --repo owner/repo1 --repo owner/repo2
fullsend repos diff --json
```

### Flags

| Flag | Short | Default | Description |
|------|-------|---------|-------------|
| `--manifest` | `-f` | `repos.yaml` | Path or HTTPS URL to manifest file |
| `--json` | | `false` | Emit JSON output instead of table |
| `--repo` | | | Filter to specific repos (repeatable) |
| `--concurrency` | | `4` | Max parallel operations (1-32) |

### Exit codes

Returns a non-zero exit code when drift exists (variables differ from manifest or secrets are missing). This makes it suitable for CI drift checks.

## `repos sync`

Reconcile configuration drift for installed repos by writing variables and secrets to match the manifest's desired state. Variables are only written when drift is detected; secrets are always written for convergence since their values cannot be read back.

```bash
fullsend repos sync
fullsend repos sync -f repos.yaml --dry-run
fullsend repos sync --repo acme/api --repo acme/web
fullsend repos sync --json
```

### Flags

| Flag | Short | Default | Description |
|------|-------|---------|-------------|
| `--manifest` | `-f` | `repos.yaml` | Path or HTTPS URL to manifest file |
| `--dry-run` | | `false` | Preview changes without applying them |
| `--json` | | `false` | Emit JSON output instead of table |
| `--repo` | | | Filter to specific repos (repeatable) |
| `--concurrency` | | `4` | Max parallel operations (1-32) |

### Scope

Sync reconciles variables (`FULLSEND_MINT_URL`, `FULLSEND_GCP_REGION`) and secrets (`FULLSEND_GCP_PROJECT_ID`). It does **not** touch scaffold shim version (`@ref`) or harness files — use `repos upgrade` for those.

## See also

- [Getting Started](../guides/getting-started/) — Standard per-repo installation
Expand Down
35 changes: 32 additions & 3 deletions docs/guides/dev/cli-internals.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,44 @@ fullsend
│ │ ├── --inference-project <id> # Default GCP project for inference
│ │ ├── --force # Overwrite output file if it exists
│ │ └── --concurrency <int> # Max parallel API calls (default: 8)
│ ├── install # Install fullsend on uninstalled manifest repos
│ ├── install [repos...] # Install fullsend on uninstalled manifest repos
│ │ ├── -f, --manifest <path> # Path or URL to repos.yaml (default: repos.yaml)
│ │ ├── --dry-run # Preview without making changes
│ │ ├── --repo <owner/repo> # Install specific repos only (repeatable)
│ │ ├── --skip-mint-check # Skip org registration in mint
│ │ ├── --concurrency <int> # Max parallel operations (1-32, default: 4)
│ │ ├── --roles <list> # Agent roles (default: triage,coder,review,fix,retro,prioritize)
│ │ └── --direct # Push scaffold to default branch (skip PR)
│ └── status # Compare manifest against actual repo state
│ ├── add <repos...> # Add repo entries to manifest
│ │ ├── -f, --manifest <path> # Path to repos.yaml (default: repos.yaml)
│ │ ├── --dry-run # Preview without making changes
│ │ ├── --install # Also install fullsend on the added repos
│ │ ├── --concurrency <int> # Max parallel operations (1-32, default: 4)
│ │ └── --direct # Push scaffold to default branch (skip PR)
│ ├── remove <repos...> # Remove repo entries from manifest
│ │ ├── -f, --manifest <path> # Path to repos.yaml (default: repos.yaml)
│ │ ├── --dry-run # Preview without making changes
│ │ ├── --uninstall # Tear down fullsend before removing
│ │ ├── --yes # Skip confirmation for glob patterns
│ │ ├── --skip-wif-cleanup # Skip GCP WIF provider deletion
│ │ └── --concurrency <int> # Max parallel operations (1-32, default: 4)
│ ├── uninstall <repos...> # Tear down fullsend from repos
│ │ ├── -f, --manifest <path> # Path to repos.yaml (default: repos.yaml)
│ │ ├── --dry-run # Preview without making changes
│ │ ├── --yes # Skip confirmation for glob patterns
│ │ ├── --skip-wif-cleanup # Skip GCP WIF provider deletion
│ │ └── --concurrency <int> # Max parallel operations (1-32, default: 4)
│ ├── status # Compare manifest against actual repo state
│ ├── diff # Show configuration drift between manifest and actual state
│ │ ├── -f, --manifest <path> # Path or URL to repos.yaml (default: repos.yaml)
│ │ ├── --json # Emit JSON output instead of table
│ │ ├── --repo <owner/repo> # Filter to specific repos (repeatable)
│ │ └── --concurrency <int> # Max parallel operations (1-32, default: 4)
│ └── sync # Reconcile configuration drift for installed repos
│ ├── -f, --manifest <path> # Path or URL to repos.yaml (default: repos.yaml)
│ ├── --dry-run # Preview changes without applying them
│ ├── --json # Emit JSON output instead of table
│ ├── --repo <owner/repo> # Filter to specific repos (repeatable)
│ └── --concurrency <int> # Max parallel operations (1-32, default: 4)
├── agent # Manage agent registrations in config
│ ├── add <url-or-path> # Register an agent (URL auto-pinned)
│ ├── list # List registered agents
Expand Down
7 changes: 6 additions & 1 deletion docs/guides/getting-started/operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,13 @@ For organizations that separate GCP and GitHub responsibilities across teams, fu
| GCP Admin (Mint) | `fullsend mint status` | Inspect mint state and PEM health |

| Fleet Admin | `fullsend repos init <org\|owner/repo>` | Generate a `repos.yaml` manifest by discovering existing installations |
| Platform Admin | `fullsend repos install -f repos.yaml` | Bulk-install fullsend on repos from a declarative manifest (parallel discovery → sequential WIF → parallel scaffold) |
| Platform Admin | `fullsend repos install [repos...]` | Bulk-install fullsend on repos from a declarative manifest (parallel discovery → sequential WIF → parallel scaffold) |
| Fleet Admin | `fullsend repos add <repos...>` | Add repo entries to `repos.yaml` manifest (with optional `--install`) |
| Fleet Admin | `fullsend repos remove <repos...>` | Remove repo entries from `repos.yaml` manifest (with optional `--uninstall`) |
| Platform Admin | `fullsend repos uninstall <repos...>` | Tear down fullsend from repos (workflow, variables, secrets, WIF) without modifying manifest |
| Fleet Admin | `fullsend repos status` | Compare `repos.yaml` manifest against actual per-repo state (drift detection) |
| Fleet Admin | `fullsend repos diff` | Show configuration drift between manifest and actual state |
| Platform Admin | `fullsend repos sync` | Reconcile configuration drift for installed repos (variables and secrets) |

| Developer | `fullsend agent add <url-or-path>` | Register an agent in config (URL auto-pinned to commit SHA) |
| Developer | `fullsend agent list` | List registered agents and their sources |
Expand Down
Loading
Loading