Local project memory that helps coding agents continue work across AI sessions.
Project description
djobs
Local project memory and explicit handoff for AI coding agents.
Continue the repository instead of explaining it again in every new AI session.
Why djobs exists
A coding agent can spend an entire session reading a repository, discovering a failed approach, learning a project constraint, editing several files, and leaving one test unfinished. When the chat closes or context is compacted, the next session often starts from zero.
djobs keeps a small local memory for each Git repository so a later session can recover:
- the user's goal and important constraints;
- successful and failed tool results;
- actual Git working-tree changes;
- a structured session capsule with progress, failures, and the next step;
- explicit task ownership and handoff evidence when coordinated work needs it.
Memory stays in local SQLite. No hosted account, remote queue, vector database, or project upload is required.
What continuing work looks like
Session 1
You: Fix the OAuth callback loop. Preserve '+' in state and do not change the public API.
Agent: pytest failed because normalization removed '+'.
Agent: callback parser updated; one integration test remains.
[chat closes or context compacts]
Session 2
You: Continue the OAuth fix.
djobs recovers:
- Goal: fix the callback loop without changing the public API
- Constraint: preserve '+' in state
- Failed approach: normalization removed '+'
- Progress: parser updated; integration test remains
- Current Git changes
Recovered text is treated as untrusted data, not as an instruction. The current user request always remains authoritative.
How it works
- Capture the session. Bounded user intent, tool results, failures, Git changes, and a deterministic structured capsule are stored as local data.
- Search for the current request.
sync_workspace(query=..., context_tier="resume")retrieves relevant repository memory under a token budget instead of replaying an entire chat history. - Continue with evidence. The agent resumes from useful state and uses explicit checkpoint or handoff only when coordinated work needs ownership.
Layered recovery
Ordinary continuation should not pay for full audit detail. sync_workspace now exposes three
recovery tiers:
| Tier | Best for | Returned detail |
|---|---|---|
resume |
Normal continuation | Goal, constraints, progress, failures, next step, task state, and Git state |
evidence |
Reviewing why a result was selected | Resume capsule plus compact supporting observations without IDs or timestamps |
audit |
Diagnosis and lifecycle updates | Full memory identifiers, timestamps, and audit detail |
The MCP defaults to resume. Direct Python callers retain the previous audit-shaped default for
compatibility and can opt into a smaller tier explicitly.
The response also includes a context_hash. A host can send it back as known_context_hash on the
next equivalent recovery. When selected passive memory is unchanged, djobs suppresses repeated
observations while still returning current task state.
Install once
VS Code / GitHub Copilot
Install the djobs VS Code extension. It registers the local MCP server and manages setup, repair, diagnostics, pause, and resume without adding a permanent sidebar, dashboard, polling loop, remote service, or cloud database.
The first djobs MCP call creates ~/.djobs/global.db and installs the detected passive lifecycle
adapter. There is no required per-project setup ritual.
Any MCP-compatible host
Add the server once:
{
"servers": {
"djobs": {
"command": "uvx",
"args": ["djobs", "mcp"]
}
}
}
Manual repair remains available for headless or damaged environments:
pipx install djobs
# or: uv tool install djobs
djobs setup
djobs doctor
Two layers, kept deliberately separate
Passive project memory
Normal sessions can record bounded observations without creating or claiming tasks.
| Memory | Example |
|---|---|
| User intent | “Keep Python 3.10 support.” |
| Tool result | “Updated src/parser.py; focused tests passed.” |
| Tool failure | “State normalization removed plus signs.” |
| Git observation | Tracked, staged, and bounded untracked changes |
| Session capsule | Goal, progress, failures, and next step |
Sibling Git worktrees share passive repository memory. Exact task ownership and leases remain
isolated to each checkout. WSL /mnt/<drive>/... paths resolve to the same Windows repository
identity when djobs runs on Windows.
Explicit checkpoint and handoff
Use explicit ownership only when coordinated work actually needs it:
checkpoint("Implement parser", path="src/parser.py")
-> this checkout owns one expiring lease
handoff(task_id, "Parser updated; edge tests remain", completed=false)
-> releases the task with bounded evidence
Passive hooks never silently turn every prompt into a task, claim another agent's work, or infer completion from natural-language output.
Five compact MCP tools
| Tool | Purpose |
|---|---|
sync_workspace(query?, context_tier="resume", known_context_hash?, ...) |
Recover a minimal continuation capsule, compact evidence, or full audit detail under a token budget. |
memory(action, ...) |
List, search, deactivate, forget, or explicitly clear passive repository memory. |
checkpoint(summary, ...) |
Deliberately create or resume one checkout-scoped unit of work. |
handoff(task_id, ...) |
Release or complete tracked work with bounded evidence. |
resume_delta(correlation_id, ...) |
Compatibility path for integrations that already persist revision IDs. |
Lower-level queue and worker tools remain available through djobs-mcp-full rather than occupying
every normal coding context.
Supported local hosts
| Host | Prompt-aware memory | Lifecycle observations | Local configuration |
|---|---|---|---|
| GitHub Copilot CLI + VS Code Agent | UserPromptSubmit |
session, tool, compact, end | ~/.copilot/hooks/djobs.json |
| Claude Code | UserPromptSubmit |
session, tool, compact, end | ~/.claude/settings.json |
| Gemini CLI | BeforeAgent |
session, tool, compress, end | ~/.gemini/settings.json |
| Kimi Code | UserPromptSubmit |
session, tool, compact, end | ~/.kimi-code/config.toml |
| Codex | query-aware MCP recovery | native session/tool hooks when available | ~/.codex/hooks.json |
Requirements
| Component | Requirement |
|---|---|
| Python runtime | Python 3.10+; Python 3.10–3.14 tested in CI |
| VS Code extension | VS Code 1.101 or newer |
| Extension development | Node.js 20+ |
| Storage | Local SQLite by default |
| Operating systems | Windows, macOS, Linux |
End users do not need Node.js. Node is required only to build or package the VS Code extension.
Reproducible recovery benchmarks
python scripts/benchmark_project_memory.py
python scripts/benchmark_resume_quality.py
| Recovery strategy | Estimated context | Minimum calls |
|---|---|---|
| Re-read every synthetic source file | ~7,805 tokens | 18 file reads |
Query-aware sync_workspace resume tier |
~224 tokens | 1 MCP call |
That is a 97.1% recovery-payload proxy reduction for the bundled synthetic fixture. It is not provider billing, latency, or model-quality measurement. The second benchmark verifies cross-worktree recall, checkout ownership isolation, stale-memory exclusion, and unchanged-context replay suppression.
Measure verified-task efficiency
Token reduction alone can hide repeated repairs. djobs gain now reports savings together with
workflow efficiency:
djobs gain
djobs gain --history
djobs gain --format json
The report includes first-pass verified rate, repair attempts, average attempts per verified task, cycle-time proxy, and estimated context tokens per verified task. These are local workflow proxies, not provider billing or exact model-call telemetry.
Privacy and control
- State defaults to
~/.djobs/global.db. - Common API keys, bearer tokens, passwords, authorization values, and URL credentials are redacted on a best-effort basis before storage.
- Add
[djobs:no-memory]to skip one prompt. - Set
DJOBS_CAPTURE_USER_INTENT=0to disable automatic prompt-intent capture. - Mark memory
resolved,superseded,stale, orcontradictedwithout erasing the audit trail. - Delete one memory or explicitly clear passive memory for the repository family.
- Hook, search, and storage failures are fail-open and never block the coding request.
Explicit checkpoint demo
The durable-task flow remains available for work that needs exact checkpoints and handoff:
Development
git clone https://github.com/jhuang-tw/djobs.git
cd djobs
python -m venv .venv
# activate the environment
python -m pip install -e ".[dev,pg]"
ruff check src tests scripts/prepare_auto_release.py scripts/extract_release_notes.py
ruff format --check src tests scripts/prepare_auto_release.py scripts/extract_release_notes.py
mypy
pytest -q
python -m build
python -m twine check dist/*
cd vscode-ext
# Node.js 20+
npm ci
npx tsc -p ./ --noEmit
npm run compile
See CONTRIBUTING.md, AGENTS.md, and docs/RELEASE.md before changing public behavior.
PyPI · VS Code Marketplace · Documentation · Issues
MIT licensed.
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 djobs-0.18.0.tar.gz.
File metadata
- Download URL: djobs-0.18.0.tar.gz
- Upload date:
- Size: 138.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
de973651137aa95b5ed4839ab6885ecfba48e2dd569c58921add78c90d3a5f40
|
|
| MD5 |
b9af2de492ddbd863e6d94443492382a
|
|
| BLAKE2b-256 |
1d938b117b0fab889c8ac7d777dfd317f054a4b106b7e7595d02fcee4044cb97
|
Provenance
The following attestation bundles were made for djobs-0.18.0.tar.gz:
Publisher:
publish.yml on jhuang-tw/djobs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
djobs-0.18.0.tar.gz -
Subject digest:
de973651137aa95b5ed4839ab6885ecfba48e2dd569c58921add78c90d3a5f40 - Sigstore transparency entry: 2234769511
- Sigstore integration time:
-
Permalink:
jhuang-tw/djobs@98f5b0af967fab77836381122076ab8e33f6f65a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/jhuang-tw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@98f5b0af967fab77836381122076ab8e33f6f65a -
Trigger Event:
push
-
Statement type:
File details
Details for the file djobs-0.18.0-py3-none-any.whl.
File metadata
- Download URL: djobs-0.18.0-py3-none-any.whl
- Upload date:
- Size: 143.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
65df04a6adeeb94e0b9903ec6261b9671d0d2f916ce5001b809729223022399e
|
|
| MD5 |
602767e7b38e7571bd5775bcedfb9856
|
|
| BLAKE2b-256 |
24cef6048b3a8cf860e311402ac087f658650a96fadc4757f8fa9ad049f0572a
|
Provenance
The following attestation bundles were made for djobs-0.18.0-py3-none-any.whl:
Publisher:
publish.yml on jhuang-tw/djobs
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
djobs-0.18.0-py3-none-any.whl -
Subject digest:
65df04a6adeeb94e0b9903ec6261b9671d0d2f916ce5001b809729223022399e - Sigstore transparency entry: 2234770144
- Sigstore integration time:
-
Permalink:
jhuang-tw/djobs@98f5b0af967fab77836381122076ab8e33f6f65a -
Branch / Tag:
refs/heads/main - Owner: https://github.com/jhuang-tw
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@98f5b0af967fab77836381122076ab8e33f6f65a -
Trigger Event:
push
-
Statement type: