From 8d572e59e36f7fcdbe2805b38fd253e2d1252bf2 Mon Sep 17 00:00:00 2001 From: John Cheng Date: Sun, 3 May 2026 07:00:48 -0700 Subject: [PATCH 1/2] =?UTF-8?q?domain-skills:=20neon=20=E2=80=94=20console?= =?UTF-8?q?.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit console.neon.tech navigation, branch picker, finding compute endpoint hostnames, and the connection-string whitespace trap (the connect dialog renders the host across multiple inline spans, so naive textContent reads yield 'aws .neon.tech' — strip all whitespace, since postgres URLs can't legally contain any). Also corrects a piece of folklore: free-plan branches do NOT share one compute endpoint — each branch has its own, observable in the Branches table's Primary compute column. Co-Authored-By: Claude Opus 4.7 (1M context) --- domain-skills/neon/console.md | 123 ++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 domain-skills/neon/console.md diff --git a/domain-skills/neon/console.md b/domain-skills/neon/console.md new file mode 100644 index 00000000..397c4f65 --- /dev/null +++ b/domain-skills/neon/console.md @@ -0,0 +1,123 @@ +--- +name: neon-console +description: Neon Postgres console (console.neon.tech) — project/branch navigation, finding compute endpoint hostnames, extracting connection strings without picking up the UI's display-whitespace. +--- + +# Neon Console — console.neon.tech + +Serverless Postgres dashboard. Auth via SSO; treat as already-logged-in. The UI is a SPA (Next.js). + +## Routes + +| Route | What | +|---|---| +| `/app/org-/projects` | Org-scoped project list (default landing) | +| `/app/projects/` | Project dashboard (Connect button lives here) | +| `/app/projects//branches` | Branches table: name, parent, compute hours, primary compute endpoint, storage | +| `/app/projects/?branchId=&database=` | Project dashboard scoped to a branch — what the left-nav BRANCH picker switches between | + +## Branches table — what the columns actually mean + +Free plan typically shows two branches (`production` + `test`). **Each branch has its own primary compute endpoint** with its own hostname (`ep--..aws.neon.tech`) — they are NOT shared. Earlier docs/folklore claiming "free plan shares one compute across branches" is wrong. + +- `Compute` column = CU-hrs consumed in current period. +- `Primary compute` column shows autoscale range (e.g. `.25 ↔ 2 CU`) and an **Idle/Active** pill. The `.25 ↔ 2 CU` text *looks* like a link but it's actually a clickable cell that opens the **Edit primary compute** drawer — that drawer shows the endpoint name (`ep-<...>`) in an editable input. + +### Getting an endpoint hostname for a branch + +```python +# On /app/projects//branches +rect = js(""" + (() => { + const rows = [...document.querySelectorAll('tr')].filter(tr => /production/i.test(tr.textContent || '') && /Default/.test(tr.textContent || '')); + if (!rows.length) return null; + const tr = rows[0]; + // Find the .25 ↔ 2 CU compute cell + const all = [...tr.querySelectorAll('*')]; + const cu = all.find(el => /CU/.test((el.textContent || '').trim()) && /↔/.test(el.textContent || '') && el.children.length <= 1); + if (!cu) return null; + const r = cu.getBoundingClientRect(); + return {x: r.x + r.width/2, y: r.y + r.height/2}; + })() +""") +click(rect["x"], rect["y"]) +wait(1) +endpoint = js("document.querySelector('input[value^=\"ep-\"]')?.value") +press_key("Escape") # close drawer +``` + +The compute cell wraps to two visual lines on rows with multi-digit CU-hrs; clicking the centre of the cell sometimes lands between lines and opens a tooltip instead of the drawer. If `endpoint` is `None`, retry by clicking the row's cell at `r.x + 30, r.y + r.height/2` (left-justified, single-line target). + +## Branch picker (left nav, "BRANCH" combobox) + +Below the PROJECT nav. Currently selected branch's name is shown in a button at roughly `x=124, y=310` for a default 1442×1508 viewport. Clicking opens a dropdown listing all branches with a checkmark on the current one. + +```python +# Switch the dashboard to the production-branch context +js(""" +(() => { + const btn = [...document.querySelectorAll('button')].find(b => /^test$/i.test((b.textContent || '').trim()) && b.getBoundingClientRect().x < 200); + btn?.click(); +})() +""") +wait(1) +js("""[...document.querySelectorAll('div')].find(el => (el.textContent || '').trim() === 'production' && el.getBoundingClientRect().x < 250)?.click()""") +wait(1) # URL updates to ?branchId=... +``` + +The branch picker scopes the **Connect** dialog (and most dashboard widgets) to that branch — so to get a branch's connection string, switch the picker first, then click Connect. + +## Getting a connection string — the whitespace trap + +Project dashboard → **Connect** button (top-right) opens "Connect to your database". Branch + Compute dropdowns let you pick role/database/pooled-vs-direct. **Show password** is a button that toggles password visibility. + +The connection string is rendered inside a `
` (NOT a `