Skip to content

FM-11: take-it-home — client-side validator, MCP config, local-agent path#13

Merged
ryandmonk merged 1 commit into
mainfrom
feat/fm11-take-it-home
Jul 14, 2026
Merged

FM-11: take-it-home — client-side validator, MCP config, local-agent path#13
ryandmonk merged 1 commit into
mainfrom
feat/fm11-take-it-home

Conversation

@ryandmonk

Copy link
Copy Markdown
Contributor

Summary

PHASE-NEXT WS1. A visitor who liked the studio can adopt the ecosystem in their own editor: a new take it home view in the shell switcher with three honest paths.

Do not merge before ds-mcp 0.3.1 is live on npm (aestheticfunction/ds-mcp#21 → trusted-publisher registration → v0.3.1 tag): the view's copy references ^0.3.1 and PHASE-NEXT forbids take-home copy referencing ds-mcp until the re-pin ships.

The spike result (task 1.2, run first as planned)

Client-side execution works: @aestheticfunction/dspack-gen's /core subpath bundles into the Next static export and lintSurface runs in-browser against the byte-synced contract. Verified on the built artifact: the caught example reproduces rule.destructive-requires-alertdialog at $.root, the console is clean, and first-load JS is unchanged (103 kB shell; core rides the async app chunk). The live-only fallback specified in PHASE-NEXT was not needed.

What the view carries

  • MCP config: npx -y @aestheticfunction/ds-mcp@^0.3.1 --dspack <absolute path>, copy + download, plus the contract itself downloaded as a build-time byte copy of packages/contracts/astryx.dspack.json (apps/web/scripts/take-home-assets.mjspublic/take-home/, gitignored — a JSON re-stringify would not preserve bytes).
  • The validator, right here: paste a dspack surface, the real linter evaluates S1/S2/S3 against the studio's contract, findings pass through unmodified; "load a caught example" prefills fixture-001's recorded attempt-0 surface. Nothing pasted leaves the browser, and the copy says so.
  • The pipeline on your machine: clone-and-run commands (launch-day option (a) per the plan; the published npx package remains an owner-gated fast-follow and is deliberately unreferenced — unit-asserted).

Honesty checks (receipts spirit)

  1. Browser validator == recorded pipeline: fixture-001's attempt-0 surface produces findings byte-identical to the dspack.gates event's recorded findings — asserted at the unit level (JSON.stringify equality) and through the UI (rule id, message, rationale per finding).
  2. Downloaded contract == repo copy: e2e fetches the download href and byte-compares against packages/contracts/astryx.dspack.json.
  3. Version floor is literal: unit + e2e parse the config and assert the ds-mcp floor ≥ 0.3.1, so a copy edit cannot silently reference the pre-fix schema.

Fail-first note

These are new-surface assertions (no prior behavior pinned them; on old code the view does not exist). The discriminating power of check 1 was demonstrated during WS0: the same byte-level comparison fails against the pre-0.1.1 schema with text-before-props at schema line 40 (see aestheticfunction/ds-mcp#21's fail-first output).

Verification

  • Unit: 6/6 web (new suite, added to CI); all package suites green (6/3/21/5/14).
  • Playwright: new take-home.spec.ts 6/6 (agent blocked at the network layer — the deployed site's state — including axe); full suite 85 passed + 3 gated skips; registered in the production config.
  • Browser: validated on the static export via the preview pane (findings render, downloads serve, console clean).
  • Clone path: the copy-paste block executed verbatim from a cold GitHub clone — agent answered {"ok":true} health and Ollama model discovery, then was shut down.

🤖 Generated with Claude Code

…ocal-agent path

The validate-ui spike CONFIRMED client-side execution: dspack-gen's /core
subpath (zero-network by its own boundary test) bundles into the Next
static export and lintSurface runs in-browser against the byte-synced
contract. First-load JS is unchanged (103 kB shell; core rides the async
app chunk). No live-only fallback needed.

- take-home view in the shell switcher: MCP client config (npx ds-mcp
  ^0.3.1, --dspack absolute path), contract download served as a
  build-time byte copy (scripts/take-home-assets.mjs -> public/take-home/,
  gitignored), the real S1/S2/S3 validator on pasted surfaces with
  findings passed through unmodified, and the clone-and-run local agent
  path (launch-day option; a published npx package is a fast-follow
  decision, deliberately unreferenced in copy).
- Honesty tests in the receipts spirit: fixture-001's recorded attempt-0
  surface reproduces the RECORDED findings byte-for-byte through the
  bundled validator (unit) and through the UI (e2e); the downloaded
  contract byte-matches packages/contracts/astryx.dspack.json (e2e); the
  MCP config's ds-mcp floor is literally asserted >= 0.3.1 (unit + e2e).
- take-home.spec.ts blocks the agent at the network layer (the deployed
  static site's state) and everything still works; registered in the
  production suite; axe clean.
- apps/web gains vitest (+ CI unit step); permalink v=home supported.

Sequencing: merging this waits on ds-mcp 0.3.1 being live on npm
(aestheticfunction/ds-mcp#21 + trusted-publisher registration + v0.3.1
tag) — the copy references ^0.3.1.

Verified end to end: static export in the browser (validator reproduces
rule.destructive-requires-alertdialog on the caught example; contract
download 200 with exact bytes; console clean) and the clone-and-run
commands executed verbatim from a cold GitHub clone (agent answered
health and model discovery).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 14, 2026 19:01

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new “take it home” view to the web studio so visitors can (1) download/copy an MCP config and contract, (2) validate a pasted dspack surface in-browser using the same linter/contract as the studio, and (3) follow copy-paste commands to run the local agent pipeline.

Changes:

  • Introduces the take-home view UI + pure logic module (MCP config generation, surface validation, caught-example loading).
  • Adds build-time asset copying so the downloadable contract is served as an exact byte copy from public/take-home/.
  • Adds unit + Playwright coverage for “honesty checks” and wires the new spec into production Playwright config and CI.

Reviewed changes

Copilot reviewed 10 out of 12 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pnpm-lock.yaml Adds locked entries for @aestheticfunction/dspack-gen and vitest used by the new validator + unit tests.
playwright.production.config.ts Includes take-home.spec.ts in the production/agent-free suite.
e2e/take-home.spec.ts Adds e2e coverage for MCP config version floor, contract download byte-match, validator findings agreement, and a11y.
apps/web/scripts/take-home-assets.mjs Copies the contract into public/take-home/ at build/dev time to preserve exact bytes.
apps/web/package.json Runs the asset-copy script for dev/build and adds vitest-based test script.
apps/web/app/take-home.ts Implements core take-home logic: MCP config generation, validator wrapper, and caught-example extraction from fixtures.
apps/web/app/take-home.test.ts Adds vitest unit tests for version pinning, validator behavior, and findings byte-equivalence.
apps/web/app/take-home-view.tsx Implements the client-side take-home view UI (copy/download, validator, local-agent commands).
apps/web/app/studio.tsx Adds the new “home” view to the switcher and renders TakeHomeView.
apps/web/app/permalink.ts Extends permalink parsing/building to support the new home view.
.gitignore Ignores generated apps/web/public/take-home/ assets.
.github/workflows/ci.yml Runs pnpm --filter web test in CI.
Files not reviewed (1)
  • pnpm-lock.yaml: Generated file

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +201 to +205
<p data-testid="local-agent-status" style={{ fontSize: 12, color: "var(--fg-dim)", margin: "8px 0 0" }}>
{agentOnline
? "A local agent is answering right now: run it live is active in this studio."
: "Once it answers on localhost:8787, this studio's run it live and break it modes use it directly."}
</p>
@ryandmonk
ryandmonk merged commit 8efe6f5 into main Jul 14, 2026
2 checks passed
ryandmonk added a commit that referenced this pull request Jul 14, 2026
Conflict resolutions, combining both sides everywhere:
- apps/web/package.json: dev/build chains run BOTH the shadcn CSS build
  and the take-home assets copy; deps carry dspack-gen + shadcn-renderers;
  the web vitest suite stays.
- apps/web/app/studio.tsx: the view union includes 'home', the shell
  carries the FM-10 design-system state, RestyleView gets the selector
  props, and the take-home view renders.
- pnpm-lock.yaml regenerated.

Combined suite on the merged tree: 90 Playwright passed + 4 gated skips
(take-home, design-swap, FM-7 interactive, and the rest together); web
unit 6/6; contracts build clean; typecheck clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

2 participants