Skip to content

[pull] main from CopilotKit:main#422

Merged
pull[bot] merged 54 commits into
bit-cook:mainfrom
CopilotKit:main
Jul 11, 2026
Merged

[pull] main from CopilotKit:main#422
pull[bot] merged 54 commits into
bit-cook:mainfrom
CopilotKit:main

Conversation

@pull

@pull pull Bot commented Jul 11, 2026

Copy link
Copy Markdown

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 : )

contextablemark and others added 30 commits July 8, 2026 21:31
…check)

OSS-451 shipped because nothing linked a demo page's CopilotKit runtimeUrl
to the existence of the /api route it names. The only automatic pre-merge
gate for showcase/** is a Docker build, which compiles a page that
references a non-existent route just fine (runtimeUrl is an unchecked
string) — so the page-404-on-load class was invisible.

Add a static validator (validate-runtime-routes.ts) that, for every SHIPPED
demo (a demo listed in its integration's manifest `features`), asserts its
runtimeUrl resolves to a real route dir under src/app/api. Unshipped /
experimental demos (not in `features`) and not_supported_features are
skipped, so incomplete placeholders don't fail the gate — but promoting one
into `features` immediately starts enforcing it. A baseline file can
grandfather pre-existing violations; the fleet is currently clean (0).

Wire it into a new pre-merge workflow (showcase_validate-wiring.yml) that
runs on every showcase/integrations PR alongside the build check. Add it to
branch-protection required checks to make it blocking.

Regression test proves it flags the exact OSS-451 shape (shipped demo,
missing route) while passing existing/base routes and skipping unshipped.

Verified: npm run validate-routes -> clean fleet-wide; removing the 3
OSS-451 routes -> flags exactly those 3; full showcase/scripts vitest suite
(2151 tests) green.

Refs OSS-451
…check) [OSS-451 prevention] (#5884)

## What

Adds a pre-merge guard that prevents the
[OSS-451](https://linear.app/copilotkit/issue/OSS-451) **dead-on-load**
failure class from recurring:

- `showcase/scripts/validate-runtime-routes.ts` — static validator +
`validate-routes` npm script
- `showcase/scripts/__tests__/validate-runtime-routes.test.ts` (+
fixture integration) — regression coverage
- `.github/workflows/showcase_validate-wiring.yml` — runs it on every
`showcase/integrations/**` PR

> **Stacked on #5881** (the fix). Base branch is
`mark/oss-451-mastra-demos-404`; retarget to `main` once #5881 merges.
The guard is green *because* #5881 is present.

## Why

OSS-451 shipped because **nothing linked a demo page's `runtimeUrl`
string to the existence of the `/api` route it names.** The only
automatic pre-merge gate for `showcase/**` is `showcase_build_check.yml`
— a Docker *build* — and a page that references a non-existent route
compiles perfectly cleanly. So three demos went dead-on-load in
production undetected (the e2e specs that *would* have caught it run
on-demand only, post-deploy, and exclude TS-only Mastra).

## How it works

For every **shipped** demo — a demo directory whose slug is in its
integration's `manifest.yaml` `features` — the validator asserts every
`runtimeUrl` it declares resolves to a real route dir under
`src/app/api/`.

- Unshipped / experimental demos (not in `features`) and
`not_supported_features` are **skipped** — they aren't claimed to work,
so they don't fail the gate. Promoting one into `features` immediately
starts enforcing it (this is the safety net for the still-unshipped
`declarative-hashbrown` / `declarative-json-render`).
- A `validate-runtime-routes.baseline.json` can grandfather pre-existing
violations (same pattern as the pin-drift `fail-baseline.json`). **The
fleet is currently clean — 0 violations, no baseline needed.**
- Handles the shared `/api/copilotkit` route and catch-all routes
(`copilotkit-auth`, `copilotkit-voice`) by asserting the top-level route
dir exists.

## Verification

- `npm run validate-routes` → clean across all 21 integrations.
- Removing the 3 OSS-451 routes locally → the guard flags **exactly
those 3** and exits 1; restoring → exits 0.
- Regression test (5 cases): flags the shipped-demo-with-missing-route
shape, passes shared + dedicated routes, skips unshipped.
- Full `showcase/scripts` vitest suite: **2151 tests green**.
- Workflow YAML validated; actions pinned to SHA; `contents: read` only;
no secrets.

## Follow-up for a maintainer
Add **"Showcase: Runtime-Route Wiring (PR)"** to the branch-protection
required checks so it blocks merge like the build check does.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
…naged entrypoint (OSS-406 Phase 1)

The realtime primitives (startManagedBots, connectPhoenixHostedBotChannel,
PhoenixRealtimeTransport) existed but nothing composed them into a launcher, so
the managed path defaulted to HTTP and Phoenix was never actually used.

- startManagedBotsOnChannel(bots, { channel, scope, runtimeInstanceId }) — wraps
  an already-connected channel in a PhoenixRealtimeTransport (delivery source +
  render sink) and starts the bots via startManagedBots. Split out so the
  behavior is unit-testable against a fake channel.
- startManagedBotsOverPhoenix(bots, config) — thin glue: connect the gateway
  bot-IO channel, delegate, disconnect on stop().
- phoenixEgress: fail-loud EgressSink (Phoenix routes all egress through the
  render sink).
- examples/slack/app/managed.ts — a REAL consumer of the launcher: the same
  Slack bot as index.ts (agent/tools/context/commands/handlers identical) run in
  managed mode over Phoenix instead of the native slack() adapter. No native
  index.ts changes.

Tests drive a real createBot through the full managed path over a fake channel:
delivered turn → render frame → completion INTENT (never self-ack); throwing
handler → fail intent. Live-stack E2E + manual validation are the OSS-406 proof;
scale-out (Teams, etc.) is OSS-459.
…ompt

Managed getHistory (app-api /api/bots/history) doesn't include the in-flight
turn — unlike native adapters whose getHistory rebuilds the live thread — so
runAgent({context}) alone runs the agent with zero messages (→ provider 400).
Pass the current message (contentParts ?? text) as `prompt`, the sanctioned
mechanism for input not in the adapter's reconstructed history. Verified live:
the managed Slack bot now returns a real answer over the Phoenix loop.
…eanup + authoritative runtimeInstanceId (OSS-406 review r2)
The managed runtime's claimOnce() declared `adapters: [this.cfg.adapter]`
(defaulting to "slack"), which Intelligence used to filter claimable
deliveries by provider. A runtime serving a bot with both Slack and Teams
adapters would therefore never receive the bot's Teams deliveries — they
stayed queued forever while Slack worked.

The managed runtime is provider-agnostic: it emits abstract render frames
and Intelligence renders per the delivery's own reply target. So the claim
must not filter by provider. Drop the adapter filter from the claim body;
one config-free `intelligenceAdapter()` now serves every channel its bot
has attached.

Verified end-to-end locally against managed Teams: inbound JWT -> claim ->
agent -> render -> Bot Connector egress all succeed with this change.
…leak-path tests + fail-loud managed entrypoint (OSS-406 review r3)
…naged entrypoint (OSS-406 Phase 1) (#5907)

## Summary

**OSS-406 Phase 1** — the missing composition that runs a managed bot
over the **Phoenix realtime path**, plus a real consumer of it.

The realtime foundation is live on main (gateway
`hosted_bots:project:<id>` channel, Redis fan-out, app-api durable
authority + lease fencing), and the SDK primitives — `startManagedBots`,
`connectPhoenixHostedBotChannel`, `PhoenixRealtimeTransport` — exist and
are unit-tested. But **nothing composed them**, so the managed adapter
fell back to its HTTP default and Phoenix was never exercised
end-to-end. This adds the launcher **and wires an example to it** so it
isn't an unused export.

## Launcher (`channels-intelligence/phoenix-launcher.ts`)

- **`startManagedBotsOnChannel(bots, { channel, scope,
runtimeInstanceId, log? })`** — wraps an already-connected channel in a
`PhoenixRealtimeTransport` (delivery source + render sink) and starts
the bots via `startManagedBots`. Split out so the *behavior* is
unit-testable against a fake channel.
- **`startManagedBotsOverPhoenix(bots, config)`** — thin glue:
`connectPhoenixHostedBotChannel` → delegate → `disconnect()` on
`stop()`.
- **`phoenixEgress`** — fail-loud `EgressSink`. `intelligenceAdapter` is
exclusive and, with a render sink wired, routes every
`post`/`update`/run-render through it — the generic `EgressSink` must
never be hit.

## Consumer (`examples/slack/app/managed.ts`)

A **real caller** of the launcher: the *same* Slack bot as
`examples/slack/app/index.ts` — identical agent, tools, context,
commands, and turn handlers — run in **managed mode over Phoenix**
instead of the native `slack()` adapter. `index.ts` (native/self-hosted)
is left untouched; `managed.ts` holds no Slack creds and no public
endpoint, just a runtime key + a Phoenix connection. Demonstrates the
"same bot, swap the transport" thesis concretely:

```
native:   createBot({ adapters: [ slack({ botToken, appToken }) ] })   // index.ts
managed:  startManagedBotsOverPhoenix([ createBot({ … }) ], { … })     // managed.ts
```

The managed `onMention` handler passes the current message as `prompt`
to `runAgent` — see the validation note below for why this is required
on the managed path (and not on native).

## Tests

Drive a **real `createBot`** through the **full managed path** over a
fake channel:
- a Phoenix-delivered turn → handler runs → `render_event` frame →
`complete_requested` (completion **intent**, never a self-ack);
- a throwing handler → `fail` intent (no completion, no ack).

Build + 97 package tests green; `examples/slack` `managed.ts`
type-clean.

## Validation — live E2E over the real Phoenix path

This didn't just pass unit tests against a fake channel; the whole loop
was driven end-to-end on a real local stack with a **real OpenAI
backend**, and I verified the message actually traveled the websocket
path (not the HTTP fallback).

**Stack:** Intelligence `main` via docker-compose (postgres,
postgres-ops, redis, keycloak, minio, tei, realtime-gateway on `:4401`)
+ app-api on `:7050` (graphile migrations applied). Managed-bots
entitlement was granted via the managed-service path (a stub ops
entitlement endpoint + `FF_MANAGED_BOTS=true` on both app-api and the
gateway; gateway join otherwise rejects with
`disabled_by_feature_flag`).

**Provisioning:** created a managed Slack bot + attached a Slack adapter
(fixture workspace/creds) against app-api, then triggered a real
`app-mention` event through a fake-Slack provider into app-api's signed
ingress.

**What was proven:**
- app-api ingress → Redis publish → gateway leases the delivery and
pushes `delivery.available` over Phoenix → `managed.ts` (via the
launcher) receives it, runs the **real OpenAI** agent, and streams
`render_event` frames back → durable render acceptances written
(`run_started`, `text_delta`, `text_end`, `finalize`) →
`complete_requested` intent → app-api commits the ack. Delivery ended
`succeeded`.
- **It genuinely used the websocket path.** With gateway debug logging
bumped, frames showed `HANDLED hosted_bot.render_event.v1 INCOMING ON
hosted_bots:project:<id> (SdkChannel)`. All app-api delivery-side calls
originated from the gateway's HTTP client (`hackney`), with **zero
launcher-originated HTTP delivery calls**, and the launcher contains no
HTTP delivery code at all. The render frames went bot → gateway over the
Phoenix socket.

**Bug found and fixed during validation (the reason `managed.ts` passes
`prompt`):**
The first real run failed with an OpenAI `400 input.messages=0` — the
agent received **zero messages**. Root cause: `runAgent`
(packages/channels `thread.ts`) only injects a user message when
`extra.prompt` is set; otherwise it relies on the adapter's
reconstructed history. The **native** path gets away with omitting
`prompt` because the native adapter's `getHistory` rebuilds the live
thread *including* the triggering message. The **managed** path does
not: app-api's `GET /api/bots/history`
(`reconstructManagedThreadHistory`) rebuilds only *prior committed*
deliveries and structurally excludes the in-flight turn (the current
delivery is handed to the SDK as the delivery envelope, not via
history). So a managed handler that omits `prompt` drops the newest user
message — turn 1 → 0 messages → 400; turn 2+ → the agent answers a
*stale* prompt. FakeAgent unit tests never caught it because they don't
exercise the history round-trip.

Fixed here by having the managed `onMention` pass `message.contentParts
?? message.text` as `prompt`. This is a **systemic** footgun for every
managed entrypoint; it's tracked with a durable-fix recommendation
(adapter auto-injects the current message so managed handlers match
native) in **OSS-459**.

## Scope

- **This PR:** the launcher composition + its first consumer +
unit/contract coverage, **plus the live-stack E2E above** which closes
OSS-406's "realtime path is unproven" gap and surfaced/fixed the managed
`prompt` bug.
- **Deferred (OSS-459):** Teams managed entrypoint, multi-tenant
multiplexing, BYO, promote to a deployable Intelligence managed-bot
runtime app, HTTP-path deprecation, shared bot-def extraction, and the
durable managed-`prompt` fix.

Refs OSS-406.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
…s-safe)

Follow-up to the provider-agnostic claim change on this branch. Now that the
runtime claims deliveries for every provider its bot has attached, Teams
deliveries flow through the same bridge — and their reply target is a distinct
shape (serviceUrl/conversationId/tenantId, no teamId/channel/threadTs). Deriving
conversationKey from Slack-only fields collapsed every Teams conversation onto
one degenerate key, and conversationKey keys the agent/session
(getOrCreate -> makeAgent), so distinct Teams conversations would share
state/memory.

Make replyTarget a discriminated union (slack|teams) and derive conversationKey
per provider: teams:{tenantId}:{conversationId}, matching Intelligence app-api's
thread_key (OSS-441 slice 2, Intelligence #511) so client and server agree on
conversation identity. Unknown adapters fail loud (the claim loop's existing
catch nacks, not wedges).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
tylerslaton and others added 24 commits July 10, 2026 12:52
…5914)

## Problem

A managed bot with **both** a Slack and a Teams adapter attached only
ever received its **Slack** deliveries. Teams deliveries stayed `queued`
forever — never claimed, never sent.

## Root cause

`channels-intelligence`'s runtime claim loop (`http-transports.ts` →
`claimOnce()`) posted a per-provider filter to
`/api/bots/listener/claim`:

```ts
{
  runtimeInstanceId: this.cfg.runtimeInstanceId,
  adapters: [this.cfg.adapter], // defaults to "slack"
}
```

app-api filters claimable deliveries by that list (`$adapters IS NULL OR
bie.provider = ANY($adapters)`), so a runtime declaring only `"slack"`
is never handed the same bot's Teams deliveries.

But the managed runtime is **provider-agnostic**: it emits abstract
render frames and Intelligence renders each reply per the delivery's own
reply target. There is no reason for the runtime to constrain claims by
provider — one `intelligenceAdapter()` should serve every channel its
bot has attached.

## Fix

Drop the `adapters` field from the claim body. `adapters` is already
optional on the app-api side (absent → `NULL` → no provider filter → all
providers), so this needs no coordinated backend change.
`this.cfg.adapter` is still used for the heartbeat's declared bots and
for egress, both unaffected.

## Testing

Verified end-to-end locally against a managed Teams bot: inbound Bot
Framework JWT → claim → agent run → render → Bot Connector egress all
`succeed` with this change. Slack continues to work unchanged.
## Summary

Adds production onboarding for the Inspector Threads empty state:

- Moves the Threads `Talk to an Engineer` CTA into the main inspector
tab nav when Threads is active.
- Replaces the enabled-empty `No threads yet` state with example thread
rows and a deselected overview.
- Lets users select an example thread to preview the real thread-details
UI with Timeline, Raw AG-UI Events, and State data.
- Adds a dismissible/reopenable example tour that persists dismissal in
local storage.
- Hides examples once real threads are present.
- Adds the `Learn how Threads work` and `Explore self-hosted
Intelligence` CTAs.
- Adds a deferred autoplay video preview to the enabled-empty deselected
overview.

## Telemetry

New/updated Threads events in this PR:

- `oss.inspector.threads_tab_clicked` — fires when the rendered Threads
nav tab is clicked.
- `oss.inspector.threads_locked_viewed` — fires once per inspector
instance for the locked state.
- `oss.inspector.threads_empty_enabled_viewed` — fires once per
inspector instance when Threads are enabled with zero real threads.
- `oss.inspector.threads_enabled_viewed` — fires once per inspector
instance when real threads are present.
- `oss.inspector.threads_intelligence_signup_clicked` — fires from
locked-state Intelligence signup CTAs.
- `oss.inspector.threads_talk_to_engineer_clicked` /
`oss.inspector.talk_to_engineer_clicked` — fire from Threads-specific
and shared Talk to an Engineer CTAs.
- `oss.inspector.threads_example_viewed` — fires once per example thread
shown in the empty state.
- `oss.inspector.threads_example_selected` — fires once per example
thread selection.
- `oss.inspector.threads_example_tour_started` — fires when the tour
auto-starts for the first selected example.
- `oss.inspector.threads_example_tour_step_viewed` — fires once per
example thread/tour step.
- `oss.inspector.threads_example_tour_dismissed` — fires when the user
skips the tour.
- `oss.inspector.threads_example_tour_completed` — fires when the user
finishes the tour.
- `oss.inspector.threads_example_tour_reopened` — fires when the user
clicks `Show tour` after dismissal.

Telemetry properties are limited to product metadata and funnel context:
package/version, inspector distinct IDs,
intelligence/thread-service/license/runtime status, runtime URL type,
CTA surface/type, telemetry-disabled status, thread count, example
thread ID, tour step/tab, and dismiss method. We do **not** send message
content, AG-UI event payloads, agent state, prompts, completions, or
thread bodies.

No telemetry was added for passive video loading; it is a visual
affordance rather than a user intent signal.

## Outbound Attribution

Threads onboarding CTAs now include existing `ref` attribution plus
these UTM parameters:

- `utm_source=copilotkit_inspector`
- `utm_medium=in_product`
- `utm_campaign=threads_onboarding`

Affected links are limited to Threads onboarding surfaces:

- Threads tab-nav `Talk to an Engineer`
- Threads locked-state `Sign up for Intelligence`
(`https://dashboard.operations.copilotkit.ai/sign-in`)
- Empty Threads overview `Learn how Threads work`
- Empty Threads overview `Explore self-hosted Intelligence`

The UTM params are opt-in for these Threads onboarding CTAs and do not
apply to generic announcement/banner links or locked Memories CTAs. The
inspector spec includes a regression test to keep locked Memories CTAs
free of the Threads campaign params.

## Video Asset + Performance

- The overview video uses the CDN-hosted asset at
`https://cdn.copilotkit.ai/corp-site/videos/copilotkit-generative-ui-agentic-frontend-demo.webm`
instead of committing a binary to `@copilotkit/web-inspector`.
- Verified the URL serves `200`, `Content-Type: video/webm`,
`Content-Length: 6765736`, and a CloudFront cache hit.
- `@copilotkit/web-inspector` currently only inlines CSS and SVG assets
in its package build, while larger docs/showcase media commonly lives on
hosted/CDN-style URLs.
- The video `src` is not rendered on the initial overview paint. It is
deferred until `requestIdleCallback` or a short timeout fallback, uses
`preload="metadata"`, fades in after `loadeddata`, and does not load for
`prefers-reduced-motion: reduce`.

## Validation

- `NX_TUI=false npx -y pnpm@10.33.4 nx run
@copilotkit/web-inspector:test -- web-inspector.spec.ts`
- `NX_TUI=false npx -y pnpm@10.33.4 nx run
@copilotkit/web-inspector:check-types`

<img width="1662" height="1382" alt="CleanShot 2026-07-10 at 12 01
03@2x"
src="https://github.com/user-attachments/assets/e2031570-f602-40dc-a54c-e9c7690fc0ba"
/>
<img width="1680" height="1388" alt="CleanShot 2026-07-10 at 12 01
12@2x"
src="https://github.com/user-attachments/assets/2c8db42f-3ab0-47e2-a235-ea54e8dd292b"
/>
## Problem

`@copilotkit/channels-intelligence` still used the retired Bot
HTTP/realtime contract and exposed Phoenix implementation details. The
managed Slack entrypoint used the same legacy API.

## Why

Intelligence now exposes a clean-break Channels contract. The SDK must
use it consistently, while keeping the Phoenix-backed transport private
behind a product-neutral Realtime Gateway API. Compatibility aliases
would hide integration mismatches.

## Fix

- Migrated HTTP paths, payloads, config, and KV state to Channel
terminology.
- Added the Realtime Gateway abstraction and Channel realtime wire
contract.
- Renamed remaining APIs/types, updated the managed Slack example, and
added forbidden-term coverage.
- Preserved framework and vendor `Bot` terminology only where it remains
semantically correct.
## Release channels v0.1.1

**Scope:** `channels` | **Bump:** `patch`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `channels` packages to `0.1.1`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
   - Publishes the `channels` packages to npm at version `0.1.1`
   - Creates git tag `channels/v0.1.1`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
## Release channels-discord v0.0.3

**Scope:** `channels-discord` | **Bump:** `patch`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `channels-discord` packages to `0.0.3`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
   - Publishes the `channels-discord` packages to npm at version `0.0.3`
   - Creates git tag `channels-discord/v0.0.3`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
## Release channels-slack v0.1.2

**Scope:** `channels-slack` | **Bump:** `patch`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `channels-slack` packages to `0.1.2`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
   - Publishes the `channels-slack` packages to npm at version `0.1.2`
   - Creates git tag `channels-slack/v0.1.2`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
## Release channels-teams v0.1.2

**Scope:** `channels-teams` | **Bump:** `patch`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `channels-teams` packages to `0.1.2`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
   - Publishes the `channels-teams` packages to npm at version `0.1.2`
   - Creates git tag `channels-teams/v0.1.2`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
## Release channels-intelligence v0.1.1

**Scope:** `channels-intelligence` | **Bump:** `patch`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `channels-intelligence` packages to `0.1.1`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
- Publishes the `channels-intelligence` packages to npm at version
`0.1.1`
   - Creates git tag `channels-intelligence/v0.1.1`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
## Release channels-telegram v0.0.4

**Scope:** `channels-telegram` | **Bump:** `patch`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `channels-telegram` packages to `0.0.4`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
- Publishes the `channels-telegram` packages to npm at version `0.0.4`
   - Creates git tag `channels-telegram/v0.0.4`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
## Release channels-whatsapp v0.0.2

**Scope:** `channels-whatsapp` | **Bump:** `patch`

---

### How this release process works

1. **This PR was created automatically** by the "release / create-pr"
workflow.
   It bumped the `channels-whatsapp` packages to `0.0.2`
   and generated AI-enhanced release notes.

2. **CI runs on this PR** — the full test suite (unit tests, lint, type
checks, build)
   must pass before merging. This is the review gate.

3. **Review the release notes** in `release-notes.md` in this PR.
If a Notion draft was created, you can edit the release notes there
before merging.

4. **When this PR is merged**, the `release / publish` workflow
automatically:
   - Builds all packages
- Publishes the `channels-whatsapp` packages to npm at version `0.0.2`
   - Creates git tag `channels-whatsapp/v0.0.2`
   - Creates a GitHub Release with the final release notes

### Before merging

- [ ] CI is green (tests, lint, types, build)
- [ ] Version bumps look correct
- [ ] Release notes are accurate (edit in Notion if a draft was created)

---

> **Do not merge until CI is fully green.** The full test suite runs
automatically on this PR.
@pull pull Bot locked and limited conversation to collaborators Jul 11, 2026
@pull pull Bot added the ⤵️ pull label Jul 11, 2026
@pull pull Bot merged commit 87db1b0 into bit-cook:main Jul 11, 2026
11 of 17 checks passed
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants