Stitch scattered AI coding work into one durable, local workflow.
Taskstitch is a local-first CLI for tracking development tasks, manual agent runs, decisions, failures, and phase acceptance—without a cloud account or AI API.
After installing Taskstitch, run these commands from the project you want to organize:
taskstitch init
taskstitch status
taskstitch task add "Create README"
taskstitch task listTaskstitch creates .taskstitch/taskstitch.db in that project. Initialization
is idempotent, so running taskstitch init again upgrades and reuses the same
workspace instead of duplicating it.
AI-assisted coding work rarely stays in one place: prompts live in chats, task state in notes, failures in terminal scrollback, and decisions in memory. Taskstitch gives each project a structured local workspace so task state and project context survive between tools and agent sessions.
- Initialize or upgrade a project-local workspace and inspect its status.
- Create, inspect, list, and transition tasks through a small workflow.
- Record planned, running, successful, and failed manual agent runs.
- Record append-only decisions and failures with their context and retry plan.
- Plan, activate, inspect, and complete phases using strict acceptance gates.
- Generate project-wide or phase-scoped local activity reports.
- Create verified whole-workspace SQLite backups and complete versioned JSON project exports without overwriting existing files.
- Validate strict version 1 JSON project exports or import them into a fresh, nonnested workspace.
- Repair a single-project workspace after its project directory moves.
- Run commands from project subdirectories by discovering the nearest workspace.
- Store everything locally in SQLite with Alembic-managed schema upgrades.
- Operate without an account, hosted service, or AI-provider connection.
Taskstitch requires Python 3.12 or newer and uv.
Until a package is published, install it from a source checkout:
git clone https://github.com/3xpp/Taskstitch.git
cd Taskstitch
uv tool install .
taskstitch --helpFor development, use the repository's isolated environment instead:
uv sync
uv run taskstitch --help| Command | Purpose |
|---|---|
taskstitch init [--name NAME] |
Initialize, upgrade, or repair the current workspace. |
taskstitch status |
Show the project, current phase, task counts, and latest logs. |
taskstitch report [--phase ID] |
Summarize phase, task, run, decision, and failure activity. |
taskstitch backup [-o PATH] |
Create and verify a whole-workspace SQLite snapshot. |
taskstitch export [-o PATH] |
Export the current project as complete versioned JSON. |
taskstitch import SOURCE [--check] |
Validate or import a version 1 project export into a fresh workspace. |
taskstitch task add/show/list/update |
Manage task records and task status. |
taskstitch run add/show/list/update |
Record a manual agent run and its lifecycle. |
taskstitch decision add/list/show |
Record append-only project decisions. |
taskstitch failure add/list/show |
Record append-only failures and retry plans. |
taskstitch phase add/show/list/update/activate/complete |
Manage phase lifecycle and acceptance gates. |
taskstitch orchestrate --task ID... |
Launch paired local automation for explicit task IDs. |
taskstitch orchestrate show/list/resume/stop/... |
Inspect or resolve durable orchestration batches. |
Use taskstitch --help or taskstitch <group> --help for argument and option
details.
Automation is opt-in and local-only. Create .taskstitch/automation.toml with
taskstitch automation init, define at least one check, then set enabled = true
and run taskstitch automation check. Writer and reviewer roles are distinct
Codex/Claude processes; native sandbox capability is required and preflight
fails closed when it cannot be proven. Credentials are never copied into
manifests, receipts, logs, or SQLite.
Launch in the foreground or persist a self-contained detached batch:
taskstitch orchestrate --task 12 --task 13
taskstitch orchestrate --task 12 --detach
taskstitch orchestrate list
taskstitch orchestrate show BATCH_ID --format json
taskstitch orchestrate resume BATCH_ID
taskstitch orchestrate stop BATCH_IDIntegration is serialized and local Git only: orchestration never fetches,
pulls, pushes, or creates remote refs. Receipts and journals are retained for
failed, interrupted, quarantined, and uncertain sessions; cleanup removes only
identity-checked disposable artifacts after terminal evidence is complete.
Use quarantine and resolve for preserved resources rather than forcing
deletion. Parallel tasks should not rely on hidden ordering or shared mutable
files; express dependencies as explicit task sequencing and checks.
Add a task to the active phase, optionally with a description and an initial status:
taskstitch task add "Implement database" \
--description "Add the initial SQLite migration" \
--status doing
taskstitch task list --status doing
taskstitch task show 1Update task progress without changing its original title or description:
taskstitch task update 1 --status done| Status | Meaning |
|---|---|
todo |
Ready but not started. |
doing |
Work is in progress. |
blocked |
Progress needs a decision, dependency, or retry. |
done |
The task's acceptance criteria are met. |
Tasks can be created only while a phase is active. A completed phase's tasks cannot be changed.
Taskstitch records work performed by an agent; it does not start an agent or send a prompt to a provider. Create a run before the work, then update it once you have an outcome:
taskstitch run add "Implement the feature" --task 1
taskstitch run update 1 --status running
taskstitch run update 1 --status succeeded \
--output-summary "Implementation completed and checks passed"
taskstitch run list --status succeeded
taskstitch run show 1A new run starts as planned. It can move to running, succeeded, or
failed; a running run can move to succeeded or failed. Successful and
failed runs require a nonblank --output-summary, and terminal runs cannot be
changed again. A run can be linked to a task with --task; unlinked runs use
the active phase.
Decisions and failures are append-only records. Add enough context that a later session can understand the outcome without reconstructing terminal history:
taskstitch decision add "Use service layer" \
--context "Commands need reuse" \
--decision "Keep services" \
--reason "Testable boundaries"
taskstitch failure add "First attempt failed" \
--cause "Invalid input" \
--retry-plan "Validate before retry" \
--task 1
taskstitch decision list
taskstitch decision show 1
taskstitch failure list --task 1
taskstitch failure show 1All decision fields and the failure summary, cause, and retry plan must contain
visible text. Both record types attach to the active phase; a failure linked to
a task attaches to that task's phase instead. status displays the most
recent decision and failure.
Initialization creates the active Phase 0 - Bootstrap. Add planned phases,
write their acceptance criteria, then activate the one you are ready to work
on:
taskstitch phase add "Release" --acceptance-criteria "Package and smoke test pass"
taskstitch phase activate 2
taskstitch phase show 2
taskstitch phase listThere can be at most one active phase; activating a planned phase returns the
previous active phase to planned. Completed phases cannot be activated.
Complete an active phase only after every task in it is done:
taskstitch task update 2 --status done
taskstitch phase complete 2The completion gate is deliberately strict. phase complete fails unless the
target phase is active, has nonblank acceptance criteria, and has no unfinished
tasks. There is no force override. Running the command is your attestation
that the written criteria have been met. A phase with no tasks can complete
once it has criteria.
Summarize the entire current project or focus the same metrics on one phase:
taskstitch report
taskstitch report --phase 1Reports show phase, task, and manual-run totals by status plus decision and
failure records. Task completion means done / all tasks. Terminal-run success
means succeeded / (succeeded + failed); planned and running runs do not affect
that rate. A rate is n/a when its denominator is zero.
Unexpected stored statuses appear as other so category totals always
reconcile. Phase reports include only records attached to that phase; records
without a phase remain visible only in the project-wide report. Failure totals
are labeled failure records because Taskstitch does not track resolution state.
Create timestamped artifacts in the ignored Taskstitch workspace:
taskstitch backup
taskstitch exportThe defaults are .taskstitch/backups/ for verified SQLite snapshots and
.taskstitch/exports/ for versioned JSON. Choose an existing destination
directory explicitly when the artifact must live elsewhere:
taskstitch backup --output ../safe/taskstitch.db
taskstitch export --output ../safe/taskstitch.jsonTaskstitch will never overwrite an existing path, and these commands have no force option. A custom output's parent directory must already exist. On POSIX systems, artifact paths must use directories owned by you or root, with sticky-bit protection on every shared-writable directory.
A backup uses SQLite's online backup API and preserves the entire workspace database, including every project record and stored root path held there. Committed WAL state is included. An export contains only the current project matching the workspace, omits its machine-specific stored root path, and includes every phase, task, run, decision, and failure field needed for later import work. Reports are likewise scoped to the current project.
A project export can be checked and imported into a new project directory:
mkdir ../transfer
taskstitch export --output ../transfer/project.json
mkdir ../imported-project
cd ../imported-project
taskstitch import ../transfer/project.json --check
taskstitch import ../transfer/project.jsonImport accepts only Taskstitch project-export format version 1. --check
performs parsing and validation plus the complete database migration,
insertion, and SQLite verification pipeline in private disposable storage. It
can run inside an existing workspace and does not inspect, create, or modify
destination state.
A real import uses the exact current directory as the new canonical root. The
directory must already exist, have no .taskstitch path of any kind, and be
outside every discoverable workspace, so an import cannot accidentally create
a nested workspace. It preserves IDs, timestamps, text, statuses, nulls, and
relationships while rebinding only the stored project root.
Imported entity timestamps are preserved as UTC values at microsecond precision. Taskstitch's canonical entity timestamp strings retain their exact values through an export/import/export round trip. An otherwise valid handcrafted entity timestamp with a shorter fractional part may be emitted later in canonical six-digit form.
A backup is not a restore command. JSON import is not a whole-database SQLite-backup restore: it consumes one project export and creates new workspace state. There is no merge, overwrite, restore in place, legacy import, sync, force, or best-effort mode.
Final publication uses hard links from a staged file in the destination directory so a concurrently created path cannot be replaced. The staged file and destination are on the same filesystem, and that filesystem must support hard links. If it does not, Taskstitch fails safely instead of using a replacement fallback. A custom destination does not need to share a filesystem with the workspace because staging happens beside the requested destination.
Both artifacts are plaintext and can contain descriptions, prompts, summaries,
decisions, failures, causes, retry plans, and other sensitive content. Export
JSON and the imported SQLite database are plaintext as well. Store and share
them deliberately. A backup inside the same project is useful before logical
changes but does not protect against project deletion, disk failure, or device
loss; use --output on separate storage for that risk.
Each initialized project has one ignored workspace directory containing its SQLite database and, when requested, generated artifacts:
.taskstitch/
├── backups/ # created on demand
├── exports/ # created on demand
└── taskstitch.db
Commands search the current directory and its parents for the nearest
initialized workspace. Use taskstitch backup for a consistent whole-database
snapshot, taskstitch export for a project-scoped JSON document, and
taskstitch import only from the intended fresh project root.
After moving an initialized project, run taskstitch init from its new root.
When that workspace contains exactly one project record, Taskstitch updates the
stored root while preserving its phases, tasks, runs, decisions, and failures.
If multiple project records make the repair ambiguous, it stops without
choosing or deleting data.
Legacy .conductor/ directories are left untouched and are not discovered as
Taskstitch workspaces.
Taskstitch is not a secret store. Never place API keys, passwords, access
tokens, private keys, session secrets, personal data, or other credentials in
task descriptions, run prompts or summaries, decision or failure logs,
examples, public issues, or pull requests. The current CLI does not read
.env files.
Backup and export artifacts and an imported SQLite database are plaintext and
may reproduce descriptions, prompts, summaries, decisions, failures, and other
sensitive stored project history. Default artifacts remain ignored under
.taskstitch/, but a custom output may not be ignored. Protect these files,
and do not commit or share them casually.
| Command | Action |
|---|---|
make install |
Sync the locked project with uv. |
make dev |
Show taskstitch --help. |
make test |
Run the unit test suite. |
make lint |
Run Ruff checks. |
make typecheck |
Run strict mypy checks over src. |
make format |
Format code and apply safe Ruff fixes. |
make build |
Build the source distribution and wheel. |
Tests use pytest temporary directories and never create Taskstitch state in a developer's home directory.
- Taskstitch records manual agent work; it does not call AI providers or execute coding agents.
- Task titles and descriptions are immutable after creation.
- Decision and failure records are append-only and cannot be edited or deleted.
- There is no dashboard, GitHub integration, authentication, or multi-user synchronization.
- Whole-database restore, JSON merge or overwrite, legacy import, and sync workflows are not built in.
- Explicit recovery for deliberately rebinding ambiguous moved workspaces.
- Read-only workspace diagnostics and integrity checks.
- Optional provider integrations only after the manual workflow is stable.