Skip to main content

Local project memory that helps coding agents continue work across AI sessions.

Project description

djobs — project memory for coding agents

Stop explaining the same project every time you open a new AI session.

Yesterday your coding agent read the repository, tried a fix, found why the tests failed, and changed several files. Today the chat is gone or the context was compacted, so it starts over.

djobs keeps a small, local memory for each Git repository so the next session can recover:

  • what you asked for and which constraints matter;
  • which tools succeeded or failed;
  • what changed in the working tree;
  • a compact end-of-session capsule with the goal, progress, failures, and next step.

It searches those memories using the current request instead of blindly replaying the latest chat history. Memory stays in local SQLite. No account, hosted service, or project upload is required.

What continuing work looks like

Session 1
You: Fix the OAuth callback loop. Keep the public auth API and preserve '+' in state.
Agent: pytest failed because normalization removed '+'.
Agent: updated src/auth/callback.py; one integration test remains.
[context compacts or the session closes]

Session 2
You: Continue the OAuth fix.
Agent receives from djobs:
- Goal: fix the OAuth callback loop without changing the public auth API
- Failed: state normalization removed '+'
- Progress: callback parser updated; integration test remains
- Current Git changes

The recovered text is data, not an instruction. The coding agent still follows your current request.

Install once, then open any repository

The easiest route for VS Code / GitHub Copilot users is the VS Code extension. It registers the local MCP server without adding a sidebar or background polling UI.

For another MCP host, add this server once:

{
  "servers": {
    "djobs": {
      "command": "uvx",
      "args": ["djobs", "mcp"]
    }
  }
}

After the MCP is present, normal Vibe Coding needs no per-project command and no setup wizard. The first djobs tool call creates ~/.djobs/global.db, identifies the current Git repository, and installs only the detected host's passive lifecycle adapter. Opening another repository uses a different local memory automatically.

djobs setup and djobs doctor remain available only for manual repair or diagnostics in headless environments.

What is saved automatically

Memory Example Changes task ownership?
User intent “Keep Python 3.10 support; do not replace Zustand.” No
Tool result “edit completed — src/parser.py — fallback parser updated” No
Tool failure “pytest failed — state normalization removed plus signs” No
Git observation Actual tracked, staged, and bounded untracked changes No
Session capsule Goal, recent progress, failures, and next step No

Exact duplicate prompts in the same session are ignored. Before context compaction and at real session end, djobs creates a deterministic capsule without calling an external model or sending repository content anywhere.

Relevant memory, not just recent memory

Agents should call:

sync_workspace(query="the user's current request")

The query searches repository-scoped memory with SQLite FTS5 when available and a portable bounded fallback otherwise. Older relevant constraints and failed approaches can therefore rank above newer unrelated activity.

You can also ask the agent naturally:

What does djobs remember about the OAuth bug?
Forget the memory about the abandoned Redis experiment.
Clear djobs memory for this repository.

The MCP exposes a memory tool for list, search, forget, and confirmed clear actions. Clearing passive memory does not delete explicit tracked tasks.

Terminal equivalents are available when useful:

djobs memory list
djobs memory search "OAuth callback"
djobs memory forget MEMORY_ID
djobs memory clear --yes

Privacy controls

  • State is stored locally in ~/.djobs/global.db by default.
  • Common API keys, bearer tokens, passwords, authorization values, and URL credentials are redacted on a best-effort basis before storage.
  • Put [djobs:no-memory] in a prompt to skip that prompt.
  • Set DJOBS_CAPTURE_USER_INTENT=0 to disable automatic prompt-intent memory.
  • Use memory(action="forget", memory_id="...") to delete one record.
  • Use confirmed memory(action="clear") to clear passive memory for the current repository.
  • Stored content is always treated as untrusted data, never executable instructions.
  • Hook, search, or storage failures are fail-open and never block the coding request.

Recovery-payload benchmark

The repository includes a deterministic proxy benchmark:

python scripts/benchmark_project_memory.py

With its default synthetic 18-file fixture, the current implementation compares:

Recovery strategy Estimated context Minimum calls
Re-read every synthetic source file ~7,805 tokens 18 file reads
Query-aware sync_workspace ~407 tokens 1 MCP call

That is a 94.8% recovery-payload proxy reduction for this fixture. It is intentionally not presented as provider billing, latency, or model-quality measurement. The script is included so results can be reproduced and challenged instead of treated as a marketing claim.

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 supported native session/tool hooks ~/.codex/hooks.json

Only djobs-managed entries are replaced or removed. Malformed configuration is never overwritten automatically. An unidentified host still gets repository-scoped MCP memory; djobs simply avoids guessing which hook file to modify.

Python 3.10+ is supported on Windows, macOS, and Linux.

Default MCP tools

The normal server deliberately stays small:

Tool Purpose
sync_workspace(query?, ...) Recover relevant goals, failures, capsules, tasks, and Git observations under a token budget.
memory(action, ...) Inspect, search, forget, or explicitly clear passive memory for the current repository.
checkpoint(summary, ...) Explicitly create or resume one tracked unit of work.
handoff(task_id, ...) Explicitly release or complete tracked work with bounded evidence.
resume_delta(correlation_id, ...) Backward-compatible revision recovery for integrations already storing IDs.

Lower-level queue and worker tools remain opt-in through djobs-mcp-full.

Advanced: explicit ownership and handoff

Passive memory never creates or claims tasks. Ownership changes only through explicit checkpoint and handoff calls:

checkpoint("Implement parser", path="src/parser.py")
  -> this session owns one expiring lease

handoff(task_id, "Parser updated; edge tests remain", completed=false)
  -> releases the work with evidence for a later session

Automatic adapters may heartbeat a task already owned by the same session, but they never:

  • turn every prompt into a task;
  • claim pending work at startup;
  • infer completion from natural-language output;
  • release work when a model turn merely stops;
  • overwrite another client's lease.

This explicit layer is optional for people who only need project memory.

Repository identity and storage

Repository resolution uses MCP roots, host cwd, the enclosing Git root, and finally process cwd. Windows paths, WSL mounts, and common Git Bash spellings resolve to compatible identities.

Default database:

~/.djobs/global.db

Override it with DJOBS_DB. A repository-specific database is also supported with djobs mcp --db .djobs/state.db; do not commit the database.

Each repository retains at most 1,000 recent visible observations by default. Git contents are hashed for change detection and are not stored as observation text.

Development

git clone https://github.com/jhuang-tw/djobs.git
cd djobs
python -m venv .venv
# activate the venv
python -m pip install -e ".[dev,pg]"

ruff check src/ tests/
ruff format --check src/ tests/
mypy
pytest -q
python -m build
python -m twine check dist/*

cd vscode-ext
npm ci
npx tsc -p ./ --noEmit
npm run compile

See CONTRIBUTING.md and AGENTS.md before changing public behavior.

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

djobs-0.16.0.tar.gz (133.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

djobs-0.16.0-py3-none-any.whl (138.5 kB view details)

Uploaded Python 3

File details

Details for the file djobs-0.16.0.tar.gz.

File metadata

  • Download URL: djobs-0.16.0.tar.gz
  • Upload date:
  • Size: 133.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for djobs-0.16.0.tar.gz
Algorithm Hash digest
SHA256 837ce0a1fdafc833ccd0eb6bc133403d95ea630fda07b96c6ae1dcfb05fd7c6a
MD5 cbbc430718255856ceccafe18052c15f
BLAKE2b-256 222716411947b9d3a9a77dc4c698a62345acce13be1735e5edc1ddb73a4cb256

See more details on using hashes here.

Provenance

The following attestation bundles were made for djobs-0.16.0.tar.gz:

Publisher: publish.yml on jhuang-tw/djobs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file djobs-0.16.0-py3-none-any.whl.

File metadata

  • Download URL: djobs-0.16.0-py3-none-any.whl
  • Upload date:
  • Size: 138.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for djobs-0.16.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a77552079ec6ebcf1af599cabc96976d14ae0f2713d93cf194428daec5f2795b
MD5 03108fca2aa8f7c975a76a50c77a3228
BLAKE2b-256 3036b6adc19a93d0880072ca45fede2438ac9715c8d27fbec0c58cc16da5cf52

See more details on using hashes here.

Provenance

The following attestation bundles were made for djobs-0.16.0-py3-none-any.whl:

Publisher: publish.yml on jhuang-tw/djobs

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page