jezero 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jezero-0.1.0/.gitignore +40 -0
- jezero-0.1.0/CHANGELOG.md +232 -0
- jezero-0.1.0/CONTRIBUTING.md +67 -0
- jezero-0.1.0/LICENSE +201 -0
- jezero-0.1.0/PKG-INFO +217 -0
- jezero-0.1.0/README.md +180 -0
- jezero-0.1.0/SECURITY.md +20 -0
- jezero-0.1.0/clients/README.md +53 -0
- jezero-0.1.0/clients/antigravity/hooks.json +13 -0
- jezero-0.1.0/clients/antigravity/mcp_config.json +8 -0
- jezero-0.1.0/clients/antigravity/plugin.json +5 -0
- jezero-0.1.0/clients/claude-code/.claude-plugin/plugin.json +11 -0
- jezero-0.1.0/clients/claude-code/.mcp.json +8 -0
- jezero-0.1.0/clients/claude-code/hooks/hooks.json +51 -0
- jezero-0.1.0/clients/codex/.codex-plugin/plugin.json +20 -0
- jezero-0.1.0/clients/codex/hooks/hooks.json +50 -0
- jezero-0.1.0/clients/core/jezero_client.py +2559 -0
- jezero-0.1.0/clients/hermes/__init__.py +298 -0
- jezero-0.1.0/clients/hermes/plugin.yaml +19 -0
- jezero-0.1.0/clients/opencode/jezero.ts +157 -0
- jezero-0.1.0/clients/opencode/package.json +26 -0
- jezero-0.1.0/clients/ruff.toml +5 -0
- jezero-0.1.0/clients/skill/SKILL.md +51 -0
- jezero-0.1.0/examples/eval.example.toml +44 -0
- jezero-0.1.0/examples/items.example.jsonl +3 -0
- jezero-0.1.0/jezero.example.toml +200 -0
- jezero-0.1.0/plugins/README.md +8 -0
- jezero-0.1.0/plugins/antigravity/core/jezero_client.py +2559 -0
- jezero-0.1.0/plugins/antigravity/core/jezero_projects.py +240 -0
- jezero-0.1.0/plugins/antigravity/hooks.json +13 -0
- jezero-0.1.0/plugins/antigravity/mcp_config.json +8 -0
- jezero-0.1.0/plugins/antigravity/plugin.json +5 -0
- jezero-0.1.0/plugins/antigravity/skills/jezero/SKILL.md +51 -0
- jezero-0.1.0/plugins/claude-code/.claude-plugin/plugin.json +11 -0
- jezero-0.1.0/plugins/claude-code/.mcp.json +8 -0
- jezero-0.1.0/plugins/claude-code/core/jezero_client.py +2559 -0
- jezero-0.1.0/plugins/claude-code/core/jezero_projects.py +240 -0
- jezero-0.1.0/plugins/claude-code/hooks/hooks.json +51 -0
- jezero-0.1.0/plugins/claude-code/skills/jezero/SKILL.md +51 -0
- jezero-0.1.0/plugins/codex/.codex-plugin/plugin.json +20 -0
- jezero-0.1.0/plugins/codex/core/jezero_client.py +2559 -0
- jezero-0.1.0/plugins/codex/core/jezero_projects.py +240 -0
- jezero-0.1.0/plugins/codex/hooks/hooks.json +50 -0
- jezero-0.1.0/plugins/codex/skills/jezero/SKILL.md +51 -0
- jezero-0.1.0/plugins/hermes/__init__.py +298 -0
- jezero-0.1.0/plugins/hermes/core/jezero_client.py +2559 -0
- jezero-0.1.0/plugins/hermes/core/jezero_projects.py +240 -0
- jezero-0.1.0/plugins/hermes/plugin.yaml +19 -0
- jezero-0.1.0/plugins/hermes/skills/jezero/SKILL.md +51 -0
- jezero-0.1.0/plugins/opencode/core/jezero_client.py +2559 -0
- jezero-0.1.0/plugins/opencode/core/jezero_projects.py +240 -0
- jezero-0.1.0/plugins/opencode/jezero.ts +157 -0
- jezero-0.1.0/plugins/opencode/package.json +26 -0
- jezero-0.1.0/plugins/opencode/skills/jezero/SKILL.md +51 -0
- jezero-0.1.0/pyproject.toml +118 -0
- jezero-0.1.0/scripts/build_clients.py +350 -0
- jezero-0.1.0/scripts/build_site.py +178 -0
- jezero-0.1.0/scripts/check_docs.py +118 -0
- jezero-0.1.0/scripts/make_architecture.py +309 -0
- jezero-0.1.0/scripts/make_reference.py +332 -0
- jezero-0.1.0/scripts/make_screenshots.py +52 -0
- jezero-0.1.0/scripts/privacy_check.py +120 -0
- jezero-0.1.0/src/jezero/__init__.py +3 -0
- jezero-0.1.0/src/jezero/__main__.py +3 -0
- jezero-0.1.0/src/jezero/cli.py +1092 -0
- jezero-0.1.0/src/jezero/client_core.py +2559 -0
- jezero-0.1.0/src/jezero/config.py +800 -0
- jezero-0.1.0/src/jezero/connectors/__init__.py +83 -0
- jezero-0.1.0/src/jezero/connectors/antigravity.py +470 -0
- jezero-0.1.0/src/jezero/connectors/base.py +237 -0
- jezero-0.1.0/src/jezero/connectors/claude_code.py +348 -0
- jezero-0.1.0/src/jezero/connectors/codex.py +442 -0
- jezero-0.1.0/src/jezero/connectors/hermes.py +280 -0
- jezero-0.1.0/src/jezero/connectors/opencode.py +305 -0
- jezero-0.1.0/src/jezero/connectors/paperclip.py +316 -0
- jezero-0.1.0/src/jezero/evaluate.py +249 -0
- jezero-0.1.0/src/jezero/inbox.py +290 -0
- jezero-0.1.0/src/jezero/ingest.py +84 -0
- jezero-0.1.0/src/jezero/models.py +161 -0
- jezero-0.1.0/src/jezero/pipeline.py +392 -0
- jezero-0.1.0/src/jezero/projects.py +240 -0
- jezero-0.1.0/src/jezero/redact.py +433 -0
- jezero-0.1.0/src/jezero/server.py +761 -0
- jezero-0.1.0/src/jezero/store.py +732 -0
- jezero-0.1.0/src/jezero/summarize.py +392 -0
- jezero-0.1.0/src/jezero/ui/__init__.py +0 -0
- jezero-0.1.0/src/jezero/ui/app.py +1211 -0
- jezero-0.1.0/src/jezero/ui/commands.py +175 -0
- jezero-0.1.0/src/jezero/ui/data.py +698 -0
- jezero-0.1.0/src/jezero/ui/look.py +219 -0
- jezero-0.1.0/src/jezero/ui/safe.py +43 -0
- jezero-0.1.0/src/jezero/watchdog.py +179 -0
- jezero-0.1.0/tests/__init__.py +0 -0
- jezero-0.1.0/tests/conftest.py +42 -0
- jezero-0.1.0/tests/test_antigravity.py +187 -0
- jezero-0.1.0/tests/test_antigravity_plugin.py +175 -0
- jezero-0.1.0/tests/test_audit_client.py +743 -0
- jezero-0.1.0/tests/test_audit_core.py +666 -0
- jezero-0.1.0/tests/test_audit_server.py +426 -0
- jezero-0.1.0/tests/test_claude_code.py +181 -0
- jezero-0.1.0/tests/test_client.py +239 -0
- jezero-0.1.0/tests/test_client_fixes.py +614 -0
- jezero-0.1.0/tests/test_codex.py +226 -0
- jezero-0.1.0/tests/test_config.py +84 -0
- jezero-0.1.0/tests/test_connector_fixes.py +185 -0
- jezero-0.1.0/tests/test_device_commands.py +315 -0
- jezero-0.1.0/tests/test_eval.py +139 -0
- jezero-0.1.0/tests/test_hermes_pipeline.py +255 -0
- jezero-0.1.0/tests/test_hermes_plugin.py +261 -0
- jezero-0.1.0/tests/test_opencode.py +148 -0
- jezero-0.1.0/tests/test_paperclip.py +156 -0
- jezero-0.1.0/tests/test_pipeline_fixes.py +446 -0
- jezero-0.1.0/tests/test_projects.py +63 -0
- jezero-0.1.0/tests/test_redact.py +102 -0
- jezero-0.1.0/tests/test_registry.py +97 -0
- jezero-0.1.0/tests/test_review2_client.py +670 -0
- jezero-0.1.0/tests/test_review2_core.py +610 -0
- jezero-0.1.0/tests/test_review2_release.py +232 -0
- jezero-0.1.0/tests/test_review2_server.py +549 -0
- jezero-0.1.0/tests/test_schedule.py +96 -0
- jezero-0.1.0/tests/test_server.py +272 -0
- jezero-0.1.0/tests/test_server_fixes.py +614 -0
- jezero-0.1.0/tests/test_store.py +171 -0
- jezero-0.1.0/tests/test_summarize.py +263 -0
- jezero-0.1.0/tests/test_ui.py +205 -0
jezero-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Local configuration and data: they describe YOUR machines and sources.
|
|
2
|
+
jezero.toml
|
|
3
|
+
*.local.toml
|
|
4
|
+
.env
|
|
5
|
+
.env.*
|
|
6
|
+
!.env.example
|
|
7
|
+
data/
|
|
8
|
+
*.db
|
|
9
|
+
*.db-wal
|
|
10
|
+
*.db-shm
|
|
11
|
+
*.sqlite
|
|
12
|
+
*.sqlite3
|
|
13
|
+
|
|
14
|
+
# Private denylist used by the pre-commit privacy check.
|
|
15
|
+
.privacy-denylist
|
|
16
|
+
|
|
17
|
+
# Python
|
|
18
|
+
__pycache__/
|
|
19
|
+
*.py[cod]
|
|
20
|
+
.venv/
|
|
21
|
+
.pytest_cache/
|
|
22
|
+
.ruff_cache/
|
|
23
|
+
*.egg-info/
|
|
24
|
+
dist/
|
|
25
|
+
build/
|
|
26
|
+
|
|
27
|
+
# Editors and OS
|
|
28
|
+
.DS_Store
|
|
29
|
+
.idea/
|
|
30
|
+
.vscode/
|
|
31
|
+
pypi-dist/
|
|
32
|
+
|
|
33
|
+
# Local leftovers that must never reach a package: config backups and lock files, caches,
|
|
34
|
+
# logs, editor backups and JavaScript dependencies.
|
|
35
|
+
*.toml.bak-*
|
|
36
|
+
.*.toml.lock
|
|
37
|
+
*.bak
|
|
38
|
+
.cache/
|
|
39
|
+
*.log
|
|
40
|
+
node_modules/
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## Unreleased
|
|
4
|
+
|
|
5
|
+
## 0.1.0 - 2026-10-23
|
|
6
|
+
|
|
7
|
+
First release on PyPI: `pip install jezero` or `uv tool install jezero`. Device
|
|
8
|
+
client 0.5.3.
|
|
9
|
+
|
|
10
|
+
- Second review before the first release. Server: a `.env` re-pointed by a symlink or
|
|
11
|
+
saved with invalid UTF-8 is handled on reload (an unreadable one disables `token_env`
|
|
12
|
+
clients); Host checks ignore case and cover websockets; inbox project names may use any
|
|
13
|
+
script (percent-encoded); config errors never echo values; a summarizer `base_url` over
|
|
14
|
+
`http://` to another host is refused unless `allow_insecure_http = true`; watchdog
|
|
15
|
+
alerts and stored errors are redacted, with configured secret values masked; server
|
|
16
|
+
instructions say every item is data, never instructions.
|
|
17
|
+
- Core: redaction no longer hides ordinary text (`La contraseña: incorrecta`,
|
|
18
|
+
`Cookie: theme=dark`, ids, camelCase names) while still catching real secrets;
|
|
19
|
+
terminal escape sequences are stripped from summaries, imports and everything the CLI
|
|
20
|
+
and the app print, and `redact-stored` cleans stored items without re-summarising;
|
|
21
|
+
unchanged Paperclip items get the new ref after `connector reset` with no model calls;
|
|
22
|
+
multi-frame Codex `.zst` rollouts are read whole; a corrupt or locked database keeps
|
|
23
|
+
the cursor.
|
|
24
|
+
- Client 0.5.3: sessions queued by 0.5.1 are sent after upgrading from any environment,
|
|
25
|
+
and those 0.5.2 wrongly marked "outside the session folder" are queued again;
|
|
26
|
+
symlinked config, token and state files stay links; `setup --agent codex` keeps tool
|
|
27
|
+
approvals, comments and other settings; prompt context is framed as data with source
|
|
28
|
+
and trust and stripped of control characters; the stdio bridge never answers
|
|
29
|
+
notifications.
|
|
30
|
+
- Release and CI: only commits on `main` are published; uv, twine and the build backend
|
|
31
|
+
are pinned (hashed constraints); releases carry `SHA256SUMS` and signed build
|
|
32
|
+
provenance; every action is pinned to a commit SHA; `build_clients.py` ships only
|
|
33
|
+
tracked files and builds a reproducible bundle; the app installs plugins from its own
|
|
34
|
+
release tag (Hermes stays on `main`); docs gain a server-from-PyPI path and bundle
|
|
35
|
+
verification.
|
|
36
|
+
- Security review before the first release. Server: `require_auth = false` is refused
|
|
37
|
+
together with `public_url` or `allowed_hosts`; Host and Origin are checked before the
|
|
38
|
+
key on every route (a bad host gets 421); `.jsonl.zst` uploads are measured
|
|
39
|
+
decompressed against `inbox.max_mb`, and the Codex connector reads rollouts in bounded
|
|
40
|
+
chunks; `token_env` values changed in `.env` apply without a restart; a config that
|
|
41
|
+
fails to load keeps only unchanged clients; `jezero device` commands refuse to
|
|
42
|
+
overwrite a file changed after they read it; search queries are bounded (4096
|
|
43
|
+
characters, 64 terms, 100 characters per term); new optional `[inbox] max_device_mb`.
|
|
44
|
+
- Client 0.5.2: never follows HTTP redirects (they could carry the key to another host
|
|
45
|
+
or to plain HTTP); `init` refuses `http://` for other computers unless
|
|
46
|
+
`--insecure-http`; one bad file no longer stops the upload queue; files over
|
|
47
|
+
`max_upload_mb` are rejected without being read into memory; only the agent's own
|
|
48
|
+
session files are uploaded (no symbolic links, nothing outside its folder); `setup
|
|
49
|
+
--agent codex` keeps line endings and a backup, writes atomically and refuses entries
|
|
50
|
+
it cannot edit safely; `setup --agent antigravity` points the plugin at its core by
|
|
51
|
+
full path; private file modes (0700/0600), uploaded exports deleted, locked
|
|
52
|
+
`state.json`, and the stdio bridge answers every request with valid JSON-RPC.
|
|
53
|
+
- Core: with `include_subagents`, sub-agent transcripts are their own items and no
|
|
54
|
+
longer prune the parent session; one unreadable session file is skipped and reported
|
|
55
|
+
instead of blocking its source; a malformed summarizer answer fails only that
|
|
56
|
+
document; redaction covers Telegram, Slack and Discord webhooks, `Authorization` and
|
|
57
|
+
`Cookie` headers, Groq, xAI, SendGrid, PyPI and Stripe webhook keys, PGP and cut-short
|
|
58
|
+
private keys, AWS secret keys, `mysql -p`, numeric and dotted passwords and Spanish key
|
|
59
|
+
names, and titles and context sent to the model are redacted too; `run --limit` no
|
|
60
|
+
longer skips sessions sharing a timestamp; Paperclip refs include the company;
|
|
61
|
+
`jezero eval` checks the types in question files; clean `error:` messages for a broken
|
|
62
|
+
config and bad `--ids`; `retag` and `resummarize` exit 3 when another run holds the
|
|
63
|
+
lock; accented project folder names count.
|
|
64
|
+
- Project skeleton: configuration file with validation and env-only secrets.
|
|
65
|
+
- SQLite + FTS5 store (trigram tokenizer, accent-insensitive) with BM25 ranking and a
|
|
66
|
+
recency boost.
|
|
67
|
+
- Read-only MCP server over Streamable HTTP with per-client bearer tokens and source
|
|
68
|
+
filtering: `search`, `get_item`, `timeline`, `list_sources`.
|
|
69
|
+
- Secret redaction before storage.
|
|
70
|
+
- JSONL import of pre-summarised items.
|
|
71
|
+
- Privacy pre-commit check.
|
|
72
|
+
- Summarizer for Anthropic and OpenAI-compatible endpoints: title, summary, questions,
|
|
73
|
+
atoms and project through a fixed JSON schema, with retries.
|
|
74
|
+
- Hermes Agent connector: read-only, dialogue only (tool results skipped), injected
|
|
75
|
+
memory blocks stripped, stable segments for long sessions, active sessions deferred.
|
|
76
|
+
- `jezero run` with `--dry-run`, `--limit` and `--sample`; per-connector cursor.
|
|
77
|
+
- A `.env` file next to the config is loaded automatically.
|
|
78
|
+
- Claude Code and Codex connectors.
|
|
79
|
+
- `jezero run --due` (per-connector intervals, one run at a time, a failing connector
|
|
80
|
+
no longer stops the others) and `jezero health` (stale/failing connectors, optional
|
|
81
|
+
webhook alert with de-duplication). systemd user units in `deploy/`.
|
|
82
|
+
- Renamed from "biblioteca" to Jezero.
|
|
83
|
+
- Codex connector: `sessions_dir` accepts a glob (one connector for every agent home an
|
|
84
|
+
orchestrator creates) and `user_prompt_markers` / `user_prompt_drop_lines` strip the
|
|
85
|
+
agent instructions an orchestrator repeats in every prompt.
|
|
86
|
+
- Paperclip connector: each issue with its description, comments (system notices and
|
|
87
|
+
deleted comments skipped), documents and answered questions, read through the API with
|
|
88
|
+
GET requests only. Entries are ordered by creation time so segments stay stable as an
|
|
89
|
+
issue grows; quiet issues only.
|
|
90
|
+
- OpenCode connector: sessions from `opencode.db` opened read-only; dialogue plus one
|
|
91
|
+
line per shell command or edited file, reasoning and read-only tools skipped.
|
|
92
|
+
- `summarizer.output_language`: write every summary in one language, so a query in that
|
|
93
|
+
language also finds sessions held in another.
|
|
94
|
+
- Prompt cleaning (`user_prompt_markers`, `user_prompt_drop_lines`) shared by connectors.
|
|
95
|
+
- A project hint from the source (working directory, project field) now wins over the
|
|
96
|
+
model's guess. `jezero retag --connector NAME [--dry-run]` re-applies the hints to items
|
|
97
|
+
already stored, without calling the model.
|
|
98
|
+
- `jezero resummarize --ids ... | --ids-file FILE`: summarise stored items again from
|
|
99
|
+
their kept original text (for example after setting `summarizer.output_language`).
|
|
100
|
+
- Antigravity CLI connector: reads the per-conversation SQLite store through a minimal
|
|
101
|
+
protobuf wire reader (user text, agent replies, one line per tool call with its summary);
|
|
102
|
+
unknown or malformed steps are skipped.
|
|
103
|
+
- Connectors can report warnings. The pipeline stores them as the connector's error and
|
|
104
|
+
holds the cursor, so `jezero health` (and the heartbeat) shows the connector as failing
|
|
105
|
+
until the cause is fixed. The Antigravity connector warns when a conversation has steps
|
|
106
|
+
but nothing in it can be read, which is how a format change shows up.
|
|
107
|
+
- MCP tool `later(item_id, query?)`: newer items in the same project on the same subject,
|
|
108
|
+
newest first, flagged `matched_by=subject` or `project_timeline` (fallback). The server
|
|
109
|
+
instructions now tell agents that decisions change and to check `later` before answering
|
|
110
|
+
with a decision, plan or status. Each item summarises one session, so nothing else marks
|
|
111
|
+
a decision as superseded.
|
|
112
|
+
- Hermes Agent plugin (`plugins/hermes`, `hermes plugins install MarsGotta/jezero/plugins/hermes`):
|
|
113
|
+
`jezero_*` tools, related past work on the first turn, the skill, and upload of the
|
|
114
|
+
session as turns end. The `hermes` connector reads those uploads with `export_dir`, and
|
|
115
|
+
takes the project from the session's working folder.
|
|
116
|
+
- OpenCode plugin is a self-contained folder (`plugins/opencode`, with its core, skill and
|
|
117
|
+
`package.json`): related past work after the first prompt, the skill installed in
|
|
118
|
+
OpenCode's skills folder.
|
|
119
|
+
- `init --no-upload` for computers that only read Jezero (the server's own computer).
|
|
120
|
+
- Client 0.3.1: `status` on a read-only computer checks reading, not uploading.
|
|
121
|
+
- Documentation rewritten and organised by Diátaxis in `docs/`: two tutorials, seven
|
|
122
|
+
how-to guides, seven reference pages, five explanation pages, a glossary and a style
|
|
123
|
+
guide. The command and configuration references are generated from the code
|
|
124
|
+
(`scripts/make_reference.py`); `scripts/check_docs.py` checks every link and anchor.
|
|
125
|
+
Both run in CI.
|
|
126
|
+
- The app's Install and Update buttons run the full documented steps for each agent
|
|
127
|
+
(plugin, MCP server), not only `setup`; the package ships the OpenCode plugin for it.
|
|
128
|
+
- The Jezero app: `jezero` with no command opens a terminal app (Textual) with Home,
|
|
129
|
+
Search (with "newer on this subject"), Timeline, Agents (detect, install and update the
|
|
130
|
+
plugins on this computer) and Agent view (the exact context an agent receives). Night
|
|
131
|
+
and dawn themes; `jezero ui --demo` runs it on made-up data. People commands:
|
|
132
|
+
`jezero connect`, `find`, `show --newer`, `agents`. New `GET /api/v1/overview` (any
|
|
133
|
+
client key, only its sources) feeds the dashboard without adding an MCP tool. The
|
|
134
|
+
client core ships inside the package as `jezero/client_core.py` (generated).
|
|
135
|
+
- Antigravity plugin (`plugins/antigravity`, client 0.4.0): the MCP server through a local
|
|
136
|
+
stdio bridge (`jezero_client.py mcp`, so the key never sits in Antigravity's config),
|
|
137
|
+
the protocol and recent work at SessionStart, related past work before the first model
|
|
138
|
+
call, the skill, and upload of `transcript.jsonl` when a conversation stops. The
|
|
139
|
+
`antigravity` connector reads those uploads with `transcripts_dir`. The key may live in
|
|
140
|
+
`~/.gemini/config/jezero` for sandboxes that cannot see the user's home.
|
|
141
|
+
- Client 0.3.3: the OpenCode plugin also finds a key in `<OpenCode config>/jezero`.
|
|
142
|
+
- Client 0.3.2: sandboxed agents keep their own key in `<agent config>/jezero`
|
|
143
|
+
(`CLAUDE_CONFIG_DIR`, `CODEX_HOME`), used when `JEZERO_CLIENT_HOME` is not set.
|
|
144
|
+
- `since`/`until` accept a bare date or a datetime without offset (read as UTC).
|
|
145
|
+
- Connectors register themselves: each module declares a `CONNECTOR_TYPE` with its
|
|
146
|
+
`build` function and is discovered automatically; other packages can add connectors
|
|
147
|
+
through the `jezero.connectors` entry point group. Adding a connector is one file.
|
|
148
|
+
- Summariser tests against a fake endpoint (both APIs, retries, errors, loose output).
|
|
149
|
+
- Tidy-up: the old `project_from_cwd` helper and an empty test file are gone; the diagram
|
|
150
|
+
script moved to `scripts/`; `plugins/` carries a do-not-edit note.
|
|
151
|
+
- The plugins install straight from GitHub: `claude plugin marketplace add MarsGotta/jezero`
|
|
152
|
+
and `codex plugin marketplace add MarsGotta/jezero`. `plugins/` is generated by
|
|
153
|
+
`scripts/build_clients.py` and checked in CI.
|
|
154
|
+
- A visual README: architecture diagram (`docs/architecture.svg`, drawn by
|
|
155
|
+
`scripts/make_architecture.py`), badges and a synthetic example of an agent using Jezero.
|
|
156
|
+
- Open-source readiness: CI workflow (lint, tests, privacy check, Python 3.9 client
|
|
157
|
+
check), `docs/architecture.md`, plugin manifests under Apache-2.0 like the project, the
|
|
158
|
+
obsolete `receiver` connector type removed (the device inbox replaces it), redaction no
|
|
159
|
+
longer hides code such as `token = get_access_token()`, neutral names in tests.
|
|
160
|
+
- Project detection without assumptions about folder names (`jezero.projects`, shared
|
|
161
|
+
by the connectors and the device client): configured `[projects] paths` first, then the
|
|
162
|
+
git repository (the main repository for worktrees), then common root folders
|
|
163
|
+
(`projects`, `code`, `dev`, `src`, `repos`... configurable, case-insensitive). Devices
|
|
164
|
+
send the project they found with each upload (`X-Jezero-Project`), stored next to the
|
|
165
|
+
session as `<file>.project`.
|
|
166
|
+
- Stronger redaction: env-style names ending in a secret word (`GITHUB_TOKEN=`,
|
|
167
|
+
`PGPASSWORD=`, `db_pass=`), quoted JSON keys, `--password X` flags, Basic auth, GitLab,
|
|
168
|
+
npm, Hugging Face and Stripe tokens, Azure keys and signed URLs. References (`$VAR`,
|
|
169
|
+
`<placeholder>`, paths) and prose (`tests PASS`, `OAuth`, `persist-credentials`) are kept.
|
|
170
|
+
`jezero redact-stored [--dry-run]` applies the rules to items already stored.
|
|
171
|
+
- `jezero device approve --source-prefix/--read-only`.
|
|
172
|
+
- Plugins for Claude Code, Codex and OpenCode (`clients/`), thin adapters over one shared
|
|
173
|
+
core (`clients/core/jezero_client.py`, Python 3.9+, standard library only). They add a
|
|
174
|
+
short protocol and the project's recent work at session start, related past work on the
|
|
175
|
+
first prompt, and upload each session to the server when it ends. The device key is
|
|
176
|
+
created on the device; the server only stores its SHA-256 (`jezero device approve`).
|
|
177
|
+
`scripts/build_clients.py` builds the bundle served at `/client/jezero-client.tar.gz`.
|
|
178
|
+
- Inbox: `PUT /inbox/v1/<agent>/<path>` for clients with `upload = true`; files land in
|
|
179
|
+
`<inbox>/<device>/<agent>/...`, mirroring each agent's store, and the usual connectors
|
|
180
|
+
read them. Codex rollouts compressed with zstd (`.jsonl.zst`) are read; OpenCode can
|
|
181
|
+
read session exports (`export_dir`); Claude Code can skip project folders
|
|
182
|
+
(`skip_project_dirs`).
|
|
183
|
+
- The MCP server unit stops within 10 s: clients keep streams open and the default 90 s
|
|
184
|
+
wait made restarts slow.
|
|
185
|
+
- Search, `later` and `timeline` show one item per copy of a segment (same
|
|
186
|
+
`original_ref` and `external_id` in two sources); `jezero eval` counts a copy of an
|
|
187
|
+
expected item as a hit.
|
|
188
|
+
- The summarizer is told that the order of `known_projects` means nothing and to use one
|
|
189
|
+
only when the document is about it: models picked the first listed slugs for unrelated
|
|
190
|
+
sessions.
|
|
191
|
+
- `jezero retag --ask-model` re-asks the model, from the stored summary, the project of
|
|
192
|
+
items whose source gives none and whose tag their own text never mentions, and moves
|
|
193
|
+
an item only when its text names the new project; prints `old -> new`, `--log` keeps
|
|
194
|
+
the changes.
|
|
195
|
+
- `jezero eval`: a TOML file of questions and the items that answer them, scored with the
|
|
196
|
+
same search the MCP server runs (top-k hits, hit@1, MRR), with `later` cases for
|
|
197
|
+
decisions that changed, a client's scope (`--client`, `--sources`), `--save` and
|
|
198
|
+
`--compare` to see which cases got better or worse, and `--fail-under` for scripts.
|
|
199
|
+
Guide: docs/how-to/measure-search.md; example: examples/eval.example.toml.
|
|
200
|
+
- The summarizer's project guess goes through `[projects].aliases` and the connector's
|
|
201
|
+
`project_aliases`, like the source's own hint; `jezero retag` applies new aliases to
|
|
202
|
+
stored guesses too.
|
|
203
|
+
- The `claude_code` connector takes a glob in `projects_dir`, like `codex` does in
|
|
204
|
+
`sessions_dir`: one connector follows the config folder of every agent an orchestrator
|
|
205
|
+
runs, reads a session copied between folders once (the newest copy), and passes the
|
|
206
|
+
folder name to the summarizer.
|
|
207
|
+
- Client 0.5.1: `init --force` keeps this computer's other settings (such as `projects`)
|
|
208
|
+
and, for a device the server already knows, prints the `jezero device rotate` line to
|
|
209
|
+
give the admin; the "uploads refused" log line names the real fix.
|
|
210
|
+
- `device approve` backs the config up like the other edits, and approving a name again
|
|
211
|
+
after `device revoke` reuses the connectors revoke kept instead of adding duplicates.
|
|
212
|
+
- Client 0.5.0:
|
|
213
|
+
- The Claude Code plugin brings its own MCP server (`.mcp.json`, the stdio bridge), and
|
|
214
|
+
`setup --agent claude-code` / `--agent codex` register the stdio bridge instead of
|
|
215
|
+
writing the bearer key in clear into the agent's config. With the Claude Code plugin
|
|
216
|
+
installed, `setup` registers nothing and removes an old user-scope `jezero` HTTP entry;
|
|
217
|
+
an old `[mcp_servers.jezero]` HTTP block in Codex' `config.toml` is replaced, the rest
|
|
218
|
+
of the file left byte for byte.
|
|
219
|
+
- `client.json` takes an optional `mcp_path` (default `/mcp`, set with
|
|
220
|
+
`init --mcp-path`) for servers with a custom `[server].path`; the core and the
|
|
221
|
+
OpenCode plugin use it.
|
|
222
|
+
- Uploads refused with HTTP 401/403 stay queued (logged once) until the key may upload;
|
|
223
|
+
files rejected with 400/413/415 are recorded as rejected, not as uploaded, and
|
|
224
|
+
`status` reports them with the queue size.
|
|
225
|
+
- A key kept in an agent's own folder (Antigravity's `~/.gemini/config/jezero`,
|
|
226
|
+
`$CLAUDE_CONFIG_DIR/jezero`, `$CODEX_HOME/jezero`) is used by the background upload,
|
|
227
|
+
`backfill --agent` and `setup --agent`, and by the `mcp` bridge for every agent.
|
|
228
|
+
- Without a key the session-start hooks print nothing; the Hermes plugin gives the
|
|
229
|
+
protocol once per session. `state.json` no longer grows without limit. `flush`
|
|
230
|
+
always prints its counts; `status` and `flush` take `--agent`.
|
|
231
|
+
- The app labels newer items found only by date: "NEWER IN THIS PROJECT (by date, not
|
|
232
|
+
by subject)".
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for your interest. Jezero is early and small on purpose.
|
|
4
|
+
|
|
5
|
+
1. Open an issue first for anything beyond a small fix, so we can agree on the approach.
|
|
6
|
+
2. Keep changes focused, with tests. Bug fixes come with a regression test.
|
|
7
|
+
3. Run the checks listed in [AGENTS.md](AGENTS.md) before opening a pull request:
|
|
8
|
+
`uv run pytest`, `uv run ruff check src tests scripts clients`,
|
|
9
|
+
`uv run ruff format --check src tests scripts clients` and
|
|
10
|
+
`python3 scripts/privacy_check.py --all`. The device client must keep running on
|
|
11
|
+
Python 3.9 with the standard library only (`clients/`, `src/jezero/projects.py`).
|
|
12
|
+
4. Enable the privacy hook once per clone: `git config core.hooksPath .githooks`.
|
|
13
|
+
Add a git-ignored `.privacy-denylist` with terms that must never be committed from
|
|
14
|
+
your machine (host names, people, employers), one per line.
|
|
15
|
+
5. Never include real transcripts, emails or personal details in issues, tests or
|
|
16
|
+
fixtures. Use synthetic data.
|
|
17
|
+
|
|
18
|
+
## Documentation
|
|
19
|
+
|
|
20
|
+
The docs live in [`docs/`](docs/README.md) and follow [docs/STYLE.md](docs/STYLE.md):
|
|
21
|
+
tutorials, how-to guides, reference and explanation, each in its folder. A change that
|
|
22
|
+
users can see comes with its docs in the same pull request.
|
|
23
|
+
|
|
24
|
+
- `docs/reference/cli.md` and `docs/reference/configuration.md` are generated from the
|
|
25
|
+
code. Change the help text or the docstring, then run
|
|
26
|
+
`uv run python scripts/make_reference.py`.
|
|
27
|
+
- `docs/app/*.svg` are real screenshots of the app on demo data:
|
|
28
|
+
`uv run python scripts/make_screenshots.py`.
|
|
29
|
+
- `uv run python scripts/check_docs.py` checks every relative link and anchor. CI runs
|
|
30
|
+
all three checks.
|
|
31
|
+
- The website is built from `docs/` with [Zensical](https://zensical.org):
|
|
32
|
+
`uv run --group docs python scripts/build_site.py --serve` previews it at
|
|
33
|
+
http://localhost:8000 with live reload. The build is strict, so a broken link fails it.
|
|
34
|
+
Every push to `main` publishes it (`.github/workflows/docs.yml`).
|
|
35
|
+
|
|
36
|
+
By contributing you agree that your contributions are licensed under the Apache-2.0
|
|
37
|
+
license of this project.
|
|
38
|
+
|
|
39
|
+
## Adding a connector
|
|
40
|
+
|
|
41
|
+
A connector is one file in `src/jezero/connectors/`. It reads a source incrementally
|
|
42
|
+
(only what changed since the cursor in `ConnectorState`) and returns `RawDoc`s; the
|
|
43
|
+
pipeline does redaction, summarising and storage. End the module with its type:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
def _build(conn: ConnectorConfig, ctx: BuildContext) -> MyConnector:
|
|
47
|
+
return MyConnector(
|
|
48
|
+
conn.name,
|
|
49
|
+
conn.options,
|
|
50
|
+
max_segment_chars=ctx.max_segment_chars,
|
|
51
|
+
default_project=conn.project,
|
|
52
|
+
project_rules=ctx.project_rules, # if it knows the working directory
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
CONNECTOR_TYPE = ConnectorType("mytool", "available", "What it reads.", build=_build)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
That is all the registration there is: `jezero check-config` lists it and `jezero run`
|
|
60
|
+
can schedule it. Add a test with synthetic files (see `tests/test_codex.py`), and an
|
|
61
|
+
example entry in `jezero.example.toml`. New connectors should start with
|
|
62
|
+
`enabled = false` in examples, so users run a pilot (`jezero run --connector NAME
|
|
63
|
+
--sample 3`) before a full load.
|
|
64
|
+
|
|
65
|
+
A connector can also live in its own package: expose its `ConnectorType` through the
|
|
66
|
+
`jezero.connectors` entry point group and Jezero picks it up once installed.
|
|
67
|
+
|
jezero-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
179
|
+
|
|
180
|
+
To apply the Apache License to your work, attach the following
|
|
181
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
182
|
+
replaced with your own identifying information. (Don't include
|
|
183
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
184
|
+
comment syntax for the file format. We also recommend that a
|
|
185
|
+
file or class name and description of purpose be included on the
|
|
186
|
+
same "printed page" as the copyright notice for easier
|
|
187
|
+
identification within third-party archives.
|
|
188
|
+
|
|
189
|
+
Copyright 2026 Marcela Gotta
|
|
190
|
+
|
|
191
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
|
+
you may not use this file except in compliance with the License.
|
|
193
|
+
You may obtain a copy of the License at
|
|
194
|
+
|
|
195
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
196
|
+
|
|
197
|
+
Unless required by applicable law or agreed to in writing, software
|
|
198
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
199
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
200
|
+
See the License for the specific language governing permissions and
|
|
201
|
+
limitations under the License.
|