{"id":49748186,"url":"https://github.com/statpan/gira","last_synced_at":"2026-06-11T15:00:48.348Z","repository":{"id":355868516,"uuid":"1221326056","full_name":"StatPan/gira","owner":"StatPan","description":"GitHub-native control plane for issue-to-PR AI software workflows","archived":false,"fork":false,"pushed_at":"2026-06-11T13:02:18.000Z","size":1957,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-11T15:00:13.451Z","etag":null,"topics":["agentic-workflow","ai-agents","cli","coding-agents","developer-tools","github-workflow","golang","issue-tracking","jira","pull-requests"],"latest_commit_sha":null,"homepage":"https://gira.statpan.com","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StatPan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-26T03:42:26.000Z","updated_at":"2026-06-11T13:02:22.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/StatPan/gira","commit_stats":null,"previous_names":["statpan/gira"],"tags_count":30,"template":false,"template_full_name":null,"purl":"pkg:github/StatPan/gira","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StatPan%2Fgira","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StatPan%2Fgira/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StatPan%2Fgira/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StatPan%2Fgira/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StatPan","download_url":"https://codeload.github.com/StatPan/gira/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StatPan%2Fgira/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34204182,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-11T02:00:06.485Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agentic-workflow","ai-agents","cli","coding-agents","developer-tools","github-workflow","golang","issue-tracking","jira","pull-requests"],"created_at":"2026-05-10T07:16:58.537Z","updated_at":"2026-06-11T15:00:48.337Z","avatar_url":"https://github.com/StatPan.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Gira\n\nGira helps humans and coding agents finish GitHub issues safely.\n\nIt is a GitHub-native control plane for AI-assisted software work: repository\nevidence stays in GitHub, while Gira makes the next safe workflow command\nexplicit.\n\nIt turns the GitHub issue-to-PR loop into a predictable workflow that humans and\ncoding agents can both follow:\n\n```text\nissue -\u003e branch -\u003e PR -\u003e checks -\u003e evidence -\u003e finish\n```\n\nAI coding agents can generate code and open pull requests, but real engineering\nwork is not finished until the repository state converges: the PR is linked,\nchecks are green, review blockers are clear, the issue is closed, active status\nlabels are normalized, and the next command is obvious. Gira makes that finish\nstep explicit.\n\nUse Gira when you want GitHub to remain the source of truth, while still having\na Jira-like lifecycle that coding agents can operate safely:\n\n- Issues are executable task packets.\n- Branches prove work has started.\n- PRs are change units.\n- Checks and reviews are validation evidence.\n- Milestones group sprint/release boundaries.\n- `ticket finish` merges only when policy allows, then converges issue state.\n- `doctor` detects repo, workflow, label, and closed-issue status drift.\n\nThe 2.x control-plane contract extends that loop with stable surfaces for\nlong-running human and agent work:\n\n- `goal status`, `goal report`, `goal next`, `goal plan --dry-run|--apply`,\n  and `goal finish` model a larger objective as an evidence-backed child-ticket\n  graph with explicit human-review stop conditions and a visible JSON or HTML\n  report.\n- Ticket readiness, PR readiness, review packets, finish readiness, finish\n  receipts, and drift audits make completion reviewable without trusting an\n  agent transcript.\n- `workspace status --json` includes `workspace-queues/v1` so operators can see\n  agent-ready, review-needed, finish-ready, blocked, failed-check, and\n  human-decision queues across repos.\n- `queue list`, `queue next`, `queue handoff`, and `queue take` expose the\n  Agent Handoff Queue for LLM task selection, handoff packet assembly, and safe\n  ticket start without launching a worker by default.\n- `stats pulse` reports recent evidence-backed workflow movement for a repo\n  without turning operator activity into a people or agent ranking.\n- Adapter-facing command metadata and approval evidence, including\n  `gira-approval-plan/v1`, let durable agent runtimes treat Gira dry-runs as\n  auditable plans before any matching `--apply`.\n- `gira completion bash|zsh|fish` prints static shell completion scripts for\n  common commands, lifecycle subcommands, and shared flags.\n\nThe 2.x release line is the CLI-first control-plane contract. It is not a\nhosted dashboard, UI/TUI launch, provider expansion, or Gira-native planning\ndatabase. The release readiness boundary is documented in\n[docs/v2-release-readiness.md](docs/v2-release-readiness.md).\n\nThe core safety model is Terraform-like:\n\n- `--dry-run` previews GitHub or repository mutations.\n- `--apply` executes only after the plan is understood.\n\nDocumentation: \u003chttps://gira.statpan.com\u003e\n\nDocs source lives in `docs-site/` and is built with VitePress. The docs toolchain is separate from the product runtime; the shipped product remains the Go-built `gira` binary.\n\nThe target branch policy contract is documented in [docs/branch-policy.md](docs/branch-policy.md). It defines the planned direction for resolving a ticket base branch once, recording it as lifecycle state, preserving it through PR creation and review, and avoiding hidden local checkout mutation during finish.\n\nGira is not a Jira clone or a separate planning database. It is a workflow\ncontrol layer over GitHub Issues, branches, PRs, checks, labels, and milestones.\nRepo-linked Projects are visibility surfaces; Project-only items stay intake or\nplanning until routed to a repository issue.\n\nJira-primary provider mode is optional. In that mode Jira owns planning and status while GitHub still owns execution evidence. See [docs/jira-primary-provider.md](docs/jira-primary-provider.md).\n\nThe core flow is:\n\n```text\ninstall -\u003e auth -\u003e init/readiness -\u003e ticket -\u003e PR -\u003e checks -\u003e finish\n```\n\n## 3-Minute Quick Start\n\nInstall Gira:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/StatPan/gira/main/install.sh | sh\n```\n\nOr install through a currently published package manager channel:\n\n```bash\nnpm install -g @statpan/gira\nbun install -g @statpan/gira\nuv tool install gira-cli\npipx install gira-cli\npython -m pip install --user gira-cli\nbrew tap StatPan/tap\nbrew install gira\n```\n\nRelease binary installs do not require Go. Use Go only when building or testing Gira from source.\n\nAuthenticate GitHub first. Gira uses GitHub as the execution backend and shells through `gh` for GitHub API access:\n\n```bash\ngira version\ngh auth status\ngira guide\n```\n\n`gira guide` is built into the installed binary. Use `gira guide quickstart`, `gira guide ticket`, `gira guide agent`, or `gira guide concepts` when you need the workflow without opening this README. `gira docs` is an alias.\n\nRead before writing. For repository setup, run init from a clean checkout so Gira can fail closed before apply steps:\n\n```bash\ngira init --repo OWNER/REPO --path . --dry-run\ngira adopt repo --repo OWNER/REPO --path . --dry-run\ngira status --repo OWNER/REPO\n```\n\nStart and finish development from a ticket:\n\n```bash\ngira status\ngira ticket new \"Add login retry\" \\\n  --goal \"Retry transient auth failures\" \\\n  --acceptance \"retries 3 times;does not retry 401;has tests\" \\\n  --dry-run\ngira ticket new \"Add login retry\" \\\n  --goal \"Retry transient auth failures\" \\\n  --acceptance \"retries 3 times;does not retry 401;has tests\" \\\n  --apply --start\ngira ticket list --state open --label status:ready --limit 20\n\n# implement the bounded issue scope, then verify locally\ngo test ./...\n\ngira ticket pr --dry-run\ngira ticket pr --apply --draft\ngira ticket view\ngira ticket prompt --role implementer --profile python\ngira ticket note \"Parser path is implemented; local tests are next.\" --dry-run\ngira ticket review --diff-summary\ngira ticket self-review --diff-summary --dry-run\ngira ticket checks\ngira ticket wait --timeout 5m\ngira ticket finish --dry-run\ngira ticket finish --apply\ngira ticket status\n```\n\n`gira ticket new` creates a repo-bound executable ticket. It writes a structured issue body from `--goal`, `--scope`, `--acceptance`, and `--notes`, or accepts a complete issue packet through `--body`, `--body-file PATH`, or `--body-file -`. It applies `type:*` and `status:ready`, previews the exact payload with `--dry-run`, and can immediately start the branch with `--start`. Requested labels must already exist in the repo; `ticket new` preflights labels during dry-run/apply and reports missing taxonomy instead of creating labels implicitly. `gira ticket list` lists GitHub issue-backed tickets with compact filters: `--state open|closed|all`, repeatable or comma-separated `--label`, `--assignee`, `--milestone`, `--limit`, and `--json`. `gira ticket view` shows the ticket operating card: issue state, Gira status, linked PR, blockers, next action, and next command. `gira ticket prompt` renders stateless planner, implementer, or reviewer prompts from the ticket, with `default` and `python` profiles. `gira ticket review --diff-summary` renders the current ticket's review packet with changed files, diff stat, hunk headers, acceptance mapping candidates, risk hints, and the full diff command; `--include-diff` prints the full diff only when explicitly requested. `gira ticket self-review --diff-summary --dry-run` previews a `kind=check` PR note for the current branch ticket, and `--apply` posts it to the linked PR. `gira ticket note` renders a structured context note and posts it to the issue, linked PR, or both after `--dry-run` review. `gira ticket supersede` creates a linked replacement issue, writes decision notes on both tickets, removes active status labels from the old ticket, adds `resolution:superseded`, and closes it after dry-run review. `gira ticket` resolves `--repo` from `.gira/config.yaml` or git origin. After `ticket start` checks out an `issue-N-*` branch, `ticket view`, `ticket prompt`, `ticket handoff`, `ticket review`, `ticket self-review`, `ticket note`, `ticket pr`, `ticket checks`, `ticket wait`, `ticket finish`, and `ticket status` can infer the ticket from the current branch or linked PR. Pass `--repo OWNER/REPO` and `--ticket N` when running outside that context.\n\nFor an existing repository, run `gira adopt repo --dry-run` before full bootstrap. Gira detects existing issues, labels, milestones, Projects, `AGENTS.md`, and GitHub templates, then recommends an adoption strategy. The default `merge` strategy preserves user-owned files and metadata while adding only the minimal Gira contract, such as `.gira/config.yaml` and an `AGENTS.md` managed block. Bootstrap sample issues are never required for normal adoption.\n\nYou can still call `gh` directly for low-level GitHub operations, but lifecycle work should use Gira ticket controls when available: `ticket view`, `ticket status`, `ticket start`, `ticket pr`, `ticket review`, `ticket self-review`, `ticket note`, `ticket supersede`, `ticket checks`, `ticket wait`, and `ticket finish`. Use raw `gh` only when Gira has no lifecycle command or when you intentionally need an unopinionated GitHub operation. The ticket commands keep the lifecycle consistent: they create or reuse the linked PR, require a closing body such as `Closes #TICKET`, compute blockers, render review packets and context notes, supersede stale work with linked replacement evidence, wait for pending checks, merge only when review and checks allow it, clean up the branch when safe, and give the next Gira command to run.\n\n`gira epic list`, `gira epic status`, and `gira epic finish` close the larger planning loop without requiring raw `gh issue list` or `gh issue close`. `epic list` is a `type:epic` view over GitHub issues with the same compact list filters as ticket list. Gira can resolve an epic from the current `issue-N-*` branch, `--title`, `--slug`, `--milestone`, or a sole open `type:epic`; `--ticket N` remains the explicit fallback. `epic finish --apply` refuses to close while child issues are still open, then normalizes active status labels and closes the epic through GitHub.\n\n`gira stats repo --repo OWNER/REPO --since 90d` renders the first Closure Funnel report. It is GitHub read-only, defaults to human text output, and uses `--json` only for automation. The report counts opened/closed issues, superseded issues, opened/merged PRs, closing-link hygiene, check friction, stale open work, and closure rate. `gira stats workspace --since 90d` is the planned multi-repo rollup; see [docs/closure-funnel-stats.md](docs/closure-funnel-stats.md).\n\n## Jira-Primary Provider Mode\n\nGitHub-native mode remains the default. Jira-primary mode is explicit and keeps a split source of truth: Jira owns planning and status, while GitHub owns branch, PR, review, checks, merge, and close evidence.\n\n```bash\ngira jira init --repo OWNER/REPO --api-base https://example.atlassian.net --project ABC --dry-run\ngira jira init --repo OWNER/REPO --api-base https://example.atlassian.net --project ABC --apply\ngira jira doctor --repo OWNER/REPO --sample-key ABC-123\ngira jira mirror ABC-123 --repo OWNER/REPO --dry-run\ngira jira mirror ABC-123 --repo OWNER/REPO --apply\ngira ticket start ABC-123 --repo OWNER/REPO --apply\ngira ticket finish --dry-run\ngira ticket finish --apply\n```\n\nProvider config is non-secret and lives in the user-global repo registry. Jira credentials come from `JIRA_EMAIL` and `JIRA_API_TOKEN`. `gira jira doctor` is read-only and reports whether a Jira-primary repo is `supported`, `partially_supported`, or `blocked` before heavier operation. `ticket finish` refuses Jira Done while GitHub evidence is incomplete, including missing mirror issue, missing linked PR, draft PR, review blocker, failing or pending checks, or unmerged PR. Jira workflow mutation, background sync, full bidirectional sync, hosted dashboards, and Jira-only completion are outside the OSS CLI slices. See [docs/jira-primary-provider.md](docs/jira-primary-provider.md) and `gira guide jira`.\n\n## Ticket Flow Cases\n\nMost first-time work starts by creating a repo-bound ticket and immediately starting it:\n\n```bash\ngira ticket new \"Fix install retry\" \\\n  --goal \"Retry transient install downloads\" \\\n  --acceptance \"retries temporary network failures;does not hide checksum errors;has tests\" \\\n  --apply --start\n```\n\nIf the GitHub issue already exists, start from that ticket number once. After Gira checks out the `issue-N-*` branch, the rest of the flow infers the ticket from context:\n\n```bash\ngira ticket start 42 --apply\ngira ticket pr --apply --draft\ngira ticket view\ngira ticket review --diff-summary\ngira ticket self-review --diff-summary --dry-run\ngira ticket note \"Ready for CI review.\" --target pr --dry-run\ngira ticket checks\ngira ticket wait --timeout 5m\ngira ticket finish --apply\n```\n\nIf someone reports an issue in GitHub without enough structure, normalize it before starting work: add the missing goal, scope, acceptance criteria, and `status:ready`/`type:*` labels in GitHub or recreate it through `gira ticket new`. Start only after the ticket is executable.\n\nUse `--json` for automation:\n\n```bash\ngira status --repo OWNER/REPO --json\ngira ticket status --repo OWNER/REPO --ticket 12 --json\n```\n\n## LLM And Agent Runbook\n\nWhen an LLM or coding agent operates a Gira-managed repository, follow this order exactly. Do not skip dry-runs, do not use raw `gh` for product workflow steps when a `gira` lifecycle command exists, and keep the PR body linked to the source issue with `Closes #TICKET`. A Project item by itself does not authorize branch, PR, checks, merge, or finish work unless it is backed by a repository issue; route or lower repo-agnostic items first.\n\n```bash\n# 1. Read current state.\ngh auth status\ngira init --repo OWNER/REPO --path . --dry-run\ngira adopt repo --repo OWNER/REPO --path . --dry-run\ngira status --repo OWNER/REPO\n\n# 2. Create and start a repo-bound ticket.\ngira ticket new \"TITLE\" --goal \"GOAL\" --acceptance \"item 1;item 2\" --dry-run\ngira ticket new \"TITLE\" --goal \"GOAL\" --acceptance \"item 1;item 2\" --apply --start\ngira ticket new --title \"TITLE\" --body-file issue.md --dry-run\ngira ticket new --title \"TITLE\" --body-file issue.md --apply --start\n\n# 3. Implement the bounded issue scope, then verify locally.\ngo test ./...\n\n# 4. Open or validate the PR through Gira.\ngira ticket pr --dry-run\ngira ticket pr --apply --draft\ngira ticket view\ngira ticket review --diff-summary\ngira ticket self-review --diff-summary --dry-run\ngira ticket note \"Ready for review.\" --target pr --dry-run\ngira ticket note \"Ready for review.\" --target pr --apply\n\n# 5. Finish through Gira after review and checks are ready.\ngira ticket checks\ngira ticket wait --timeout 5m\ngira ticket finish --dry-run\ngira ticket finish --apply\n\n# 6. Re-check the ticket and Project bridge.\ngira ticket status\n```\n\nUse GitHub assignees for accountable humans. Use `agent:*` labels for the execution actor, for example `agent:human`, `agent:codex`, `agent:reviewer`, or `agent:gira`. Use `lane:*` labels for delegation authority and risk, such as `lane:agent`, `lane:human`, or `lane:hybrid`. `gira projects sync` mirrors the execution actor label into the Project planning field; it does not replace GitHub assignees or make the Project item the source of truth.\n\nAdvanced visibility commands such as `gira projects sync --config .gira/config.yaml --dry-run`, `gira epic status`, and `gira epic finish --dry-run` are useful after the first ticket loop is working.\n\n## Command Model\n\nThe Go-built `gira` binary is the sole product implementation. The default user experience is Jira-style ticket work backed by GitHub issues, PRs, labels, and milestones.\n\n- `gira ticket ...` is the daily issue -\u003e branch -\u003e PR workflow.\n- `gira workspace ...` is the Jira-like personal workspace and inbox layer for repo-agnostic backlog before work is routed to an execution repo.\n- `gira projects ...` mirrors canonical repository issue state into visible GitHub Projects board items.\n- `gira sprint ...`, `gira release`, and `gira status` are daily planning and reporting commands.\n- `gira audit readiness --repo OWNER/REPO` combines doctor checks, audit ledger health, and the next Gira-first action.\n- `gira ops ...` contains advanced setup, migration, policy, audit, and raw GitHub controls.\n- `gira start` and `gira work ...` remain compatibility aliases.\n\n## Advanced Setup\n\nMost daily work should use `gira ticket`, `gira workspace`, `gira projects`, `gira sprint`, `gira release`, and `gira status`. Use `gira ops` for setup, adoption, policy, audit, and lower-level GitHub controls.\n\nPlan setup without changing GitHub or repository files:\n\n```bash\ngira adopt repo --repo OWNER/REPO --path . --dry-run\ngira ops bootstrap --repo OWNER/REPO --template default --dry-run\ngira ops sync --repo OWNER/REPO --dry-run\n```\n\nApply the reviewed setup:\n\n```bash\ngira ops bootstrap --repo OWNER/REPO --path /path/to/repo\ngira ops sync --repo OWNER/REPO\ngira ops onboard verify --repo OWNER/REPO --stage steady-state\n```\n\n## Jira To GitHub Mapping\n\nGira keeps the user-facing workflow close to Jira while storing canonical state in GitHub. The v1 model is intentionally small:\n\n| Jira concept | GitHub object | Gira behavior |\n| --- | --- | --- |\n| Workspace | GitHub account plus configured inbox and execution repos | A workspace groups repo-agnostic intake with one or more execution repos so personal backlog is visible before it is assigned to a repo. |\n| Project | Repository plus optional repo-linked GitHub Project board | A repo is the default execution space. Repo-linked Projects can show repo issue state even when the Project URL is under `users/OWNER/projects/N` or `orgs/OWNER/projects/N`. Multi-repo work starts as a top-level ticket and is lowered into repo issues when ownership is clear. |\n| Backlog | Inbox repo issues plus repo issues | `gira workspace status` and `gira workspace backlog` show unrouted inbox tickets together with routed repo work. |\n| Epic | Parent or top-level issue | A milestone-sized outcome. `gira epic status` and `gira epic finish` inspect and close epics without requiring the issue number when branch, title, slug, milestone, or repo context is enough. |\n| Story / Task / Bug | Issue | The main work packet. Type, priority, blocked, and status are represented with managed labels and issue metadata. |\n| Sprint | Milestone | `gira sprint` plans, starts, closes, and rolls over milestone-scoped work. |\n| Status | Labels plus PR evidence | Gira reads and updates status labels, then cross-checks branch, PR, review, and check state. In Jira-primary mode, Jira owns planning/status and GitHub status labels are mirrors or execution hints. |\n| Assignee | GitHub assignee | Ownership stays visible in GitHub and can be supplemented with owner or worker labels. |\n| Branch | Issue execution context | `gira ticket start` verifies the ticket, creates or reuses a branch, and moves work to in-progress on apply. |\n| Pull request | Change unit | `gira ticket pr` creates or validates a linked PR with a closing keyword such as `Closes #12`. |\n| Done | Merged PR plus closed issue | Completion is proven by GitHub merge and close evidence, not by hidden local state. Jira Done transitions are gated on this evidence when Jira-primary mode is enabled. |\n| Release | GitHub Release plus readiness report | `gira release readiness` checks whether issue, PR, review, and milestone evidence are ready for delivery. |\n\nFull GitHub Projects v2 view automation, Web UI/TUI, chat bots, LLM decomposition, background Jira sync, and full bidirectional Jira sync are not v1 product workflows. Jira import/export commands are explicit migration helpers. Projects sync links and mirrors repository issue state into Projects; it does not make Project items the execution source of truth.\n\n## Workspace Backlog\n\nFor a single repo, `gira status --repo OWNER/REPO` is enough. For Jira-style intake that is not yet tied to a repository, configure a personal workspace:\n\n```yaml\nworkspace:\n  name: personal\n  owner: OWNER\n  inbox_repo: OWNER/backlog\n  repos:\n    - OWNER/app\n    - OWNER/cli\n```\n\nThe inbox repo is where repo-agnostic tickets live. Execution repos are where branch, PR, milestone, and release work happens.\n\n```bash\ngira workspace status --config .gira/config.yaml\ngira workspace backlog --config .gira/config.yaml\ngira workspace list --config .gira/config.yaml\ngira workspace sync --dry-run --config .gira/config.yaml\ngira workspace ticket new \"Define billing model\" --body-file issue.md --config .gira/config.yaml\ngira workspace ticket new \"Define billing model\" --repo OWNER/app --dry-run --config .gira/config.yaml\ngira workspace ticket new \"Define billing model\" --repo OWNER/app --apply --config .gira/config.yaml\ngira workspace ticket route --ticket 12 --repo OWNER/app --dry-run --config .gira/config.yaml\ngira workspace ticket route --ticket 12 --repo OWNER/app --apply --config .gira/config.yaml\ngira workspace project adopt --owner OWNER --title \"Gira\" --dry-run --config .gira/config.yaml\ngira workspace project adopt --owner OWNER --title \"Gira\" --apply --config .gira/config.yaml\ngira projects sync --dry-run --config .gira/config.yaml\ngira projects sync --apply --config .gira/config.yaml\n```\n\n`workspace status` is safe for larger global workspaces: it reports GitHub API\nbudget when available, bounds concurrent repo reads, caches per-repo status for\nfive minutes by default, and supports `--repo`, `--limit`, `--active-only`, and\n`--refresh` for practical CLI and future GUI refresh loops.\n\nUse `gira config storage --repo OWNER/REPO` when you need to see what Gira\nstores locally. It is read-only and classifies config, private runtime state,\ndisposable cache, export bundles, audit ledgers, and wrapper binary cache by\ndurability, privacy, rebuild source, and source-of-truth boundary.\n\n`workspace ticket new --repo OWNER/REPO --apply` creates an inbox ticket, routes it to a repo execution issue, and links the child issue back to the inbox ticket without requiring the user to copy the inbox issue number. Use `--body`, `--body-file PATH`, or `--body-file -` when the inbox packet is already drafted in Markdown. `workspace ticket route --ticket N` remains available for older or externally-created inbox tickets. After routing, the normal loop continues with `gira ticket start`, `gira ticket pr`, and `gira ticket status` on the target repo.\n\n`workspace project adopt` registers an existing profile or org GitHub Project in `workspace.project`; it never creates Projects and fails instead of replacing a different configured Project. `projects sync` then keeps that existing GitHub Projects v2 board visible by linking configured repos, adding missing open issues as project items, mirroring Gira status labels to the board's standard Status field, keeping closed issues as `Done`, creating supported planning fields, mirroring `priority:*`, `area:*`, and `agent:*` labels into Project planning fields, and copying milestone due dates into `Target date`. A Project may live under `users/OWNER/projects/N` or `orgs/OWNER/projects/N`; when it is linked to the repo and its items are repo issues, it is still a normal repo board surface. Repo issues remain the execution source of truth. Add `--archive-closed` only when closed issue items should leave the active Project item set. GitHub does not expose supported Project view creation APIs, so Gira reports the manual Board/Schedule view setup step instead of hiding it behind raw Project numbers.\n\n## GitHub Workflow Templates\n\nThe default bootstrap template includes GitHub issue forms and a pull request template under `.github/`. These templates are part of the Gira repository contract: they help downstream repos collect the context needed before an issue becomes `status:ready`, then keep PRs tied to the issue -\u003e branch -\u003e checks -\u003e finish loop.\n\n```bash\ngira ops bootstrap --repo OWNER/REPO --template default --dry-run\ngira ops bootstrap --repo OWNER/REPO --path /path/to/repo\n```\n\nIssue forms collect goal, scope, acceptance criteria, priority, optional source ticket, rollout or migration notes, observability/security impact, and expected verification. They do not ask for a Gira ticket ID before issue creation because the GitHub issue number becomes the ticket ID after submission. The PR template requires a closing issue reference, records the expected `gira ticket start` and `gira ticket finish` lifecycle commands, and includes production-readiness checks for tests, migrations, rollout, observability, security, and docs.\n\n## Install, Upgrade, and Remove\n\nGira is implemented as a Go-built CLI. Normal users should install the release binary through `install.sh`, npm/bun, PyPI via uv/pipx/pip, or Homebrew. These channels do not require Go, do not build from source, and do not mutate any repository.\n\n### Release Binary Channels\n\nUse one of the release channels:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/StatPan/gira/main/install.sh | sh\nnpm install -g @statpan/gira\nbun install -g @statpan/gira\nuv tool install gira-cli\npython -m pip install --user gira-cli\npipx install gira-cli\nbrew tap StatPan/tap\nbrew install gira\n```\n\nAll channels install the same Go-built `gira` binary. Package managers are wrappers around the release binary, not alternate runtimes.\n\n### Install Script\n\nInstall the latest tagged release:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/StatPan/gira/main/install.sh | sh\n```\n\nPin a version:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/StatPan/gira/main/install.sh | GIRA_VERSION=v1.0.0 sh\n```\n\nInstall to a custom directory:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/StatPan/gira/main/install.sh | GIRA_INSTALL_DIR=\"${HOME}/bin\" sh\n```\n\nThe install script:\n\n- Detects `os` and `arch`, then selects the matching GitHub release archive.\n- Installs `latest` by default and accepts an explicit version, for example `GIRA_VERSION=v1.0.0`.\n- Downloads from GitHub release assets, not from a source checkout or CI artifact.\n- Requires the release `checksums.txt` asset and verifies the selected archive before unpacking it.\n- Installs to `${GIRA_INSTALL_DIR}` when set, otherwise to `${HOME}/.local/bin`.\n- Prints PATH guidance when the install directory is not already on `PATH`.\n- Replaces an existing `gira` binary in the selected install directory atomically when possible.\n- Never modifies repository files, GitHub labels, milestones, or issues during binary installation.\n\nVerification:\n\n```bash\ncommand -v gira\ngira --help\ngira version\ngira upgrade\ngira doctor --repo OWNER/REPO\ngira audit readiness --repo OWNER/REPO\n```\n\n### Developer Source Build\n\nUse `go install` only for source and development workflows, not as a normal user install path:\n\n```bash\ngo install github.com/StatPan/gira/cmd/gira@latest\n```\n\nThe module is `github.com/StatPan/gira` and the binary package is under `cmd/gira`, so the install path includes `/cmd/gira`. If the repository is private in your environment, configure Go private module access first, for example with `GOPRIVATE=github.com/StatPan/gira` plus normal GitHub authentication.\n\nFrom this checkout, build and install the current source version:\n\n```bash\nGOBIN=\"${HOME}/.local/bin\" go install ./cmd/gira\n```\n\nUse a temporary install directory for smoke tests:\n\n```bash\nGOBIN=\"$(mktemp -d)\" go install ./cmd/gira\n\"${GOBIN}/gira\" --help\n\"${GOBIN}/gira\" version\n```\n\n### GitHub Release Archives\n\nManual release-archive installation uses the same release assets as the install script. Release archive names follow:\n\n```text\ngira_VERSION_linux_amd64.tar.gz\ngira_VERSION_linux_arm64.tar.gz\ngira_VERSION_darwin_amd64.tar.gz\ngira_VERSION_darwin_arm64.tar.gz\ngira_VERSION_windows_amd64.zip\n```\n\nExample:\n\n```bash\nversion=v1.0.0\ncurl -fLO \"https://github.com/StatPan/gira/releases/download/${version}/gira_${version}_linux_amd64.tar.gz\"\ntar -xzf \"gira_${version}_linux_amd64.tar.gz\"\ninstall -m 0755 \"gira_${version}_linux_amd64/gira\" \"${HOME}/.local/bin/gira\"\ngira --help\n```\n\nVerify the archive with the release `checksums.txt` before installing the binary. Every v1 release should publish `checksums.txt`; treat a missing checksum asset as a release defect.\n\n### Wrapper Distribution Boundaries\n\nPackage-manager wrappers such as Homebrew, npm, bun, pip, pipx, or `uv` are allowed only as distribution channels for the Go-built release binary. They must not reimplement Gira in another runtime, change the command surface, or install unversioned CI artifacts.\n\nThe npm/bun wrapper package is maintained under `packages/npm`, and the PyPI wrapper package is maintained under `packages/pypi`. Homebrew publishing targets the external `StatPan/homebrew-tap` repository. These channels install the Go-built release binary and verify release checksums.\n\nWrapper packages must preserve the same command surface as the native binary:\n\n```bash\ngira version\ngira ticket start 12 --repo OWNER/REPO --dry-run\ngira ops bootstrap --repo OWNER/REPO --template default --dry-run\ngira ops sync --repo OWNER/REPO --dry-run\ngira status --repo OWNER/REPO --json\n```\n\nOfficial release install channels:\n\n```bash\nnpm install -g @statpan/gira\nbun install -g @statpan/gira\nuv tool install gira-cli\npython -m pip install --user gira-cli\npipx install gira-cli\nbrew tap StatPan/tap\nbrew install gira\n```\n\nThe install script downloads GitHub Release assets directly. The npm and bun channels install the `@statpan/gira` wrapper from the npm registry. The uv, pip, and pipx channels install the `gira-cli` wrapper from PyPI. The Homebrew channel is published through `StatPan/homebrew-tap`. All channels install the same Go-built release binary and keep the `gira` command surface unchanged. Normal release-binary users do not need Go installed.\n\napt/deb packaging is a future target, not an initial official channel. It should wait until usage justifies signing keys, repository hosting, architecture matrix maintenance, and upgrade policy support.\n\nUnsupported distribution channels are source snapshots, unversioned binaries copied from CI artifacts, package wrappers that do not execute the official Go-built binary, and alternate product runtimes.\n\n### Upgrade\n\nCheck the latest release and print the right next step for your install channel:\n\n```bash\ngira upgrade\ngira update\ngira upgrade --channel uv\ngira upgrade --channel pipx\ngira upgrade --json\n```\n\n`gira upgrade` and `gira update` are aliases. They are advisory by default: the installed Go-built binary checks the latest GitHub release and prints the channel-specific command, but it does not run package managers or mutate repositories. If Gira cannot confidently infer how it was installed, pass `--channel install.sh|uv|pipx|pip|homebrew|npm|bun`. Use `--channel go` only for developer source builds.\n\nUse the same channel that installed Gira:\n\n```bash\ncurl -fsSL https://raw.githubusercontent.com/StatPan/gira/main/install.sh | sh\ncurl -fsSL https://raw.githubusercontent.com/StatPan/gira/main/install.sh | GIRA_VERSION=v1.0.0 sh\nuv tool upgrade gira-cli\npython -m pip install --user --upgrade gira-cli\npipx upgrade gira-cli\nbrew update \u0026\u0026 brew upgrade gira\nnpm update -g @statpan/gira\nbun update -g @statpan/gira\n```\n\nUpgrade with the same release channel used for installation. Developer source builds can be refreshed with `go install github.com/StatPan/gira/cmd/gira@latest` or `GOBIN=\"${HOME}/.local/bin\" go install ./cmd/gira`, but those are not normal release-binary upgrade paths.\n\nFor uv, pip, and pipx installs, the `gira-cli` PyPI wrapper caches downloaded native binaries under `GIRA_PYPI_CACHE_DIR` when set, otherwise under `~/.cache/gira-cli/\u003cversion\u003e`. After upgrading, preview stale cache cleanup before deleting anything:\n\n```bash\ngira cache prune --dry-run\ngira cache prune --apply\n```\n\n`gira cache prune` only removes direct child directories with stable semver release names older than the active `gira` version. It skips the active version, newer versions, malformed entries, files, symlinks, and any directory containing the current executable. Use `--root PATH` for a custom wrapper cache and `--json` for automation.\n\nAn upgrade replaces only the local `gira` binary or package wrapper. It must not mutate repository files or GitHub metadata. After upgrading, verify the command still resolves from the expected install location:\n\n```bash\ncommand -v gira\ngira --help\ngira version\ngira upgrade\ngira doctor --repo OWNER/REPO\ngira audit readiness --repo OWNER/REPO\n```\n\n### Binary Uninstall\n\nBinary uninstall removes the local CLI from the machine. It does not detach a repository from Gira and does not delete GitHub labels, milestones, issues, or files.\n\nFor install-script or manual installs:\n\n```bash\ngira_path=\"${GIRA_INSTALL_DIR:+${GIRA_INSTALL_DIR}/gira}\"\ngira_path=\"${gira_path:-$(command -v gira)}\"\nrm \"${gira_path}\"\n```\n\nIf you installed to a custom directory, set `GIRA_INSTALL_DIR` to that same directory or remove the path printed by `command -v gira`. For npm, bun, uv, pip, pipx, or Homebrew installs, uninstall with the same package manager used for installation.\n\nVerification:\n\n```bash\ncommand -v gira\n```\n\nIf `command -v gira` still prints a path, remove the remaining binary or package from that location.\n\n### Repository Detach\n\nRepository detach is separate from binary uninstall. Detach means removing or disabling Gira-managed repository files and GitHub metadata for one repository while leaving the local `gira` binary installed.\n\nFuture command contract:\n\n```bash\ngira ops detach --repo OWNER/REPO --dry-run\ngira ops detach --repo OWNER/REPO --dry-run --json\ngira ops detach --repo OWNER/REPO --apply\n```\n\nDefault behavior must be dry-run-first:\n\n- `gira ops detach --repo OWNER/REPO --dry-run` reports the Gira-managed files, labels, milestones, and bootstrap issues that would be removed, archived, or left in place.\n- `gira ops detach --repo OWNER/REPO --dry-run --json` emits the same plan in machine-readable form for review and automation.\n- `gira ops detach --repo OWNER/REPO --apply` performs only the actions shown by the dry-run plan and should require an explicit apply flag.\n- Destructive deletion is never default behavior. File deletion, GitHub issue closure, label deletion, and milestone deletion must be opt-in and visible in the dry-run plan before apply.\n- Detach must not delete user-authored project history by default. Prefer archiving, closing with an explanatory comment, or leaving unmanaged resources in place unless the operator explicitly requests cleanup.\n\nVerification after detach:\n\n```bash\ngira status --repo OWNER/REPO --json\ngira ops sync --repo OWNER/REPO --dry-run\n```\n\n`status` should make clear that the repository is not fully Gira-managed. `sync --dry-run` should show what would be recreated if the repository is adopted again.\n\n## Daily Happy Path\n\nFrom a fresh shell, make sure the install directory is on `PATH`, then run Gira directly (no source checkout):\n\n```bash\ngira --help\ngira ops sync --repo OWNER/REPO --dry-run\ngira ops onboard verify --repo OWNER/REPO --stage steady-state\ngira status --repo OWNER/REPO\ngira ticket start 12 --repo OWNER/REPO --dry-run\ngira ticket start 12 --repo OWNER/REPO --apply\ngira ticket pr --dry-run\ngira ticket status\n```\n\nThis is the canonical operator path for daily use.\n\nUse `--json` for automation only; human output ends with a concise `next step:` line where Gira can suggest a safe continuation.\n\n`gira start` and `gira work start|pr|status` remain compatibility aliases for users and scripts that already adopted the earlier issue-oriented wording. New documentation uses `ticket` because the intended mental model is Jira-style tickets mapped onto GitHub issues.\n\n## Advanced Adoption And Migration\n\nUse the bootstrap and policy-mode commands when introducing Gira to a new or already-configured repository:\n\n```bash\ngira ops bootstrap --repo OWNER/REPO --template default --dry-run\ngira ops bootstrap --repo OWNER/REPO --path /path/to/repo\ngira ops sync --repo OWNER/REPO --dry-run --policy-mode adopt\ngira ops sync --repo OWNER/REPO --dry-run --policy-mode merge\ngira ops sync --repo OWNER/REPO --dry-run --policy-mode enforce\ngira ops onboard verify --repo OWNER/REPO --stage init --json\ngira status --repo OWNER/REPO --json\n```\n\nPackage-manager wrappers such as npm, bun, uv, pip, pipx, or Homebrew may be used as distribution channels when they install or invoke the Go-built `gira` binary. They are not alternate product implementations.\n\nFor local development from this checkout:\n\n```bash\nGOBIN=\"$(mktemp -d)\" go install ./cmd/gira\n\"${GOBIN}/gira\" --help\n```\n\nTo smoke-test the binary from outside the source checkout:\n\n```bash\nGOBIN=\"$(mktemp -d)\" go install ./cmd/gira\n(cd /tmp \u0026\u0026 \"${GOBIN}/gira\" --help)\n(cd /tmp \u0026\u0026 \"${GOBIN}/gira\" version)\n(cd /tmp \u0026\u0026 \"${GOBIN}/gira\" ops bootstrap --repo OWNER/REPO --template default --dry-run)\n(cd /tmp \u0026\u0026 \"${GOBIN}/gira\" ops bootstrap --repo OWNER/REPO --path /path/to/repo --no-branch)\n(cd /tmp \u0026\u0026 \"${GOBIN}/gira\" ops sync --repo OWNER/REPO --dry-run)\n(cd /tmp \u0026\u0026 \"${GOBIN}/gira\" ops sync --repo OWNER/REPO --dry-run --bootstrap-issues)\n(cd /tmp \u0026\u0026 \"${GOBIN}/gira\" status --repo OWNER/REPO --json)\n```\n\n## Release Flow\n\nTagged Go releases are built by `.github/workflows/release.yml`. Pull requests and `main` pushes run validation builds only. Tags that start with `v` publish stable GitHub Release assets, then publish configured package-manager channels.\n\nThe workflow checks `install.sh` syntax, runs `go test ./...`, runs npm and PyPI wrapper tests, builds Linux, macOS, and Windows CLI archives with version metadata, generates `checksums.txt`, verifies the checksum manifest, and publishes those assets to the GitHub release. Published release assets are treated as immutable; rerun with a new patch tag instead of replacing an existing release. If `NPM_TOKEN` is configured, it publishes `@statpan/gira`. If `PYPI_API_TOKEN` is configured, it publishes `gira-cli`. If `HOMEBREW_TAP_TOKEN` is configured, it updates `StatPan/homebrew-tap`.\n\nMaintainer flow:\n\n```bash\ngit checkout main\ngit pull --ff-only origin main\n$EDITOR CHANGELOG.md\ngit tag -a v1.0.0 -m \"gira v1.0.0\"\ngit push origin v1.0.0\n```\n\nExpected release assets:\n\n```text\nchecksums.txt\ngira_VERSION_linux_amd64.tar.gz\ngira_VERSION_linux_arm64.tar.gz\ngira_VERSION_darwin_amd64.tar.gz\ngira_VERSION_darwin_arm64.tar.gz\ngira_VERSION_windows_amd64.zip\n```\n\nAfter publishing, smoke-test the official installer against the tag:\n\n```bash\ntmpdir=\"$(mktemp -d)\"\nGIRA_INSTALL_DIR=\"${tmpdir}\" GIRA_VERSION=v1.0.0 sh install.sh\n\"${tmpdir}/gira\" --help\n\"${tmpdir}/gira\" version\n```\n\nThe release policy and package-manager channel details are documented in [docs/release-distribution.md](docs/release-distribution.md). Developer experience conventions for first-run onboarding, dry-run/apply output, JSON, recovery, and the issue-to-PR loop are documented in [docs/dx.md](docs/dx.md).\n\nThe Gira 2.0 release-readiness boundary is documented in [docs/v2-release-readiness.md](docs/v2-release-readiness.md). The GitHub-native Product OS schema for future Projects v2 planning, roadmap date semantics, permission/secret model, and dry-run-first automation is documented in [docs/product-os-schema.md](docs/product-os-schema.md). The execution roadmap for that phase is tracked in [docs/product-os-roadmap.md](docs/product-os-roadmap.md). The Gira state ownership model for labels, computed JSON state, receipts, local cache, and storage diagnostics is documented in [docs/state-model.md](docs/state-model.md). The Jira-vs-Gira operating boundary, work decomposition contract, and assistant/dev-agent split are documented in [docs/jira-gira-operating-boundary.md](docs/jira-gira-operating-boundary.md). Goal-level autonomy for long-running agent work is documented in [docs/goal-operating-model.md](docs/goal-operating-model.md). Jira-primary provider mode and workflow safety are documented in [docs/jira-primary-provider.md](docs/jira-primary-provider.md). Closure Funnel stats are documented in [docs/closure-funnel-stats.md](docs/closure-funnel-stats.md), and the Gira-native task momentum design is documented in [docs/task-momentum-loop.md](docs/task-momentum-loop.md). Agent delegation lanes, approval policy, and Delegation Quality metrics are documented in [docs/agent-delegation-lanes.md](docs/agent-delegation-lanes.md). The worker boundary and runtime evidence manifest are documented in [docs/worker-boundary-provenance.md](docs/worker-boundary-provenance.md) and [docs/worker-run-manifest.md](docs/worker-run-manifest.md). The workspace backlog layer is documented in [docs/workspace.md](docs/workspace.md), and the Agent Handoff Queue operating model is documented in [docs/agent-handoff-queue.md](docs/agent-handoff-queue.md). Business-group multi-repo workflow design is documented in [docs/business-group-workflows.md](docs/business-group-workflows.md), and the older portfolio intake compatibility layer is documented in [docs/portfolio-intake.md](docs/portfolio-intake.md). The vendor-neutral dashboard/export boundary for Notion and other consumers is documented in [docs/dashboard-consumer-contract.md](docs/dashboard-consumer-contract.md), and the first concrete export bundle layout is documented in [docs/dashboard-export-artifacts.md](docs/dashboard-export-artifacts.md). The hosted control-plane product boundary and service roadmap are documented in [docs/hosted-control-plane-roadmap.md](docs/hosted-control-plane-roadmap.md). The MVP CRUD support contract is documented in [docs/crud-capability-matrix.md](docs/crud-capability-matrix.md). Adoption on pre-configured repositories is documented in [docs/adoption-migration-playbook.md](docs/adoption-migration-playbook.md).\n\nThe first Gira 3.0 UX decision is documented in [docs/gira-3-local-report-bundle-ux.md](docs/gira-3-local-report-bundle-ux.md): start with a local report bundle over existing state contracts before adding hosted or TUI surfaces. The workspace dashboard contract gaps for that bundle are documented in [docs/workspace-dashboard-contract-gaps.md](docs/workspace-dashboard-contract-gaps.md).\n\nThe dashboard signal projection strategy is documented in [docs/dashboard-signal-projection.md](docs/dashboard-signal-projection.md): add `pulse` and `storage` to the local export bundle before GitHub Projects view expansion or any SQLite/local index.\n\nThe first local workspace report bundle can be generated with `gira export dashboard --config .gira/config.yaml --output out/dashboard --dry-run`, then applied by dropping `--dry-run`.\n\nThis repository dogfoods Gira for its own work. The active operating loop, sprint commands, and maintainer handoff are documented in [docs/dogfood.md](docs/dogfood.md).\n\nExplicit non-goals for 2.0: full GitHub Projects v2 view automation, LLM PRD-to-issue decomposition, Web UI/TUI, chat-bot integration, hosted dashboards, GitLab/Forgejo/Gitea providers, Notion integration, SQLite or another Gira-native planning database as the source of truth, background Jira sync, full bidirectional Jira sync, and Jira workflow mutation. Gira may keep explicit migration helpers, but the 2.0 source of truth is the GitHub execution loop unless a repo explicitly enables Jira-primary planning/status.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstatpan%2Fgira","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstatpan%2Fgira","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstatpan%2Fgira/lists"}