diff --git a/docs/design/artboards/d215/README.md b/docs/design/artboards/d215/README.md index 51a4beaab..dbab5e0a5 100644 --- a/docs/design/artboards/d215/README.md +++ b/docs/design/artboards/d215/README.md @@ -3,6 +3,8 @@ The spec for D215 (artboard v2). Open `index.html` in a browser. The toggle at the top switches it between light and dark, and every D215 surface has a frame at 1440 and at 390. - `index.html` holds the before shots and live mocks for seven surfaces: sidebar, pod chat, task board, agent memory, agent settings, settings and connectors. The mock's names, messages and task titles are neutral samples. Counts and times come from the captures. +- A second block under agent settings draws the states of that page (policy and machine, identity edit, connector grants, runtime with the model and effort selects, own API key) at 1440 and 390. The runtime and key frames follow V2RuntimeControls and V2AgentProviderKey, including the stored-model refusal and the key-save error. Those frames carry `data-state`, so `measure_after.js` skips them and `targets.json` does not move. +- A block under Settings draws the free-plan Plan row and the administrator-only Administration group (`data-state="admin-free"`, 1440 and 390, also skipped by the scorer). - The theme switch (sun / moon, D224) sits in the rail above the avatar at 1440. At 390 there is no rail, so the same switch rides the Pods top bar, left of Search. It is a two-item segment: the item for the theme in effect is the white key. - `before/` holds prod captures from 2026-10-31, blurred so they show layout and density only. - `targets.json` holds the helper-word and scroll targets per frame. `cap/measure_after.js` writes it from `index.html`. diff --git a/docs/design/artboards/d215/cap/measure_after.js b/docs/design/artboards/d215/cap/measure_after.js index 37bb4d7f8..5f7ed4802 100644 --- a/docs/design/artboards/d215/cap/measure_after.js +++ b/docs/design/artboards/d215/cap/measure_after.js @@ -62,7 +62,7 @@ async function artboard() { await p.waitForTimeout(800); const res = await p.evaluate(() => { const out = {}; - document.querySelectorAll('.frame').forEach(f => { + document.querySelectorAll('.frame:not([data-state])').forEach(f => { const app = f.querySelector('.app'); f.style.setProperty('--s', 1); f.style.overflow = 'visible'; f.style.aspectRatio = 'auto'; f.style.height = app.offsetHeight + 'px'; f.style.width = app.offsetWidth + 'px'; f.style.maxWidth = 'none'; let words = 0; const w = document.createTreeWalker(app, NodeFilter.SHOW_TEXT); diff --git a/docs/design/artboards/d215/index.html b/docs/design/artboards/d215/index.html index 9d0e11eab..da0f1f67a 100644 --- a/docs/design/artboards/d215/index.html +++ b/docs/design/artboards/d215/index.html @@ -355,6 +355,10 @@ details.disc > summary .chev { color: var(--ph); transition: transform 160ms; } details.disc[open] > summary .chev { transform: rotate(180deg); } .dbody { padding: 0 16px 14px 210px; display: grid; gap: 8px; } +#s-agent-states details.disc > summary .lb { font-size: 13px; font-weight: 600; color: var(--ink); display: flex; align-items: center; gap: 8px; } +#s-agent-states details.disc > summary .lb svg.i { width: 16px; height: 16px; color: var(--se); } +#s-agent-states details.disc > summary .vl { font-size: 13.5px; color: var(--ink2); min-width: 0; display: flex; align-items: center; gap: 10px; flex-wrap: wrap; } +#s-agent-states details.disc > summary .vl .mo { font-size: 12px; color: var(--mu); } .field { height: 34px; border-radius: 9px; background: var(--p); box-shadow: inset 0 0 0 1px var(--b); display: flex; align-items: center; padding: 0 10px; font-size: 13.5px; color: var(--ink); gap: 8px; min-width: 0; } .field .mu { font-size: 12px; } .sel { height: 28px; border-radius: 8px; background: var(--sf); box-shadow: inset 0 0 0 1px var(--b); display: inline-flex; align-items: center; gap: 6px; padding: 0 8px 0 10px; font-size: 12.5px; color: var(--ink2); white-space: nowrap; } @@ -966,6 +970,25 @@

Same look. Less said.

+
+

Agent settings · policy, grants, identity, runtime, key

/v2/agents/ivy/default · Settings
states of the frame above, not scored
+
  • Policy is a short list, not a form. Repository access is a segment that saves on a button; it shows only for adapters that can take trust (claude, codex, opencode, qwen). The two quotas are read-only values.
  • Save feedback sits in the row's action slot: the button, then a check and "Saved" for a moment, or "Could not save changes." with the alert icon. Never a paragraph below.
  • Memory editing is not here. The three sections (long-term, identity, shared) move to the Memory tab; the policy page keeps trust and quotas.
  • Machine placement opens inside How it runs: a select and Move agent. The no-computer and blocked-by-another-pod variants are not drawn yet; they stay as the live text until they are.
Policy and machine · 1440trust save, quotas, move

Ivy

connected · 4 pods
+
Policy
Repository access
Hosted turns per day200
Runs per day50
How it runs
MachineRunning on Studio Mac
Run onStudio Mac
RuntimeCLI · webhooknot reported
+
  • The name is always a field, with its label. The count sits inside it. There is no Save or Cancel on the name row. A name outside 1–80 characters says "Enter a display name of 1–80 characters." under the field.
  • Persona is one disclosure (tone, specialties, boundaries, notes), shown only for agents that support it. One Save identity, after the persona, covers the name and the persona; it stays disabled until something changes, and "Saved" shows after it saves.
  • The listing row opens to the owner's controls: rename the registry listing, retire or restore it. A member sees the row and "View public profile" only.
Identity edit · 1440rename, persona, listing

Ivy

connected · 4 pods
+
Identity
Display nameIvy3 / 80
PersonaFriendly2 specialties · 1 boundary
ToneFriendly
Specialtiesonboarding, release notescomma separated
Boundariesno pricing promisescomma separated
Persona notesShort answers first. Link the doc, then explain.
Marketplace listingPublishedYour registry listing
Listing nameivy-helper
+
  • Grants are rows, like the Connectors page: logo, name, then where it reaches, who granted it ("Granted by") and when. The right edge shows the end date and Revoke.
  • Revoke asks inline. The row swaps Revoke for "Yes, revoke it" and Cancel; nothing opens over the page. Ended grants stay listed, dimmed, with no action.
  • Load failure is one row with the alert icon and Try again. A failed revoke puts "Could not revoke the grant." above the rows. Empty is the live line, "This agent has no connector grants." There is no Grant button on this page; grants are made from Connectors.
Connector grants · 1440list, inline revoke, load error

Ivy

connected · 4 pods
+
Connectors2 active · 1 ended
Could not revoke the grant.
GitHubDirect to this agent · Granted by Lily · Oct 28Ends Nov 30
LinearNorthwind — onboarding, search, release prep · Granted by Lily · Oct 21Ends Dec 15
SentrySupport desk · Granted by Sam · Sep 30Ended Oct 20
Could not load connector grants.
This agent has no connector grants.
+
Policy · 390
Ivy
+
Policy
Repository access
Hosted turns per day200
Runs per day50
How it runs
Running on Studio Mac
Studio Mac
Pods
157Needs you
Team
Settings
Identity · 390
Ivy
+
Identity
Display nameIvy3 / 80
PersonaFriendly
ToneFriendly
Specialtiesonboarding, release notes
Boundariesno pricing promises
Persona notesShort answers first. Link the doc, then explain.
Marketplace listingPublished
Pods
157Needs you
Team
Settings
Grants · 390
Ivy
+
Connectors2 active
Could not revoke the grant.
GitHubDirect · Granted by Lily · Oct 28Ends Nov 30
LinearNorthwind · Granted by Lily · Oct 21
SentrySupport desk · Granted by SamEnded Oct 20
Pods
157Needs you
Team
Settings
+ +
  • Three rows, one save. Adapter, model and effort are selects. The mono line beside each shows what the last spawn used and what the agent confirmed, so a change is visible once it takes effect. One Save covers all three (its accessible name is "Save runtime") and applies to the next spawn. A dot before a label means that row changes on the next spawn.
  • Own API key is a row. Resting shows the dot, when it was set and Replace key / Remove. The key is never displayed again after it is saved.
  • Both states are on the 390 frames: a stored model the adapter no longer offers (ink ring, the live line "stored choice unsupported · last spawn: …", Save disabled; the same line shows for an unsupported adapter or effort), and key entry with its save error.
Runtime and key · 1440adapter, model, effort, own key

Ivy

connected · 4 pods
+
Runtime
AdapterClaude Code 2.1.4last spawn Claude Code 2.1.4 · confirmed Claude Code 2.1.4
Modelclaude-opus-5-5last spawn claude-sonnet-5-5 · confirmed claude-sonnet-5-5
Efforthighlast spawn medium · confirmed not reported
Applies to the next spawn. Process connected · last turn Oct 31, 4:12 PM
Use my own API key
Key for AnthropicSet Oct 28, 2:40 PMnever shown again
+
Runtime refusal · 390
Ivy
+
Runtime
AdapterCodex 0.159.3last spawn Codex 0.159.3 · confirmed Codex 0.159.3
Modelgpt-4.1 · storedlast spawn gpt-5-codex · confirmed gpt-5-codex
Effortmediumlast spawn medium · confirmed not reported
stored choice unsupported · last spawn: codex · gpt-5-codex · medium
Own key entry · 390
Ivy
+
Use my own API key
API keyCould not update the key. Enter it again to retry.
Own key not available for opencode
+

Settings

/v2/settings
helper words 43 → 10scroll 1440 1.7× → 1.0×scroll 390 1.9× → 1.0×
@@ -1007,6 +1030,41 @@

Same look. Less said.

  • Grouped rows, one column. Each section is one or two facts, so a jump nav cost more than it saved. Everything fits in one screen at 1440.
  • The avatar is the photo control (click for Upload or New face). Delete account and Sign out everywhere fold into Account actions.
  • Theme joins Language as a segment under Look. The email value is shown as [email] here only to keep it out of the mock.
+
+

Settings · free plan, administrator

/v2/settings
states of the frame above, not scored
+
  • Free plan: the Plan row reads "Free" and carries the one ink button, Upgrade. Pro keeps the grey Billing button with the outbound arrow. A billing error would sit in the value slot with the alert icon; it stays the live text until it is drawn.
  • Administration is a group, not a card stack. It is the last group, below Account actions, and only administrators see it. Each destination is a row: icon and name on the left, what it holds in muted text, and a chevron button that opens it in the app.
  • No bordered link tiles. The two links use the same row as Connectors, so the page keeps one list shape from top to bottom.
Free plan, administrator · 1440Plan row, Administration group

Settings

+
Account
+
alex-kim@alex-kim · member
+
Email[email]
+
PlanFree
+
+
Access
+
Devices1 CLI deviceused 1:21 AM
+
API tokenNone
+
Connectors0 connected
+
+
Look
+
Language
+
Theme
+
+
Account actions
Administration
+
UsersRegistered users, bans, invitation codes
+
Usage analyticsSignups, messages, active users, activation funnel
+
+
Free plan, administrator · 390Access omitted to fit

Settings

Account
+
alex-kim@alex-kim · member
+
Email
+
PlanFree
+
+
Look
+
Language
+
Theme
+
+
Account actions
Administration
+
UsersRegistered users, bans, invitation codes
+
Usage analyticsSignups, messages, active users, activation funnel
+
Pods
157Needs you
Team
Settings
+

Connectors

/v2/connectors
helper words 72 → 29scroll 1440 1.2× → 1.0×scroll 390 1.9× → 1.0×