Skip to content

Follow the coding agent on the locked dashboard (Paper LOCK-N) - #397

Merged
egeozin merged 2 commits into
mainfrom
feat/lock-page-live-steps
Oct 12, 2026
Merged

egeozin merged 2 commits into
mainfrom
feat/lock-page-live-steps

Conversation

@egeozin

@egeozin egeozin commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

What and why

People who try Tin in the browser hit the locked dashboard, and many never connect an agent. Production, since 14 Sep: 133 people signed in, and only 44 ever made a project call from their agent. 138 visitors saw the lock page; 68 ever reached the agent consent page. The old page said "Browser setup is not available yet" next to a single install line. It gave no next step and didn't change while the agent worked. It also stayed on the empty personal project after the agent had set up the business in a new one.

This builds Paper boards LOCK-N · A and LOCK-N · B and C (file thinklikeanagent, page OSS landing):

  • Three live steps replace the old copy:

    1. Run this in a terminal, inside your project (tabs and the copy box live in this step).
    2. Click Allow in the tab {Agent} opens.
    3. Tin reads your project and drafts a plan.
      Each step ticks as Tin sees it happen. Done steps show a moss check; while setup runs, step 3 shows a spinner and a mono "started {time}" line.
  • The plan opens in its project. When the onboarding run waits for picks or has finished, the page shows "{Project}'s plan is ready" and "Open {Project} →". About 3 s later the tab switches to that project by itself; the project list is reloaded first if the project is new to this tab.

  • The install line starts the agent too:

    • codex mcp add tin --url … && codex "Set up Tin"
    • claude mcp add -s user -t http tin … && claude "Set up Tin"

    Both live in LOCK_PAGE_COMMANDS in app.js; we're still testing the chained form with both agents, so it may change. The line is one line with an ellipsis on a desktop and wraps on a phone. Copy copies the full line; the toast says "Copied. Paste it in a terminal inside your project."

  • GET /api/projects/{project_id}/agent-setup is new. It checks membership and reads Postgres only, answering for the person across every project they belong to, because the agent usually creates a separate business project. It returns:

    • agent.connected_at: the earliest of the person's project_mcp_usage rows and their MCP-started runs (trigger_source = 'mcp').
    • agent.client: the latest trigger_client on those runs.
    • setup: their latest growth.onboarding run that wasn't superseded, with its project name. plan_ready is true for needs_input or succeeded.

    No migration.

  • Analytics: the lock page event endpoint also accepts agent_connected, setup_started and plan_ready. Each is sent once, and only when the open page watched that step happen, so it measures people who followed along.

Verification

  • uv run pytest -n auto against a disposable Postgres 17 (-c max_locks_per_transaction=1024): 5764 passed, 22 skipped, 2 failed. Both failures are in tests/test_schedule_sync_safety.py, where the localtime timezone is refused. That file and the schedule code aren't touched here.
  • New tests/test_agent_setup.py:
    • non-members get 404, and their request never reaches the per-person query;
    • states run against real migrations: nothing yet, connected by a project call, setup in another project, waiting for picks counts as ready, superseded runs / a teammate's run / a project you aren't in / a deleted project are ignored, and a browser-started run doesn't count as the agent.
  • tests/test_lock_page_event.py covers the new actions; tests/test_product_ui.py assertions are updated.
  • npm run test:browser: 148/148 web, 50 + 45 extension, all pass. web/lock-page.browser.test.js now covers:
    • state A: copy text per tab, the one-line clamp, the clipboard text and the toast;
    • A → B → C as the endpoint changes, the steps ticking, the 3 s switch to "Acme", and the step events;
    • opening while the plan is already ready (no step events; the button switches immediately);
    • phone width with no horizontal scroll.
  • uv run ruff format --check ., uv run ruff check ., uv run lint-imports: clean.
  • Screenshots of A, B and C in light and dark, and A at 390 px, came from the Playwright fixtures (synthetic data, TIN_LOCK_SCREENSHOTS). They match the boards; they're not attached here.

Notes

  • The "connected" signal comes from existing data. project_mcp_usage keeps only the latest call per project, so the time shown can be later than the agent's first call. Step 2 also ticks only at the first project-scoped call (usually get_started), not at list_projects or create_project, so there can be a short gap after Allow. Recording the first MCP call at sign-in would need a column; I left that out on purpose.
  • The unlocked rail's "Use your coding agent" block keeps its old lines and prompt; this PR changes only the locked page.
  • Fixture tests aren't a real run. Before calling this done, run it on production with a fresh account and each agent.

🤖 Generated with Claude Code

A browser sign-up whose project has nothing yet used to land on a page that
said "Browser setup is not available yet" next to one install line. Now the
page shows three steps and ticks them as Tin sees them: run the line, click
Allow in the tab the agent opens, and Tin reads the project. When the plan
waits for picks, the tab moves to the project the agent made, so nobody is
left watching the empty personal one.

The install line also starts the agent with "Set up Tin" (Codex, and Claude
Code with -s user), kept in one place in app.js. It stays one line with an
ellipsis on a desktop and wraps on a phone.

GET /api/projects/{id}/agent-setup is membership checked and reads Postgres
only: the person's project calls (project_mcp_usage) and MCP-started runs for
the agent, and their latest growth.onboarding run that was not superseded for
setup. No migration. The page polls it every 5 s while visible and records
the steps it watched as lock page events.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@egeozin
egeozin requested a review from a team as a code owner October 12, 2026 05:37
Claude Code's authenticate tool prints the sign-in link instead of opening a tab, and
its turn ends there, so step 2 says to open the link and reply. Codex keeps the tab copy.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@egeozin
egeozin merged commit 9e7aba9 into main Oct 12, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant