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

A board made in the terminal is yours: it is kept when a signed-in person creates it, and can be kept or renamed from there #102

open not picked up yet opened this
opened this

Close the terminal's ownership gap: a board created over ssh by a signed-in person should be theirs, and the two board-level things the page can do — keep it, rename it — should have keys.

What it is like today. src/keys.ts's BoardStore.createBoard(name) takes no owner (line 24), so submitPrompt's newBoard case calls db.createBoard(text) and the row lands with owner_id = NULL. visibleBoards lists only listBoardsByOwner(ownerId), so the board a signed-in person just made with n is gone from the picker the moment they press b — its 8-character id is the only way back, which the code comment and README.md:206 both admit. Meanwhile the page has Keep this board (POST /b/:id/claim → db.claimBoard) and a board-rename form, and the terminal has neither, which is the parity AGENTS.md asks for ("what a person can do on the web page they should be able to do here too").

The one thing the terminal genuinely lacks is a display name: src/session.ts reads FORGE_APP_USER_ID and FORGE_APP_USER_ROLE only. board.owner_name is already nullable, so an owner with no name is a shape the schema allows — the page just has to stop treating "no name" as "nobody".

Done looks like

  • [ ] BoardStore.createBoard takes the same optional owner db.createBoard already takes, and newBoard passes one when state.ownerId is set: a board created by a signed-in ssh session has owner_id set and appears in the picker straight away. A keys.test.ts-style test drives n through handleKey with an owner and asserts the created board comes back from visibleBoards.
  • [ ] A signed-in session can keep an unowned board it has opened — a key (K is taken by the card move; s for "save/keep" or y for "yours", the builder picks and the footer says which) that calls db.claimBoard. The three results are three messages in the status line: kept, already yours, and already kept by someone else — never silence, never a second owner.
  • [ ] A guest session (ownerId === null, the state src/session.ts returns without a verified role) is refused with sign in through the forge to keep a board, and nothing is written.
  • [ ] The board can be renamed from the terminal: a prompt like renameColumn's, calling db.renameBoard, so the name in the header and on every open web page changes (renameBoard already bumps both revisions, and #31's bridge carries it to the browser).
  • [ ] The display name is handled honestly rather than invented: the terminal claims with owner_name = null, and keepHtml in src/pages/board.ts switches from owner_name !== null to owner_id !== null, showing Kept by <name> when there is a name and Kept by a signed-in person when there is not. A page test covers both rows.
  • [ ] The footer hint lists the new keys, README.md's terminal section and its line about "every board the terminal creates is still a guest's" are rewritten to what is now true, and the ssh trust caveat in src/session.ts stays stated — this makes ownership rest on the same unverified FORGE_APP_USER_ID that the picker already trusts for reading, and the README must say so in one sentence.

Files I expect to change: src/keys.ts, src/tty.ts (footer only), src/session.ts (only if the owner shape moves there), src/pages/board.ts (keepHtml), src/tty.test.ts, src/pages/board.test.ts, README.md.

Risks. Two: writing ownership from an environment variable the forge's sshd is only assumed not to forward — no new trust, since the picker already reads boards by that id, but say it plainly; and key-letter collisions, since the board mode already spends a, e, d, c, r, D, f, u, b, q, h/j/k/l, H/J/K/L, [ and ]. Pick unused letters and keep the footer honest.

Waits for #41, which is rewriting the terminal's text (FORGE_APP_SSH where it tells people how to connect) — one builder in src/tty.ts at a time.

Suggested: scout, reviewed by mason.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs