Metadata-Version: 2.4
Name: djobs
Version: 0.15.0
Summary: Local repository memory, passive observations, and explicit handoff for coding agents.
Project-URL: Homepage, https://jhuang-tw.github.io/djobs/
Project-URL: Repository, https://github.com/jhuang-tw/djobs
Project-URL: Documentation, https://jhuang-tw.github.io/djobs/
Project-URL: Issues, https://github.com/jhuang-tw/djobs/issues
License-Expression: MIT
License-File: LICENSE
Keywords: ai-agent,claude-code,codex,coding-agent,context-recovery,copilot,cross-agent-handoff,gemini,kimi-code,local-agent-memory,mcp,model-context-protocol,multi-agent,passive-hooks,repository-memory,resumable-workflow,sqlite,workflow-state
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Software Development :: Libraries
Classifier: Topic :: Software Development :: Quality Assurance
Classifier: Topic :: System :: Distributed Computing
Requires-Python: >=3.10
Requires-Dist: mcp[cli]<2,>=1.0
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pre-commit>=3.5; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: pyyaml>=6.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: pg
Requires-Dist: psycopg[binary]>=3.1; extra == 'pg'
Description-Content-Type: text/markdown

# djobs

**Local repository memory and handoff for coding agents.**

`djobs` is intentionally local-first:

- MCP servers run on the user's machine;
- hooks run on the user's machine;
- state is stored in local SQLite;
- Git observations are produced from the local working tree;
- no hosted service, remote database, cloud queue, or account is required.
- Python 3.10+ is supported.

GitHub Copilot CLI and VS Code Agent are the default integration host because one local Copilot adapter can serve every model selected inside Copilot. GPT, Claude, Gemini, or another model running inside Copilot all use the same djobs MCP and hooks.

The core remains client-neutral. Codex, Claude Code, Gemini CLI, Kimi Code, and custom agents may use optional local adapters, the same MCP server, or the Git sidecar.

## Zero-touch start

Add or install **djobs** as an MCP server in the coding host you already use. That is the
only required user action.

On the first call to `sync_workspace`, `checkpoint`, or `handoff`, djobs automatically:

- creates the shared local SQLite memory at `~/.djobs/global.db` when needed;
- identifies the current Git repository and records its first bounded snapshot;
- detects Copilot, Codex, Claude Code, Gemini CLI, or Kimi Code when the host exposes its
  identity;
- installs or repairs only that host's passive local lifecycle adapter;
- preserves unrelated MCP servers, hooks, and settings;
- continues the coding request even if initialization cannot be completed.

There is no per-project command and no setup wizard. Opening another repository automatically
uses a separate repository identity inside the same local database. A host that cannot be
identified still gets repository-scoped MCP memory; djobs simply avoids guessing which hook
configuration to modify.

The CLI remains available only for manual installation, diagnostics, or repair in headless
environments:

```powershell
pipx install djobs
djobs setup
djobs doctor
```

Those commands are not part of the normal Vibe Coding flow after the MCP is installed.

### VS Code extension

The headless VS Code extension follows the same model. Its native MCP launch identifies itself
as Copilot, so the first tool call silently installs the passive Copilot lifecycle adapter. The
**djobs: Set up / Repair djobs** command remains as a fallback when the Python package itself is
missing or an older launch path needs repair. The extension still adds no task sidebar, polling
loop, or cloud service.

## Local Copilot-first architecture

```text
GPT / Claude / Gemini / other model
                 │
                 ▼
       local GitHub Copilot host
      CLI + VS Code Agent adapter
                 │
          hooks + compact MCP
                 │
                 ▼
        ~/.djobs/global.db
                 │
      observations + explicit tasks
```

The default design stops at the local machine. It does not create a remote MCP service, synchronize state through GitHub, or add a cloud persistence backend.

The Copilot adapter uses the native versioned hook format at:

```text
~/.copilot/hooks/djobs.json
```

It records these passive lifecycle events:

- session start;
- successful and failed tool results;
- pre-compaction state;
- real session end.

It deliberately does **not** install `UserPromptSubmit` or `Stop` automation. Ordinary prompts do not become tasks, and a model turn ending does not release ownership.

## Automatic observations versus explicit ownership

Automatic adapters may:

- load compact local state at session start without claiming it;
- record successful and failed tool outcomes;
- snapshot Git state and report changed paths;
- save a small marker before context compaction;
- heartbeat a task already claimed by the same session.

Automatic adapters never:

- turn every user prompt into a task;
- claim the newest pending task at startup;
- release work at every model `Stop` event;
- infer completion from natural-language output;
- overwrite another client's lease.

Ownership changes only through explicit operations:

```text
checkpoint(summary, path?, details?)
handoff(task_id, evidence, completed?)
```

Example:

```text
Copilot opens repository A
  -> SessionStart reads local tasks and observations
  -> checkpoint("Implement parser", path="src/parser.py")
  -> this Copilot session owns the explicit lease
  -> tool hooks record observations without creating tasks
  -> handoff(task_id, "Parser complete; edge tests remain")

Another local agent opens repository A
  -> sync_workspace reads the released task and Git observations
  -> checkpoint("Implement parser", path="src/parser.py")
  -> resumes the same task instead of creating a duplicate
```

If an agent disappears without a handoff, its lease eventually expires and normal local recovery makes the work available again.

## Optional local host adapters

Use a specific target only when that host runs independently from Copilot:

```powershell
djobs setup copilot
djobs setup codex
djobs setup claude
djobs setup gemini
djobs setup kimi
```

Configure every detected local host only when separate integrations are intentional:

```powershell
djobs setup all
```

| Host | Local user configuration | Passive events |
|---|---|---|
| GitHub Copilot CLI + VS Code Agent | `~/.copilot/hooks/djobs.json` | session start/end, tool success/failure, pre-compact |
| Codex | `~/.codex/hooks.json` | session start/end, tool result, pre-compact |
| Claude Code | `~/.claude/settings.json` | session start/end, tool success/failure, pre-compact |
| Gemini CLI | `~/.gemini/settings.json` | session start/end, after-tool, pre-compress |
| Kimi Code | `~/.kimi-code/config.toml` | one-time prompt context, session end, tool success/failure, pre-compact |

Kimi's MCP entry is merged into `~/.kimi-code/mcp.json`. Other hosts use their supported local MCP registration commands. Only djobs-managed entries are replaced or removed. Malformed settings are never overwritten automatically.

For Codex, review and trust newly installed local commands through `/hooks` when prompted.

Repair and remove also default to Copilot:

```powershell
djobs repair
djobs remove
djobs repair all
djobs remove kimi
```

## Any future or custom local agent

The normalized event entrypoint accepts any client identifier:

```bash
# The client sends its native hook JSON on stdin.
djobs agent-event session-start --client my-agent
djobs agent-event post --client my-agent
djobs agent-event post-failure --client my-agent
djobs agent-event pre-compact --client my-agent
djobs agent-event session-end --client my-agent
```

An adapter only maps native event names and payload fields to this command. Queue and ownership logic stay in the shared local core.

For a client with no hook mechanism, use the local Git sidecar:

```bash
djobs observe /path/to/repository --watch
```

The sidecar records real working-tree transitions. Its fingerprint includes tracked, staged, and bounded untracked content, so a second edit is detected even when `git status` still shows the same `M` state. Contents are hashed for comparison and are not stored as observation text.

MCP itself cannot force every possible client to call a tool at session start. The common local guarantees are the shared data format, Git observation fallback, MCP/CLI access, and explicit ownership semantics.

## Compact MCP tools

The default server exposes four tools:

| Tool | Purpose |
|---|---|
| `sync_workspace()` | Read tasks plus recent observations for the current repository under a token budget. It never claims work. |
| `checkpoint(summary, path?, details?)` | Deliberately create or resume and atomically claim one unit of work. |
| `handoff(task_id, evidence, completed?)` | Explicitly release or complete owned work with bounded evidence. |
| `resume_delta(correlation_id, ...)` | Backward-compatible revision recovery for integrations already storing IDs. |

Lower-level queue tools remain available through `djobs-mcp-full`.

## Observation durability and privacy

Observations use their own schema and never masquerade as jobs.

- Snapshot compare-and-record is one immediate transaction, so concurrent clients do not duplicate the same repository transition.
- Each repository keeps at most 1,000 recent observations by default.
- Metadata remains valid JSON when bounded.
- Common bearer tokens, API keys, passwords, authorization values, and URL passwords are redacted on a best-effort basis.
- Stored task text and observations are untrusted data, never executable instructions.
- Hook, sidecar, or storage failure is fail-open and does not block coding.
- No observation or task state is uploaded by djobs.

## Repository detection

The resolver uses:

1. MCP client roots;
2. cwd supplied by a host, adapter, or event;
3. the enclosing Git repository root;
4. the process startup directory.

Starting in `repo/src/feature` resolves to `repo`. Windows, WSL, and common Git Bash spellings share one repository identity, while compatible aliases keep earlier path-based state readable.

## Local storage

Default database:

```text
~/.djobs/global.db
```

Override it with `DJOBS_DB`:

```powershell
$env:DJOBS_DB = "D:\state\team-djobs.db"
djobs-mcp
```

A repository-specific database is also supported:

```powershell
djobs mcp --db .djobs/state.db
```

Do not commit the database.

## Compatibility status

| Surface | Validation level |
|---|---|
| Copilot hook document, idempotent install/remove, MCP registration shape, and Copilot-default setup | Automated unit tests. |
| Repository resolution, shared SQLite, atomic claims, leases, isolation, and token bounds | Automated Python tests. |
| Passive observation versus explicit ownership | Automated integration tests against SQLite. |
| Optional Codex, Claude, Gemini, and Kimi configuration merge | Unit tests against documented configuration shapes. |
| Content-aware Git snapshots, concurrent deduplication, metadata validity, retention, and redaction | Unit and isolated SQLite tests. |
| Real installed clients and native Windows/macOS/Linux behavior | Requires machine-level verification; not claimed by the isolated build environment. |

## Development

```bash
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

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

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

## License

MIT
