Skip to content

Local bare clones of hub.toml projects via hub fetch #19

@ooloth

Description

@ooloth

Why

Skills and fix workflows need to read file contents across all hub.toml repos; going over the network on every scan is wasteful, and depending on the user's local checkouts risks dirty working trees or feature branches. Agent-driven fixes need an isolated working directory per task. And none of this should require the user to remember to run a command — the TUI should keep everything current automatically.

Current state

hub.toml stores a GitHub slug (repo = "ooloth/hub") and a name per project but no local path. Skills that read repo files must call gh api on every invocation. No hub-managed checkout exists, no hub fetch command exists, and there is no canonical local path convention for any project.

Ideal state

Bare clones

  • hub fetch creates a bare clone at ~/.hub/repos/<name>/ for each project in hub.toml (where <name> is the TOML name field)
  • Running hub fetch again on an existing clone fetches latest without re-cloning
  • File contents are readable via git -C ~/.hub/repos/<name> show HEAD:<path>
  • All tracked paths are listable via git -C ~/.hub/repos/<name> ls-tree -r --name-only HEAD
  • Adding a project to hub.toml and running hub fetch creates its bare clone automatically
  • Removing a project from hub.toml leaves its clone intact, with a logged warning that it is orphaned

Worktrees

  • Agent-created worktrees live nested inside the bare clone dir: ~/.hub/repos/<name>/<branch-slug>/
  • This makes clone and its worktrees co-located — ls ~/.hub/repos/<name>/ shows the full picture
  • hub fetch detects worktrees whose branches have merged on GitHub and removes them automatically
  • Worktrees for unmerged branches are left intact so the agent's in-progress work can be inspected

TUI integration

  • The TUI refresh loop runs fetch automatically on startup and on each refresh cycle
  • No manual hub fetch is needed for interactive use — opening the TUI is sufficient
  • The hub fetch CLI command remains available for debugging and unattended automation (agents, scripts)

Out of scope

  • Scheduling hub fetch via launchd or a daemon (TUI handles the interactive case; scripts handle automation)
  • Auto-pruning orphaned clones (projects removed from hub.toml)

Starting points

  • config/src/toml.rsProject struct with name and repo fields that hub fetch would iterate
  • ui/cli/src/main.rs — CLI command dispatch where the fetch subcommand would be added
  • ui/tui/src/main.rs — background refresh loop where fetch should be integrated
  • docs/architecture/secrets.md — credential injection pattern; hub fetch will need GITHUB_TOKEN for private repos

QA plan

  1. Run hub fetch with hub.toml listing one project — expect ~/.hub/repos/<name>/ to exist as a bare clone with a valid HEAD ref
  2. Run git -C ~/.hub/repos/<name> show HEAD:README.md — expect the file contents to print
  3. Run git -C ~/.hub/repos/<name> ls-tree -r --name-only HEAD — expect a flat list of all tracked file paths
  4. Run hub fetch again — expect it to complete without re-cloning; expect any commits pushed since step 1 to now appear in git log HEAD
  5. Add a second project to hub.toml, run hub fetch — expect a new bare clone at ~/.hub/repos/<second-name>/
  6. Remove a project from hub.toml, run hub fetch — expect its clone to remain untouched, with a warning that it is orphaned
  7. Create a worktree manually: git -C ~/.hub/repos/<name> worktree add <name>/<branch> -b <branch> — expect the working directory to appear at ~/.hub/repos/<name>/<branch>/
  8. Merge the branch on GitHub, run hub fetch — expect the worktree directory to be removed and a log line confirming cleanup
  9. Start the TUI — expect bare clones to be created or updated as part of startup without any manual fetch invocation
  10. Push a commit to a tracked repo while the TUI is running — expect the clone to reflect that commit after the next TUI refresh cycle

Done when

  • hub fetch creates and keeps bare clones current for every project in hub.toml, and file contents are readable offline via git show HEAD:<path>
  • Agent-created worktrees live at ~/.hub/repos/<name>/<branch-slug>/ and are removed automatically by hub fetch when their branches merge
  • The TUI refresh loop runs fetch automatically — no manual command needed for interactive use

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions