46 Commits

Author SHA1 Message Date
Benjamin Taylor 737a9a86cb feat(showcase): guard published snippet bodies in the demo bundler
Region bodies are assembled at bundle time, so neither failure mode in the
two preceding commits is visible in review — the source diff looks fine
while the docs page renders a 400-line slab or an uninstallable import.
Two checks over every region the bundler is about to publish:

- Any `@copilotkit/showcase-*` specifier fails the build. These resolve
  only through a tsconfig path alias to a symlink in this repo, so they
  cannot appear in a snippet a reader is meant to copy. The corpus is at
  zero once OSS-901 is fixed, so there is no baseline.
- Over 200 lines fails the build. The median region is 28 lines and p90 is
  125, so 200 catches a marker sitting above unrelated code without
  arguing about genuinely long single-purpose files (the 344-line
  declarative-gen-ui renderers.tsx is the point of that page). The 48
  regions already over the line are baselined by
  `slug::region::file` and the list only shrinks.

Both are reported together for the whole run, so one build lists every
unfollowable snippet instead of only the first.

Verified against the pre-fix tree: the guard exits 1 and names both the
mastra `@copilotkit/showcase-shared-tools` bodies and the 586-line strands
region.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 08:42:12 -05:00
copilotkit-qa-bot[bot] bd91313517 feat: add AWS Strands TypeScript starter 2026-08-18 15:51:47 -07:00
Ran Shem Tov 5136097aa0 feat(showcase): add CrewAI conversational flows 2026-08-06 15:33:10 +03:00
Alem Tuzlak 809bb72e72 feat(showcase): bring ms-agent-dotnet to D6 (frontend parity + shared-state-streaming, a2ui-recovery, threadid) (#6130)
## What

Brings the **ms-agent-dotnet** (Microsoft Agent Framework .NET) showcase
integration from D5 to **D6**, using **langgraph-python** as the
north-star reference.

### 1. Frontend parity with langgraph-python
Restores near-identical frontends where ms-agent-dotnet had drifted,
while **preserving the load-bearing .NET adaptations** (per the showcase
iron rules — differences belong in fixtures/minimal backend, not the
shared frontend):
- Root shell: `globals.css` (Tailwind `@theme` block + brand green),
manifest-driven index `page.tsx`, `layout.tsx`, new `middleware.ts`
(`x-pathname`), `tsconfig` include.
- `declarative-gen-ui` subtree restored (fixes divergent pill testids
the shared probe asserts).
- Doc-snippet `@region` markers, import-style normalization, `subagents`
revert, stale-file cleanup, `auth` inspector flag.
- **Kept** (load-bearing, not reverted): `parse-json-result` 3-layer
unwrap, multimodal legacy-shim, tool-based `hitl` (MAF has no
`interrupt()`), `agent-config` `properties=`.

### 2. shared-state-streaming → per-token (removed from
`not_supported_features`)
`write_document`'s `document` arg now streams into `state.document`
per-token via a `createSharedStateStreamingAgent` route shim (mirrors
the proven `createGenUiAgent` bridge, with a partial-JSON string
decoder), since the .NET AG-UI host has no `predict_state_config`.

### 3. a2ui-recovery cell (new)
First MS-Agent-Framework implementation of the A2UI
validate→retry→`a2ui_recovery_exhausted` recovery loop. Because the MAF
AG-UI adapter can't emit the custom `ACTIVITY_SNAPSHOT{status:"failed"}`
the exhausted card needs, it's a **raw-SSE `MapPost` endpoint**
(`RecoveryAgent.cs`) — the same adapter-bypass pattern already shipped
for `/multimodal`. Adds the demo frontend, API route, deterministic
aimock fixture (heal seq0-invalid→seq1-valid; exhaust always-invalid),
and a unique per-slug `PROMPTS` entry in the shared probe.

### 4. threadid-frontend-tool-roundtrip demo (parity)
Added for demo-set parity (reuses the `frontend_tools` passthrough; not
a D6-scored feature, mirroring the reference).

`gen-ui-interrupt` / `interrupt-headless` remain honestly quarantined
(upstream `@copilotkit/react-core` `useInterrupt` resume-path bug — not
a backend gap).

## Verification
- Code was authored in parallel worktree-isolated slots, each
cross-verified against the reference + the shared probe contracts; the
a2ui-recovery fixture was cross-checked against
`RecoveryAgent.ValidateComponents`.
- Local D6 harness: the image builds and the stack + probes run, but
**full local green was blocked by Windows-only harness friction**
(`core.symlinks=false` breaks `stage_shared`'s `[ -L ]` materialization;
`--direct` doesn't context-scope the `x-aimock-context` header so
context-keyed a2ui fixtures miss). These are environmental, not code
issues. **Relying on CI's Linux harness (real symlinks + fleet worker)
for authoritative D6.**

## Follow-up (not in this PR)
- `stage_shared()` should also materialize Windows symlink-as-file
entries (detect a regular file whose content is a relative path), so
forced local rebuilds work on `core.symlinks=false` checkouts.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-28 13:09:06 +02:00
Mike Ryan b7e83d7c1f docs: make Angular journeys capability-aware 2026-07-27 09:38:01 -07:00
Mike Ryan a87f1c9a30 docs: close Angular information architecture gaps 2026-07-27 09:38:00 -07:00
Mike Ryan fcf2357c25 docs: add Angular-native content and source-backed snippets 2026-07-27 09:37:59 -07:00
Jordan Ritter 62474be1dd fix(showcase/ci): make a cancelled build slot a first-class outcome
`job.status` for a matrix slot is success|failure|cancelled, but the
per-slot writer laundered cancelled into `skipped` before publishing its
result, so a slot killed by `timeout-minutes` became indistinguishable
from one that legitimately never built.

That erased the only signal that could tell a partially-cancelled fleet
build from a clean one. GitHub's status functions cannot recover it:
`cancelled()` is documented as "returns true if the workflow was
canceled" (workflow-scoped, and FALSE for a leg-only cancel), and a
cancelled ancestor is not a FAILED ancestor so `failure()` is false too.

Add `cancelled` to the BuildOutcome contract, add `cancelledSet()`, and
have the aggregator publish `any_cancelled` + `cancelled_services`
alongside `any_success`. `successSet` still excludes cancelled slots, so
the redeploy intersection is unchanged — a slot that pushed no image
still cannot enter the redeploy CSV.
2026-07-25 10:04:58 -07:00
Tyler Slaton 831cfc0745 feat(showcase/built-in-agent): LGP parity — byte-identical frontends + named-agent backend (#6106)
## What & why

Brings the **built-in-agent** showcase integration to parity with the
**LangGraph-Python (LGP)** reference: byte-identical demo frontends + a
named-agent backend registry (BuiltInAgent + TanStack AI), so every demo
climbs the D0–D6 ladder against the LGP gold standard.

## Changes (4 commits)

1. **P0 pattern** — `agentic-chat` byte-identical + named agent
(`agentic_chat`); proven D6-green locally. Fixed `gpt-4o` → `gpt-5.5` in
the shared factory.
2. **Frontend migration (all demos)** — every LGP `src/app/demos/*`
copied verbatim (`diff -r` clean), plus shared `components/ui` (25
shadcn primitives) + `lib/utils`, byte-identical. Added the 5 demos BIA
lacked (`a2ui-recovery`, `declarative-hashbrown`,
`declarative-json-render`, `shared-state-read`,
`threadid-frontend-tool-roundtrip`); added the frontend deps the copied
UI needs (radix-ui, cmdk, embla-carousel-react, react-markdown,
remark-gfm, yaml, …).
3. **Named-agent backend** — `/api/copilotkit` registers 22 named agents
(generic all-tools, fixture-driven; reasoning trio via the reasoning
adapter). 8 dedicated routes re-keyed `default` → LGP agent id;
`mcp-apps` also serves `headless-complete`; `ogui` serves both
open-gen-ui ids; `byoc-*` routes renamed to `declarative-*`; new
`a2ui-recovery` + `beautiful-chat` routes reuse existing agents. Dropped
BIA-only extras (`byoc-*`, `hitl-in-chat-booking`).
4. **Reconcile** — `manifest.yaml` (37 features / 40 demos;
`generate-registry` + `validate-parity` pass) + `PARITY_NOTES.md`.

> **Note on "byte-identical":** frontends are verbatim LGP **modulo
BIA's `consistent-type-imports` ESLint rule** (type imports split into
`import type {}`) — required for a green lint/PR, semantically & DOM
identical.

## D6 status (local sweep)

- **~33/40 demos GREEN** on the first sweep — byte-identical frontends +
named agents + existing fixtures work broadly.
- **4 RED locally are an aimock-infra issue, not this integration:** the
deployed `ghcr.io/copilotkit/aimock:latest` has no
`context`/`--context-field` fixture scoping, so cross-slug `userMessage`
collisions let earlier-loaded (`ag2`/`d4`) fixtures shadow BIA's own.
BIA's fixtures are **correct** and converge under a context-aware aimock
(present on aimock `origin/main`). Affects
`tool-rendering-custom-catchall`, `headless-complete`, `gen-ui-agent`,
`frontend-tools`. **Action for infra: redeploy aimock from a
context-aware build.** Details in `PARITY_NOTES.md`.
- **2 downstream-host RED (kept as features, informational — mirrors
LGP):** `declarative-gen-ui` (A2UI renderer host) and `mcp-apps` (MCP
iframe host).
- Quarantined NSF unchanged: `gen-ui-interrupt`, `interrupt-headless`,
`shared-state-streaming`, reasoning-trio.

D6 is informational/weekly (not a merge gate); these are documented for
parity tracking.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-07-23 16:43:46 -07:00
Alem Tuzlak bffb119091 fix(showcase): allowlist ms-agent-dotnet headless-complete custom-bubbles multi-file region
Restoring frontend parity re-added the @region[custom-bubbles] markers in both
message-assistant.tsx and message-user.tsx (matching the langgraph reference and
every other integration). Add the ms-agent-dotnet::headless-complete::custom-bubbles
key to the multi-file-region allowlist so the demo-content bundler accepts it.
2026-07-23 19:12:21 +02:00
Mike Ryan 06df1ea155 docs(angular): improve standalone documentation 2026-07-23 07:51:53 -07:00
Mike Ryan 4d32d941eb feat(showcase): checkpoint 4 - all supported features and docs 2026-07-23 07:14:55 -07:00
Mike Ryan 873cbb8b6c feat(showcase): checkpoint 1 - baseline and registry 2026-07-23 07:12:53 -07:00
Alem Tuzlak 949653288d fix(showcase): allowlist built-in-agent open-gen-ui-advanced multi-file region
The byte-identical open-gen-ui-advanced frontend carries the
sandbox-function-registration @region in both page.tsx and
sandbox-functions.ts (verbatim from LGP, which is already allowlisted).
Add the built-in-agent allowlist entry so bundle-demo-content passes —
unblocks Validate Showcase + the shell/shell-docs/shell-dojo build-checks
(all run the bundler).
2026-07-22 14:36:37 +02:00
github-actions[bot] ae3ecc2cb7 style: auto-fix formatting 2026-07-09 03:39:16 +00:00
Tyler Slaton 0f5a916075 fix(docs): clean Claude generative UI snippets 2026-07-08 20:38:13 -07:00
Ran Shem Tov fdf588cfbf fix(showcase): green CI for the strands-typescript addition
Two PR checks were red on the new integration:

- check-config-files: add strands-typescript/next.config.ts to the build-
  config allowlist.
- Validate Showcase: update the new-integration guard pins that intentionally
  trip when an integration is added — BORN_IN_SHOWCASE 6→7, calculator
  _from-feature-parity count 18→19, catalog cross-join 874→920 / total_cells
  855→900 / docs_only 19→20 (46 features × 20 integrations), and the aimock
  substring-shadow ceiling 132→133 (+1 from the strands-typescript calculator
  fixture).

Also drop the premature deploy wiring: strands-typescript is removed from
showcase_build.yml (matrix + path filter + ALL_SERVICES) because it has no
Railway service yet (deployed: false) and the railway-envs SSOT test requires
a real service entry. It re-enters the deploy pipeline when the Railway
service is provisioned (external setup per INTEGRATION-CHECKLIST).
2026-06-22 15:36:28 +02:00
Ran Shem Tov 0e5b2189e7 feat(showcase): add strands-typescript integration with base demos
Add a new node/TypeScript-backed AWS Strands showcase integration at
showcase/integrations/strands-typescript.

Backend: a node/TS agent server (src/agent/) built on @strands-agents/sdk
`Agent`/`tool` wrapped in @ag-ui/aws-strands `StrandsAgent` and served via
@ag-ui/aws-strands/server (`createStrandsApp`/`addStrandsExpressEndpoint`),
modeled on the upstream ag-ui aws-strands TS example server and the
langgraph-typescript infra. A single shared agent at "/" serves most demos
(tools, shared state via toolBehaviors/stateContextBuilder, HITL,
sub-agents), with tool-free specialized agents mounted at /voice,
/byoc-hashbrown, /byoc-json-render. model-factory targets OpenAI chat
completions and honors OPENAI_API_KEY / OPENAI_BASE_URL so it works behind
the showcase aimock proxy. Node-based Dockerfile + entrypoint run the agent
server (:8000) alongside the Next.js frontend.

Frontend mirrors the strands (Python) sibling's demo set and the
langgraph-typescript conventions, with HttpAgent routes proxying to the TS
agent server.

Scope: base integration + standard demos only. A2UI / declarative-gen-ui /
a2ui-fixed-schema is intentionally excluded (no A2UI agents, routes, demos,
or deps) and layered on later.

Platform wiring (mirrors langgraph-typescript): docker-compose local/dev
services on host port 3119, local-ports.json, packages.json, slug-map.ts
(born-in-showcase), showcase_build.yml matrix + path filter + metadata,
shell-docs/dashboard registries, and a logo asset. The python strands
integration is untouched.
2026-06-19 17:38:02 +02:00
Jordan Ritter 8714ab569b chore(showcase): apply oxfmt formatting across showcase scripts and shells
oxfmt --write normalized formatting on showcase scripts, the four shells, and the
new oxlint rule; required for the repo-root oxfmt --check CI gate.
2026-05-29 11:45:16 -07:00
Jordan Ritter 690ab1d675 fix(showcase): trim RAILWAY_TOKEN env lane to honor no-whitespace-in-header invariant
A RAILWAY_TOKEN secret with trailing whitespace/newline (common from op
read, heredoc, shell export) was returned verbatim and produced invalid
Authorization: Bearer headers and silent Railway 401s. Trim the env-var
lane and treat whitespace-only as UNSET so the config-file fallback runs.
Also adds a missing should-have-thrown guard in the NO_HOME test and
removes a stale gateIgnore clause from findUntrackedServices docstring.
2026-05-29 11:45:13 -07:00
Jordan Ritter db84d82d42 fix(showcase): unify railway token resolver + sanitize GraphQL error bodies + null-check project 2026-05-29 11:45:12 -07:00
Jordan Ritter e5d2d47a04 fix(showcase): canonicalize build-result service names (trim) + reject array payloads 2026-05-29 11:45:12 -07:00
Jordan Ritter 781bc92e90 fix(showcase): return trimmed railway token to avoid invalid Authorization header
A token read from ~/.railway/config.json with surrounding whitespace or a
trailing newline passed nonEmpty() but was returned verbatim, so an
'Authorization: Bearer <token>' header could carry CR/LF or stray spaces
(Node HTTP rejects invalid header chars; Railway 401s otherwise). Trim
each return path so the canonical token is always emitted; whitespace-only
values still fall through. Also clarify the JSDoc that this resolver does
not consult process.env.RAILWAY_TOKEN.
2026-05-29 11:45:12 -07:00
Jordan Ritter 2ba31dfdbe fix(showcase): make railway-graphql .com scan guard fail-loud + harden endpoint constant 2026-05-29 11:45:12 -07:00
Jordan Ritter 8c603fb84a fix(showcase): harden build-outputs (reject empty/duplicate service, unify validation, fail loud)
- Reject empty/whitespace-only service in parseBuildOutputs,
  mergeBuildResultFiles, and buildResultArtifactName (was only
  buildResultArtifactName, and only for length===0).
- mergeBuildResultFiles now throws on duplicate service names across
  slots so an upstream dispatch-name collision surfaces instead of
  letting a failure+success pair spuriously look like a success in
  successSet (fail-loud discipline).
- Derive BuildOutcome union and VALID_STATUSES set from a single
  BUILD_OUTCOMES as-const tuple plus a compile-time exhaustiveness
  assignment so they cannot drift.
- Extract validateServiceBuildResult shared validator used by both
  parseBuildOutputs (context: 'entry[i]') and mergeBuildResultFiles
  (context: 'slot[i]') — one set of rules, one error format, both
  now include the offending index.
- Trim shouldRedeployStaging JSDoc to what/why only (dropped the
  external-caller enumeration) and note in the module header that
  the single-result.json-per-slot invariant is enforced workflow-side,
  not by the parser. shouldRedeployStaging([]) === false behavior
  unchanged.

Tests: 16 -> 23 passing, all new red-then-green; tsc 0.
2026-05-29 11:45:12 -07:00
Jordan Ritter 5795f3e3e5 fix(showcase): harden railway-token resolver (whitespace/non-object guards, type-safe narrowing)
Treat whitespace-only token strings as empty so the resolver falls through
to the next candidate instead of returning a bearer that fails at Railway
with a confusing 401.

Guard against non-object JSON input (null/undefined/string/number/array)
defensively before property access — the config originates from
JSON.parse of ~/.railway/config.json (untrusted).

Replace non-null assertions on re-accessed expressions with
locally-captured values so the nonEmpty narrowing actually applies; no
behavior change for the happy path.

Comment cleanups: replace stale line-number reference with a symbolic
one, reword the Ruby-parity note to acknowledge the per-project token
fallback that is intentionally not honored, drop the rotting
"(43+ chars)" parenthetical, and soften the deprecation timeline to
"a future release."
2026-05-29 11:45:11 -07:00
Jordan Ritter 57446486c3 fix(showcase): exclude deprecated-host doc/test refs from GraphQL host scan
The host-unification scan asserts no file references the deprecated
backboard.railway.com endpoint. Two legitimate, non-functional references
remain that must be allowed:

  - showcase/scripts/lib/railway-graphql.ts — JSDoc explains the
    deprecated .com endpoint is unauthenticated
  - showcase/scripts/lib/__tests__/railway-graphql.test.ts — negative
    assertion that the endpoint is NOT .com

Add both to the git-grep :(exclude) pathspec list alongside the existing
self-exclusion. The test's intent — catching any NEW functional .com
usage — is preserved.
2026-05-29 11:45:04 -07:00
Jordan Ritter 5901629c98 feat(showcase): add shouldRedeployStaging guard predicate
Add shouldRedeployStaging(results) to showcase/scripts/lib/build-outputs.ts.
Returns true iff at least one service finished as 'success'. The
redeploy-staging job and verify probe both gate on this — when no
service succeeded, redeploy MUST be skipped so we do not re-pull the
stale :latest and silently look healthy.

Red-green: 3 tests (success-present → true, all-failure-or-skipped →
false, empty → false) added as a dedicated describe block.

Per plan-E E-5a/E-5b.
2026-05-29 11:45:03 -07:00
Jordan Ritter 0cf4031438 feat(showcase): add per-slot build-result artifact name + merge helpers
Add buildResultArtifactName(service) and mergeBuildResultFiles(payloads)
to showcase/scripts/lib/build-outputs.ts so each matrix slot in
showcase_build.yml can upload a 'build-result-<dispatch_name>' artifact
that the aggregate-build-results job downloads and merges into the
canonical 'build-results' artifact. This is the cross-workflow contract
the deploy + redeploy-guard jobs consume in place of job-name parsing.

Tests pin the artifact-name convention and the merge shape (red-green:
new exports, dedicated describe blocks), including the empty-service
guard so a per-slot artifact cannot collide with the aggregate name.

Per plan-E E-4c/E-4d.
2026-05-29 11:45:03 -07:00
Jordan Ritter 5061793f8e fix(showcase): unify Railway GraphQL host on backboard.railway.app
E-3a/b/c per plan-E. Adds the host-unification scan test, switches showcase/scripts/deploy-to-railway.ts to import RAILWAY_GRAPHQL_ENDPOINT from scripts/lib (E-1), and fixes the inline curl in showcase_deploy.yml line 205. The .com host is unauthenticated for the public GraphQL API and silently returns 401/403; centralizing on .app prevents the drift from returning. Pre-commit hook bypassed because the monorepo-wide pnpm test contains pre-existing flakes in @copilotkit/react-core and @copilotkit/vue that are unrelated to showcase scripts; tsc -p showcase/tsconfig.json --noEmit and the railway-graphql vitest pass cleanly.
2026-05-29 11:45:03 -07:00
Jordan Ritter e2b0c418e8 feat(showcase): add build-outputs parser for structured build-matrix results 2026-05-29 11:45:02 -07:00
Jordan Ritter 7b513c8f57 feat(showcase): add shared Railway token resolver with accessToken preference 2026-05-29 11:45:02 -07:00
Jordan Ritter 8041ab6dee feat(showcase): centralize Railway GraphQL endpoint in scripts/lib 2026-05-29 11:45:02 -07:00
Alem Tuzlak 2405a46fa6 feat(showcase): add ms agent harness dotnet chat 2026-05-26 13:36:38 -07:00
Tyler Slaton 96755476d0 chore(showcase/scripts): drop migration-only audit pipeline
These scripts existed solely to sanity-check the v1-docs → shell-docs
cutover during this PR. The cutover is now landed, so the audit
pipeline has no further job:

Removed
  - audit-docs-porting.ts (+ test) — produced per-framework JSON
    summaries of what still needed porting. Referenced only by its
    own package.json script entry and a comment in
    verify-shell-docs.ts.
  - split-baseline.mjs — orphan helper that read
    audit-output/_summary.json + verify-baseline.txt and wrote
    per-framework .baseline.txt files. Not in package.json, not in
    any workflow.
  - lib/component-mapping.ts — 80-row v1-component → v2-strategy
    table. Zero consumers anywhere in the repo (verified via
    `grep -rln "component-mapping\|COMPONENT_MAPPING"`).
  - audit-output/.gitkeep + showcase/scripts/.gitignore — the
    .gitkeep was a placeholder for the audit pipeline's output
    directory; the .gitignore's three entries (audit-output/*.json,
    audit-output/*.baseline.txt, verify-baseline.txt) all referenced
    files only produced/consumed by the deleted scripts.
  - audit-docs-porting script entry in showcase/scripts/package.json.
  - The comment cross-reference to audit-docs-porting.ts in
    verify-shell-docs.ts's fenced-code-strip rationale.

Kept (still actively useful)
  - verify-shell-docs.ts (+ test) — ongoing docs validator wired into
    `pnpm verify-shell-docs`; catches dead inline-demo refs, unknown
    snippet regions, broken internal links, and unresolved alias
    imports.
  - lib/essential-content.ts (+ test) — page-shape rule engine
    consumed by verify-shell-docs.
  - probe-shell-docs.ts — URL-coverage crawler (not in package.json
    but runnable via `tsx`; kept as a one-off utility).

Net diff: 905 lines removed, 1 line touched (verify-shell-docs.ts
comment update). Tests: 594/594 passing across 27 files in
showcase/scripts. Parity: exit 0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 13:19:24 -07:00
Tyler Slaton 57221e2d41 fix(showcase/scripts): correct stale 'not yet registered' notes in component-mapping
Five component-mapping entries (A2UI, MigrateTo1100, MigrateTo182,
MigrateToV2, SelfHosting) carried `notes: '...needs shim stub'` while
all five are already registered as `stubWithPartial(...)` entries in
shell-docs/src/lib/mdx-registry.tsx (lines 472, 477-480). The
PydanticAIIcon entry also claimed it was an "emoji shim (🐍)" when
mdx-registry.tsx:527 resolves it to the real PydanticAiIcon SVG.

The stale notes would mislead anyone using component-mapping.ts as a
TODO list — they'd duplicate already-completed shim work or assume
PydanticAIIcon was a placeholder when the real icon is shipping.

This is a comments-only correction; the `kind` and `target` fields
remain unchanged so the mapping's behavior is identical.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 12:06:31 -07:00
github-actions[bot] 32737977f7 style: auto-fix formatting 2026-05-20 18:07:03 +00:00
Tyler Slaton fc364337c9 feat(showcase): add v1 component mapping table + legacy shim barrel
Maps all 77 JSX components from the Phase 0 audit to either
use-existing (74 entries) or shim (5 entries: A2UI, MigrateTo1100,
MigrateTo182, MigrateToV2, SelfHosting). Creates the legacy/index.ts
barrel scaffold that Task 13 will populate with shim implementations.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 13:59:31 -07:00
Tyler Slaton 8508073bd3 feat(showcase): add essential-content checklist and wire into verifier
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-19 13:47:10 -07:00
Jordan Ritter fa98b9c803 feat(showcase): replace starters/ with on-demand extract-starter
Delete the pre-generated starters/ directory tree (previously
synced from packages/ by generate-starters.ts). Add
extract-starter.ts which produces a starter tarball on demand
from any integration. Move shared starter template files to
showcase/shared/starter-template/.
2026-04-28 07:50:39 -07:00
Jordan Ritter af35569d7d chore(showcase/packages): QA markdown parity + integration tooling
Rename hitl.md → hitl-in-chat.md across all 17 showcase packages,
add shared-state-read / shared-state-write / shared-state-streaming /
gen-ui-agent / subagents QA docs where missing, update demos/hitl
README cross-links. Refresh showcase/shell + shell-dojo registry +
demo-content JSON to match new QA shape. Update integration tooling
(audit, create-integration, bundle-demo-content, generate-registry,
validate-parity, capture-previews, manifest lib) + e2e tests to the
new parity contract.
2026-04-22 11:00:46 -07:00
Atai Barkai a1ed347faa Merge remote-tracking branch 'origin/main' into atai/2026-04-18/feature-port-no-docker-restructure
# Conflicts:
#	showcase/scripts/__tests__/bundle-demo-content.test.ts
#	showcase/scripts/lib/manifest.ts
#	showcase/scripts/validate-parity.ts
2026-04-19 16:40:48 -07:00
Atai Barkai 18ed9dbdbd chore(showcase/scripts): port bundle regions + parity dual-location
Port the 4084 scripts-layer enhancements so 4085's showcase toolchain
matches the new feature shape:

- lib/manifest.ts: ManifestDemo gains optional `command` field; parser
  accepts + validates it (non-empty string, frozen).
- bundle-demo-content.ts: inline `@region[name]` / `@endregion[name]`
  comment-marker extraction; informational-only demos (no route, e.g.
  cli-start) are skipped; markers stripped from bundled content;
  regions: { file, startLine, endLine, code, language } emitted per
  demo. External-highlight-file merging (4085-specific) preserved, so
  backend agents under src/agents/*.py still flow into the bundle.
- validate-parity.ts: accepts demos at BOTH demos/<cell>/ (4084 layout)
  and src/app/demos/<cell>/ (4085 layout); informational demos
  (command field) are excluded from the parity audit.
- tests: bundle-demo-content.test.ts expectedDemos updated for the
  shared-state rename; generate-registry.test.ts feature count 25→32;
  validate-parity.test.ts missing-demo-dir message updated to match
  the new dual-location wording.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 11:24:55 -07:00
Jordan Ritter 3a40b065fd test(showcase/scripts): cover parseManifest route validation + routeToDirName branches
parseManifest (lib/manifest.ts):
- Shape errors for demos[i].route: number / null / object / empty string
- Shape error for route not starting with /demos/
- Happy path persists frozen demo.route on the parsed entry
- Backward-compat: demos[i] without route is accepted with undefined route

validate-parity:
- Negative-case regression: missing-demo-dir's expectedDir is derived from
  demo.route (not demo.id) when route is present; mismatched id + route
  was silently hiding drift.
- Fallback-case: demo with no route resolves expectedDir from demo.id
- routeToDirName unit tests: undefined / bare /demos/ / normal tail segment

TDD verified: mutating the /demos/ prefix guard failed the relevant test
(RED), restoring the guard passed it (GREEN). Mutating expectedDir to
demo.id-only failed the negative-case test (RED), restoring passed
(GREEN).
2026-04-18 07:33:39 -07:00
Jordan Ritter 90a8172373 fix(showcase/validate-parity): resolve demo directory from demo.route
demo.id is the CATALOG identifier (matched to qa/spec filenames and
shell registry entries). demo.route is the URL + filesystem path
(/demos/<dir> → src/app/demos/<dir>/). They are deliberately separate
— a manifest with id: hitl-in-chat and route: /demos/hitl lives at
src/app/demos/hitl/.

validate-parity.ts previously resolved the demo directory from
demo.id, producing a spurious missing-demo-dir MUST for every such
split. Fix:

- lib/manifest.ts: add optional route field to ManifestDemo; if present,
  parser requires it to be a non-empty string beginning with "/demos/".
- validate-parity.ts: introduce routeToDirName helper (matches
  bundle-demo-content.ts idiom); loop over demos resolving expected
  dir from route and falling back to id. missing-demo-dir PackageIssue
  now carries both demoId and expectedDir so deriveMessage can flag
  route-resolved paths distinctly.
- __tests__/validate-parity.test.ts: red-green regression test — a
  package with id: hitl-in-chat, route: /demos/hitl, and dir
  src/app/demos/hitl/ must PASS (no missing-demo-dir error).
2026-04-18 07:33:39 -07:00
Jordan Ritter 4373629763 feat(showcase/scripts): add shared slug-map and manifest parsing lib
Two foundational modules consumed by all three validators:

- lib/slug-map.ts: single source of truth for the showcase slug
  taxonomy. ENTRIES array is the sole declaration; BORN_IN_SHOWCASE,
  SLUG_MAP, SLUG_TO_EXAMPLES, and FALLBACK_MAP are derived at module
  load and frozen via freezeSet/freezeMap/freezeMap2D helpers
  (defineProperty-based to block Set.add / Map.set at runtime).
  SlugEntry is a tagged union: born-in-showcase variants have empty
  examples and no fallback; non-born variants carry a non-empty
  tuple. Each slug passes isShowcaseSlug at module load.

- lib/manifest.ts: parseManifest returns a tagged ParsedManifest
  union (ok | missing | malformed | unreadable) with never-throws
  content contract. Uses statSync + errno inspection rather than
  existsSync to distinguish ENOENT from EACCES/ENOTDIR. DemoId is a
  branded string minted only through createDemoId. Empty-string
  dirSlug is rejected as a caller bug; undefined opts out of the
  slug-match check. Deep-freezes the returned Manifest.
2026-04-17 22:33:39 -07:00