{"id":44542374,"url":"https://github.com/gioe/tusk","last_synced_at":"2026-06-17T01:01:21.508Z","repository":{"id":338091736,"uuid":"1156554140","full_name":"gioe/tusk","owner":"gioe","description":"Portable task management for Claude Code — local SQLite DB, CLI, and skills for autonomous workflows","archived":false,"fork":false,"pushed_at":"2026-06-11T23:53:34.000Z","size":7732,"stargazers_count":1,"open_issues_count":34,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-12T00:14:32.216Z","etag":null,"topics":["ai-agents","claude-code","cli","developer-tools","sqlite","task-management"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gioe.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"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-02-12T19:28:47.000Z","updated_at":"2026-06-11T23:53:29.000Z","dependencies_parsed_at":null,"dependency_job_id":"3688fcf3-d5c6-4dec-a6f4-0ab3f9254065","html_url":"https://github.com/gioe/tusk","commit_stats":null,"previous_names":["gioe/tusker","gioe/tusk"],"tags_count":1009,"template":false,"template_full_name":null,"purl":"pkg:github/gioe/tusk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gioe%2Ftusk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gioe%2Ftusk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gioe%2Ftusk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gioe%2Ftusk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gioe","download_url":"https://codeload.github.com/gioe/tusk/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gioe%2Ftusk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34429493,"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-16T02:00:06.860Z","response_time":126,"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":["ai-agents","claude-code","cli","developer-tools","sqlite","task-management"],"created_at":"2026-02-13T19:01:10.367Z","updated_at":"2026-06-17T01:01:21.436Z","avatar_url":"https://github.com/gioe.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# tusk\n\nA portable task and context handoff system for AI-assisted software projects. Tusk gives Claude Code and Codex a local SQLite database, CLI, skills/prompts, and durable task records so agents can track, prioritize, resume, and complete work without relying on the original chat transcript.\n\n## What You Get\n\n- **`tusk` CLI** — single entry point for task state, context hydration, criteria, dependencies, sessions, review, and merge operations\n- **Skills and prompts** — Claude Code skills and Codex prompt ports for task workflows (`/tusk-init`, `/tusk`, `/create-task`, `/groom-backlog`)\n- **Durable context snapshots** — objectives, tasks, criteria, progress, jots, reviews, and context atoms preserve enough handoff context for a future agent to act\n- **Scripts** — Python utilities for task briefs, duplicate detection, dependency management, summaries, dashboard data, and migrations\n- **Config-driven schema** — define your project's domains, task types, agents, and validation rules in JSON; validation triggers are generated automatically\n\n## Quick Start\n\n```bash\n# Clone the repo somewhere on your machine\ngit clone https://github.com/gioe/tusk.git\n\n# From your project root (must be a git repo)\ncd /path/to/your/project\n/path/to/tusk/install.sh\n```\n\nThis will:\n1. Install `tusk`, skills, scripts, and default config\n2. Create `tusk/config.json` with defaults\n3. Initialize the database at `tusk/tasks.db`\n\nThen start a new Claude Code session and run `/tusk-init` — it will scan your codebase, suggest domains and agents, write your config, and seed tasks from TODOs.\n\nYou can also configure manually by editing `tusk/config.json` and running `tusk init --force`.\n\n## Context Handoff Model\n\nTusk treats the database as a durable context snapshot, not just a backlog. Objectives capture larger intent, tasks stay scoped to shippable work, criteria define completion, verifications prove the work, and compact context atoms preserve decisions, risks, assumptions, and memory for the next agent.\n\nThe write side of tusk (`/create-task`, `/retro`, `/investigate`, and direct task or criteria commands) records structured context as work is discovered. The read side (`/tusk`, `/resume-task`, `/chain`) starts from the task record, criteria, dependencies, progress, and `tusk task-brief \u003cid\u003e` so it can hydrate only the relevant context needed to ship the next change.\n\n### Upgrading\n\nTo pull the latest version of tusk into an installed project:\n\n```bash\ntusk upgrade\n```\n\nThis downloads the latest release from GitHub, updates all files (CLI, skills, scripts), and runs schema migrations. Your config (`tusk/config.json`) and database (`tusk/tasks.db`) are never touched.\n\n## Configuration\n\nEdit `tusk/config.json` after install:\n\n```json\n{\n  \"domains\": [\"Frontend\", \"Backend\", \"Infrastructure\", \"Docs\"],\n  \"task_types\": [\"bug\", \"feature\", \"refactor\", \"test\", \"docs\", \"infrastructure\"],\n  \"statuses\": [\"To Do\", \"In Progress\", \"Done\"],\n  \"priorities\": [\"Highest\", \"High\", \"Medium\", \"Low\", \"Lowest\"],\n  \"closed_reasons\": [\"completed\", \"expired\", \"wont_do\", \"duplicate\"],\n  \"agents\": {\n    \"frontend-engineer\": \"React, CSS, and UI components\",\n    \"backend-engineer\": \"API endpoints, database, and server logic\"\n  },\n  \"test_command\": \"pytest tests/\",  // shell command run by `tusk commit` before staging; empty string disables\n  \"review\": {\n    \"mode\": \"ai_only\",              // \"disabled\" skips /review-commits; \"ai_only\" runs one AI reviewer\n    \"max_passes\": 2,                // maximum review-fix-re-review cycles before stopping\n    \"reviewer\": { \"name\": \"general\", \"description\": \"...\" }  // single AI reviewer persona; omit for inline review only\n  },\n  \"dupes\": {\n    \"check_threshold\": 0.82,        // cosine similarity above which a task is flagged as a likely duplicate\n    \"similar_threshold\": 0.6        // cosine similarity above which a task is surfaced as possibly similar\n  },\n  \"merge\": {\n    \"mode\": \"local\"                 // \"local\" = fast-forward merge; \"pr\" = squash-merge via gh pr merge\n  },\n  \"project_type\": \"ios_app\"        // selects bootstrap/\u003cproject_type\u003e.json for task seeding (null = disabled)\n}\n```\n\n- **domains**: Empty array means no domain validation (any value accepted)\n- **task_types**: Empty array means no task_type validation\n- **agents**: Used by `/groom-backlog` to auto-assign tasks; empty object skips assignment\n- **statuses**, **priorities**, **closed_reasons**: Changing these is possible but not recommended\n- **test_command**: Shell command run by `tusk commit` before staging files; a non-zero exit blocks the commit. Empty string disables the check.\n- **review.mode**: Controls `/review-commits` behavior — `\"disabled\"` skips AI review entirely; `\"ai_only\"` runs the configured reviewer\n- **review.max_passes**: Maximum number of review → fix → re-review cycles before the skill stops iterating\n- **review.reviewer**: Optional AI reviewer persona with `name` and `description`. When absent, `/review-commits` falls back to inline (non-agent) review\n- **dupes.check_threshold**: Cosine similarity score (0–1) above which a candidate is treated as a likely duplicate and blocked\n- **dupes.similar_threshold**: Cosine similarity score (0–1) above which a candidate is surfaced as possibly similar (for human review)\n- **merge.mode**: `\"local\"` performs a fast-forward merge directly; `\"pr\"` squash-merges via `gh pr merge`\n- **project_type**: Selects which `bootstrap/\u003cproject_type\u003e.json` file is used for task seeding during `/tusk-init`; `null` disables seeding\n\n### Project Bootstrap\n\nDuring `/tusk-init`, tusk can seed your backlog with a starter set of tasks based on your project type. Set `project_type` in `tusk/config.json` (or via `/tusk-update`) to enable this.\n\nTwo built-in project types are included:\n\n| `project_type` | Library repo | What gets seeded |\n|---|---|---|\n| `ios_app` | [gioe/ios-libs](https://github.com/gioe/ios-libs) — standalone Swift Package providing SharedKit (UI design tokens) and APIClient (HTTP client) | Tasks for adding the SPM dependency, configuring design tokens, and wiring up APIClient |\n| `python_service` | [gioe/python-libs](https://github.com/gioe/python-libs) — standalone Python package (`gioe-libs`) providing structured logging and observability utilities | Tasks for installing the package, configuring structured logging, and enabling observability |\n\nBootstrap files live under `bootstrap/` in the tusk source repo and are copied to `.claude/bin/bootstrap/` at install time. A new reader can review them to see exactly which tasks they will receive before running `/tusk-init`.\n\n## CLI Reference\n\n```bash\ntusk \"SELECT ...\"           # Run SQL\ntusk -header -column \"SQL\"   # With formatting flags\ntusk path                    # Print resolved DB path\ntusk config                  # Print full config JSON\ntusk config domains          # List valid domains\ntusk config agents           # List configured agents\ntusk init                    # Bootstrap DB (safe — skips if exists)\ntusk init --force            # Recreate DB from scratch\ntusk shell                   # Interactive sqlite3 shell\ntusk version                 # Print installed version\ntusk migrate                 # Apply pending schema migrations\ntusk upgrade                 # Upgrade tusk from GitHub\ntusk task-brief \u003cid\u003e         # Compile a pickup brief for context hydration\ntusk context add \u003cid\u003e --type decision --content \"...\"  # Add a durable context atom\ntusk context list \u003cid\u003e       # List active context atoms for a task\n```\n\n## Skills\n\n| Skill | Description |\n|-------|-------------|\n| `/tusk` | Get the highest-priority ready task and start working on it |\n| `/tusk 42` | Begin the full dev workflow on task #42 |\n| `/tusk list 5` | Show top 5 ready tasks |\n| `/tusk preview` | Show next task without starting it |\n| `/groom-backlog` | Analyze and clean up the backlog |\n| `/tusk-init` | Interactive setup wizard — scans codebase, suggests config, seeds tasks |\n\n## CLAUDE.md Setup\n\nThe `/tusk-init` skill can generate this automatically. To add it manually:\n\n```markdown\n## Task Queue\n\nThe project task database is managed via `tusk`. Use it for all task operations:\n\n    tusk \"SELECT ...\"          # Run SQL\n    tusk -header -column \"SQL\"  # With formatting flags\n    tusk path                   # Print resolved DB path\n    tusk config                 # Print project config\n    tusk init                   # Bootstrap DB\n\nNever hardcode the DB path — always go through `tusk`.\n```\n\n## Schema\n\nThe database schema is documented in detail in [`docs/DOMAIN.md`](docs/DOMAIN.md). At a high level, tusk stores:\n\n- **Objectives** for larger product or project intent\n- **Tasks** for shippable work units, with status, priority, scope, dependencies, and closeout metadata\n- **Acceptance criteria** for completion promises\n- **Task context items** for durable handoff atoms such as assumptions, risks, decisions, questions, memory, and entry points\n- **Progress, sessions, skill runs, and reviews** for auditability, cost tracking, resumability, and proof of completion\n\nThe schema is migration-backed and config-aware: enum-like fields are validated by SQLite triggers generated from `tusk/config.json`, while migrations preserve existing task history during upgrades.\n\n## Pricing\n\n`pricing.json` contains per-model token rates (USD per million tokens) used by `tusk session-stats` to compute the `cost_dollars` column in `task_sessions`. It ships with tusk and is updated via `tusk pricing-update`.\n\n### Structure\n\n```json\n{\n  \"models\": {\n    \"claude-sonnet-4-6\": {\n      \"input\": 3.0,\n      \"cache_write_5m\": 3.75,\n      \"cache_write_1h\": 6.0,\n      \"cache_read\": 0.3,\n      \"output\": 15.0\n    }\n  },\n  \"aliases\": {\n    \"claude-sonnet-4-6-20250918\": \"claude-sonnet-4-6\"\n  }\n}\n```\n\n- **`models`**: Canonical model IDs mapped to USD per million tokens (e.g., `\"input\": 3.0` = $3.00/MTok) for five token categories\n- **`aliases`**: Date-stamped model IDs mapped to their canonical key (e.g., `claude-sonnet-4-6-20250918` → `claude-sonnet-4-6`)\n\n### How costs are calculated\n\n`tusk-session-stats.py` parses Claude Code JSONL transcripts, aggregates the `usage` object from each API response, resolves the model ID (exact match → alias lookup → prefix match), and computes cost as:\n\n```\ncost = (usage.input_tokens / 1M × input)\n     + (cache_creation.ephemeral_5m_input_tokens / 1M × cache_write_5m)\n     + (cache_creation.ephemeral_1h_input_tokens / 1M × cache_write_1h)\n     + (usage.cache_read_input_tokens / 1M × cache_read)\n     + (usage.output_tokens / 1M × output)\n```\n\nThe left side of each term comes from the transcript; the right side comes from the model's entry in `pricing.json`. When the nested `cache_creation` object is absent (older transcripts), all `cache_creation_input_tokens` are assigned to the 5m tier as a fallback. Claude Code automatically writes JSONL transcripts to `~/.claude/projects/\u003cproject_hash\u003e/` during each session — tusk reads these but never writes them. A typical usage object in the transcript looks like:\n\n```json\n{\n  \"input_tokens\": 2750,\n  \"output_tokens\": 483,\n  \"cache_creation_input_tokens\": 12500,\n  \"cache_read_input_tokens\": 8200,\n  \"cache_creation\": {\n    \"ephemeral_5m_input_tokens\": 10000,\n    \"ephemeral_1h_input_tokens\": 2500\n  }\n}\n```\n\nIf `pricing.json` is missing or a model isn't found, cost defaults to `$0` with a warning.\n\n### Updating prices\n\n```bash\ntusk pricing-update              # Fetch latest from Anthropic and update (both cache tiers)\ntusk pricing-update --dry-run    # Show diff without writing\ntusk session-recalc              # Re-run cost calculations for all existing sessions\n```\n\n## How It Works\n\nThe `tusk` CLI is the single source of truth for the database path. Everything references it:\n\n- **Skills** call `tusk \"SQL\"` (never raw `sqlite3`)\n- **Python scripts** resolve the path via `subprocess.check_output([\"tusk\", \"path\"])`\n- **Config** lives at `tusk/config.json`; triggers are generated from it at init time\n\nIf the DB path ever changes, update one line in `bin/tusk`.\n\n## File Structure\n\nAfter installation, your project will have:\n\n```\nyour-project/\n├── .claude/\n│   ├── bin/\n│   │   ├── tusk                       # CLI (single source of truth)\n│   │   ├── tusk-dupes.py              # Duplicate detection (via tusk dupes)\n│   │   ├── tusk-session-stats.py      # Token/cost tracking (via tusk session-stats)\n│   │   ├── config.default.json        # Fallback config\n│   │   ├── pricing.json               # Per-model token rates (USD/MTok)\n│   │   └── VERSION                    # Installed distribution version\n│   └── skills/\n│       ├── tusk/SKILL.md\n│       ├── groom-backlog/SKILL.md\n│       ├── tasks/SKILL.md\n│       └── tusk-init/SKILL.md\n├── scripts/\n│   └── manage_dependencies.py\n└── tusk/\n    ├── config.json                    # Your project's config\n    └── tasks.db                       # The database\n```\n\n## Troubleshooting\n\n### Skill not found after install\n\nIf Claude Code reports an unknown skill (e.g., `/tusk` not recognized) immediately after running `install.sh`, the skill was installed mid-session and has not been discovered yet.\n\n**Resolution:** Start a new Claude Code session. Skills are discovered at session startup — a skill added after the session began will not be available until you restart.\n\n### Task stuck in the wrong state\n\nIf a task is stuck `In Progress` when it should be `To Do`, or you need to force-close a task that has open criteria:\n\n```bash\n# Reopen an In Progress task back to To Do\ntusk task-reopen \u003ctask_id\u003e --force\n\n# Force-close a task (e.g., wont_do) even if criteria are open\ntusk task-done \u003ctask_id\u003e --reason wont_do --force\n```\n\n### Migration failure\n\nIf `tusk migrate` fails or reports that schema changes cannot be applied, check for a version mismatch between the installed CLI and the database schema:\n\n```bash\ntusk version          # distribution version of the installed CLI\ntusk shell            # opens sqlite3 shell; then run: PRAGMA user_version;\n```\n\nIf `user_version` is ahead of what the installed CLI knows about, you may have downgraded the CLI. Re-run `tusk upgrade` to restore the latest version, then retry `tusk migrate`.\n\n### Database corruption\n\nIf the database is corrupted and `tusk` commands are failing with SQLite errors:\n\n\u003e **Warning:** `tusk init --force` **destroys all existing task data**. Back up `tusk/tasks.db` before proceeding.\n\n```bash\ncp tusk/tasks.db tusk/tasks.db.bak   # back up first\ntusk init --force                     # recreate the database from scratch\n```\n\nAfter reinitializing, re-run `tusk migrate` to apply any pending schema migrations.\n\n## Reporting Issues\n\nFound a bug or have a feature request? Open an issue at https://github.com/gioe/tusk/issues.\n\nIf you're reporting a problem from a project where tusk is installed (rather than from the tusk source repo itself), please use the **[Tusk instance feedback](https://github.com/gioe/tusk/issues/new?template=tusk-instance-feedback.md)** issue template. It prompts for your tusk version, project context, observed behavior, reproduction steps, and expected behavior — which helps diagnose issues across different installation environments.\n\n\u003e **Note:** Do not patch `.claude/bin/` files directly. Those files are managed by tusk and will be overwritten the next time you run `tusk upgrade`. To contribute a fix, open an issue or submit a pull request to the source repository.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgioe%2Ftusk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgioe%2Ftusk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgioe%2Ftusk/lists"}