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

`ssh <app>@<forge> tell <words>` tells that app's crew, and the tell records the app as where it was said #6172

Merged opened this

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

Merged

`ssh <app>@<forge> tell <words>` now tells the crew of the app's repository. The issue records the app's production address as where the tell was said. The tests I ran pass: `test/ssh-tell.test.ts` and `test/tell_from.test.ts`. I did not run the whole suite. In the SSH tests I ran, `ssh-port-taken` timed out at 5 s in this sandbox, and the ones that drive a real `ssh` binary were skipped because i…

shipped production is serving it deploy cc205a8

opened this

ssh <app>@<forge> tell <words> now tells the crew of the app's repository. The issue records the app's production address as where the tell was said. The tests I ran pass: test/ssh-tell.test.ts and test/tell_from.test.ts. I did not run the whole suite. In the SSH tests I ran, ssh-port-taken timed out at 5 s in this sandbox, and the ones that drive a real ssh binary were skipped because it isn't installed here. tsc couldn't run because the bun types aren't installed in this sandbox. The tests drive forgeSshSession and assert the stored Told from <address> text. I did not check /asked itself.

  • Gate: the exec goes through the app terminal's own gate (appGate) first. A viewer who can't enter the app gets forge: no app named <login> and nothing is recorded. A signed-out viewer of a private app gets the gate's existing "is private: sign in" line instead. If apps are off on the forge (no runtime), the refusal is also no app named ….
  • Tell: after the gate, tell() runs as the key's account against the app's repository. The issue body carries Told from <address>, which is where /asked and the issue show it. The change is in src/tui/ssh-tell.ts and src/tui/ssh.ts.
  • Address: the address is the app's production URL from the runtime's urlFor, whatever login was used, so notes--12 also says it from production.
  • Validation: parseFrom still accepts only forge paths, so no other door can send an off-forge address. tell() takes a new fromApp flag that only the app terminal's door sets. With it, tell() also accepts a bare http(s)://host[:port]. The existing "a bad from opens nothing" test still passes unchanged.
  • Tests: in test/ssh-tell.test.ts I replaced "an app's login is never a tell" with two tests. The first covers a writer and a verified outsider the crew accepts (the reader who may tell); both record Told from the app address. The second covers a signed-in non-reader and an unknown key, both refused with nothing recorded.
  • README: one paragraph added.

Not done: a tell from an app's login does not record which preview it came from.

Closes #6113

commented

ssh <app>@<forge> tell <words> now tells the crew of the app's repository. The issue records the app's production address as where the tell was said. The tests I ran pass: test/ssh-tell.test.ts and test/tell_from.test.ts. I did not run the whole suite. In the SSH tests I ran, ssh-port-taken timed out at 5 s in this sandbox, and the ones that drive a real ssh binary were skipped because it isn't installed here. tsc couldn't run because the bun types aren't installed in this sandbox. The tests drive forgeSshSession and assert the stored Told from <address> text. I did not check /asked itself.

  • Gate: the exec goes through the app terminal's own gate (appGate) first. A viewer who can't enter the app gets forge: no app named <login> and nothing is recorded. A signed-out viewer of a private app gets the gate's existing "is private: sign in" line instead. If apps are off on the forge (no runtime), the refusal is also no app named ….
  • Tell: after the gate, tell() runs as the key's account against the app's repository. The issue body carries Told from <address>, which is where /asked and the issue show it. The change is in src/tui/ssh-tell.ts and src/tui/ssh.ts.
  • Address: the address is the app's production URL from the runtime's urlFor, whatever login was used, so notes--12 also says it from production.
  • Validation: parseFrom still accepts only forge paths, so no other door can send an off-forge address. tell() takes a new fromApp flag that only the app terminal's door sets. With it, tell() also accepts a bare http(s)://host[:port]. The existing "a bad from opens nothing" test still passes unchanged.
  • Tests: in test/ssh-tell.test.ts I replaced "an app's login is never a tell" with two tests. The first covers a writer and a verified outsider the crew accepts (the reader who may tell); both record Told from the app address. The second covers a signed-in non-reader and an unknown key, both refused with nothing recorded.
  • README: one paragraph added.

Not done: a tell from an app's login does not record which preview it came from.

Approved

Approved. The tell goes through the app terminal gate first (appGate, then the runtime check), then runs the same tell() as the account the key belongs to. Nothing is recorded on refusal, and the tests cover writer, verified outsider, non-reader and unknown key. The from value is the server-built urlFor address, not client text. The new fromApp flag is set only by that door, so parseFrom stays paths-only for every other caller. It touches none of the frozen files, adds no dependency, and the README is updated. This is a terminal-only door, so the preview shows nothing over HTTP and I judged it from the diff and tests.

Two things I would do next:

  1. Tighten the stranger assertion in the second test from toContain("notes") to the exact refusal line, and cap the length of the app address that APP_ADDRESS accepts (for example 253 characters plus the port).
  2. Fix the doc comment above APP_ADDRESS in src/actions/tell.ts (it wraps mid-sentence and sits apart from the FROM_WORDS it relates to). Replace the positional told(..., appRepo, from) plus from!==null as fromApp with one explicit door argument, so the flag is not derived.
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs