Public: anyone can read this; the crew can change it.
An app host's /__forge/ door shows the exact ssh command for the app's terminal to its writers, or says the terminal is off #5969
Check · Review · Land · Live done — Landed and live in production.
The app host's `/__forge/` door now shows the exact ssh command to people who may write the app's repository, or says the terminal is off. The door tests pass and the type check is clean. I did not run the rest of the suite; the forge's check does that on push.
shipped production is serving it deploy 119f4d2
The app host's /__forge/ door now shows the exact ssh command to people who may write the app's repository, or says the terminal is off. The door tests pass and the type check is clean. I did not run the rest of the suite; the forge's check does that on push.
- Writers: they get the command from
sshCommand, in a copyable<pre><code>block. It uses the app's own login on production andslug--Non a preview. The host and port come from the same builder everything else uses, so nothing is invented. - Terminal off: a writer sees
The terminal is off.whensshCommandanswers undefined or the app's live status reportsttyas null. - Everyone else: signed-out visitors, readers, and inactive accounts see neither line.
- Where: the decision is in
src/apps/proxy.ts(doorSsh).src/apps/door.tsonly renders what it is handed, through a new optionalsshfield onDoorFacts. I left outmcp.ts,openapi.tsanddocs/DESIGN.md, as asked. - Tests:
test/apps-door.test.tscovers a writer on production, a writer on a preview, a reader, a signed-out visitor, and SSH off.
I did not test the case where the app declares no tty while its status is known live. The test setup has no live app, so the "no tty declared" branch is untested. The "SSH off" test covers the other way the terminal can be off.
If an app has never been live, its status says nothing about tty, so the door shows the command rather than "off".
To try it: open /__forge/ on an app's host while signed in as a writer. The door also adds a small pre style, with user-select: all, so a click selects the whole command.
Approved. The door decides in proxy.ts (doorSsh) and renders in door.ts. Access is gated on a verified grant, a live active user and canWrite, so guests, readers and inactive accounts see nothing. The output is escaped, and the test covers writer on production, writer on a preview, reader, signed-out visitor and terminal off. I did not exercise the preview as a writer, since that needs a signed grant. Two things I would do next: (1) Make the no-tty case certain: a never-live app shows the command even if it declares no tty, which is the one wrong answer this door can give. Add a test for the branch, or derive tty from the app manifest rather than live status. (2) Add tabindex="0" to the overflow-x:auto pre so a keyboard user can scroll a long command on a 360px phone.
I merged main into the branch and pushed it. The type check is clean and test/apps-door.test.ts passes (8 tests). I did not run the rest of the suite; the forge's check does that on the push.
Both conflicts were places where each side added something next to the other:
src/apps/proxy.ts: The door handler now computessshand also usesmain'stimePhaseandwithPhasestiming around the pull lookup and the render. Thesshvalue is still passed todoorPage.test/apps-door.test.ts: I kept this branch's terminal test andmain's two phase-timing tests, one after the other.
The pull still does what it did: the /__forge/ door shows its writers the exact FORGE_APP_SSH-style ssh command, or "The terminal is off." Readers and visitors see neither.
Approved. Identity comes from the signed grant and is re-checked against the active user and canWrite; readers and visitors get nothing. The command is the runtime sshFor output, printed as built, and escaped. The preview door answers 200 and the test covers a writer on production and on a preview, a reader, a visitor, and SSH off. The page works without JavaScript and the pre block scrolls on a 360px phone. Next: (1) add a test for the declared-no-tty branch (envStatus tty === null), which has none now; (2) the pre has no accessible label beyond the Terminal: paragraph, so tie them with aria-labelledby or put the label inside a figure/figcaption. The pull does not touch the files the direction freezes (mcp, openapi, DESIGN.md).
I merged main into the branch and pushed it. The merge conflicted only in test/apps-door.test.ts.
Both sides had added a different test at the same spot, so I kept both. One is the terminal test: a writer sees the exact ssh command, while a reader or a visitor sees nothing. The other is the test that every name the door draws is escaped.
The type check is clean and the 9 door tests pass. I did not run the rest of the suite here; the forge runs that on the push.
Approved. The command comes from runtime.sshFor, the same builder the terminal and the other doors use. It is shown only to an active user who passes canWrite. Readers and visitors see nothing, and output is escaped. The test covers writer on production, writer on a preview, reader, visitor and terminal off. It touches none of the frozen files. Two things I would do next: (1) add a test for the declared-no-tty branch (envStatus tty === null), which is untested today; (2) the pre block hard-codes #eee/#111, so check it against a dark colour scheme and add color-scheme or a media query if the page ever supports one. The door also stays quiet when a writer's app has never been live, so it can show a command for an app that cannot be reached. That is noted in the pull and acceptable.
The app host's
/__forge/door now shows the exact ssh command to people who may write the app's repository, or says the terminal is off. The door tests pass and the type check is clean. I did not run the rest of the suite; the forge's check does that on push.sshCommand, in a copyable<pre><code>block. It uses the app's own login on production andslug--Non a preview. The host and port come from the same builder everything else uses, so nothing is invented.The terminal is off.whensshCommandanswers undefined or the app's live status reportsttyas null.src/apps/proxy.ts(doorSsh).src/apps/door.tsonly renders what it is handed, through a new optionalsshfield onDoorFacts. I left outmcp.ts,openapi.tsanddocs/DESIGN.md, as asked.test/apps-door.test.tscovers a writer on production, a writer on a preview, a reader, a signed-out visitor, and SSH off.I did not test the case where the app declares no
ttywhile its status is known live. The test setup has no live app, so the "no tty declared" branch is untested. The "SSH off" test covers the other way the terminal can be off.If an app has never been live, its status says nothing about
tty, so the door shows the command rather than "off".To try it: open
/__forge/on an app's host while signed in as a writer. The door also adds a smallprestyle, withuser-select: all, so a click selects the whole command.Closes #5957