feat(fresh-ui): AI/workspace surface primitives + token/layout/theme foundation#190
Conversation
Adds the spacing steps the compiled closure omitted (--ns-space-2-5/-3-5/-7/ -9/-11/-14/-24 — their absence zeroed every var(--ns-space-2-5) gap downstream), finer type steps (--ns-text-3xs/-2xs/-chat), label tokens, avatar/control sizing, and app-shell layout dims (--ns-app-nav/-rail, --ns-topbar-h, --ns-shell-content). Source-driven: new entries in tokens/primitives.tokens.json + ROOT_GROUPS and the theme-bridge spacing list in scripts/build-tokens.ts; registry/theme/* regenerated via `deno task tokens:build`. No raw colors added (all dimensions). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Promotes the eis-chat AI-surface shell from app-hardcoded CSS to token-driven fresh-ui layout primitives so consumers compose them with ~zero custom layout CSS: .ns-app (3-pane grid on --ns-app-nav/1fr/--ns-app-rail, [data-nav|rail=off] collapse, rail folds <1024px / nav <640px), .ns-nav shell (+__head/__body/__foot), .ns-main (+__scroll/__pad centered on --ns-shell-content), .ns-session (+__scroll/__composer), .ns-topbar2 (+__title/__actions on --ns-topbar-h), and the .ns-divider-y / .ns-kbd utilities. All dims are the S1 tokens; no raw colors. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
DataTable.Row compiled to a bare `grid` with no grid-template-columns, so every cell collapsed into one stacked column. Add a `cols` prop that sets grid-template-columns (merged with any incoming style); pass the same template to header + body rows to align them. Tests cover cols, style-merge, and the no-cols opt-in default. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The generated :root already carries the dark role map (color-scheme: dark); emit it as `:root, [data-theme='dark']` so dark is a first-class, cascade-safe selector (no-attr → dark; data-theme='dark' → dark incl. scoped regions; data-theme='light' still overrides). Also annotate the un-auto-classifiable easing tokens with `/* @kind other */` so the design-system token checker files them correctly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Identity chip for people/agents: initials or image fallback, sm/md/lg sizes (--ns-avatar-* tokens), presence dot (online/away/offline via data-presence), and an agent variant (primary fill). Token-only CSS, role=img + aria-label, registered in the manifest and CLI assets barrel. Tests cover initials derivation, variants, and presence. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Inline per-claim source marker [n] for grounded-agent answers: clickable superscript button that pairs with a sources list (is-active filled state, aria-pressed + labelled source, onClick(index)). Token-only CSS with focus-visible ring. Registered in manifest + CLI assets barrel; 3 unit tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Event-handler props aren't surfaced via vnode.props under jsx: precompile (handlers land in a separate runtime slot; static attrs like title/aria-* are inspectable). Click wiring is covered by the browser gate, not the unit pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- check-ds-no-raw-hex: skip generated asset barrels (*.generated.ts). They embed already-gated source verbatim — incl. registry/theme's legitimate OKLCH ramp hex — so scanning them double-counted those literals and failed the gate on pristine main (registry.generated.ts). Real component css/tsx still scanned (negative-tested: an injected hex in avatar.css still FAILs). - check-manifest-integrity: import registry.manifest.ts (the repo moved the manifest to the package root from registry/manifest.ts), unbreaking the gate. Both now pass: no-raw-hex 102 files clean; manifest-integrity 68/68 claimed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fenced code surface for assistant messages: filename + language header, a copy affordance (data-part='copy' + data-clipboard for app-island hydration, with a data-state='copied' style hook), and a scrollable <pre><code>. Token-only CSS, mono-themed; syntax highlighting layered at L4. Manifest + barrel; 2 unit tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…to foundation Domain-group the copy-based registry via collections (not a sub-export — components are ui:add-copied, never imported): new `ai` collection for chat-surface seams (starts with citation-chip; message/model-selector/prompt-input/tool-call-card/ typing-indicator follow). General primitives stay core — avatar + code-block added to `foundation` (chart/icon will too) so analytics/marketing domains can reuse them. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Disclosure-backed model/provider picker for the prompt composer: native <details> trigger (provider + label) over a listbox menu of options (label/desc/check, is-active + aria-selected), left/right alignment. Native open/close + Esc; app island can add outside-click-close. Token-only CSS; in the `ai` collection. 3 unit tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Inline MCP/tool invocation as a native <details>: ƒ icon + mono name + Spinner (while running) + status Badge + chevron, over an args/result IO panel. Native disclosure (no island), reduced-motion guard on the chevron, data-status hook (error border). Composes Badge + Spinner (registryDependencies); `ai` collection. 3 unit tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Inline token-driven metric chart: horizontal bars (default, for long labels) or a vertical column chart with nice-rounded y-axis ticks, dashed gridlines, and value labels. Intents via data-tone (success/warning/destructive/secondary → semantic tokens); never a hardcoded color (fixes the v1 #6366f1 chart). General/analytics primitive → `foundation` collection. reduced-motion guard. 3 unit tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
SVG arc-segment donut: stroke-dasharray rings rotated from 12 o'clock, a center total (sum or override), and a legend. Segment colors come from data-tone or a semantic-token cycle (primary/success/warning/secondary/destructive) — no raw colors. General/analytics primitive → `foundation`. reduced-motion guard. 2 tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Chat composer as a presentational <form>: textarea field over a toolbar of research/grounding toggle pills (aria-pressed), a composed ModelSelector, attach/screenshot/voice iconbtns, and a circular send button. onSubmit reads the field (Enter-to-send + auto-grow are app-island enhancements per the handover). :focus-within ring, token-only CSS, reduced-motion guard. registryDependencies: model-selector; `ai` collection. 3 unit tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…2, ai) The chat-thread message: composes Avatar; inline-markup body via renderInline (**bold**, `code`, [n] → CitationChip); tool-call + chart/code blocks; follow-up pills; hover copy/regenerate actions; pending TypingIndicator. User = right primary bubble, assistant = card-less prose, system = centered note. renderInline + TypingIndicator exported for reuse. Token-only CSS, motion-rule typing dots. registryDependencies: avatar/citation-chip/chart-block/code-block/tool-call-card; `ai` collection. 4 unit tests (precompile-safe). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Audit of the prototype's inlined patterns surfaced generic affordances that belong in core rather than app-side: - Dropzone (L2, foundation): <label>-based file-drop target (label/hint/icon, native file input via children, data-active drag-over). Token-only, reduced-motion guard. - .ns-thread layout object: vertical rhythm for a message list. - .ns-fade-in entrance util: one-shot, collapses to 0.01ms under reduced-motion (preserves end state, per the motion rule). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Headless combobox runtime for ⌘K palettes, nav search, and slash/mention menus — the doctrine-correct home for the "combo search box" (shared behavior → L1, per P-LIFT). Compound namespace (Root/Input/Content/Item/Empty) over a use-combobox state machine: controllable open/value/inputValue, roving highlight (↑/↓/Home/End, loop or clamp), Enter-select, Escape-close, and the full ARIA combobox contract (role=combobox/listbox/option, aria-expanded/controls/activedescendant/selected) via data-part/data-state prop getters. Pure index/state helpers in combobox.utils (6 runtime tests); exported from interactive.ts + exercised in consumer-render. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…elity Diffed the from-spec ports against the prototype's actual ns-ai.css and closed the visible-quality gaps: - Message: user bubble is now a SOLID primary bubble with the asymmetric radius (xl/xl/sm/xl) + 82%/640px width, matching the prototype (was a subtle tint). - ToolCallCard: running status uses the warning tone (was secondary). - PromptInput: composer is radius-2xl on --ns-card with shadow-sm and a primary-subtle focus glow (was flat radius-lg). - Avatar: initials render in the sans face on --ns-fg (was mono/muted). Parity note: the prototype overrides NO pre-existing core component (only adds new ones + a contextual .ns-topbar2 .ns-breadcrumb constraint); its only pre-existing fixes were DataTable (§0b) and the dark theme (§0a), both already landed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
In a constrained topbar the breadcrumb didn't shrink/truncate. Fold the guard into the Breadcrumb source: flex-shrink:1 on .ns-breadcrumb (already min-width:0) so it can shrink as a flex item, and max-width:30ch on .ns-breadcrumb__current (already ellipsis) so a long current segment truncates instead of pushing the bar. Matches the prototype's topbar-scoped workaround, now general. (Item 5 of the core parity list.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Aligns the source with the intended toggle contract (core fix #3): no attribute = light, data-theme="dark" on <html> = dark. Previously :root defaulted to dark. Generator change only (no token-JSON rewrite): :root now renders semantic with the light.tokens.json overrides applied (full light), and [data-theme='dark'] renders the semantic (dark) values for just the theme-variant roles (LIGHT_GROUPS). The [data-theme='light'] block is dropped — light is the bare default, and an explicit data-theme="light" still resolves to it via :root. tokens.json now reports themes.dark. BREAKING: flips the framework's default theme from dark to light for all consumers. Set data-theme="dark" pre-paint from localStorage to opt into dark. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
writeStylesAggregator regenerated assets/styles.css from the theme base plus only the current install's items, so an incremental `ui:add <collection>` (e.g. the `ai` collection) after `ui:init` dropped the foundation's per-item @import lines instead of appending its own — leaving those components unstyled. Read the existing aggregator and union its previously-registered per-item imports with the new items' imports so single-item and collection installs register CSS identically and additively. Adds registry-styles tests proving a collection install appends (and dedupes) the per-item @imports onto an existing aggregator. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Modal command palette composing the L1 Dialog (native <dialog>
backdrop/overlay) over the L1 Combobox (ARIA combobox + roving keys):
grouped, searchable commands rendered as combobox items with optional
icon/hash/kind sub-parts and a group label. Props: open/onOpenChange,
groups of {id,label,icon?,hash?,kind?,onSelect}, placeholder, emptyLabel.
Token-only CSS (semantic --ns-* + color-mix(), reduced-motion on the
enter animation). Registered in the ai collection; barrel regenerated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Compact, presentational nav search: a button styled as an input with a leading search glyph and a trailing ⌘K keyboard hint (.ns-kbd) that opens the command palette via onOpen. Token-only CSS (semantic --ns-* + color-mix(), reduced-motion on the hover transition). Registered in the ai collection; barrel regenerated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@openhands-agent model=openrouter/qwen/qwen3.7-max output=pr-comment iterations=500 use harness You are the IMPL-EVAL evaluator (separate session, final post-implementation pass) for the AI/workspace fresh-ui primitive library + 5 core NS One fixes + the ui:add CSS-registration fix + .ns-cmdk/.ns-search on branch SKILL
Scope to verify11 L2 primitives (Avatar, CitationChip, CodeBlock, ModelSelector, ToolCallCard, ChartBlock, Donut, PromptInput, Message+renderInline+TypingIndicator, Dropzone) + the headless L1 Combobox + .ns-cmdk command palette + .ns-search + the app-shell layout objects; the 5 fixes to existing NS One (DataTable.Row Run the package gates yourself, diff the change against the issue + the archetype/L0 contract, confirm no regressions, then post the verdict as a PR comment. |
OpenHands Agent — CompletedModel: openrouter/qwen/qwen3.7-max IMPL-EVAL Summary — PR #190 (feat/fresh-ui-ai-additions)SummaryThis IMPL-EVAL session verified the PR #190 implementation against the harness Changes
ValidationGates run and status (confirmed)
Gates launched but result not confirmed
Gates NOT run
Scope verified by file inspection only (no runtime verification)
Remaining risks / unverified scopeThe following items from the evaluator scope list were not independently verified:
Recommendation: Resume the evaluator session (or re-invoke) to confirm the in-progress fresh-ui Run: https://github.com/rickylabs/netscript/actions/runs/28478150691 |
|
Fixed the CI flagged 4 lines I hadn't run the scoped Restored the incidental CRLF churn the Windows |
CI's `deno task fmt:check` (scoped to packages/plugins, line-width) flagged four lines I hadn't run the scoped formatter over: the ModelSelector import in prompt-input.tsx, the getNextComboboxIndex call in use-combobox.ts, and two long lines in the data-table + message tests. Ran `deno task fmt` (write) — fmt:check now reports 0 findings. No logic change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
@openhands-agent model=openrouter/qwen/qwen3.7-max output=pr-comment iterations=500 use harness Re-dispatch: the prior IMPL-EVAL run (run-28478150691-1) confirmed 5 gates green but did NOT emit a verdict — You are the IMPL-EVAL evaluator (separate session, final post-implementation pass) for the AI/workspace fresh-ui primitive library + 5 core NS One fixes + the ui:add CSS-registration fix + .ns-cmdk/.ns-search on branch SKILL
Scope to verify11 L2 primitives (Avatar, CitationChip, CodeBlock, ModelSelector, ToolCallCard, ChartBlock, Donut, PromptInput, Message+renderInline+TypingIndicator, Dropzone) + the headless L1 Combobox + .ns-cmdk command palette + .ns-search + the app-shell layout objects; the 5 fixes to existing NS One (DataTable.Row Run the package gates yourself, diff the change against the issue + the archetype/L0 contract, confirm no regressions, then post the verdict as a PR comment. |
OpenHands Agent — CompletedModel: openrouter/qwen/qwen3.7-max IMPL-EVAL Summary — PR #190SummaryIndependent final evaluator pass (IMPL-EVAL) for Changes
ValidationAll gates executed and all passed with reproducible evidence: Root workspace:
Design-system fitness (
Fresh-ui package:
CLI package:
Scope verification:
Verdict written to Responses to review/issue comments
Remaining risks
Run: https://github.com/rickylabs/netscript/actions/runs/28483123786 |
…nfig (#199) * docs(site): reconcile to merged #193/#183/#190 surface + fmt-guard config Brings the doc site current with the three just-merged PRs, and hardens the standalone docs project config so `deno fmt` can never again reflow Vento markdown or split its `{{ comp }}` tags. Content (12 pages): - #190 fresh-ui: document the AI/workspace primitive catalog (11 L2 primitives + command-palette/search) and the headless Combobox interactive namespace; extra `ui:add` examples. (customize-fresh-ui, capabilities/fresh-ui) - #193 triggers-oRPC truth: triggers serve a typed v1 oRPC contract for introspection/management/SSE; only the webhook ingress endpoint (POST /api/v1/webhooks/:triggerId) stays a raw HMAC-verifying route by design. Corrected every stale "raw Hono, not oRPC" claim. (triggers, capabilities/index, contracts, architecture, glossary, deploy, storefront/05-shipping-webhook) - #183/#172 two-tier plugin shape: `netscript plugin new <name>` emits a core engine package + thin connector; --kind feature|proxy (default proxy), --overwrite. (cli-reference, author-a-plugin, plugin-system) Config: - docs/site/deno.json gains an fmt block (proseWrap preserve; excludes **/*.md, **/*.mdx, **/*.vto, _site/, _cache/) and a lint block, so the authored Markdown/Vento surface is out of scope for `deno fmt`. Verified: `deno task build` green (306 files); `check:links` green (18456 internal links across 130 pages resolve). Docs-only; no framework source. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014gW4zfhMMQU6txC828ijct * chore(openhands): record run trace 28485224548-1 * docs(site): correct `plugin new` flag names (IMPL-EVAL #199 Domain 2 FAIL_FIX) The two-tier topology prose was correct, but the CLI flag spellings were invented. Ground truth (packages/cli/.../new/new-plugin-command.ts): - boolean `--feature` (default proxy) → kind: feature|proxy - boolean `--force` → overwrite - `--project-root <path>` There is no `--kind feature|proxy` flag and no `--overwrite` flag. Running `netscript plugin new billing --kind proxy` would fail. Corrected the two docs that showed the wrong flags: - cli-reference.md: example → `netscript plugin new billing` (proxy default); desc → `--feature` / `--force`. - how-to/author-a-plugin.md: example → `netscript plugin new notifier`; options prose → `--feature` (route-backed feature connector vs default proxy), `--force` (overwrite), `--project-root <path>`. Verified: `deno task build` green (306 files); `check:links` green (18456 internal links across 130 pages resolve). Docs-only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014gW4zfhMMQU6txC828ijct * chore(openhands): record run trace 28486223232-1 --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: OpenHands Bot <openhands@all-hands.dev>
Syncs the eis-chat Claude Design AI/workspace prototype back into
@netscript/fresh-uias reusable, token-only, doctrine-compliant primitives. Authored under the Harnessfresh-ui-horizontalgates (Claude-implements fallback — WSL Codex lane unavailable on the authoring machine; recorded in the run drift log).Foundation
--ns-space-2-5…-24, whose absence zeroedvar(--ns-space-2-5)gaps downstream — the "overlapping icons" root cause), finer type (text-3xs/2xs/chat),label-*,avatar-*,control-h*, and app-shell dims (app-nav/-rail,topbar-h,shell-content). Style-Dictionary source →deno task tokens:build..ns-app3-pane grid +.ns-nav/.ns-main/.ns-session/.ns-topbar2/.ns-divider-y/.ns-kbd, fully tokenized (consumers compose them with ~zero custom layout CSS).:root, [data-theme='dark'](cascade-safe explicit alias) +@kind otheron ease tokens for the DS token checker.colsprop →grid-template-columns(fixes the stacked-cells bug) + tests.L2 primitives
Each ships
tsx+css(token-only, semantic--ns-*+color-mix), a manifest entry, the regenerated CLI assets barrel, and unit tests; each filed into a registry collection.ai: CitationChip, ModelSelector, ToolCallCard, PromptInput, Message (+ exportedrenderInline+TypingIndicator).foundation: Avatar, CodeBlock, ChartBlock (token-driven — kills the v1#6366f1), Donut.New
airegistry collection added; general primitives stay infoundation(copy-based package → grouping is viacollections, not sub-exports). Charts/avatar/code are reusable by futuremarketing/analyticsdomains.Tooling fixes (pre-existing, blocking clean gating)
check-ds-no-raw-hexnow skips generated asset barrels (*.generated.ts) — they embed already-gated source incl. the theme's legitimate OKLCH ramp hex; it was failing on pristinemain. Negative-tested.check-manifest-integrityimport path corrected to package-rootregistry.manifest.ts.Gates (green per slice)
deno task check·deno task test·tokens:check·ds-no-raw-hex·ds-color-utilities·manifest-integrity.Still to come (draft)
apps/playground+ Playwright light/dark browser gate.🤖 Generated with Claude Code