ferry-tui 0.1.1__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.
- ferry_tui-0.1.1/.gitignore +8 -0
- ferry_tui-0.1.1/CHANGELOG.md +12 -0
- ferry_tui-0.1.1/LICENSE +21 -0
- ferry_tui-0.1.1/PKG-INFO +104 -0
- ferry_tui-0.1.1/README.md +79 -0
- ferry_tui-0.1.1/pyproject.toml +49 -0
- ferry_tui-0.1.1/src/ferry/__init__.py +3 -0
- ferry_tui-0.1.1/src/ferry/adapters.py +666 -0
- ferry_tui-0.1.1/src/ferry/cleaning.py +154 -0
- ferry_tui-0.1.1/src/ferry/cli.py +446 -0
- ferry_tui-0.1.1/src/ferry/index.py +700 -0
- ferry_tui-0.1.1/src/ferry/launch.py +90 -0
- ferry_tui-0.1.1/src/ferry/mcp_server.py +264 -0
- ferry_tui-0.1.1/src/ferry/paths.py +85 -0
- ferry_tui-0.1.1/src/ferry/plugins/__init__.py +1 -0
- ferry_tui-0.1.1/src/ferry/plugins/claude_cowork.py +192 -0
- ferry_tui-0.1.1/src/ferry/tags.py +145 -0
- ferry_tui-0.1.1/src/ferry/titles.py +159 -0
- ferry_tui-0.1.1/src/ferry/transfer.py +420 -0
- ferry_tui-0.1.1/src/ferry/tui.py +925 -0
- ferry_tui-0.1.1/tests/conftest.py +89 -0
- ferry_tui-0.1.1/tests/test_launch.py +45 -0
- ferry_tui-0.1.1/tests/test_release.py +242 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.1
|
|
4
|
+
|
|
5
|
+
- First public release from a fresh repository history.
|
|
6
|
+
- Entirely synthetic demo and test conversations.
|
|
7
|
+
- Cropped demo, readable Markdown previews, and narrow-terminal layout.
|
|
8
|
+
- Generated Codex transfers require CLI resume to avoid an empty desktop chat.
|
|
9
|
+
- Local search, linked conversation history, transfer modes, archive/undo, and read-only MCP.
|
|
10
|
+
- Offline switch disables model-assisted titles, tags, and summaries.
|
|
11
|
+
|
|
12
|
+
Known limits: Cowork is read-only; there is no GUI/CLI toggle; adapter checks do not establish compatibility with every vendor release. OpenCode is supported through handoff but has not been exercised against a live OpenCode installation in this release.
|
ferry_tui-0.1.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Abdou Ghanim
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
ferry_tui-0.1.1/PKG-INFO
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: ferry-tui
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: One window for every AI coding conversation on this machine. List, search, preview, open, and carry a thread across to the other agent.
|
|
5
|
+
Project-URL: Homepage, https://github.com/a-ghanim/ferry-tui
|
|
6
|
+
Project-URL: Issues, https://github.com/a-ghanim/ferry-tui/issues
|
|
7
|
+
Author: Abdou Ghanim
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: claude,codex,handoff,mcp,opencode,sessions,tui
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Topic :: Software Development
|
|
16
|
+
Requires-Python: >=3.10
|
|
17
|
+
Requires-Dist: click<9,>=8.1
|
|
18
|
+
Requires-Dist: handoff-agent==0.1.3
|
|
19
|
+
Requires-Dist: mcp<3,>=2.2
|
|
20
|
+
Requires-Dist: textual<9,>=8.2.8
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# ferry
|
|
27
|
+
|
|
28
|
+
A little boat for your AI coding conversations. Search your local history, pick up where you left off, or carry a conversation from one agent to another.
|
|
29
|
+
|
|
30
|
+

|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
uv tool install git+https://github.com/a-ghanim/ferry-tui@v0.1.1
|
|
36
|
+
ferry
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Requires Python 3.10 or newer and an existing supported agent store. Ferry is an early release, tested on macOS. The receiving agent's CLI must be installed and authenticated to continue a transferred conversation.
|
|
40
|
+
|
|
41
|
+
## Use
|
|
42
|
+
|
|
43
|
+
| Key | Action |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| Enter | Open the selected conversation in its agent |
|
|
46
|
+
| Tab | Transfer context to another agent, then open it |
|
|
47
|
+
| / | Search titles and message text |
|
|
48
|
+
| p | Focus the transcript; switch panes in a narrow terminal |
|
|
49
|
+
| e | Expand linked sessions in a conversation |
|
|
50
|
+
| Space | Select multiple conversations |
|
|
51
|
+
| r / t | Rename / edit tags |
|
|
52
|
+
| d / u | Archive / undo the last Ferry write |
|
|
53
|
+
| 2 | Create a second opinion in the other available agents |
|
|
54
|
+
| q | Quit |
|
|
55
|
+
|
|
56
|
+
The transfer dialog shows the source, message and token estimates, target agent, and working folders. Choose raw context, compact context without tool calls/results/reasoning, or a brief summary. Ferry groups the resulting sessions together and marks where the context came from. A transfer carries recorded conversation text and available artifacts; it does not preserve a model's hidden state, running tools, permissions, or unsaved files.
|
|
57
|
+
|
|
58
|
+
## CLI and desktop behavior
|
|
59
|
+
|
|
60
|
+
Existing native Codex threads open in the desktop app on macOS, with CLI fallback where no desktop opener is available. Ferry-generated Codex sessions use `codex resume`: the synthetic history used by this adapter is not reliably displayed as prior chat bubbles in the desktop app. Ferry refuses to open these through the app when the CLI is missing. There is currently no UI/CLI preference toggle.
|
|
61
|
+
|
|
62
|
+
Claude Code opens with `claude --remote-control --resume`. Remote Control availability depends on Claude Code and your account. Cowork sessions are read-only; transfer their context to a writable agent to continue.
|
|
63
|
+
|
|
64
|
+
## Local storage and privacy
|
|
65
|
+
|
|
66
|
+
Ferry imports [Jackson Clark's handoff](https://github.com/HacksonClark/handoff) as a Python library. Its extractors and injectors convert agent records through a canonical transcript. Ferry adds search, titles, linked session history, transfer checks, and the interface.
|
|
67
|
+
|
|
68
|
+
| Store | Read from | Transfer writes |
|
|
69
|
+
| --- | --- | --- |
|
|
70
|
+
| Codex | `~/.codex/sessions/` and `session_index.jsonl` | New rollout; SQLite registration when the agent database exists |
|
|
71
|
+
| Claude Code, including desktop Code sessions in this store | `~/.claude/projects/` | New session under the selected folder |
|
|
72
|
+
| Claude Cowork | macOS Claude local-agent-mode-sessions store | Read-only |
|
|
73
|
+
| OpenCode | handoff's configured OpenCode store | Through handoff's adapter |
|
|
74
|
+
|
|
75
|
+
The searchable user/assistant text stays in `~/.cache/ferry/index.db`. There is no hosted Ferry backend. The cache is sensitive even after automatic secret redaction; redaction is best-effort and does not anonymize conversations. `ferry exclude <handle>` removes a conversation from searchable text. Archive and undo files also live in this directory, so do not delete the cache if you need those files back.
|
|
76
|
+
|
|
77
|
+
Ferry preserves transfer sources, refuses recently modified sessions, redacts known secret patterns, checks that the target adapter can read the new session, and logs writes for `ferry undo`. A successful adapter check is not a guarantee of compatibility with every future agent version.
|
|
78
|
+
|
|
79
|
+
Missing titles can be generated through your authenticated `claude -p`, which sends excerpts to Claude. Brief summaries and requested tag suggestions also use Claude. Normal indexing/search does not need a model. Use `FERRY_OFFLINE=1 ferry` to disable these model-assisted features and use local fallback labels/summaries.
|
|
80
|
+
|
|
81
|
+
## MCP
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
ferry mcp # local stdio transport
|
|
85
|
+
ferry mcp-config # client configuration examples
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The read-only tools are `search_conversations` and `get_conversation`. Results label retrieved transcripts as data, not instructions. Configure this server only in clients you intend to give archive access. Optional `ferry mcp --http 8765` binds to localhost; do not expose it publicly without a separate authenticated access layer.
|
|
89
|
+
|
|
90
|
+
## Development
|
|
91
|
+
|
|
92
|
+
```sh
|
|
93
|
+
uv sync --extra dev
|
|
94
|
+
uv run pytest -q
|
|
95
|
+
uv build
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Public tests construct fictional transcripts in temporary stores. No personal conversation fixtures or previous private Git history are included. `demo/make_gif.py` records the real UI and a verified transfer using fictional data; agent launch is disabled, and the transfer is undone. It needs macOS Quick Look and ffmpeg.
|
|
99
|
+
|
|
100
|
+
## Credits
|
|
101
|
+
|
|
102
|
+
handoff supplies extraction, injection, redaction, and its plugin registry. Ferry's Cowork reader registers through that plugin API. Design influences include claude-codex-bridge (lineage), session-porter (transfer modes), showagent (transfer previews), CASR (read-back checks), cct (folder remapping), Waybill, and syne. Ferry is independently maintained and is not an official OpenAI or Anthropic product.
|
|
103
|
+
|
|
104
|
+
MIT.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# ferry
|
|
2
|
+
|
|
3
|
+
A little boat for your AI coding conversations. Search your local history, pick up where you left off, or carry a conversation from one agent to another.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
uv tool install git+https://github.com/a-ghanim/ferry-tui@v0.1.1
|
|
11
|
+
ferry
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Requires Python 3.10 or newer and an existing supported agent store. Ferry is an early release, tested on macOS. The receiving agent's CLI must be installed and authenticated to continue a transferred conversation.
|
|
15
|
+
|
|
16
|
+
## Use
|
|
17
|
+
|
|
18
|
+
| Key | Action |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| Enter | Open the selected conversation in its agent |
|
|
21
|
+
| Tab | Transfer context to another agent, then open it |
|
|
22
|
+
| / | Search titles and message text |
|
|
23
|
+
| p | Focus the transcript; switch panes in a narrow terminal |
|
|
24
|
+
| e | Expand linked sessions in a conversation |
|
|
25
|
+
| Space | Select multiple conversations |
|
|
26
|
+
| r / t | Rename / edit tags |
|
|
27
|
+
| d / u | Archive / undo the last Ferry write |
|
|
28
|
+
| 2 | Create a second opinion in the other available agents |
|
|
29
|
+
| q | Quit |
|
|
30
|
+
|
|
31
|
+
The transfer dialog shows the source, message and token estimates, target agent, and working folders. Choose raw context, compact context without tool calls/results/reasoning, or a brief summary. Ferry groups the resulting sessions together and marks where the context came from. A transfer carries recorded conversation text and available artifacts; it does not preserve a model's hidden state, running tools, permissions, or unsaved files.
|
|
32
|
+
|
|
33
|
+
## CLI and desktop behavior
|
|
34
|
+
|
|
35
|
+
Existing native Codex threads open in the desktop app on macOS, with CLI fallback where no desktop opener is available. Ferry-generated Codex sessions use `codex resume`: the synthetic history used by this adapter is not reliably displayed as prior chat bubbles in the desktop app. Ferry refuses to open these through the app when the CLI is missing. There is currently no UI/CLI preference toggle.
|
|
36
|
+
|
|
37
|
+
Claude Code opens with `claude --remote-control --resume`. Remote Control availability depends on Claude Code and your account. Cowork sessions are read-only; transfer their context to a writable agent to continue.
|
|
38
|
+
|
|
39
|
+
## Local storage and privacy
|
|
40
|
+
|
|
41
|
+
Ferry imports [Jackson Clark's handoff](https://github.com/HacksonClark/handoff) as a Python library. Its extractors and injectors convert agent records through a canonical transcript. Ferry adds search, titles, linked session history, transfer checks, and the interface.
|
|
42
|
+
|
|
43
|
+
| Store | Read from | Transfer writes |
|
|
44
|
+
| --- | --- | --- |
|
|
45
|
+
| Codex | `~/.codex/sessions/` and `session_index.jsonl` | New rollout; SQLite registration when the agent database exists |
|
|
46
|
+
| Claude Code, including desktop Code sessions in this store | `~/.claude/projects/` | New session under the selected folder |
|
|
47
|
+
| Claude Cowork | macOS Claude local-agent-mode-sessions store | Read-only |
|
|
48
|
+
| OpenCode | handoff's configured OpenCode store | Through handoff's adapter |
|
|
49
|
+
|
|
50
|
+
The searchable user/assistant text stays in `~/.cache/ferry/index.db`. There is no hosted Ferry backend. The cache is sensitive even after automatic secret redaction; redaction is best-effort and does not anonymize conversations. `ferry exclude <handle>` removes a conversation from searchable text. Archive and undo files also live in this directory, so do not delete the cache if you need those files back.
|
|
51
|
+
|
|
52
|
+
Ferry preserves transfer sources, refuses recently modified sessions, redacts known secret patterns, checks that the target adapter can read the new session, and logs writes for `ferry undo`. A successful adapter check is not a guarantee of compatibility with every future agent version.
|
|
53
|
+
|
|
54
|
+
Missing titles can be generated through your authenticated `claude -p`, which sends excerpts to Claude. Brief summaries and requested tag suggestions also use Claude. Normal indexing/search does not need a model. Use `FERRY_OFFLINE=1 ferry` to disable these model-assisted features and use local fallback labels/summaries.
|
|
55
|
+
|
|
56
|
+
## MCP
|
|
57
|
+
|
|
58
|
+
```sh
|
|
59
|
+
ferry mcp # local stdio transport
|
|
60
|
+
ferry mcp-config # client configuration examples
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The read-only tools are `search_conversations` and `get_conversation`. Results label retrieved transcripts as data, not instructions. Configure this server only in clients you intend to give archive access. Optional `ferry mcp --http 8765` binds to localhost; do not expose it publicly without a separate authenticated access layer.
|
|
64
|
+
|
|
65
|
+
## Development
|
|
66
|
+
|
|
67
|
+
```sh
|
|
68
|
+
uv sync --extra dev
|
|
69
|
+
uv run pytest -q
|
|
70
|
+
uv build
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Public tests construct fictional transcripts in temporary stores. No personal conversation fixtures or previous private Git history are included. `demo/make_gif.py` records the real UI and a verified transfer using fictional data; agent launch is disabled, and the transfer is undone. It needs macOS Quick Look and ffmpeg.
|
|
74
|
+
|
|
75
|
+
## Credits
|
|
76
|
+
|
|
77
|
+
handoff supplies extraction, injection, redaction, and its plugin registry. Ferry's Cowork reader registers through that plugin API. Design influences include claude-codex-bridge (lineage), session-porter (transfer modes), showagent (transfer previews), CASR (read-back checks), cct (folder remapping), Waybill, and syne. Ferry is independently maintained and is not an official OpenAI or Anthropic product.
|
|
78
|
+
|
|
79
|
+
MIT.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "ferry-tui"
|
|
7
|
+
version = "0.1.1"
|
|
8
|
+
description = "One window for every AI coding conversation on this machine. List, search, preview, open, and carry a thread across to the other agent."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { text = "MIT" }
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [{ name = "Abdou Ghanim" }]
|
|
13
|
+
keywords = ["claude", "codex", "opencode", "handoff", "tui", "sessions", "mcp"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 3 - Alpha",
|
|
16
|
+
"Environment :: Console",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Topic :: Software Development",
|
|
20
|
+
]
|
|
21
|
+
dependencies = [
|
|
22
|
+
"handoff-agent==0.1.3",
|
|
23
|
+
"textual>=8.2.8,<9",
|
|
24
|
+
"click>=8.1,<9",
|
|
25
|
+
"mcp>=2.2,<3",
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
[project.optional-dependencies]
|
|
29
|
+
dev = ["pytest>=8", "pytest-asyncio>=0.23"]
|
|
30
|
+
|
|
31
|
+
[project.scripts]
|
|
32
|
+
ferry = "ferry.cli:main"
|
|
33
|
+
|
|
34
|
+
[project.entry-points."handoff.agents"]
|
|
35
|
+
claude-cowork = "ferry.plugins.claude_cowork:register"
|
|
36
|
+
|
|
37
|
+
[project.urls]
|
|
38
|
+
Homepage = "https://github.com/a-ghanim/ferry-tui"
|
|
39
|
+
Issues = "https://github.com/a-ghanim/ferry-tui/issues"
|
|
40
|
+
|
|
41
|
+
[tool.hatch.build.targets.sdist]
|
|
42
|
+
include = ["/src", "/tests", "/README.md", "/LICENSE", "/CHANGELOG.md", "/pyproject.toml"]
|
|
43
|
+
exclude = ["**/__pycache__/**", "**/*.pyc"]
|
|
44
|
+
|
|
45
|
+
[tool.hatch.build.targets.wheel]
|
|
46
|
+
packages = ["src/ferry"]
|
|
47
|
+
|
|
48
|
+
[tool.pytest.ini_options]
|
|
49
|
+
testpaths = ["tests"]
|