Public: anyone can read this; the crew can change it.

The terminal lists your connected origins, syncs one now with `s` and disconnects one with `d` after a confirm, as Settings › Origins does #8010

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

The terminal now has a "Connected origins" palette entry. It lists your origins, `s` syncs the selected one now, and `d` disconnects it after a confirm.

shipped production is serving it deploy a4add02

opened this

The terminal now has a "Connected origins" palette entry. It lists your origins, s syncs the selected one now, and d disconnects it after a confirm.

What changed

  • List. src/tui/screens/connections.ts shows host, account, repository count and last synced for each origin, and flags an origin whose last sync failed.
  • Palette entry. The origins entry is offered to a signed-in person who isn't an agent. In entries.ts the import and the entry sit directly after cloud.
  • s. It calls syncOriginNow and toasts the report in the module's words, or its error in danger tone.
  • d. It opens confirmScreen with the confirm page's disconnect detail, Cancel first. Choosing Disconnect calls disconnectOrigin and toasts the module's sentence.
  • Shared words. The page's sentences moved into src/actions/origin_words.ts, and src/web/pages/origins.ts imports them unchanged.
  • One addition you didn't ask for. The confirm detail text also lives in origin_words.ts as DISCONNECT_DETAIL. src/web/pages/search.ts now imports it, so the page and the terminal can't drift apart.

What I left out

  • The tests don't call syncOriginNow, so nothing reaches a host. s is covered by the type check only.
  • There's no connect, re-authorize or token replacement from the terminal.

Tests

  • test/tui-origins.test.ts. It covers the list showing a seeded origin and never its token, d then Cancel keeping the origin, d then Disconnect removing it with the toast, and a guest not being offered the entry. It would fail without the change.
  • Checks run. tsc, scripts/gate.ts and scripts/design-lint.ts pass. So do the new test and the five neighbouring tests I picked (origin-words, origins-reconnect, origins-security-auth, confirm-parent-timing, tui-migrate).
  • Not run here. scripts/fast.ts said the diff was too broad to name, so I didn't run the full suite. The forge's check runs it on this push.

Try it: SSH to the terminal with FORGE_APP_SSH, press ctrl+k, type "Connected origins", then use j/k, s and d.

Closes #8000

commented

The terminal now has a "Connected origins" palette entry. It lists your origins, s syncs the selected one now, and d disconnects it after a confirm.

What changed

  • List. src/tui/screens/connections.ts shows host, account, repository count and last synced for each origin, and flags an origin whose last sync failed.
  • Palette entry. The origins entry is offered to a signed-in person who isn't an agent. In entries.ts the import and the entry sit directly after cloud.
  • s. It calls syncOriginNow and toasts the report in the module's words, or its error in danger tone.
  • d. It opens confirmScreen with the confirm page's disconnect detail, Cancel first. Choosing Disconnect calls disconnectOrigin and toasts the module's sentence.
  • Shared words. The page's sentences moved into src/actions/origin_words.ts, and src/web/pages/origins.ts imports them unchanged.
  • One addition you didn't ask for. The confirm detail text also lives in origin_words.ts as DISCONNECT_DETAIL. src/web/pages/search.ts now imports it, so the page and the terminal can't drift apart.

What I left out

  • The tests don't call syncOriginNow, so nothing reaches a host. s is covered by the type check only.
  • There's no connect, re-authorize or token replacement from the terminal.

Tests

  • test/tui-origins.test.ts. It covers the list showing a seeded origin and never its token, d then Cancel keeping the origin, d then Disconnect removing it with the toast, and a guest not being offered the entry. It would fail without the change.
  • Checks run. tsc, scripts/gate.ts and scripts/design-lint.ts pass. So do the new test and the five neighbouring tests I picked (origin-words, origins-reconnect, origins-security-auth, confirm-parent-timing, tui-migrate).
  • Not run here. scripts/fast.ts said the diff was too broad to name, so I didn't run the full suite. The forge's check runs it on this push.

Try it: SSH to the terminal with FORGE_APP_SSH, press ctrl+k, type "Connected origins", then use j/k, s and d.

commented

Two of the three failing tests are fixed and pushed. The third, "enter on an unparsable row shows its reason", I left alone.

  • Palette roster tests: the two roster tests failed because the new "Connected origins" palette entry is shown to site-admin and member people, and the expected lists in test/palette-roster.test.ts didn't have it. I added it to both lists, before "Failure domains" for the admin and before "Front page" for the member. The agent and signed-out lists are unchanged, since they don't show the entry. The test was wrong, not the code.
  • Waves test: it passes when I run it here. It sends fixed keystrokes to the terminal and looks like a timing flake on a loaded shard, not something this change touches, so I didn't edit it. If it fails again on the forge, that points to a real problem.

test/palette-roster.test.ts and test/tui-waves.test.ts pass together (15 tests), and bun x tsc --noEmit is clean. I haven't re-run the full check; the forge will on this push.

Changes requested — before the latest push

Sound shape: it reuses disconnectOrigin/syncOriginNow, which check the actor and emit the bus event, and the entry is hidden from guests and agents. Two things to fix in one round:

  1. s has no test. The pull's own description says it is covered only by the type check, and the rule is that every behaviour a change adds has a test that would fail without it. Test s without reaching a host: for example, with no origins the key does nothing, and with the seeded origin (git.example.test is not resolvable or trusted) the toast shows the report's error in danger tone, or inject a stub. Also assert that a user cannot sync or disconnect another user's origin id (the not-found path).
  2. The README and docs do not say how to use it. Add the terminal door (palette 'Connected origins', j/k, s, d with confirm) to docs/ORIGINS.md next to the Settings › Origins text, and a line in the README's terminal section if it lists screens.

Minor: the agent exclusion in offered is not tested. The palette-roster agent list should stay unchanged, so add one assertion for that.

commented

Most of the review is addressed and pushed. The error toast for s is still untested, and the not-found toast on s is only covered at the action level. test/tui-origins.test.ts and test/palette-roster.test.ts pass (12 tests) and bun x tsc --noEmit is clean. I did not run the full suite.

What I added

  • s success: a test syncs a loopback origin, which the sync reaches without error, and asserts the "Synced 0 repositories." toast and that "never synced" is gone from the row. It fails if s does nothing.
  • s with no origins: the key does nothing and no "Syncing" toast appears.
  • Another user's origin: syncOriginNow returns not_found and disconnectOrigin refuses, so the owner's origin survives. The action-level refusal is tested, not the screen's NO_SUCH_ORIGIN toast.
  • Agents: the screen test checks that an agent is not offered the entry. test/palette-roster.test.ts also asserts that the agent roster has no origins id.
  • Docs: docs/ORIGINS.md now describes the terminal door (palette "Connected origins", j/k, s, d with confirm) next to the Settings › Origins text. The README gets one line, since it lists terminal features in prose.

What is not covered

  • Error toast on s: the sandbox denies the network, so an unreachable host can't fail quickly here. An unresolvable host such as git.example.test outlasted the 5-second test timeout, and a refused loopback port just synced zero repositories. A test that waits on DNS would be flaky, so I left it out. A stub that makes the sync report an error would cover it, but syncOrigin has no injection point, and adding one is outside this pull.
  • Not-found toast on s: the screen reads the origin list on each key press, so the id can't go missing between the list and the key. The toast line is untested on the screen itself.
the crew's run was interrupted: restart, resumes on the next pass — cancelled
Approved

Approved. The terminal door matches the page. Connected origins is offered only to a signed-in non-agent. s and d go through syncOriginNow and disconnectOrigin, which check the actor and scope by owner. d asks first, with Cancel as the first choice. The sentences are shared in origin_words.ts, so the page and the terminal cannot drift. The roster, docs/ORIGINS.md and README are updated. Tests cover the list, s success, s with no origins, another user's id, agent and guest not offered, and d with Cancel and with Disconnect. The web edits only swap strings for shared constants, so docs/DESIGN.md is untouched. I did not run the tests or the terminal on the preview, and the preview does not serve the terminal.

Two things I would do next:

  1. Give syncOrigin an injection point so the s error toast and the screen's NO_SUCH_ORIGIN toast can be tested without a network call.
  2. Replace the 100ms poll loop in the s test with a wait on the toast or the bus event, so it cannot flake on a loaded shard.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs