Local-first cache for GitHub Project data with ad hoc and periodic sync.
Project description
gh-project-offline
Local-first cache for a GitHub Project v2 view so humans and agent tools can inspect board data without live GitHub calls on every read.
Alpha scope
This repo is now ready for alpha testing against a real board with:
- read-only sync from one configured GitHub Project v2 view into SQLite
- manual sync and periodic sync
- board item cache plus hydrated issue or pull request details
- cached issue comments, labels, milestone, assignees, state, and raw JSON payloads
- CLI commands for setup checks and offline inspection
- SQL access for human or agent workflows
Not implemented yet
This is still a CLI-first alpha. It does not yet provide:
- a GitHub-like web UI
- dark theme board rendering
- multi-project sync in one config
Quick start
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -e .[dev]
$env:GITHUB_TOKEN = "your-classic-pat"
gh-project-offline start --project-url https://github.com/users/YOUR-OWNER/projects/123/views/1
For end users after publication, prefer:
pipx install gh-project-offline
gh-project-offline start --project-url https://github.com/users/YOUR-OWNER/projects/123/views/1
start is the main onboarding command. It will:
- prompt for the project URL when needed
- prompt for the PAT when the configured env var is missing
- validate access to the target project
- run the first sync with live progress in the CLI
- optionally continue straight into watch mode
- let you keep or override the sync interval before watch starts
- write runtime files under
.ghpo/
Run periodic sync every 15 minutes:
gh-project-offline watch --interval 15m
If GITHUB_TOKEN is missing and you run sync or watch from an interactive terminal, the CLI will prompt for it once for that process.
Config
Example config:
[github]
project_url = "https://github.com/users/YOUR-OWNER/projects/123/views/1"
token_env = "GITHUB_TOKEN"
[storage]
database_path = "data/cache.db"
logs_dir = "logs"
[sync]
interval = "15m"
timeout_seconds = 30
user_agent = "gh-project-offline/0.1.0"
include_closed_items = false
You can still set owner, owner_type, project_number, and view_number explicitly, but project_url is the easiest way to get started.
CLI
gh-project-offline start --project-url <board-or-view-url>gh-project-offline start --forcegh-project-offline setupgh-project-offline init --project-url <board-or-view-url>gh-project-offline doctorgh-project-offline syncgh-project-offline watch --interval 15mgh-project-offline statusgh-project-offline itemsgh-project-offline issuesgh-project-offline find --label bug --state open --status "Todo"gh-project-offline find --interactivegh-project-offline issue owner/repo 123gh-project-offline query "select * from cached_issue_details limit 5"
Cached data
The SQLite cache stores:
- project snapshot JSON
- project fields
- project views when the API exposes them
- items for the configured view
- hydrated issue or pull request details for repo-backed board items
- issue or pull request descriptions or bodies
- issue comments
- raw JSON payloads alongside normalized columns
Runtime artifacts are isolated under one local app folder by default:
- config:
.ghpo/config.toml - SQLite cache:
.ghpo/data/cache.db - per-session logs:
.ghpo/logs/session-YYYYMMDD-HHMMSS.log
If you already used an older root-level layout during local development, run python scripts/migrate_runtime_layout.py once to move gh-project-offline.toml, data/, and logs/ into .ghpo/.
By default, sync skips closed issues and pull requests during local caching. Set include_closed_items = true in config if you want the cache to include them too.
If GitHub rate-limits the sync, the tool stops and tells you the suggested cooldown. It does not auto-retry by default. Incremental sync also reuses cached issue/comment state when GitHub reports the item unchanged, so later syncs are much lighter than the first hydration run.
Test with your board
Use the step-by-step guide in docs/TESTING.md for setup, smoke checks, SQL examples, and troubleshooting. For a newcomer-friendly command guide, see docs/GETTING_STARTED.md.
Token note
For user-owned Project v2 view endpoints, GitHub currently documents that a compatible classic-style personal access token is required rather than a fine-grained token or GitHub App token.
For security, the app does not automatically persist the PAT into system-wide environment variables. The safer default is to prompt for it when needed and use it only in the current process unless the user explicitly chooses their own persistence method.
Release docs
Credits
This CLI builds on:
License
GPL-3.0-only
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gh_project_offline-0.1.0.tar.gz.
File metadata
- Download URL: gh_project_offline-0.1.0.tar.gz
- Upload date:
- Size: 37.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7652ee137c4fc50886c08129c920cf98328803f98a14ebc6735711295a588f23
|
|
| MD5 |
54e60625bde5202ce4e3f8a40f2310a7
|
|
| BLAKE2b-256 |
2eaa1e34f5a761f3c9fd2cd5134b9f726bb22ca799407bc9aa0cff138c01d9ad
|
File details
Details for the file gh_project_offline-0.1.0-py3-none-any.whl.
File metadata
- Download URL: gh_project_offline-0.1.0-py3-none-any.whl
- Upload date:
- Size: 26.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
091085009ef17abec9ddca3240694deba8c084fc167b4999c27194d2f30664b7
|
|
| MD5 |
9b3c7df003543464243d59ce2262d7a7
|
|
| BLAKE2b-256 |
82c8339fd3738b18c5767e97e0433f6e015c4f5a96cbbb191975122d2e4183f3
|