Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions design-system/apps/design-lab/src/design-layout.css
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,26 @@
line-height: var(--openbitfun-type-body-md-line-height);
}
.lab-shell [hidden] { display: none !important; }
/* Product-site typography belongs to the shell; previews retain their published type roles. */
.lab-shell .lab-page.design-home,
.lab-topbar,
.design-home-slogan {
font-family: var(--_lab-font);
}
/* Both brand lockups share the shell's typography, with spacing and color owned locally. */
.design-wordmark-link,
.design-home-footer-wordmark {
font-size: var(--_lab-wordmark-size);
font-weight: var(--_lab-wordmark-weight);
letter-spacing: var(--_lab-wordmark-tracking);
line-height: var(--_lab-wordmark-leading);
}
/* Keep the full-bleed footer aligned with the shell column at every viewport width. */
.design-home-footer {
inline-size: 100vw;
margin-inline: calc(50% - 50vw);
padding-inline: max(var(--openbitfun-space-6), calc((100vw - var(--_lab-content-width)) / 2 + var(--openbitfun-space-6)));
}
/* The homepage's closing band is the one block that leaves the centred column and runs edge to edge
(see .design-home-footer). Where the platform reserves space for a scrollbar, 100vw is wider than
what is visible, so the band is clipped instead of widening the document. clip is not a scroll
Expand Down Expand Up @@ -130,10 +150,6 @@
gap: var(--openbitfun-space-3);
color: var(--openbitfun-color-content-primary);
text-decoration: none;
font-size: var(--_lab-wordmark-size);
font-weight: var(--_lab-wordmark-weight);
letter-spacing: var(--_lab-wordmark-tracking);
line-height: var(--_lab-wordmark-leading);
}
/* The app mark is silver artwork on a transparent canvas. The site flattens it to solid ink in
its light header; the Lab does the same, and lifts it back for the dark theme. */
Expand Down
25 changes: 1 addition & 24 deletions design-system/apps/design-lab/src/pages/OverviewPage.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,6 @@
min-width: 0;
}

/* Typography: the homepage runs the product site's own face — IBM Plex Mono, regular weight,
tight leading, slightly negative tracking. The topbar follows on every route, because shell
chrome that changed font between pages would read as a bug. Component instances inside the
preview frame keep the design system's published type roles, so their text stays on the sans
stack. Every other page still renders in the design system's own sans. */
.lab-shell .lab-page.design-home,
.lab-topbar {
font-family: var(--_lab-font);
}

/* The headline states the design stance and what it is a stance about: one sentence, no
subtitle. Weight is the real 600 cut (see the @font-face block in design-layout.css) — the
reference site has no 600, and a synthesised bold on a display-size mono headline looks
Expand All @@ -65,7 +55,6 @@
.design-home-slogan {
max-width: 60rem;
margin: 0;
font-family: var(--_lab-font);
font-size: var(--openbitfun-type-display-fluid-title-font-size);
font-weight: var(--openbitfun-font-weight-semibold);
line-height: var(--openbitfun-type-display-fluid-title-line-height);
Expand Down Expand Up @@ -320,10 +309,6 @@
tile; if a surface-inverse token is ever added, this is the line that should switch to it. */
.design-home-footer {
--_lab-band-pad-block: calc(var(--openbitfun-space-12) * var(--_lab-home-air));
/* The band is the viewport, not the page's column, so it reproduces the column gutter in its own
padding: the shell's auto margin plus the page's 36px inner padding. Below the shell's width cap
that expression goes negative, which is what the max() floors. */
--_lab-column-gutter: max(var(--openbitfun-space-6), calc((100vw - var(--_lab-content-width)) / 2 + var(--openbitfun-space-6)));
--_lab-on-dark: var(--openbitfun-color-content-on-dark);
--_lab-on-dark-secondary: color-mix(in srgb, var(--openbitfun-color-content-on-dark) 72%, transparent);
--_lab-on-dark-muted: color-mix(in srgb, var(--openbitfun-color-content-on-dark) 50%, transparent);
Expand All @@ -332,15 +317,11 @@
display: flex;
flex-direction: column;
gap: calc(var(--openbitfun-space-12) * var(--_lab-home-air));
/* Full bleed: the band leaves the page's centred column and runs to both edges, so it carries no
radius and the page keeps no block-end padding under it. */
inline-size: 100vw;
margin-inline: calc(50% - 50vw);
/* Full-bleed geometry and column alignment are owned by design-layout.css. */
/* The band opens on the page's full rhythm but closes on half of it: the small print is the last
line on the page, so the space under it only has to hold the band's edge rather than separate
it from anything. */
padding-block: var(--_lab-band-pad-block) calc(var(--openbitfun-space-6) * var(--_lab-home-air));
padding-inline: var(--_lab-column-gutter);
color: var(--_lab-on-dark);
background: var(--openbitfun-color-content-on-light);
}
Expand Down Expand Up @@ -372,10 +353,6 @@
margin: 0;
color: var(--_lab-on-dark);
text-decoration: none;
font-size: var(--_lab-wordmark-size);
font-weight: var(--_lab-wordmark-weight);
letter-spacing: var(--_lab-wordmark-tracking);
line-height: var(--_lab-wordmark-leading);
}

.design-home-footer-wordmark-arrow {
Expand Down
10 changes: 5 additions & 5 deletions design-system/apps/design-lab/src/pages/OverviewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@ export function OverviewPage({ onNavigate, colorScheme, contrast, density, token
const previewSessions: readonly PreviewSessionRow[] = [
{ id: "claw", icon: "user", name: "Claw" },
{ id: "claw-session", indent: true, name: "New Claw Session" },
{ id: "bitfun", icon: "folder", name: "BitFun" },
{ id: "bitfun-session", indent: true, name: "New Code Session" },
{ id: "bitfun-welcome", indent: true, name: t("design.homePreview.welcome"), selected: true },
{ id: "bitfun-more", name: t("design.homePreview.showMore"), metadata: <NumberBadge value="+14" /> },
{ id: "openbitfun", icon: "folder", name: "OpenBitFun" },
{ id: "openbitfun-session", indent: true, name: "New Code Session" },
{ id: "openbitfun-welcome", indent: true, name: t("design.homePreview.welcome"), selected: true },
{ id: "openbitfun-more", name: t("design.homePreview.showMore"), metadata: <NumberBadge value="+14" /> },
{ id: "root", icon: "session", name: "root", metadata: <StatusPill emphasis tone="success">38.47.103.247</StatusPill> },
{ id: "root-session", indent: true, name: "New Code Session" },
{ id: "root-relay", indent: true, name: "relay-server account" },
Expand Down Expand Up @@ -184,7 +184,7 @@ export function OverviewPage({ onNavigate, colorScheme, contrast, density, token
{t("design.homePreview.contextMachine")}
</Button>
<ComposerDivider />
<Button size="xs" tabIndex={-1} trailingIcon={<Icon name="chevron-down" />} variant="text">BitFun</Button>
<Button size="xs" tabIndex={-1} trailingIcon={<Icon name="chevron-down" />} variant="text">OpenBitFun</Button>
<ComposerDivider />
<span className="design-home-preview-context">1.0.0-explore</span>
<ComposerDivider />
Expand Down
10 changes: 5 additions & 5 deletions design-system/apps/design-lab/src/preview/MultiSurfaceMorph.css
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
position: relative;
inline-size: var(--_morph-w);
block-size: var(--_morph-h);
border: var(--_lab-rule);
border: var(--openbitfun-border-width-default) solid var(--openbitfun-color-border-subtle);
border-radius: var(--_morph-r);
overflow: hidden;
background: var(--openbitfun-color-surface-canvas);
Expand Down Expand Up @@ -105,7 +105,7 @@
}

.design-morph-phone-head {
border-block-end: var(--_lab-rule);
border-block-end: var(--openbitfun-border-width-default) solid var(--openbitfun-color-border-subtle);
}

.design-morph-phone-thread {
Expand Down Expand Up @@ -149,7 +149,7 @@
content: "";
position: absolute;
inset: var(--openbitfun-space-3);
border: var(--_lab-rule);
border: var(--openbitfun-border-width-default) solid var(--openbitfun-color-border-subtle);
border-radius: var(--openbitfun-radius-pill);
}

Expand All @@ -166,7 +166,7 @@

.design-morph-watch-wave > i {
inline-size: 3px;
block-size: var(--_morph-wave, 40%);
block-size: var(--_morph-wave);
border-radius: var(--openbitfun-radius-pill);
background: var(--openbitfun-color-accent-default);
}
Expand Down Expand Up @@ -196,7 +196,7 @@
gap: var(--openbitfun-space-4);
inline-size: min(calc(100% - var(--openbitfun-space-16)), 640px);
padding: var(--openbitfun-space-3) var(--openbitfun-space-5);
border: var(--_lab-rule);
border: var(--openbitfun-border-width-default) solid var(--openbitfun-color-border-subtle);
border-radius: var(--openbitfun-radius-2xl);
background: var(--openbitfun-color-surface-panel);
color: var(--openbitfun-color-content-primary);
Expand Down
25 changes: 25 additions & 0 deletions scripts/check-core-boundaries.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,31 @@ const MODULES = [

const TEST_ROOT = join('C:', 'repo');

test('builtin agent catalog requires the GeneralPurpose fast model default', () => {
const rule = requiredContentRules.find(
rule => rule.path === 'src/crates/execution/agent-runtime/src/agents.rs'
&& rule.patterns.some(pattern => pattern.message.includes('GeneralPurpose')),
);
assert.ok(rule);
const mapping = `builtin_agent_spec(
"GeneralPurpose",
SubAgent,
"fast",
SubagentVisibilityPolicy::public(),
)`;
const catalog = `fn builtin_agent_definition_specs() {
${mapping};
SubagentVisibilityPolicy::restricted(["Claw"]);
}`;
const accepts = text => rule.patterns.every(({ regex }) => regex.test(text));
assert.ok(accepts(catalog));
assert.ok(!accepts(catalog.replace(mapping, '')));
assert.ok(!accepts(catalog.replace('"fast"', '"primary"')));
assert.ok(!accepts(catalog.replace('SubAgent,', 'Mode,')));
assert.ok(!accepts(catalog.replace('"GeneralPurpose"', '"Explore"')));
assert.ok(!accepts(catalog.replace('SubagentVisibilityPolicy::restricted(["Claw"]);', '')));
});

test('tool-runtime search regex stays available without enabling HTML extractors', () => {
const rule = requiredContentRules.find(
rule => rule.path === 'src/crates/execution/tool-execution/Cargo.toml',
Expand Down
4 changes: 2 additions & 2 deletions scripts/core-boundaries/rules/source/required-rules.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7827,8 +7827,8 @@ export const requiredContentRules = [
message: 'missing builtin agent definition catalog owner',
},
{
regex: /builtin_agent_spec\(\s*"GeneralPurpose",\s*SubAgent,\s*"primary"/,
message: 'missing GeneralPurpose runtime default model mapping',
regex: /builtin_agent_spec\(\s*"GeneralPurpose",\s*SubAgent,\s*"fast"/,
message: 'missing GeneralPurpose runtime fast default model mapping',
},
{
regex: /SubagentVisibilityPolicy::restricted\(\["Claw"\]\)/,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ each missing what the other had.
| `../../../infrastructure/diagnostics/flowChatViewportDiagnostics.test.ts` | coalescing, placement sampling, the switch |
| `useFlowChatVirtualizer.test.ts` | the offsets-and-positions boundary |
| `useFlowChatVirtualizer.measurement.test.tsx` | `measureRenderedItems` against a real virtualizer |
| `useFlowChatVirtualizer.cascade.test.tsx` | bounded synchronous measurement notifications, cross-frame convergence, ordinary synchronous opening, reader takeover and StrictMode/session cleanup; real hooks with supplied geometry, not native paint evidence |
| `useFlowChatVirtualizer.initial-window.test.tsx` | tail-first window, empty hydration, head default, one-time seed, user-scroll takeover, opening readbacks before native events, suspended viewport, measured-window reconciliation with delayed scroll/scroll-end delivery; supplied DOM geometry, not performance validation |
| `useFlowChatVirtualizer.aim.test.tsx` | the re-aim, and giving it up on takeover |
| `VirtualMessageList.layout.test.ts` | the item-height estimate and the spacer |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,26 @@ the saved hint, attempts, or member identities.

## Measurement compensation and cached offsets

Geometry updates and React rendering have separate delivery contracts. The
virtualizer updates its size cache, applies owner-approved compensation and
publishes the physical offset synchronously. Its local core adapter coalesces
render requests within a commit and permits at most 16 notification-driven
commits before yielding to an animation frame. The frame renders current state;
it does not retain a scroll target or replay a former owner's write. Cleanup
cancels the frame, including session remounts and StrictMode effect replay.

This bounds a converging measurement cascade as well as an oscillating one:
many near-empty rows can require more than React's nested-update limit while
the window replaces estimates with measurements. Do not defer only the opening
reconciliation callback: follow layout effects and physical range clamping can
also advance the window. Explicit `measureRenderedItems` remains synchronous
for callers that must read geometry before the next React commit. Normal small
cascades still settle synchronously; the budget reset alone causes no render.
`useFlowChatVirtualizer.cascade.test.tsx` covers tiny and zero-height rows,
convergence across frames, reader takeover and remount cleanup using real hooks
and supplied geometry. It is not proof of the production crash's data trigger
or native paint timing.

When the viewport owner accepts a shift for a measured row wholly above the
reader, the virtualizer publishes the actual scroll offset after updating its
size cache, before selecting the next rendered window. This applies during
Expand Down
Loading
Loading