context-forge-cli 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- context_forge_cli-0.1.0/.contextforge.toml +12 -0
- context_forge_cli-0.1.0/.github/workflows/publish.yml +25 -0
- context_forge_cli-0.1.0/.gitignore +10 -0
- context_forge_cli-0.1.0/.python-version +1 -0
- context_forge_cli-0.1.0/AGENTS.md +93 -0
- context_forge_cli-0.1.0/PKG-INFO +340 -0
- context_forge_cli-0.1.0/PLAN.md +129 -0
- context_forge_cli-0.1.0/README.md +312 -0
- context_forge_cli-0.1.0/contextforge/__init__.py +3 -0
- context_forge_cli-0.1.0/contextforge/adapters/__init__.py +3 -0
- context_forge_cli-0.1.0/contextforge/adapters/altimate_code.py +179 -0
- context_forge_cli-0.1.0/contextforge/adapters/base.py +44 -0
- context_forge_cli-0.1.0/contextforge/adapters/claude_code.py +393 -0
- context_forge_cli-0.1.0/contextforge/adapters/claude_desktop.py +306 -0
- context_forge_cli-0.1.0/contextforge/adapters/codex.py +220 -0
- context_forge_cli-0.1.0/contextforge/adapters/registry.py +31 -0
- context_forge_cli-0.1.0/contextforge/cli.py +523 -0
- context_forge_cli-0.1.0/contextforge/core/__init__.py +0 -0
- context_forge_cli-0.1.0/contextforge/core/analytics.py +226 -0
- context_forge_cli-0.1.0/contextforge/core/compactor.py +182 -0
- context_forge_cli-0.1.0/contextforge/core/db.py +181 -0
- context_forge_cli-0.1.0/contextforge/core/injector.py +94 -0
- context_forge_cli-0.1.0/contextforge/core/scanner.py +72 -0
- context_forge_cli-0.1.0/contextforge/core/summarizer.py +155 -0
- context_forge_cli-0.1.0/contextforge/core/token_analyzer.py +91 -0
- context_forge_cli-0.1.0/contextforge/models/__init__.py +4 -0
- context_forge_cli-0.1.0/contextforge/models/config.py +34 -0
- context_forge_cli-0.1.0/contextforge/models/session.py +37 -0
- context_forge_cli-0.1.0/contextforge/tui/__init__.py +0 -0
- context_forge_cli-0.1.0/contextforge/tui/app.py +204 -0
- context_forge_cli-0.1.0/contextforge/tui/styles.tcss +50 -0
- context_forge_cli-0.1.0/contextforge/tui/widgets/__init__.py +0 -0
- context_forge_cli-0.1.0/contextforge/tui/widgets/session_detail.py +191 -0
- context_forge_cli-0.1.0/contextforge/tui/widgets/session_table.py +277 -0
- context_forge_cli-0.1.0/contextforge/tui/widgets/stats_panel.py +340 -0
- context_forge_cli-0.1.0/contextforge/tui/widgets/status_bar.py +102 -0
- context_forge_cli-0.1.0/contextforge/tui/widgets/tokens_panel.py +134 -0
- context_forge_cli-0.1.0/contextforge/tui/widgets/transfer_panel.py +119 -0
- context_forge_cli-0.1.0/contextforge/utils/__init__.py +0 -0
- context_forge_cli-0.1.0/contextforge/utils/display.py +105 -0
- context_forge_cli-0.1.0/contextforge/utils/tokens.py +17 -0
- context_forge_cli-0.1.0/pyproject.toml +51 -0
- context_forge_cli-0.1.0/tests/__init__.py +0 -0
- context_forge_cli-0.1.0/tests/adapters/__init__.py +0 -0
- context_forge_cli-0.1.0/tests/adapters/test_claude_code.py +75 -0
- context_forge_cli-0.1.0/tests/core/__init__.py +0 -0
- context_forge_cli-0.1.0/tests/core/test_compactor.py +65 -0
- context_forge_cli-0.1.0/tests/core/test_db.py +62 -0
- context_forge_cli-0.1.0/tests/core/test_injector.py +323 -0
- context_forge_cli-0.1.0/tests/core/test_summarizer.py +226 -0
- context_forge_cli-0.1.0/tests/core/test_token_analyzer.py +112 -0
- context_forge_cli-0.1.0/tests/fixtures/claude_session_sample.jsonl +4 -0
- context_forge_cli-0.1.0/uv.lock +860 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# ContextForge project-level config (used when running cf from this repo)
|
|
2
|
+
# Override user-level config at ~/.contextforge/config.toml
|
|
3
|
+
|
|
4
|
+
[llm]
|
|
5
|
+
# model = "claude-haiku-4-5-20251001"
|
|
6
|
+
|
|
7
|
+
[compactor]
|
|
8
|
+
default_strategy = "summary_only"
|
|
9
|
+
default_token_budget = 4096
|
|
10
|
+
|
|
11
|
+
[scanner]
|
|
12
|
+
max_sessions_per_tool = 200
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- "v*"
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
publish:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
environment: pypi
|
|
12
|
+
permissions:
|
|
13
|
+
id-token: write # required for trusted publishing
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Install uv
|
|
19
|
+
uses: astral-sh/setup-uv@v5
|
|
20
|
+
|
|
21
|
+
- name: Build
|
|
22
|
+
run: uv build
|
|
23
|
+
|
|
24
|
+
- name: Publish to PyPI
|
|
25
|
+
run: uv publish
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.13
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# AGENTS.md — Guidelines for Agents Working on ContextForge
|
|
2
|
+
|
|
3
|
+
This file tells automated agents (Claude Code, Codex, altimate-code, etc.) how to work
|
|
4
|
+
safely and effectively on this repository.
|
|
5
|
+
|
|
6
|
+
## Project Overview
|
|
7
|
+
|
|
8
|
+
ContextForge is a Python CLI/TUI tool. Entry point: `contextforge/cli.py` (command: `cf`).
|
|
9
|
+
Core modules: `adapters/`, `core/`, `models/`, `tui/`. Tests: `tests/`.
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
uv sync # install all dependencies
|
|
15
|
+
uv run pytest # run the test suite
|
|
16
|
+
uv run cf --help # run the CLI locally
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Hard Invariants — Never Violate These
|
|
20
|
+
|
|
21
|
+
1. **Adapters are read-only.** No adapter may write to tool-native storage
|
|
22
|
+
(`~/.claude/`, `~/.codex/`, `~/.local/share/altimate-code/`). This is a hard safety boundary.
|
|
23
|
+
|
|
24
|
+
2. **`build_inject_command()` returns a string; it does NOT execute it.**
|
|
25
|
+
Execution happens only in `core/injector.py` when the user passes `--execute`.
|
|
26
|
+
|
|
27
|
+
3. **Pydantic models in `models/` are the canonical data contract.**
|
|
28
|
+
Adapters must return valid `Session` and `Message` objects. Never pass raw dicts
|
|
29
|
+
across module boundaries.
|
|
30
|
+
|
|
31
|
+
4. **SQLite schema changes require a migration function in `core/db.py`.**
|
|
32
|
+
Do not ALTER TABLE directly. Add a new migration in `_migrate()` keyed by version integer.
|
|
33
|
+
|
|
34
|
+
5. **Token budget is a hard cap, not a guideline.**
|
|
35
|
+
`compactor.py` must never return a bundle exceeding `token_budget`.
|
|
36
|
+
Use `utils/tokens.py` to verify before returning.
|
|
37
|
+
|
|
38
|
+
## Adding a New Tool Adapter
|
|
39
|
+
|
|
40
|
+
1. Create `contextforge/adapters/<tool_name>.py`, subclass `ToolAdapter` from `adapters/base.py`
|
|
41
|
+
2. Implement `discover_sessions()`, `load_messages()`, `build_inject_command()`
|
|
42
|
+
3. Register in `adapters/registry.py`: `ADAPTERS["<tool_name>"] = MyAdapterClass`
|
|
43
|
+
4. Add fixture session data to `tests/fixtures/`
|
|
44
|
+
5. Add tests in `tests/adapters/test_<tool_name>.py`
|
|
45
|
+
6. Update the Supported Tools table in `README.md`
|
|
46
|
+
7. Mark the relevant item `[x]` in `PLAN.md`
|
|
47
|
+
|
|
48
|
+
## Updating the Plan
|
|
49
|
+
|
|
50
|
+
- As you complete items, mark them `[x]` in `PLAN.md`
|
|
51
|
+
- When starting a new Phase, update the `Status:` line at the top of `PLAN.md`
|
|
52
|
+
- When completing a phase, update `README.md` to reflect new capabilities
|
|
53
|
+
|
|
54
|
+
## CLI Conventions
|
|
55
|
+
|
|
56
|
+
- Every command that produces structured data must support `--format json`
|
|
57
|
+
- Long-running operations (scan, summarize --all) must show a `rich.progress` bar
|
|
58
|
+
- Errors must be printed to stderr; exit code 1 on failure
|
|
59
|
+
|
|
60
|
+
## Testing
|
|
61
|
+
|
|
62
|
+
- All adapter tests must work offline (no live tool required). Use fixtures.
|
|
63
|
+
- Summarizer tests must mock the Anthropic client.
|
|
64
|
+
- Run `uv run pytest tests/` before committing.
|
|
65
|
+
- Target >80% coverage on `core/` and `adapters/`.
|
|
66
|
+
|
|
67
|
+
## Commit Style
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
feat(adapters): add opencode standalone adapter
|
|
71
|
+
fix(compactor): respect token budget when combining sessions
|
|
72
|
+
docs(readme): add troubleshooting section for Codex SQLite path
|
|
73
|
+
test(core): add scanner integration tests
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Module Ownership
|
|
77
|
+
|
|
78
|
+
| Area | Module |
|
|
79
|
+
|---|---|
|
|
80
|
+
| Tool discovery | `adapters/<tool>.py` |
|
|
81
|
+
| Session indexing | `core/scanner.py` |
|
|
82
|
+
| DB schema + CRUD | `core/db.py` |
|
|
83
|
+
| Summarization | `core/summarizer.py` |
|
|
84
|
+
| Context compaction | `core/compactor.py` |
|
|
85
|
+
| Shell command building | `core/injector.py` |
|
|
86
|
+
| CLI commands | `contextforge/cli.py` |
|
|
87
|
+
| TUI layout | `tui/app.py` |
|
|
88
|
+
|
|
89
|
+
## Do Not Touch
|
|
90
|
+
|
|
91
|
+
- `~/.claude/`, `~/.codex/`, `~/.local/share/altimate-code/` — tool-native storage
|
|
92
|
+
- `uv.lock` — only `uv` should modify this
|
|
93
|
+
- `~/.contextforge/contextforge.db` — only `core/db.py` should modify this
|
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: context-forge-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Session manager and context bridge for agentic CLI tools
|
|
5
|
+
Project-URL: Homepage, https://github.com/emmver/contextforge
|
|
6
|
+
Project-URL: Repository, https://github.com/emmver/contextforge
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/emmver/contextforge/issues
|
|
8
|
+
Author-email: emmver <emmvereroudakis@gmail.com>
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: ai,claude,cli,codex,context,sessions,tui
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
19
|
+
Requires-Python: >=3.13
|
|
20
|
+
Requires-Dist: anthropic>=0.89.0
|
|
21
|
+
Requires-Dist: pydantic>=2.12.5
|
|
22
|
+
Requires-Dist: rich>=14.3.3
|
|
23
|
+
Requires-Dist: sqlite-utils>=3.39
|
|
24
|
+
Requires-Dist: textual>=8.2.2
|
|
25
|
+
Requires-Dist: tiktoken>=0.12.0
|
|
26
|
+
Requires-Dist: typer>=0.24.1
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
|
|
29
|
+
# ContextForge
|
|
30
|
+
|
|
31
|
+
**Session manager and context bridge for agentic CLI tools.**
|
|
32
|
+
|
|
33
|
+
ContextForge (`cf`) tracks sessions from Claude Code, Codex, altimate-code, and other
|
|
34
|
+
agentic CLI tools. It generates plain-English summaries of each session and can compact
|
|
35
|
+
and transfer context from one or more sessions into a new session — within the same tool
|
|
36
|
+
or across different tools.
|
|
37
|
+
|
|
38
|
+
## What it does
|
|
39
|
+
|
|
40
|
+
- **Discovers sessions** from Claude Code (`~/.claude/projects/`), Codex (`~/.codex/state_5.sqlite`), and altimate-code (`~/.local/share/altimate-code/`)
|
|
41
|
+
- **Generates summaries** of what each session accomplished (with optional Claude API integration)
|
|
42
|
+
- **Compacts context** intelligently, reducing multi-turn conversations to a token-efficient ContextBundle
|
|
43
|
+
- **Transfers context** across tools and sessions (Claude Code → Codex, Codex → altimate-code, etc.)
|
|
44
|
+
- **Provides a TUI dashboard** to browse and manage sessions interactively
|
|
45
|
+
|
|
46
|
+
## Prerequisites
|
|
47
|
+
|
|
48
|
+
- **Python 3.13+** (ContextForge requires Python 3.13 or later)
|
|
49
|
+
- **uv** or **pipx** (for installation as a tool)
|
|
50
|
+
- At least one of: Claude Code, Codex, or altimate-code installed and with session history
|
|
51
|
+
|
|
52
|
+
## Install
|
|
53
|
+
|
|
54
|
+
### Using `uv` (recommended)
|
|
55
|
+
```bash
|
|
56
|
+
uv tool install context-forge-cli
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Using `pipx`
|
|
60
|
+
```bash
|
|
61
|
+
pipx install context-forge-cli
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### From source (development)
|
|
65
|
+
```bash
|
|
66
|
+
git clone https://github.com/emmver/contextforge.git
|
|
67
|
+
cd contextforge
|
|
68
|
+
uv sync
|
|
69
|
+
uv run cf --help
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Verify installation
|
|
73
|
+
```bash
|
|
74
|
+
cf --help # Should show the CLI with all commands
|
|
75
|
+
cf config # Show or edit configuration
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Quick Start
|
|
79
|
+
|
|
80
|
+
### 1. Scan for sessions
|
|
81
|
+
```bash
|
|
82
|
+
cf scan # discover and index sessions from all installed tools
|
|
83
|
+
```
|
|
84
|
+
This reads tool-native storage and builds a local SQLite index at `~/.contextforge/contextforge.db`.
|
|
85
|
+
First run typically takes a few seconds depending on session count.
|
|
86
|
+
|
|
87
|
+
### 2. List and explore sessions
|
|
88
|
+
```bash
|
|
89
|
+
cf ls # list all recent sessions (with summaries if available)
|
|
90
|
+
cf ls --format json # machine-readable output
|
|
91
|
+
cf show <id> # show full detail + summary for a specific session
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 3. Generate summaries (optional)
|
|
95
|
+
```bash
|
|
96
|
+
cf summarize --all # generate summaries for all unsummarized sessions
|
|
97
|
+
cf summarize <id> # refresh summary for a single session
|
|
98
|
+
cf summarize --all --force # regenerate all summaries (e.g., after config change)
|
|
99
|
+
```
|
|
100
|
+
Summaries require an Anthropic API key (see [Configuration](#configuration) below).
|
|
101
|
+
|
|
102
|
+
### 4. Launch the dashboard
|
|
103
|
+
```bash
|
|
104
|
+
cf dashboard # interactive TUI with live session browser
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### 5. Transfer context to a new session
|
|
108
|
+
```bash
|
|
109
|
+
# Preview the context bundle
|
|
110
|
+
cf compact <session-id>
|
|
111
|
+
|
|
112
|
+
# Inject context into a new Claude Code session
|
|
113
|
+
cf transfer <session-id> --to claude_code --execute
|
|
114
|
+
|
|
115
|
+
# Inject into Codex with richer context
|
|
116
|
+
cf transfer <session-id> --to codex --strategy key_messages --execute
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Context Transfer
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# Preview: compact a session into a ContextBundle and display it
|
|
123
|
+
cf compact <session-id>
|
|
124
|
+
|
|
125
|
+
# Save a bundle to the DB for later reuse
|
|
126
|
+
cf compact <session-id> --save
|
|
127
|
+
|
|
128
|
+
# Preview: show the exact command that would inject context into a new Codex session
|
|
129
|
+
cf transfer <session-id> --to codex
|
|
130
|
+
|
|
131
|
+
# Execute: launch a new Codex session with context injected
|
|
132
|
+
cf transfer <session-id> --to codex --execute
|
|
133
|
+
|
|
134
|
+
# Multi-session bundle → altimate-code, richer key_messages strategy
|
|
135
|
+
cf transfer <id1> <id2> --to altimate-code --strategy key_messages --execute
|
|
136
|
+
|
|
137
|
+
# Resume an existing session with injected context
|
|
138
|
+
cf transfer <id> --to claude_code --session <existing-session-id> --execute
|
|
139
|
+
|
|
140
|
+
# Machine-readable output
|
|
141
|
+
cf transfer <id> --to codex --format json
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Injection methods
|
|
145
|
+
|
|
146
|
+
| Method | When used | How |
|
|
147
|
+
|---|---|---|
|
|
148
|
+
| `system_prompt` | New session, small context (≤4k tokens) | Passed via `--system-prompt` flag |
|
|
149
|
+
| `resume` | Continuing an existing session | `--resume` / `resume` / `run -s` |
|
|
150
|
+
| `fork` | Branch from existing session | `fork` / `--fork` |
|
|
151
|
+
| `file` | Any context >4k tokens | Writes `CONTEXT.md` to target dir; system prompt references it |
|
|
152
|
+
|
|
153
|
+
The method is chosen automatically based on token count and whether a target session is specified. Override with `--method`.
|
|
154
|
+
|
|
155
|
+
## Compaction Strategies
|
|
156
|
+
|
|
157
|
+
| Strategy | Tokens | Best for |
|
|
158
|
+
|---|---|---|
|
|
159
|
+
| `summary_only` | ~100–300 per session | Default; maximum token efficiency |
|
|
160
|
+
| `key_messages` | 1k–8k | Richer context; scores messages by importance |
|
|
161
|
+
| `full_recent` | Up to budget | Same-tool transfers; preserves recent conversation |
|
|
162
|
+
|
|
163
|
+
## Supported Tools
|
|
164
|
+
|
|
165
|
+
| Tool | Discovery | Inject method |
|
|
166
|
+
|---|---|---|
|
|
167
|
+
| Claude Code (CLI) | `~/.claude/projects/` JSONL | `--system-prompt` / `--resume` |
|
|
168
|
+
| Claude Desktop | `~/Library/Application Support/Claude/local-agent-mode-sessions/` | `--system-prompt` |
|
|
169
|
+
| Codex | `~/.codex/state_5.sqlite` | `resume` / `fork` |
|
|
170
|
+
| altimate-code | `~/.local/share/altimate-code/opencode.db` | `run -s` / `import` |
|
|
171
|
+
|
|
172
|
+
## Session Summaries
|
|
173
|
+
|
|
174
|
+
ContextForge generates plain-English summaries of what each session accomplished.
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
cf summarize <id> # generate or refresh summary for one session
|
|
178
|
+
cf summarize --all # bulk-generate summaries for all sessions
|
|
179
|
+
cf summarize --all --force # regenerate even existing ones
|
|
180
|
+
|
|
181
|
+
# Scan + summarize in one step
|
|
182
|
+
cf scan --summarize
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**How summaries work:**
|
|
186
|
+
1. **Codex** — reuses pre-computed `stage1_outputs.rollout_summary` when available (zero LLM cost)
|
|
187
|
+
2. **All tools** — calls the Claude API (Haiku model) to produce a 3–5 sentence summary
|
|
188
|
+
3. **No API key** — falls back to showing the first user message as a preview
|
|
189
|
+
|
|
190
|
+
Summaries are cached in the local SQLite index and shown in `cf ls` and `cf show`.
|
|
191
|
+
|
|
192
|
+
## Configuration
|
|
193
|
+
|
|
194
|
+
Config file: `~/.contextforge/config.toml` (created on first run)
|
|
195
|
+
|
|
196
|
+
### Manage config from CLI
|
|
197
|
+
```bash
|
|
198
|
+
cf config show # display current config
|
|
199
|
+
cf config set llm.api_key sk-ant-...
|
|
200
|
+
cf config set compactor.default_strategy key_messages
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Full reference
|
|
204
|
+
```toml
|
|
205
|
+
[llm]
|
|
206
|
+
api_key = "sk-ant-..." # optional; enables LLM summarization
|
|
207
|
+
model = "claude-haiku-4-5-20251001" # or any Claude model
|
|
208
|
+
|
|
209
|
+
[compactor]
|
|
210
|
+
default_strategy = "summary_only" # summary_only | key_messages | full_recent
|
|
211
|
+
default_token_budget = 4096 # max tokens per compacted session
|
|
212
|
+
|
|
213
|
+
[scanner]
|
|
214
|
+
max_sessions_per_tool = 200 # limit sessions indexed per tool
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### Notes on configuration
|
|
218
|
+
|
|
219
|
+
- **Without API key**: Summaries fall back to showing the first user message (no LLM cost)
|
|
220
|
+
- **With API key**: Summaries use Claude Haiku via the Anthropic API (~0.30¢ per summary)
|
|
221
|
+
- **Token budget**: Controls how aggressively context is compacted; higher = richer context
|
|
222
|
+
- **Strategies**: See [Compaction Strategies](#compaction-strategies) for details on each
|
|
223
|
+
|
|
224
|
+
## Storage
|
|
225
|
+
|
|
226
|
+
ContextForge stores its index at `~/.contextforge/contextforge.db` (SQLite).
|
|
227
|
+
It **never modifies** tool-native storage. All source files are read-only.
|
|
228
|
+
|
|
229
|
+
## Agent / Machine Usage
|
|
230
|
+
|
|
231
|
+
All structured commands support `--format json`:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
cf ls --format json
|
|
235
|
+
cf show <id> --format json
|
|
236
|
+
cf compact <id> --format json
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
See [AGENTS.md](AGENTS.md) for contribution guidelines and [PLAN.md](PLAN.md) for development status.
|
|
240
|
+
|
|
241
|
+
## TUI Dashboard
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
cf dashboard
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
A full-screen Textual dashboard with live session browsing, filtering, and analytics.
|
|
248
|
+
|
|
249
|
+
```
|
|
250
|
+
┌ Sessions ────────────────┬ Detail ─────────────────────────┐
|
|
251
|
+
│ 🔵 CC utastar 1.2M │ utastar_thesis │
|
|
252
|
+
│ 🟢 Codex dataset 45k │ │
|
|
253
|
+
│ 🟣 Alt BigQuery 12k │ Tool Claude Code │
|
|
254
|
+
│ 🔵 CC jira-mcp 890k │ CWD ~/Github/utastar_... │
|
|
255
|
+
│ ... │ Tokens 1.2M │
|
|
256
|
+
│ │ Created 2026-03-10 09:14 UTC │
|
|
257
|
+
│ │ Updated 2026-04-03 22:41 UTC │
|
|
258
|
+
│ │ │
|
|
259
|
+
│ │ ── Summary ── │
|
|
260
|
+
│ │ │
|
|
261
|
+
│ │ Worked on UTASTAR ensemble │
|
|
262
|
+
│ │ pruning framework... │
|
|
263
|
+
└──────────────────────────┴─────────────────────────────────┘
|
|
264
|
+
Sessions — CC:12 │ Codex:4 │ Alt:3 │ Total:19 │ 129M tok 14:32:01
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Key bindings
|
|
268
|
+
|
|
269
|
+
| Key | Action |
|
|
270
|
+
|---|---|
|
|
271
|
+
| `a` | Analytics dashboard (tool charts, activity sparkline, top projects) |
|
|
272
|
+
| `x` | Per-turn token breakdown for selected session |
|
|
273
|
+
| `/` | Toggle live filter bar (text search + tool buttons) |
|
|
274
|
+
| `r` | Rescan all tools |
|
|
275
|
+
| `s` | Summarize selected session |
|
|
276
|
+
| `t` | Open transfer modal (choose tool + strategy) |
|
|
277
|
+
| `c` | Compact selected session and preview bundle |
|
|
278
|
+
| `q` | Quit |
|
|
279
|
+
| `↑↓` | Navigate sessions |
|
|
280
|
+
|
|
281
|
+
### Analytics modal (`a`)
|
|
282
|
+
|
|
283
|
+
Shows aggregate stats with configurable time windows:
|
|
284
|
+
|
|
285
|
+
- **W** = last 7 days, **M** = 30 days, **H** = 6 months, **Y** = 1 year
|
|
286
|
+
- Sessions and token usage per tool (unicode bar charts)
|
|
287
|
+
- Activity sparkline over time
|
|
288
|
+
- Top 5 projects by session count
|
|
289
|
+
|
|
290
|
+
### Live filter (`/`)
|
|
291
|
+
|
|
292
|
+
Press `/` to open the filter bar above the session list:
|
|
293
|
+
- Type to filter by title or project path (instant, no DB re-query)
|
|
294
|
+
- Click **All / CC / Codex / Alt** to filter by tool
|
|
295
|
+
- Combine text + tool filters; match count shown in the status bar
|
|
296
|
+
- Press `ESC` to clear and close
|
|
297
|
+
|
|
298
|
+
### Transfer modal (`t`)
|
|
299
|
+
|
|
300
|
+
Press `t` on any session to open the transfer panel. Choose:
|
|
301
|
+
- **Target tool** — Claude Code, Codex, or altimate-code
|
|
302
|
+
- **Strategy** — `summary_only`, `key_messages`, or `full_recent`
|
|
303
|
+
- **Preview** — shows the exact shell command (no side effects)
|
|
304
|
+
- **Execute** — builds the bundle and launches the target tool
|
|
305
|
+
|
|
306
|
+
## Troubleshooting
|
|
307
|
+
|
|
308
|
+
### `command not found: cf`
|
|
309
|
+
- **Cause**: Tool not in PATH after installation
|
|
310
|
+
- **Fix**: Restart your shell, or reinstall: `uv tool install contextforge --force`
|
|
311
|
+
|
|
312
|
+
### `RuntimeError: no sessions found` or empty `cf ls`
|
|
313
|
+
- **Cause**: No sessions discovered from installed tools
|
|
314
|
+
- **Fix**: Run `cf scan` first; check that you have Claude Code/Codex/altimate-code with session history
|
|
315
|
+
|
|
316
|
+
### `ANTHROPIC_API_KEY not set` warning
|
|
317
|
+
- **Cause**: No API key configured for summaries
|
|
318
|
+
- **Fix**: Set it via `cf config set llm.api_key sk-ant-...` or set `ANTHROPIC_API_KEY` env var
|
|
319
|
+
- **Note**: Summaries are optional; you can still use ContextForge without API keys
|
|
320
|
+
|
|
321
|
+
### Session not appearing after tool update
|
|
322
|
+
- **Cause**: Tool storage location changed or was not yet indexed
|
|
323
|
+
- **Fix**: Run `cf scan` again to reindex all tools
|
|
324
|
+
|
|
325
|
+
### `cf dashboard` crashes or displays incorrectly
|
|
326
|
+
- **Cause**: Terminal size too small or unsupported terminal type
|
|
327
|
+
- **Fix**: Resize terminal to at least 80x24; try a different terminal emulator
|
|
328
|
+
|
|
329
|
+
### Database locked / concurrent access error
|
|
330
|
+
- **Cause**: Two `cf` commands running at once
|
|
331
|
+
- **Fix**: Wait for the first command to finish, or delete `~/.contextforge/contextforge.db` and run `cf scan` again
|
|
332
|
+
|
|
333
|
+
## Development
|
|
334
|
+
|
|
335
|
+
```bash
|
|
336
|
+
uv sync # install all dependencies including dev
|
|
337
|
+
uv run pytest # run tests
|
|
338
|
+
uv run cf --help # run CLI locally
|
|
339
|
+
uv tool install . --force # test local installation
|
|
340
|
+
```
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# ContextForge — Development Plan
|
|
2
|
+
|
|
3
|
+
Last updated: 2026-04-04
|
|
4
|
+
Status: Phase 4 Complete / Phase 5 Ready
|
|
5
|
+
|
|
6
|
+
## How to use this file
|
|
7
|
+
|
|
8
|
+
Agents and contributors: update this file as you work.
|
|
9
|
+
- Mark completed items `[x]`
|
|
10
|
+
- Update `Status:` at the top when starting/completing a phase
|
|
11
|
+
- Update `Last updated:` to today's date when you make changes
|
|
12
|
+
- When completing a phase, also update `README.md` to reflect new capabilities
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Phase 1: Foundation [COMPLETE]
|
|
17
|
+
|
|
18
|
+
- [x] Project scaffold (`uv init`, deps, `pyproject.toml` entry point `cf`)
|
|
19
|
+
- [x] Data models (`models/session.py` — Session, Message, ContextBundle)
|
|
20
|
+
- [x] Config models (`models/config.py` — ForgeConfig)
|
|
21
|
+
- [x] SQLite schema + CRUD (`core/db.py`)
|
|
22
|
+
- [x] Abstract adapter base (`adapters/base.py`)
|
|
23
|
+
- [x] Claude Code adapter (`adapters/claude_code.py`)
|
|
24
|
+
- [x] Codex adapter (`adapters/codex.py`)
|
|
25
|
+
- [x] altimate-code adapter (`adapters/altimate_code.py`)
|
|
26
|
+
- [x] Adapter registry (`adapters/registry.py`)
|
|
27
|
+
- [x] Scanner (`core/scanner.py`)
|
|
28
|
+
- [x] Token utilities (`utils/tokens.py`)
|
|
29
|
+
- [x] Display helpers (`utils/display.py`)
|
|
30
|
+
- [x] CLI: `cf scan`, `cf ls`, `cf show`, `cf tag`, `cf config` (`cli.py`)
|
|
31
|
+
- [x] Tests: Claude Code adapter, db, compactor (13 passing → 22 with Phase 2)
|
|
32
|
+
- [x] README.md, AGENTS.md, PLAN.md
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Phase 2: Summarizer [COMPLETE]
|
|
37
|
+
|
|
38
|
+
- [x] Wire summarizer into `cf scan` via `--summarize` flag (auto-summarizes new sessions)
|
|
39
|
+
- [x] `cf summarize <id>` and `cf summarize --all` commands with rich progress bar
|
|
40
|
+
- [x] Summarizer tests with mocked Anthropic client (`tests/core/test_summarizer.py` — 9 tests)
|
|
41
|
+
- [x] Codex pre-existing `stage1_outputs.rollout_summary` shortcut (zero LLM cost)
|
|
42
|
+
- [x] `batch_summarize()` helper with `on_progress` callback
|
|
43
|
+
- [x] Update README.md with summarizer section
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Phase 3: Compaction + Transfer [COMPLETE]
|
|
48
|
+
|
|
49
|
+
- [x] `cf compact` with `--save` (persists bundle to DB) and `--format json`
|
|
50
|
+
- [x] `cf transfer` cross-tool: Claude Code → Codex, Codex → altimate-code, altimate → Claude Code
|
|
51
|
+
- [x] Multi-session cross-tool bundle transfer tested
|
|
52
|
+
- [x] Large-context file injection (`CONTEXT.md` strategy auto-selected when >4k tokens)
|
|
53
|
+
- [x] `--format json` on both `cf compact` and `cf transfer`
|
|
54
|
+
- [x] 23 injector tests — per-tool commands, file injection, DB recording, cross-tool scenarios (45 total passing)
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Phase 4: TUI Dashboard [COMPLETE]
|
|
59
|
+
|
|
60
|
+
- [x] `textual` moved to runtime deps (removed from dev group)
|
|
61
|
+
- [x] `SessionTable` widget — DataTable with tool emoji, title, updated, tokens, ID
|
|
62
|
+
- [x] `SessionDetail` widget — reactive right panel; title, metadata block, summary text
|
|
63
|
+
- [x] `TransferPanel` widget — `ModalScreen` with RadioSet for tool + strategy, Preview/Execute buttons
|
|
64
|
+
- [x] `StatusBar` widget — per-tool session counts + last refresh time (docked bottom)
|
|
65
|
+
- [x] `tui/styles.tcss` — full layout CSS, panel borders, modal styling
|
|
66
|
+
- [x] `cf dashboard` command fully wired; passes DB path from config; keybindings in docstring
|
|
67
|
+
- [x] App actions: r=rescan, s=summarize, t=transfer modal, c=compact, q=quit
|
|
68
|
+
- [x] Update README.md with dashboard section
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Ad-hoc: Token Analysis [COMPLETE]
|
|
73
|
+
|
|
74
|
+
- [x] `cf tokens <id>` — per-turn breakdown with bar chart, role totals, averages, heaviest turn
|
|
75
|
+
- [x] `cf tokens <id> --top N` — show only the N heaviest turns
|
|
76
|
+
- [x] `cf tokens <id> --format json` — machine-readable output
|
|
77
|
+
- [x] `core/token_analyzer.py` — `SessionTokenReport` dataclass + `analyze_tokens()`
|
|
78
|
+
- [x] 7 tests in `tests/core/test_token_analyzer.py`
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Phase 5: Polish [ ]
|
|
83
|
+
|
|
84
|
+
- [ ] `cf config set` persists to `~/.contextforge/config.toml`
|
|
85
|
+
- [ ] Graceful degradation: missing tools silently skipped with `--verbose` warning
|
|
86
|
+
- [ ] `--format json` on all remaining commands
|
|
87
|
+
- [ ] Install docs: `uv tool install contextforge`
|
|
88
|
+
- [ ] GitHub Actions CI: `uv run pytest --cov=contextforge`
|
|
89
|
+
- [ ] `open-claw` adapter (if/when CLI interface is documented)
|
|
90
|
+
- [ ] Session search: `cf ls --search <query>`
|
|
91
|
+
- [ ] Session archiving: `cf archive <id>`
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Architecture Reference
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
contextforge/
|
|
99
|
+
├── cli.py ← Typer root; all commands
|
|
100
|
+
├── tui/
|
|
101
|
+
│ ├── app.py ← Textual Application
|
|
102
|
+
│ └── widgets/
|
|
103
|
+
├── adapters/
|
|
104
|
+
│ ├── base.py ← Abstract ToolAdapter
|
|
105
|
+
│ ├── claude_code.py ← Claude Code (JSONL)
|
|
106
|
+
│ ├── codex.py ← Codex (SQLite + JSONL)
|
|
107
|
+
│ ├── altimate_code.py ← altimate-code (SQLite)
|
|
108
|
+
│ └── registry.py ← ADAPTERS dict + helpers
|
|
109
|
+
├── core/
|
|
110
|
+
│ ├── db.py ← SQLite schema + CRUD
|
|
111
|
+
│ ├── scanner.py ← multi-adapter discovery
|
|
112
|
+
│ ├── summarizer.py ← LLM summarization + caching
|
|
113
|
+
│ ├── compactor.py ← 3-strategy context compaction
|
|
114
|
+
│ └── injector.py ← shell command builder + executor
|
|
115
|
+
├── models/
|
|
116
|
+
│ ├── session.py ← Session, Message, ContextBundle
|
|
117
|
+
│ └── config.py ← ForgeConfig
|
|
118
|
+
└── utils/
|
|
119
|
+
├── tokens.py ← tiktoken helpers
|
|
120
|
+
└── display.py ← rich helpers
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Key Design Decisions
|
|
124
|
+
|
|
125
|
+
- **Adapters are always read-only** — ContextForge never writes to tool-native storage
|
|
126
|
+
- **`build_inject_command()` returns a string, never executes** — execution only in `injector.py` with `--execute`
|
|
127
|
+
- **Token budget is a hard cap** — `compactor.py` always truncates to stay within budget
|
|
128
|
+
- **SQLite for index only** — messages re-read from source on demand (no duplication)
|
|
129
|
+
- **LLM API key is optional** — graceful degradation to first-message preview
|