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

The app page's Adapter section has Pull now, as the API and MCP already do #10144

Merged opened this

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

Merged

The Adapter section on the app page now has a **Pull now** button, shown to a writer only. The new test file, `test/adapter-card.test.ts`, `test/app-pull-now.test.ts`, `test/mcp-size.test.ts` and `test/hot-reads-indexed.test.ts` pass. So do `bun x tsc --noEmit`, `bun scripts/design-lint.ts` and `bun scripts/gate.ts`. I did not run the full suite, since the forge runs it on push.

shipped production is serving it deploy ef7edf1

opened this

The Adapter section on the app page now has a Pull now button, shown to a writer only. The new test file, test/adapter-card.test.ts, test/app-pull-now.test.ts, test/mcp-size.test.ts and test/hot-reads-indexed.test.ts pass. So do bun x tsc --noEmit, bun scripts/design-lint.ts and bun scripts/gate.ts. I did not run the full suite, since the forge runs it on push.

What changed

  • Button: adapterCard in src/web/studio/adapter.ts takes the request context and the repo. A writer gets a same-origin POST form under the rows; a reader or visitor sees none.
  • Route: POST /:owner/:name/app/pull (adapterPull, registered in src/http/server.ts) calls pullNow, the same function the API and MCP use.

- A non-writer, or a repo with no app, gets 404. - A cross-origin POST gets 403, from readForm. - Success redirects to the app page, where Last pull shows the new run. - A refusal redirects with ?pull=<code>, and the card shows that sentence from PULL_NOW_REFUSALS in one <p class="muted small">, not a banner. Only codes pullNow can return are believed; anything else shows nothing.

  • Tests: test/adapter-pull-button.test.ts covers five cases.

- The button is shown to a writer and not to a reader. - A writer's POST records a pull run. - A reader's POST gets 404 and records nothing. - A cross-origin POST is refused. - A refusal sentence appears, and an unknown code shows nothing.

  • Docs: docs/features/adapters-card.md says where the button is.

Things to know

  • /<owner>/<repo>/app answers 302 to /<owner>/<repo>, which is where the app page actually lives. The redirect after a pull therefore goes to /<owner>/<repo>, because a redirect through /app would lose the ?pull= query.
  • The MCP is untouched: no new tool and no ceiling changes.
  • I did not add a flash banner, a JSON variant of the route, or a second pull path.

To try it, sign in as a writer on an app whose forge.json declares an adapter, open the app page, and press Pull now.

🤖 Generated with Claude Code

Closes #10125

commented

The Adapter section on the app page now has a Pull now button, shown to a writer only. The new test file, test/adapter-card.test.ts, test/app-pull-now.test.ts, test/mcp-size.test.ts and test/hot-reads-indexed.test.ts pass. So do bun x tsc --noEmit, bun scripts/design-lint.ts and bun scripts/gate.ts. I did not run the full suite, since the forge runs it on push.

What changed

  • Button: adapterCard in src/web/studio/adapter.ts takes the request context and the repo. A writer gets a same-origin POST form under the rows; a reader or visitor sees none.
  • Route: POST /:owner/:name/app/pull (adapterPull, registered in src/http/server.ts) calls pullNow, the same function the API and MCP use.

- A non-writer, or a repo with no app, gets 404. - A cross-origin POST gets 403, from readForm. - Success redirects to the app page, where Last pull shows the new run. - A refusal redirects with ?pull=<code>, and the card shows that sentence from PULL_NOW_REFUSALS in one <p class="muted small">, not a banner. Only codes pullNow can return are believed; anything else shows nothing.

  • Tests: test/adapter-pull-button.test.ts covers five cases.

- The button is shown to a writer and not to a reader. - A writer's POST records a pull run. - A reader's POST gets 404 and records nothing. - A cross-origin POST is refused. - A refusal sentence appears, and an unknown code shows nothing.

  • Docs: docs/features/adapters-card.md says where the button is.

Things to know

  • /<owner>/<repo>/app answers 302 to /<owner>/<repo>, which is where the app page actually lives. The redirect after a pull therefore goes to /<owner>/<repo>, because a redirect through /app would lose the ?pull= query.
  • The MCP is untouched: no new tool and no ceiling changes.
  • I did not add a flash banner, a JSON variant of the route, or a second pull path.

To try it, sign in as a writer on an app whose forge.json declares an adapter, open the app page, and press Pull now.

🤖 Generated with Claude Code

commented

The gate failed because no commit message had a "Try:" line. I added an empty commit that has one and pushed it. I did not change any code or tests. bun scripts/gate.ts printed nothing when I ran it, so I read that as passing, and I did not re-run the tests or the type check.

The Try line says: open /alice/hello on the preview as a writer of an app whose forge.json declares an adapter, and press Pull now under the Adapter rows. Last pull should then show the new run.

The pull itself is unchanged: a Pull now button on the app page's Adapter section for a writer only. It posts same-origin to POST /<owner>/<repo>/app/pull, which calls pullNow. A non-writer gets 404, and a refusal shows its sentence in one muted line. test/adapter-pull-button.test.ts covers it, and docs/features/adapters-card.md says where the button is.

🤖 Generated with Claude Code

Changes requested — before the latest push

The web door works and is well tested, but the terminal door is missing, and the checklist makes that a change request.

Fix first: the terminal Adapter screen (src/tui/screens/adapter.ts) has no Pull now. Add a key on that screen that calls pullNow as the signed-in writer. It should be hidden from non-writers, show the PULL_NOW_REFUSALS sentence on refusal, and show the new run live. Add a TUI test for it, and mention it in docs/features/adapters-card.md, which currently documents the terminal screen as read-only rows.

Smaller: the trailing space after page(aliceRw, "?pull=asleep"); in the test.

The rest is fine: the same-origin check comes from readForm, the writer gate returns 404, the ?pull= code is allow-listed with Object.hasOwn, output is escaped, README is untouched, and there is no new dependency.

commented

The terminal Adapter screen now has Pull now on p for a writer, as the page does. The adapter TUI and button tests pass (11 tests), and bun scripts/gate.ts and bun x tsc --noEmit printed nothing. I did not re-run the MCP size test, the design lint or the wider suite for this push.

  • Terminal key: p in src/tui/screens/adapter.ts calls pullNow as the signed-in person.

- Writers only: it is listed in the key bar only for a writer, and a reader's p does nothing. - Success: a toast "Pulled." appears and the rows are read again, so the new run shows at once. - Refusal: the PULL_NOW_REFUSALS sentence is toasted instead. - Repeat presses: a second p while a pull is running is ignored.

  • Tests: test/adapter-tui.test.ts has three new cases, all passing.

- A writer's p records a run and shows "Pulled." - A refused pull (asleep app) shows its sentence and records nothing. - A reader has no key, and nothing is pulled. - They call the screen's key handler directly, not through the ssh input path. They also pass a stand-in for the pull's reach, as test/app-pull-now.test.ts does.

  • Docs: docs/features/adapters-card.md now says the terminal screen is no longer read-only and describes p. The screen's header comment says the same.
  • Test nit: I stripped trailing spaces in test/adapter-pull-button.test.ts. The line you pointed at had been rewritten earlier, so the only change there is the strip.

To try it, ssh in as a writer, open a repository whose app declares an adapter, choose "Adapter" in the palette and press p.

🤖 Generated with Claude Code

commented

I merged main into this branch, resolved the three conflicts keeping both sides, and pushed. The type check and the adapter tests pass (28 tests, 5 files). The design lint and scripts/gate.ts showed no failures. I did not run the full suite; the forge's check will run it on this push.

The Adapter section of the app page now keeps the Pull now button and its refusal line, and shows main's "Pull runs" list underneath. The terminal Adapter screen keeps p for a writer and main's pull-run rows. docs/features/adapters-card.md has both descriptions.

In src/web/studio/adapter.ts, adapterCard still takes (ctx, record, repo), as it did on this branch. It no longer takes main's (app, record).

Pull now on the app page's Adapter section. A writer gets a button that posts same-origin to POST /<owner>/<repo>/app/pull and calls pullNow, the function the API and MCP use. It returns to the app page. A refusal shows its PULL_NOW_REFUSALS sentence in one muted line. Anyone who can't write gets a 404 and no button.

Pull now in the terminal. The Adapter screen has p for a writer. It calls pullNow, toasts the refusal sentence if there is one, and reads the rows again so the new run shows at once.

To try it, open the app page on the preview at https://lab--10144--forge-trevato-apps.open-platform.sh as someone who can write to the repository.

commented

I merged main into the branch and pushed. bun x tsc --noEmit is clean and the adapter tests pass (28 tests across 5 files). scripts/gate.ts printed nothing, which I read as clean. I did not run the full suite.

main had already added its own p Pull now to the terminal Adapter screen, so I kept its version. That meant taking main's src/tui/screens/adapter.ts and test/adapter-tui.test.ts whole, which drops this branch's terminal p code and its tests. docs/features/adapters-card.md now has main's terminal wording.

What this pull still adds is the app page's Pull now button: a writer-only form that posts to POST /<owner>/<repo>/app/pull, calls pullNow, and returns to the page. A refusal shows as ?pull=<code> and its sentence from PULL_NOW_REFUSALS.

To try it, open the app page on the preview at https://lab--10144--forge-trevato-apps.open-platform.sh as someone who can write to the repository.

Approved

Clean. The Pull now form is writer-only and posts same-origin. readForm gives the cross-origin 403, and a non-writer or an app-less repo gets 404. The route calls pullNow. A ?pull= code is believed only if it is a key of PULL_NOW_REFUSALS, and the sentence is escaped in one muted small line, so there is no injection or banner. The terminal p key came from main, so both doors have it. The docs are in adapters-card.md and not the README. The five tests cover button visibility, a recorded run, 404 for a reader, 403 cross-origin, and the refusal line. The design uses btn and a post form, adds no accent, and works with JavaScript off. I could not diff against 89b68b54720c (commit not in the clone), so I read the full diff. Non-blocking: the 303 and the ?pull= query go to the repo root because /app redirects there, as the pull description notes.

the crew's run was interrupted: restart, resumes on the next pass — cancelled
Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs