spec: update spec
- new "p worker" command wrapping register/workers/default - tmux session updates
This commit is contained in:
143
SPEC.md
143
SPEC.md
@@ -41,7 +41,14 @@ Communication happens over SSH port forwarding — no extra open ports needed.
|
|||||||
p -- <command>
|
p -- <command>
|
||||||
```
|
```
|
||||||
Sync the current directory to the default worker and run `<command>` on it.
|
Sync the current directory to the default worker and run `<command>` on it.
|
||||||
Attaches to the job's output by default. `Ctrl+C` detaches without killing the job.
|
Attaches to the job's tmux session immediately. `Ctrl+B D` detaches without
|
||||||
|
killing the job. `Ctrl+C` sends SIGINT to the running process (standard behavior).
|
||||||
|
|
||||||
|
When the job finishes, the session stays open and displays:
|
||||||
|
```
|
||||||
|
--- Job done [exit 0]. Press any key to detach. ---
|
||||||
|
```
|
||||||
|
This lets the user read final output before returning to their shell.
|
||||||
|
|
||||||
```
|
```
|
||||||
p <worker> -- <command>
|
p <worker> -- <command>
|
||||||
@@ -65,7 +72,10 @@ command, status, duration. Style inspired by `docker ps` / `lxc list`.
|
|||||||
```
|
```
|
||||||
p attach <job-id>
|
p attach <job-id>
|
||||||
```
|
```
|
||||||
Re-attach to the console of a running job (via tmux). Supports partial IDs.
|
Re-attach to the tmux session of a running job. Supports partial IDs.
|
||||||
|
Behaves identically to the initial attach: `Ctrl+B D` detaches, and if the job
|
||||||
|
has already finished the "press any key" screen is shown.
|
||||||
|
Only works on **running** jobs. For finished jobs, use `p logs`.
|
||||||
|
|
||||||
```
|
```
|
||||||
p logs <job-id>
|
p logs <job-id>
|
||||||
@@ -90,26 +100,33 @@ p rm <job-id>
|
|||||||
Remove a job record and its remote work directory. Refuses to remove a
|
Remove a job record and its remote work directory. Refuses to remove a
|
||||||
running job without `--force`.
|
running job without `--force`.
|
||||||
|
|
||||||
### Workers
|
### Worker management
|
||||||
|
|
||||||
```
|
```
|
||||||
p register [<name>] <connection-string>
|
p worker register <connection-string> [-n <name>]
|
||||||
```
|
```
|
||||||
Register a worker. The connection string is an SSH target (`user@host`,
|
Register a worker. The connection string is an SSH target (`user@host`,
|
||||||
`user@host:port`, or an SSH config alias). If `<name>` is omitted, the
|
`user@host:port`, or an SSH config alias). If `-n` is omitted, the hostname
|
||||||
hostname is used. The first registered worker becomes the default.
|
is used as the name. The first registered worker becomes the default.
|
||||||
|
|
||||||
```
|
```
|
||||||
p workers
|
p worker ls
|
||||||
```
|
```
|
||||||
List registered workers with their name, connection string, and reachability
|
List registered workers with their name and connection string.
|
||||||
status.
|
Pass `--check` / `-c` to also probe reachability over SSH (slow).
|
||||||
|
|
||||||
```
|
```
|
||||||
p default <worker>
|
p worker rm <name>
|
||||||
|
```
|
||||||
|
Unregister a worker. Refuses if the worker has running jobs.
|
||||||
|
|
||||||
|
```
|
||||||
|
p worker default <name>
|
||||||
```
|
```
|
||||||
Set the default worker.
|
Set the default worker.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Directory Sync
|
## Directory Sync
|
||||||
|
|
||||||
- Uses `rsync` over SSH.
|
- Uses `rsync` over SSH.
|
||||||
@@ -121,6 +138,63 @@ Set the default worker.
|
|||||||
- No automatic sync-back after job completion. Use `p pull` to retrieve
|
- No automatic sync-back after job completion. Use `p pull` to retrieve
|
||||||
specific artifacts.
|
specific artifacts.
|
||||||
|
|
||||||
|
## Attach / Detach Mechanics
|
||||||
|
|
||||||
|
Jobs run inside a `tmux` session on the worker. `p` attaches to the session
|
||||||
|
immediately after starting the job.
|
||||||
|
|
||||||
|
### Status bar
|
||||||
|
The tmux session has a custom status bar showing:
|
||||||
|
```
|
||||||
|
p-<short-id> beefy make [running] 0:02:14
|
||||||
|
```
|
||||||
|
Fields: job short-ID, worker name, command (truncated), status, elapsed time.
|
||||||
|
|
||||||
|
### Key bindings while attached
|
||||||
|
| Key | Effect |
|
||||||
|
|---|---|
|
||||||
|
| `Ctrl+B D` | Detach from session. Job keeps running. |
|
||||||
|
| `Ctrl+C` | Sends SIGINT to the foreground process (standard terminal behavior). |
|
||||||
|
|
||||||
|
### On job completion
|
||||||
|
When the job's process exits, `run.sh` writes the exit code and then displays:
|
||||||
|
```
|
||||||
|
--- Job done [exit 0]. Press any key to detach. ---
|
||||||
|
```
|
||||||
|
The tmux session stays open (`remain-on-exit on` for the window) so the user
|
||||||
|
can scroll through final output. Pressing any key detaches the client and
|
||||||
|
returns to the local shell. `p` then reads the exit code and prints a summary.
|
||||||
|
|
||||||
|
### `p attach` on a finished job
|
||||||
|
If the job has already finished and the tmux session is still open (user has
|
||||||
|
not yet pressed a key), `p attach` reconnects to the "press any key" screen.
|
||||||
|
Once the key is pressed, the session closes. For a fully-closed session, use
|
||||||
|
`p logs` instead.
|
||||||
|
|
||||||
|
> **Worker requirements:** `tmux` and `rsync` must be available on the worker
|
||||||
|
> (standard on most Linux systems). The `p-agent` binary is auto-uploaded by `p`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Job Status & Notification
|
||||||
|
|
||||||
|
The **p-agent** runs as a lightweight background process on the worker
|
||||||
|
(started automatically, not a system service). It:
|
||||||
|
|
||||||
|
- Manages job launch and tmux session creation
|
||||||
|
- Tees output to `output.log`
|
||||||
|
- Writes `exitcode` on completion
|
||||||
|
- Notifies the client over the SSH reverse tunnel when a job finishes
|
||||||
|
|
||||||
|
The client maintains a local job database (`~/.local/share/p/jobs/<uuid>.json`)
|
||||||
|
mirroring job state. `p ls` reads from this local store (fast, no SSH),
|
||||||
|
updated in real time while attached, and via agent notifications otherwise.
|
||||||
|
|
||||||
|
### Degraded mode (agent unreachable / client was offline)
|
||||||
|
If the client missed a completion notification, `p ls` marks affected jobs as
|
||||||
|
`unknown`. The next `p ls` SSH-polls all workers with known-running jobs to
|
||||||
|
reconcile state.
|
||||||
|
|
||||||
## Worker-side Layout
|
## Worker-side Layout
|
||||||
|
|
||||||
All data lives under `~/.p/` on the worker (no root access required).
|
All data lives under `~/.p/` on the worker (no root access required).
|
||||||
@@ -142,47 +216,13 @@ All data lives under `~/.p/` on the worker (no root access required).
|
|||||||
<uuid>/ # rsync'd copy of client CWD for this job
|
<uuid>/ # rsync'd copy of client CWD for this job
|
||||||
```
|
```
|
||||||
|
|
||||||
## Attach / Detach Mechanics
|
|
||||||
|
|
||||||
Jobs run inside a `tmux` session on the worker (requirement: `tmux` must be
|
|
||||||
installed on the worker). Output is simultaneously captured to `output.log`
|
|
||||||
via `tmux pipe-pane` or a `tee` wrapper.
|
|
||||||
|
|
||||||
- `p attach <id>` → `ssh -t worker "tmux attach -t p-<id>"`
|
|
||||||
- `Ctrl+C` while attached → sends detach signal to tmux, **not** SIGINT to
|
|
||||||
the job. The job keeps running.
|
|
||||||
- `p attach` only works on **running** jobs. For finished jobs, use `p logs`.
|
|
||||||
|
|
||||||
> **Note:** `tmux` is the only required dependency on the worker beyond a
|
|
||||||
> standard POSIX environment. The `p-agent` binary and `rsync` are also
|
|
||||||
> required; `p` ensures the agent is present automatically. `rsync` must be
|
|
||||||
> available on the worker (standard on most Linux systems).
|
|
||||||
|
|
||||||
## Job Status & Notification
|
|
||||||
|
|
||||||
The **p-agent** runs as a lightweight background process on the worker
|
|
||||||
(started automatically, not a system service). It:
|
|
||||||
|
|
||||||
- Manages job launch and tmux session creation
|
|
||||||
- Tees output to `output.log`
|
|
||||||
- Writes `exitcode` on completion
|
|
||||||
- Notifies the client over the SSH reverse tunnel when a job finishes
|
|
||||||
|
|
||||||
The client maintains a local job database (`~/.local/share/p/jobs.db`,
|
|
||||||
SQLite) mirroring job state. `p ls` reads from this local DB (fast, no SSH),
|
|
||||||
updated in real time while attached, and via agent notifications otherwise.
|
|
||||||
|
|
||||||
### Degraded mode (agent unreachable / client was offline)
|
|
||||||
If the client missed a completion notification, `p ls` marks affected jobs as
|
|
||||||
`unknown`. Running the next `p ls` SSH-polls all
|
|
||||||
workers with known-running jobs to reconcile state.
|
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
File: `~/.config/p/config.yaml`
|
File: `~/.config/p/config.yaml`
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
default_worker = "beefy"
|
default_worker: beefy
|
||||||
workers:
|
workers:
|
||||||
- name: beefy
|
- name: beefy
|
||||||
connection: user@192.168.1.50
|
connection: user@192.168.1.50
|
||||||
@@ -194,9 +234,10 @@ workers:
|
|||||||
|
|
||||||
```
|
```
|
||||||
ID WORKER CWD COMMAND STATUS DURATION
|
ID WORKER CWD COMMAND STATUS DURATION
|
||||||
a3f2 beefy ~/projects/foo make running 0:02:14
|
-------- ------ --------------- --------------- --------- --------
|
||||||
7c91 beefy ~/projects/bar cargo test done [0] 0:01:03
|
a3f2b091 beefy ~/projects/foo make running 0:02:14
|
||||||
b004 cloud ~/scripts ./bench.sh done [1] 0:00:47
|
7c91d302 beefy ~/projects/bar cargo test done [0] 0:01:03
|
||||||
|
b004f123 cloud ~/scripts ./bench.sh done [1] 0:00:47
|
||||||
```
|
```
|
||||||
|
|
||||||
## Open Questions
|
## Open Questions
|
||||||
@@ -216,4 +257,8 @@ b004 cloud ~/scripts ./bench.sh done [1] 0:00:47
|
|||||||
should prompt to clean up.
|
should prompt to clean up.
|
||||||
|
|
||||||
- **Non-Linux workers**: tmux availability and path conventions may differ on
|
- **Non-Linux workers**: tmux availability and path conventions may differ on
|
||||||
macOS workers. Out of scope for Phase 1.
|
macOS workers. Out of scope for now.
|
||||||
|
|
||||||
|
- **Ctrl+C → detach** (future): it would be nicer if Ctrl+C detached the
|
||||||
|
session instead of sending SIGINT to the job, matching the spirit of the
|
||||||
|
tool. This requires per-session tmux key table configuration and is deferred.
|
||||||
|
|||||||
Reference in New Issue
Block a user