Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 30 additions & 29 deletions packages/extension/skills/add-fleet-device/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ what you say:
| hub / server / canonical | "home base" — the machine that hosts your work |
| enroll / join token | "link this machine in" |
| client | "a window onto home base" |
| standalone + advertise `serving` (peer) | "its own studio you can hop to" |
| standalone + advertise `serving` (peer) | "its own studio, with fleet sessions and prompts syncing between machines" |
| verify-attach / roster health | "check the link actually works" |
| transport (ssh / tailscale) | "how the machines reach each other" |

Expand Down Expand Up @@ -57,18 +57,15 @@ first"). Do not try to stand up home base here.

Frame the topology choice as an outcome, never with the words "hub" or "peer":

> **"When this machine is away from home base (or home base is off), what should happen?"**
> - **"It's my window into home base — I mostly work off the other machine"** → a
> window onto home base (recommended, and the fully-wired path: your sessions
> follow you, this machine shows the same work).
> - **"It should fully work on its own, and I'll hop between the two"** → its own
> studio.
> **"Should this machine run its own studio, or depend on one host?"**
> - **"Run its own studio, and keep fleet sessions in sync"** (recommended) → peer
> studio. Each machine has its own engine; session activity and prompts sync
> between them in near real time.
> - **"Use one host for all my work"** → a window onto home base. The other machine
> depends on that host being reachable.

If they choose "its own studio," add the honest caveat immediately: *"You can set
that up today and hop between them — but running a live chat directly on the other
machine's engine is still landing, so the smoothest 'both machines as one' is
keeping one as home base. Want the window setup instead, or the independent one
with that caveat?"* Then honor their choice.
Honor their choice. Do not describe peer studios as simply hopping between isolated
histories: session activity and prompts sync between peer machines.

## Step 3 — pick the one machine

Expand All @@ -80,10 +77,15 @@ you like").

## Step 4 — readiness: can the two machines already reach each other?

Ask the plain question first, before anything is changed:
First choose the connection method in Step 5. SSH is not a prerequisite when the
machines will connect over Tailscale. For Tailscale, check both devices are signed
in and online, and that MagicDNS resolves. If it is not set up, direct the user to
[Tailscale's install guide](https://tailscale.com/kb/1017/install) and resume when
they are ready. Do not ask for router port-forwarding.

> **"Have you ever connected to this machine over SSH from here? (If you've `ssh`'d
> into it before, yes.)"**
For SSH, ask the plain question first, before anything is changed:

> **"Have you ever connected to this machine over SSH from here? (If you've `ssh`'d into it before, yes.)"**

Then **probe silently** and only surface a prerequisite if it actually fails:

Expand All @@ -101,20 +103,20 @@ pipeline:
I'll retry." (Behind the scenes: enable the service, append this machine's public
key to the target's `~/.ssh/authorized_keys`, add a `Host <alias>` block to
`~/.ssh/config`.)
- **No SSH alias** → the enroll step requires one; add the `Host <alias>` block
before proceeding (the link install refuses without it).
- **No SSH alias** → add the `Host <alias>` block only if SSH is the chosen
connection method.

## Step 5 — how the machines connect (transport), by OS

Default is **SSH** — the universal floor, works everywhere. Choose **Tailscale**
only when the machine roams between networks *and* Tailscale is actually up:
Recommend **Tailscale** when the machines may be on different or changing networks.
It provides private reachability without router port-forwarding. If it is not
installed or signed in, direct the user to [Tailscale's install guide](https://tailscale.com/kb/1017/install)
and pause until setup is complete. Use **SSH** for a trusted reachable network or
when the user prefers SSH:

- Before choosing Tailscale, verify both machines are online in `tailscale status`,
MagicDNS resolves, and home base is sharing its engine with `tailscale serve`
(never `funnel`). If any of that isn't true, fall back to SSH and say so.
- **Safety, not just reachability:** home base trusts the connection itself as the
boundary, so the link must stay private — a private SSH tunnel or the tailnet via
`serve` — and never a publicly exposed port (`funnel`, or a public bind).
- Before relying on Tailscale, verify both machines are online in `tailscale
status` and the peer's MagicDNS name resolves. Do not ask the user to expose a
port publicly, use `tailscale funnel`, or configure router port-forwarding.

**Per-OS reality of the steady link** (the machine being added is what matters):

Expand Down Expand Up @@ -142,13 +144,12 @@ amico fleet enroll --join-token ~/.amico/ops/fleet/join-token.json \
The verb runs the whole thing: build check → link config → register → install the
guard/link → confirm. Read its JSON verdict (Step 6a).

**Its own studio (peer).** There is no turnkey wizard yet — guide it: on the new
**Its own studio (peer, recommended).** There is no turnkey wizard yet — guide it: on the new
machine run **Amicode: Fleet — Go Standalone** (it runs its own engine), then have
it advertise itself (`serving`) and point the directory pointer
(`~/.amico/ops/fleet/keeper.json`) at the roster host so both machines see each
other with an **Attach** control. Repeat the honest caveat: attaching flips the
pointer, but running your live session *on* the other machine's engine is still
landing.
other with an **Attach** control. Explain that each machine runs its own engine
and session activity and prompts sync between machines in near real time.

### Step 6a — read the verdict, but trust the real link

Expand Down
70 changes: 35 additions & 35 deletions packages/extension/skills/create-a-fleet/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ terms live in the commands you run, never in what you say:
| hub / star / server / canonical | "home base" — the machine that hosts your work |
| client / thin client | "a window onto home base" |
| standalone | "works on its own" |
| peer studios | "two independent studios you hop between" |
| peer studios | "your own studio on each machine, with sessions and prompts syncing between them" |
| enroll / join token | "link this machine in" |
| verify-attach / roster / health | "check the link actually works" |
| transport (ssh / tailscale) | "how the machines reach each other" |
Expand Down Expand Up @@ -72,21 +72,18 @@ Ask it in outcomes, never with "hub" or "peer":

> **"When your machines are apart — one's off, or you've taken the laptop out —
> what should happen?"**
> - **"One machine hosts my work; the others are windows into it"** (recommended)
> → home-base setup. The fully-wired path: your sessions live on home base and
> follow you to any machine.
> - **"Each machine should fully work on its own, and I'll hop between them"** →
> independent studios.

**Default to home base with the always-on machine as home base** (the workstation,
not the laptop) — it's the coherent, fully-wired experience. Pick "independent
studios" only when the user explicitly wants each machine usable alone, and then
give the honest caveat up front: *"You can set that up today and hop between them,
but running a live chat directly on the other machine's engine is still landing —
so the smoothest 'both as one' is still home base. Independent anyway, or home
base?"* Honor their choice; jump to **Peer studios** below for that path.

The rest of this skill is the home-base (hub/star) build.
> - **"Each machine should work on its own, while my fleet sessions stay in sync"** (recommended) → peer studios. Each machine has its own engine, and session activity and prompts sync between machines in near real time. Any one machine can keep working if another is offline.
> - **"I want one machine to host everything; the others are windows onto it"** → home-base setup. The other machines depend on home base being reachable.

Default to peer studios when the user wants multiple machines to work as one fleet
without a single machine being a point of failure. Explain that each machine runs
its own engine, while session activity and prompts sync between them in near real
time. Choose home base when the user specifically wants one shared engine/database
and accepts that the other machines depend on it. Honor their choice.

If the user chooses peer studios, skip the home-base provisioning and window-link
steps below; follow **Peer studios** instead. The remaining numbered steps describe
the home-base (hub/star) build.

## Step 2 — discover the machines

Expand Down Expand Up @@ -160,11 +157,14 @@ On failure, walk **one** step in plain terms and retry — don't recite a pipeli

One machine at a time. While one is paused awaiting a human step, move to the next.

**a. How it connects (transport).** Default **SSH** (the universal floor, works
everywhere). Choose **Tailscale** only for a machine that roams *and* only after
verifying both machines are online in `tailscale status`, MagicDNS resolves, and
home base shares its engine via `tailscale serve` (never `funnel`) — else fall back
to SSH and say so.
**a. How it connects (transport).** Recommend **Tailscale** for machines on
different or changing networks: it creates a private connection without router
port-forwarding. If Tailscale is not installed or signed in, point the user to
[Tailscale's install guide](https://tailscale.com/kb/1017/install) and pause that
machine until setup is complete. Verify both machines are online in `tailscale
status` and that the peer's MagicDNS name resolves before using it. Use **SSH**
when the machines are on a trusted reachable network or the user prefers SSH. Never
ask the user to expose a fleet port publicly or configure router port forwarding.

**b. Confirm.** Show the exact link-in for this one machine; get an explicit yes.

Expand Down Expand Up @@ -229,34 +229,34 @@ you'll see the same sessions."** Name any machine still paused and the one step
it's waiting on — nothing is silently dropped. Anything still stuck after its
guided step is a job for `/troubleshoot-fleet`; hand off and stop.

## Peer studios (the independent-studios path)
## Peer studios (the recommended path)

The additive topology: every machine runs its **own** engine on its **own**
database and *advertises* itself; you attach/switch between them. A machine that's
off doesn't strand the others — there is no single machine whose loss stops the
fleet. A peer stays "on its own" (never a window onto home base) and never installs
the never-fork guard.
Every machine runs its **own** engine on its **own** database and advertises itself.
Session activity and prompts sync between machines in near real time, so users can
work from either machine without making one machine the host for all work. If a
machine is offline, the others keep working. A peer remains standalone (never a
window onto home base) and does not install the never-fork guard. Do not describe
peer studios as merely switching between isolated histories.

**What works today — and the honest edges (state it plainly):**

- **Works:** each machine as its own independent, resilient studio; advertising
(`serving`); the shared directory of machines (the keeper); the **Attach** control
and per-machine transport/credential plumbing; **observing** another machine's
sessions (read) works without a grant.
(`serving`); the shared directory of machines (the keeper); synced session
activity and prompts; the **Attach** control and per-machine transport/credential
plumbing.
- **Sharp edge — observe hands a write-capable credential:** *controlling* another
machine's session (prompting/archiving it) is wired, but the machine you attach to
currently accepts the same credential it accepts for *reading* — so granting
someone "observe" effectively grants write too. A separate control-only credential
is future work. Scope who you grant to accordingly.
- **Not yet:** clicking **Attach** does not yet run your *live* session on the other
machine's engine (the live re-target is a scoped follow-up). So peer is great for
independent + resilient studios today; live shared driving across them is landing.
- Per-machine removal is `amico fleet revoke <machine_id>` (drops the grant + bars
re-mint + fans out to serving peers); verify a revoked machine can no longer reach
the others rather than trusting the exit code.

**No turnkey peer wizard exists yet**, so guide it by hand. To make an existing
home-base/window pair into independent studios:
**No turnkey peer wizard exists yet**, so guide it by hand. For a new peer fleet,
keep each machine standalone, have each advertise `serving`, and point each
machine's `~/.amico/ops/fleet/keeper.json` at the shared directory host. For an
existing home-base/window pair:

1. On the **window machine**, run **Amicode: Fleet — Go Standalone** — it now runs
its own studio and no longer depends on home base.
Expand Down
Loading
Loading