tiroir 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.
@@ -0,0 +1,32 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ os: [ubuntu-latest, macos-latest]
17
+ python: ["3.11", "3.13"]
18
+ runs-on: ${{ matrix.os }}
19
+ timeout-minutes: 10
20
+ steps:
21
+ - uses: actions/checkout@v4
22
+ with:
23
+ persist-credentials: false
24
+ - uses: astral-sh/setup-uv@v6
25
+ with:
26
+ python-version: ${{ matrix.python }}
27
+ - name: Lint
28
+ run: uv run --extra dev ruff check . && uv run --extra dev ruff format --check .
29
+ - name: Tests
30
+ run: uv run --extra dev pytest -q
31
+ - name: Build
32
+ run: uv build
@@ -0,0 +1,5 @@
1
+ .venv/
2
+ __pycache__/
3
+ dist/
4
+ *.egg-info/
5
+ dist/
tiroir-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 tiroir
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.
tiroir-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,119 @@
1
+ Metadata-Version: 2.5
2
+ Name: tiroir
3
+ Version: 0.1.0
4
+ Summary: Fork a tiroir hub's agent session to your own machine and carry on in Claude Code.
5
+ Author-email: tiroir <202564+tiroir@users.noreply.github.com>
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Classifier: Environment :: Console
9
+ Classifier: Operating System :: MacOS
10
+ Classifier: Operating System :: POSIX
11
+ Classifier: Programming Language :: Python :: 3
12
+ Requires-Python: >=3.11
13
+ Provides-Extra: dev
14
+ Requires-Dist: pytest>=8.0; extra == 'dev'
15
+ Requires-Dist: ruff>=0.6; extra == 'dev'
16
+ Description-Content-Type: text/markdown
17
+
18
+ # tiroir
19
+
20
+ `tiroir work` takes an agent session that runs on a tiroir hub and gives you your own copy of it
21
+ on your laptop, in Claude Code, with the whole conversation so far. You carry on from where it
22
+ stands, under your own name, with your own tools.
23
+
24
+ It works with a **tiroir hub**: a server that shows shared markdown documents ("sheaves") and
25
+ keeps the transcripts of the agent sessions working on them. Without such a hub this command has
26
+ nothing to do.
27
+
28
+ ## What you need
29
+
30
+ - macOS or Linux (Windows is not supported yet);
31
+ - [uv](https://docs.astral.sh/uv/) (or pipx), to run the command;
32
+ - [Claude Code](https://docs.claude.com/en/docs/claude-code), with the `claude` command on your
33
+ `PATH`;
34
+ - an account on the hub's front, and a sheaf that is open to you.
35
+
36
+ ## Run it
37
+
38
+ Copy the command from the sheaf's page (☰ menu, **Work on this**, **Fork to your machine**), or
39
+ type it with the sheaf's address:
40
+
41
+ ```bash
42
+ uvx tiroir work https://hub.example.com/list/acme/site/plan.md
43
+ uvx tiroir work https://hub.example.com/list/acme/site/plan.md --cwd ~/work/acme-site
44
+ uvx tiroir work https://hub.example.com/list/acme/site/plan.md --dry-run
45
+ ```
46
+
47
+ To keep it installed instead: `uv tool install tiroir`, then `tiroir work <address>`.
48
+
49
+ ## What it does, on your laptop only
50
+
51
+ 1. Downloads the transcript of the sheaf's live session from the hub, as you. Only a sheaf that
52
+ is open to you works.
53
+ 2. Stores it in `~/.claude/projects/<your folder>/<session id>.jsonl`, readable by you alone. It
54
+ replaces an older copy when the new transcript extends it (the session grew since your last
55
+ fork). Claude Code needs exactly one copy of a session, so any other copy of it, in this
56
+ folder or another one (sheaves of one project can share one session), is kept aside once the
57
+ new one is written, as `<session id>.jsonl.kept-<UTC time>` in its own folder, and named in one
58
+ line. No other copy is deleted, and a fork you made earlier keeps working: it holds its own
59
+ copy of the conversation. Claude Code no longer reads a kept file; delete it yourself when you
60
+ no longer want it.
61
+ 3. Writes on the sheaf that you forked it, from which machine, with the new session's id.
62
+ 4. Starts `claude --resume <id> --fork-session --session-id <new id>` in the folder you gave with
63
+ `--cwd` (by default the folder you are in). That is a new session: your messages go to your
64
+ copy, never back to the hub's.
65
+
66
+ What it does not do: it never runs anything on the hub's machine, never changes the session it
67
+ copied, and never sends your messages anywhere but your own Claude Code. `--dry-run` downloads and
68
+ stores the transcript, records nothing on the sheaf, and prints the `claude` command instead of
69
+ starting it.
70
+
71
+ The transcript holds everything the session saw, including tool results: keep it as private as
72
+ the sheaf itself.
73
+
74
+ ## Your sign-in token
75
+
76
+ `tiroir work` signs in to the hub with the session token of your account on the front the hub
77
+ sits behind. It reads it from the file `~/.config/tiroir/front-token`, or from the variable
78
+ `TIROIR_FRONT_TOKEN` when that is set. It sends it only to the sheaf's own host, and never prints
79
+ it.
80
+
81
+ To get it, sign in to the front in your browser, open the developer tools, and copy the value of
82
+ the cookie `token` for the front's address (Chrome: Application > Cookies). Then, on a Mac:
83
+
84
+ ```bash
85
+ mkdir -p ~/.config/tiroir
86
+ pbpaste > ~/.config/tiroir/front-token # with the token on the clipboard
87
+ chmod 600 ~/.config/tiroir/front-token
88
+ ```
89
+
90
+ On Linux, use `xclip -selection clipboard -o` instead of `pbpaste`. The file must be readable by
91
+ you alone (`chmod 600`); `tiroir work` refuses it otherwise. The token expires with your session
92
+ on the front: when `tiroir work` says you are not signed in, copy a fresh one the same way.
93
+
94
+ ## When something is refused
95
+
96
+ `tiroir work` says why in one sentence and exits with code 2. The reasons:
97
+ - you are not signed in;
98
+ - the sheaf is not open to you, or has no session on the hub;
99
+ - the address is not a sheaf's;
100
+ - the token file is readable by others;
101
+ - a link sits under the session's file name.
102
+
103
+ When the hub refuses to record the fork, `tiroir work` gives the hub's reason. The transcript is
104
+ then already on your laptop, and Claude Code is not started: run the same command again once the
105
+ reason is fixed.
106
+
107
+ ## Development
108
+
109
+ ```bash
110
+ uv run --extra dev pytest
111
+ uv run --extra dev ruff check . && uv run --extra dev ruff format --check .
112
+ ```
113
+
114
+ The tests run the command against a fake hub on 127.0.0.1 and never touch your real
115
+ `~/.claude`.
116
+
117
+ ## License
118
+
119
+ MIT, see `LICENSE`.
tiroir-0.1.0/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # tiroir
2
+
3
+ `tiroir work` takes an agent session that runs on a tiroir hub and gives you your own copy of it
4
+ on your laptop, in Claude Code, with the whole conversation so far. You carry on from where it
5
+ stands, under your own name, with your own tools.
6
+
7
+ It works with a **tiroir hub**: a server that shows shared markdown documents ("sheaves") and
8
+ keeps the transcripts of the agent sessions working on them. Without such a hub this command has
9
+ nothing to do.
10
+
11
+ ## What you need
12
+
13
+ - macOS or Linux (Windows is not supported yet);
14
+ - [uv](https://docs.astral.sh/uv/) (or pipx), to run the command;
15
+ - [Claude Code](https://docs.claude.com/en/docs/claude-code), with the `claude` command on your
16
+ `PATH`;
17
+ - an account on the hub's front, and a sheaf that is open to you.
18
+
19
+ ## Run it
20
+
21
+ Copy the command from the sheaf's page (☰ menu, **Work on this**, **Fork to your machine**), or
22
+ type it with the sheaf's address:
23
+
24
+ ```bash
25
+ uvx tiroir work https://hub.example.com/list/acme/site/plan.md
26
+ uvx tiroir work https://hub.example.com/list/acme/site/plan.md --cwd ~/work/acme-site
27
+ uvx tiroir work https://hub.example.com/list/acme/site/plan.md --dry-run
28
+ ```
29
+
30
+ To keep it installed instead: `uv tool install tiroir`, then `tiroir work <address>`.
31
+
32
+ ## What it does, on your laptop only
33
+
34
+ 1. Downloads the transcript of the sheaf's live session from the hub, as you. Only a sheaf that
35
+ is open to you works.
36
+ 2. Stores it in `~/.claude/projects/<your folder>/<session id>.jsonl`, readable by you alone. It
37
+ replaces an older copy when the new transcript extends it (the session grew since your last
38
+ fork). Claude Code needs exactly one copy of a session, so any other copy of it, in this
39
+ folder or another one (sheaves of one project can share one session), is kept aside once the
40
+ new one is written, as `<session id>.jsonl.kept-<UTC time>` in its own folder, and named in one
41
+ line. No other copy is deleted, and a fork you made earlier keeps working: it holds its own
42
+ copy of the conversation. Claude Code no longer reads a kept file; delete it yourself when you
43
+ no longer want it.
44
+ 3. Writes on the sheaf that you forked it, from which machine, with the new session's id.
45
+ 4. Starts `claude --resume <id> --fork-session --session-id <new id>` in the folder you gave with
46
+ `--cwd` (by default the folder you are in). That is a new session: your messages go to your
47
+ copy, never back to the hub's.
48
+
49
+ What it does not do: it never runs anything on the hub's machine, never changes the session it
50
+ copied, and never sends your messages anywhere but your own Claude Code. `--dry-run` downloads and
51
+ stores the transcript, records nothing on the sheaf, and prints the `claude` command instead of
52
+ starting it.
53
+
54
+ The transcript holds everything the session saw, including tool results: keep it as private as
55
+ the sheaf itself.
56
+
57
+ ## Your sign-in token
58
+
59
+ `tiroir work` signs in to the hub with the session token of your account on the front the hub
60
+ sits behind. It reads it from the file `~/.config/tiroir/front-token`, or from the variable
61
+ `TIROIR_FRONT_TOKEN` when that is set. It sends it only to the sheaf's own host, and never prints
62
+ it.
63
+
64
+ To get it, sign in to the front in your browser, open the developer tools, and copy the value of
65
+ the cookie `token` for the front's address (Chrome: Application > Cookies). Then, on a Mac:
66
+
67
+ ```bash
68
+ mkdir -p ~/.config/tiroir
69
+ pbpaste > ~/.config/tiroir/front-token # with the token on the clipboard
70
+ chmod 600 ~/.config/tiroir/front-token
71
+ ```
72
+
73
+ On Linux, use `xclip -selection clipboard -o` instead of `pbpaste`. The file must be readable by
74
+ you alone (`chmod 600`); `tiroir work` refuses it otherwise. The token expires with your session
75
+ on the front: when `tiroir work` says you are not signed in, copy a fresh one the same way.
76
+
77
+ ## When something is refused
78
+
79
+ `tiroir work` says why in one sentence and exits with code 2. The reasons:
80
+ - you are not signed in;
81
+ - the sheaf is not open to you, or has no session on the hub;
82
+ - the address is not a sheaf's;
83
+ - the token file is readable by others;
84
+ - a link sits under the session's file name.
85
+
86
+ When the hub refuses to record the fork, `tiroir work` gives the hub's reason. The transcript is
87
+ then already on your laptop, and Claude Code is not started: run the same command again once the
88
+ reason is fixed.
89
+
90
+ ## Development
91
+
92
+ ```bash
93
+ uv run --extra dev pytest
94
+ uv run --extra dev ruff check . && uv run --extra dev ruff format --check .
95
+ ```
96
+
97
+ The tests run the command against a fake hub on 127.0.0.1 and never touch your real
98
+ `~/.claude`.
99
+
100
+ ## License
101
+
102
+ MIT, see `LICENSE`.
@@ -0,0 +1,41 @@
1
+ [project]
2
+ name = "tiroir"
3
+ version = "0.1.0"
4
+ description = "Fork a tiroir hub's agent session to your own machine and carry on in Claude Code."
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ authors = [{ name = "tiroir", email = "202564+tiroir@users.noreply.github.com" }]
9
+ requires-python = ">=3.11"
10
+ dependencies = []
11
+ classifiers = [
12
+ "Environment :: Console",
13
+ "Operating System :: POSIX",
14
+ "Operating System :: MacOS",
15
+ "Programming Language :: Python :: 3",
16
+ ]
17
+
18
+ [project.scripts]
19
+ tiroir = "tiroir.work:main"
20
+
21
+ [project.optional-dependencies]
22
+ dev = [
23
+ "pytest>=8.0",
24
+ "ruff>=0.6",
25
+ ]
26
+
27
+ [tool.ruff]
28
+ line-length = 100
29
+
30
+ [tool.ruff.lint]
31
+ select = ["E", "F", "I", "B", "UP", "SIM", "RUF"]
32
+
33
+ [tool.pytest.ini_options]
34
+ testpaths = ["tests"]
35
+
36
+ [build-system]
37
+ requires = ["hatchling>=1.27"]
38
+ build-backend = "hatchling.build"
39
+
40
+ [tool.hatch.build.targets.wheel]
41
+ packages = ["src/tiroir"]
@@ -0,0 +1 @@
1
+ """tiroir on your own machine: the laptop side of a tiroir hub."""