@futurelastic/muster 0.6.0-rc.1 → 0.6.0-rc.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 +64 -273
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -106,83 +106,21 @@ and merges branches, say — is that the dependency runs one way:
|
|
|
106
106
|
## The parts that are unusual
|
|
107
107
|
|
|
108
108
|
Most tools in this space manage sessions on one laptop, for one vendor's agent,
|
|
109
|
-
behind a TUI.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
`docs/positioning.md`](docs/positioning.md)
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
working --> quota_blocked: quota exhausted
|
|
125
|
-
quota_blocked --> idle: quota window resets
|
|
126
|
-
|
|
127
|
-
note right of waiting_input
|
|
128
|
-
Dead end. Only a respond call moves it:
|
|
129
|
-
answer by index, checked against a nonce.
|
|
130
|
-
This is the state that strands work.
|
|
131
|
-
end note
|
|
132
|
-
|
|
133
|
-
note right of quota_blocked
|
|
134
|
-
Not idle. On screen both are a quiet
|
|
135
|
-
terminal with an empty composer.
|
|
136
|
-
The API keeps them apart.
|
|
137
|
-
end note
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
On screen, an agent that finished, an agent out of quota, an agent whose turn
|
|
141
|
-
died on a transient error, and an agent holding text nobody submitted all look
|
|
142
|
-
identical: a quiet terminal with an empty composer. Collapsing them is how
|
|
143
|
-
abandoned work goes unnoticed for a day.
|
|
144
|
-
|
|
145
|
-
So they are different states, each carrying its evidence, and every state says
|
|
146
|
-
whether it was `observed` from a structured read or `inferred` from a screen.
|
|
147
|
-
|
|
148
|
-
### Sending a prompt is not fire-and-forget
|
|
149
|
-
|
|
150
|
-
```mermaid
|
|
151
|
-
flowchart TB
|
|
152
|
-
A(["POST input — send a prompt"]) --> R{result}
|
|
153
|
-
R -->|submitted| S["delivered — the agent has it"]
|
|
154
|
-
R -->|queued| Q["accepted — submit registered"]
|
|
155
|
-
R -->|unknown| U["NOT sent — text stranded<br/>in the composer"]
|
|
156
|
-
U -. "retry: send resumes its own<br/>unconfirmed delivery, never a human's text" .-> A
|
|
157
|
-
|
|
158
|
-
classDef bad stroke-width:2px,stroke-dasharray:6 4
|
|
159
|
-
class U bad
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
`unknown` means the text is sitting in the composer and was **not** submitted. A
|
|
163
|
-
system that reports success here loses instructions silently, and you find out
|
|
164
|
-
hours later when nothing happened. Retrying resubmits only text the service
|
|
165
|
-
itself placed there — never text a human typed.
|
|
166
|
-
|
|
167
|
-
There is a fourth outcome, `refused`, for when the driver actively protects the
|
|
168
|
-
session from input that would corrupt it. A refusal is information to act on,
|
|
169
|
-
not a fault to retry, so it arrives as an ordinary `200`.
|
|
170
|
-
|
|
171
|
-
### A session blocked on a dialog can be answered remotely
|
|
172
|
-
|
|
173
|
-
The dialog is read with every option enumerated, and you answer by index —
|
|
174
|
-
carrying a nonce, so your answer cannot land on a question that changed while
|
|
175
|
-
you were deciding. A session lost to a question nobody can reach is the most
|
|
176
|
-
expensive failure in a fleet, and an ordinary `send` cannot fix it: the property
|
|
177
|
-
that makes `send` safe for messages makes it useless for control.
|
|
178
|
-
|
|
179
|
-
### Every route is authenticated, and exposure is never accidental
|
|
180
|
-
|
|
181
|
-
There is no unauthenticated mode — not on loopback, not in development. A
|
|
182
|
-
service with no token refuses to start. The default bind is loopback on an
|
|
183
|
-
ephemeral port, and binding all interfaces logs a warning that names the risk.
|
|
184
|
-
Callers are named principals with per-verb grants; every mutation is audited
|
|
185
|
-
with an actor, not an address.
|
|
109
|
+
behind a TUI. These are the properties that turned out to be rare — all of them
|
|
110
|
+
consequences of taking failure seriously. Each is worked through, with its state
|
|
111
|
+
and delivery diagrams, in [`docs/unusual-parts.md`](docs/unusual-parts.md); the
|
|
112
|
+
survey behind "rare" is [`docs/positioning.md`](docs/positioning.md).
|
|
113
|
+
|
|
114
|
+
- **A session has a state, not a pulse.** Finished, out of quota, died on an
|
|
115
|
+
error and holding unsent text all look like a quiet terminal; here they are
|
|
116
|
+
different states, each saying whether it was `observed` or `inferred`.
|
|
117
|
+
- **Sending a prompt is not fire-and-forget.** `submitted`, `queued`, `unknown`
|
|
118
|
+
and `refused` are distinct outcomes; `unknown` means the text is stranded, not
|
|
119
|
+
sent, and a retry never resubmits a human's text.
|
|
120
|
+
- **A session blocked on a dialog can be answered remotely** — by option index,
|
|
121
|
+
carrying a nonce so the answer cannot land on a question that changed.
|
|
122
|
+
- **Every route is authenticated.** No unauthenticated mode, loopback bind by
|
|
123
|
+
default, named principals with per-verb grants, every mutation audited.
|
|
186
124
|
|
|
187
125
|
---
|
|
188
126
|
|
|
@@ -197,18 +135,12 @@ npm i -g @futurelastic/muster # or install the `muster` command
|
|
|
197
135
|
muster --version # muster <version> (...)
|
|
198
136
|
```
|
|
199
137
|
|
|
200
|
-
`@futurelastic/muster` is a small launcher
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
publish under the `next` dist-tag (`npx @futurelastic/muster@next`); `latest`
|
|
207
|
-
only ever moves to a final release.
|
|
208
|
-
|
|
209
|
-
Windows is built and tested by every release but not published to npm yet, and
|
|
210
|
-
has no interactive-terminal driver; see
|
|
211
|
-
[`docs/install.md`](docs/install.md#windows).
|
|
138
|
+
`@futurelastic/muster` is a small launcher: npm installs exactly one platform
|
|
139
|
+
package beside it and runs that binary. Nothing is downloaded at install time,
|
|
140
|
+
and every release carries npm provenance. Release candidates publish under the
|
|
141
|
+
`next` dist-tag; `latest` only moves to a final release. Windows is built and
|
|
142
|
+
tested by every release but not published to npm yet and has no
|
|
143
|
+
interactive-terminal driver — see [`docs/install.md`](docs/install.md#windows).
|
|
212
144
|
|
|
213
145
|
Configure it with the `FLEET_*` environment the [Quickstart](#quickstart) shows
|
|
214
146
|
and start it with `muster serve`. A service that survives a reboot is
|
|
@@ -228,7 +160,7 @@ go build ./... && go test ./...
|
|
|
228
160
|
export FLEET_MACHINE=machine-a
|
|
229
161
|
export FLEET_TOKEN="$(openssl rand -hex 32)"
|
|
230
162
|
export FLEET_ADDR=127.0.0.1:9000
|
|
231
|
-
go run ./cmd/muster
|
|
163
|
+
go run ./cmd/muster serve
|
|
232
164
|
```
|
|
233
165
|
|
|
234
166
|
```sh
|
|
@@ -239,185 +171,44 @@ There is no default port — pick one and keep it. The default bind is loopback
|
|
|
239
171
|
an ephemeral port, so a service you have not deliberately configured is
|
|
240
172
|
reachable only from its own machine.
|
|
241
173
|
|
|
242
|
-
### Two machines
|
|
174
|
+
### Two machines
|
|
243
175
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
```sh
|
|
250
|
-
mkdir -p ~/.config/muster
|
|
251
|
-
openssl rand -hex 32 > ~/.config/muster/machine-a.token
|
|
252
|
-
chmod 600 ~/.config/muster/machine-a.token
|
|
253
|
-
```
|
|
254
|
-
|
|
255
|
-
**2. On machine-b — the one that owns the sessions.** Bind the interface the
|
|
256
|
-
peer will actually reach: **a specific address, never `0.0.0.0`**. On a VPN that
|
|
257
|
-
is the VPN address; on a trusted LAN it is the LAN address. Loopback is added
|
|
258
|
-
alongside it automatically, so the service never becomes undiagnosable from its
|
|
259
|
-
own machine.
|
|
260
|
-
|
|
261
|
-
```sh
|
|
262
|
-
export FLEET_MACHINE=machine-b
|
|
263
|
-
export FLEET_TOKEN="$(cat ~/.config/muster/machine-b.token)"
|
|
264
|
-
export FLEET_ADDR=10.8.0.12:9000 # this machine's VPN or LAN address
|
|
265
|
-
export FLEET_ALLOW_MUTATIONS=1 # permit writes to its own sessions
|
|
266
|
-
muster
|
|
267
|
-
```
|
|
268
|
-
|
|
269
|
-
**3. On machine-a — the one that will call it.** A peer is statically
|
|
270
|
-
configured; there is no discovery. The address is one **you** have confirmed
|
|
271
|
-
reachable from this machine, never the peer's own idea of its name — that is how
|
|
272
|
-
a fleet ends up pointing at a hostname which resolves on only one side.
|
|
273
|
-
|
|
274
|
-
```sh
|
|
275
|
-
export FLEET_MACHINE=machine-a
|
|
276
|
-
export FLEET_TOKEN="$(cat ~/.config/muster/machine-a.token)"
|
|
277
|
-
export FLEET_PEERS="machine-b=http://10.8.0.12:9000"
|
|
278
|
-
export FLEET_ALLOW_RELAY=1 # permit forwarding writes to a peer
|
|
279
|
-
muster
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
**4. Verify, from machine-a.**
|
|
283
|
-
|
|
284
|
-
```sh
|
|
285
|
-
curl -s -H "Authorization: Bearer $(cat ~/.config/muster/machine-a.token)" \
|
|
286
|
-
http://127.0.0.1:9000/v1/machines
|
|
287
|
-
```
|
|
288
|
-
|
|
289
|
-
```json
|
|
290
|
-
{ "items": [ { "machine": "machine-a", "self": true, "status": "ok" },
|
|
291
|
-
{ "machine": "machine-b", "self": false, "status": "ok" } ],
|
|
292
|
-
"complete": true }
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
Both reading `ok` is the entire handshake. If machine-b reads `unreachable`,
|
|
296
|
-
the bind address or the network path is wrong — **not** the token: a bad
|
|
297
|
-
credential is a `401`, not a silence.
|
|
298
|
-
|
|
299
|
-
> **The two credentials are not symmetric.** The token machine-a presents for a
|
|
300
|
-
> peer is *machine-a's identity on machine-b*, not machine-b's identity here.
|
|
301
|
-
> They are different secrets, and conflating them is how a fleet quietly ends up
|
|
302
|
-
> back on one shared token.
|
|
303
|
-
|
|
304
|
-
You now have one API over both machines. What to do with it is below.
|
|
176
|
+
Federating two instances is four steps — a credential per machine, the owner's
|
|
177
|
+
bind address, the caller's peer list, and one `GET /v1/machines` to verify. The
|
|
178
|
+
full walk-through is [`docs/multi-machine.md`](docs/multi-machine.md); what a
|
|
179
|
+
caller can then do (one fleet-wide session list, input and dialog answers sent
|
|
180
|
+
across the hop) is [`docs/driving-a-machine.md`](docs/driving-a-machine.md).
|
|
305
181
|
|
|
306
182
|
> **This is a demo, not an install.** Every process above ends with its shell.
|
|
307
183
|
> A service that survives a reboot — a principal table, a state directory, a
|
|
308
184
|
> service unit, and a `muster doctor` run that checks all of it — is
|
|
309
185
|
> [`docs/install.md`](docs/install.md).
|
|
310
186
|
|
|
187
|
+
## Who it serves
|
|
311
188
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
What the two-machine setup above actually buys you, end to end. Every call is
|
|
315
|
-
made against the **local** service; that it crosses a LAN or a VPN to reach the
|
|
316
|
-
other machine is the service's problem, not the caller's.
|
|
317
|
-
|
|
318
|
-
```mermaid
|
|
319
|
-
sequenceDiagram
|
|
320
|
-
autonumber
|
|
321
|
-
actor C as client
|
|
322
|
-
box transparent machine-a
|
|
323
|
-
participant A as muster (a)
|
|
324
|
-
end
|
|
325
|
-
box transparent machine-b
|
|
326
|
-
participant B as muster (b)
|
|
327
|
-
participant T as tmux driver
|
|
328
|
-
participant X as agent CLI
|
|
329
|
-
end
|
|
330
|
-
|
|
331
|
-
C->>A: GET /v1/machines/machine-b/sessions/s42
|
|
332
|
-
Note over A,B: one hop · LAN / VPN<br/>HTTP + bearer token
|
|
333
|
-
A->>B: proxy — same API, service's own credential
|
|
334
|
-
B->>T: read session
|
|
335
|
-
T->>X: capture + classify screen
|
|
336
|
-
X-->>T: screen
|
|
337
|
-
T-->>B: state: waiting_input
|
|
338
|
-
B-->>A: session s42
|
|
339
|
-
A-->>C: session s42
|
|
340
|
-
Note over C,A: the caller never learns the session was remote.<br/>Fan-out stops here — peers never recurse.
|
|
341
|
-
```
|
|
342
|
-
|
|
343
|
-
### Drive it
|
|
189
|
+
Clients, not end users. Three kinds are in mind, and the API treats them alike:
|
|
344
190
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
191
|
+
- **Session dashboards** — a view over every session on every machine, with the
|
|
192
|
+
state each one is in and a way to answer the one that is stuck.
|
|
193
|
+
- **Coordinators** — programs that decide what work should happen and need a
|
|
194
|
+
session to run it on; they hold the work vocabulary, this service holds the
|
|
195
|
+
session.
|
|
196
|
+
- **Desktop and command-line apps** — a launcher or picker that lists sessions
|
|
197
|
+
and attaches to one.
|
|
349
198
|
|
|
350
|
-
|
|
199
|
+
Which of these you are building decides where to start in
|
|
200
|
+
[`docs/client-guide.md`](docs/client-guide.md).
|
|
351
201
|
|
|
352
|
-
|
|
353
|
-
curl -s -H "$AUTH" "$FLEET/v1/sessions?scope=fleet"
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
```json
|
|
357
|
-
{
|
|
358
|
-
"items": [
|
|
359
|
-
{ "machine": "machine-a", "id": "s17", "state": { "status": "working", "confidence": "inferred" } },
|
|
360
|
-
{ "machine": "machine-b", "id": "s42", "state": { "status": "waiting_input", "confidence": "inferred",
|
|
361
|
-
"waitingOn": "prompt",
|
|
362
|
-
"prompt": { "question": "Allow running tests?", "options": ["No", "Yes", "Yes, always"],
|
|
363
|
-
"selected": 1, "kind": "tool-permission", "nonce": "a3f1" } } }
|
|
364
|
-
],
|
|
365
|
-
"sources": [ { "machine": "machine-a", "status": "ok" }, { "machine": "machine-b", "status": "ok" } ],
|
|
366
|
-
"complete": true
|
|
367
|
-
}
|
|
368
|
-
```
|
|
202
|
+
## Layout
|
|
369
203
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
curl -s -X POST -H "$AUTH" -H 'Content-Type: application/json' \
|
|
379
|
-
-d '{"text":"run the test suite","submit":true}' \
|
|
380
|
-
"$FLEET/v1/machines/machine-b/sessions/s42/input"
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
```json
|
|
384
|
-
{ "outcome": "submitted" }
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
If that comes back `"unknown"`, the text is stranded in the composer on the
|
|
388
|
-
other machine and was not sent. Retry the identical call with
|
|
389
|
-
`"resumeIfStranded": true`.
|
|
390
|
-
|
|
391
|
-
**Answer the dialog it is blocked on** — quoting the nonce from the read above:
|
|
392
|
-
|
|
393
|
-
```sh
|
|
394
|
-
curl -s -X POST -H "$AUTH" -H 'Content-Type: application/json' \
|
|
395
|
-
-d '{"choice":2,"nonce":"a3f1"}' \
|
|
396
|
-
"$FLEET/v1/machines/machine-b/sessions/s42/respond"
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
`choice` is 1-based against `prompt.options`, so this answers **"Yes"**. If the
|
|
400
|
-
prompt changed while you were deciding, the nonce no longer matches and the
|
|
401
|
-
answer is refused rather than applied to a different question.
|
|
402
|
-
|
|
403
|
-
### What has to be true for that to work
|
|
404
|
-
|
|
405
|
-
| | machine-a (calls) | machine-b (owns the session) |
|
|
406
|
-
|---|---|---|
|
|
407
|
-
| Reachable address | — | `FLEET_ADDR` on the LAN/VPN interface |
|
|
408
|
-
| Peer configured | `FLEET_PEERS` | — |
|
|
409
|
-
| Write to own sessions | — | `FLEET_ALLOW_MUTATIONS=1` |
|
|
410
|
-
| Forward writes to a peer | `FLEET_ALLOW_RELAY=1` | — |
|
|
411
|
-
|
|
412
|
-
With a principal table those two booleans become per-identity grants: the caller
|
|
413
|
-
needs `relay` on machine-a, and the verb grant (`send`) is checked on machine-b.
|
|
414
|
-
They are separate refusals and you meet them one at a time. Both default to
|
|
415
|
-
denied, on a fresh deployment as much as an established one.
|
|
416
|
-
|
|
417
|
-
> **Exposing this is a decision, not a default.** The service reads paths and,
|
|
418
|
-
> when mutations are enabled, starts processes. Put it on a VPN or a trusted
|
|
419
|
-
> LAN segment, bind a specific interface, and give each caller its own
|
|
420
|
-
> credential with only the grants it needs.
|
|
204
|
+
| Path | What lives there |
|
|
205
|
+
|---|---|
|
|
206
|
+
| `cmd/muster/` | The `muster` binary: `serve`, `doctor`, `compat`, `principal` |
|
|
207
|
+
| `internal/` | The service: HTTP API, state store, session drivers, delivery, peer federation |
|
|
208
|
+
| `clients/` | Reference shell clients — [`clients/README.md`](clients/README.md) |
|
|
209
|
+
| `scripts/` | Gate, smoke, build and release scripts |
|
|
210
|
+
| `npm/` | The launcher and platform packages published to npm |
|
|
211
|
+
| `docs/` | API reference, specs, install and deploy procedures, ADRs — see [Documentation](#documentation) |
|
|
421
212
|
|
|
422
213
|
---
|
|
423
214
|
|
|
@@ -432,6 +223,7 @@ denied, on a fresh deployment as much as an established one.
|
|
|
432
223
|
| Adopt this in an existing system | [`docs/adoption.md`](docs/adoption.md) — staged so each step is reversible; §2 is the precondition that surprised us |
|
|
433
224
|
| Work on the service | [`docs/internals.md`](docs/internals.md) — measurements, decided questions, known gaps |
|
|
434
225
|
| Check a runtime build before the fleet takes it | [`docs/compat.md`](docs/compat.md) — `muster compat`: a versioned report of whether a candidate build still behaves as this service assumes |
|
|
226
|
+
| Set up two machines | [`docs/multi-machine.md`](docs/multi-machine.md) — credentials, bind address, peer list, verify; then [`docs/driving-a-machine.md`](docs/driving-a-machine.md) for what a caller can do across the hop |
|
|
435
227
|
| Install it on a new machine | [`docs/install.md`](docs/install.md) — from nothing to a running service, ending with `muster doctor` |
|
|
436
228
|
| Deploy it | [`docs/deploy.md`](docs/deploy.md) — from a merged commit to a service that already runs |
|
|
437
229
|
| Declare a machine-wide session identity | [`docs/session-identity.md`](docs/session-identity.md) — `sessionEnv`, precedence against a caller, verification |
|
|
@@ -457,34 +249,33 @@ implemented it:
|
|
|
457
249
|
- ✅ **A first working driver** — a terminal multiplexer running an interactive
|
|
458
250
|
agent CLI. It amended four sections of the spec and found one defect the spec
|
|
459
251
|
cannot fix on its own.
|
|
460
|
-
- ✅ **Event subscription** —
|
|
461
|
-
|
|
462
|
-
- ✅ **A second driver: a remote peer** — federation, proven
|
|
463
|
-
|
|
464
|
-
back with real sessions in ~30 ms. Neither service needed a special case.
|
|
252
|
+
- ✅ **Event subscription** — served as SSE with cursors, epoch, retention and
|
|
253
|
+
announced resync. No polling anywhere.
|
|
254
|
+
- ✅ **A second driver: a remote peer** — federation, proven; neither service
|
|
255
|
+
needed a special case.
|
|
465
256
|
- ✅ **Answering, not just observing** — enumerated options, a nonce, and
|
|
466
257
|
verification that the prompt actually cleared.
|
|
467
258
|
- ✅ **A second *local* driver** — a third-party agent spawned as a subprocess,
|
|
468
|
-
the first able to declare `observesState: true`.
|
|
469
|
-
at once, which is the proof the interface was worth having.
|
|
259
|
+
the first able to declare `observesState: true`.
|
|
470
260
|
- ✅ **State that survives a restart** — idempotency keys, event epoch and
|
|
471
|
-
cursor, and driver session records persisted atomically
|
|
472
|
-
|
|
261
|
+
cursor, and driver session records persisted atomically.
|
|
262
|
+
- ✅ **A supervisor as a client** — a supervisor now talks to this service
|
|
263
|
+
instead of to the terminal multiplexer. The plan that got there, including the
|
|
264
|
+
precondition that could not be discharged from inside this repository, is
|
|
265
|
+
[`docs/adoption.md`](docs/adoption.md).
|
|
266
|
+
- ✅ **A release path** — one npm install surface, release candidates and
|
|
267
|
+
finals, and a Windows build that is tested on every release.
|
|
473
268
|
|
|
474
|
-
Next
|
|
269
|
+
Next:
|
|
475
270
|
|
|
476
|
-
- ⬜ **A supervisor as a client**, replacing direct terminal-multiplexer access.
|
|
477
|
-
Until that happens this is a second implementation of session management
|
|
478
|
-
rather than a replacement for one. Planned in
|
|
479
|
-
[`docs/adoption.md`](docs/adoption.md) — including the one precondition that
|
|
480
|
-
cannot be discharged from inside this repository: nothing here prevents two
|
|
481
|
-
machines editing one working tree, because repository state is a non-goal.
|
|
482
271
|
- ⬜ **Credential lifecycle.** Grants are per principal and per verb, and
|
|
483
272
|
enrolment is a command. Nothing expires, a compromised token is revoked by
|
|
484
273
|
editing a file, and changing a principal's grants means removing and
|
|
485
274
|
re-adding it.
|
|
486
275
|
- ⬜ **Metrics.** Subprocess spawn cost is known to degrade with host load —
|
|
487
276
|
8× on a machine under heavy load — and nothing measures it in production.
|
|
277
|
+
- ⬜ **Windows publication and an interactive-terminal driver there.** Built and
|
|
278
|
+
tested today; not yet on npm, and the multiplexer driver is not available.
|
|
488
279
|
|
|
489
280
|
The honest list of what is missing is in
|
|
490
281
|
[`docs/internals.md`](docs/internals.md), kept current on purpose.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@futurelastic/muster",
|
|
3
|
-
"version": "0.6.0-rc.
|
|
3
|
+
"version": "0.6.0-rc.2",
|
|
4
4
|
"description": "muster — a machine-local service that owns session agents across a fleet. Launcher: runs the prebuilt binary for this platform.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/futurelastic/muster#readme",
|
|
@@ -20,10 +20,10 @@
|
|
|
20
20
|
"LICENSE"
|
|
21
21
|
],
|
|
22
22
|
"optionalDependencies": {
|
|
23
|
-
"@futurelastic/muster-darwin-arm64": "0.6.0-rc.
|
|
24
|
-
"@futurelastic/muster-darwin-x64": "0.6.0-rc.
|
|
25
|
-
"@futurelastic/muster-linux-x64": "0.6.0-rc.
|
|
26
|
-
"@futurelastic/muster-linux-arm64": "0.6.0-rc.
|
|
23
|
+
"@futurelastic/muster-darwin-arm64": "0.6.0-rc.2",
|
|
24
|
+
"@futurelastic/muster-darwin-x64": "0.6.0-rc.2",
|
|
25
|
+
"@futurelastic/muster-linux-x64": "0.6.0-rc.2",
|
|
26
|
+
"@futurelastic/muster-linux-arm64": "0.6.0-rc.2"
|
|
27
27
|
},
|
|
28
28
|
"publishConfig": {
|
|
29
29
|
"access": "public",
|