[pull] main from CopilotKit:main#300
Merged
Merged
Conversation
Add a top-level Cookbook section to the docs (landing page + meta.json wiring) and the first recipe: wire CopilotKit's Built-in Agent up with a runCode server tool that executes code in an isolated Daytona sandbox. The tool takes a language (python/typescript/javascript, default python) and returns stdout + exit code; recipe code validated end to end against published @copilotkit/runtime@1.58.0 with both Python and JavaScript snippets round- tripping through a real sandbox. Also fixes a stale '../direct-to-llm/cookbook/state-machine' link in learn/meta.json by repointing it at the new /cookbook section. OSS-222
Add an installable Agent Skill that wires a Daytona-backed runCode server tool into an existing CopilotKit Built-in Agent app. Mirrors the structure of skills/copilotkit-setup (SKILL.md + assets + references + eval.yaml + sources.md + a workspace fixture). References point at Daytona's maintained sources (llms.txt, dashboard limits, the official daytona skill, and the Daytona MCP server) rather than duplicating a hand-copied SDK surface that would rot. The runCode tool itself was validated live against published @copilotkit/runtime@1.58.0 with Python and JavaScript snippets executing in real sandboxes. The recipe in docs/content/docs/cookbook/daytona.mdx now also points at this skill alongside the inline coding-agent prompt. OSS-222
Remove the root and learn meta.json entries that placed the Cookbook in the docs sidebar / Learn footer, deferring the nav-placement decision (top-level tab vs sidebar group) to a follow-up. The recipe pages still route at /cookbook and /cookbook/daytona (Fumadocs discovers MDX from the filesystem, confirmed via .source generation), so Daytona-side deeplinks continue to work. Nothing in our docs nav points at the section until the decision lands. Also drops the stale '[Cookbook: State Machine]' Learn entry entirely (it had been temporarily repointed to /cookbook in the previous commit). OSS-222
Decision made on the nav-placement deferral from the previous commit: the Cookbook gets a top-level nav tab (next to Learn) — mirroring how reference and learn appear both as top-level tabs and as root meta.json entries. Adds a Cookbook entry to LEFT_LINKS in navbar.tsx using the lucide ChefHat icon (matching the section's frontmatter icon) and restores 'cookbook' to the root docs meta.json so it also appears in the Documentation sidebar. OSS-222
…up skill @copilotkit/react and @copilotkit/agent do not exist on npm. Replace with the real published packages (@copilotkit/react-core, @copilotkit/runtime) and update all import paths to use the v2 subpath exports throughout.
Verification revealed @copilotkit/runtime/express is not a real subpath export (throws ERR_PACKAGE_PATH_NOT_EXPORTED). The correct path is @copilotkit/runtime/v2/express.
After validating the recipe's inline 'Get started' prompt against a fresh coding-agent run on a minimal Built-in Agent fixture, the skill package is no longer needed — the prompt alone produces the same correct setup. Keep the docs surface minimal per OSS-222's 'as minimal as possible' mandate. OSS-222
- Remove the 'copilotkit-daytona skill packages this same setup' sentence
from the 'Get started with a coding agent' section, since the skill is
no longer shipped.
- Tighten the prompt so coding agents map the Daytona SDK response
correctly: `codeRun` returns an ExecuteResponse whose stdout is on
`.result` (not `.stdout`). A verification run with a fresh subagent
on a minimal Built-in Agent fixture initially produced `{ stdout:
res.stdout }` (silent undefined); the tightened prompt now reliably
produces `{ stdout: res.result, exitCode: res.exitCode }`.
OSS-222
…l-docs Addresses PR review feedback (@tylerslaton): the docs/ folder is deprecated in favor of showcase/shell-docs and will be removed soon. Move the entire Cookbook contribution to shell-docs: - showcase/shell-docs/src/content/docs/cookbook/ — landing + Daytona recipe copied verbatim (Fumadocs frontmatter/components/dividers all match). - showcase/shell-docs/src/content/docs/meta.json — new top-level '---Cookbook---' divider with a '...cookbook' spread, slotted between Platforms and Other. - showcase/shell-docs/src/components/brand-nav.tsx — Cookbook tab added to LEFT_LINKS (lucide ChefHat icon) and active-route detection extended so /cookbook/* highlights it (peer to the existing Reference handling). Reverts all earlier edits to docs/ from this PR (navbar, root meta, learn meta, and the docs/content/docs/cookbook/ tree) so the deprecated folder is left at zero-diff vs main. OSS-222
…emote
shell-docs renders MDX server-side via MDXRemote, not Fumadocs's compile-
time MDX pipeline, so inline 'import { Boxes } from "lucide-react"' in an
.mdx body doesn't resolve at render time — Boxes ends up undefined and the
page errors with 'Expected component Boxes to be defined' on /cookbook.
Drop the import and the icon prop from the landing's <Card>. Existing
shell-docs pages (e.g. tutorials/ai-powered-textarea/*) use <Card> with no
icon, so this matches the local idiom. The Daytona recipe page is
unaffected because its icon is in frontmatter (icon: 'lucide/Boxes' — a
string, resolved by the page layout, not by MDX body).
OSS-222
The deployable Next.js demo behind the new Daytona cookbook recipe. A minimal CopilotKit Built-in Agent whose only added capability is the recipe's runCode server tool — executes Python / TypeScript / JavaScript in an isolated Daytona sandbox and streams the result back to the chat via a custom useRenderTool card (fixed-height streaming code pane with react-syntax-highlighter + vscDarkPlus, mirroring @copilotkit/react-ui's own CodeBlock, and a fixed- height result pane with a 'Generated code:' / 'Result:' label pair). The agent's system prompt instructs it not to restate stdout in chat text since the renderer already shows it. Standalone npm project — intentionally not in the monorepo's pnpm workspace (matches the existing examples/showcases/* convention; only generative-ui- playground is in the workspace globs). Validated end to end against published @copilotkit/runtime@1.58.0 with both Python and JavaScript snippets round- tripping through real Daytona sandboxes. OSS-222
Reviewer asked to emphasize the runCode tool more, so:
- Replace CopilotSidebar with a centered CopilotChat (the chat is now the
focal point of the page rather than a docked side panel).
- Increase the renderer's code pane to ~12 lines (was ~6) so multi-line
generated code is visible without scrolling.
- Add 'Generated code:' label above the code pane to match the 'Result:'
label below.
- Configure starter suggestion pills via useConfigureSuggestions with
descriptive titles ('Python — Zoo animals', 'TypeScript — Fibonacci
numbers', 'JavaScript — Current timestamp') and available: 'always' so
they persist across iterations rather than disappearing after the first
message.
- Wrap the chat in CopilotChatConfigurationProvider to replace the default
'How can I help you today?' welcome text with something on-topic
('Ready to run code in a Daytona sandbox. Try a starter below, or
describe what you'd like to execute.').
- Tighten the BuiltInAgent system prompt so the agent does not restate
stdout in chat text — the renderer card already shows it.
OSS-222
Embed the live demo directly in the cookbook recipe, mirroring the in-doc
iframe approach used by integration landing pages (framework-overview.tsx
liveDemos[] / IframeSwitcher). The recipe now opens with a 'Try it live'
section above the prerequisites, iframing the showcase deployment so
readers can drive the runCode tool against a real Daytona sandbox without
leaving the page.
URL is a placeholder ('showcase-daytona-runcode-production.up.railway.app',
matching the showcase-{slug}-production.up.railway.app backend host
pattern from the registry generator). Will render Railway's not-found
page until a permanent demo deployment is provisioned at that name; the
inline MDX comment notes the placeholder.
OSS-222
…elpers Single source of truth mapping SSOT service keys to Railway service/env IDs, dispatchName values, ciBuilt/gateValidated flags, and per-env repo-name overrides (aimock and pocketbase/webhooks map to their showcase-* wrapper repos in both envs). Adds dispatchName round-trip + workflow YAML forward-guard tests.
…atest) Prod must be sha256-digest-pinned (promote-only); staging floats :latest. Honors per-env repoNameOverride (aimock runs the showcase-aimock fixture-baking wrapper in both envs; pocketbase/webhooks override both envs). Adds coverage assertion for gateValidated services.
…ploys Resolves dispatchName/SSOT keys to service IDs and calls serviceInstanceRedeploy. Default scope is the 25 CI-built services (never pocketbase/webhooks). Staging failures are non-blocking (exit 0); prod failures exit 1. Config errors fail loud.
Push-to-main now redeploys staging only (never prod) via redeploy-env.ts in a dedicated redeploy-staging job, guarded to tolerate per-slot build failures but suppress on wholesale build skip/cancel. Prod stays promote-only.
…user.token fallback)
…user.token fallback)
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.
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.
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.
… scaffold on backboard.railway.app
…t 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.
…lt artifacts
Build matrix slots now publish per-slot build-result-<dispatch_name>
artifacts containing {service, status}. A new aggregate-build-results
job downloads every per-slot artifact, merges them via the shared
mergeBuildResultFiles helper, and uploads the canonical build-results
artifact (results.json) for cross-workflow consumption.
The deploy workflow's resolve-matrix step now downloads build-results
via gh api .../artifacts/<id>/zip and filters its verification matrix
from the structured JSON success set. No more gh api .../jobs calls,
no more capture("^build \\(") regex on job names — those silently
break on job-name renames. The contract (service + status enum) is
enforced in one place: showcase/scripts/lib/build-outputs.ts.
[BLITZ:L3-wf] E-4e/E-4f wiring.
… upload mandatory
Three correctness holes uncovered by confirmation review of the earlier
deploy-gate fix:
(1) showcase_deploy.yml — Build verify matrix step: when workflow_run fires
with summary_present=false (legitimate "build redeployed nothing", e.g.
docs/script-only push under showcase/**), the gate correctly no-oped but
the matrix fell through the empty-OK_FROM_REDEPLOY branch and resolved to
the FULL probe-eligible set. Verify then ran against the whole staging
fleet for a push that deployed nothing — gratuitous, and false-reds the
deploy workflow if any unrelated staging service happens to be unhealthy
at probe time. Thread github.event_name + summary_present into the step
via env and add an explicit (workflow_run && summary_present==false)
guard that sets services_csv="" / has_services=false. workflow_dispatch
fall-through (full fleet / chosen service) preserved. workflow_run +
summary present + all-errors path unchanged: enforce-redeploy-gate still
trips RED on redeploy_red=true.
(2) showcase_build.yml — Upload redeploy summary step: was gated on
services != '' && hashFiles('.redeploy/summary.json') != ''. If
redeploy-env.ts crashes before writing summary.json (the script is
documented "always exits 0", but a crash/OOM/unhandled-rejection can
skip the write), services != '' but hashFiles == '' silently skipped
the upload. The deploy side then saw "artifact absent", treated it as
"nothing redeployed", skipped the gate, and produced a FALSE GREEN
despite a real redeploy failure. Drop the hashFiles clause so the upload
is mandatory whenever a redeploy was attempted; if-no-files-found:error
(already set) then fails the step → fails the redeploy-staging job →
fails the build workflow → showcase_deploy.yml's resolve-matrix.if
(workflow_run.conclusion == 'success') blocks the deploy run from
starting at all. Loud failure on the build side. The legitimate
services == '' (matrix ∩ success-set empty) path is preserved by the
services != '' guard.
(3) showcase_deploy.yml — check-redeploy-summary github-script: was a
single per_page:100 list call. While the current run uploads ~28
artifacts (well within 100), a future expansion past 100 could push
redeploy-summary off the first page and produce a false "absent" → gate
skipped → false-green. Switch to github.paginate.iterator with the
endpoint's name="redeploy-summary" filter for an exact-match,
pagination-safe lookup. No try/catch is added: github-script propagates
unhandled rejections by default, so a 5xx/permission error fails the
step → resolve-matrix.result == 'failure' → enforce-redeploy-gate trips
RED. Silent default-to-false on API error would open the gate on a
broken pipeline, which is what we explicitly do NOT want.
Validation: actionlint shows 8 findings on both files, identical to the
integration baseline (zero new findings). python3 yaml.safe_load OK on
both. Regression suites green: showcase/scripts vitest 44/44
(aggregate-build-results + lint-rule-no-public-env);
showcase/bin/spec/all_tests.rb 87 runs / 251 assertions / 0 failures.
…redeploy success-set empty
Extract the inline bash+jq decision logic from showcase_deploy.yml's
resolve-matrix job into showcase/scripts/resolve-verify-matrix.ts, a
pure function with a vitest suite. The bash had produced two confirmed
bugs across prior CR rounds, so making it testable is the lasting fix.
Issue A (the bug this PR fixes): when summary_present=true but
ok_services is empty (every service errored on redeploy), the old bash
skipped the intersection and fell through to the full probe-eligible
fleet, gratuitously probing every service against stale :latest. The
resolver now returns has_services=false in that case — enforce-redeploy
-gate independently reds the workflow on redeploy_red=true, so this
case is already loud; there is nothing left to verify.
Parity preserved for unchanged cases:
- workflow_dispatch + 'all'/empty → full probe-eligible set
- workflow_dispatch + specific svc → that one (unknown → error exit)
- workflow_run + summary_present=false → has_services=false
- workflow_run + present + ok non-empty → intersection with probe-
eligible (SSOT key OR dispatchName aliases both resolve)
Also clarified the Upload-redeploy-summary comment in showcase_build.yml
to document both red paths (hard crash → redeploy step exits non-zero;
exit-0-but-no-file → if-no-files-found:error reds the step) so no
false-green path is possible.
Tests: 12-case vitest suite covers each decision-table row plus the
Issue A fix (written red-first; failed against a naive full-fleet
fallback, passed once the early return was added). CLI parity verified
against the real generated SSOT for the three representative env-var
combinations (workflow_run + present + ok=[a,c]; workflow_run + present
+ ok empty; workflow_dispatch + 'all').
…e), fail loud, test CLI contract
A 7-agent review of the verify-matrix resolver and its surrounding workflow plumbing found three
boundary surfaces that could silently produce a GREEN deploy on a broken release, plus an
untested CLI contract that CI compares against the literal strings 'true' / 'false'.
FIX 1 — Validate the SSOT shape in loadSsotServices(). The prior `JSON.parse(...) as
{services: SsotService[]}` was an unchecked cast: a truncated/drifted SSOT (emitter crashed
mid-write, or schema renamed) parses fine but silently shrinks/empties the probe-eligible set
→ some redeployed services go unverified, or verify is skipped on a real redeploy. Extract a
pure exported parseSsotServices(raw, path) that requires the shape we depend on (non-empty
services array; each entry has a non-empty string name, an optional string|null dispatchName,
and a probe object with a boolean staging). Throw `::error::SSOT <path> malformed: <detail>`
on any violation. Also re-check existsSync(SSOT_JSON) after the regenerate-if-missing
execFileSync — a regen that exits 0 without writing must not proceed to a useless JSON.parse
crash. Drop the defensive `probe?.staging` once shape is guaranteed.
FIX 2 — Validate summary.json shape in the redeploy-gate bash. The bullseye false-green
surface: if redeploy-env.ts's schema ever drifts (e.g. `status` → `state`, `ok` → `success`),
every `jq select(.status==...)` yields empty → redeploy_red=false AND ok_services="" →
resolver skips verify → GREEN CI on a real unverified redeploy. Add a TOTAL vs WITH_STATUS
shape guard right after loading the summary: if TOTAL > 0 && WITH_STATUS == 0, emit
::error::summary.json has $TOTAL entries but none with status ok|error (schema drift?) and
exit 1. The legitimate empty-array path (TOTAL=0) is preserved.
FIX 3 — Fail loud on unknown eventName in resolveVerifyMatrix. The prior code fell through to
the workflow_run intersection branch for ANY unrecognized eventName (typo, unexpected
trigger), silently emitting has_services=false → indistinguishable from a legit "summary
absent" skip. Add an explicit guard so only workflow_run / workflow_dispatch are accepted;
anything else throws ::error::resolve-verify-matrix: unexpected eventName '<value>'. Tighten
the eventName parameter type to the literal union.
FIX 4 — Trim ok tokens + warn on dropped tokens in okCsvToCanonicalNames. Split, then
.map(t => t.trim()).filter(Boolean) so "a, b" (spaces) matches. Collect tokens that match NO
SSOT service (by name or dispatchName) and have the CLI wrapper emit ::warning::ok_services
tokens dropped (no SSOT match): <list> on stderr when non-empty — surfaces SSOT/build drift.
The pure function stays IO-free; logging lives in the wrapper.
FIX 5 — CLI wrapper integration test. New resolve-verify-matrix.cli.test.ts spawns
`npx tsx showcase/scripts/resolve-verify-matrix.ts` with a temp $GITHUB_OUTPUT file across
four scenarios and asserts the temp file contents EXACTLY (the workflow YAML compares
has_services against the literal strings 'true'/'false', so the byte-for-byte format is part
of the contract). Uses the real railway-envs.generated.json so the loader exercise is real.
FIX 6 — Cleanup. Remove the dead `env: DISPATCH_SERVICE: ...` block on the redeploy-gate
step (the next step redeclares it — leftover from the extraction). Soften the §3
decision-table all-errors bullet to match resolve-verify-matrix.ts's careful wording, and
append that when the success-set is empty (or the intersection collapses to empty), verify
is skipped and the gate reds independently. Append to showcase_build.yml's "Upload redeploy
summary" path-(A) comment that `if-no-files-found: error` still reds path (A) even if a
future change adds `if: always()`.
Tests: red→green for FIX 1/3/4/5 verified locally. Resolve-verify-matrix vitest count:
12 → 28. Full requested suite (resolve-verify-matrix + cli + aggregate-build-results +
lint-rule-no-public-env): 72 passed. showcase/bin ruby specs: 87 runs / 0 failures / 0
errors / 0 skips. actionlint baseline preserved (8 findings, identical to integration tip).
…es; fix stale comment + flaky test
Closing hardening pass on the showcase deploy-gate's verify-matrix
resolver. The 7-agent review confirmed the gate is correct; this
commit fixes the residual rough edges.
- showcase_deploy.yml: correct the false §3 ok-non-empty comment.
The empty-intersection case can coexist with redeploy_red=false
(every redeploy succeeded, just none probe-eligible) — that's a
correctly-green run, not a red one.
- showcase_deploy.yml: tighten the summary.json shape guard to catch
PARTIAL drift (TOTAL>0 && WITH_STATUS<TOTAL). The previous all-or-
nothing TOTAL>0 && WITH_STATUS==0 check silently dropped drifted
rows on a mixed summary. Validated locally on mixed/normal/empty/
total-drift jq samples.
- resolve-verify-matrix.ts: add asSupportedEventName narrowing helper
+ use it in the CLI. Replaces the unchecked `as` cast — type system
and runtime now tell one story. Resolver's internal eventName
guard becomes defense-in-depth for direct (test) callers.
- resolve-verify-matrix.ts: make the workflow_run boundary total —
summaryPresent MUST be exactly "true"/"false". Any other value
(including "" from a step-id-rename wiring break) throws now
instead of silently emitting has_services=false.
- resolve-verify-matrix.ts: drop the try/catch around
fileURLToPath(import.meta.url) in `invokedDirectly`. The catch
used to swallow ESM-interop failures and silently no-op the CLI
(exit 0, no GITHUB_OUTPUT write → verify skipped = false-green).
- resolve-verify-matrix.ts: reword parseSsotServices JSDoc to
distinguish schema-drift from truncation (the two are different
failure modes, not one conflated story).
- showcase_build.yml: comment addendum on the redeploy-summary
upload — swapping the guard to `if: always()` would red the
legitimate services=='' path (no summary written), trading the
already-closed false-green for a false-red on every non-buildable
push.
- resolve-verify-matrix.cli.test.ts: switch to spawnSync so stderr
is captured on both zero and non-zero exit (execFileSync only
exposes stderr on throw). Hard-code two stable probe-eligible
names ("aimock", "harness") for the sorted-CSV test rather than
picking probe[0]/probe[1] off the live SSOT — the prior test was
tautological (already-sorted in, sorted out) and would silently
pass if the resolver did nothing.
- resolve-verify-matrix.cli.test.ts: add CLI coverage for the
dropped-token ::warning:: path (FIX 3 — the entire drift-detection
contract had zero CLI coverage), the unexpected-EVENT_NAME error
(FIX 5), and the workflow_run-summary_present total boundary
(FIX 7, both "" and "True" inputs).
- resolve-verify-matrix.test.ts: add unit coverage for the new
workflow_run summaryPresent boundary (empty + "True" + the
workflow_dispatch ignores-summaryPresent regression).
Red-green: 6 tests RED before code changes (FIX 3 warning, FIX 5
unknown EVENT_NAME, FIX 7 unit + CLI ×2 for "" and "True"); 79
tests GREEN after.
Validation: 4 vitest files / 79 tests passing; 87/87 ruby specs
passing; actionlint findings unchanged vs integration baseline
(8 → 8, identical diff); yaml.safe_load OK on both workflows.
…-config; tolerate env-name variants
Six fixes addressing CR findings on the Option-B runtime URL-injection migration:
1. SSR_PLACEHOLDER must be parseable URL sentinels — `new URL("")` throws on
SSR causing 500s for any consumer that constructs URLs from runtime-config
fields. Use `.invalid`-TLD sentinels (RFC 2606) for URL fields; analytics
keys stay empty string. Add `suppressHydrationWarning` on consumers that
render the placeholder server-side and the real value post-hydration
(integration-grid, page-actions popover).
2. Hook-order: move `usePathname()`/`useEffect` ABOVE the early-return in
use-google-analytics. Gate the effect bodies on `GA_ID` instead so React
sees a stable hook order across renders.
3. `readUrl`/`readKey` accept either bare or `NEXT_PUBLIC_*`-prefixed env
names via a fallback chain — covers both server-only and inlined-public
variable conventions without forcing a rename across deploy targets.
4. Extract `serializeRuntimeConfig` to `lib/runtime-config-serialize.ts` so
the OWASP-escape behavior (XSS via </script>, U+2028/U+2029 line-terminator
injection) can be unit-tested without importing the layout into vitest.
5. Reclassify `intelligenceSignupUrl`/`posthogHost` from FATAL-CONFIG to
info-level in shell-docs — these are optional integrations, not hard
wiring failures, so absence should not poison the error stream.
6. Comment-rot cleanup: drop "Option B", B12, "the bug we are fixing", fix
"four substrings"→"three substrings" miscounts, and refresh shell-docs
.env.example to describe the runtime-injection contract instead of a
stale next.config throw claim.
V1: shell + shell-docs `next build` succeeds (no Edge-runtime crash on
`unstable_noStore`).
V2: `OPS_BASE_URL=` shell-dashboard `next build` no longer throws —
`next.config.ts` is now a phase-aware function that emits a sentinel
destination at build time and throws only at start (PHASE_PRODUCTION_BUILD
from next/constants).
Tests: shell-docs 72/72, shell 12/12, shell-dashboard runtime-config 16/16
(pre-existing baseline-partner-count failure unchanged).
…lesce, test hardening Non-functional cleanup pass on the showcase deploy-pipeline integration branch. All changes are scoped to comment rot, log severity for already- demoted runtime-config fields, length-aware env-name coalescing (a deliberately-empty primary no longer masks a populated alternate), and test-quality tightening. No production behavior change beyond the specific items below. Changes by area: - shell/shell-dashboard/shell-docs runtime-config.ts: factor the `process.env[primary] ?? process.env[alt]` chain into a shared length-aware `readEnvPair` helper. The prior `??` form treated `PRIMARY=""` as set, masking a populated alternate; the helper now treats empty-string as unset and falls through to the alternate. - shell-docs runtime-config.ts: demote the two recoverable URL fields (`intelligenceSignupUrl`, `posthogHost`) from console.info to console.warn. The `FATAL-CONFIG:` Sentry-alert prefix is preserved only on the true sentinels; the demoted fields now clear prod log- aggregation thresholds without raising ops alerts. - All three shells' runtime-config.ts: prefix log lines with the shell name (e.g. `[shell-docs runtime-config]`) so the shared log stream identifies which shell emitted the line. - shell-docs runtime-config-serialize.ts: rewrite the U+2028 / U+2029 RegExp arguments using six-character ASCII backslash-u escape sequences (was: literal codepoints in the string arg). The literal codepoints are line terminators that a formatter or editor could silently strip, breaking the security-critical XSS escape. The ASCII form is robust to any such pass. - shell-docs use-google-analytics.test.ts: de-tautologize the hook- order test. It now asserts `usePathname(` and `useEffect(` both exist in the source, so deleting all hooks would fail the test rather than trivially satisfying the early-return path. - shell-dashboard baseline-types.test.ts: update the partner-count expectation from 25 to 26 -- the 26th entry (Cloudflare) is a legitimate integration that landed independently; the test was stale and had nothing to do with this branch. - scripts/resolve-verify-matrix.ts: drop the `FIX 7 --` plan- internal prefix from a comment; keep the explanation. - shell-docs/.env.example: correct the `NEXT_PUBLIC_SHELL_URL` fallback claim (sentinel, not canonical prod host) and document the remaining 7 consumed env vars with their FATAL/warn/silent semantics so the example matches runtime-config.ts. Skipped: - C-SENTINEL-DEDUP (`http://ops.invalid` shared constant across shell-dashboard's next.config.ts and runtime-config.ts): both files are at different module levels (root vs src/lib) and the string appears once in each; extracting to a shared module would widen the diff into a refactor for marginal benefit. Skipped per the spec's "if it widens diff awkwardly, skip" guidance. - C-SSRTEST: already exhaustively covered. Each of the three shells has an SSR placeholder test that exercises every URL field via `new URL()` parseability and (for shell-docs) the analytics-key empty-string semantics. Treated as a no-op. Validation: shell + shell-dashboard + shell-docs runtime-config / serialize / GA tests green; bin/showcase Ruby suite green (87 runs); showcase/scripts resolve-verify-matrix + aggregate-build-results + lint-rule-no-public-env green (79 runs).
…et-scoped preflight CLI accepts optional positional SERVICE + --digest REF (the showcase_promote.yml per-service loop contract); validates against the SSOT; narrows the promotion target while fleet-scoped preflight (service-set parity, expected prod domains) keeps reading full snapshots so a healthy fleet isn't spuriously refused; adds red-green specs.
…jo runner stages runner-stage ENV NEXT_PUBLIC_COMMIT_SHA/BRANCH expanded empty because Docker ARGs are per-stage; re-declaring them in the runner stage (mirroring shell-docs) restores build-arg values at runtime. Verified via local buildx.
…rkflow shell-dashboard/shell-docs read those URLs at runtime (Option-B runtime-config); their Dockerfiles no longer declare the ARGs. Matrix aligned with showcase_build.yml; dead downstream handling removed; sha/branch retained.
…rix.ts deploy.yml moved SSOT consumption into resolve-verify-matrix.ts; the test now asserts deploy.yml invokes that script AND the script reads railway-envs.generated.json + filters probe.staging===true, rather than scanning the YAML for literals that moved one hop down.
…rity configs the integration was added to the railway-services SSOT and smoke.yml nameExcludes; this adds it to the sibling probe configs the probe-config-parity invariant requires to stay in lockstep.
…hells oxfmt --write normalized formatting on showcase scripts, the four shells, and the new oxlint rule; required for the repo-root oxfmt --check CI gate.
…fy zizmor zizmor ref-version-mismatch flagged the @a4effe49 (#v1) pin; align to the repo's existing afeafc3d / v1.310.0 ruby/setup-ruby pin used in showcase_lint_prod.yml so both workflows share one zizmor-clean version.
Addresses PR #5087 review comment from @tylerslaton: > When we open the cookbook section, the sidebar should update to include > only the recipes. Similar to how Reference works today. Mirror the dedicated-route approach Reference uses (app/reference/page.tsx + app/reference/[...slug]/page.tsx), reusing the existing MDX flow via DocsPageView's pre-built navTree prop: - app/cookbook/page.tsx — landing route. Builds a navTree scoped to the cookbook subdir (buildNavTree(CONTENT_DIR/cookbook, 'cookbook')) and passes it to DocsPageView so the sidebar shows only cookbook entries. - app/cookbook/[...slug]/page.tsx — catch-all for /cookbook/<recipe>, using the same scoped navTree. - Remove the '---Cookbook---' divider and '...cookbook' spread from showcase/shell-docs/src/content/docs/meta.json so cookbook no longer appears in the Documentation sidebar (only via the navbar tab). Verified locally: - /cookbook and /cookbook/daytona serve 200 with sidebar scoped to Overview + Daytona only (active highlight tracks the current page). - / has exactly one /cookbook anchor — the navbar tab — and no cookbook entries in the Documentation sidebar. - /built-in-agent sidebar has zero /cookbook entries. OSS-222
Addresses PR #5087 review comment from @tylerslaton: > Remove the blue padding around the chat, change the header to > 'CopilotKit x Daytona' - Drop the linear-gradient(160deg,#f8fafc,#eef2ff) background from <main>. The chat's own white card now stands on the default page background — no surrounding tint. - Change the h1 from 'CopilotKit × Daytona' (× = U+00D7 multiplication sign) to literal 'CopilotKit x Daytona' (ASCII x), per Tyler's literal request. Mirrored byte-for-byte from the Railway demo source. OSS-222
CI's check-config-allowlist failed on the new daytona-runcode showcase. Rather than just adding an .mjs row, convert to .ts to match the dominant pattern across examples/showcases/* (the .mjs predates the Next 14 TS-config support and is only kept in a handful of older showcases — banking, enterprise-brex, orca, presentation). New showcases should follow the .ts convention. - Replace examples/showcases/daytona-runcode/next.config.mjs with an equivalent next.config.ts (empty config, same behavior). - Add the new path to .github/config-allowlist.txt in alphabetical position (between chatkit-studio/.../world and deep-agents-finance-erp). - Verified locally: bash .github/scripts/check-config-allowlist.sh passes. OSS-222
## Summary - Establishes a two-stage push-to-main deploy pipeline for the showcase fleet: build GHCR images and redeploy STAGING (which floats `:latest`); PROD is digest-pinned (`@sha256:`) and promote-only via a gated workflow. - Introduces a single source of truth (SSOT) for Railway env/service IDs, image refs, per-env domains, and probe configs, consumed by Ruby tooling, TypeScript pipeline scripts, and CI workflows. - Adds a Ruby `bin/railway` promote command with per-service targeting, `--digest` pinning, and fleet-scoped preflight gates (P1 GHCR digest existence, P2 staging-latest SUCCESS, P3 staging-green live re-probe, P5 mutation correctness, P6 parity matrix). - Migrates the four Next.js shells (shell, shell-dashboard, shell-docs, shell-dojo) to runtime URL config (\"Option B\"): server-side reads of `NEXT_PUBLIC_*` at request time + `window.__SHOWCASE_CONFIG__` injection, with an oxlint rule guarding against build-time public-env reads. - Hardens the image-ref gate (per-env: prod `@sha256`, staging `:latest`), adds untracked-service hard-fail and `gateIgnore` opt-out, and rolls five additional services into the gate. - Adds verify-deploy probe drivers, per-env verify matrix resolution, per-slot build-result artifacts, and end-to-end fail-loud boundaries across the pipeline scripts. ## Key changes ### Deploy model and workflows - `showcase_build.yml`, `showcase_build_check.yml`, `showcase_deploy.yml`, `showcase_promote.yml` updated/added for the new two-stage flow. - Push-to-main redeploy retargeted from prod to staging; redeploy-summary upload is now mandatory and bridged into the build workflow artifact. - New prod promote workflow (`showcase_promote.yml`) gates on the Ruby preflight suite. ### Railway envs SSOT - `showcase/scripts/railway-envs.ts` + generated `railway-envs.generated.json` as the canonical source of env/service IDs, per-env domains, probe config, dispatch-name uniqueness invariant, and `gateIgnore` per service. - CI `--check` mode verifies the generated artifact is in sync with the TS source. - Ruby `bin/railway` reads `EXPECTED_DOMAINS` from the TS SSOT artifact. - Snapshot schema v2 adds `healthcheck`/`region`/`replicas`/`restartPolicy` for the parity matrix. ### TS pipeline scripts (`showcase/scripts/`) - `redeploy-env.ts` for explicit per-env Railway redeploys with per-service JSON summary emission. - `resolve-verify-matrix.ts` for SSOT-driven verify matrix resolution (skips verify when redeploy success-set is empty; pinned by a contract test). - `verify-deploy.ts` parameterized per-env probe + baseline driver implementations. - `verify-railway-image-refs.ts` per-env gate (prod `@sha256`, staging `:latest`), untracked-service hard-fail, malformed-ref negatives, per-service shape tests. - `aggregate-build-results.ts` per-slot build-result artifacts, fail-loud on missing slot file, GHA heredoc output. - `emit-railway-envs-json.ts` SSOT artifact emitter with hermetic, fail-loud read errors. - Shared `scripts/lib/`: unified Railway GraphQL endpoint (backboard.railway.app), shared token resolver preferring `user.accessToken`, whitespace/type-safe narrowing, sanitized GraphQL error bodies. ### Ruby promote (`showcase/bin/railway` + `lib/`) - `PromoteCommand` refactored for testable preflight; single-service targeting via `--digest`. - `Railway::Auth.ghcr_token` + `GHCR.manifest_exists` (P1 GHCR digest gate). - P2 staging-latest-deployment SUCCESS check. - P3 require-staging-green live re-probe via `verify-deploy --env staging`. - P5 mutation-correctness verification (boolean + re-query retry). - P6 parity matrix (healthcheck/region/replicas/restartPolicy). - Promote resolves staging tag to GHCR digest once, pins prod, verifies redeploy, fails loud on partial promote. ### Runtime URL config across Next shells (\"Option B\") - `shell`, `shell-dashboard`, `shell-docs`, `shell-dojo`: new `runtime-config.ts` (server) + `runtime-config.client.ts` (client) modules; `__SHOWCASE_CONFIG__` injected via root layout; middleware and URL consumers migrated. - Dropped build-time `NEXT_PUBLIC_*` build-args from CI and Dockerfiles; re-declared `COMMIT_SHA`/`BRANCH` ARG in runner stages where needed. - `shell-docs` sitemap/robots made dynamic; analytics + middleware routed through runtime config; `signup-link` and CTA components migrated with SSR tests. - New oxlint rule rejects `NEXT_PUBLIC_*` reads from shell source. - Playwright env-routing spec per shell per env; no-rebuild env-switch integration test. ### Test hardening - vitest coverage for runtime-config server/client, SSR safety, env-name tolerance. - Contract tests pin verify-matrix SSOT shape and CLI behavior. - Per-service image-ref gate shape tests; malformed-ref negatives. ## Test plan - [ ] CI: \`build-checks\` green on this branch - [ ] CI: \`validate-showcase\` green (SSOT \`--check\` passes) - [ ] CI: Python tests green - [ ] CI: oxlint passes (no NEXT_PUBLIC_* reads in shells) - [ ] Local: \`bundle exec rspec\` (Ruby promote suite) green - [ ] Local: \`pnpm -C showcase/scripts test\` (vitest) green - [ ] Local: \`pnpm -C showcase/shell test\` and sibling shells green (runtime-config + SSR) - [ ] Local: \`docker buildx build\` succeeds for each shell with the trimmed build-args - [ ] Local: Playwright env-routing spec passes against a running shell - [ ] Manual: dry-run \`bin/railway promote --digest <sha256>\` against a staging service; P1–P6 gates report as expected
main's static/quality format gate was red because this file was not ruff-formatted (introduced by an earlier unrelated python commit). Apply ruff 0.15.13 format to restore the gate.
The cookbook's 'Try it live' iframe is 600px tall, but the demo page
included its own h1/subtitle + ~32px main padding + the chat section had
minHeight:520, which pushed total content past 600px and forced a
scrollbar inside the iframe.
The shell-docs cookbook page already provides a header and surrounding
chrome; the demo's own h1 ('CopilotKit x Daytona') and subtitle are
redundant in the embedded context. Drop them and let the chat fill the
iframe viewport exactly:
- Remove the <header> (h1 + subtitle).
- Set <main> to height:100vh, padding:0, margin:0.
- Chat <section> uses flex:1 + minHeight:0 (no fixed minHeight) so it
grows/shrinks to fill the available iframe height.
Side effect: the standalone Railway URL now also shows just the chat
(no h1/subtitle). Fine — the URL is a demo embedding target rather
than a polished standalone landing.
OSS-222
Fixes the red `static / quality` format gate on main caused by an unformatted Python test file (pre-existing, unrelated to the showcase pipeline work). Applied ruff 0.15.13 format to `sdk-python/tests/test_agui_agent.py` only.
## Summary - update the LangGraph Python Threads template CopilotKit packages from 1.57.0 to 1.59.1 - align @ag-ui/client to 0.0.53 so @ag-ui/langgraph and @copilotkit/runtime share the same agent base types - regenerate the standalone template package-lock.json ## Verification - npm run build (from examples/integrations/langgraph-python-threads) - lefthook pre-commit: check-binaries, sync-lockfile, test-and-check-packages
…5087) ## Summary - New top-level **Cookbook** docs section with a small landing page, added both as a top-level nav tab (next to Learn) and as a sidebar section under Documentation. First recipe wires CopilotKit's Built-in Agent up with a `runCode` server tool that executes Python, TypeScript, or JavaScript in an isolated [Daytona](https://www.daytona.io) sandbox and returns stdout to chat. - New **`copilotkit-daytona` Agent Skill** (`skills/copilotkit-daytona/`) — `SKILL.md` + `assets/` + `references/` + `eval.yaml` + a workspace fixture, mirroring `skills/copilotkit-setup`. The skill's reference doc deliberately points at Daytona's maintained sources (`llms.txt`, the dashboard limits page, the official `daytona` Agent Skill, and the Daytona MCP server) rather than duplicating a hand-copied SDK surface that would rot. - Fixes a stale `learn/meta.json` link that pointed at `../direct-to-llm/cookbook/state-machine` (target no longer exists). Closes OSS-222. ## Test plan - [x] `next build` compiles `/cookbook` and `/cookbook/daytona` as static routes; OG images emit for both. - [x] Broken-link checker shows no new broken links relative to `main`. - [x] Cookbook appears as a top-level nav tab next to Learn, and as a section in the Documentation sidebar. - [x] Recipe code validated end-to-end on a deployed Railway app against published `@copilotkit/runtime@1.58.0`: agent invokes `runCode`, a real Daytona sandbox executes both Python and JavaScript snippets, output round-trips through the chat (unique-token proof). ## Notes (out of scope, separate follow-ups) - The Built-in Agent **quickstart** doc shows a v1 `<CopilotKit>` provider mixed with v2 `<CopilotSidebar>`; the v2 demos use the all-v2 stack (`CopilotKitProvider` + `useSingleEndpoint` + `createCopilotEndpointSingleRoute`). Worth a doc reconciliation in a separate PR. - The Vercel AI SDK emits *"System messages in the prompt or messages fields…"* when the agent runs — it originates inside `BuiltInAgent`'s call construction (passes system content via `messages` rather than the SDK's `system` option). Benign, but a CopilotKit runtime improvement worth filing separately. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
…up skill (#5089) ## Summary - `@copilotkit/react` and `@copilotkit/agent` do not exist on npm — every user following the setup skill fails on Step 1 with a 404 - Replaces them with the correct published packages: `@copilotkit/react-core` and `@copilotkit/runtime` - Updates all import paths throughout the skill to use the v2 subpath exports (`@copilotkit/react-core/v2`, `@copilotkit/runtime/v2`) - Removes references to the non-existent `@copilotkit/core` and `@copilotkit/agent` packages from the Package map table ## Changes - Step 1 install commands now use real package names that resolve on npm - All code examples import `BuiltInAgent`, `CopilotRuntime`, `InMemoryAgentRunner`, endpoint factories from `@copilotkit/runtime/v2` - All frontend code examples import `CopilotKitProvider`, `CopilotChat`, `CopilotSidebar`, styles from `@copilotkit/react-core/v2` - Package map table updated to reflect the two real installable packages ## Test plan - [x] `npm install @copilotkit/react-core @copilotkit/runtime hono` — installs without 404 - [x] All import paths in examples resolve to real published subpath exports
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )