threadkeeper 0.10.0__tar.gz → 0.12.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.
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/PKG-INFO +108 -84
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/README.md +106 -82
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/pyproject.toml +2 -2
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_adapters.py +44 -5
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_agent_status.py +50 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_curator.py +5 -0
- threadkeeper-0.12.0/tests/test_evolve_applier.py +1133 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_evolve_daemon.py +77 -10
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_lessons.py +3 -2
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_menubar_app.py +24 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_skills.py +1 -1
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_spawn_config.py +25 -7
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/_setup.py +14 -13
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/adapters/__init__.py +8 -3
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/adapters/_hook_helpers.py +1 -1
- threadkeeper-0.12.0/threadkeeper/adapters/antigravity.py +137 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/adapters/base.py +5 -3
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/adapters/codex.py +2 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/adapters/vscode.py +1 -1
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/agent_status.py +34 -10
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/assets/macos-agent-status/README.md +8 -0
- threadkeeper-0.12.0/threadkeeper/assets/macos-agent-status/ThreadKeeperAgentStatus.swift +1814 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/brief.py +4 -3
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/config.py +6 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/curator.py +19 -0
- threadkeeper-0.12.0/threadkeeper/evolve_applier.py +1445 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/evolve_daemon.py +98 -66
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/identity.py +6 -4
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/nudges.py +6 -6
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/review_prompts.py +6 -4
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/spawn_config.py +30 -9
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/evolve_applier.py +45 -1
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/skills.py +3 -3
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/spawn.py +1 -1
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/threads.py +2 -2
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper.egg-info/PKG-INFO +108 -84
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper.egg-info/SOURCES.txt +1 -0
- threadkeeper-0.10.0/tests/test_evolve_applier.py +0 -445
- threadkeeper-0.10.0/threadkeeper/assets/macos-agent-status/ThreadKeeperAgentStatus.swift +0 -760
- threadkeeper-0.10.0/threadkeeper/evolve_applier.py +0 -709
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/LICENSE +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/setup.cfg +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_auto_update.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_brief_footprint.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_brief_sections.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_candidate_reviewer.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_config_settings.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_core_memory.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_dashboard.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_delegated_search.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_dialectic.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_dialectic_feed_tools.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_dialectic_miner.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_dialectic_observation_resolve.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_dialectic_recompute.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_dialectic_tier.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_dialectic_validator.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_error_paths.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_evolve_apply_2.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_evolve_apply_3.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_extract_daemon.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_extract_dedup.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_i18n_multilang.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_identity.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_ingest_status.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_memory_guard.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_missed_spawns.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_nudges.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_onnx_embeddings.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_panel.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_probe_daemon.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_process_health.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_search_fts_punctuation.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_shadow_review.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_skill_hint.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_skill_passive_tier.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_skill_tier.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_skill_use_parser.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_skill_watcher.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_spawn_budget.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_spawn_codex_stdin.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_spawn_hint.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_spawn_reap.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_spawn_slim.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_spawn_wrap.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_thread_janitor.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_threads.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_tools_smoke.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_validate_threads.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/tests/test_vec_search.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/__init__.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/_mcp.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/_spawn_wrap.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/adapters/claude_code.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/adapters/claude_desktop.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/adapters/copilot.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/adapters/gemini.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/assets/macos-agent-status/Info.plist +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/assets/macos-agent-status/build.sh +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/assets/macos-agent-status/install.sh +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/auto_update.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/candidate_reviewer.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/db.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/dialectic_miner.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/dialectic_validator.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/embeddings.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/extract_daemon.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/helpers.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/i18n.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/ingest.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/lessons.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/memory_guard.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/menubar_app.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/migrate_embeddings.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/probe_daemon.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/process_health.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/search_proxy.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/server.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/shadow_review.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/skill_watcher.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/spawn_budget.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/thread_janitor.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/__init__.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/agent_status.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/candidate_reviewer.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/concepts.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/consolidate.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/core_memory.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/correlation.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/curator.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/dashboard.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/dialectic.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/dialectic_feed.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/dialog.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/distill.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/extract.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/graph.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/invariants.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/lessons.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/memory_guard.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/missed_spawns.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/panel.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/peers.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/pickup.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/probes.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/process_health.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/session.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/shadow_review.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/style.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper/tools/validate.py +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper.egg-info/dependency_links.txt +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper.egg-info/entry_points.txt +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper.egg-info/requires.txt +0 -0
- {threadkeeper-0.10.0 → threadkeeper-0.12.0}/threadkeeper.egg-info/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: threadkeeper
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary: Multi-agent shared brain across Claude Code/Desktop, Codex, Gemini, Copilot, VS Code. Cross-session memory, self-improving skill loops, inter-agent signaling — one local MCP server.
|
|
3
|
+
Version: 0.12.0
|
|
4
|
+
Summary: Multi-agent shared brain across Claude Code/Desktop, Codex, Antigravity CLI, Gemini, Copilot, VS Code. Cross-session memory, self-improving skill loops, inter-agent signaling — one local MCP server.
|
|
5
5
|
Author: thread-keeper contributors
|
|
6
6
|
License: MIT
|
|
7
7
|
Project-URL: Homepage, https://github.com/po4erk91/thread-keeper
|
|
@@ -45,17 +45,17 @@ Dynamic: license-file
|
|
|
45
45
|
[](https://www.python.org/downloads/)
|
|
46
46
|
[](LICENSE)
|
|
47
47
|
[](https://pypi.org/project/threadkeeper/)
|
|
48
|
-
[](#multi-cli-integration)
|
|
48
|
+
[](#multi-cli-integration)
|
|
49
49
|
|
|
50
|
-
**Multi-agent shared brain across Claude Code/Desktop, Codex,
|
|
51
|
-
Copilot, and VS Code.**
|
|
52
|
-
loops, and inter-agent signaling —
|
|
53
|
-
|
|
54
|
-
isolated chats.
|
|
50
|
+
**Multi-agent shared brain across Claude Code/Desktop, Codex,
|
|
51
|
+
Antigravity CLI (`agy`), Gemini legacy, Copilot, and VS Code.**
|
|
52
|
+
Cross-session memory, self-improving skill loops, and inter-agent signaling —
|
|
53
|
+
one local MCP server turns parallel agent instances into a coordinated
|
|
54
|
+
multi-agent system instead of N isolated chats.
|
|
55
55
|
|
|
56
|
-
Every connected client (Claude Code, Claude Desktop, Codex CLI +
|
|
57
|
-
|
|
58
|
-
one SQLite store, one set of threads, one user model, and one learning
|
|
56
|
+
Every connected client (Claude Code, Claude Desktop, Codex CLI + desktop,
|
|
57
|
+
Antigravity CLI, Gemini legacy, Copilot, every MCP-aware VS Code extension)
|
|
58
|
+
shares one SQLite store, one set of threads, one user model, and one learning
|
|
59
59
|
loop that improves the skill library autonomously over time.
|
|
60
60
|
|
|
61
61
|
The brief format is dense — structural tags, opaque IDs, ~6 KB per
|
|
@@ -67,7 +67,7 @@ session-start injection. Optimized for agent consumption, not human reading.
|
|
|
67
67
|
|
|
68
68
|
Every agent CLI starts cold. Context dies at session boundaries.
|
|
69
69
|
Skills you taught Claude don't transfer to Codex. Threads you closed
|
|
70
|
-
in yesterday's
|
|
70
|
+
in yesterday's Antigravity chat are invisible to today's Copilot. Parallel
|
|
71
71
|
agent instances running the same task don't know about each other and
|
|
72
72
|
duplicate work or step on each other's writes.
|
|
73
73
|
|
|
@@ -92,9 +92,10 @@ make it more than a memory store:
|
|
|
92
92
|
materialize class-level skills as the agents work. Adapted to multi-CLI:
|
|
93
93
|
SKILL.md is the primary write target and gets mirrored to every
|
|
94
94
|
known/configured skills root simultaneously (`~/.claude/skills/`,
|
|
95
|
-
`~/.codex/skills/`,
|
|
96
|
-
|
|
97
|
-
|
|
95
|
+
`~/.codex/skills/`, `~/.gemini/config/skills/` for Antigravity,
|
|
96
|
+
existing `~/.agents/skills/`, extra roots from
|
|
97
|
+
`THREADKEEPER_EXTRA_SKILLS_DIRS`, and `~/.threadkeeper/skills/`), with
|
|
98
|
+
lessons.md as a fallback for CLIs without a native skills loader.
|
|
98
99
|
|
|
99
100
|
Foreground MCP servers also run a daily self-update check by default. Source
|
|
100
101
|
checkouts fast-forward their tracked git branch and reinstall the editable
|
|
@@ -113,15 +114,17 @@ pipx install 'threadkeeper[semantic]' && thread-keeper-setup
|
|
|
113
114
|
```
|
|
114
115
|
|
|
115
116
|
`thread-keeper-setup` detects every CLI you have installed (Claude
|
|
116
|
-
Code / Claude Desktop / Codex CLI + desktop /
|
|
117
|
-
Code), registers the MCP server in each one's
|
|
117
|
+
Code / Claude Desktop / Codex CLI + desktop / Antigravity CLI `agy` /
|
|
118
|
+
Gemini legacy / Copilot / VS Code), registers the MCP server in each one's
|
|
119
|
+
config, copies hooks to
|
|
118
120
|
`~/.threadkeeper/hooks/`, and writes a managed instructions block into
|
|
119
121
|
each CLI's per-user instructions file (`CLAUDE.md` / `AGENTS.md` /
|
|
120
122
|
`GEMINI.md` / `copilot-instructions.md` — Claude Desktop and VS Code
|
|
121
123
|
have no global instructions file, so that step is skipped for them).
|
|
122
124
|
|
|
123
|
-
Restart your CLI of choice.
|
|
124
|
-
|
|
125
|
+
Restart your CLI of choice. Hook-capable clients inject a brief on the first
|
|
126
|
+
message; hookless clients such as Codex and Antigravity CLI follow the managed
|
|
127
|
+
instructions block and call `brief()` / `context()` manually before answering.
|
|
125
128
|
|
|
126
129
|
### Alternative installs
|
|
127
130
|
|
|
@@ -168,16 +171,18 @@ thread-keeper-setup --dry-run
|
|
|
168
171
|
| Claude Code | `~/.claude.json` `mcpServers` | `~/.claude/CLAUDE.md` | `~/.claude/settings.json` `hooks` | `~/.claude/projects/**/*.jsonl` |
|
|
169
172
|
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` `mcpServers` (macOS); `%APPDATA%\Claude\…` (Win); `~/.config/Claude/…` (Linux) | none (GUI-only) | not supported by the app | none — chats live in Electron IndexedDB |
|
|
170
173
|
| Codex (CLI + desktop) | `~/.codex/config.toml` `[mcp_servers]` (shared between CLI and `Codex.app`) | `~/.codex/AGENTS.md` | not supported | `~/.codex/sessions/**/rollout-*.jsonl` |
|
|
171
|
-
|
|
|
174
|
+
| Antigravity CLI (`agy`) | `~/.gemini/config/mcp_config.json` `mcpServers` | `~/.gemini/config/AGENTS.md` | not wired yet | not yet parsed — sqlite/protobuf under `~/.gemini/antigravity-cli/conversations/*.db` |
|
|
175
|
+
| Gemini legacy | `~/.gemini/settings.json` `mcpServers` | `~/.gemini/GEMINI.md` | `~/.gemini/settings.json` `hooks` | `~/.gemini/tmp/<user>/chats/session-*.jsonl` |
|
|
172
176
|
| Copilot | `~/.copilot/mcp-config.json` `mcpServers` | `~/.copilot/copilot-instructions.md` | `~/.copilot/hooks.json` | `~/.copilot/session-store.db` (sqlite) |
|
|
173
177
|
| VS Code | `~/Library/Application Support/Code/User/mcp.json` `servers` (macOS); `%APPDATA%\Code\User\mcp.json` (Win); `~/.config/Code/User/mcp.json` (Linux) | none (per-workspace only) | not supported | none — extensions own their history |
|
|
174
178
|
|
|
175
179
|
Every CLI that produces parseable transcripts feeds the same
|
|
176
180
|
`dialog_messages` table with a `source` tag, so `dialog_search()` finds
|
|
177
|
-
matches regardless of where the conversation happened. Claude Desktop
|
|
178
|
-
and the VS Code adapter are the exceptions — MCP registration
|
|
179
|
-
their chats don't reach the table for now (Electron IndexedDB on the
|
|
180
|
-
Claude Desktop side;
|
|
181
|
+
matches regardless of where the conversation happened. Claude Desktop,
|
|
182
|
+
Antigravity CLI, and the VS Code adapter are the exceptions — MCP registration
|
|
183
|
+
only; their chats don't reach the table for now (Electron IndexedDB on the
|
|
184
|
+
Claude Desktop side; sqlite/protobuf on the Antigravity side; per-extension
|
|
185
|
+
stores on the VS Code side).
|
|
181
186
|
|
|
182
187
|
VS Code's user-level `mcp.json` is the central host that **every
|
|
183
188
|
MCP-aware VS Code extension** consumes — GitHub Copilot Chat, the
|
|
@@ -234,7 +239,12 @@ memory button, self-restarts when its own RSS crosses
|
|
|
234
239
|
notification permission, and sends a notification when a newly completed
|
|
235
240
|
autonomous child task produces a useful result in `recent_results`; the first
|
|
236
241
|
poll only marks existing results as seen, so old completions do not spam
|
|
237
|
-
notifications.
|
|
242
|
+
notifications. The header gear opens a separate Settings window for
|
|
243
|
+
`~/.threadkeeper/.env`: common knobs are grouped into guided controls, the raw
|
|
244
|
+
`.env` remains editable for advanced values, three local presets can be saved
|
|
245
|
+
and loaded, and Save & Restart writes the file then asks existing
|
|
246
|
+
`threadkeeper.server` processes to exit so MCP hosts reconnect with the new
|
|
247
|
+
configuration. Probe backlog is due objective
|
|
238
248
|
probes only, not every registered probe, so a healthy cooldown shows `0 due
|
|
239
249
|
probes` instead of looking stuck. On macOS, `python -m threadkeeper.server`
|
|
240
250
|
automatically installs and launches it on MCP startup, and restarts the app when
|
|
@@ -323,16 +333,19 @@ shows agents focused on their primary task rarely do).
|
|
|
323
333
|
| 2 | shadow_review daemon | every 15 min (env knob) | recent `dialog_messages` window | SKILL.md, lessons.md |
|
|
324
334
|
| 3 | extract daemon | every 10 min (env knob) | recent `dialog_messages` window | `extract_candidates` pending queue |
|
|
325
335
|
| 4 | candidate-reviewer daemon | every 1 h (env knob) | pending candidates queue | SKILL.md (create/patch) / notes / verbatim / reject |
|
|
326
|
-
| 5 | Curator daemon | every 7 days (env knob) | every existing lesson + recently-touched skill | REPORT
|
|
327
|
-
| 6 |
|
|
328
|
-
| 7 |
|
|
336
|
+
| 5 | Curator daemon | every 7 days (env knob) | every existing lesson + recently-touched skill | `REPORT-<date>.md`; Evolve applier applies it after roadmap issues |
|
|
337
|
+
| 6 | evolve_reviewer daemon | configurable (env knob; 0=off) | code/docs/issues + web research when useful | roadmap updates + GitHub issues |
|
|
338
|
+
| 7 | evolve_applier daemon | configurable (env knob; 0=off) | open GitHub issues, Curator reports, legacy promoted evolve suggestions | PRs + applied markers |
|
|
339
|
+
| 8 | dialectic_miner daemon | configurable (env knob; 0=off) | recent `dialog_messages` — user replies + preceding-assistant context | `dialectic_observations` buffer |
|
|
340
|
+
| 9 | dialectic_validator daemon | configurable (env knob; 0=off) | buffered `dialectic_observations` | dialectic claims + evidence (support / contradict / supersede) via spawned opus child |
|
|
329
341
|
|
|
330
|
-
|
|
342
|
+
Learning loops write into the universal Skill format (`SKILL.md` under each
|
|
331
343
|
known/configured skills root — `~/.claude/skills/`, `~/.codex/skills/`,
|
|
332
|
-
existing `~/.agents/skills/`,
|
|
333
|
-
plus the canonical
|
|
334
|
-
`~/.threadkeeper/lessons.md` as a
|
|
335
|
-
without a native skills loader (Gemini
|
|
344
|
+
`~/.gemini/config/skills/` for Antigravity, existing `~/.agents/skills/`,
|
|
345
|
+
optional `THREADKEEPER_EXTRA_SKILLS_DIRS`, plus the canonical
|
|
346
|
+
`~/.threadkeeper/skills/` mirror), with `~/.threadkeeper/lessons.md` as a
|
|
347
|
+
CLI-agnostic fallback for clients without a native skills loader (Gemini
|
|
348
|
+
legacy, Copilot, bare MCP).
|
|
336
349
|
|
|
337
350
|
#### 1. Auto-review on close_thread
|
|
338
351
|
|
|
@@ -420,56 +433,63 @@ entries are marked `[PROTECTED]` in the inventory so the curator
|
|
|
420
433
|
never proposes destructive changes against them.
|
|
421
434
|
|
|
422
435
|
Curator itself stays advisory-only by default. The existing Evolve applier is
|
|
423
|
-
the apply worker:
|
|
424
|
-
Curator report (`CURATOR_PASS_COMPLETE`) that has not
|
|
425
|
-
spawns an `evolve_applier` child to apply only safe,
|
|
426
|
-
maintenance through `lesson_append` / `lesson_remove` /
|
|
427
|
-
touches `[PROTECTED]`, foreground/user, pinned, or
|
|
428
|
-
the child finishes does it call
|
|
429
|
-
prevents replaying the same
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
`evolve_format(
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
`
|
|
436
|
+
also the Curator apply worker: after the roadmap issue queue is empty, it looks
|
|
437
|
+
for the latest complete Curator report (`CURATOR_PASS_COMPLETE`) that has not
|
|
438
|
+
been marked applied, then spawns an `evolve_applier` child to apply only safe,
|
|
439
|
+
still-current memory maintenance through `lesson_append` / `lesson_remove` /
|
|
440
|
+
`skill_manage`. It never touches `[PROTECTED]`, foreground/user, pinned, or
|
|
441
|
+
validated entries. Only after the child finishes does it call
|
|
442
|
+
`evolve_mark_curator_report_applied(...)`, which prevents replaying the same
|
|
443
|
+
report.
|
|
444
|
+
|
|
445
|
+
Curator can also feed the roadmap loop upstream: when a skill or lesson exposes
|
|
446
|
+
an important way to improve thread-keeper itself, the curator child may call
|
|
447
|
+
`evolve_format(...)` and add an `EVOLVE_CANDIDATE:` line to its report. Evolve
|
|
448
|
+
reviewer then audits that candidate and turns it into a GitHub issue when it is
|
|
449
|
+
worth doing.
|
|
450
|
+
|
|
451
|
+
#### 6. Evolve reviewer/applier — roadmap evolution loop
|
|
452
|
+
|
|
453
|
+
The Evolve reviewer is thread-keeper's upstream product/engineering auditor. On
|
|
454
|
+
its interval it audits thread-keeper itself for security/privacy risks, memory
|
|
455
|
+
leaks, runaway daemons, cost waste, reliability gaps, optimizations, and new
|
|
456
|
+
ideas from current agent/MCP/memory tooling research. It does **not** implement
|
|
457
|
+
code. Its durable outputs are updates to `docs/ROADMAP.md` and GitHub issues
|
|
458
|
+
with problem statement, proposed direction, acceptance criteria, test/docs
|
|
459
|
+
impact, and research sources when applicable. Legacy `evolve_format(...)`
|
|
460
|
+
suggestions are still included as audit input, but durable implementation work
|
|
461
|
+
should become GitHub issues.
|
|
462
|
+
|
|
463
|
+
The Evolve applier is the downstream implementer. `evolve_apply_roadmap_issue()`
|
|
464
|
+
picks one open GitHub issue at a time (`roadmap` label first, then FIFO), skips
|
|
465
|
+
issues with an active Evolve claim comment, posts its own claim comment before
|
|
466
|
+
spawning, and advances to the next issue when an issue-local dispatch failure
|
|
467
|
+
prevents startup. The child implements exactly that issue, runs the full suite,
|
|
468
|
+
opens a PR whose body includes `Closes #N`, and only then calls
|
|
469
|
+
`evolve_mark_roadmap_issue_applied(issue_number, pr_url)`. It never commits or
|
|
470
|
+
pushes to `main`, and it never marks an issue applied without a real PR URL. A
|
|
471
|
+
manual `evolve_apply_roadmap_issue(issue_number=N)` remains exact: it reports
|
|
472
|
+
why that issue cannot start instead of silently switching to another issue.
|
|
473
|
+
|
|
474
|
+
Fallback/manual paths remain:
|
|
475
|
+
|
|
476
|
+
- `evolve_apply_curator_report(report_path="")` applies safe Curator memory
|
|
477
|
+
maintenance when no roadmap issue is being drained.
|
|
478
|
+
- `evolve_apply(evolve_id)` still implements legacy promoted
|
|
479
|
+
`evolve_format(...)` suggestions behind a PR and calls
|
|
480
|
+
`evolve_mark_applied(evolve_id, pr_url)`.
|
|
481
|
+
|
|
482
|
+
Set `THREADKEEPER_EVOLVE_REVIEW_INTERVAL_S>0` to run periodic audit/research
|
|
483
|
+
passes and `THREADKEEPER_EVOLVE_APPLY_INTERVAL_S>0` to drain one issue per pass.
|
|
484
|
+
Pin the agent/model with `THREADKEEPER_SPAWN__LOOP__EVOLVE_APPLIER` /
|
|
470
485
|
`THREADKEEPER_SPAWN__MODEL__EVOLVE_APPLIER`. Single-flight (one applier child at
|
|
471
486
|
a time, enforced by a short dispatch file lock plus running-task detection)
|
|
472
487
|
keeps code edits and memory maintenance from colliding.
|
|
488
|
+
Automatic apply passes respect the configured interval so multiple foreground
|
|
489
|
+
MCP server startups do not repeatedly spawn workers for the same open issue.
|
|
490
|
+
Manual tools such as `evolve_apply_roadmap_issue()` dispatch immediately. If no
|
|
491
|
+
roadmap issue is startable, the pass falls back to Curator reports and then
|
|
492
|
+
legacy promoted `evolve_format(...)` suggestions.
|
|
473
493
|
|
|
474
494
|
#### Honest take
|
|
475
495
|
|
|
@@ -586,12 +606,14 @@ The most-used env knobs (full list in `threadkeeper/config.py`):
|
|
|
586
606
|
| `THREADKEEPER_DIALECTIC_VALIDATE_INTERVAL_S` | 0 (off) | dialectic_validator daemon tick (s); 0 disables LLM-driven claim synthesis |
|
|
587
607
|
| `THREADKEEPER_DIALECTIC_VALIDATE_MIN` | 5 | min buffered observations before validator engages |
|
|
588
608
|
| `THREADKEEPER_DIALECTIC_VALIDATE_BATCH_SIZE` | 50 | max observations sent to one validator child; prevents oversized prompts and drains large queues incrementally |
|
|
589
|
-
| `THREADKEEPER_EVOLVE_REVIEW_INTERVAL_S` | 0 (off) | evolve-reviewer daemon tick (s);
|
|
590
|
-
| `THREADKEEPER_EVOLVE_APPLY_INTERVAL_S` | 0 (off) | evolve-applier daemon tick (s);
|
|
609
|
+
| `THREADKEEPER_EVOLVE_REVIEW_INTERVAL_S` | 0 (off) | evolve-reviewer daemon tick (s); audits thread-keeper for safety/leaks/optimization/new ideas, researches current approaches, updates roadmap/issues, and includes legacy evolve suggestions as input |
|
|
610
|
+
| `THREADKEEPER_EVOLVE_APPLY_INTERVAL_S` | 0 (off) | evolve-applier daemon tick (s); implements one open GitHub issue at a time, then falls back to Curator reports and promoted legacy evolve suggestions. Empty checks are throttled between intervals; actionable work and manual apply tools still dispatch |
|
|
591
611
|
| `THREADKEEPER_DIALECTIC_MAX_NEW_CLAIMS` | 3 | max new dialectic claims the validator may create per pass |
|
|
592
612
|
|
|
593
613
|
Persist them in `~/.threadkeeper/.env` (copy from `.env.example`) — one file,
|
|
594
|
-
read via pydantic-settings; real environment variables still override it.
|
|
614
|
+
read via pydantic-settings; real environment variables still override it. On
|
|
615
|
+
macOS, the menu-bar app's gear button can edit the same file visually, save up
|
|
616
|
+
to three local presets, and request a ThreadKeeper restart after saving.
|
|
595
617
|
Hot-config reload is
|
|
596
618
|
[tracked](https://github.com/po4erk91/thread-keeper/issues/2).
|
|
597
619
|
|
|
@@ -622,7 +644,8 @@ THREADKEEPER_SPAWN__MODEL__DIALECTIC_VALIDATOR=opus
|
|
|
622
644
|
Resolution per role: `SPAWN__LOOP__<role>` → `SPAWN__DEFAULT` → active CLI →
|
|
623
645
|
`claude`; `"auto"` (or unset) defers to the active CLI. Real environment
|
|
624
646
|
variables override the `.env`. Force host detection with
|
|
625
|
-
`THREADKEEPER_ACTIVE_CLI=claude
|
|
647
|
+
`THREADKEEPER_ACTIVE_CLI=claude` (or `codex`, `antigravity`/`agy`,
|
|
648
|
+
`gemini`, `copilot`). See `.env.example` for the full knob list.
|
|
626
649
|
|
|
627
650
|
Adapters without headless support (Claude Desktop, VS Code) can't be
|
|
628
651
|
spawn targets — `spawn_status()` reports them as "no adapter" and any
|
|
@@ -760,6 +783,7 @@ threadkeeper/
|
|
|
760
783
|
│ ├── claude_code.py
|
|
761
784
|
│ ├── claude_desktop.py
|
|
762
785
|
│ ├── codex.py
|
|
786
|
+
│ ├── antigravity.py
|
|
763
787
|
│ ├── gemini.py
|
|
764
788
|
│ ├── copilot.py
|
|
765
789
|
│ └── vscode.py
|
|
@@ -4,17 +4,17 @@
|
|
|
4
4
|
[](https://www.python.org/downloads/)
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[](https://pypi.org/project/threadkeeper/)
|
|
7
|
-
[](#multi-cli-integration)
|
|
7
|
+
[](#multi-cli-integration)
|
|
8
8
|
|
|
9
|
-
**Multi-agent shared brain across Claude Code/Desktop, Codex,
|
|
10
|
-
Copilot, and VS Code.**
|
|
11
|
-
loops, and inter-agent signaling —
|
|
12
|
-
|
|
13
|
-
isolated chats.
|
|
9
|
+
**Multi-agent shared brain across Claude Code/Desktop, Codex,
|
|
10
|
+
Antigravity CLI (`agy`), Gemini legacy, Copilot, and VS Code.**
|
|
11
|
+
Cross-session memory, self-improving skill loops, and inter-agent signaling —
|
|
12
|
+
one local MCP server turns parallel agent instances into a coordinated
|
|
13
|
+
multi-agent system instead of N isolated chats.
|
|
14
14
|
|
|
15
|
-
Every connected client (Claude Code, Claude Desktop, Codex CLI +
|
|
16
|
-
|
|
17
|
-
one SQLite store, one set of threads, one user model, and one learning
|
|
15
|
+
Every connected client (Claude Code, Claude Desktop, Codex CLI + desktop,
|
|
16
|
+
Antigravity CLI, Gemini legacy, Copilot, every MCP-aware VS Code extension)
|
|
17
|
+
shares one SQLite store, one set of threads, one user model, and one learning
|
|
18
18
|
loop that improves the skill library autonomously over time.
|
|
19
19
|
|
|
20
20
|
The brief format is dense — structural tags, opaque IDs, ~6 KB per
|
|
@@ -26,7 +26,7 @@ session-start injection. Optimized for agent consumption, not human reading.
|
|
|
26
26
|
|
|
27
27
|
Every agent CLI starts cold. Context dies at session boundaries.
|
|
28
28
|
Skills you taught Claude don't transfer to Codex. Threads you closed
|
|
29
|
-
in yesterday's
|
|
29
|
+
in yesterday's Antigravity chat are invisible to today's Copilot. Parallel
|
|
30
30
|
agent instances running the same task don't know about each other and
|
|
31
31
|
duplicate work or step on each other's writes.
|
|
32
32
|
|
|
@@ -51,9 +51,10 @@ make it more than a memory store:
|
|
|
51
51
|
materialize class-level skills as the agents work. Adapted to multi-CLI:
|
|
52
52
|
SKILL.md is the primary write target and gets mirrored to every
|
|
53
53
|
known/configured skills root simultaneously (`~/.claude/skills/`,
|
|
54
|
-
`~/.codex/skills/`,
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
`~/.codex/skills/`, `~/.gemini/config/skills/` for Antigravity,
|
|
55
|
+
existing `~/.agents/skills/`, extra roots from
|
|
56
|
+
`THREADKEEPER_EXTRA_SKILLS_DIRS`, and `~/.threadkeeper/skills/`), with
|
|
57
|
+
lessons.md as a fallback for CLIs without a native skills loader.
|
|
57
58
|
|
|
58
59
|
Foreground MCP servers also run a daily self-update check by default. Source
|
|
59
60
|
checkouts fast-forward their tracked git branch and reinstall the editable
|
|
@@ -72,15 +73,17 @@ pipx install 'threadkeeper[semantic]' && thread-keeper-setup
|
|
|
72
73
|
```
|
|
73
74
|
|
|
74
75
|
`thread-keeper-setup` detects every CLI you have installed (Claude
|
|
75
|
-
Code / Claude Desktop / Codex CLI + desktop /
|
|
76
|
-
Code), registers the MCP server in each one's
|
|
76
|
+
Code / Claude Desktop / Codex CLI + desktop / Antigravity CLI `agy` /
|
|
77
|
+
Gemini legacy / Copilot / VS Code), registers the MCP server in each one's
|
|
78
|
+
config, copies hooks to
|
|
77
79
|
`~/.threadkeeper/hooks/`, and writes a managed instructions block into
|
|
78
80
|
each CLI's per-user instructions file (`CLAUDE.md` / `AGENTS.md` /
|
|
79
81
|
`GEMINI.md` / `copilot-instructions.md` — Claude Desktop and VS Code
|
|
80
82
|
have no global instructions file, so that step is skipped for them).
|
|
81
83
|
|
|
82
|
-
Restart your CLI of choice.
|
|
83
|
-
|
|
84
|
+
Restart your CLI of choice. Hook-capable clients inject a brief on the first
|
|
85
|
+
message; hookless clients such as Codex and Antigravity CLI follow the managed
|
|
86
|
+
instructions block and call `brief()` / `context()` manually before answering.
|
|
84
87
|
|
|
85
88
|
### Alternative installs
|
|
86
89
|
|
|
@@ -127,16 +130,18 @@ thread-keeper-setup --dry-run
|
|
|
127
130
|
| Claude Code | `~/.claude.json` `mcpServers` | `~/.claude/CLAUDE.md` | `~/.claude/settings.json` `hooks` | `~/.claude/projects/**/*.jsonl` |
|
|
128
131
|
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` `mcpServers` (macOS); `%APPDATA%\Claude\…` (Win); `~/.config/Claude/…` (Linux) | none (GUI-only) | not supported by the app | none — chats live in Electron IndexedDB |
|
|
129
132
|
| Codex (CLI + desktop) | `~/.codex/config.toml` `[mcp_servers]` (shared between CLI and `Codex.app`) | `~/.codex/AGENTS.md` | not supported | `~/.codex/sessions/**/rollout-*.jsonl` |
|
|
130
|
-
|
|
|
133
|
+
| Antigravity CLI (`agy`) | `~/.gemini/config/mcp_config.json` `mcpServers` | `~/.gemini/config/AGENTS.md` | not wired yet | not yet parsed — sqlite/protobuf under `~/.gemini/antigravity-cli/conversations/*.db` |
|
|
134
|
+
| Gemini legacy | `~/.gemini/settings.json` `mcpServers` | `~/.gemini/GEMINI.md` | `~/.gemini/settings.json` `hooks` | `~/.gemini/tmp/<user>/chats/session-*.jsonl` |
|
|
131
135
|
| Copilot | `~/.copilot/mcp-config.json` `mcpServers` | `~/.copilot/copilot-instructions.md` | `~/.copilot/hooks.json` | `~/.copilot/session-store.db` (sqlite) |
|
|
132
136
|
| VS Code | `~/Library/Application Support/Code/User/mcp.json` `servers` (macOS); `%APPDATA%\Code\User\mcp.json` (Win); `~/.config/Code/User/mcp.json` (Linux) | none (per-workspace only) | not supported | none — extensions own their history |
|
|
133
137
|
|
|
134
138
|
Every CLI that produces parseable transcripts feeds the same
|
|
135
139
|
`dialog_messages` table with a `source` tag, so `dialog_search()` finds
|
|
136
|
-
matches regardless of where the conversation happened. Claude Desktop
|
|
137
|
-
and the VS Code adapter are the exceptions — MCP registration
|
|
138
|
-
their chats don't reach the table for now (Electron IndexedDB on the
|
|
139
|
-
Claude Desktop side;
|
|
140
|
+
matches regardless of where the conversation happened. Claude Desktop,
|
|
141
|
+
Antigravity CLI, and the VS Code adapter are the exceptions — MCP registration
|
|
142
|
+
only; their chats don't reach the table for now (Electron IndexedDB on the
|
|
143
|
+
Claude Desktop side; sqlite/protobuf on the Antigravity side; per-extension
|
|
144
|
+
stores on the VS Code side).
|
|
140
145
|
|
|
141
146
|
VS Code's user-level `mcp.json` is the central host that **every
|
|
142
147
|
MCP-aware VS Code extension** consumes — GitHub Copilot Chat, the
|
|
@@ -193,7 +198,12 @@ memory button, self-restarts when its own RSS crosses
|
|
|
193
198
|
notification permission, and sends a notification when a newly completed
|
|
194
199
|
autonomous child task produces a useful result in `recent_results`; the first
|
|
195
200
|
poll only marks existing results as seen, so old completions do not spam
|
|
196
|
-
notifications.
|
|
201
|
+
notifications. The header gear opens a separate Settings window for
|
|
202
|
+
`~/.threadkeeper/.env`: common knobs are grouped into guided controls, the raw
|
|
203
|
+
`.env` remains editable for advanced values, three local presets can be saved
|
|
204
|
+
and loaded, and Save & Restart writes the file then asks existing
|
|
205
|
+
`threadkeeper.server` processes to exit so MCP hosts reconnect with the new
|
|
206
|
+
configuration. Probe backlog is due objective
|
|
197
207
|
probes only, not every registered probe, so a healthy cooldown shows `0 due
|
|
198
208
|
probes` instead of looking stuck. On macOS, `python -m threadkeeper.server`
|
|
199
209
|
automatically installs and launches it on MCP startup, and restarts the app when
|
|
@@ -282,16 +292,19 @@ shows agents focused on their primary task rarely do).
|
|
|
282
292
|
| 2 | shadow_review daemon | every 15 min (env knob) | recent `dialog_messages` window | SKILL.md, lessons.md |
|
|
283
293
|
| 3 | extract daemon | every 10 min (env knob) | recent `dialog_messages` window | `extract_candidates` pending queue |
|
|
284
294
|
| 4 | candidate-reviewer daemon | every 1 h (env knob) | pending candidates queue | SKILL.md (create/patch) / notes / verbatim / reject |
|
|
285
|
-
| 5 | Curator daemon | every 7 days (env knob) | every existing lesson + recently-touched skill | REPORT
|
|
286
|
-
| 6 |
|
|
287
|
-
| 7 |
|
|
295
|
+
| 5 | Curator daemon | every 7 days (env knob) | every existing lesson + recently-touched skill | `REPORT-<date>.md`; Evolve applier applies it after roadmap issues |
|
|
296
|
+
| 6 | evolve_reviewer daemon | configurable (env knob; 0=off) | code/docs/issues + web research when useful | roadmap updates + GitHub issues |
|
|
297
|
+
| 7 | evolve_applier daemon | configurable (env knob; 0=off) | open GitHub issues, Curator reports, legacy promoted evolve suggestions | PRs + applied markers |
|
|
298
|
+
| 8 | dialectic_miner daemon | configurable (env knob; 0=off) | recent `dialog_messages` — user replies + preceding-assistant context | `dialectic_observations` buffer |
|
|
299
|
+
| 9 | dialectic_validator daemon | configurable (env knob; 0=off) | buffered `dialectic_observations` | dialectic claims + evidence (support / contradict / supersede) via spawned opus child |
|
|
288
300
|
|
|
289
|
-
|
|
301
|
+
Learning loops write into the universal Skill format (`SKILL.md` under each
|
|
290
302
|
known/configured skills root — `~/.claude/skills/`, `~/.codex/skills/`,
|
|
291
|
-
existing `~/.agents/skills/`,
|
|
292
|
-
plus the canonical
|
|
293
|
-
`~/.threadkeeper/lessons.md` as a
|
|
294
|
-
without a native skills loader (Gemini
|
|
303
|
+
`~/.gemini/config/skills/` for Antigravity, existing `~/.agents/skills/`,
|
|
304
|
+
optional `THREADKEEPER_EXTRA_SKILLS_DIRS`, plus the canonical
|
|
305
|
+
`~/.threadkeeper/skills/` mirror), with `~/.threadkeeper/lessons.md` as a
|
|
306
|
+
CLI-agnostic fallback for clients without a native skills loader (Gemini
|
|
307
|
+
legacy, Copilot, bare MCP).
|
|
295
308
|
|
|
296
309
|
#### 1. Auto-review on close_thread
|
|
297
310
|
|
|
@@ -379,56 +392,63 @@ entries are marked `[PROTECTED]` in the inventory so the curator
|
|
|
379
392
|
never proposes destructive changes against them.
|
|
380
393
|
|
|
381
394
|
Curator itself stays advisory-only by default. The existing Evolve applier is
|
|
382
|
-
the apply worker:
|
|
383
|
-
Curator report (`CURATOR_PASS_COMPLETE`) that has not
|
|
384
|
-
spawns an `evolve_applier` child to apply only safe,
|
|
385
|
-
maintenance through `lesson_append` / `lesson_remove` /
|
|
386
|
-
touches `[PROTECTED]`, foreground/user, pinned, or
|
|
387
|
-
the child finishes does it call
|
|
388
|
-
prevents replaying the same
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
`evolve_format(
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
`
|
|
395
|
+
also the Curator apply worker: after the roadmap issue queue is empty, it looks
|
|
396
|
+
for the latest complete Curator report (`CURATOR_PASS_COMPLETE`) that has not
|
|
397
|
+
been marked applied, then spawns an `evolve_applier` child to apply only safe,
|
|
398
|
+
still-current memory maintenance through `lesson_append` / `lesson_remove` /
|
|
399
|
+
`skill_manage`. It never touches `[PROTECTED]`, foreground/user, pinned, or
|
|
400
|
+
validated entries. Only after the child finishes does it call
|
|
401
|
+
`evolve_mark_curator_report_applied(...)`, which prevents replaying the same
|
|
402
|
+
report.
|
|
403
|
+
|
|
404
|
+
Curator can also feed the roadmap loop upstream: when a skill or lesson exposes
|
|
405
|
+
an important way to improve thread-keeper itself, the curator child may call
|
|
406
|
+
`evolve_format(...)` and add an `EVOLVE_CANDIDATE:` line to its report. Evolve
|
|
407
|
+
reviewer then audits that candidate and turns it into a GitHub issue when it is
|
|
408
|
+
worth doing.
|
|
409
|
+
|
|
410
|
+
#### 6. Evolve reviewer/applier — roadmap evolution loop
|
|
411
|
+
|
|
412
|
+
The Evolve reviewer is thread-keeper's upstream product/engineering auditor. On
|
|
413
|
+
its interval it audits thread-keeper itself for security/privacy risks, memory
|
|
414
|
+
leaks, runaway daemons, cost waste, reliability gaps, optimizations, and new
|
|
415
|
+
ideas from current agent/MCP/memory tooling research. It does **not** implement
|
|
416
|
+
code. Its durable outputs are updates to `docs/ROADMAP.md` and GitHub issues
|
|
417
|
+
with problem statement, proposed direction, acceptance criteria, test/docs
|
|
418
|
+
impact, and research sources when applicable. Legacy `evolve_format(...)`
|
|
419
|
+
suggestions are still included as audit input, but durable implementation work
|
|
420
|
+
should become GitHub issues.
|
|
421
|
+
|
|
422
|
+
The Evolve applier is the downstream implementer. `evolve_apply_roadmap_issue()`
|
|
423
|
+
picks one open GitHub issue at a time (`roadmap` label first, then FIFO), skips
|
|
424
|
+
issues with an active Evolve claim comment, posts its own claim comment before
|
|
425
|
+
spawning, and advances to the next issue when an issue-local dispatch failure
|
|
426
|
+
prevents startup. The child implements exactly that issue, runs the full suite,
|
|
427
|
+
opens a PR whose body includes `Closes #N`, and only then calls
|
|
428
|
+
`evolve_mark_roadmap_issue_applied(issue_number, pr_url)`. It never commits or
|
|
429
|
+
pushes to `main`, and it never marks an issue applied without a real PR URL. A
|
|
430
|
+
manual `evolve_apply_roadmap_issue(issue_number=N)` remains exact: it reports
|
|
431
|
+
why that issue cannot start instead of silently switching to another issue.
|
|
432
|
+
|
|
433
|
+
Fallback/manual paths remain:
|
|
434
|
+
|
|
435
|
+
- `evolve_apply_curator_report(report_path="")` applies safe Curator memory
|
|
436
|
+
maintenance when no roadmap issue is being drained.
|
|
437
|
+
- `evolve_apply(evolve_id)` still implements legacy promoted
|
|
438
|
+
`evolve_format(...)` suggestions behind a PR and calls
|
|
439
|
+
`evolve_mark_applied(evolve_id, pr_url)`.
|
|
440
|
+
|
|
441
|
+
Set `THREADKEEPER_EVOLVE_REVIEW_INTERVAL_S>0` to run periodic audit/research
|
|
442
|
+
passes and `THREADKEEPER_EVOLVE_APPLY_INTERVAL_S>0` to drain one issue per pass.
|
|
443
|
+
Pin the agent/model with `THREADKEEPER_SPAWN__LOOP__EVOLVE_APPLIER` /
|
|
429
444
|
`THREADKEEPER_SPAWN__MODEL__EVOLVE_APPLIER`. Single-flight (one applier child at
|
|
430
445
|
a time, enforced by a short dispatch file lock plus running-task detection)
|
|
431
446
|
keeps code edits and memory maintenance from colliding.
|
|
447
|
+
Automatic apply passes respect the configured interval so multiple foreground
|
|
448
|
+
MCP server startups do not repeatedly spawn workers for the same open issue.
|
|
449
|
+
Manual tools such as `evolve_apply_roadmap_issue()` dispatch immediately. If no
|
|
450
|
+
roadmap issue is startable, the pass falls back to Curator reports and then
|
|
451
|
+
legacy promoted `evolve_format(...)` suggestions.
|
|
432
452
|
|
|
433
453
|
#### Honest take
|
|
434
454
|
|
|
@@ -545,12 +565,14 @@ The most-used env knobs (full list in `threadkeeper/config.py`):
|
|
|
545
565
|
| `THREADKEEPER_DIALECTIC_VALIDATE_INTERVAL_S` | 0 (off) | dialectic_validator daemon tick (s); 0 disables LLM-driven claim synthesis |
|
|
546
566
|
| `THREADKEEPER_DIALECTIC_VALIDATE_MIN` | 5 | min buffered observations before validator engages |
|
|
547
567
|
| `THREADKEEPER_DIALECTIC_VALIDATE_BATCH_SIZE` | 50 | max observations sent to one validator child; prevents oversized prompts and drains large queues incrementally |
|
|
548
|
-
| `THREADKEEPER_EVOLVE_REVIEW_INTERVAL_S` | 0 (off) | evolve-reviewer daemon tick (s);
|
|
549
|
-
| `THREADKEEPER_EVOLVE_APPLY_INTERVAL_S` | 0 (off) | evolve-applier daemon tick (s);
|
|
568
|
+
| `THREADKEEPER_EVOLVE_REVIEW_INTERVAL_S` | 0 (off) | evolve-reviewer daemon tick (s); audits thread-keeper for safety/leaks/optimization/new ideas, researches current approaches, updates roadmap/issues, and includes legacy evolve suggestions as input |
|
|
569
|
+
| `THREADKEEPER_EVOLVE_APPLY_INTERVAL_S` | 0 (off) | evolve-applier daemon tick (s); implements one open GitHub issue at a time, then falls back to Curator reports and promoted legacy evolve suggestions. Empty checks are throttled between intervals; actionable work and manual apply tools still dispatch |
|
|
550
570
|
| `THREADKEEPER_DIALECTIC_MAX_NEW_CLAIMS` | 3 | max new dialectic claims the validator may create per pass |
|
|
551
571
|
|
|
552
572
|
Persist them in `~/.threadkeeper/.env` (copy from `.env.example`) — one file,
|
|
553
|
-
read via pydantic-settings; real environment variables still override it.
|
|
573
|
+
read via pydantic-settings; real environment variables still override it. On
|
|
574
|
+
macOS, the menu-bar app's gear button can edit the same file visually, save up
|
|
575
|
+
to three local presets, and request a ThreadKeeper restart after saving.
|
|
554
576
|
Hot-config reload is
|
|
555
577
|
[tracked](https://github.com/po4erk91/thread-keeper/issues/2).
|
|
556
578
|
|
|
@@ -581,7 +603,8 @@ THREADKEEPER_SPAWN__MODEL__DIALECTIC_VALIDATOR=opus
|
|
|
581
603
|
Resolution per role: `SPAWN__LOOP__<role>` → `SPAWN__DEFAULT` → active CLI →
|
|
582
604
|
`claude`; `"auto"` (or unset) defers to the active CLI. Real environment
|
|
583
605
|
variables override the `.env`. Force host detection with
|
|
584
|
-
`THREADKEEPER_ACTIVE_CLI=claude
|
|
606
|
+
`THREADKEEPER_ACTIVE_CLI=claude` (or `codex`, `antigravity`/`agy`,
|
|
607
|
+
`gemini`, `copilot`). See `.env.example` for the full knob list.
|
|
585
608
|
|
|
586
609
|
Adapters without headless support (Claude Desktop, VS Code) can't be
|
|
587
610
|
spawn targets — `spawn_status()` reports them as "no adapter" and any
|
|
@@ -719,6 +742,7 @@ threadkeeper/
|
|
|
719
742
|
│ ├── claude_code.py
|
|
720
743
|
│ ├── claude_desktop.py
|
|
721
744
|
│ ├── codex.py
|
|
745
|
+
│ ├── antigravity.py
|
|
722
746
|
│ ├── gemini.py
|
|
723
747
|
│ ├── copilot.py
|
|
724
748
|
│ └── vscode.py
|
|
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "threadkeeper"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "Multi-agent shared brain across Claude Code/Desktop, Codex, Gemini, Copilot, VS Code. Cross-session memory, self-improving skill loops, inter-agent signaling — one local MCP server."
|
|
7
|
+
version = "0.12.0"
|
|
8
|
+
description = "Multi-agent shared brain across Claude Code/Desktop, Codex, Antigravity CLI, Gemini, Copilot, VS Code. Cross-session memory, self-improving skill loops, inter-agent signaling — one local MCP server."
|
|
9
9
|
requires-python = ">=3.11"
|
|
10
10
|
authors = [{ name = "thread-keeper contributors" }]
|
|
11
11
|
license = { text = "MIT" }
|