tabc 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.
tabc-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 TAE HYEONG KIM
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.
tabc-0.1.0/MANIFEST.in ADDED
@@ -0,0 +1,5 @@
1
+ include PYPI.md LICENSE
2
+ exclude tabus/locales/ko.json
3
+ exclude README.md
4
+ prune tests
5
+ prune scripts
tabc-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,143 @@
1
+ Metadata-Version: 2.4
2
+ Name: tabc
3
+ Version: 0.1.0
4
+ Summary: A shared inbox for AI agents and programs on one machine
5
+ License: MIT License
6
+
7
+ Copyright (c) 2026 TAE HYEONG KIM
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
27
+ Keywords: agents,messaging,ipc,cli
28
+ Classifier: Development Status :: 3 - Alpha
29
+ Classifier: Environment :: Console
30
+ Classifier: Intended Audience :: Developers
31
+ Classifier: License :: OSI Approved :: MIT License
32
+ Classifier: Programming Language :: Python :: 3
33
+ Classifier: Topic :: Communications
34
+ Requires-Python: >=3.9
35
+ Description-Content-Type: text/markdown
36
+ License-File: LICENSE
37
+ Requires-Dist: cryptography>=41
38
+ Dynamic: license-file
39
+
40
+ # tabc
41
+
42
+ <img src="https://raw.githubusercontent.com/jultabc/tabc/main/docs/logo.png" alt="tabc" width="320">
43
+
44
+ A shared inbox for AI agents and programs on one machine.
45
+ Messages are stored locally. Programs can send events; they do not receive replies.
46
+
47
+ This is an experimental package. It is not a security boundary between agents
48
+ using the same operating-system account. Message delivery does not imply that
49
+ an agent read, understood, or completed a request.
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ pip install tabc
55
+ ```
56
+
57
+ Installing from TestPyPI is a different command, and the dependency comes from
58
+ the main index:
59
+
60
+ ```bash
61
+ pip install --index-url https://test.pypi.org/simple/ \
62
+ --extra-index-url https://pypi.org/simple/ tabc
63
+ ```
64
+
65
+ ## Requirements
66
+
67
+ Python 3.9 or later is declared. Installation has been exercised on CPython
68
+ 3.11 and 3.13, on macOS. Other versions and operating systems are untested.
69
+ `cryptography` and its platform-dependent dependencies are installed by pip.
70
+
71
+ ## A first round trip
72
+
73
+ Two shells. If this works, the installation is sound.
74
+
75
+ ```bash
76
+ # shell 1 — start the server, register yourself
77
+ tabd &
78
+ tabc register --node alice --kind generic
79
+
80
+ # shell 2 — register before anything is sent here
81
+ tabc register --node bob --kind generic
82
+
83
+ # shell 1 — send
84
+ tabc send --sender alice --to bob --subject "hello" --body "first"
85
+
86
+ # shell 2 — read it, then record that you did
87
+ tabc pull --node bob --mode full
88
+ tabc ack --node bob --id <full-uuid> --state READ
89
+
90
+ # shell 1 — the point: bob: READ
91
+ tabc sent --node alice
92
+ ```
93
+
94
+ The last line is what matters. It shows the message reached the other side,
95
+ rather than showing that sending did not fail. `--id` takes the full UUID from
96
+ the `pull --mode full` detail block, not the truncated one on a title line.
97
+
98
+ Terminal notification is a separate process and does not start with the
99
+ install; see the repository's guide before turning it on.
100
+
101
+ ## Commands
102
+
103
+ - `tabc register --node alice --kind codex`: register an agent.
104
+ - `tabc send --sender alice --to bob --subject "Hello" --body "Ready to collaborate."`: send a dm.
105
+ - `tabc dm --node bob`: list unread messages.
106
+ - `tabc read --node bob`: display messages and record them as read.
107
+ - `tabc sent --node alice`: inspect outgoing delivery states.
108
+ - `tabc tac search --node alice --query text`: search joined topics without changing read state.
109
+
110
+ Register each recipient before sending. tac creators must also join their topic.
111
+ Run `tabc --help` for available commands. The local server is `tabd`; management
112
+ commands are provided separately by `tabm`.
113
+ The source repository carries the operating guide and the security notes.
114
+
115
+ Release packages include only the English message catalog. English is the default
116
+ and fallback language, including when `TABC_LANG=ko` is set without a Korean catalog.
117
+
118
+ ## Local operation and limitations
119
+
120
+ Run one `tabd` for a shared store. Its default address is `127.0.0.1:8765`.
121
+ That address is a default, not a fixture:
122
+
123
+ ```bash
124
+ tabd --bind <address> --port <port> # the daemon
125
+ export TABC_BUS_URL=http://<address>:<port> # the clients
126
+ ```
127
+
128
+ Keep the store, keys, and server address consistent across participating terminals.
129
+ For isolated tests, use separate `TABC_HOME`, `TABC_DB`, and `TABC_BUS_URL` settings.
130
+
131
+ Terminal notifications require a separate notifier and a valid terminal route.
132
+ Installation alone does not enable notifications. Automatic Enter defaults to off
133
+ for new routes. Omitting the setting during registration preserves the same active
134
+ route; `--auto-enter off` disables it explicitly.
135
+
136
+ Do not connect notifications to an unreviewed command prompt.
137
+ Automatic Enter does not guarantee a reply.
138
+
139
+ Requests are signed, but agents sharing an operating-system account can access
140
+ each other's key files. Messages are not encrypted at rest. Use only within a
141
+ trusted local workspace. Terminal notification types into an input field, which
142
+ is a decision about that terminal rather than a convenience; it is off until you
143
+ turn it on.
tabc-0.1.0/PYPI.md ADDED
@@ -0,0 +1,104 @@
1
+ # tabc
2
+
3
+ <img src="https://raw.githubusercontent.com/jultabc/tabc/main/docs/logo.png" alt="tabc" width="320">
4
+
5
+ A shared inbox for AI agents and programs on one machine.
6
+ Messages are stored locally. Programs can send events; they do not receive replies.
7
+
8
+ This is an experimental package. It is not a security boundary between agents
9
+ using the same operating-system account. Message delivery does not imply that
10
+ an agent read, understood, or completed a request.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ pip install tabc
16
+ ```
17
+
18
+ Installing from TestPyPI is a different command, and the dependency comes from
19
+ the main index:
20
+
21
+ ```bash
22
+ pip install --index-url https://test.pypi.org/simple/ \
23
+ --extra-index-url https://pypi.org/simple/ tabc
24
+ ```
25
+
26
+ ## Requirements
27
+
28
+ Python 3.9 or later is declared. Installation has been exercised on CPython
29
+ 3.11 and 3.13, on macOS. Other versions and operating systems are untested.
30
+ `cryptography` and its platform-dependent dependencies are installed by pip.
31
+
32
+ ## A first round trip
33
+
34
+ Two shells. If this works, the installation is sound.
35
+
36
+ ```bash
37
+ # shell 1 — start the server, register yourself
38
+ tabd &
39
+ tabc register --node alice --kind generic
40
+
41
+ # shell 2 — register before anything is sent here
42
+ tabc register --node bob --kind generic
43
+
44
+ # shell 1 — send
45
+ tabc send --sender alice --to bob --subject "hello" --body "first"
46
+
47
+ # shell 2 — read it, then record that you did
48
+ tabc pull --node bob --mode full
49
+ tabc ack --node bob --id <full-uuid> --state READ
50
+
51
+ # shell 1 — the point: bob: READ
52
+ tabc sent --node alice
53
+ ```
54
+
55
+ The last line is what matters. It shows the message reached the other side,
56
+ rather than showing that sending did not fail. `--id` takes the full UUID from
57
+ the `pull --mode full` detail block, not the truncated one on a title line.
58
+
59
+ Terminal notification is a separate process and does not start with the
60
+ install; see the repository's guide before turning it on.
61
+
62
+ ## Commands
63
+
64
+ - `tabc register --node alice --kind codex`: register an agent.
65
+ - `tabc send --sender alice --to bob --subject "Hello" --body "Ready to collaborate."`: send a dm.
66
+ - `tabc dm --node bob`: list unread messages.
67
+ - `tabc read --node bob`: display messages and record them as read.
68
+ - `tabc sent --node alice`: inspect outgoing delivery states.
69
+ - `tabc tac search --node alice --query text`: search joined topics without changing read state.
70
+
71
+ Register each recipient before sending. tac creators must also join their topic.
72
+ Run `tabc --help` for available commands. The local server is `tabd`; management
73
+ commands are provided separately by `tabm`.
74
+ The source repository carries the operating guide and the security notes.
75
+
76
+ Release packages include only the English message catalog. English is the default
77
+ and fallback language, including when `TABC_LANG=ko` is set without a Korean catalog.
78
+
79
+ ## Local operation and limitations
80
+
81
+ Run one `tabd` for a shared store. Its default address is `127.0.0.1:8765`.
82
+ That address is a default, not a fixture:
83
+
84
+ ```bash
85
+ tabd --bind <address> --port <port> # the daemon
86
+ export TABC_BUS_URL=http://<address>:<port> # the clients
87
+ ```
88
+
89
+ Keep the store, keys, and server address consistent across participating terminals.
90
+ For isolated tests, use separate `TABC_HOME`, `TABC_DB`, and `TABC_BUS_URL` settings.
91
+
92
+ Terminal notifications require a separate notifier and a valid terminal route.
93
+ Installation alone does not enable notifications. Automatic Enter defaults to off
94
+ for new routes. Omitting the setting during registration preserves the same active
95
+ route; `--auto-enter off` disables it explicitly.
96
+
97
+ Do not connect notifications to an unreviewed command prompt.
98
+ Automatic Enter does not guarantee a reply.
99
+
100
+ Requests are signed, but agents sharing an operating-system account can access
101
+ each other's key files. Messages are not encrypted at rest. Use only within a
102
+ trusted local workspace. Terminal notification types into an input field, which
103
+ is a decision about that terminal rather than a convenience; it is off until you
104
+ turn it on.
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "tabc"
7
+ version = "0.1.0"
8
+ description = "A shared inbox for AI agents and programs on one machine"
9
+ readme = "PYPI.md"
10
+ requires-python = ">=3.9"
11
+ license = { file = "LICENSE" }
12
+ keywords = ["agents", "messaging", "ipc", "cli"]
13
+ classifiers = [
14
+ "Development Status :: 3 - Alpha",
15
+ "Environment :: Console",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Programming Language :: Python :: 3",
19
+ "Topic :: Communications",
20
+ ]
21
+ # 🔴 One runtime dependency, and it is not optional. Signing used to be a feature
22
+ # you could leave out: it labelled a sender, nothing depended on the label, and
23
+ # so the core stayed standard-library-only with `cryptography` behind a `sign`
24
+ # extra. Authenticating every request by node-key signature ended that —
25
+ # `tabus.daemon` imports `nodekey` at module level and raises ImportError on the
26
+ # first line without it. An extra the daemon cannot start without is not an
27
+ # extra; leaving it optional made the documented `pip install -e .` produce an
28
+ # installation with no working `tabd`.
29
+ dependencies = ["cryptography>=41"]
30
+
31
+ [project.scripts]
32
+ tabc = "tabus.cli:main"
33
+ tabm = "tabus.admin:main"
34
+ tabd = "tabus.daemon:main"
35
+
36
+ [tool.setuptools]
37
+ # 🔴 Named, not found automatically. Auto-discovery would also sweep in `tests`
38
+ # and `scripts`, which are part of the repository but not part of what a user
39
+ # installs.
40
+ packages = ["tabus"]
41
+
42
+ [tool.setuptools.package-data]
43
+ # The message catalogues ship with the code: they are a package resource, not
44
+ # user state, and tabus.lang resolves them relative to the module.
45
+ tabus = ["locales/en.json"]
46
+
47
+ [tool.setuptools.exclude-package-data]
48
+ tabus = ["locales/ko.json"]
tabc-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,143 @@
1
+ Metadata-Version: 2.4
2
+ Name: tabc
3
+ Version: 0.1.0
4
+ Summary: A shared inbox for AI agents and programs on one machine
5
+ License: MIT License
6
+
7
+ Copyright (c) 2026 TAE HYEONG KIM
8
+
9
+ Permission is hereby granted, free of charge, to any person obtaining a copy
10
+ of this software and associated documentation files (the "Software"), to deal
11
+ in the Software without restriction, including without limitation the rights
12
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13
+ copies of the Software, and to permit persons to whom the Software is
14
+ furnished to do so, subject to the following conditions:
15
+
16
+ The above copyright notice and this permission notice shall be included in all
17
+ copies or substantial portions of the Software.
18
+
19
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25
+ SOFTWARE.
26
+
27
+ Keywords: agents,messaging,ipc,cli
28
+ Classifier: Development Status :: 3 - Alpha
29
+ Classifier: Environment :: Console
30
+ Classifier: Intended Audience :: Developers
31
+ Classifier: License :: OSI Approved :: MIT License
32
+ Classifier: Programming Language :: Python :: 3
33
+ Classifier: Topic :: Communications
34
+ Requires-Python: >=3.9
35
+ Description-Content-Type: text/markdown
36
+ License-File: LICENSE
37
+ Requires-Dist: cryptography>=41
38
+ Dynamic: license-file
39
+
40
+ # tabc
41
+
42
+ <img src="https://raw.githubusercontent.com/jultabc/tabc/main/docs/logo.png" alt="tabc" width="320">
43
+
44
+ A shared inbox for AI agents and programs on one machine.
45
+ Messages are stored locally. Programs can send events; they do not receive replies.
46
+
47
+ This is an experimental package. It is not a security boundary between agents
48
+ using the same operating-system account. Message delivery does not imply that
49
+ an agent read, understood, or completed a request.
50
+
51
+ ## Install
52
+
53
+ ```bash
54
+ pip install tabc
55
+ ```
56
+
57
+ Installing from TestPyPI is a different command, and the dependency comes from
58
+ the main index:
59
+
60
+ ```bash
61
+ pip install --index-url https://test.pypi.org/simple/ \
62
+ --extra-index-url https://pypi.org/simple/ tabc
63
+ ```
64
+
65
+ ## Requirements
66
+
67
+ Python 3.9 or later is declared. Installation has been exercised on CPython
68
+ 3.11 and 3.13, on macOS. Other versions and operating systems are untested.
69
+ `cryptography` and its platform-dependent dependencies are installed by pip.
70
+
71
+ ## A first round trip
72
+
73
+ Two shells. If this works, the installation is sound.
74
+
75
+ ```bash
76
+ # shell 1 — start the server, register yourself
77
+ tabd &
78
+ tabc register --node alice --kind generic
79
+
80
+ # shell 2 — register before anything is sent here
81
+ tabc register --node bob --kind generic
82
+
83
+ # shell 1 — send
84
+ tabc send --sender alice --to bob --subject "hello" --body "first"
85
+
86
+ # shell 2 — read it, then record that you did
87
+ tabc pull --node bob --mode full
88
+ tabc ack --node bob --id <full-uuid> --state READ
89
+
90
+ # shell 1 — the point: bob: READ
91
+ tabc sent --node alice
92
+ ```
93
+
94
+ The last line is what matters. It shows the message reached the other side,
95
+ rather than showing that sending did not fail. `--id` takes the full UUID from
96
+ the `pull --mode full` detail block, not the truncated one on a title line.
97
+
98
+ Terminal notification is a separate process and does not start with the
99
+ install; see the repository's guide before turning it on.
100
+
101
+ ## Commands
102
+
103
+ - `tabc register --node alice --kind codex`: register an agent.
104
+ - `tabc send --sender alice --to bob --subject "Hello" --body "Ready to collaborate."`: send a dm.
105
+ - `tabc dm --node bob`: list unread messages.
106
+ - `tabc read --node bob`: display messages and record them as read.
107
+ - `tabc sent --node alice`: inspect outgoing delivery states.
108
+ - `tabc tac search --node alice --query text`: search joined topics without changing read state.
109
+
110
+ Register each recipient before sending. tac creators must also join their topic.
111
+ Run `tabc --help` for available commands. The local server is `tabd`; management
112
+ commands are provided separately by `tabm`.
113
+ The source repository carries the operating guide and the security notes.
114
+
115
+ Release packages include only the English message catalog. English is the default
116
+ and fallback language, including when `TABC_LANG=ko` is set without a Korean catalog.
117
+
118
+ ## Local operation and limitations
119
+
120
+ Run one `tabd` for a shared store. Its default address is `127.0.0.1:8765`.
121
+ That address is a default, not a fixture:
122
+
123
+ ```bash
124
+ tabd --bind <address> --port <port> # the daemon
125
+ export TABC_BUS_URL=http://<address>:<port> # the clients
126
+ ```
127
+
128
+ Keep the store, keys, and server address consistent across participating terminals.
129
+ For isolated tests, use separate `TABC_HOME`, `TABC_DB`, and `TABC_BUS_URL` settings.
130
+
131
+ Terminal notifications require a separate notifier and a valid terminal route.
132
+ Installation alone does not enable notifications. Automatic Enter defaults to off
133
+ for new routes. Omitting the setting during registration preserves the same active
134
+ route; `--auto-enter off` disables it explicitly.
135
+
136
+ Do not connect notifications to an unreviewed command prompt.
137
+ Automatic Enter does not guarantee a reply.
138
+
139
+ Requests are signed, but agents sharing an operating-system account can access
140
+ each other's key files. Messages are not encrypted at rest. Use only within a
141
+ trusted local workspace. Terminal notification types into an input field, which
142
+ is a decision about that terminal rather than a convenience; it is off until you
143
+ turn it on.
@@ -0,0 +1,26 @@
1
+ LICENSE
2
+ MANIFEST.in
3
+ PYPI.md
4
+ pyproject.toml
5
+ tabc.egg-info/PKG-INFO
6
+ tabc.egg-info/SOURCES.txt
7
+ tabc.egg-info/dependency_links.txt
8
+ tabc.egg-info/entry_points.txt
9
+ tabc.egg-info/requires.txt
10
+ tabc.egg-info/top_level.txt
11
+ tabus/__init__.py
12
+ tabus/admin.py
13
+ tabus/bus.py
14
+ tabus/cli.py
15
+ tabus/compat_bcn.py
16
+ tabus/compat_busd.py
17
+ tabus/daemon.py
18
+ tabus/doorbell.py
19
+ tabus/doorbell_poll.py
20
+ tabus/lang.py
21
+ tabus/nodekey.py
22
+ tabus/paths.py
23
+ tabus/route_capture.py
24
+ tabus/sent.py
25
+ tabus/tac_search.py
26
+ tabus/locales/en.json
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ tabc = tabus.cli:main
3
+ tabd = tabus.daemon:main
4
+ tabm = tabus.admin:main
@@ -0,0 +1 @@
1
+ cryptography>=41
@@ -0,0 +1 @@
1
+ tabus
@@ -0,0 +1,35 @@
1
+ """tabus — a message bus between sessions on one machine.
2
+
3
+ The bus itself lives in `tabus.bus`. This module re-exports it so that
4
+ `import tabus` followed by `tabus.bus_send(...)` keeps meaning what it always
5
+ meant: before the package layout, `tabus` *was* that module, and twenty-seven
6
+ call sites are written that way. Re-exporting keeps the public surface identical
7
+ while the files underneath get a shape a package can have.
8
+
9
+ tabus.bus the store and its operations
10
+ tabus.cli the `tabc` command line
11
+ tabus.daemon the local HTTP daemon
12
+ tabus.doorbell the notifier
13
+ tabus.nodekey ed25519 signing keys, one per node
14
+ tabus.lang the message catalogue
15
+ tabus.paths where this installation keeps its state
16
+
17
+ 🔴 `from .bus import *` rather than a hand-listed set of names. The bus module
18
+ defines what is public; restating that list here would be a second copy of it,
19
+ and the two would drift the first time someone added a function to one and not
20
+ the other. `bus` carries no `__all__`, so this takes its module-level names that
21
+ do not begin with an underscore — the same rule a reader would apply by eye.
22
+ """
23
+
24
+ from .bus import * # noqa: F401,F403
25
+ from . import bus # noqa: F401 — also reachable by its own name
26
+ from . import paths # noqa: F401
27
+
28
+ # 🔴 Re-export copies references; it does not alias the module. Reading
29
+ # `tabus.bus_send` and `tabus.bus.bus_send` gives the same function, but
30
+ # *assigning* `tabus.bus_send = f` rebinds the name here only — callers inside
31
+ # tabus.bus look their globals up in their own module and never see it. Code
32
+ # that replaces a function (a test with a stub, a caller installing a policy)
33
+ # must target `tabus.bus`. The read path being identical is what makes this
34
+ # easy to get wrong, so it is stated rather than left to be discovered.
35
+ __version__ = bus.__version__ if hasattr(bus, "__version__") else "0"
@@ -0,0 +1,68 @@
1
+ """tabm: management command names, reusing the existing signed request handlers.
2
+
3
+ This command split is not an authorization boundary. Key recovery alone is
4
+ local-only; disable/enable/purge retain the daemon's existing authorization.
5
+ """
6
+
7
+ from argparse import Namespace
8
+
9
+ from . import cli
10
+
11
+
12
+ def change_node(a):
13
+ args = Namespace(node=a.target, actor=a.node, by=a.by,
14
+ purge=a.cmd == "purge", yes=getattr(a, "yes", False))
15
+ if a.cmd == "enable":
16
+ cli.fn_restore(args)
17
+ else:
18
+ cli.fn_rm(args)
19
+
20
+
21
+ def rotate_key(a):
22
+ # Local key recovery deliberately has no HTTP equivalent.
23
+ from .bus import cmd_rotate_key
24
+
25
+ cmd_rotate_key(a)
26
+
27
+
28
+ def commands():
29
+ specs = {
30
+ "config": (cli.fn_config, "read or set the local owner email", [
31
+ (("--email",), dict(default=None)),
32
+ ]),
33
+ "list": (cli.fn_who, "list active nodes and pending counts", [
34
+ (("--node",), dict(required=True, help="acting node")),
35
+ ]),
36
+ "rotate-key": (rotate_key, "local-only public key recovery; not a remote request", [
37
+ (("node",), dict(help="target node")),
38
+ (("pubkey",), dict(help="replacement public key")),
39
+ (("--by",), dict(required=True, help="operator recorded in the audit")),
40
+ ]),
41
+ }
42
+ for action, description in (
43
+ ("disable", "disable a node, retaining its history"),
44
+ ("enable", "enable a previously disabled node"),
45
+ ("purge", "permanently delete a node only if it has no history"),
46
+ ):
47
+ args = [
48
+ (("--node",), dict(required=True, help="acting node signing this request")),
49
+ (("--target",), dict(required=True, help="node being changed")),
50
+ (("--by",), dict(default=None, help="audit label, not authentication")),
51
+ ]
52
+ if action != "enable":
53
+ args.append((("--yes",), dict(action="store_true", help="confirm the operation")))
54
+ specs[action] = (change_node, description, args)
55
+ return specs
56
+
57
+
58
+ def build_parser():
59
+ return cli.build_parser(prog="tabm", commands=commands())
60
+
61
+
62
+ def main():
63
+ args = build_parser().parse_args()
64
+ commands()[args.cmd][0](args)
65
+
66
+
67
+ if __name__ == "__main__":
68
+ main()