145 Commits

Author SHA1 Message Date
Benjamin Taylor 4c2ba2d161 feat(skills): add channels-setup pointing at the hosted onboarding guide
The Channels onboarding workflow is served at
https://copilotkit.ai/channels-guide.md, and every other entry point now
copies one line that points there (#6357 for the docs surfaces). Coding
agents invoked through a skill had no such pointer, so they fell back to
setup-slack-channel, which is scoped to Slack, to the provider half, and to
an OpenTag checkout.

channels-setup is a pointer, not a copy. The workflow stays in one place and
is corrected there instead of drifting against the CLI on its own schedule.

Verifying the fetch is the substance of the file. The site answers unknown
paths with a "Page not found" HTML page under HTTP 200, so a status check
proves nothing: an agent that keys on the status code gets a marketing 404
and improvises the workflow from memory. The skill checks the body instead
-- markdown, the guide's H1, five Phase headings -- and stops if any fail.

Standalone skills are not generated from packages/*/skills, so the slug is
registered in RESERVED_LIFECYCLE_SLUGS. Without that entry the sync treats
the directory as an orphan and deletes it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 10:30:02 -05:00
GeneralJerel d51fe15c71 Merge branch 'main' into feat/channel-setup-skills
Resolves the one conflict in skills/copilotkit-channels/SKILL.md, where main
(#6320) rewrote the same frontmatter description this branch narrowed.

The two sides disagreed on Teams. This branch scoped the skill to the code half
and said it "assumes the provider app already exists"; main established that
Teams provider setup *is* this skill's job, because the CLI or dashboard wizard
performs it. Kept the branch's code-half framing and the handoff to
setup-slack-channel, but scoped that handoff to first-time Slack app creation
only, so it no longer contradicts main's Teams sections or the Slack provider
troubleshooting that stays in this file. Took main's version 1.1.0.

Also registers setup-slack-channel in RESERVED_LIFECYCLE_SLUGS. Standalone
skills have no packages/*/skills source, so without an entry the sync script
treats the directory as an orphan: `pnpm check:plugin-skills` fails, and
`pnpm sync:plugin-skills` deletes all 8 files of the new skill. Verified both
behaviours against the pre-fix script before fixing. The paired size assertion
in the unit test moves 9 -> 10.
2026-08-03 11:17:09 -07:00
Mike Ryan b88f9b7e4f feat(channels): complete native JSX contracts 2026-08-03 09:23:15 -07:00
Benjamin Taylor 065d525340 feat(skills): make managed Intelligence the default setup path, add a Channels skill
The most-used "add CopilotKit to your project" path walked every new user into the
self-hosted SSE runtime and never offered the managed one.
`CopilotIntelligenceRuntime`, `CopilotKitIntelligence`, the required
`identifyUser`, and the hosted environment values all appeared in this skill's
reference files but were wired by no step, so the skill could describe managed
Intelligence without ever producing it.

Step 2 now chooses the runtime mode before any runtime code is written, because
the mode changes how the runtime is constructed and retrofitting it means
rewriting the file. Managed Intelligence is the recommended default and now has
real wiring. Self-hosted SSE stays fully documented as a deliberate opt-out with
its prerequisites and its tradeoff stated plainly at the point of choice -- the
open-source packages are published and MIT-licensed, so obscuring the alternative
would not prevent its use and would cost credibility on everything around it.

Step 6 becomes the actual Intelligence step rather than a telemetry aside. It
separates the two credentials that setup mistakes usually conflate: the
server-side project API key, which is a secret and must never take a
NEXT_PUBLIC_/VITE_ prefix, and the public license key, which is a project
identifier meant to reach the client.

It also fixes a command that does not exist. Both this skill and
references/telemetry-setup.md instructed `npx copilotkit auth`; the command is
`login`, and `project select` is what provisions the project.

The new copilotkit-channels skill covers the code half of a managed Channel: the
declaration, the long-running host requirement, and the awaited
`listener.channels.ready()` call. Activation is lazy on every host, so a runtime
that omits that call serves HTTP, reports no error, shows an encouraging badge in
the dashboard, and answers nothing -- the failure the skill exists to prevent. It
states the managed-versus-self-hosted boundary up front, since both product
families use the words "channels" and "Slack".

A standalone skill must be registered in RESERVED_LIFECYCLE_SLUGS. Without an
entry the sync script treats it as an orphan and deletes it, so the test now pins
that requirement with the reason.
2026-08-01 14:47:36 -05:00
Tyler Slaton 289a39d00c fix(release): simplify canary dependency pins 2026-07-29 22:13:45 -04:00
Tyler Slaton ac42ca5f4c fix(release): exact-pin canary dependency sets 2026-07-29 22:05:17 -04:00
Mike Ryan 702874096e feat(channels): route delivery through live sessions (#6236)
## What changes

This replaces the managed Channels adapter and transport stack with live
sessions over Realtime Gateway.

- Channels use the standard AgentRunner and canonical AG-UI history for
each turn.
- One admitted delivery runs one prompt; multiple agent calls run in
order; concurrent calls fail with a bounded protocol error.
- Slack and Teams reuse their native renderers to emit destination-free
provider effects.
- Files, rich controls, interaction handlers, and provider cursors cross
the live-session protocol with bounded payloads.
- The old claim mapping, HTTP fallback, render batches, listener
election, in-memory transport, and legacy adapter code are removed.
- The public `@copilotkit/channels` umbrella remains limited to public
provider adapters; the managed launcher stays in
`@copilotkit/channels-intelligence`.

Companion service PR and kind proof:
https://github.com/CopilotKit/Intelligence/pull/638

## Why

Managed delivery must use the same AgentRunner path as other
Intelligence runs. SDK code emits provider-neutral effects; the trusted
Gateway owns credentials, destinations, admission, retries, and terminal
outcomes.

## Validation

- `pnpm nx run-many -t build,check-types,test -p
@copilotkit/channels-core,@copilotkit/channels-intelligence,@copilotkit/channels-slack,@copilotkit/channels-teams,@copilotkit/channels,@copilotkit/runtime`
— 31 tasks passed
- `pnpm nx test @copilotkit/channels-teams` — 89 passed
- `pnpm vitest run scripts/release/lib/channels-umbrella.test.ts` — 8
passed
- `pnpm verify:channels-umbrella` — packed snapshot, dependency
resolution, and TSX consumer passed
- affected package pre-commit tests, publint, and API type checks passed
- changed-file Prettier and `git diff --check` passed

## Known unrelated check

`pnpm nx build demo` now compiles past the prior Channels telemetry
dependency leak, then fails on the existing AG-UI 0.0.51 versus 0.0.57
private `_debug` type mismatch.
2026-07-29 18:28:49 -07:00
Benjamin Taylor 2a1a141389 perf(release): publish canary packages with bounded concurrency
After the npx fix each publish is ~4.7s and almost entirely a registry
round-trip, so a 26-package scope=all canary still spent ~125s waiting
serially. Publish 4 at a time (CANARY_PUBLISH_CONCURRENCY=1 restores
serial for debugging).

This weakens no ordering invariant. prerelease.ts's own header already
documents that the cross-scope graph has cycles (runtime ->
channels-intelligence, channels-core -> core), so no serial order avoided
publishing a package before the same-run version it pins.

Per-package output is captured and replayed as one block rather than
inherited, since a pool would otherwise interleave several npm publishes
line-by-line — and that log is the only forensic record when a canary
half-publishes. Every package is attempted even if others fail, so one
report names all of them; main() now exits non-zero on failure rather
than letting an unhandled rejection pass the step.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 19:53:05 -05:00
Benjamin Taylor 6a35e3cdbf perf(release): cut canary publish wall-clock roughly in half
The canary flow took ~11.5 min steady-state (and 20 min in an observed
run). Measured from run 30473499191, the time went to five avoidable
places rather than to real work.

1. `npx --yes npm@11.15.0 publish` ran per package, and npx re-resolves
   the spec against the registry on EVERY invocation: ~16s of each
   package's ~21s. A 9-package channels canary paid ~2.4 min of pure npx
   overhead; a 16-package monorepo release paid over 4 min. Hoist the
   pinned npm into lib/npm-cli.ts, install it once into a throwaway
   prefix, and reuse the binary.

2. publish-release.yml was the only workflow in the repo with no pnpm
   store cache, so all three jobs installed 4608 packages cold every
   time. Usually ~45s each, but registry-bandwidth bound and heavy
   tailed: the observed run spent 9m08s here on tarballs arriving at
   2-49 KiB/s. Add the same node-version-keyed cache the rest of CI uses.

3. The notify job ran for canaries only to compute "post nothing" — the
   builder already returns should_post=false for mode=prerelease and the
   self-watchdog is already gated off. ~85s of dead work on the critical
   path, since canary.yml waits for the whole run. Skip the job, keeping
   it reachable for a python_publish dispatch.

4. The build job fetched full history for canaries, which need none (no
   tag, no GH Release, no release-note commit range, and `nx run-many`
   resolves no merge base). That rode along in the 837 MiB workspace
   artifact too. Shallow-fetch prereleases; stable keeps depth 0 because
   its publish job pushes tags out of that artifact's .git.

5. Two smaller ones: the artifact was gzipped and then re-deflated into
   the artifact zip (compression-level: 0), and the orchestrator's
   run-discovery loop slept 6s before its first poll.

Verified: 143 release-script tests pass (6 new for the npm-cli helper),
actionlint + shellcheck + the scope-dropdown guard are clean, the
prerelease dry-run path still enumerates all 9 channels packages, and a
live probe confirms the helper installs npm 11.15.0 once (3.2s) and
memoizes thereafter (0ms).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-29 19:29:38 -05:00
Mike Ryan 6a222953a9 fix(channels): align umbrella with managed launcher 2026-07-29 16:42:02 -07:00
github-actions[bot] 5588636bd8 style: auto-fix formatting 2026-07-28 22:04:13 +00:00
copilotkit-qa-bot a0cfc60c1b Address FAC-49 review feedback 2026-07-28 14:40:24 -07:00
Benjamin Taylor 4a9837e176 fix(release): pack runtime workspace deps locally in verify-runtime-package
`verify:runtime-package` could not pass on a channels release PR. `pnpm pack`
rewrites the runtime's `workspace:` ranges to the workspace's current version,
so on a release PR the temp consumer tried to resolve the freshly-bumped
`@copilotkit/channels-intelligence` from npm — the version this very PR is
about to publish. It failed `unit (20.x)` by construction on #6185 and #6025.

Apply the fix `verify-channels-umbrella` already uses: pack the whole
first-party `workspace:` closure locally and pin it through pnpm `overrides`.
The packing helpers move to `lib/pack-workspace.ts` so both scripts share one
implementation instead of duplicating it.

The contract is unchanged: the packed runtime must still declare
channels-intelligence as a real dependency, and it must still load through
both ESM and CJS.
2026-07-27 11:10:32 -05:00
Benjamin Taylor 710b5ad783 fix(release): report literal cross-scope pins, which scope=all cannot fix
Adversarial pass on the previous commit. The warning only inspected
`workspace:` ranges, so it missed the OTHER way a cross-scope pin goes stale: a
literal version range naming a package in another scope. `bumpPackages` rewrites
literal ranges for in-scope packages only, so such a pin survives every bump —
`scope=all` publishes the canary and the artifact still resolves the dependency's
last stable release, silently, which is the exact failure this warning exists to
surface.

`findCrossScopeWorkspaceDeps` becomes `findCrossScopePins`, reporting both shapes
tagged with a `reason`, and the literal case carries its own remedy (convert to
`workspace:`) instead of the useless "re-run with scope=all".

No such pin exists in the tree today — every cross-scope edge is `workspace:` —
so this closes a latent hole rather than a live one, in the one place a future
refactor would reintroduce it.

Also documents the multi-scope partial-failure mode in prerelease.ts: the
cross-scope graph has cycles, so no publish order avoids a package shipping
before the same-run version it pins, and npm's no-republish rule means a failed
run must be retried under a new suffix.
2026-07-24 16:08:15 -05:00
Benjamin Taylor bee19e78df fix(release): make canary publishes reachable and cross-scope composable
Two release-tooling defects turned a pair of canary publishes into a broken
combination for consumers (a canary runtime resolving the last STABLE
channels-intelligence, which still called the removed `channel.addAdapter`).

1. Canary versions were prereleases of an ALREADY-PUBLISHED version. A stable
   release leaves the working tree on the version it just published, and
   computePrereleaseVersion appended `-canary.<id>` to exactly that, so the
   canary sorted BELOW its own release (`0.2.1-canary.x < 0.2.1`): the `canary`
   dist-tag pointed behind `latest`, and no dependent range could ever resolve
   it. Base the canary on the next unreleased version instead (patch bump,
   reusing computeNextStableVersion's prerelease rule).

2. A canary published one scope at a time, but the scopes are only independent
   on the version axis. `@copilotkit/runtime` carries
   `"@copilotkit/channels-intelligence": "workspace:*"`, and `pnpm pack`
   resolves that against the working tree — so a `monorepo` canary pinned the
   channels family to its last stable release even when the commit changed both
   sides of the contract. Add a prerelease-only `all` selector that bumps and
   publishes every scope from one commit under one shared canary id, and warn
   loudly when a single-scope canary leaves a cross-scope pin behind.

`all` is a selector, never a scope: stable releases stay single-scope (their
tag, release branch, and npm/Slack links all derive from one scope name), which
publish-release.yml enforces in both jobs and the dropdown guard enforces per
workflow.
2026-07-24 15:53:13 -05:00
Mike Ryan cd0b5b4061 fix(angular): address SDK review findings 2026-07-23 07:48:25 -07:00
Mike Ryan fec70d086f feat(angular): checkpoint 2 - core and package 2026-07-23 07:14:55 -07:00
Benjamin Taylor d221c03f02 fix(release): make packed Channels umbrella verify hermetic
The local `verify:channels-umbrella` check packs the Channels family and
installs a throwaway consumer, overriding only the family tarballs. The
family depends on monorepo-versioned packages (`@copilotkit/core`,
`@copilotkit/shared`) via the `workspace:` protocol, which `pnpm pack`
rewrites to the workspace's current version. On a release PR that version
is the freshly-bumped one that isn't on the registry until the release
publishes, so the consumer install fell through to npm and failed with
ERR_PNPM_NO_MATCHING_VERSION — the unit(20.x) red that blocked every
monorepo release PR (e.g. #5992, #6019) on its own not-yet-published
version.

Pack those workspace siblings locally too and pin them as consumer
overrides, so local mode never races the registry against our own
in-flight release. Siblings are discovered transitively via the
`workspace:` protocol so the list never drifts as the family's internal
dependencies change.

Verified by bumping shared+core to an unpublished version: the old script
fails with ERR_PNPM_NO_MATCHING_VERSION, the fixed script reports OK.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 13:58:02 -05:00
Benjamin Taylor 1110f18e30 fix(release): exempt first-party publishes from the release-age gate
The packed Channels umbrella (and the runtime-package verify) install
first-party packages straight from the registry, so a just-published
@copilotkit/* version fails pnpm's 24h minimumReleaseAge check — this is
what reddened `unit (20.x)` on channels PRs. The enumerated exclude lists
drift every time an internal dependency is added (main already had to bolt
on @copilotkit/channels-core, then #6012 added @copilotkit/core + shared).

Wildcard the @copilotkit/* scope (org-owned, same publish pipeline — no
outsider can inject a package, and it stops the drift). Keep @ag-ui
enumerated rather than wildcarded: it's a separate upstream org, so we don't
extend immediate-install trust to its entire scope. Third-party deps stay
fully gated. Applied to both the generated consumer workspace and the
repo-root .npmrc.

Verified: `pnpm run verify:channels-umbrella` installs the packed umbrella
with no ERR_PNPM_NO_MATURE_MATCHING_VERSION; umbrella unit tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 13:10:58 -05:00
Martha Schumann 9e9ce128dd test(runtime): verify packed managed channels dependency 2026-07-16 10:44:10 -07:00
Martha Schumann e84eceffbf fix(release): exempt Channels transitive packages from age gate 2026-07-16 10:35:14 -07:00
Tyler Slaton a5387831c0 fix(release): exempt Channels verifier from maturity gate 2026-07-15 14:11:44 -07:00
Tyler Slaton 5811cab177 fix(channels): align rebase with channel API 2026-07-15 10:29:21 -07:00
Tyler Slaton eed52e13c7 refactor(release): preserve configured publish order 2026-07-15 10:13:19 -07:00
Tyler Slaton 3b22abbbd1 fix(release): stage channels publishing 2026-07-15 10:13:18 -07:00
Tyler Slaton 17213998a1 chore(release): unify channels version scope 2026-07-15 10:13:18 -07:00
Tyler Slaton fad2aed6c2 test(channels): verify packed umbrella consumers 2026-07-15 10:13:17 -07:00
Tyler Slaton 163d0e99b8 chore(release): add channels core and umbrella scopes 2026-07-15 10:12:23 -07:00
Benjamin Taylor b394f06fdc refactor(channels): rename @copilotkit/bot* packages to @copilotkit/channels* (OSS-438)
Renames the Bots SDK to the Channels SDK. Names only — no behavior change.

- 8 packages @copilotkit/bot* -> @copilotkit/channels* (git mv dirs, names,
  workspace: cross-deps). Now includes @copilotkit/bot-intelligence ->
  @copilotkit/channels-intelligence (landed on main via #5761; unpublished, so
  renamed fresh with the family).
- release.config.json scope keys + versionSource; ReleaseScope union;
  canary/stable-release/publish-release scope dropdowns; verify script
- examples/slack (Kite) + examples/teams: deps, jsxImportSource, imports
- showcase/shell-docs: content dirs docs/bots->docs/channels and
  reference/bot->reference/channels, nav registry, redirects

createBot and other API names unchanged. Old @copilotkit/bot* to be deprecated
after the new packages publish (bot-intelligence was never published).

Re-derived onto latest main (was conflicting after #5761 landed).

Refs OSS-438
2026-07-08 13:27:35 -05:00
Benjamin Taylor 71a4ac42e4 Merge origin/main into alem/oss-360-sdk-foundations
Brings the 499-commit-stale foundations branch up to date with main so #5761
has a clean diff and no stale reverts (e.g. forwardHeaders). Conflicts:
- CopilotThreadsDrawer.tsx: took main's (main renamed CopilotDrawer -> ThreadsDrawer
  + added the collapse feature; the branch's edit was a no-op import-type split).
- pnpm-lock.yaml: regenerated with the pinned pnpm 10.33.4 (adds @copilotkit/bot-intelligence).
2026-07-08 11:01:58 -05:00
Tyler Slaton 7527ee64d0 fix(release): fold web-components into monorepo scope 2026-07-01 09:54:51 -07:00
Tyler Slaton 3e8e409f1f chore(release): add web-components release scope 2026-07-01 09:43:04 -07:00
Alem Tuzlak 972dd64476 refactor(bot): split the Intelligence managed adapter into @copilotkit/bot-intelligence
Move the Intelligence-delivered managed-bot surface out of @copilotkit/bot into
its own package so the adapter, transports, contracts, and lifecycle ship
independently of bot core.

- New @copilotkit/bot-intelligence: intelligenceAdapter + DeliverySource/EgressSink
  (+ in-memory impls) + placeholder contracts + startManagedBots/validation/
  activation metadata. Production code imports only types from @copilotkit/bot
  and @copilotkit/bot-ui.
- @copilotkit/bot keeps the generic PlatformCodec seam (moved to src/codec.ts) and
  all core createBot changes (addAdapter, deferred store, id fields,
  __managed/skipIngressDedup, exclusive guard). It now also exports the
  FakeAdapter/FakeAgent test utilities for downstream adapter-package tests.
- Registered the new release scope: release.config.json, scripts/release/lib/
  config.ts, and the canary/publish/stable release workflows.

Tests preserved: bot 150 + bot-intelligence 19 (= the prior 169); bot-slack 261.
Builds typecheck across bot/bot-intelligence/bot-slack/runtime; publint/attw/
oxlint/oxfmt clean.
2026-06-29 14:30:28 +02:00
Alem Tuzlak e0307facc8 refactor(bot): drop bot-store-redis/postgres adapters (never published)
The StateStore interface and the in-memory MemoryStore default remain;
durable backends can be reintroduced as a follow-up. Both adapter packages
were merged in #5613 but never published to npm, so removal is a clean
delete with no consumer impact.

- Delete packages/bot-store-redis and packages/bot-store-postgres.
- Revert the bot release scope and drift guard to bot + bot-ui.
- Strip the Redis dep, demo:restart script, restart demo, docker-compose,
  and REDIS_URL env from examples/slack.
- Rewrite the bot persistence/transcripts docs around "MemoryStore default
  + implement the StateStore interface yourself for durability".
2026-06-26 14:40:10 -07:00
Tyler Slaton a1b1792ef0 Add bot-teams to release scopes 2026-06-25 15:30:05 -07:00
Alem Tuzlak 5ecdee36b8 feat(bot): pluggable StateStore persistence + cross-platform transcripts
Adds a durable persistence layer for @copilotkit/bot, replacing the
in-memory-only ActionStore with a pluggable StateStore.

- StateStore interface (kv/list/lock/dedup/queue) with a shared
  conformance suite; MemoryStore default plus @copilotkit/bot-store-redis
  and @copilotkit/bot-store-postgres backends.
- createBot({ store }): typed per-thread state via Standard Schema,
  action snapshots persisted through the store, per-conversation turn
  lock (onLockConflict drop|force), and inbound-event dedup keyed on a
  stable eventId. ActionStore is kept as a deprecated alias.
- Cross-platform transcripts (bot.transcripts + identity resolver) with
  age-bounded retention (prune on append + filter on read), and
  runAgent({ transcript: true }) to auto-inject history and capture the
  reply.
- createBot({ components }) re-registers components so durable actions
  re-fire after a restart; restart-durability demo in examples/slack.
- Dedup is marked seen only after the turn lock is acquired, so a turn
  dropped on lock-conflict does not burn its eventId (no lost retries).
- Release lockstep: bot-store-redis/postgres version with bot + bot-ui.
2026-06-23 18:33:38 +02:00
Sam Julien 75e397049b test(doc-tests): fix langgraph quickstart doctest 2026-06-19 13:11:05 -07:00
Sam Julien 3ae761a966 chore(docs): remove retired docs app (#5548)
## Summary
- remove the retired top-level `docs/` Next app and the disabled
docs-sync workflow/script
- add `docs -> showcase/shell-docs` as a top-level symlink for `cd docs`
muscle memory without restoring the old docs tree
- move the docs model allowlist into `showcase/shell-docs/` and retarget
docs validation/doctest extraction to shell-docs content
- update docs/agent guidance and CI path filters so `docs/` is treated
as an alias, not an active separate docs surface
- tighten the pre-commit package check so non-package docs/tooling
changes do not fan out into the full package matrix

## Validation
- `pnpm exec tsx scripts/validate-doc-model-names.ts`
- `pnpm exec tsx scripts/doc-tests/extract.ts`
- `pnpm exec vitest run
scripts/__tests__/validate-doc-model-names.test.ts
scripts/doc-tests/__tests__/extract.test.ts
showcase/harness/src/cli/eval/scope.test.ts`
- `pnpm exec oxlint showcase/harness/src/cli/eval/scope.test.ts
scripts/doc-tests/extract.ts`
- `git diff --cached --check` before follow-up commit
- `test "$(readlink docs)" = "showcase/shell-docs"`
- `test -f docs/package.json`
- `pnpm exec oxfmt --check .claude/docs/documentation.md
.claude/docs/hooks.md AGENTS.md CLAUDE.md CONTRIBUTING.md
showcase/shell-docs/README.md`
- commit hooks passed

## Notes
- historical docs remain recoverable from
`archive/docs-save-do-not-prune` and `archive/docs-retired-2026-06-17`
- I intentionally left Vercel/project teardown out of this PR; this is
repo cleanup only
2026-06-19 07:33:51 -07:00
Alem Tuzlak 7fe12d6d3c Merge remote-tracking branch 'origin/main' into feat/bot-telegram-adapter
# Conflicts:
#	examples/slack/README.md
#	examples/slack/package.json
#	pnpm-lock.yaml
2026-06-19 11:04:18 +02:00
Mike Ryan 64999fb9a9 chore: prepare angular package release 2026-06-18 13:49:35 -07:00
Sam Julien 33a79485b6 chore(docs): remove retired docs app 2026-06-18 10:54:16 -07:00
Alem Tuzlak 02be193fcc ci(release): make @copilotkit/bot-discord a releasable scope 2026-06-18 19:28:25 +02:00
Austin Merrick 2829daff03 fix(plugin): sync marketplace metadata.version and re-pin to runtime 1.60.2
The plugin version pins to packages/runtime/package.json, but plugin.json
(1.60.0) and marketplace.json (plugins[0] 1.60.0, metadata 1.57.3) had
rotted behind the runtime package (1.60.2), so check:plugin-skills was
failing on main.

handleVersionSync previously managed only plugin.json.version and
marketplace plugins[0].version, leaving marketplace metadata.version
unmanaged and free to drift independently. Extend it to track
metadata.version against the runtime version too, and re-run the sync to
bring all three fields to 1.60.2.
2026-06-18 09:23:03 -07:00
Alem Tuzlak 80e95f26d4 ci(release): make @copilotkit/bot-telegram a releasable scope 2026-06-18 15:50:23 +02:00
Maxim f0f8a7a16d ci(release): add release-scope dropdown drift guard
Compares the workflow_dispatch scope choice dropdowns in
publish-release.yml, stable-release.yml, and canary.yml against the
authoritative .scopes keys in release.config.json, failing CI on drift.
Also validates that every explicitly-named arm in publish-release.yml's
notify-job npm-url case statement is a valid scope (catch-all makes
full coverage unnecessary). Parsers fail loud and distinct on shape
changes (anchored case detection, loose-vs-strict cross-check,
zero-options and zero-block guards) rather than silently passing.

Ported from ag-ui-protocol/ag-ui (PR #1914 wiring); config lives at
the repo root in CopilotKit.
2026-06-11 01:28:35 +02:00
Maxim adaeda2dc6 fix(release): enforce GHA-safe output keys and tighten publish guards
Round-2 review fixes for the GITHUB_OUTPUT helper and the release scripts
that emit through it.

emitGithubOutputs (scripts/release/lib/github-output.ts):
- Replace the key newline/CR check with a full GitHub-Actions-safe charset
  check: /^[A-Za-z_][A-Za-z0-9_-]*$/. A key containing "=" or whitespace
  would silently corrupt the key=value line; rejecting up-front is
  strictly safer. Value validation (single-line) is unchanged — "=" in
  values is legal because GitHub splits on the first "=".
- Update the docblock accordingly.

prerelease.ts:
- Remove the dead `?? getCurrentVersion(scope)` fallback. The empty-list
  guard above makes packages[0] guaranteed, and the fallback would have
  masked a package.json missing its version field by emitting a version
  divergent from what the loop publishes. Fail loudly with an explicit
  exit instead.
- Drop the now-unused getCurrentVersion import.
- Add a comment above the dry-run emitGithubOutputs call explaining that
  emitting in dry-run is safe — the publish workflow gates publish + the
  verify guard on inputs.dry-run != true, so the dry-run emission only
  serves local/e2e contract verification.

publish-release.ts:
- Hoist getPackagesForScope + empty-list guard above the prerelease-suffix
  and registry checks. A misconfigured scope now fails with the clear
  "no packages found" error instead of a misleading "not greater than
  published" one. Loop is unchanged.

github-output.test.ts:
- Loosen the key-newline assertion from the JSON.stringify-coupled
  /bad\\nkey/ to the stable /alphanumeric/ phrase from the new message.
- Add tests: "=" in key throws, space in key throws, empty key throws,
  and "=" in value is accepted and written verbatim (note=a=b).
- Move vi.restoreAllMocks() to the top of afterEach so spies cannot leak
  into env restore + rmSync cleanup.

Call sites audited:
- emitGithubOutputs: only ever called with {version, scope} (prerelease,
  publish-release) — all valid under the new charset.
- publishVersion derivation: only used inside prerelease.ts main().
- getCurrentVersion: still imported by publish-release.ts, bump-prerelease.ts,
  prepare-release.ts; only the prerelease.ts import was removed.
- getPackagesForScope hoist in publish-release.ts: `packages` was only
  read inside the publish loop below; nothing earlier depended on it.
2026-06-10 22:58:03 +02:00
Maxim e8fa74ce45 fix(release): validate GITHUB_OUTPUT values and fail loudly on empty package lists
Hardens the new GITHUB_OUTPUT emission path so a malformed value can't smuggle
extra `key=value` lines into the workflow's step outputs, and so the workflow's
"Verify publish step emitted version" guard can't be fooled by a publish that
did nothing.

emitGithubOutputs now validates every key/value for `\n`/`\r` BEFORE the
GITHUB_OUTPUT early-return — a malformed value is a caller bug and should fail
loudly even when running locally. A multi-line value would need the heredoc
form, which this helper deliberately does not support.

prerelease.ts and publish-release.ts now fail loud when getPackagesForScope
returns an empty list. Without this, the new GITHUB_OUTPUT emission would make
the workflow's "Verify publish step emitted version" guard pass on a run that
published nothing — previously the missing output made such a run fail. The
guard runs BEFORE the dry-run branch in prerelease.ts. In publish-release.ts,
the inline iteration of getPackagesForScope(scope) is hoisted to a `packages`
const so the same guard fires before the publish loop.

The "no-op when GITHUB_OUTPUT is unset" test now spies on fs.appendFileSync
and asserts it wasn't called (the previous read of the unrelated temp file
was vacuously true). New tests cover newline/CR in value and newline in key.

The prerelease.ts usage string previously advertised `[--suffix <label>]`,
but the script never parses --suffix (suffix handling lives in
bump-prerelease.ts per the header comment). Removed.

Call sites enumerated:
- emitGithubOutputs: prerelease.ts (dry-run + post-publish), publish-release.ts
- getPackagesForScope: prerelease.ts, publish-release.ts (this commit);
  bump-prerelease.ts, prepare-release.ts, versions.ts (not changed — out of
  scope for this hardening)

Verification:
- npx vitest run --config scripts/release/vitest.config.mts → 91 passed
- Red-green for the newline validation: temporarily removed the validation,
  the 3 new newline/CR tests failed (assertion: expected fn to throw); restored,
  back to green.
- E2E: GITHUB_OUTPUT="$OUT" pnpm release:prerelease:dry succeeded and the
  output file contained `version=1.59.5` and `scope=monorepo`.

Note: Fix 2's empty-list guard fires only on a misconfigured scope (no unit
test reachable — prerelease.ts is outside the vitest include glob and the
guard is boundary validation against a misconfigured scope, not a behavior
worth contriving a test harness for).
2026-06-10 22:58:02 +02:00
Maxim afef53de65 fix(release): emit version/scope to GITHUB_OUTPUT from prerelease.ts
prerelease.ts published canaries successfully but never wrote the
version output the publish-release workflow's "Verify publish step
emitted version" guard reads, so every canary dispatch ended red after
a successful publish. Extract the GITHUB_OUTPUT append (previously
inline in publish-release.ts) into a shared lib/github-output.ts helper
and call it from both publish scripts.

Call-site enumeration:
- emitGithubOutputs: declared lib/github-output.ts; called from
  prerelease.ts (dry-run path + after publish) and publish-release.ts
  (replaces the inline appendFileSync block, same version=/scope= keys).
- No symbols removed; fs import in publish-release.ts still used (3
  remaining call sites).
2026-06-10 22:58:02 +02:00
Tyler Slaton fe685eb46f feat(release): npm release scopes for bot(+bot-ui) and bot-slack
- release.config.json: 'bot' scope versions @copilotkit/bot and
  @copilotkit/bot-ui together (sharedVersion: true, source: bot);
  'bot-slack' is its own scope, mirroring the angular precedent
- ReleaseScope type + VALID_SCOPES arrays + usage strings extended across
  release scripts
- stable-release.yml / publish-release.yml: scope choice options
- bot, bot-ui, bot-slack manifests: drop private, add publishConfig (public),
  repository/homepage/keywords, publint/attw targets; first release v0.0.1
- internal bot-package deps use workspace:~ (tilde): caret on a 0.0.x version
  pins the exact patch, tilde tracks the 0.0.x line; core/shared stay
  workspace:^ (caret is correct at 1.x)

Verified: release-script tests 85/85; prepare-release --scope bot --dry-run
bumps bot AND bot-ui in lockstep; actionlint clean on touched lines.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 12:57:13 -07:00
Benjamin Taylor 26ea1187e7 Merge ben1/intelligence-threads-examples-rollout into codex/ent-734-crewai-crews
Graft resolution (her branch predates the crewai-crews rebuild on main):
- page.tsx: jpr5's rebuilt full demo (setThemeColor/updateProverb/
  get_weather tools, seed effect, delete buttons, WeatherCard) is the
  base; her threads shell (drawer + gate + provider) grafted around it;
  agent key AGENT_ID=default (was starterAgent on her branch)
- layout/route/package.json: rollout side (default key, AGENT_URL
  normalization, 1.59.3) + her drawer deps + intelligence route block
- contract test: crewai-crews added to the parameterized array (66/66)
- lockfile regenerated; .gitignore !.env.example negation added

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-04 10:26:23 -05:00