opencode-thrum-pro 0.1.12 → 0.1.14
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.
- package/assets/commands/thrum-compact-extended.md +5 -0
- package/assets/commands/thrum-compact.md +5 -0
- package/assets/skills/coordinator-assessing-agent-completion/SKILL.md +17 -20
- package/assets/skills/coordinator-deploying-a-node/SKILL.md +2 -2
- package/assets/skills/coordinator-hotpath-merge-gate/SKILL.md +11 -2
- package/assets/skills/coordinator-merging-code/SKILL.md +79 -5
- package/assets/skills/coordinator-philosophy-merge-gate/SKILL.md +2 -2
- package/assets/skills/coordinator-rolling-out-to-nodes/SKILL.md +2 -2
- package/assets/skills/diagnosing-fleet-and-daemon/SKILL.md +1 -1
- package/assets/skills/implementer-receiving-dispatch/SKILL.md +1 -1
- package/assets/skills/orchestrate/SKILL.md +1 -1
- package/assets/skills/persistent-watcher-archetype/SKILL.md +24 -8
- package/assets/skills/persistent-watcher-archetype/resources/roster-watch.sh +3 -3
- package/assets/skills/project-setup/SKILL.md +7 -12
- package/assets/skills/project-setup/resources/implementation-agent.md +2 -2
- package/assets/skills/researcher-maintaining-memory/SKILL.md +1 -1
- package/assets/skills/thrum/resources/CLI_REFERENCE.md +1 -1
- package/assets/skills/thrum/resources/LISTENER_PATTERN.md +2 -2
- package/assets/skills/using-monitors/SKILL.md +156 -18
- package/assets/skills/using-tmux-ssh/SKILL.md +121 -0
- package/assets/skills/using-tmux-ssh/resources/tmux-ssh +1158 -0
- package/assets/skills/verify-against-plan/SKILL.md +1 -1
- package/dist/installer.js +3 -5
- package/package.json +1 -1
- package/assets/skills/coordinator-context-monitoring/SKILL.md +0 -685
- package/assets/skills/coordinator-post-restart-sweep/SKILL.md +0 -135
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: using-monitors
|
|
3
|
-
description: "Use when scheduling a reminder, watching a log, or running a periodic check that must reach an agent - thrum monitor start, cron --schedule, --match, --notify-on-success, --debounce, recurring nudge, script check with exit codes, why a monitor message did not arrive, how to verify a monitor delivered."
|
|
3
|
+
description: "Use when scheduling a reminder, watching a log, or running a periodic check that must reach an agent - thrum monitor start, cron --schedule, --match, --notify-on-success, --debounce, recurring nudge, plan follow-up reminder, remind me to check on my plan, check whether blockers have moved, prompt my pane on a schedule, monitor script that runs thrum tmux send, edit the script not the monitor, change a reminder without recreating the monitor, script check with exit codes, why a monitor message did not arrive, how to verify a monitor delivered."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Thrum Monitors - Reminders And Script Checks
|
|
6
|
+
# Thrum Monitors - Reminders, Pane Prompts And Script Checks
|
|
7
7
|
|
|
8
8
|
## Overview
|
|
9
9
|
|
|
@@ -14,6 +14,12 @@ kept line, a scheduled monitor sends all the lines of a run in one message. With
|
|
|
14
14
|
and restarts with backoff when it exits. Monitors persist across daemon
|
|
15
15
|
restarts and run only on the daemon that owns them.
|
|
16
16
|
|
|
17
|
+
A monitor reaches an agent in two ways. Its matched lines arrive as inbox
|
|
18
|
+
messages, read at the next inbox check. Its command can also be a script that
|
|
19
|
+
runs `thrum tmux send` to put a short prompt into the agent's own pane, which
|
|
20
|
+
starts a turn. Keep the wording and logic of anything that will change in a
|
|
21
|
+
script file: you then edit the script, and the monitor stays as it is.
|
|
22
|
+
|
|
17
23
|
Every flag below appears in `thrum monitor start --help`. Re-read the help
|
|
18
24
|
before relying on a flag not listed here.
|
|
19
25
|
|
|
@@ -32,11 +38,23 @@ thrum monitor delete <name|id>
|
|
|
32
38
|
```
|
|
33
39
|
|
|
34
40
|
- `--name`, `--match` and `--to` are required; the command follows `--`.
|
|
41
|
+
- The daemon accepts caller-relative target aliases on start/update and persists
|
|
42
|
+
the registered caller's concrete ID. Register the runtime with
|
|
43
|
+
`thrum quickstart`, or give an explicit recipient. Repair a legacy unresolved
|
|
44
|
+
alias with `thrum monitor update <id> --to @<agent>`, then restart; list/show
|
|
45
|
+
display its unresolved-target warning.
|
|
35
46
|
- `--schedule` takes a 5-field cron expression. `update --schedule` changes the
|
|
36
47
|
cron of a scheduled monitor at any time. Setting a first schedule or removing
|
|
37
48
|
it (`--schedule ""`) switches the mode, which is refused while the monitor is
|
|
38
49
|
running and allowed while it is stopped.
|
|
39
50
|
- `--debounce` is leading-edge with a 30s minimum (default 1m).
|
|
51
|
+
- `update` changes only the match, target, debounce and schedule. The command,
|
|
52
|
+
its arguments, `--cwd` and `--env` are fixed when the monitor starts, so text
|
|
53
|
+
written inline in the command can be changed only by deleting the monitor and
|
|
54
|
+
starting a new one. Text kept in a script file is changed by editing the file.
|
|
55
|
+
- `--cwd` is the working directory the command runs in (default: the directory
|
|
56
|
+
you start the monitor from). `--env` adds one `KEY=VALUE` variable to the
|
|
57
|
+
command's environment and can be repeated.
|
|
40
58
|
- `stop` leaves a stopped record that still holds the name; `delete` frees the
|
|
41
59
|
name. Use a unique name per monitor.
|
|
42
60
|
|
|
@@ -45,6 +63,11 @@ thrum monitor delete <name|id>
|
|
|
45
63
|
Each output line is tested against `--match` on its own. A line is truncated at
|
|
46
64
|
2048 bytes with a marker appended.
|
|
47
65
|
|
|
66
|
+
Read generated summaries as `<name>@<host>` and system notices as
|
|
67
|
+
`[monitor:<name>@<host>]`; an unavailable hostname omits `@<host>`.
|
|
68
|
+
Matched summaries show up to 160 characters of the deciding line; read the full
|
|
69
|
+
matched output below, within the existing output and message limits.
|
|
70
|
+
|
|
48
71
|
A scheduled (`--schedule`) job is a one-shot run, so its exit code is
|
|
49
72
|
authoritative. It delivers ONE message at exit that carries every matched line,
|
|
50
73
|
in order. A continuous job has no exit code per line, so it classifies and
|
|
@@ -52,11 +75,12 @@ delivers and classifies each matched line on its own, by its words.
|
|
|
52
75
|
|
|
53
76
|
| Scheduled job | Delivered as |
|
|
54
77
|
| --------------------------------------------------------------- | --------------------------------------------- |
|
|
55
|
-
| Non-zero exit
|
|
56
|
-
|
|
|
57
|
-
| Exit 0,
|
|
78
|
+
| Non-zero exit | `[FAIL] <name>@<host>: exit code N` with the output tail, then the matched lines |
|
|
79
|
+
| Command failed to start | `[FAIL] <name>@<host>: <start error>` with details and an inspect command |
|
|
80
|
+
| Exit 0, a matched line starts `ERROR:`, `FATAL:` or `FAIL:` | `[FAIL] <name>@<host>: <matched line>` + all matched lines |
|
|
81
|
+
| Exit 0, highest prefix is `WARN:`, `WARNING:` or `ALERT:` | `[WARN] <name>@<host>: <matched line>` + all matched lines |
|
|
58
82
|
| Exit 0, lines matched, no such prefix | All matched lines, in order, verbatim |
|
|
59
|
-
| Exit 0, nothing matched, `--notify-on-success` | `[OK] <name>: succeeded` |
|
|
83
|
+
| Exit 0, nothing matched, `--notify-on-success` | `[OK] <name>@<host>: succeeded` |
|
|
60
84
|
| Exit 0, nothing matched | Nothing (logged only) |
|
|
61
85
|
|
|
62
86
|
Cadence: the first non-zero scheduled run sends its `[FAIL]` notice; repeats of
|
|
@@ -93,8 +117,8 @@ past the retained prefix still sets the label.
|
|
|
93
117
|
|
|
94
118
|
| Continuous job (no `--schedule`) | Delivered as |
|
|
95
119
|
| --------------------------------------------------------------- | --------------------------------------------- |
|
|
96
|
-
| Contains `error`, `fatal`, `fail`, `permission denied` | `[FAIL] <name>: matched
|
|
97
|
-
| Contains `warn` or `warning` | `[WARN] <name>: matched
|
|
120
|
+
| Contains `error`, `fatal`, `fail`, `permission denied` | `[FAIL] <name>@<host>: <matched line>` + line |
|
|
121
|
+
| Contains `warn` or `warning` | `[WARN] <name>@<host>: <matched line>` + line |
|
|
98
122
|
| Contains a whole word `success`, `succeeded`, `complete`, `completed`, `done`, `ok` | Not delivered (logged only) |
|
|
99
123
|
| Any other matched line | The line, verbatim |
|
|
100
124
|
|
|
@@ -111,13 +135,25 @@ Delivery limits:
|
|
|
111
135
|
- The `[FAIL]` body for a non-zero exit carries only the last 500 bytes of
|
|
112
136
|
output, so the message that matters goes last.
|
|
113
137
|
|
|
114
|
-
##
|
|
138
|
+
## Choosing A Reminder Form
|
|
139
|
+
|
|
140
|
+
| Need | Form |
|
|
141
|
+
| ----------------------------------------------------------------- | ----------------------------- |
|
|
142
|
+
| Fixed wording, enough that it is read at the next inbox check | Inbox reminder |
|
|
143
|
+
| Must start a turn, or the wording will change as the work moves | Pane prompt through a script |
|
|
144
|
+
| A probe that reports a finding only when something is wrong | Script check |
|
|
145
|
+
|
|
146
|
+
A reminder that arrives, in the inbox or in the pane, shows the schedule fired.
|
|
147
|
+
It does not show that the work moved. Check the work itself (commits, queue,
|
|
148
|
+
state) before treating the reminder as progress.
|
|
115
149
|
|
|
116
|
-
|
|
117
|
-
|
|
150
|
+
## Inbox Reminder
|
|
151
|
+
|
|
152
|
+
An inbox reminder is a monitor whose command only prints a fixed line. Give the
|
|
153
|
+
line a stable prefix and match exactly that prefix.
|
|
118
154
|
|
|
119
155
|
```bash
|
|
120
|
-
thrum monitor start --name standup-nudge --to
|
|
156
|
+
thrum monitor start --name standup-nudge --to @<your_agent_name> \
|
|
121
157
|
--match '^REMINDER-STANDUP:' --schedule "0 9 * * 1-5" -- \
|
|
122
158
|
echo "REMINDER-STANDUP: post the status update, then reply to the open review"
|
|
123
159
|
```
|
|
@@ -128,9 +164,94 @@ thrum monitor start --name standup-nudge --to @me \
|
|
|
128
164
|
carries no action.
|
|
129
165
|
- Add `--notify-on-success` only when a delivered line must be guaranteed for a
|
|
130
166
|
run that matched nothing.
|
|
131
|
-
-
|
|
132
|
-
|
|
133
|
-
|
|
167
|
+
- An inline `echo` suits wording that will not change. For wording that will
|
|
168
|
+
change, use a pane prompt through a script.
|
|
169
|
+
|
|
170
|
+
## Pane Prompt Through A Script
|
|
171
|
+
|
|
172
|
+
Use this form for a recurring nudge that must start a turn, and for any reminder
|
|
173
|
+
whose wording follows the work. The standard case is plan follow-up: a
|
|
174
|
+
brainstormer or plan owner schedules a prompt that tells it to check how
|
|
175
|
+
implementation of its plan is going and to notify the coordinator or the
|
|
176
|
+
orchestrators working on the plan if blockers have not moved.
|
|
177
|
+
|
|
178
|
+
The monitor runs a script file. The script runs
|
|
179
|
+
`thrum tmux send <your-agent> "<prompt>"`: the daemon types the text into the
|
|
180
|
+
pane and submits it. The prompt text and all logic live in the script.
|
|
181
|
+
|
|
182
|
+
Put the script at a stable path you own, outside tracked source, that survives a
|
|
183
|
+
restart of your session. Use its absolute path in the monitor command.
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
#!/usr/bin/env bash
|
|
187
|
+
# plan-nudge.sh: prompt my own pane to follow up on my plan.
|
|
188
|
+
# Edit AGENT and PROMPT when the plan moves. The monitor stays as it is.
|
|
189
|
+
AGENT="<your-agent>"
|
|
190
|
+
PROMPT="Check how implementation of <plan> is going. If the blockers have not moved since the last check, notify the coordinator or the orchestrators working on it."
|
|
191
|
+
|
|
192
|
+
timeout 30 thrum tmux send "$AGENT" "$PROMPT" >/dev/null 2>&1
|
|
193
|
+
rc=$?
|
|
194
|
+
case "$rc" in
|
|
195
|
+
0) exit 0 ;;
|
|
196
|
+
3 | 4)
|
|
197
|
+
echo "WARN: PLAN-NUDGE send exit $rc, the prompt was typed into $AGENT but its submit is not confirmed; look at the pane"
|
|
198
|
+
exit 0
|
|
199
|
+
;;
|
|
200
|
+
*)
|
|
201
|
+
echo "PLAN-NUDGE: thrum tmux send to $AGENT failed with exit $rc"
|
|
202
|
+
exit "$rc"
|
|
203
|
+
;;
|
|
204
|
+
esac
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
chmod +x <script-dir>/plan-nudge.sh
|
|
209
|
+
<script-dir>/plan-nudge.sh # run once by hand: the prompt lands, nothing prints
|
|
210
|
+
|
|
211
|
+
thrum monitor start --name plan-nudge-<your-agent> --to @<your-agent> \
|
|
212
|
+
--match 'PLAN-NUDGE' --schedule "0 */2 * * *" --cwd <your-worktree> -- \
|
|
213
|
+
<script-dir>/plan-nudge.sh
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Exit codes of a text `thrum tmux send`, from its help:
|
|
217
|
+
|
|
218
|
+
| Exit | Meaning | Script does |
|
|
219
|
+
| ----- | ----------------------------------------------------------------- | ------------------------------------ |
|
|
220
|
+
| 0 | Delivered | Prints nothing, exits 0 |
|
|
221
|
+
| 3 | Held: the text was typed, the confirming Enter was withheld | Prints a `WARN:` line, exits 0 |
|
|
222
|
+
| 4 | Verdict unknown: Enter may or may not have been sent | Prints a `WARN:` line, exits 0 |
|
|
223
|
+
| 1 | Any other error | Prints the finding, exits non-zero |
|
|
224
|
+
|
|
225
|
+
What the monitor then delivers to `--to`, per the scheduled-job table above:
|
|
226
|
+
|
|
227
|
+
| Script outcome | Target receives |
|
|
228
|
+
| -------------------------------------- | -------------------------------------------- |
|
|
229
|
+
| Prompt delivered | Nothing in the inbox; the prompt in the pane |
|
|
230
|
+
| Exit 3 or 4 | One `[WARN]` message for that tick |
|
|
231
|
+
| Any other non-zero exit, or the `timeout` (124) | One `[FAIL] <name>@<host>: exit code N` message with the finding line |
|
|
232
|
+
|
|
233
|
+
Rules:
|
|
234
|
+
|
|
235
|
+
1. Keep the prompt to one or two sentences. It is a nudge; the plan and your
|
|
236
|
+
state hold the detail.
|
|
237
|
+
2. When the plan moves (a blocker clears, a new one appears, a different
|
|
238
|
+
orchestrator owns the work), edit the script. The next tick uses the new
|
|
239
|
+
text. Do not run `thrum monitor update` and do not delete and recreate the
|
|
240
|
+
monitor for a change of wording or logic.
|
|
241
|
+
3. Change the monitor only for what the monitor owns: `update --schedule` for a
|
|
242
|
+
new cadence, `update --to` for a new recipient of failure notices.
|
|
243
|
+
4. Bound the send with `timeout`; a hung send holds the tick.
|
|
244
|
+
5. Never call raw `tmux send-keys` from a monitor script. `thrum tmux send` is
|
|
245
|
+
the only way a script types into a pane.
|
|
246
|
+
6. Target your own pane. Prompt another agent's pane only when that agent's
|
|
247
|
+
owner asked for it.
|
|
248
|
+
7. Never send the text a second time from the script. After exit 3 or 4 the text
|
|
249
|
+
may already sit in the pane: look at the pane and submit or clear it. The
|
|
250
|
+
next tick sends again by itself.
|
|
251
|
+
8. Keep the output quiet on success. A matching line on every tick fills the
|
|
252
|
+
inbox with the reminder the pane already received.
|
|
253
|
+
9. Start the monitor with `--cwd` set to your own worktree, so the send runs
|
|
254
|
+
from the checkout that carries your identity.
|
|
134
255
|
|
|
135
256
|
## Script Check
|
|
136
257
|
|
|
@@ -138,7 +259,7 @@ A script check runs a bounded, synchronous probe and reports through its exit
|
|
|
138
259
|
code and one structured line.
|
|
139
260
|
|
|
140
261
|
```bash
|
|
141
|
-
thrum monitor start --name disk-check --to
|
|
262
|
+
thrum monitor start --name disk-check --to @<your_agent_name> \
|
|
142
263
|
--match '^CHECK-DISK:' --schedule "*/15 * * * *" -- \
|
|
143
264
|
bash -c 'u=$(df --output=pcent / | tail -1 | tr -dc 0-9)
|
|
144
265
|
[ "$u" -lt 90 ] && exit 0
|
|
@@ -146,6 +267,10 @@ thrum monitor start --name disk-check --to @me \
|
|
|
146
267
|
exit 3'
|
|
147
268
|
```
|
|
148
269
|
|
|
270
|
+
Inline `bash -c` suits a short probe whose text and threshold are fixed. Put a
|
|
271
|
+
probe whose logic, threshold or wording will change in a script file and give
|
|
272
|
+
the monitor the file's path, as in the pane prompt example.
|
|
273
|
+
|
|
149
274
|
Rules:
|
|
150
275
|
|
|
151
276
|
1. Bound every probe with `timeout <secs>`; a hung probe holds the tick.
|
|
@@ -161,7 +286,7 @@ Rules:
|
|
|
161
286
|
| Outcome | Script does | Target receives |
|
|
162
287
|
| -------- | ---------------------------------------- | ---------------------------------- |
|
|
163
288
|
| Quiet | Exit 0, no matching line | Nothing |
|
|
164
|
-
| Failure | Non-zero exit, finding line last | One `[FAIL] <name>: exit code N` message with the tail and the finding line |
|
|
289
|
+
| Failure | Non-zero exit, finding line last | One `[FAIL] <name>@<host>: exit code N` message with the tail and the finding line |
|
|
165
290
|
| Finding | Exit 0, matching line(s) | The line(s), verbatim (labeled only by an `ERROR:`/`FATAL:`/`FAIL:` or `WARN:`/`WARNING:`/`ALERT:` prefix) |
|
|
166
291
|
| Reminder | Exit 0, one stable-prefix instruction | The line, verbatim |
|
|
167
292
|
|
|
@@ -174,7 +299,7 @@ Start the monitor with a unique name, `--to` the verifying agent, and a
|
|
|
174
299
|
one-minute schedule, then read the delivered message back in full.
|
|
175
300
|
|
|
176
301
|
```bash
|
|
177
|
-
thrum monitor start --name verify-<unique> --to
|
|
302
|
+
thrum monitor start --name verify-<unique> --to @<your_agent_name> --match '^VERIFY-<unique>:' \
|
|
178
303
|
--schedule "* * * * *" -- echo "VERIFY-<unique>: delivery body check"
|
|
179
304
|
thrum inbox --unread
|
|
180
305
|
thrum message get <message-id> # the complete delivered body
|
|
@@ -186,6 +311,10 @@ Confirm the body carries the prefix, the wording and no unexpected `[FAIL]`
|
|
|
186
311
|
or `[WARN]` label. Delete the monitor when done; never alter a monitor another
|
|
187
312
|
agent owns.
|
|
188
313
|
|
|
314
|
+
A pane prompt sends nothing to the inbox when it works. Verify it by running
|
|
315
|
+
the script once by hand and seeing the prompt in the pane, then by `thrum
|
|
316
|
+
monitor show` reporting exit 0 after the first tick.
|
|
317
|
+
|
|
189
318
|
## Troubleshooting
|
|
190
319
|
|
|
191
320
|
- Nothing arrived: `thrum monitor show` for state and last exit, `thrum
|
|
@@ -196,3 +325,12 @@ agent owns.
|
|
|
196
325
|
with `ERROR:`/`FATAL:`/`FAIL:`, or (continuous job) the line contains a fail or
|
|
197
326
|
error substring.
|
|
198
327
|
- Name already in use: a stopped record holds it. `thrum monitor delete` it.
|
|
328
|
+
- Pane prompt did not appear: `thrum monitor show` for the last exit, then run
|
|
329
|
+
the script by hand. Check that the script path is absolute and executable,
|
|
330
|
+
that the agent name in the script is current, and that the monitor's
|
|
331
|
+
`--cwd` is your worktree.
|
|
332
|
+
- Pane prompt shows the old wording: the script was not saved, or the monitor
|
|
333
|
+
was started with a different script path than the one you edited.
|
|
334
|
+
- `[WARN]` naming a held or unknown send: the text may sit unsubmitted in the
|
|
335
|
+
pane. Look at the pane and submit or clear the text. Do not send the text
|
|
336
|
+
again by hand; the next tick sends it.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: using-tmux-ssh
|
|
3
|
+
description: "Use when about to ssh to a host, run a command on a VM or remote box, start a long test or build on another machine, inspect a remote log, or recover after an ssh connection dropped or a remote command timed out. Use tmux-ssh for remote commands, saved-watch resume, and concurrent observation."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Running Remote Commands With tmux-ssh
|
|
7
|
+
|
|
8
|
+
`tmux-ssh` drives one persistent SSH login per host in a local tmux pane.
|
|
9
|
+
Use it for every command on another machine or VM, short or long, including
|
|
10
|
+
remote tests, builds, and log reads. Use `--read` and `--status` to observe;
|
|
11
|
+
never use plain SSH polling or Monitor loops.
|
|
12
|
+
|
|
13
|
+
## Resolve the bundled executable
|
|
14
|
+
|
|
15
|
+
Resolve `resources/tmux-ssh` relative to the active `using-tmux-ssh` skill
|
|
16
|
+
folder supplied by your runtime. Set `TMUX_SSH` to that absolute executable
|
|
17
|
+
path, then read its live help:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
TMUX_SSH='/absolute/path/to/using-tmux-ssh/resources/tmux-ssh'
|
|
21
|
+
"$TMUX_SSH" --help
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The runtime's loaded plugin root contains
|
|
25
|
+
`skills/using-tmux-ssh/resources/tmux-ssh` for Claude, Codex, Cursor, and Muse;
|
|
26
|
+
OpenCode contains `assets/skills/using-tmux-ssh/resources/tmux-ssh`. Locate the
|
|
27
|
+
root from the active skill's path rather than assuming plugin root environment
|
|
28
|
+
variables are set in an interactive shell. Nothing else from Thrum is
|
|
29
|
+
required; local `tmux` and `ssh` must be installed.
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
The examples below invoke the resolved executable through `"$TMUX_SSH"`. `HOST` is an
|
|
34
|
+
SSH config alias or `user@host`.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
"$TMUX_SSH" HOST # connect if needed; print status
|
|
38
|
+
"$TMUX_SSH" HOST 'uname -a' # finite command; return its exit code
|
|
39
|
+
"$TMUX_SSH" HOST --timeout 900 'make test' # bounded observation, in seconds
|
|
40
|
+
"$TMUX_SSH" HOST --resume --timeout 900 # continue the saved watch; never resend
|
|
41
|
+
"$TMUX_SSH" HOST --status # session and recorded state
|
|
42
|
+
"$TMUX_SSH" HOST --read --settle # screen; usable during another call
|
|
43
|
+
"$TMUX_SSH" HOST --abort # deliberately interrupt and clear the watch
|
|
44
|
+
"$TMUX_SSH" HOST --kill # close SSH and clear saved state
|
|
45
|
+
|
|
46
|
+
"$TMUX_SSH" HOST --send 'top' # interactive program
|
|
47
|
+
"$TMUX_SSH" HOST --read
|
|
48
|
+
"$TMUX_SSH" HOST --send --key C-c
|
|
49
|
+
|
|
50
|
+
"$TMUX_SSH" HOST "tmux new -d -s JOB 'long-command >job.log 2>&1'"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Run mode waits for a command that ends. For editors, REPLs, attached tmux,
|
|
54
|
+
and other programs that stay open, use `--send`/`--read`. Run mode refuses
|
|
55
|
+
obvious interactive commands with code 2; use `--force-run` only deliberately.
|
|
56
|
+
`--send` types into the current program and refuses a dead session rather
|
|
57
|
+
than reconnecting and losing interactive state.
|
|
58
|
+
|
|
59
|
+
Quote remote commands locally so variables expand on the intended machine.
|
|
60
|
+
They execute in the remote login shell, which may be zsh; invoke `bash` for
|
|
61
|
+
Bash syntax. For long or complex content, transfer a script using `scp` or
|
|
62
|
+
`rsync` with the same connection options, then run a short command through
|
|
63
|
+
`tmux-ssh`. The wrapper transports commands, not files.
|
|
64
|
+
|
|
65
|
+
## Rules
|
|
66
|
+
|
|
67
|
+
- **One command per host session.** Mutating calls share a local per-host lock
|
|
68
|
+
and wait up to 30 seconds by default. `--read` and `--status` observe without
|
|
69
|
+
that lock. Coordinate drivers across machines or different `TMUX_SSH_DIR`
|
|
70
|
+
values; these do not provide a global lock.
|
|
71
|
+
- **Resume observation, never resubmit a queued or visible command.** Code 124
|
|
72
|
+
ends the wait; the command may still be running or waiting for input. Use
|
|
73
|
+
`--read`, then `--resume`, which retains the watch and never sends the command
|
|
74
|
+
again. Resume reuses the original timeout unless overridden. Other run calls
|
|
75
|
+
refuse while a watch remains.
|
|
76
|
+
- **Interrupt deliberately.** `--interrupt-on-timeout` sends Ctrl-C when the
|
|
77
|
+
wait expires. `--abort` sends Ctrl-C and clears the watch; code 0 reports a
|
|
78
|
+
ready/finished/gone session, code 1 means the shell did not answer. Inspect
|
|
79
|
+
`--read` before further input. An abort receipt does not prove job success.
|
|
80
|
+
- **Give long jobs an independent remote lifecycle.** Use detached remote
|
|
81
|
+
tmux, retaining the job name and logs. An ordinary call can reconnect a dead
|
|
82
|
+
SSH session, but a drop during foreground execution leaves completion unknown
|
|
83
|
+
and may terminate that command. Check the job and its results before deciding
|
|
84
|
+
to retry. `--kill` closes SSH; it does not stop an independent remote job.
|
|
85
|
+
- **Interpret the diagnostic and completion evidence.** Remote command exit
|
|
86
|
+
codes are passed through and can overlap wrapper codes. Wrapper code 124 is
|
|
87
|
+
a wait timeout; 125 is refusal or 'completion unknown', so it alone cannot
|
|
88
|
+
prove nothing ran; 2 is a usage error; 3 means input state UNKNOWN after a
|
|
89
|
+
failed keystroke, dropped send, or failed watch persistence. Code 3 guards
|
|
90
|
+
later typing until `--kill`; `--read`, `--status`, and `--resume` still work.
|
|
91
|
+
Do not blindly retry unknown completion or input, or kill another driver's
|
|
92
|
+
session or lock merely because it looks stuck.
|
|
93
|
+
|
|
94
|
+
## Connection options and pool leases
|
|
95
|
+
|
|
96
|
+
Obtain the key, known-hosts file, target address, and actual remote OS hostname
|
|
97
|
+
from the current lease. Keep these values outside the skill.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
TMUX_SSH_OPTS='-i /path/to/lease-key -o IdentitiesOnly=yes -o UserKnownHostsFile=/path/to/lease-known-hosts -o StrictHostKeyChecking=yes' \
|
|
101
|
+
TMUX_SSH_EXPECT_HOST='<remote-os-hostname>' \
|
|
102
|
+
"$TMUX_SSH" user@<lease-address> 'uname -a'
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Options precede built-in defaults, so SSH's first `-o` wins. Allowed characters
|
|
106
|
+
are letters, digits, spaces, and `- _ . / = : , @ ~ + %`; paths cannot contain
|
|
107
|
+
spaces. A live session retains its original options: deliberately close it
|
|
108
|
+
with `--kill` before changing them. `--help`, `--status`, and `--kill` work
|
|
109
|
+
with invalid options. `--expect-host` overrides `TMUX_SSH_EXPECT_HOST` and
|
|
110
|
+
matches short/FQDN hostname forms case-insensitively; the SSH alias need not
|
|
111
|
+
match the OS hostname.
|
|
112
|
+
|
|
113
|
+
## Execution identity checks
|
|
114
|
+
|
|
115
|
+
SSH is the pane's own process; a dropped connection leaves a dead pane, not a
|
|
116
|
+
local shell. Run mode checks a live SSH pane, probes the recorded hostname,
|
|
117
|
+
and wraps execution with a hostname check. Interactive input checks the live
|
|
118
|
+
SSH pane because a program may own stdin. These checks catch mistaken targets;
|
|
119
|
+
they are not an adversarial security boundary. Remote targets reporting the
|
|
120
|
+
local hostname are refused; explicit `localhost`/`127.0.0.1` aliases permit
|
|
121
|
+
intentional local use.
|