@hediet/linkrpc-cli 0.0.3-next.20261008.2 → 0.0.3-next.20261021.2
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/README.md +452 -8
- package/dist/chunks/{cli-JE4URhh3.js → cli-CO0iSiY_.js} +3328 -743
- package/dist/chunks/cli-CO0iSiY_.js.map +1 -0
- package/dist/chunks/{runApprovalUi-BFI84eck.js → runApprovalUi-BVAPyMfz.js} +3 -4
- package/dist/chunks/{runApprovalUi-BFI84eck.js.map → runApprovalUi-BVAPyMfz.js.map} +1 -1
- package/dist/chunks/{runComplete-DvUneaDU.js → runComplete-B3b-UhnA.js} +860 -37
- package/dist/chunks/runComplete-B3b-UhnA.js.map +1 -0
- package/dist/chunks/{runUi-BNCT8zwR.js → runUi-BrFeYazs.js} +5 -6
- package/dist/chunks/{runUi-BNCT8zwR.js.map → runUi-BrFeYazs.js.map} +1 -1
- package/dist/chunks/{scroll-CY9Rcshb.js → scroll-D3Yj8rjk.js} +2 -2
- package/dist/chunks/{scroll-CY9Rcshb.js.map → scroll-D3Yj8rjk.js.map} +1 -1
- package/dist/chunks/src-ConeU7vr.js +821 -0
- package/dist/chunks/src-ConeU7vr.js.map +1 -0
- package/dist/daemon.d.ts +1 -0
- package/dist/daemon.js +5732 -0
- package/dist/daemon.js.map +1 -0
- package/dist/hub.js +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/linkrpc.js +1 -1
- package/dist/rpc.js +1 -1
- package/package.json +11 -7
- package/dist/chunks/cli-JE4URhh3.js.map +0 -1
- package/dist/chunks/dist-BOcSU4-O.js +0 -1500
- package/dist/chunks/dist-BOcSU4-O.js.map +0 -1
- package/dist/chunks/runComplete-DvUneaDU.js.map +0 -1
package/README.md
CHANGED
|
@@ -9,6 +9,284 @@ interfaces (`hubrpc.defaults`, `hubrpc.directory`, `hubrpc.schemas`) are
|
|
|
9
9
|
used to discover what the endpoint exposes. Generic RPC commands work with any
|
|
10
10
|
reflected interface; compiled-in views add specialized CLI and TUI renderers.
|
|
11
11
|
|
|
12
|
+
## Daemon-owned endpoints (`hub services`)
|
|
13
|
+
|
|
14
|
+
`hub services` manages processes and existing connections **through the daemon
|
|
15
|
+
management RPC API**, including on the local machine. The CLI may bootstrap a
|
|
16
|
+
local per-user daemon, but never supervises the managed workload itself.
|
|
17
|
+
|
|
18
|
+
The daemon executable and implementation are bundled in this package's `dist/`
|
|
19
|
+
(`daemon.js`). Installing the CLI does not require publishing or installing
|
|
20
|
+
`@hediet/linkrpc-hub-daemon` separately. The daemon source package is a build-only
|
|
21
|
+
workspace dependency; bootstrap launches the bundled executable with Node.js.
|
|
22
|
+
|
|
23
|
+
Before using a daemon, the CLI checks its `requiredInterfaces` against the
|
|
24
|
+
interface IDs and hashes advertised through reflection. Each required hash must
|
|
25
|
+
be supported; no package/protocol version or automatic update policy is used.
|
|
26
|
+
A legacy daemon without reflection, a missing interface, or a different hash
|
|
27
|
+
fails with an actionable error before the workload is created:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
hub services restart
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This explicit command sends the local daemon's management `shutdown` RPC,
|
|
34
|
+
waits for exit, starts the CLI's bundled daemon, and rechecks its interfaces.
|
|
35
|
+
It disconnects Hub clients and stops workloads. Ephemeral endpoints disappear;
|
|
36
|
+
persistent definitions retain their existing restart/desired-state semantics.
|
|
37
|
+
It does **not** modify OS autostart registrations. A selected endpoint/config or
|
|
38
|
+
routed manager is never silently replaced: update it on its execution host, or
|
|
39
|
+
explicitly select the default local daemon with
|
|
40
|
+
`hub --context :empty --no-use-env services restart`.
|
|
41
|
+
|
|
42
|
+
OS autostart integration for `hub services` is postponed. Bootstrap/restart
|
|
43
|
+
does not invoke the OS service manager, and persistent endpoint creation does
|
|
44
|
+
not enable login startup. Existing registrations are left untouched and may
|
|
45
|
+
still start a different build at the next login.
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
# Create a context explicitly and run attached (daemon-owned lifetime):
|
|
49
|
+
hub services run --new-context . -- node server.js
|
|
50
|
+
|
|
51
|
+
# Bind the service lifetime to this terminal's CLI process:
|
|
52
|
+
hub services run --foreground --id temporary -- node server.js
|
|
53
|
+
|
|
54
|
+
# Another terminal in this context:
|
|
55
|
+
hub services list
|
|
56
|
+
hub ls
|
|
57
|
+
hub services logs --follow
|
|
58
|
+
|
|
59
|
+
# Detach an attached pipe console with Ctrl+D on an empty line.
|
|
60
|
+
# Or launch detached from the outset:
|
|
61
|
+
hub services run --id worker --detach -- node worker.js
|
|
62
|
+
hub services attach --id worker
|
|
63
|
+
hub services stop --id worker
|
|
64
|
+
|
|
65
|
+
# Run in a pseudoterminal (TTY); detach with Ctrl+B, then d:
|
|
66
|
+
hub services run -x -t --id shell -- pwsh
|
|
67
|
+
|
|
68
|
+
# Stop and replace an existing endpoint with the same ID:
|
|
69
|
+
hub services run --force --id worker --detach -- node worker.js
|
|
70
|
+
|
|
71
|
+
# Retain a definition and resume it when the daemon next starts:
|
|
72
|
+
hub services run --id worker --persistent --restart on-failure --detach -- node worker.js
|
|
73
|
+
hub services configure --id worker --restart always
|
|
74
|
+
hub services stop --id worker # stays stopped across daemon restarts
|
|
75
|
+
hub services start --id worker
|
|
76
|
+
hub services remove --id worker
|
|
77
|
+
|
|
78
|
+
# Connect rather than spawn (URI is interpreted on the daemon host):
|
|
79
|
+
hub services connect --id peer --target-endpoint ws://localhost:7000 --restart on-failure
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
`--id` defaults to `main`. Namespace defaults to the selected context's canonical
|
|
83
|
+
folder path (case-normalized on Windows), its named context identity (`id:<name>`),
|
|
84
|
+
or `:root` where no folder context applies. The `:empty` context has no namespace.
|
|
85
|
+
Override it with `hub services --namespace <name> ...`. `--namespace` belongs
|
|
86
|
+
only to `services`; it does not select or filter services for `call`, `ls`, or
|
|
87
|
+
`ui`. `--context` only selects an existing context;
|
|
88
|
+
`--new-context .` creates one before the attached command starts. A namespace
|
|
89
|
+
does not determine a remote working directory.
|
|
90
|
+
|
|
91
|
+
Definitions default to ephemeral: they disappear after stop, completion, or
|
|
92
|
+
terminal failure. `--persistent` retains a definition. `--restart` is `never`
|
|
93
|
+
(default), `on-failure`, or `always`; for connections, disconnect counts as
|
|
94
|
+
failure. Persistent restarting endpoints resume when the daemon next starts,
|
|
95
|
+
unless explicitly stopped. This does not arrange for the daemon itself to start
|
|
96
|
+
after OS restart. Persistent `never` definitions remain stopped after daemon
|
|
97
|
+
restart.
|
|
98
|
+
|
|
99
|
+
Endpoint selection keeps the usual explicit flag / environment / context
|
|
100
|
+
precedence, including `HUBRPC_*` aliases. An explicit `--context` suppresses the
|
|
101
|
+
ambient endpoint unless `--use-env` is passed. On an effective Hub connection,
|
|
102
|
+
the manager defaults to `<hubServiceId>/daemon`; override with
|
|
103
|
+
`--daemon-service`. Both that option and `--namespace` can be saved using
|
|
104
|
+
`context set`. An unreachable or unauthorized selected manager is an error,
|
|
105
|
+
**never** a fallback to local execution.
|
|
106
|
+
|
|
107
|
+
```sh
|
|
108
|
+
hub --endpoint ws://remote-host:7000 --daemon-service remote/daemon \
|
|
109
|
+
--context . services run --id worker --cwd /srv/project --detach -- node worker.js
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Remote launches require `--cwd` on the execution host. Commands, files, and
|
|
113
|
+
environment values are not uploaded. Arguments after `--` are an executable
|
|
114
|
+
and argv, not a shell command string. Execution host, namespace, ID, command,
|
|
115
|
+
and working directory are printed before creation. Local fallback is used only
|
|
116
|
+
when no endpoint/config is selected. `run`, `connect`, and `start` may bootstrap
|
|
117
|
+
the local daemon; reads never do. Without a selected endpoint, `hub ls`, `call`,
|
|
118
|
+
and other connected commands (including `ui`) use the local Hub whenever its
|
|
119
|
+
daemon runs, whether or not any services do. If it is not running, the command
|
|
120
|
+
reports an error without starting the daemon. A configured endpoint that fails
|
|
121
|
+
never falls back to the local Hub.
|
|
122
|
+
Use the full `serviceId` returned by `services list` for RPC
|
|
123
|
+
calls; endpoint IDs and published RPC service IDs are different things.
|
|
124
|
+
|
|
125
|
+
Process readiness defaults to connecting to the provided `LINKRPC_ENDPOINT`
|
|
126
|
+
and token. Use `--no-rpc` (short form `-x`) for non-LinkRPC programs: they become
|
|
127
|
+
ready on spawn, without a participant socket or managed identity. Ambient
|
|
128
|
+
`LINKRPC_ENDPOINT`/`LINKRPC_TOKEN` and legacy `HUBRPC_*` connection variables
|
|
129
|
+
are not inherited in this mode; explicitly supplied `--env` values are preserved.
|
|
130
|
+
`--readiness spawned` alone still provisions RPC, but does not wait for connection.
|
|
131
|
+
`--no-rpc --readiness connected` is an error. Detached launches
|
|
132
|
+
wait up to 30 seconds for readiness; a timeout leaves the endpoint managed and
|
|
133
|
+
inspectable. Attachments stream bounded recent output and supervisor notices,
|
|
134
|
+
forward input and interrupts, and do not own the process lifetime. `logs`
|
|
135
|
+
prints recent output; `logs --follow` keeps streaming; `attach --read-only`
|
|
136
|
+
observes without sending input.
|
|
137
|
+
|
|
138
|
+
Every process endpoint has a console that implements the standard
|
|
139
|
+
[`linkrpc.console.v1`](../linkrpc-infra/README.md#process-consoles-linkrpcconsole)
|
|
140
|
+
interface template: the daemon's management interface contains one template
|
|
141
|
+
instance, `consoles`, whose params are the endpoint address. `hub services attach`
|
|
142
|
+
calls it directly. The generic `attach` command works with **any** participant
|
|
143
|
+
that instantiates the template, not only daemon-managed processes. It discovers
|
|
144
|
+
consoles through the `linkrpc.console` directory tag and reads the wire methods
|
|
145
|
+
and params schema from reflection:
|
|
146
|
+
|
|
147
|
+
```sh
|
|
148
|
+
hub attach # list consoles and their params schemas
|
|
149
|
+
hub attach hub/daemon --params '{"namespace":"d:\\work\\app","id":"main"}'
|
|
150
|
+
rpc --endpoint ws://localhost:7000 attach my/service --read-only
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
`--params` (default `{}`) is validated against the instance's reflected params
|
|
154
|
+
schema. When a service has several console instances, select one with
|
|
155
|
+
`--instance` or `--interface`.
|
|
156
|
+
|
|
157
|
+
#### Pipe and TTY consoles
|
|
158
|
+
|
|
159
|
+
Processes default to a **pipe console**: stdout and stderr stay separate, and
|
|
160
|
+
the program sees no terminal. `-t` / `--tty` runs it in a pseudoterminal
|
|
161
|
+
(ConPTY on Windows) instead: output is a single terminal stream, programs enable
|
|
162
|
+
colors, prompts, and full-screen interfaces, and attachments can resize it. The
|
|
163
|
+
TTY adopts the size of the most recent interactive attachment. Joining
|
|
164
|
+
attachments receive the **current screen** (rendered by a headless terminal in
|
|
165
|
+
the daemon, including scrollback) instead of a raw byte replay, so full-screen
|
|
166
|
+
programs display correctly.
|
|
167
|
+
|
|
168
|
+
| | Pipe console | TTY console (`-t`) |
|
|
169
|
+
| --- | --- | --- |
|
|
170
|
+
| Local input | Line editing; Enter sends the line | Raw: every key goes to the program |
|
|
171
|
+
| Ctrl+C | Interrupts (sends SIGINT where supported), or stops a foreground owner | Goes to the program (an interrupt in a shell) |
|
|
172
|
+
| Ctrl+D | On an empty line: detach, or stop a foreground owner | Goes to the program (EOF in a shell) |
|
|
173
|
+
| Detach | Ctrl+D on an empty line (Ctrl+] also works) | The detach keys: Ctrl+B, then d by default |
|
|
174
|
+
|
|
175
|
+
TTY detach keys use Docker's `--detach-keys` syntax: comma-separated keys, each
|
|
176
|
+
a character or `ctrl-<key>` (`a`-`z`, `@`, `[`, `\`, `]`, `^`, `_`). The default
|
|
177
|
+
is `ctrl-b,d`, tmux's binding. Docker's `ctrl-p,ctrl-q` does not work in VS
|
|
178
|
+
Code's integrated terminal, which handles Ctrl+P (Quick Open) and, on Windows,
|
|
179
|
+
Ctrl+Q itself; Ctrl+B passes through. Keys of an incomplete sequence are held
|
|
180
|
+
back and forwarded unchanged when the sequence does not complete. Change the
|
|
181
|
+
sequence per command or store it in a context:
|
|
182
|
+
|
|
183
|
+
```sh
|
|
184
|
+
hub --detach-keys ctrl-p,ctrl-q services attach --id shell
|
|
185
|
+
hub context set --detach-keys 'ctrl-],q' # store it in the active context
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Choose another sequence when the attached program uses Ctrl+B itself, for
|
|
189
|
+
example tmux running inside the console.
|
|
190
|
+
|
|
191
|
+
Windows pipes have no interrupt channel: there, Ctrl+C in a pipe attachment
|
|
192
|
+
prints a hint instead of terminating the shared process; use `-t` when the
|
|
193
|
+
program should receive Ctrl+C. When a TTY attachment ends, the CLI resets
|
|
194
|
+
terminal modes the program may have enabled (mouse, bracketed paste, alternate
|
|
195
|
+
screen). Piped input is forwarded as received; EOF on a pipe does not cancel the
|
|
196
|
+
attachment or stop the service, so it can continue producing output.
|
|
197
|
+
|
|
198
|
+
The attached-console banner prints a `hub services attach ...` command for
|
|
199
|
+
reattaching, and detaching prints it again. Duplicate `run`/`connect` errors
|
|
200
|
+
print the same recovery command without stopping or replacing the existing
|
|
201
|
+
endpoint, and point to `--force`. Hints include the selected
|
|
202
|
+
context, namespace, endpoint ID, environment policy, and explicit connection
|
|
203
|
+
overrides. Reuse the same environment when `--use-env` is shown and the same
|
|
204
|
+
working directory for relative connection/config paths. Explicit tokens and
|
|
205
|
+
command-environment values are replaced with `<same ...>` placeholders rather
|
|
206
|
+
than exposed in the hint.
|
|
207
|
+
|
|
208
|
+
`--force` stops an existing endpoint with the same address and replaces it with
|
|
209
|
+
the new definition in one daemon operation. This also applies to persistent
|
|
210
|
+
endpoints (their stored definition is replaced) and to a foreground endpoint
|
|
211
|
+
owned by another terminal: that terminal prints a notice and its command ends.
|
|
212
|
+
|
|
213
|
+
`run --foreground` instead creates the process inside a lifetime-owning
|
|
214
|
+
management RPC. Ctrl+C, SIGTERM, cancellation, or a detected CLI disconnect
|
|
215
|
+
causes the daemon to stop the process tree and remove the endpoint, even when
|
|
216
|
+
the CLI is forcibly killed and cannot run an exit handler. On a remote Hub,
|
|
217
|
+
cleanup begins once the disconnect is detected. The normal graceful stop
|
|
218
|
+
timeout applies when a stop request can be delivered: SIGTERM on POSIX or
|
|
219
|
+
disconnecting an active RPC connection. On Windows, a process without an
|
|
220
|
+
RPC connection has no graceful stop channel, so its tree is terminated
|
|
221
|
+
immediately instead of waiting out an idle five-second timeout.
|
|
222
|
+
|
|
223
|
+
Other terminals can discover/call RPC services and attach as observers; closing
|
|
224
|
+
an observer does not stop it. The detach key of the owning terminal (Ctrl+D on
|
|
225
|
+
an empty line, or the TTY detach keys) cancels the foreground command and
|
|
226
|
+
therefore stops the service, rather than detaching it.
|
|
227
|
+
`--foreground` conflicts with `--detach` and `--persistent`; the management API
|
|
228
|
+
also rejects making a foreground endpoint persistent later. Restart policies
|
|
229
|
+
apply only while the owning call is alive. Hub replacement stops foreground
|
|
230
|
+
endpoints rather than restoring them without an owner. Ordinary `run` and
|
|
231
|
+
`attach` retain their daemon-owned lifetime behavior.
|
|
232
|
+
|
|
233
|
+
With a pipe console, interactive terminals use local line editing: with
|
|
234
|
+
unfinished text, Ctrl+D retains the line and uses normal delete-under-cursor
|
|
235
|
+
behavior.
|
|
236
|
+
|
|
237
|
+
#### Plain stdio programs
|
|
238
|
+
|
|
239
|
+
The [counter example](examples/counter.mjs) prints one number per second and has
|
|
240
|
+
no LinkRPC dependency. From this package directory, with an existing context:
|
|
241
|
+
|
|
242
|
+
```sh
|
|
243
|
+
# Background: the counter survives the launching CLI.
|
|
244
|
+
hub services run -x --id counter --detach -- node examples/counter.mjs
|
|
245
|
+
hub services attach --id counter
|
|
246
|
+
# Ctrl+D on an empty line detaches without stopping the counter.
|
|
247
|
+
hub services logs --id counter --follow
|
|
248
|
+
hub services stop --id counter
|
|
249
|
+
|
|
250
|
+
# Foreground: closing this CLI stops and removes the counter.
|
|
251
|
+
hub services run --no-rpc --foreground --id counter -- node examples/counter.mjs
|
|
252
|
+
# A different terminal can still attach while the owner is running:
|
|
253
|
+
hub services attach --id counter
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
The [interactive counter](examples/interactive-counter.mjs) also accepts input.
|
|
257
|
+
It prints `tick 1`, `tick 2`, ... once per second and responds to `count`,
|
|
258
|
+
`reset`, `echo <text>`, and `quit`:
|
|
259
|
+
|
|
260
|
+
```sh
|
|
261
|
+
hub services run -x --foreground --id interactive -- node examples/interactive-counter.mjs
|
|
262
|
+
# Type: count, echo hello, reset, or quit (then Enter).
|
|
263
|
+
# Or start with --detach instead of --foreground and attach separately:
|
|
264
|
+
hub services attach --id interactive
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
`count` prints the current number, `reset` sets it to zero, `echo hello` prints
|
|
268
|
+
`[<current count>] hello`, and `quit` exits the service. Requests can come from
|
|
269
|
+
any attachment; all attachments see the responses and ticks.
|
|
270
|
+
|
|
271
|
+
Create a context first with `hub context --new-context .` if needed. Multiple
|
|
272
|
+
attachments receive the same output; interactive attachments share the process's
|
|
273
|
+
stdin. Use `logs --follow` for a read-only observer. Restart/persistence policies
|
|
274
|
+
work for plain processes too.
|
|
275
|
+
|
|
276
|
+
`services list` reports `rpc: false` for these processes. They do not publish
|
|
277
|
+
application RPC methods under their reserved `serviceId`: other Hub participants
|
|
278
|
+
attach to their console (`hub services attach`, or generically through the
|
|
279
|
+
daemon's `consoles` template instance) to observe output and
|
|
280
|
+
send input, in both foreground and background mode. When the program adds
|
|
281
|
+
LinkRPC support, omit `-x` to provision its RPC connection. Add `-t` when the
|
|
282
|
+
program expects a terminal.
|
|
283
|
+
|
|
284
|
+
Connections support initialized LinkRPC socket/WebSocket endpoints. Forwarding
|
|
285
|
+
preserves method names and signatures, rather than rewriting root services
|
|
286
|
+
under a new prefix. The target must serve the assigned namespace (available
|
|
287
|
+
from `services list` or by querying the Hub's granted namespace over the
|
|
288
|
+
bidirectional connection). Connecting does not own or stop the target process.
|
|
289
|
+
|
|
12
290
|
## Views
|
|
13
291
|
|
|
14
292
|
Views target an **interface** or a **service** (including the main/root service),
|
|
@@ -183,6 +461,36 @@ linkrpc hub --endpoint ws://localhost:7700 call app::api::get
|
|
|
183
461
|
linkrpc hub call app::api::get --endpoint ws://localhost:7700
|
|
184
462
|
```
|
|
185
463
|
|
|
464
|
+
Profiles are presets, not restrictions on shared call behavior. Signing defaults
|
|
465
|
+
to off in `linkrpc`/`rpc` and on in `linkrpc hub`/`rpc hub`/`hub`.
|
|
466
|
+
Use `--sign` or `--no-sign` to override that default. `--principal` chooses
|
|
467
|
+
the identity; it does not by itself enable signing. Signed calls present stored
|
|
468
|
+
grants; unsigned calls do not load or present the capability bag.
|
|
469
|
+
`caps` management is available only in the Hub profile, but shared `call`
|
|
470
|
+
supports `--cap:request` and the `--cap:allow-*` options in both profiles.
|
|
471
|
+
|
|
472
|
+
Setting precedence is explicit CLI overrides, then enabled environment
|
|
473
|
+
overrides, then saved context values, then profile defaults. Environment
|
|
474
|
+
overrides currently supply endpoint/token settings, not signing settings.
|
|
475
|
+
`--sign`/`--no-sign` are saved with `context set` or `--context-set` and can be
|
|
476
|
+
removed with `context set --unset sign`. The existing environment-selection
|
|
477
|
+
policy remains: an explicit `--context` suppresses the Hub's default environment
|
|
478
|
+
override unless `--use-env` is supplied.
|
|
479
|
+
|
|
480
|
+
`--cap:request` enables signing when the signing setting is unspecified; it
|
|
481
|
+
does not change validation/environment defaults or switch command profiles.
|
|
482
|
+
An explicit or saved `sign: false` conflicts with capability operations;
|
|
483
|
+
override it with `--sign`. `--cap:request --validation off` is also rejected.
|
|
484
|
+
These calls illustrate equivalent settings:
|
|
485
|
+
|
|
486
|
+
```sh
|
|
487
|
+
linkrpc hub call files::fs::read --cap:request --p:path=/docs/a
|
|
488
|
+
linkrpc call files::fs::read --cap:request --validation required --use-env --p:path=/docs/a
|
|
489
|
+
|
|
490
|
+
# Reuse stored grants through the generic profile, without requesting:
|
|
491
|
+
linkrpc call files::fs::read --sign --validation required --p:path=/docs/a
|
|
492
|
+
```
|
|
493
|
+
|
|
186
494
|
Use `--validation auto|required|off` to override a profile default.
|
|
187
495
|
|
|
188
496
|
## Contexts
|
|
@@ -190,15 +498,19 @@ Use `--validation auto|required|off` to override a profile default.
|
|
|
190
498
|
Contexts persist command defaults in the global user configuration store. A
|
|
191
499
|
folder context is keyed by its canonical folder path; no file is written into
|
|
192
500
|
that folder. Without `--context`, the CLI searches from the current directory
|
|
193
|
-
through its parents, then uses `:root
|
|
501
|
+
through its parents, then uses `:root`.
|
|
194
502
|
|
|
195
503
|
Context selectors are:
|
|
196
504
|
|
|
197
505
|
- An absolute or relative folder path.
|
|
198
506
|
- `id:<name>` for a named context.
|
|
199
507
|
- `:root` for the system-wide root above platform filesystem roots. On Unix,
|
|
200
|
-
`/` is equivalent to `:root`.
|
|
201
|
-
|
|
508
|
+
`/` is equivalent to `:root`. The root context **always exists**: until you
|
|
509
|
+
store defaults in it, it has none. It cannot be created with `--new-context`,
|
|
510
|
+
and removing it resets it to no defaults. Because it applies to every folder
|
|
511
|
+
without its own context, `context set` and `--context-set` change it only when
|
|
512
|
+
selected explicitly (`--context :root`).
|
|
513
|
+
- `:empty` for no stored defaults, selected only explicitly. It is immutable.
|
|
202
514
|
|
|
203
515
|
`LINKRPC_CONTEXT` selects a context when `--context` is absent;
|
|
204
516
|
`HUBRPC_CONTEXT` is its legacy alias. An explicit `--context` also suppresses
|
|
@@ -206,8 +518,8 @@ the Hub profile's normal environment endpoint overlay. Every context value can
|
|
|
206
518
|
still be overridden by a command-line option.
|
|
207
519
|
|
|
208
520
|
```sh
|
|
209
|
-
#
|
|
210
|
-
hub context set --endpoint 'wss://hub.example?token=%' \
|
|
521
|
+
# Explicitly create a context for cwd with endpoint and principal defaults.
|
|
522
|
+
hub context set --new-context . --endpoint 'wss://hub.example?token=%' \
|
|
211
523
|
--endpoint-token secret --principal user:work
|
|
212
524
|
|
|
213
525
|
# Create a named context from the effective values only after the call succeeds.
|
|
@@ -217,14 +529,25 @@ hub call app::api::get --new-context id:working-copy
|
|
|
217
529
|
hub call app::api::get --validation off --context-set
|
|
218
530
|
|
|
219
531
|
hub context # same as `hub context show`
|
|
532
|
+
hub context create id:working-copy # same as: hub context --new-context id:working-copy
|
|
220
533
|
hub context resolve --context id:working-copy
|
|
221
|
-
hub context list
|
|
534
|
+
hub context list # always includes :root
|
|
222
535
|
hub context remove --context .
|
|
536
|
+
hub context set --context :root --principal user:work # defaults for folders without a context
|
|
537
|
+
hub context remove --context :root # resets :root to no defaults
|
|
223
538
|
hub call app::api::get --context :empty --endpoint ws://localhost:7700
|
|
224
539
|
```
|
|
225
540
|
|
|
226
|
-
Context creation
|
|
227
|
-
`--
|
|
541
|
+
Context creation is explicit: use `hub context create <selector>` or
|
|
542
|
+
`--new-context <selector>` (for example, `hub context --new-context .` creates a
|
|
543
|
+
folder context from effective defaults and shows it).
|
|
544
|
+
`--context <selector>` only selects an existing context; missing-context errors
|
|
545
|
+
show how to create it. `context set` and `--context-set` update existing contexts
|
|
546
|
+
and do not implicitly create a cwd context. Use `context set --new-context <selector>`
|
|
547
|
+
to create one with initial defaults. Combining `--context existing` with
|
|
548
|
+
`--new-context new` derives the new context from an existing one; it never creates
|
|
549
|
+
the selected source context.
|
|
550
|
+
Context values, including
|
|
228
551
|
endpoint tokens, are currently stored inline and unencrypted. Principals are
|
|
229
552
|
stored by selector (`managed`, `user:<id>`, or `file:<path>`); their private
|
|
230
553
|
keys remain in the existing identity store.
|
|
@@ -260,6 +583,7 @@ Every endpoint is a valid `new URL()` — safe in env vars and logs:
|
|
|
260
583
|
|
|
261
584
|
| URI | Transport |
|
|
262
585
|
| ----------------------------------------- | ------------------------------------------ |
|
|
586
|
+
| `linkrpc:local` | CLI discovery of the current user's local LinkRPC Hub |
|
|
263
587
|
| `unix:/run/hub/hub.sock?token=…` | unix-domain socket |
|
|
264
588
|
| `npipe://./pipe/linkrpc?token=…` | Windows named pipe |
|
|
265
589
|
| `ws://host:7700?token=…` / `wss://…` | LinkRPC WebSocket (token → `hubrpc::initialize`) |
|
|
@@ -267,6 +591,23 @@ Every endpoint is a valid `new URL()` — safe in env vars and logs:
|
|
|
267
591
|
| `cmd:?command=…` / `cmd:?argv=…&argv=…` | spawn-as-server (`--endpoint-cmd`) |
|
|
268
592
|
| `cmd-stdio:?command=…` / `?argv=…&argv=…` | spawn over stdio (`--endpoint-cmd-stdio`) |
|
|
269
593
|
|
|
594
|
+
`linkrpc:local` resolves the local daemon's application endpoint and credentials
|
|
595
|
+
from its discovery file, honoring `LINKRPC_HUB_HOME`. It never starts the daemon
|
|
596
|
+
and works even when no managed services are running. It is a CLI lookup URI,
|
|
597
|
+
not a wire transport or a service filter; raw SDK endpoint parsers do not resolve
|
|
598
|
+
it. It works as a CLI flag, a saved context endpoint, or an endpoint environment
|
|
599
|
+
variable. Explicit selection overrides ambient endpoint settings:
|
|
600
|
+
|
|
601
|
+
```sh
|
|
602
|
+
hub --endpoint linkrpc:local ui
|
|
603
|
+
hub --endpoint linkrpc:local ls
|
|
604
|
+
hub context --new-context . --endpoint linkrpc:local
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
Credentials come exclusively from discovery; `--endpoint-token` is rejected for
|
|
608
|
+
this URI. No username-derived pipe address needs to be hardcoded. By contrast,
|
|
609
|
+
the implicit local fallback requires at least one running managed endpoint.
|
|
610
|
+
|
|
270
611
|
`cmd:` children can use `startEndpoint({ onConnection })` without parsing any
|
|
271
612
|
transport flags: the parent injects `LINKRPC_ENDPOINT` and `LINKRPC_TOKEN`.
|
|
272
613
|
The CLI accepts one authenticated callback connection and exposes the child's
|
|
@@ -291,6 +632,12 @@ LINKRPC_ENDPOINT=unix:/run/hub/hub.sock?token=abc linkrpc ls
|
|
|
291
632
|
|
|
292
633
|
## Commands
|
|
293
634
|
|
|
635
|
+
### Consoles
|
|
636
|
+
|
|
637
|
+
| Command | Purpose |
|
|
638
|
+
| ----------------------------- | ---------------------------------------------------------------------------------------------------- |
|
|
639
|
+
| `attach [serviceId] [--params <json>] [--instance <name>] [--interface <id>] [--read-only]` | Attach to a [`linkrpc.console.v1`](../linkrpc-infra/README.md#process-consoles-linkrpcconsole) template instance of any service, found through the `linkrpc.console` tag; without a service, list consoles. Pipe consoles use line editing (Ctrl+D on an empty line detaches); TTY consoles receive raw keys (`--detach-keys`, default Ctrl+B, then d, detaches). |
|
|
640
|
+
|
|
294
641
|
### Reflection
|
|
295
642
|
|
|
296
643
|
| Command | Purpose |
|
|
@@ -446,6 +793,97 @@ frame, and each remote frame is written as one JSON line:
|
|
|
446
793
|
hub --endpoint unix:/run/hub.sock json-rpc-stdio language-server
|
|
447
794
|
```
|
|
448
795
|
|
|
796
|
+
### Capabilities
|
|
797
|
+
|
|
798
|
+
`linkrpc hub caps list [--json]` lists the selected principal's stored capabilities,
|
|
799
|
+
including expired grants. `caps request <methodRef>` requests and stores a
|
|
800
|
+
capability without executing the method. `call --cap:request` ensures the same
|
|
801
|
+
scope is available before executing the call. These explicit operations enable
|
|
802
|
+
signing even for generic-profile `call` and require a LinkRPC endpoint.
|
|
803
|
+
Without `--cap:request`, `call` never requests new capabilities (including
|
|
804
|
+
reflection access). When signing is enabled, it signs with the selected
|
|
805
|
+
identity and presents stored grants. Generic calls remain unsigned unless
|
|
806
|
+
`--sign` or a saved signing setting enables signing.
|
|
807
|
+
Missing or unusable grants fail with guidance to retry using `--cap:request`;
|
|
808
|
+
unguarded methods and plain RPC endpoints remain usable without capabilities.
|
|
809
|
+
|
|
810
|
+
Both request forms share `call`'s method references, `--params`, `--param`, and
|
|
811
|
+
`--p:<name>` shortcuts, including nested argument overrides and dynamic help.
|
|
812
|
+
Concrete arguments become exact constraints by default. Repeat
|
|
813
|
+
`--cap:allow-param 'key=<matcher JSON>'` to relax individual **top-level** parameters:
|
|
814
|
+
|
|
815
|
+
```sh
|
|
816
|
+
linkrpc hub --endpoint "$ENDPOINT" caps list --json
|
|
817
|
+
|
|
818
|
+
# Request permission without reading the file:
|
|
819
|
+
linkrpc hub --endpoint "$ENDPOINT" caps request files::fs::read \
|
|
820
|
+
--p:path=/workspace/readme.txt \
|
|
821
|
+
--cap:allow-param 'path={"prefix":"/workspace/"}'
|
|
822
|
+
|
|
823
|
+
# Ensure permission for that scope, then read a file:
|
|
824
|
+
linkrpc --endpoint "$ENDPOINT" call files::fs::read --cap:request \
|
|
825
|
+
--p:path=/workspace/another.txt \
|
|
826
|
+
--cap:allow-param 'path={"prefix":"/workspace/"}'
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
Matchers are `{"exact":value}`, `{"enum":[value,...]}`,
|
|
830
|
+
`{"prefix":"string-prefix"}`, `{"subsetOf":["allowed","array","items"]}`,
|
|
831
|
+
or `{"any":true}`. Constraints must be compatible with the reflected,
|
|
832
|
+
Zod-derived method schema, and the concrete example arguments must satisfy
|
|
833
|
+
both that schema and every constraint. Required and unknown keys are checked.
|
|
834
|
+
Nested matcher paths are unsupported by the capability protocol.
|
|
835
|
+
`any` allows every JSON value, so it is accepted only for unconstrained schema
|
|
836
|
+
properties; use `prefix`/`enum`/`subsetOf` for typed properties. A prefix cannot
|
|
837
|
+
be proven compatible with a finite enum or a formatted string; use an enum
|
|
838
|
+
of valid values instead. Remote reflection cannot reproduce arbitrary
|
|
839
|
+
producer-side custom Zod refinements.
|
|
840
|
+
|
|
841
|
+
Instead of naming the key in `--cap:allow-param`, attach a shortcut immediately
|
|
842
|
+
after a `--param key=value` or `--p:key=value` assignment:
|
|
843
|
+
|
|
844
|
+
```sh
|
|
845
|
+
linkrpc hub call files::fs::read --cap:request \
|
|
846
|
+
--p:path=/workspace/readme.txt --cap:allow-prefix=/workspace/
|
|
847
|
+
```
|
|
848
|
+
|
|
849
|
+
| Shortcut | Matcher | Meaning |
|
|
850
|
+
| --- | --- | --- |
|
|
851
|
+
| `--cap:allow-prefix <string>` | `prefix` | Any string beginning with the prefix |
|
|
852
|
+
| `--cap:allow-any` | `any` | Any JSON value; requires an unconstrained schema property |
|
|
853
|
+
| `--cap:allow-enum <JSON array>` | `enum` | One entire value from a non-empty array of alternatives |
|
|
854
|
+
| `--cap:allow-subset <JSON string array>` | `subsetOf` | An array containing only allowed strings; empty arrays, repetitions, and any ordering are allowed |
|
|
855
|
+
|
|
856
|
+
Each parameter can have only one explicit constraint. Mixing shortcuts with
|
|
857
|
+
`--cap:allow-param` for the same key, repeating constraints, or reassigning a
|
|
858
|
+
constrained parameter is an error. Shortcuts do not attach to `--params` JSON
|
|
859
|
+
or across intervening options. With variadic `--param`, a shortcut attaches
|
|
860
|
+
to the last assignment. The same schema and example-value validation applies
|
|
861
|
+
to shortcuts and explicit matchers.
|
|
862
|
+
|
|
863
|
+
Value-taking options support both `--option=value` and `--option value`.
|
|
864
|
+
Parameter assignment itself still uses `key=value`, e.g.
|
|
865
|
+
`--param path=/docs/a` or `--param=path=/docs/a`. Use the equals form for
|
|
866
|
+
dash-prefixed values. Quote JSON and strings containing spaces.
|
|
867
|
+
`--cap:request` and `--cap:allow-any` are switches with no value.
|
|
868
|
+
The older `--request-cap`, `--allow-param`, and `--duration` spellings have
|
|
869
|
+
been replaced by the `--cap:` options.
|
|
870
|
+
|
|
871
|
+
Schema validation is mandatory for explicit requests: `--no-validate` and
|
|
872
|
+
`--validation off` are rejected. On `call`, `--cap:allow-param` requires
|
|
873
|
+
`--cap:request`. For explicit requests, a method reference's `@hash` also pins
|
|
874
|
+
the permission; signed calls include that hash in their signed metadata.
|
|
875
|
+
The default requested duration is `persistent`; `--cap:duration shortLived` and
|
|
876
|
+
`--cap:duration longLived` are also supported. The Hub still decides what to grant.
|
|
877
|
+
One-shot approval cannot satisfy a reusable scope and is rejected.
|
|
878
|
+
|
|
879
|
+
Fresh durable grants for the selected principal are reused when they cover
|
|
880
|
+
the **entire requested scope**, not merely the example call. Broader prefixes,
|
|
881
|
+
enum sets, subset sets, and unconstrained grants can cover narrower requests.
|
|
882
|
+
New grants are saved through the principal's existing capability bag and are
|
|
883
|
+
available to later invocations using the same identity. Denial or an insufficient
|
|
884
|
+
grant fails without executing the method. `caps request` outputs the granted
|
|
885
|
+
capabilities and a `reused` flag; `call --cap:request` retains normal call output.
|
|
886
|
+
|
|
449
887
|
### Identity and approvals
|
|
450
888
|
|
|
451
889
|
These commands resolve the same persistent identity selected by the global
|
|
@@ -474,6 +912,12 @@ only when the selected identity is a configured trusted root.
|
|
|
474
912
|
Discovery diagnostics are written to stderr, including every manifest source
|
|
475
913
|
and its pending-request count; `--json` stdout remains machine-readable.
|
|
476
914
|
|
|
915
|
+
Hub calls (`call`, `ls`, …) additionally present a self-issued capability for
|
|
916
|
+
every call. A Hub accepts it only where the identity is a configured trusted
|
|
917
|
+
root, so a root needs no approval for its own calls; elsewhere it is ignored
|
|
918
|
+
and stored or requested grants apply as before. A Hub answers a trusted root's
|
|
919
|
+
access request at once, without parking it for approval.
|
|
920
|
+
|
|
477
921
|
```sh
|
|
478
922
|
hub --endpoint unix:/run/hub.sock?token=abc identity show --json
|
|
479
923
|
hub --endpoint unix:/run/hub.sock?token=abc approval requests --json
|