threadkeeper 0.9.2__tar.gz → 0.11.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.
Files changed (154) hide show
  1. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/PKG-INFO +153 -88
  2. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/README.md +151 -86
  3. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/pyproject.toml +2 -2
  4. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_adapters.py +44 -5
  5. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_agent_status.py +191 -0
  6. threadkeeper-0.11.0/tests/test_auto_update.py +138 -0
  7. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_config_settings.py +5 -0
  8. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_curator.py +5 -0
  9. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_evolve_applier.py +409 -0
  10. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_evolve_daemon.py +77 -10
  11. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_lessons.py +3 -2
  12. threadkeeper-0.11.0/tests/test_menubar_app.py +210 -0
  13. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_skills.py +1 -1
  14. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_spawn_config.py +25 -7
  15. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_thread_janitor.py +1 -0
  16. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/_setup.py +14 -13
  17. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/adapters/__init__.py +8 -3
  18. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/adapters/_hook_helpers.py +1 -1
  19. threadkeeper-0.11.0/threadkeeper/adapters/antigravity.py +137 -0
  20. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/adapters/base.py +5 -3
  21. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/adapters/codex.py +2 -0
  22. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/adapters/vscode.py +1 -1
  23. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/agent_status.py +161 -10
  24. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/assets/macos-agent-status/README.md +28 -2
  25. threadkeeper-0.11.0/threadkeeper/assets/macos-agent-status/ThreadKeeperAgentStatus.swift +1814 -0
  26. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/assets/macos-agent-status/install.sh +5 -0
  27. threadkeeper-0.11.0/threadkeeper/auto_update.py +347 -0
  28. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/brief.py +4 -3
  29. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/config.py +9 -0
  30. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/curator.py +19 -0
  31. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/evolve_applier.py +520 -27
  32. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/evolve_daemon.py +98 -66
  33. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/identity.py +11 -4
  34. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/menubar_app.py +73 -3
  35. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/nudges.py +6 -6
  36. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/review_prompts.py +6 -4
  37. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/spawn_config.py +30 -9
  38. threadkeeper-0.11.0/threadkeeper/tools/agent_status.py +41 -0
  39. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/dashboard.py +1 -0
  40. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/evolve_applier.py +45 -1
  41. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/skills.py +3 -3
  42. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/spawn.py +1 -1
  43. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/threads.py +2 -2
  44. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper.egg-info/PKG-INFO +153 -88
  45. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper.egg-info/SOURCES.txt +3 -0
  46. threadkeeper-0.9.2/tests/test_menubar_app.py +0 -69
  47. threadkeeper-0.9.2/threadkeeper/assets/macos-agent-status/ThreadKeeperAgentStatus.swift +0 -482
  48. threadkeeper-0.9.2/threadkeeper/tools/agent_status.py +0 -19
  49. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/LICENSE +0 -0
  50. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/setup.cfg +0 -0
  51. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_brief_footprint.py +0 -0
  52. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_brief_sections.py +0 -0
  53. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_candidate_reviewer.py +0 -0
  54. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_core_memory.py +0 -0
  55. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_dashboard.py +0 -0
  56. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_delegated_search.py +0 -0
  57. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_dialectic.py +0 -0
  58. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_dialectic_feed_tools.py +0 -0
  59. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_dialectic_miner.py +0 -0
  60. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_dialectic_observation_resolve.py +0 -0
  61. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_dialectic_recompute.py +0 -0
  62. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_dialectic_tier.py +0 -0
  63. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_dialectic_validator.py +0 -0
  64. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_error_paths.py +0 -0
  65. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_evolve_apply_2.py +0 -0
  66. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_evolve_apply_3.py +0 -0
  67. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_extract_daemon.py +0 -0
  68. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_extract_dedup.py +0 -0
  69. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_i18n_multilang.py +0 -0
  70. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_identity.py +0 -0
  71. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_ingest_status.py +0 -0
  72. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_memory_guard.py +0 -0
  73. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_missed_spawns.py +0 -0
  74. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_nudges.py +0 -0
  75. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_onnx_embeddings.py +0 -0
  76. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_panel.py +0 -0
  77. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_probe_daemon.py +0 -0
  78. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_process_health.py +0 -0
  79. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_search_fts_punctuation.py +0 -0
  80. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_shadow_review.py +0 -0
  81. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_skill_hint.py +0 -0
  82. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_skill_passive_tier.py +0 -0
  83. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_skill_tier.py +0 -0
  84. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_skill_use_parser.py +0 -0
  85. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_skill_watcher.py +0 -0
  86. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_spawn_budget.py +0 -0
  87. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_spawn_codex_stdin.py +0 -0
  88. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_spawn_hint.py +0 -0
  89. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_spawn_reap.py +0 -0
  90. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_spawn_slim.py +0 -0
  91. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_spawn_wrap.py +0 -0
  92. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_threads.py +0 -0
  93. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_tools_smoke.py +0 -0
  94. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_validate_threads.py +0 -0
  95. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/tests/test_vec_search.py +0 -0
  96. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/__init__.py +0 -0
  97. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/_mcp.py +0 -0
  98. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/_spawn_wrap.py +0 -0
  99. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/adapters/claude_code.py +0 -0
  100. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/adapters/claude_desktop.py +0 -0
  101. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/adapters/copilot.py +0 -0
  102. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/adapters/gemini.py +0 -0
  103. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/assets/macos-agent-status/Info.plist +0 -0
  104. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/assets/macos-agent-status/build.sh +0 -0
  105. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/candidate_reviewer.py +0 -0
  106. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/db.py +0 -0
  107. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/dialectic_miner.py +0 -0
  108. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/dialectic_validator.py +0 -0
  109. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/embeddings.py +0 -0
  110. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/extract_daemon.py +0 -0
  111. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/helpers.py +0 -0
  112. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/i18n.py +0 -0
  113. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/ingest.py +0 -0
  114. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/lessons.py +0 -0
  115. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/memory_guard.py +0 -0
  116. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/migrate_embeddings.py +0 -0
  117. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/probe_daemon.py +0 -0
  118. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/process_health.py +0 -0
  119. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/search_proxy.py +0 -0
  120. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/server.py +0 -0
  121. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/shadow_review.py +0 -0
  122. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/skill_watcher.py +0 -0
  123. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/spawn_budget.py +0 -0
  124. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/thread_janitor.py +0 -0
  125. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/__init__.py +0 -0
  126. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/candidate_reviewer.py +0 -0
  127. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/concepts.py +0 -0
  128. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/consolidate.py +0 -0
  129. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/core_memory.py +0 -0
  130. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/correlation.py +0 -0
  131. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/curator.py +0 -0
  132. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/dialectic.py +0 -0
  133. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/dialectic_feed.py +0 -0
  134. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/dialog.py +0 -0
  135. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/distill.py +0 -0
  136. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/extract.py +0 -0
  137. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/graph.py +0 -0
  138. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/invariants.py +0 -0
  139. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/lessons.py +0 -0
  140. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/memory_guard.py +0 -0
  141. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/missed_spawns.py +0 -0
  142. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/panel.py +0 -0
  143. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/peers.py +0 -0
  144. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/pickup.py +0 -0
  145. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/probes.py +0 -0
  146. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/process_health.py +0 -0
  147. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/session.py +0 -0
  148. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/shadow_review.py +0 -0
  149. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/style.py +0 -0
  150. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper/tools/validate.py +0 -0
  151. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper.egg-info/dependency_links.txt +0 -0
  152. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper.egg-info/entry_points.txt +0 -0
  153. {threadkeeper-0.9.2 → threadkeeper-0.11.0}/threadkeeper.egg-info/requires.txt +0 -0
  154. {threadkeeper-0.9.2 → threadkeeper-0.11.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.9.2
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.11.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
  [![Python](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org/downloads/)
46
46
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
47
47
  [![PyPI](https://img.shields.io/pypi/v/threadkeeper.svg)](https://pypi.org/project/threadkeeper/)
48
- [![CLIs](https://img.shields.io/badge/CLIs-Claude%20%7C%20Codex%20%7C%20Gemini%20%7C%20Copilot%20%7C%20VS%20Code-green)](#multi-cli-integration)
48
+ [![CLIs](https://img.shields.io/badge/CLIs-Claude%20%7C%20Codex%20%7C%20Antigravity%20%7C%20Gemini%20legacy%20%7C%20Copilot%20%7C%20VS%20Code-green)](#multi-cli-integration)
49
49
 
50
- **Multi-agent shared brain across Claude Code/Desktop, Codex, Gemini,
51
- Copilot, and VS Code.** Cross-session memory, self-improving skill
52
- loops, and inter-agent signaling — one local MCP server turns parallel
53
- agent instances into a coordinated multi-agent system instead of N
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
- desktop, Gemini, Copilot, every MCP-aware VS Code extension) shares
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 Gemini chat are invisible to today's Copilot. Parallel
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,16 @@ 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/`, existing `~/.agents/skills/`, extra roots from
96
- `THREADKEEPER_EXTRA_SKILLS_DIRS`, and `~/.threadkeeper/skills/`),
97
- with lessons.md as a fallback for CLIs without a native skills loader.
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.
99
+
100
+ Foreground MCP servers also run a daily self-update check by default. Source
101
+ checkouts fast-forward their tracked git branch and reinstall the editable
102
+ package; PyPI/pipx/venv installs run `pip install --upgrade` in the current
103
+ interpreter environment. Dirty or diverged git checkouts are skipped rather
104
+ than overwritten.
98
105
 
99
106
  ---
100
107
 
@@ -107,15 +114,17 @@ pipx install 'threadkeeper[semantic]' && thread-keeper-setup
107
114
  ```
108
115
 
109
116
  `thread-keeper-setup` detects every CLI you have installed (Claude
110
- Code / Claude Desktop / Codex CLI + desktop / Gemini / Copilot / VS
111
- Code), registers the MCP server in each one's config, copies hooks to
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
112
120
  `~/.threadkeeper/hooks/`, and writes a managed instructions block into
113
121
  each CLI's per-user instructions file (`CLAUDE.md` / `AGENTS.md` /
114
122
  `GEMINI.md` / `copilot-instructions.md` — Claude Desktop and VS Code
115
123
  have no global instructions file, so that step is skipped for them).
116
124
 
117
- Restart your CLI of choice. The SessionStart hook injects a brief on
118
- first message; no manual `brief()` call required.
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.
119
128
 
120
129
  ### Alternative installs
121
130
 
@@ -162,16 +171,18 @@ thread-keeper-setup --dry-run
162
171
  | Claude Code | `~/.claude.json` `mcpServers` | `~/.claude/CLAUDE.md` | `~/.claude/settings.json` `hooks` | `~/.claude/projects/**/*.jsonl` |
163
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 |
164
173
  | Codex (CLI + desktop) | `~/.codex/config.toml` `[mcp_servers]` (shared between CLI and `Codex.app`) | `~/.codex/AGENTS.md` | not supported | `~/.codex/sessions/**/rollout-*.jsonl` |
165
- | Gemini | `~/.gemini/settings.json` `mcpServers` | `~/.gemini/GEMINI.md` | `~/.gemini/settings.json` `hooks` | `~/.gemini/tmp/<user>/chats/session-*.jsonl` |
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` |
166
176
  | Copilot | `~/.copilot/mcp-config.json` `mcpServers` | `~/.copilot/copilot-instructions.md` | `~/.copilot/hooks.json` | `~/.copilot/session-store.db` (sqlite) |
167
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 |
168
178
 
169
179
  Every CLI that produces parseable transcripts feeds the same
170
180
  `dialog_messages` table with a `source` tag, so `dialog_search()` finds
171
- matches regardless of where the conversation happened. Claude Desktop
172
- and the VS Code adapter are the exceptions — MCP registration only;
173
- their chats don't reach the table for now (Electron IndexedDB on the
174
- Claude Desktop side; per-extension stores on the VS Code 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).
175
186
 
176
187
  VS Code's user-level `mcp.json` is the central host that **every
177
188
  MCP-aware VS Code extension** consumes — GitHub Copilot Chat, the
@@ -206,6 +217,7 @@ or compact text for external monitors:
206
217
  ```sh
207
218
  tk-agent-status
208
219
  tk-agent-status --json
220
+ tk-agent-status --cleanup-memory
209
221
  ```
210
222
 
211
223
  `apps/macos-agent-status/` contains a small macOS menu-bar app that polls this
@@ -215,15 +227,50 @@ spawned a worker. PyPI wheels and sdists also bundle the same Swift source under
215
227
  `threadkeeper/assets/macos-agent-status/`, so a normal `pipx`/`uv tool` install
216
228
  does not need a git checkout for the widget to build. Active loops are sorted
217
229
  first (`running`, then `ready`), so background work stays at the top of the
218
- panel. The app also requests macOS notification permission and sends a
219
- notification when a newly completed autonomous child task produces a useful
220
- result in `recent_results`; the first poll only marks existing results as seen,
221
- so old completions do not spam notifications. Probe backlog is due objective
230
+ panel. `tk-agent-status --cleanup-memory` runs the safe cleanup path used by the
231
+ widget: request server cache trims, apply the RSS guard, and remove orphan MCP
232
+ server processes without killing active spawned child agents. The menu-bar
233
+ status item is backed by AppKit `NSStatusItem`: it shows the black `memorychip`
234
+ icon while idle, then swaps fixed-center, synchronized gear frames whenever
235
+ `running_loop_count` reports at least one active autonomous loop. The status item is
236
+ icon-only; loop counts live in the popover and tooltip. The app also has a Clean
237
+ memory button, self-restarts when its own RSS crosses
238
+ `THREADKEEPER_MENUBAR_RESTART_RSS_MB` (1024 MB default), requests macOS
239
+ notification permission, and sends a notification when a newly completed
240
+ autonomous child task produces a useful result in `recent_results`; the first
241
+ poll only marks existing results as seen, so old completions do not spam
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
222
248
  probes only, not every registered probe, so a healthy cooldown shows `0 due
223
249
  probes` instead of looking stuck. On macOS, `python -m threadkeeper.server`
224
- automatically installs and launches it on MCP startup. Set
250
+ automatically installs and launches it on MCP startup, and restarts the app when
251
+ the installed bundle has changed while an older menu-bar process is still
252
+ running. Set
225
253
  `THREADKEEPER_MENUBAR_AUTO_LAUNCH=0` to disable that behavior.
226
254
 
255
+ ### Auto Update
256
+
257
+ The MCP server starts an auto-update daemon in foreground parent processes.
258
+ By default it checks once per day (`THREADKEEPER_AUTO_UPDATE_INTERVAL_S=86400`):
259
+
260
+ - editable git checkout: skip if tracked files are dirty, otherwise fetch the
261
+ tracked remote branch, fast-forward with `git pull --ff-only`, reinstall the
262
+ editable package, and rerun `threadkeeper._setup`;
263
+ - installed package: run `pip install --upgrade threadkeeper` or
264
+ `threadkeeper[semantic]` in the current interpreter environment, preserving
265
+ semantic extras when they are already installed, then rerun setup when the
266
+ installed version changes.
267
+
268
+ After a successful update, the daemon exits the current MCP process by default
269
+ so the host can restart it on the new code. Disable that with
270
+ `THREADKEEPER_AUTO_UPDATE_RESTART=0`, or disable the updater entirely with
271
+ `THREADKEEPER_AUTO_UPDATE_INTERVAL_S=0`. Each real check records an
272
+ `auto_update_pass` event that appears in dashboard/status telemetry.
273
+
227
274
  Manual fallback from a source checkout:
228
275
 
229
276
  ```sh
@@ -286,16 +333,19 @@ shows agents focused on their primary task rarely do).
286
333
  | 2 | shadow_review daemon | every 15 min (env knob) | recent `dialog_messages` window | SKILL.md, lessons.md |
287
334
  | 3 | extract daemon | every 10 min (env knob) | recent `dialog_messages` window | `extract_candidates` pending queue |
288
335
  | 4 | candidate-reviewer daemon | every 1 h (env knob) | pending candidates queue | SKILL.md (create/patch) / notes / verbatim / reject |
289
- | 5 | Curator daemon | every 7 days (env knob) | every existing lesson + recently-touched skill | REPORT-`<date>`.md; Evolve applier applies the latest complete report |
290
- | 6 | dialectic_miner daemon | configurable (env knob; 0=off) | recent `dialog_messages` user replies + preceding-assistant context | `dialectic_observations` buffer |
291
- | 7 | dialectic_validator daemon | configurable (env knob; 0=off) | buffered `dialectic_observations` | dialectic claims + evidence (support / contradict / supersede) via spawned opus child |
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 |
292
341
 
293
- All five write into the universal Skill format (`SKILL.md` under each
342
+ Learning loops write into the universal Skill format (`SKILL.md` under each
294
343
  known/configured skills root — `~/.claude/skills/`, `~/.codex/skills/`,
295
- existing `~/.agents/skills/`, optional `THREADKEEPER_EXTRA_SKILLS_DIRS`,
296
- plus the canonical `~/.threadkeeper/skills/` mirror), with
297
- `~/.threadkeeper/lessons.md` as a CLI-agnostic fallback for clients
298
- without a native skills loader (Gemini, Copilot, bare MCP).
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).
299
349
 
300
350
  #### 1. Auto-review on close_thread
301
351
 
@@ -383,56 +433,63 @@ entries are marked `[PROTECTED]` in the inventory so the curator
383
433
  never proposes destructive changes against them.
384
434
 
385
435
  Curator itself stays advisory-only by default. The existing Evolve applier is
386
- the apply worker: on its next pass it first looks for the latest complete
387
- Curator report (`CURATOR_PASS_COMPLETE`) that has not been marked applied, then
388
- spawns an `evolve_applier` child to apply only safe, still-current memory
389
- maintenance through `lesson_append` / `lesson_remove` / `skill_manage`. It never
390
- touches `[PROTECTED]`, foreground/user, pinned, or validated entries. Only after
391
- the child finishes does it call `evolve_mark_curator_report_applied(...)`, which
392
- prevents replaying the same report.
393
-
394
- #### 6. Evolve applier — code evolution + curator report apply
395
-
396
- The brief format is not fixed: any session can file a change to it with
397
- `evolve_format(suggestion, rationale)`. The `evolve_reviewer` daemon triages
398
- the queue and **promotes** the good ones promoted suggestions surface in the
399
- brief with a ★. Until now that's where it stopped: a human had to hand-edit
400
- `render_brief` in `brief.py`.
401
-
402
- `evolve_apply(evolve_id)` closes the loop. It spawns an `evolve_applier` child
403
- (resolved through the normal spawn role/model config — recommend opus, it
404
- writes code) that:
405
-
406
- 1. edits `render_brief()` to implement the suggestion;
407
- 2. adds/extends a **golden brief test** asserting both that the new
408
- behavior/field appears *and* that the existing brief sections still render —
409
- a format change can't silently break the brief;
410
- 3. runs the full suite (`.venv/bin/python -m pytest -q`) until green;
411
- 4. opens a **pull request** on a feature branch via `gh`, body quoting the
412
- suggestion + rationale. The generated commit and PR title use the repo's
413
- allowed Conventional Commit types (`feat:`/`fix:` etc.), never the internal
414
- `evolve:` label.
415
-
416
- **Autonomy is the PR gate, nothing more.** The child never pushes or commits to
417
- `main` (which has branch protection); a human reviews and merges. On a
418
- successful PR the child calls `evolve_mark_applied(evolve_id, pr_url)`, which
419
- sets `applied=1` so the suggestion stops resurfacing. Validation inside the
420
- child (golden render_brief test + full suite green) is the objective gate the
421
- loop otherwise lacks.
422
-
423
- The same applier role also drains Curator reports. `evolve_apply_curator_report`
424
- manually applies the latest complete report, or a specific report path. This
425
- path does **not** edit code or open a PR; it uses memory MCP tools only and
426
- marks the report applied with `evolve_mark_curator_report_applied(...)`.
427
-
428
- Manual: `evolve_apply(#id)` (get ids from `evolve_review()`). Optional daemon:
429
- set `THREADKEEPER_EVOLVE_APPLY_INTERVAL_S>0` (default 0 = off) to periodically
430
- apply the latest complete Curator report first, then implement the oldest
431
- promoted+unapplied suggestion. Pin the agent/model with
432
- `THREADKEEPER_SPAWN__LOOP__EVOLVE_APPLIER` /
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` /
433
485
  `THREADKEEPER_SPAWN__MODEL__EVOLVE_APPLIER`. Single-flight (one applier child at
434
486
  a time, enforced by a short dispatch file lock plus running-task detection)
435
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.
436
493
 
437
494
  #### Honest take
438
495
 
@@ -512,6 +569,9 @@ The most-used env knobs (full list in `threadkeeper/config.py`):
512
569
  |---|---|---|
513
570
  | `THREADKEEPER_DB` | `~/.threadkeeper/db.sqlite` | SQLite file |
514
571
  | `THREADKEEPER_AUTO_REVIEW` | "" (off) | auto-review on `close_thread` |
572
+ | `THREADKEEPER_AUTO_UPDATE_INTERVAL_S` | 86400 | MCP self-update check interval; 0 disables |
573
+ | `THREADKEEPER_AUTO_UPDATE_RESTART` | "1" | exit MCP process after applying an update so the host restarts on new code |
574
+ | `THREADKEEPER_AUTO_UPDATE_TIMEOUT_S` | 600 | max seconds for git/pip update commands |
515
575
  | `THREADKEEPER_SHADOW_REVIEW_INTERVAL_S` | 0 (off) | shadow daemon tick (s) |
516
576
  | `THREADKEEPER_SHADOW_REVIEW_WINDOW_S` | 900 | sliding window for shadow scan (s) |
517
577
  | `THREADKEEPER_EXTRACT_INTERVAL_S` | 0 (off) | extract daemon tick (s); 600 = 10 min recommended |
@@ -525,6 +585,7 @@ The most-used env knobs (full list in `threadkeeper/config.py`):
525
585
  | `THREADKEEPER_PROBE_COOLDOWN_S` | 604800 | per-category probe cooldown; 86400 = 1d recommended for active reliability tracking |
526
586
  | `THREADKEEPER_SPAWN_BUDGET_MB` | 3072 | combined child RSS cap (MB); 0 disables |
527
587
  | `THREADKEEPER_MENUBAR_AUTO_LAUNCH` | true | macOS: auto install/launch status menu-bar app on MCP startup |
588
+ | `THREADKEEPER_MENUBAR_RESTART_RSS_MB` | 1024 | macOS widget self-restart RSS threshold; 0 disables |
528
589
  | `THREADKEEPER_MEMORY_GUARD_POLL_S` | 30 | server RSS guard tick (s); 0 disables |
529
590
  | `THREADKEEPER_MEMORY_GUARD_WARN_MB` | 1536 | notify/log when a server crosses this RSS |
530
591
  | `THREADKEEPER_MEMORY_GUARD_KILL_MB` | 3072 | SIGTERM server above this RSS; 0 disables killing |
@@ -545,12 +606,14 @@ The most-used env knobs (full list in `threadkeeper/config.py`):
545
606
  | `THREADKEEPER_DIALECTIC_VALIDATE_INTERVAL_S` | 0 (off) | dialectic_validator daemon tick (s); 0 disables LLM-driven claim synthesis |
546
607
  | `THREADKEEPER_DIALECTIC_VALIDATE_MIN` | 5 | min buffered observations before validator engages |
547
608
  | `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); triages the format-evolution queue (promote/dismiss) |
549
- | `THREADKEEPER_EVOLVE_APPLY_INTERVAL_S` | 0 (off) | evolve-applier daemon tick (s); applies latest complete Curator report first, then oldest promoted+unapplied suggestion behind a PR. Manual `evolve_apply` / `evolve_apply_curator_report` work regardless |
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 |
550
611
  | `THREADKEEPER_DIALECTIC_MAX_NEW_CLAIMS` | 3 | max new dialectic claims the validator may create per pass |
551
612
 
552
613
  Persist them in `~/.threadkeeper/.env` (copy from `.env.example`) — one file,
553
- 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.
554
617
  Hot-config reload is
555
618
  [tracked](https://github.com/po4erk91/thread-keeper/issues/2).
556
619
 
@@ -581,7 +644,8 @@ THREADKEEPER_SPAWN__MODEL__DIALECTIC_VALIDATOR=opus
581
644
  Resolution per role: `SPAWN__LOOP__<role>` → `SPAWN__DEFAULT` → active CLI →
582
645
  `claude`; `"auto"` (or unset) defers to the active CLI. Real environment
583
646
  variables override the `.env`. Force host detection with
584
- `THREADKEEPER_ACTIVE_CLI=claude`. See `.env.example` for the full knob list.
647
+ `THREADKEEPER_ACTIVE_CLI=claude` (or `codex`, `antigravity`/`agy`,
648
+ `gemini`, `copilot`). See `.env.example` for the full knob list.
585
649
 
586
650
  Adapters without headless support (Claude Desktop, VS Code) can't be
587
651
  spawn targets — `spawn_status()` reports them as "no adapter" and any
@@ -719,6 +783,7 @@ threadkeeper/
719
783
  │ ├── claude_code.py
720
784
  │ ├── claude_desktop.py
721
785
  │ ├── codex.py
786
+ │ ├── antigravity.py
722
787
  │ ├── gemini.py
723
788
  │ ├── copilot.py
724
789
  │ └── vscode.py