Files
vulp/docs/cli.md
T
dualfroz f1432d1cd3 Sprint B.5: add-LICENSE action (MIT/Apache-2.0) in [m] menu + vulp repo license
- src/license/: embedded templates, holder resolution (config > git user.name
  > account username), write path shared by TUI and CLI
- TUI: bulk-aware [m] entry over action_targets(), kind select + confirm,
  point-updates has_license/is_dirty, logs to activity (new License kind)
- CLI: vulp repo license <repo>...|--all [--kind] [--holder] [--json],
  skips already-licensed repos, exit 2/4 contract kept
- config: license_holder + default_license fields (TUI-editable)
- never overwrites an existing license, never auto-commits
2026-07-06 15:37:25 +02:00

4.5 KiB

vulp CLI — reference

Complete non-interactive surface. Written for machine consumers (AI agents, scripts) as much as humans: every read command supports --json, nothing ever prompts, and exit codes are meaningful.

vulp                    # no args → interactive TUI (humans)
vulp <command> [--json] # non-interactive (scripts/AI)

Contract

  • --json (global flag): machine-readable JSON on stdout. Available on: list, status, scan, stats, activity, todo list, pr list, issue list, project list, accounts, refresh, repo license.
  • No prompts, ever. Missing input = error + non-zero exit.
  • stdout = results only. stderr = progress and errors.
  • Exit codes: 0 ok · 1 execution error · 2 bad usage · 3 auth missing/invalid · 4 not found (repo/todo/project).
  • Repo arguments match the display label or the directory basename, case-insensitively (e.g. vulp status vulp matches "Vulp - Open Source!").
  • Mutating commands write to the same ~/.vulp/activity.log as the TUI, so CLI actions appear in the TUI's Overview feed.

Workspace (local, no network)

vulp scan                                # repo count + dirty/behind/ahead summary
vulp list [--dirty] [--behind] [--ahead] [--lang ts] [--project NAME]
vulp status <repo>                       # branch, dirty, ahead/behind, last commit...
vulp stats [--period 1d|7d|30d|90d|1y|all]   # commits per repo in period
vulp activity [--limit N] [--kind push|pull|release|"new repo"|todo|pr|issue|commit|license]

vulp list --json returns an array of repo objects:

[{ "name": "...", "path": "...", "branch": "main", "ahead": 0, "behind": 0,
   "is_dirty": true, "last_commit_msg": "...", "last_commit_age": "2h ago",
   "last_commit_ts": 1780000000, "last_tag": null, "visibility": null,
   "owner": "dualfroz", "has_license": false, "lang": "TypeScript 96%",
   "bookmarked": false, "stars": null, "open_issues": null, "open_prs": null }]

Git operations

vulp sync <repo>... [--action pull|push|commit-push] [-m MSG]
vulp sync --all --action pull
vulp sync --project NAME --action push
vulp release <repo> --tag v1.2.0 [--notes "..."]   # git tag + push + provider release

commit-push requires -m/--message. sync exits 1 if any target failed (per-repo progress on stderr).

Todos

vulp todo list [--status open|in-progress|done|cancelled] [--json]
vulp todo add "Title" [--desc "..."] [--project NAME]
vulp todo start|done|cancel|rm <id>

Projects (repo groupings)

vulp project list [--json]
vulp project create NAME [--color "#e74c3c"]
vulp project assign NAME <repo>...
vulp project rm NAME

Provider API (needs vulp auth import first)

vulp pr list [--repo R] [--json]        # cached — run `vulp refresh` for fresh
vulp pr create --repo R --title T --head BRANCH [--base main]
vulp issue list [--repo R] [--json]
vulp issue create --repo R --title T [--body "..."]
vulp refresh                            # re-fetch meta + PRs + issues into cache
vulp init NAME [--private] [--description "..."]   # local init + create remote + push
vulp accounts [--json]

pr/issue list read the on-disk cache (~/.vulp/) — the same one the TUI uses; run vulp refresh first when freshness matters.

Per-repo utilities

vulp repo url <repo>                    # print origin URL
vulp repo path <repo>                   # print absolute path
vulp repo open <repo>                   # open provider page in browser
vulp repo label <repo> "Display Name"   # empty name clears the label
vulp repo bookmark <repo>               # toggle
vulp repo pin <repo>                    # toggle
vulp repo collab <repo> <user> [--role pull|push|admin]
vulp repo license <repo>... [--kind mit|apache-2.0] [--holder NAME]
vulp repo license --all                 # every repo missing a license

repo license writes a LICENSE file into each target repo. It never overwrites an existing license (reported as skipped) and never commits — review and commit the file yourself. Defaults come from config: default_license (mit) and license_holder (falls back to git config user.name, then the account username).

Recipes for AI agents

# What needs attention right now?
vulp list --dirty --json

# Commit and push everything in one project
vulp sync --project client-panel --action commit-push -m "chore: batch update"

# Fresh cross-repo picture (meta + PRs + issues), then read it
vulp refresh --json && vulp pr list --json

# Weekly activity summary
vulp stats --period 7d --json