kache-ssh 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.
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/PKG-INFO +3 -22
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/README.md +187 -205
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/pyproject.toml +42 -43
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/AGENTS.md +1 -2
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/__init__.py +17 -17
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/agent.py +1 -23
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/cli.py +11 -91
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/tests/test_agent_api.py +15 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/tests/test_v02.py +247 -292
- kache_ssh-0.2.0/src/kache/notify.py +0 -173
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/.gitignore +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/AGENTS.md +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/LICENSE +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/__main__.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/client.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/config.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/evidence.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/files.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/jobs.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/keys.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/mcp.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/network.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/probe.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/service.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/telemetry.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/src/kache/tui.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/tests/test_e2e.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/tests/test_service.py +0 -0
- {kache_ssh-0.2.0 → kache_ssh-0.3.0}/tests/test_tui.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: kache-ssh
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Kache: one terminal to command all your devices over SSH, with a gatekeeper agent on every device.
|
|
5
5
|
Author: Simon Malm
|
|
6
6
|
License-Expression: MIT
|
|
@@ -16,7 +16,6 @@ Requires-Python: >=3.10
|
|
|
16
16
|
Requires-Dist: asyncssh>=2.14
|
|
17
17
|
Requires-Dist: platformdirs>=4.0
|
|
18
18
|
Requires-Dist: psutil>=5.9
|
|
19
|
-
Requires-Dist: segno>=1.5
|
|
20
19
|
Requires-Dist: textual>=8.0
|
|
21
20
|
Provides-Extra: dev
|
|
22
21
|
Requires-Dist: build>=1.0; extra == 'dev'
|
|
@@ -56,8 +55,6 @@ kache
|
|
|
56
55
|
live output, and stops it.
|
|
57
56
|
- **Files both ways.** `kache push` and `kache pull` copy files and whole
|
|
58
57
|
folders over the same paired connection.
|
|
59
|
-
- **Phone notifications.** Get a push message when a job finishes, an
|
|
60
|
-
agent's order fails, a device goes offline or someone asks to pair.
|
|
61
58
|
- **Device health at a glance.** Online/offline, CPU and RAM use, GPU load,
|
|
62
59
|
temperature and memory (NVIDIA), and CPU temperature where the OS exposes it.
|
|
63
60
|
- **Pairing with a yes/no question.** Ask another device to pair; its Kache
|
|
@@ -146,22 +143,6 @@ kache pull desktop:C:/proj/results . # copy back
|
|
|
146
143
|
kache run desktop -f setup.ps1 # send a whole script
|
|
147
144
|
```
|
|
148
145
|
|
|
149
|
-
## Phone notifications
|
|
150
|
-
|
|
151
|
-
Kache uses [ntfy](https://ntfy.sh), a free open-source push service:
|
|
152
|
-
|
|
153
|
-
1. Install the **ntfy** app on your phone (App Store or Google Play).
|
|
154
|
-
2. On one of your devices run `kache notify setup`. It shows a QR code;
|
|
155
|
-
scan it (or subscribe in the app to the topic it prints). All your paired
|
|
156
|
-
devices get the same setting.
|
|
157
|
-
3. Run `kache notify test`.
|
|
158
|
-
|
|
159
|
-
You get a message when a background job ends, an order from a script or AI
|
|
160
|
-
agent fails, a device goes offline or comes back, or a device asks to pair.
|
|
161
|
-
Messages contain a short summary, never command output. The topic name is
|
|
162
|
-
a long random secret; anyone who knows it can read the messages, so keep it
|
|
163
|
-
private, or use your own ntfy server with `--server`.
|
|
164
|
-
|
|
165
146
|
## Away from home: Tailscale
|
|
166
147
|
|
|
167
148
|
Kache connects devices directly, so a device must be reachable from the one
|
|
@@ -220,8 +201,8 @@ Tailscale, each address, the device's key, the pairing) and says what to fix.
|
|
|
220
201
|
|
|
221
202
|
## Status
|
|
222
203
|
|
|
223
|
-
Version 0.
|
|
224
|
-
background jobs, file transfer,
|
|
204
|
+
Version 0.3: pairing, orders, sessions, evidence, live feed, health,
|
|
205
|
+
background jobs, file transfer, start at boot,
|
|
225
206
|
Tailscale, JSON output and MCP work on Windows, Linux and macOS.
|
|
226
207
|
|
|
227
208
|
Planned:
|
|
@@ -1,205 +1,187 @@
|
|
|
1
|
-
# Kache
|
|
2
|
-
|
|
3
|
-
One terminal to command all your devices.
|
|
4
|
-
|
|
5
|
-
Kache is a hub that runs in your terminal. Pair your computers once, then
|
|
6
|
-
type a command and it runs on the device you picked, or on all of them at
|
|
7
|
-
once, exactly as if you were sitting at that machine. Every device runs a
|
|
8
|
-
small **gatekeeper** that only obeys devices you paired, refuses orders that
|
|
9
|
-
cannot work there, and sends back an evidence report when something fails.
|
|
10
|
-
Every order anyone sends (you, a script, or an AI agent working for you)
|
|
11
|
-
shows up in the live feed with the exact command.
|
|
12
|
-
|
|
13
|
-
```
|
|
14
|
-
pip install kache-ssh
|
|
15
|
-
kache
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## What you get
|
|
19
|
-
|
|
20
|
-
- **A real remote terminal.** What you type is what runs on the other device,
|
|
21
|
-
in its own shell (PowerShell on Windows, your shell on Linux and macOS).
|
|
22
|
-
`cd` sticks between commands, output streams live, Ctrl+C stops an order.
|
|
23
|
-
- **One device or all of them.** Pick a device, or press F6 and send the same
|
|
24
|
-
order to every device in parallel; output is labelled per device.
|
|
25
|
-
- **Jobs that keep running.** Press F7 instead of Enter (or `kache run
|
|
26
|
-
--detach`) and the order keeps going after you close Kache or lose the
|
|
27
|
-
connection: training runs, builds, downloads. F8 shows every job, its
|
|
28
|
-
live output, and stops it.
|
|
29
|
-
- **Files both ways.** `kache push` and `kache pull` copy files and whole
|
|
30
|
-
folders over the same paired connection.
|
|
31
|
-
- **
|
|
32
|
-
|
|
33
|
-
- **
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
|
81
|
-
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
|
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
|
|
|
89
|
-
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
kache
|
|
113
|
-
kache
|
|
114
|
-
kache
|
|
115
|
-
kache
|
|
116
|
-
kache
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
kache
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
devices trusted to command it, the feed and the evidence reports.
|
|
189
|
-
|
|
190
|
-
If something does not connect, `kache doctor` checks every step (gatekeeper,
|
|
191
|
-
Tailscale, each address, the device's key, the pairing) and says what to fix.
|
|
192
|
-
|
|
193
|
-
## Status
|
|
194
|
-
|
|
195
|
-
Version 0.2: pairing, orders, sessions, evidence, live feed, health,
|
|
196
|
-
background jobs, file transfer, phone notifications, start at boot,
|
|
197
|
-
Tailscale, JSON output and MCP work on Windows, Linux and macOS.
|
|
198
|
-
|
|
199
|
-
Planned:
|
|
200
|
-
- full interactive sessions (`kache attach` for programs like vim or htop);
|
|
201
|
-
- permissions per sender: read-only scripts and agents, your approval for dangerous orders;
|
|
202
|
-
- pairing both directions in one step;
|
|
203
|
-
- a relay for devices that cannot reach each other directly.
|
|
204
|
-
|
|
205
|
-
MIT licensed.
|
|
1
|
+
# Kache
|
|
2
|
+
|
|
3
|
+
One terminal to command all your devices.
|
|
4
|
+
|
|
5
|
+
Kache is a hub that runs in your terminal. Pair your computers once, then
|
|
6
|
+
type a command and it runs on the device you picked, or on all of them at
|
|
7
|
+
once, exactly as if you were sitting at that machine. Every device runs a
|
|
8
|
+
small **gatekeeper** that only obeys devices you paired, refuses orders that
|
|
9
|
+
cannot work there, and sends back an evidence report when something fails.
|
|
10
|
+
Every order anyone sends (you, a script, or an AI agent working for you)
|
|
11
|
+
shows up in the live feed with the exact command.
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
pip install kache-ssh
|
|
15
|
+
kache
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## What you get
|
|
19
|
+
|
|
20
|
+
- **A real remote terminal.** What you type is what runs on the other device,
|
|
21
|
+
in its own shell (PowerShell on Windows, your shell on Linux and macOS).
|
|
22
|
+
`cd` sticks between commands, output streams live, Ctrl+C stops an order.
|
|
23
|
+
- **One device or all of them.** Pick a device, or press F6 and send the same
|
|
24
|
+
order to every device in parallel; output is labelled per device.
|
|
25
|
+
- **Jobs that keep running.** Press F7 instead of Enter (or `kache run
|
|
26
|
+
--detach`) and the order keeps going after you close Kache or lose the
|
|
27
|
+
connection: training runs, builds, downloads. F8 shows every job, its
|
|
28
|
+
live output, and stops it.
|
|
29
|
+
- **Files both ways.** `kache push` and `kache pull` copy files and whole
|
|
30
|
+
folders over the same paired connection.
|
|
31
|
+
- **Device health at a glance.** Online/offline, CPU and RAM use, GPU load,
|
|
32
|
+
temperature and memory (NVIDIA), and CPU temperature where the OS exposes it.
|
|
33
|
+
- **Pairing with a yes/no question.** Ask another device to pair; its Kache
|
|
34
|
+
terminal asks *"laptop wants to send orders to this device. Code 482 913.
|
|
35
|
+
Accept?"* Both screens show the same code, so nobody can sit in between.
|
|
36
|
+
- **Works at home and away.** Kache remembers every address of a device (LAN,
|
|
37
|
+
Tailscale IP, Tailscale name) and uses whichever answers. Pair once at
|
|
38
|
+
home; it keeps working over [Tailscale](https://tailscale.com) anywhere.
|
|
39
|
+
- **A gatekeeper on every device.** Unknown devices can only say hello or ask
|
|
40
|
+
to pair. Paired devices are pinned by key. Orders for commands that do not
|
|
41
|
+
exist on that device are refused up front (Linux/macOS) or explained
|
|
42
|
+
afterwards (Windows).
|
|
43
|
+
- **Evidence when things break.** A failing order comes back with a report:
|
|
44
|
+
exit code, last lines of output, labelled hints (command not found,
|
|
45
|
+
permission, disk full, missing Python module, network, out of memory...)
|
|
46
|
+
and the machine's state at that moment. An order that "succeeded" while
|
|
47
|
+
PowerShell printed errors says so: *ok, but 3 errors were reported*.
|
|
48
|
+
- **A live feed of every order.** Who sent what to which device, when, and
|
|
49
|
+
how it ended, including orders from scripts and AI agents, which are
|
|
50
|
+
labelled with the agent's name.
|
|
51
|
+
- **Built for AI agents too.** Every command has `--json`, there is an MCP
|
|
52
|
+
server (`kache mcp`), and `kache guide` explains everything an agent needs.
|
|
53
|
+
|
|
54
|
+
## Quick start
|
|
55
|
+
|
|
56
|
+
On every device, one command:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
pip install kache-ssh
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Then open Kache by typing `kache`. The first time, it also starts its
|
|
63
|
+
gatekeeper in the background and from then on at every login, so the device
|
|
64
|
+
stays reachable when the window is closed (`kache service uninstall` turns
|
|
65
|
+
that off, `kache service status` shows it). No administrator rights needed.
|
|
66
|
+
|
|
67
|
+
In the Kache terminal on the device you want to command *from*, press **F2**
|
|
68
|
+
and enter the other device's address: its LAN IP, Tailscale IP or Tailscale
|
|
69
|
+
machine name (devices on your tailnet are listed for you). Accept on the
|
|
70
|
+
other device when the codes match. It appears in your device list, and
|
|
71
|
+
anything you type now runs there.
|
|
72
|
+
|
|
73
|
+
On Windows, the first time the gatekeeper starts, Windows may ask whether
|
|
74
|
+
Python may accept connections. Allow it, or other devices cannot reach this one.
|
|
75
|
+
|
|
76
|
+
### Keys
|
|
77
|
+
|
|
78
|
+
| Key | Action |
|
|
79
|
+
|------------|-----------------------------------------------|
|
|
80
|
+
| Enter | send what you typed to the selected device(s) |
|
|
81
|
+
| ↑ / ↓ | previous / next command |
|
|
82
|
+
| Ctrl+↑ / ↓ | select the previous / next device |
|
|
83
|
+
| F6 | switch between one device and all devices |
|
|
84
|
+
| F7 | send what you typed as a background job |
|
|
85
|
+
| F8 | jobs: watch their output live, stop them |
|
|
86
|
+
| Ctrl+C | stop the running order(s) |
|
|
87
|
+
| F2 | pair a new device |
|
|
88
|
+
| F3 | rename the selected device |
|
|
89
|
+
| F4 | remove the selected device |
|
|
90
|
+
| F5 | show the last failure's evidence |
|
|
91
|
+
| Ctrl+Q | quit |
|
|
92
|
+
|
|
93
|
+
### Start at boot
|
|
94
|
+
|
|
95
|
+
By default the gatekeeper starts when you log in. For a computer that must
|
|
96
|
+
stay reachable after a restart even when nobody logs in (a Windows Update
|
|
97
|
+
reboot while you are away), run once in an administrator terminal:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
kache service install --at-boot
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
When the computer shuts down, Kache simply stops; nothing needs saving.
|
|
104
|
+
Background jobs that were running are reported as *lost* afterwards, so
|
|
105
|
+
you know to start them again.
|
|
106
|
+
|
|
107
|
+
## Jobs and files
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
kache run desktop --detach -- python train.py # starts a job, prints its id
|
|
111
|
+
kache jobs # every job on every device
|
|
112
|
+
kache logs J-3f2a9c -f # follow its output live
|
|
113
|
+
kache cancel J-3f2a9c # stop it
|
|
114
|
+
kache push model.pt data/ desktop:C:/proj # copy to a device
|
|
115
|
+
kache pull desktop:C:/proj/results . # copy back
|
|
116
|
+
kache run desktop -f setup.ps1 # send a whole script
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Away from home: Tailscale
|
|
120
|
+
|
|
121
|
+
Kache connects devices directly, so a device must be reachable from the one
|
|
122
|
+
commanding it. At home that is your LAN. Away from home, install
|
|
123
|
+
[Tailscale](https://tailscale.com) (free for personal use) on both devices
|
|
124
|
+
and sign in with the same account. Then:
|
|
125
|
+
|
|
126
|
+
- `kache discover` lists the devices on your tailnet and which run Kache;
|
|
127
|
+
- pairing by Tailscale name works: `kache pair my-desktop`;
|
|
128
|
+
- devices paired over LAN switch to Tailscale automatically when the LAN
|
|
129
|
+
address stops answering;
|
|
130
|
+
- `kache listen tailscale` makes a gatekeeper answer on your tailnet only,
|
|
131
|
+
ignoring the local network.
|
|
132
|
+
|
|
133
|
+
## For scripts and AI agents
|
|
134
|
+
|
|
135
|
+
Everything the terminal does is also a command with `--json` output, and
|
|
136
|
+
every order still appears in the feed:
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
kache devices --json # status and health of every device
|
|
140
|
+
kache run desktop --json --timeout 60 -- nvidia-smi
|
|
141
|
+
kache run all --as nightly-job -- git pull # labelled in every feed
|
|
142
|
+
kache feed -d all -f --json # live JSON-lines feed from all devices
|
|
143
|
+
kache evidence E-3f2a9c -d desktop # a failure report
|
|
144
|
+
kache doctor desktop --json # why a device cannot be reached
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
For MCP clients (Claude Code, Claude Desktop, Cursor and others):
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
claude mcp add kache -- kache mcp
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Agents get the tools `kache_devices`, `kache_run` (optionally as a job),
|
|
154
|
+
`kache_jobs`, `kache_job_log`, `kache_cancel_job`, `kache_push`,
|
|
155
|
+
`kache_pull`, `kache_feed`, `kache_evidence`, `kache_doctor`,
|
|
156
|
+
`kache_discover`, `kache_pending` and `kache_pair`. Accepting pair requests and revoking devices stays with
|
|
157
|
+
people. `kache guide` prints the full guide: JSON shapes, feed event kinds,
|
|
158
|
+
exit codes and rules for agents.
|
|
159
|
+
|
|
160
|
+
## How it works
|
|
161
|
+
|
|
162
|
+
Each device has one ed25519 key, created on first run. The gatekeeper is an
|
|
163
|
+
SSH server (built on asyncssh, port 7722) that accepts any key but only lets
|
|
164
|
+
unknown keys say hello or ask to pair; paired keys may send orders. The
|
|
165
|
+
Kache terminal is an SSH client that pins each paired device's key. Nothing
|
|
166
|
+
goes through a server in between.
|
|
167
|
+
|
|
168
|
+
State lives in one folder per device (`kache whoami` shows where; override
|
|
169
|
+
with `KACHE_HOME`): the device key, its name, the devices it commands, the
|
|
170
|
+
devices trusted to command it, the feed and the evidence reports.
|
|
171
|
+
|
|
172
|
+
If something does not connect, `kache doctor` checks every step (gatekeeper,
|
|
173
|
+
Tailscale, each address, the device's key, the pairing) and says what to fix.
|
|
174
|
+
|
|
175
|
+
## Status
|
|
176
|
+
|
|
177
|
+
Version 0.3: pairing, orders, sessions, evidence, live feed, health,
|
|
178
|
+
background jobs, file transfer, start at boot,
|
|
179
|
+
Tailscale, JSON output and MCP work on Windows, Linux and macOS.
|
|
180
|
+
|
|
181
|
+
Planned:
|
|
182
|
+
- full interactive sessions (`kache attach` for programs like vim or htop);
|
|
183
|
+
- permissions per sender: read-only scripts and agents, your approval for dangerous orders;
|
|
184
|
+
- pairing both directions in one step;
|
|
185
|
+
- a relay for devices that cannot reach each other directly.
|
|
186
|
+
|
|
187
|
+
MIT licensed.
|
|
@@ -1,43 +1,42 @@
|
|
|
1
|
-
[build-system]
|
|
2
|
-
requires = ["hatchling>=1.24"]
|
|
3
|
-
build-backend = "hatchling.build"
|
|
4
|
-
|
|
5
|
-
[project]
|
|
6
|
-
name = "kache-ssh"
|
|
7
|
-
version = "0.
|
|
8
|
-
description = "Kache: one terminal to command all your devices over SSH, with a gatekeeper agent on every device."
|
|
9
|
-
readme = "README.md"
|
|
10
|
-
requires-python = ">=3.10"
|
|
11
|
-
license = "MIT"
|
|
12
|
-
license-files = ["LICENSE"]
|
|
13
|
-
authors = [{ name = "Simon Malm" }]
|
|
14
|
-
keywords = ["ssh", "remote", "orchestration", "terminal", "tui", "fleet", "tailscale", "mcp", "ai-agents"]
|
|
15
|
-
classifiers = [
|
|
16
|
-
"Environment :: Console",
|
|
17
|
-
"Operating System :: Microsoft :: Windows",
|
|
18
|
-
"Operating System :: POSIX :: Linux",
|
|
19
|
-
"Operating System :: MacOS",
|
|
20
|
-
"Programming Language :: Python :: 3",
|
|
21
|
-
"Topic :: System :: Systems Administration",
|
|
22
|
-
]
|
|
23
|
-
dependencies = [
|
|
24
|
-
"asyncssh>=2.14",
|
|
25
|
-
"textual>=8.0",
|
|
26
|
-
"psutil>=5.9",
|
|
27
|
-
"platformdirs>=4.0",
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
[
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
[
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
testpaths = ["tests"]
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.24"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "kache-ssh"
|
|
7
|
+
version = "0.3.0"
|
|
8
|
+
description = "Kache: one terminal to command all your devices over SSH, with a gatekeeper agent on every device."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [{ name = "Simon Malm" }]
|
|
14
|
+
keywords = ["ssh", "remote", "orchestration", "terminal", "tui", "fleet", "tailscale", "mcp", "ai-agents"]
|
|
15
|
+
classifiers = [
|
|
16
|
+
"Environment :: Console",
|
|
17
|
+
"Operating System :: Microsoft :: Windows",
|
|
18
|
+
"Operating System :: POSIX :: Linux",
|
|
19
|
+
"Operating System :: MacOS",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Topic :: System :: Systems Administration",
|
|
22
|
+
]
|
|
23
|
+
dependencies = [
|
|
24
|
+
"asyncssh>=2.14",
|
|
25
|
+
"textual>=8.0",
|
|
26
|
+
"psutil>=5.9",
|
|
27
|
+
"platformdirs>=4.0",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.optional-dependencies]
|
|
31
|
+
gpu = ["nvidia-ml-py>=12"]
|
|
32
|
+
dev = ["pytest>=8", "pytest-asyncio>=0.23", "build>=1.0"]
|
|
33
|
+
|
|
34
|
+
[project.scripts]
|
|
35
|
+
kache = "kache.cli:main"
|
|
36
|
+
|
|
37
|
+
[tool.hatch.build.targets.wheel]
|
|
38
|
+
packages = ["src/kache"]
|
|
39
|
+
|
|
40
|
+
[tool.pytest.ini_options]
|
|
41
|
+
asyncio_mode = "auto"
|
|
42
|
+
testpaths = ["tests"]
|
|
@@ -79,7 +79,6 @@ with `"v"` (the schema version, currently 1). In JSON mode, errors are
|
|
|
79
79
|
| `kache cancel JOB [-d DEVICE]` | stop a job and its whole process tree |
|
|
80
80
|
| `kache push LOCAL... DEVICE:PATH` | copy files/folders to a device (`all:PATH` for every device) |
|
|
81
81
|
| `kache pull DEVICE:PATH... LOCAL` | copy files/folders from a device |
|
|
82
|
-
| `kache notify setup\|test\|off\|status` | phone notifications through ntfy (a person sets these up) |
|
|
83
82
|
| `kache feed [-d DEVICE\|all] [-n N] [-f]` | recent events; `-f` follows live. `--json` prints JSON lines, one event per line |
|
|
84
83
|
| `kache evidence ID -d DEVICE` | a failure report (always JSON) |
|
|
85
84
|
| `kache doctor [DEVICE]` | connectivity diagnosis with fixes |
|
|
@@ -249,7 +248,7 @@ macOS, or `$KACHE_HOME` if set.
|
|
|
249
248
|
| `agent.log` | what the background gatekeeper did (started, bound, problems) |
|
|
250
249
|
| `devices.json` | devices this one commands: addresses, port, pinned fingerprint |
|
|
251
250
|
| `trusted.json` | devices allowed to command this one |
|
|
252
|
-
| `device.json` | this device's name, port, listen mode
|
|
251
|
+
| `device.json` | this device's name, port, listen mode and autostart setting |
|
|
253
252
|
| `device_key` | this device's private key. Never read, copy or print it |
|
|
254
253
|
|
|
255
254
|
## Troubleshooting
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
"""Kache: one terminal to command all your devices.
|
|
2
|
-
|
|
3
|
-
Every device runs a gatekeeper agent (an SSH server with its own rules);
|
|
4
|
-
the Kache terminal pairs devices, shows their health, sends orders to one
|
|
5
|
-
device or all of them, and keeps a live feed of every order anyone sends.
|
|
6
|
-
"""
|
|
7
|
-
|
|
8
|
-
__version__ = "0.
|
|
9
|
-
|
|
10
|
-
# Bumped whenever devices running different Kache versions could
|
|
11
|
-
# misunderstand each other. The gatekeeper refuses orders from other
|
|
12
|
-
# protocol versions instead of guessing.
|
|
13
|
-
PROTOCOL = 1
|
|
14
|
-
|
|
15
|
-
# Version of the JSON shapes scripts and AI agents read (feed events, CLI
|
|
16
|
-
# --json output, MCP tool results). Every feed event carries it as "v".
|
|
17
|
-
SCHEMA = 1
|
|
1
|
+
"""Kache: one terminal to command all your devices.
|
|
2
|
+
|
|
3
|
+
Every device runs a gatekeeper agent (an SSH server with its own rules);
|
|
4
|
+
the Kache terminal pairs devices, shows their health, sends orders to one
|
|
5
|
+
device or all of them, and keeps a live feed of every order anyone sends.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
__version__ = "0.3.0"
|
|
9
|
+
|
|
10
|
+
# Bumped whenever devices running different Kache versions could
|
|
11
|
+
# misunderstand each other. The gatekeeper refuses orders from other
|
|
12
|
+
# protocol versions instead of guessing.
|
|
13
|
+
PROTOCOL = 1
|
|
14
|
+
|
|
15
|
+
# Version of the JSON shapes scripts and AI agents read (feed events, CLI
|
|
16
|
+
# --json output, MCP tool results). Every feed event carries it as "v".
|
|
17
|
+
SCHEMA = 1
|