ctxttools 0.2.0__tar.gz → 0.3.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 (34) hide show
  1. {ctxttools-0.2.0/ctxttools.egg-info → ctxttools-0.3.0}/PKG-INFO +86 -38
  2. {ctxttools-0.2.0 → ctxttools-0.3.0}/README.md +85 -36
  3. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctools/agents.py +791 -43
  4. ctxttools-0.3.0/ctools/backup.py +454 -0
  5. ctxttools-0.3.0/ctools/ccat.py +260 -0
  6. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctools/cconnect.py +55 -32
  7. ctxttools-0.3.0/ctools/ccopy.py +652 -0
  8. ctxttools-0.3.0/ctools/cdir.py +708 -0
  9. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctools/cdu.py +50 -26
  10. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctools/cextract.py +111 -41
  11. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctools/cgrep.py +176 -57
  12. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctools/cli.py +37 -25
  13. ctxttools-0.3.0/ctools/crecover.py +234 -0
  14. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctools/crm.py +58 -38
  15. ctxttools-0.3.0/ctools/filterlib.py +432 -0
  16. ctxttools-0.3.0/ctools/testing.py +61 -0
  17. ctxttools-0.3.0/ctools/webui.py +1811 -0
  18. {ctxttools-0.2.0 → ctxttools-0.3.0/ctxttools.egg-info}/PKG-INFO +86 -38
  19. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctxttools.egg-info/SOURCES.txt +5 -0
  20. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctxttools.egg-info/entry_points.txt +3 -0
  21. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctxttools.egg-info/requires.txt +0 -1
  22. {ctxttools-0.2.0 → ctxttools-0.3.0}/pyproject.toml +4 -2
  23. ctxttools-0.2.0/ctools/ccopy.py +0 -317
  24. ctxttools-0.2.0/ctools/cdir.py +0 -424
  25. ctxttools-0.2.0/ctools/filterlib.py +0 -116
  26. {ctxttools-0.2.0 → ctxttools-0.3.0}/LICENSE.MIT +0 -0
  27. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctools/__init__.py +0 -0
  28. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctools/ctools_mcp.py +0 -0
  29. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctools/lib.py +0 -0
  30. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctools/log.py +0 -0
  31. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctools/strategy.py +0 -0
  32. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctxttools.egg-info/dependency_links.txt +0 -0
  33. {ctxttools-0.2.0 → ctxttools-0.3.0}/ctxttools.egg-info/top_level.txt +0 -0
  34. {ctxttools-0.2.0 → ctxttools-0.3.0}/setup.cfg +0 -0
@@ -1,11 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ctxttools
3
- Version: 0.2.0
3
+ Version: 0.3.0
4
4
  Summary: CLI tools for LLM conversations
5
5
  Requires-Python: >=3.10
6
6
  Description-Content-Type: text/markdown
7
7
  License-File: LICENSE.MIT
8
- Requires-Dist: typer>=0.9.0
9
8
  Requires-Dist: rich>=13.0.0
10
9
  Requires-Dist: tiktoken>=0.5.0
11
10
  Requires-Dist: structlog>=24.0
@@ -18,44 +17,45 @@ Dynamic: license-file
18
17
  <p align="center">
19
18
  <img width="500" alt="ctools" src="https://github.com/user-attachments/assets/ee781bbe-6364-44ed-be2d-72114f1e6d8a" /><br/>
20
19
  <a href=https://pypi.org/project/ctxttools><img src=https://badge.fury.io/py/ctxttools.svg/></a>
20
+ <br/><br/><b>Try it now</b><br/>
21
+ <code>uvx --from ctxttools cdir</code>
22
+ <br/><br/><b>Then install it</b><br/>
23
+ <code>uv tool install ctxttools</code>
21
24
  </p>
22
25
 
23
26
  ------
27
+ **ctools** is a suite of simple tools for navigating through the sessions of the most popular LLM agents and coding tools. It allows you to search your history, transfer conversations, filter them, and even share them among machines and users.
24
28
 
25
- Grep through your conversation history in Claude Desktop, Claude Code, Codex, Pi, Hermes, Goose, Kilo, Hermes, FreeBuff, Cline, and omp.
29
+ It supports [Claude Desktop](https://claude.com/download), [Claude Code](https://github.com/anthropics/claude-code), [Codex](https://github.com/openai/codex), [Pi](https://github.com/earendil-works/pi), [Hermes](https://github.com/NousResearch/hermes-agent), [Goose](https://github.com/aaif-goose/goose), [Kilo](https://github.com/Kilo-Org/kilocode), [FreeBuff](https://github.com/CodebuffAI/freebuff), [Cline](https://github.com/cline/cline), [omp](https://github.com/can1357/oh-my-pi), and [OpenClaw](https://openclaw.ai/).
26
30
 
27
- Copy your conversation from one to another. Start in one program, continue in another. using the normal resume syntax.
31
+ Here's an example:
28
32
 
33
+ > I look for mentions of snake game in opencode using cgrep
34
+ <pre>
35
+ $ <b>cgrep</b> "snake game" opencode
36
+ opencode/ses_a1d1a5a4df984ee698cab4a7:1:user: make a simple snake game in python
37
+ opencode/ses_a1d1a5a4df984ee698cab4a7:2:assistant: I'll make a terminal-based snake game using `curses` (standard library, no dependencies).
38
+ opencode/ses_a1d1a5a4df984ee698cab4a7:3:assistant: Done — `snake.py` is a terminal snake game using Python's built-in `curses` module (no dependencies).
39
+ </pre>
29
40
 
30
- ### 1. `cgrep` — find it in your past conversations
41
+ > cool let's look at the status of that session using cdir
42
+ <pre>
43
+ $ <b>cdir</b> -l opencode/ses_a1d1a5a4df984ee698cab4a7
44
+ ID NAME MODIFIED SIZE MSGS PATH
45
+ ses_a1d1a5a4df984ee698cab4a7 make a simple snake game in python 2026-10-07 16:56 2.7 KB 3 /home/chris/.local/share/opencode
31
46
 
32
- You already know the answer is in a session you had months ago. You just don't remember which one. `cgrep` searches **every session you ever had, across every agent you use**, with a plain regex:
47
+ 1 session(s)
48
+ </pre>
33
49
 
34
- ```shell
35
- $ cgrep -i "ssl"
36
- claude-code/a351eedf:142:assistant: … the TLS handshake fails with SSL wrong version number …
37
- opencode/ses_000d460f:16:user: ok graflex has an erorr in the check. i see this: … [[SSL: WRONG_VERSION_NUMBER] …
38
- opencode/ses_000d460f:34:assistant: Found it. Root cause: `_check_host` (graflex/__init__.py:128) tries `http`, and …
39
- ```
40
-
41
- No agent argument? It searches **every installed agent at once** — Claude Code, Opencode, Kilo, Codex, Pi, Goose, Hermes, Cline, omp, and Freebuff, all in one pass. That last line is the root-cause analysis you wrote six months ago and would never have found again.
42
-
43
- ### 2. `ccopy` — move your project from one tool to another
44
-
45
- Switched from opencode to Claude Code mid-project? You don't have to start from zero. Copy the whole conversation — context, decisions, the lot — into a fresh session in the other tool:
46
-
47
- ```shell
48
- $ ccopy opencode/ses_abc123 claude-code
49
- Copied 128 message(s) from opencode/ses_abc123 to a new claude-code session: 1a2b3c
50
+ > Alright let's copy that session from opencode into pi!
51
+ <pre>
52
+ $ <b>ccopy</b> opencode/ses_a1d1a5a4df984ee698cab4a7 pi
53
+ Copied 3 message(s) from opencode/ses_a1d1a5a4df984ee698cab4a7 to a new pi session: e357f435-f813-463a-b313-f97f1051f3cb
50
54
  Resume it with:
51
- claude-code --resume 1a2b3c
52
- ```
53
-
54
- Your work travels with you. The source is never touched, so it's a true copy. And when the destination is on another machine, it's just `ccopy opencode/ses_abc123 ssh://chris@remote/codex` — it runs over your normal ssh.
55
+ pi --session e357f435-f813-463a-b313-f97f1051f3cb
56
+ </pre>
55
57
 
56
- ctools is a set of GNU-style tools for the history your coding agents leave behind. These two are the headline; the rest (`cdir` to list sessions, `cextract` to move concepts, `cconnect` to pipe them live, `cdu` to count tokens, `crm` to prune) are in service of them.
57
-
58
- **Works with the agents you already use:** Claude Desktop, Claude Code, Opencode, Kilo, Codex, Pi, Goose, Hermes, Cline, omp (oh-my-pi), and Freebuff (Codebuff).
58
+ As you can see, these are unix-friendly tools using simple paradigms that you are already familiar with.
59
59
 
60
60
  ## Tools
61
61
 
@@ -63,13 +63,21 @@ ctools is a set of GNU-style tools for the history your coding agents leave behi
63
63
  |------|--------------|------|
64
64
  | `cgrep` | Search conversation content (grep across every agent) | [docs/cgrep.md](docs/cgrep.md) |
65
65
  | `cdir` | List sessions (ls for your history) | [docs/cdir.md](docs/cdir.md) |
66
+ | `ccat` | Print one or more conversations (cat for your history) | [docs/ccat.md](docs/ccat.md) |
66
67
  | `ccopy` | Copy a whole conversation from one agent to a new session in another | [docs/ccopy.md](docs/ccopy.md) |
67
68
  | `cextract` | Extract concepts from a session into files, and inject them back | [docs/cextract.md](docs/cextract.md) |
68
69
  | `cconnect` | Live concept pipelines between sessions | [docs/cconnect.md](docs/cconnect.md) |
69
70
  | `cdu` | Token usage per session (du for context windows) | [docs/cdu.md](docs/cdu.md) |
70
71
  | `crm` | Remove concepts from a session (mdel) | [docs/crm.md](docs/crm.md) |
72
+ | `ctools-web` | Browser dashboard for all of the above | [Web dashboard](#web-dashboard) |
73
+
74
+ Every tool takes `--version`. The session-mover tools (`ccopy`, `cextract`, `cconnect`, `crm`) also take `--verbose` for structured logging. Each tool's full flag reference, output formats, and examples live in its `docs/` page — the table above is just the 30-second version.
71
75
 
72
- Every tool takes `--version` and `--verbose` (structured logging). Each tool's full flag reference, output formats, and examples live in its `docs/` page — the table above is just the 30-second version.
76
+ ## The problem
77
+
78
+ You talk to LLMs all day. Over weeks, you build up a set of constraints, preferences, and goals. These live in your conversations as system messages. They are valuable. They are also trapped.
79
+
80
+ Say you have been working with opencode for a month. You have refined your coding style through dozens of sessions. Now you start a new Claude Code project and you want those same preferences. You could copy them by hand. Or you could `cextract` them out and `cextract` them back in, or copy the whole conversation across with `ccopy`. Either way, your memory travels with you.
73
81
 
74
82
  ## How it works
75
83
 
@@ -80,6 +88,8 @@ Two stages: **extraction** and **filtering**.
80
88
  - A **strategy** extracts concepts from a conversation. It defines what counts as a concept and how to find it: regex patterns, LLM extraction, whatever. Different strategies produce different ontologies from the same conversation, because context is contestable.
81
89
  - A **filter** selects which extracted concepts reach a destination. It's a binary classifier: pass through or filter out. One concept list can fan out to many destinations, each with its own filter. A coding agent gets coding preferences, a security agent gets security constraints, a PM agent gets goals, all from the same source.
82
90
 
91
+ A filter can be as simple as a type or substring match, or as smart as a **decision model** — a small local classifier that scores each concept and lets it through only when confident. Point a filter at a model and you get *semantic* filtering with no free text to parse: ask "is this concept about security?" and gate on the answer. The model is asked either through Ollama's typed `/v1/systemone` endpoint (calibrated probabilities, the home of decision-dedicated models) or through any OpenAI-compatible `/v1/chat/completions` server (portable, lettered decision-task prompt) — one `endpoint` field decides. See [cextract](docs/cextract.md) for the decision-model and JSON-RPC filter configs.
92
+
83
93
  ```mermaid
84
94
  graph LR
85
95
  SRC["source session"] --> STRAT["strategy<br/>(extraction)"]
@@ -92,13 +102,7 @@ graph LR
92
102
  FC --> DEST_C["destination C"]
93
103
  ```
94
104
 
95
- Context windows are endpoints: opencode, Claude Code, Codex, Pi. They all speak different protocols, but they all consume the same packets. See [cextract](docs/cextract.md) for the concept packet format, strategies, and the filter (JSON-RPC) protocol.
96
-
97
- ## The problem
98
-
99
- You talk to LLMs all day. Over weeks, you build up a set of constraints, preferences, and goals. These live in your conversations as system messages. They are valuable. They are also trapped.
100
-
101
- Say you have been working with opencode for a month. You have refined your coding style through dozens of sessions. Now you start a new Claude Code project and you want those same preferences. You could copy them by hand. Or you could `cextract` them out and `cextract` them back in, or copy the whole conversation across with `ccopy`. Either way, your memory travels with you.
105
+ Context windows are endpoints: opencode, Claude Code, Codex, Pi. They all speak different protocols, but they all consume the same packets. See [cextract](docs/cextract.md) for the concept packet format, strategies, and the filter configs (decision model and JSON-RPC).
102
106
 
103
107
  ## Supported endpoints
104
108
 
@@ -115,6 +119,12 @@ Say you have been working with opencode for a month. You have refined your codin
115
119
  | cline | JSON (`~/.cline/data/tasks/`) |
116
120
  | omp | JSONL (`~/.omp/agent/sessions/`, tree journal) |
117
121
  | freebuff | JSON (`~/.config/<codebuff>/projects/`) |
122
+ | openclaw | SQLite (per-agent, `~/.openclaw/agents/`, `OPENCLAW_STATE_DIR`) |
123
+
124
+ OpenClaw is a **personal assistant** rather than a terminal coding agent, so it
125
+ runs in a local Gateway that owns its store; ctools reads and exports its
126
+ sessions but does not seed new ones (the store has canonical-index and integrity
127
+ checks that a raw insert cannot satisfy).
118
128
 
119
129
  Run `cdir` to see which endpoints are found on your system and where they store data.
120
130
 
@@ -157,6 +167,37 @@ Add to your MCP config:
157
167
  }
158
168
  ```
159
169
 
170
+ ## Web dashboard
171
+
172
+ Prefer a mouse to a man page? ctools ships a browser dashboard — a small local
173
+ web server (Python stdlib only, no web dependencies) with the same library
174
+ underneath. Same on macOS, Windows, and Linux:
175
+
176
+ ```sh
177
+ $ ctools-web # or: python -m ctools.webui
178
+ ctools 0.2.1 dashboard: http://127.0.0.1:8765
179
+ ```
180
+
181
+ Open the URL. You get four views:
182
+
183
+ - **Overview** — every supported agent, installed or not, with session counts
184
+ and total tokens, and a jump into each agent's sessions.
185
+ - **Search** — `cgrep` in the browser: one regex box, per-agent chips, live
186
+ matches; click any match to open that conversation.
187
+ - **Sessions** — `cdir` for one agent: newest, largest, or by token usage.
188
+ - **Conversation** — `ccat` with the source session's messages, token usage,
189
+ the resume command, concept extraction (`cextract`), a markdown export,
190
+ and **Copy** — `ccopy` to any other installed agent, which creates a fresh
191
+ session there (source untouched) and tells you how to resume it.
192
+
193
+ The server binds to `127.0.0.1` by default, so nothing is exposed to your
194
+ network unless you pass `--host 0.0.0.0`. There is one write operation:
195
+ Copy. Everything else is read-only against the agents' storage.
196
+
197
+ ```sh
198
+ ctools-web --port 9000
199
+ ```
200
+
160
201
  ## Installation
161
202
 
162
203
  ```sh
@@ -179,7 +220,7 @@ from ctools.lib import get_formatter
179
220
  from ctools.cgrep import grep_session
180
221
  from ctools.cextract import extract_concepts_from_messages
181
222
  from ctools.cdu import count_tokens, get_session_tokens
182
- from ctools.filterlib import JSONRPCFilter, load_filter
223
+ from ctools.filterlib import JSONRPCFilter, SystemOneFilter, load_filter
183
224
  from ctools.log import configure_logging, get_logger
184
225
  ```
185
226
 
@@ -204,6 +245,13 @@ from ctools.agents import OpencodeAgent
204
245
  agent = OpencodeAgent('/backup/opencode')
205
246
  ```
206
247
 
248
+ ## Where to go next
249
+
250
+ - **Per-tool reference** — the [Tools](#tools) table above links to a `docs/` page for each command: every flag, output format, and a worked example.
251
+ - **The interchange format** — how a conversation becomes a portable, lossless envelope and back, and why 2N agents compose into N² transfers. See [interchange](docs/interchange.md).
252
+ - **Filtering with decision models** — the full decision-model and JSON-RPC filter configs, with live examples. See [cextract](docs/cextract.md#filters) and [cconnect](docs/cconnect.md#filter-configuration).
253
+ - **Adding an endpoint** — one `Agent` subclass plus a line in `AGENT_CLASSES`. See [Supported endpoints](#supported-endpoints).
254
+
207
255
  ## Credits
208
256
 
209
257
  ctools was extracted from [Gab n' Go](https://github.com/day50-dev/gabngo). It's named after [GNU mtools](https://www.gnu.org/software/mtools/), which does the same thing for DOS floppies — because your context window is about the size of a DOS-floppy. The flag habits are GNU's too: `--version`, `-1`, `-S`, `-u`, and the rest behave the way you'd expect.
@@ -1,44 +1,45 @@
1
1
  <p align="center">
2
2
  <img width="500" alt="ctools" src="https://github.com/user-attachments/assets/ee781bbe-6364-44ed-be2d-72114f1e6d8a" /><br/>
3
3
  <a href=https://pypi.org/project/ctxttools><img src=https://badge.fury.io/py/ctxttools.svg/></a>
4
+ <br/><br/><b>Try it now</b><br/>
5
+ <code>uvx --from ctxttools cdir</code>
6
+ <br/><br/><b>Then install it</b><br/>
7
+ <code>uv tool install ctxttools</code>
4
8
  </p>
5
9
 
6
10
  ------
11
+ **ctools** is a suite of simple tools for navigating through the sessions of the most popular LLM agents and coding tools. It allows you to search your history, transfer conversations, filter them, and even share them among machines and users.
7
12
 
8
- Grep through your conversation history in Claude Desktop, Claude Code, Codex, Pi, Hermes, Goose, Kilo, Hermes, FreeBuff, Cline, and omp.
13
+ It supports [Claude Desktop](https://claude.com/download), [Claude Code](https://github.com/anthropics/claude-code), [Codex](https://github.com/openai/codex), [Pi](https://github.com/earendil-works/pi), [Hermes](https://github.com/NousResearch/hermes-agent), [Goose](https://github.com/aaif-goose/goose), [Kilo](https://github.com/Kilo-Org/kilocode), [FreeBuff](https://github.com/CodebuffAI/freebuff), [Cline](https://github.com/cline/cline), [omp](https://github.com/can1357/oh-my-pi), and [OpenClaw](https://openclaw.ai/).
9
14
 
10
- Copy your conversation from one to another. Start in one program, continue in another. using the normal resume syntax.
15
+ Here's an example:
11
16
 
17
+ > I look for mentions of snake game in opencode using cgrep
18
+ <pre>
19
+ $ <b>cgrep</b> "snake game" opencode
20
+ opencode/ses_a1d1a5a4df984ee698cab4a7:1:user: make a simple snake game in python
21
+ opencode/ses_a1d1a5a4df984ee698cab4a7:2:assistant: I'll make a terminal-based snake game using `curses` (standard library, no dependencies).
22
+ opencode/ses_a1d1a5a4df984ee698cab4a7:3:assistant: Done — `snake.py` is a terminal snake game using Python's built-in `curses` module (no dependencies).
23
+ </pre>
12
24
 
13
- ### 1. `cgrep` — find it in your past conversations
25
+ > cool let's look at the status of that session using cdir
26
+ <pre>
27
+ $ <b>cdir</b> -l opencode/ses_a1d1a5a4df984ee698cab4a7
28
+ ID NAME MODIFIED SIZE MSGS PATH
29
+ ses_a1d1a5a4df984ee698cab4a7 make a simple snake game in python 2026-10-07 16:56 2.7 KB 3 /home/chris/.local/share/opencode
14
30
 
15
- You already know the answer is in a session you had months ago. You just don't remember which one. `cgrep` searches **every session you ever had, across every agent you use**, with a plain regex:
31
+ 1 session(s)
32
+ </pre>
16
33
 
17
- ```shell
18
- $ cgrep -i "ssl"
19
- claude-code/a351eedf:142:assistant: … the TLS handshake fails with SSL wrong version number …
20
- opencode/ses_000d460f:16:user: ok graflex has an erorr in the check. i see this: … [[SSL: WRONG_VERSION_NUMBER] …
21
- opencode/ses_000d460f:34:assistant: Found it. Root cause: `_check_host` (graflex/__init__.py:128) tries `http`, and …
22
- ```
23
-
24
- No agent argument? It searches **every installed agent at once** — Claude Code, Opencode, Kilo, Codex, Pi, Goose, Hermes, Cline, omp, and Freebuff, all in one pass. That last line is the root-cause analysis you wrote six months ago and would never have found again.
25
-
26
- ### 2. `ccopy` — move your project from one tool to another
27
-
28
- Switched from opencode to Claude Code mid-project? You don't have to start from zero. Copy the whole conversation — context, decisions, the lot — into a fresh session in the other tool:
29
-
30
- ```shell
31
- $ ccopy opencode/ses_abc123 claude-code
32
- Copied 128 message(s) from opencode/ses_abc123 to a new claude-code session: 1a2b3c
34
+ > Alright let's copy that session from opencode into pi!
35
+ <pre>
36
+ $ <b>ccopy</b> opencode/ses_a1d1a5a4df984ee698cab4a7 pi
37
+ Copied 3 message(s) from opencode/ses_a1d1a5a4df984ee698cab4a7 to a new pi session: e357f435-f813-463a-b313-f97f1051f3cb
33
38
  Resume it with:
34
- claude-code --resume 1a2b3c
35
- ```
36
-
37
- Your work travels with you. The source is never touched, so it's a true copy. And when the destination is on another machine, it's just `ccopy opencode/ses_abc123 ssh://chris@remote/codex` — it runs over your normal ssh.
39
+ pi --session e357f435-f813-463a-b313-f97f1051f3cb
40
+ </pre>
38
41
 
39
- ctools is a set of GNU-style tools for the history your coding agents leave behind. These two are the headline; the rest (`cdir` to list sessions, `cextract` to move concepts, `cconnect` to pipe them live, `cdu` to count tokens, `crm` to prune) are in service of them.
40
-
41
- **Works with the agents you already use:** Claude Desktop, Claude Code, Opencode, Kilo, Codex, Pi, Goose, Hermes, Cline, omp (oh-my-pi), and Freebuff (Codebuff).
42
+ As you can see, these are unix-friendly tools using simple paradigms that you are already familiar with.
42
43
 
43
44
  ## Tools
44
45
 
@@ -46,13 +47,21 @@ ctools is a set of GNU-style tools for the history your coding agents leave behi
46
47
  |------|--------------|------|
47
48
  | `cgrep` | Search conversation content (grep across every agent) | [docs/cgrep.md](docs/cgrep.md) |
48
49
  | `cdir` | List sessions (ls for your history) | [docs/cdir.md](docs/cdir.md) |
50
+ | `ccat` | Print one or more conversations (cat for your history) | [docs/ccat.md](docs/ccat.md) |
49
51
  | `ccopy` | Copy a whole conversation from one agent to a new session in another | [docs/ccopy.md](docs/ccopy.md) |
50
52
  | `cextract` | Extract concepts from a session into files, and inject them back | [docs/cextract.md](docs/cextract.md) |
51
53
  | `cconnect` | Live concept pipelines between sessions | [docs/cconnect.md](docs/cconnect.md) |
52
54
  | `cdu` | Token usage per session (du for context windows) | [docs/cdu.md](docs/cdu.md) |
53
55
  | `crm` | Remove concepts from a session (mdel) | [docs/crm.md](docs/crm.md) |
56
+ | `ctools-web` | Browser dashboard for all of the above | [Web dashboard](#web-dashboard) |
57
+
58
+ Every tool takes `--version`. The session-mover tools (`ccopy`, `cextract`, `cconnect`, `crm`) also take `--verbose` for structured logging. Each tool's full flag reference, output formats, and examples live in its `docs/` page — the table above is just the 30-second version.
54
59
 
55
- Every tool takes `--version` and `--verbose` (structured logging). Each tool's full flag reference, output formats, and examples live in its `docs/` page — the table above is just the 30-second version.
60
+ ## The problem
61
+
62
+ You talk to LLMs all day. Over weeks, you build up a set of constraints, preferences, and goals. These live in your conversations as system messages. They are valuable. They are also trapped.
63
+
64
+ Say you have been working with opencode for a month. You have refined your coding style through dozens of sessions. Now you start a new Claude Code project and you want those same preferences. You could copy them by hand. Or you could `cextract` them out and `cextract` them back in, or copy the whole conversation across with `ccopy`. Either way, your memory travels with you.
56
65
 
57
66
  ## How it works
58
67
 
@@ -63,6 +72,8 @@ Two stages: **extraction** and **filtering**.
63
72
  - A **strategy** extracts concepts from a conversation. It defines what counts as a concept and how to find it: regex patterns, LLM extraction, whatever. Different strategies produce different ontologies from the same conversation, because context is contestable.
64
73
  - A **filter** selects which extracted concepts reach a destination. It's a binary classifier: pass through or filter out. One concept list can fan out to many destinations, each with its own filter. A coding agent gets coding preferences, a security agent gets security constraints, a PM agent gets goals, all from the same source.
65
74
 
75
+ A filter can be as simple as a type or substring match, or as smart as a **decision model** — a small local classifier that scores each concept and lets it through only when confident. Point a filter at a model and you get *semantic* filtering with no free text to parse: ask "is this concept about security?" and gate on the answer. The model is asked either through Ollama's typed `/v1/systemone` endpoint (calibrated probabilities, the home of decision-dedicated models) or through any OpenAI-compatible `/v1/chat/completions` server (portable, lettered decision-task prompt) — one `endpoint` field decides. See [cextract](docs/cextract.md) for the decision-model and JSON-RPC filter configs.
76
+
66
77
  ```mermaid
67
78
  graph LR
68
79
  SRC["source session"] --> STRAT["strategy<br/>(extraction)"]
@@ -75,13 +86,7 @@ graph LR
75
86
  FC --> DEST_C["destination C"]
76
87
  ```
77
88
 
78
- Context windows are endpoints: opencode, Claude Code, Codex, Pi. They all speak different protocols, but they all consume the same packets. See [cextract](docs/cextract.md) for the concept packet format, strategies, and the filter (JSON-RPC) protocol.
79
-
80
- ## The problem
81
-
82
- You talk to LLMs all day. Over weeks, you build up a set of constraints, preferences, and goals. These live in your conversations as system messages. They are valuable. They are also trapped.
83
-
84
- Say you have been working with opencode for a month. You have refined your coding style through dozens of sessions. Now you start a new Claude Code project and you want those same preferences. You could copy them by hand. Or you could `cextract` them out and `cextract` them back in, or copy the whole conversation across with `ccopy`. Either way, your memory travels with you.
89
+ Context windows are endpoints: opencode, Claude Code, Codex, Pi. They all speak different protocols, but they all consume the same packets. See [cextract](docs/cextract.md) for the concept packet format, strategies, and the filter configs (decision model and JSON-RPC).
85
90
 
86
91
  ## Supported endpoints
87
92
 
@@ -98,6 +103,12 @@ Say you have been working with opencode for a month. You have refined your codin
98
103
  | cline | JSON (`~/.cline/data/tasks/`) |
99
104
  | omp | JSONL (`~/.omp/agent/sessions/`, tree journal) |
100
105
  | freebuff | JSON (`~/.config/<codebuff>/projects/`) |
106
+ | openclaw | SQLite (per-agent, `~/.openclaw/agents/`, `OPENCLAW_STATE_DIR`) |
107
+
108
+ OpenClaw is a **personal assistant** rather than a terminal coding agent, so it
109
+ runs in a local Gateway that owns its store; ctools reads and exports its
110
+ sessions but does not seed new ones (the store has canonical-index and integrity
111
+ checks that a raw insert cannot satisfy).
101
112
 
102
113
  Run `cdir` to see which endpoints are found on your system and where they store data.
103
114
 
@@ -140,6 +151,37 @@ Add to your MCP config:
140
151
  }
141
152
  ```
142
153
 
154
+ ## Web dashboard
155
+
156
+ Prefer a mouse to a man page? ctools ships a browser dashboard — a small local
157
+ web server (Python stdlib only, no web dependencies) with the same library
158
+ underneath. Same on macOS, Windows, and Linux:
159
+
160
+ ```sh
161
+ $ ctools-web # or: python -m ctools.webui
162
+ ctools 0.2.1 dashboard: http://127.0.0.1:8765
163
+ ```
164
+
165
+ Open the URL. You get four views:
166
+
167
+ - **Overview** — every supported agent, installed or not, with session counts
168
+ and total tokens, and a jump into each agent's sessions.
169
+ - **Search** — `cgrep` in the browser: one regex box, per-agent chips, live
170
+ matches; click any match to open that conversation.
171
+ - **Sessions** — `cdir` for one agent: newest, largest, or by token usage.
172
+ - **Conversation** — `ccat` with the source session's messages, token usage,
173
+ the resume command, concept extraction (`cextract`), a markdown export,
174
+ and **Copy** — `ccopy` to any other installed agent, which creates a fresh
175
+ session there (source untouched) and tells you how to resume it.
176
+
177
+ The server binds to `127.0.0.1` by default, so nothing is exposed to your
178
+ network unless you pass `--host 0.0.0.0`. There is one write operation:
179
+ Copy. Everything else is read-only against the agents' storage.
180
+
181
+ ```sh
182
+ ctools-web --port 9000
183
+ ```
184
+
143
185
  ## Installation
144
186
 
145
187
  ```sh
@@ -162,7 +204,7 @@ from ctools.lib import get_formatter
162
204
  from ctools.cgrep import grep_session
163
205
  from ctools.cextract import extract_concepts_from_messages
164
206
  from ctools.cdu import count_tokens, get_session_tokens
165
- from ctools.filterlib import JSONRPCFilter, load_filter
207
+ from ctools.filterlib import JSONRPCFilter, SystemOneFilter, load_filter
166
208
  from ctools.log import configure_logging, get_logger
167
209
  ```
168
210
 
@@ -187,6 +229,13 @@ from ctools.agents import OpencodeAgent
187
229
  agent = OpencodeAgent('/backup/opencode')
188
230
  ```
189
231
 
232
+ ## Where to go next
233
+
234
+ - **Per-tool reference** — the [Tools](#tools) table above links to a `docs/` page for each command: every flag, output format, and a worked example.
235
+ - **The interchange format** — how a conversation becomes a portable, lossless envelope and back, and why 2N agents compose into N² transfers. See [interchange](docs/interchange.md).
236
+ - **Filtering with decision models** — the full decision-model and JSON-RPC filter configs, with live examples. See [cextract](docs/cextract.md#filters) and [cconnect](docs/cconnect.md#filter-configuration).
237
+ - **Adding an endpoint** — one `Agent` subclass plus a line in `AGENT_CLASSES`. See [Supported endpoints](#supported-endpoints).
238
+
190
239
  ## Credits
191
240
 
192
241
  ctools was extracted from [Gab n' Go](https://github.com/day50-dev/gabngo). It's named after [GNU mtools](https://www.gnu.org/software/mtools/), which does the same thing for DOS floppies — because your context window is about the size of a DOS-floppy. The flag habits are GNU's too: `--version`, `-1`, `-S`, `-u`, and the rest behave the way you'd expect.