feat(cli): workspace project repo lifecycle (list, add, rm, sync, doctor)

Author: harshitsinghbhandariCreated Sep 19, 2026Updated Sep 19, 2026
Labelsenhancementneeds-triagecomp/clineeds-discussion

Summary

Umbrella for making workspace projects operable from the ao CLI after initial ao project add --as-workspace.

Today a workspace is scanned once at add time. ao project get --json returns a thin workspaceRepos list (name, relativePath, repo). There is no CLI (and little daemon surface) to list children with health, add or remove a child later, rescan the folder, set a per-child default branch, or explain which child blew up ao spawn.

This is long-running. Ship in slices. Related: #5643 (add-repo only). Keep that issue; this one is the full lifecycle.

Why

Workspace projects grow. Orchestrators and agents only have the CLI. Example: AgentLab added alab-cli after the workspace existed. Clone + root .gitignore was possible by hand. The project record did not update, so new session worktrees still omit the child. Spawn failures name a nested .git/config lock and kill the whole workspace spawn with no child-level diagnosis.

Desktop project settings mostly display workspaceRepos. They are not a substitute for CLI.

Current surface (checked 2026-09-19)

  • ao project add --as-workspace: initial register; adopts children present at that moment
  • ao project set-config: branch, env, agents, rules, etc. No workspace-repo fields
  • ao project get --json: workspaceRepos without default_branch, even though workspace_repos.default_branch exists in the store
  • No ao project repos, repo add, repo rm, repos sync, or workspace-specific doctor checks

Desired CLI (names are proposals)

1. List

ao project repos [<project-id>]
ao project repos --json

Per child: name, relative path, origin URL, default branch, on-disk present, last-known git status / HEAD resolve. This is the inspect primitive everything else hangs off.

2. Add and remove (overlaps #5643)

ao project repo add --project <id> --path <dir>
ao project repo rm --project <id> <name>

Add: existing git checkout under the workspace root (or clone-then-attach if we later add an explicit --clone <url>). Infer name, relative path, origin, default branch. Update the project record so the next ao spawn worktrees that child. Update root .gitignore for the child path when that is already the workspace convention.

Remove: drop the registry row. Do not delete the folder unless --delete-files is explicit.

3. Sync / rescan

ao project repos sync [<project-id>]

Rescan the workspace directory. Adopt new git children already on disk that are not in workspaceRepos. Report missing registered children. Do not surprise-delete registry rows; rm stays explicit.

This is the 80% path: human or agent clones a repo into the workspace, then sync.

4. Per-child default branch

ao project repo set <name> --default-branch <branch>

Workspace-wide defaultBranch is the wrong knob when children disagree. Unresolved origin/HEAD already fails spawn with DEFAULT_BRANCH_UNRESOLVED. Expose and set the per-child column the DB already has.

5. Spawn diagnostics per child

When ao spawn fails inside a workspace worktree add, the error must name:

  • child repo name and path
  • git command
  • lock or config file if that is the cause

Today one nested git config lock aborts the entire workspace spawn as a generic worktree error.

6. Doctor checks

ao doctor (or ao project doctor) for workspace kind:

  • child missing on disk
  • child not a git repo
  • child on disk but not in workspaceRepos
  • child not gitignored at workspace root (when other children are)
  • origin HEAD unresolved

Orchestrators should run this before a wave of spawns.

Non-goals

  • Nested workspaces
  • Silent auto-clone from GitHub into the workspace
  • Spawn that checks out only one child (workspace remains all children in one worktree)
  • Changing single-repo or scratch project kinds

--clone <url> on add can be a later slice. Not required for v1 of this umbrella.

Suggested slices (independent PRs)

  1. ao project repos list (+ json), including default branch
  2. repo add / repo rm (can close #5643 when add ships)
  3. repos sync
  4. repo set --default-branch
  5. Spawn error includes child identity
  6. Doctor checks

Acceptance (umbrella)

  • A workspace can gain a child without re-running ao project add --as-workspace
  • ao project repos --json is enough for an orchestrator to see drift vs disk
  • Next ao spawn after add or sync worktrees the new child
  • A spawn failure on child B does not look like a generic workspace failure with no name
  • ao doctor flags unsynced children

Environment

  • Project kind: workspace
  • Trigger: AgentLab workspace, 2026-09-19, adding alab-cli after initial register

Source: Untrivial-ai/agent-orchestrator