Skip to content

feat(web,mobile): your devices in Linked environments - #170

Merged
jayleaton merged 3 commits into
mainfrom
feat/linked-devices-rows
Oct 30, 2026
Merged

jayleaton merged 3 commits into
mainfrom
feat/linked-devices-rows

Conversation

@jayleaton

@jayleaton jayleaton commented Oct 30, 2026 •

Copy link
Copy Markdown
Owner

Linked environments listed only the links this machine made, so you couldn't see or manage your other tailnet devices' access.

What changed

  • Shared (packages/client-runtime):
    • state/tailnetDevices wraps tailnetDevices.list | setAccess | updateSettings | openDevice. The three mutations use createEnvironmentRpcCommand, and the UI gates on their permissionAtom.
    • tailnet-devices holds linkedDeviceRows, which merges the device list, this environment's links and this app's saved environments by environmentId. It also holds isTailnetDevicesForbidden.
  • Web, in the Linked environments section:
    • Header rows: "Link my tailnet devices automatically", "Only devices with the T3 capability" (requireCapability) and "Access for new devices", all through updateSettings.
    • Device rows: status, Tailnet or Paired, an access dropdown, Revoke/Restore, and Forget when a link exists.
    • Open calls openDevice, then ConnectionOnboarding.registerDevice from feat(server,client-runtime): apps open any of my devices without a code #173, so there's one redemption path. A device below full access shows "Opens read-only", matching the server's scope rule. Open doesn't show for devices already saved here.
  • Mobile, in LinkedEnvironmentsSection: the same rows. Tapping a row expands its access levels, Revoked included. Revoke asks to confirm; choosing a level restores the device.
  • Servers without the device RPCs (older versions): listing devices fails there. The section shows a quiet "not available on this server yet" note and keeps showing links. An authorization failure hides the device rows instead.
  • Docs: docs/user/remote-access.md gets a "Your tailnet devices" section: automatic linking on one Tailscale account, access and revoke/restore, pairing codes for everything else, and the t3.codes/device capability option. The Labs paragraph now says linked environments is on by default.

Risk: low. Changes are confined to the Linked environments section and new client-runtime modules. Open only adds an environment through the existing onboarding path.

Verification

  • vp test run src/tailnetDevices.test.ts (client-runtime): 3 passed.
    • Row merge.
    • The real wire shape: a snapshot shaped like TailnetDevices.list output decodes through the contract's JSON codec into the expected rows (revoked incoming-only device, tailnet link, paired link).
    • Forbidden vs unavailable.
  • Typecheck clean (uncached) for client-runtime, web and mobile.
  • Lint clean on changed files.

Screenshots: placeholder, coming from Captain's integrated pass.

🤖 Generated with Claude Code · Claude Opus 5.5 in T3 Code

@jayleaton
jayleaton force-pushed the feat/linked-devices-rows branch from 7d26952 to f670495 Compare October 30, 2026 10:15
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XL and removed size:XXL labels Oct 30, 2026
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 5.0 KiB 5.0 KiB 0 B (0.0%) 6.8 KiB ✅
Codex Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.2 KiB 1.2 KiB 0 B (0.0%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 21.6 KiB 21.6 KiB 0 B (0.0%) 24.4 KiB ✅
Codex Live turn messages 2 2 0 (0.0%) 8 ✅
Claude Total thread wire 5.0 KiB 5.0 KiB +29 B (+0.6%) 6.8 KiB ✅
Claude Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.2 KiB 1.3 KiB +29 B (+2.3%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 21.9 KiB 21.9 KiB +41 B (+0.2%) 24.4 KiB ✅
Claude Live turn messages 1 2 +1 (+100.0%) 8 ✅

Baseline: 8bcd7d1 · PR result: af71d17 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@jayleaton
jayleaton force-pushed the feat/linked-devices-rows branch from f670495 to 422f385 Compare October 30, 2026 10:52
@jayleaton
jayleaton changed the base branch from feat/mesh-contracts-pr2 to feat/tailnet-device-open October 30, 2026 10:52
@jayleaton
jayleaton changed the base branch from feat/tailnet-device-open to main October 30, 2026 10:58
jayleaton and others added 3 commits October 30, 2026 17:59
Linked environments listed only this machine's links, so your other tailnet
devices and their access were invisible. The section now merges the server's
device list with its links by environmentId: each device shows how it is
linked, its status, an access level, Revoke/Restore, and on web Open, which
adds it to this app without a pairing code. The header holds automatic
linking and the default access. Servers that cannot list devices yet show a
quiet "not available" note instead of an error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Open now asks the host for a credential and hands it to
ConnectionOnboarding.registerDevice, the one path that redeems it at the
first address answering as that device. Rows note when a device below full
access opens read-only. The section also offers the stricter capability
rule, and the remote-access guide covers your tailnet devices.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@jayleaton
jayleaton force-pushed the feat/linked-devices-rows branch from 422f385 to af71d17 Compare October 30, 2026 11:00
@jayleaton
jayleaton marked this pull request as ready for review October 30, 2026 11:13
@jayleaton
jayleaton merged commit a2160b9 into main Oct 30, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant