Skip to content

docs: rebuild onboarding around the CopilotKit channels CLI - #31

Merged
jerelvelarde merged 2 commits into
mainfrom
jerel/opentag-readme-onboarding-0f7e3d
Aug 5, 2026
Merged

docs: rebuild onboarding around the CopilotKit channels CLI#31
jerelvelarde merged 2 commits into
mainfrom
jerel/opentag-readme-onboarding-0f7e3d

Conversation

@jerelvelarde

@jerelvelarde jerelvelarde commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

Why

The documented path to a first reply could not work. Both Slack manifests in
this repo set socket_mode_enabled: true with no request_url. Managed
delivery requires Slack to POST events to an Intelligence-hosted Request URL, so
an app created the way the README instructed installs green, reports healthy, and
delivers nothing — forever. That was the recommended path for every new user.

Three more defects sat alongside it:

Was Actually
Slack credentials setup.md asked for an xapp- app-level token No xapp- exists on this path. The adapter takes a bot token (xoxb-) + signing secret.
Pinned versions README and setup.md both said 0.7.0 / 1.66.0 package.json says 0.7.3 / 1.66.2 since 674a366
pnpm test on main assumed green redapp/cleanup.test.ts was a third copy of 0.7.0

That last one is the same root cause as the second: a version pin restated in
prose and in a test assertion drifts the moment someone bumps deps. Three copies,
three drifts, one of them breaking the build.

What changed

Rather than document around the manifest bug, this removes it structurally.
npx copilotkit@latest channels add generates a Slack manifest already pointed
at the correct Request URL
, so the wrong app can no longer be created by
following instructions. That replaces the hand-written "create a project → create
a Channel → issue a key → configure adapters" dashboard walkthrough entirely.

README.md — a five-minute path to a working bot

Ordered so the Channel is created before Slack, because the Channel is what
generates the manifest.

Step 2 offers both paths. channels setup installs the channels-setup skill
and hands the flow to a coding agent; project select + channels add is the
explicit sequence. Two caveats a reader would otherwise hit are called out: the
skill installs to every coding agent it detects with no way to narrow the
list (skills onboard --channels --agent <name> takes the same prompt and does),
and its workflow is written for a project starting from nothing — so it has
phases for building the agent and writing the Channel runtime, which OpenTag
already has. An agent following it literally could rewrite working code.

The quick start ends in the three checks that separate "installed" from
"answering":

  1. Mention it → expect a reply.
  2. Unmentioned follow-up in that thread → expect a reply (a mention subscribes the thread).
  3. Unmentioned message in a fresh conversation → expect silence.

Check 3 is exactly what #29 and #30 were fighting, and no doc asserted it.

Also newly documented, all of it previously tribal knowledge:

  • channels status --json as the first debugging step — and which two of its
    warnings are expected for OpenTag, since app/env.ts defaults both
    Intelligence URLs in code rather than in .env.
  • LOG_LEVEL=debug. The runtime logger defaults to error while every Channel
    lifecycle breadcrumb logs at warn, so channel "<name>" requires setup — the
    highest-value diagnostic here — is written and discarded by default. Verified
    against 1.66.2: getCommonConfig reads process.env.LOG_LEVEL || "error".
  • /invite. Workspace-installed ≠ channel member; Slack emits no app_mention
    at all for a channel the app isn't in, so OpenTag looks broken while behaving correctly.
  • Channel names claim deliveries. Two runtimes declaring one name in one
    project race per delivery and the loser is silently starved — the tell is a
    Slack reply your terminal knows nothing about. INTELLIGENCE_CHANNEL_NAME
    defaults to open-tag, the production name, so a fork reusing a key inherits
    that race by default.
  • Signals that look like health and aren't: ready() resolves on
    setup_required too, and /api/copilotkit/info returning 200 says nothing
    about Slack.
  • That the runtime doesn't hot-reload Channel wiring — a stale process answering
    with old behavior is indistinguishable from a change that didn't work.

setup.md — reference only

Environment contract, Channel CLI reference, optional sources, Railway, tests.
No quick start (that's the README), no pinned version numbers, no xapp-.

One honesty fix: /agent, /triage, /preview, and /file-issue were listed as
features. They're registered in app/channel.tsx, but managed-path delivery
depends on the generated manifest declaring slash_commands, and as of the 0.7.0
verification it declared none and view_submission wasn't handled — so they
compile, start, report online, and never fire. Now marked unverified with an
instruction to test before relying on them, rather than promised.

docs/migration-kite.md — new

The internal @kite cutover moved out of the newcomer path. It's rewritten around
the real constraint: the app must not be recreated, yet its delivery mode must
change, because Socket Mode and a Request URL are mutually exclusive. Credentials
corrected, and the reinstall tension (scopes apply only on reinstall; the signing
secret is reissued by it) is flagged as needing confirmation against the live app
before anyone touches production.

Deletions

slack-app-manifest.{yaml,json} are gone. OpenTag supports only the managed path
app/index.ts composes an adapter-free Channel and Intelligence owns the
adapters — so these could never work here and existed only to mislead. Their only
remaining references were in archived docs/superpowers/ design records, left as
historical.

app/cleanup.test.ts

Now asserts the pin shape (a bare semver, no range operator) instead of a
literal version. Same guarantee — reproducible deploys — but it can't drift on the
next bump. This is what turns main's red suite green.

.gitignore

copilotkit channels setup writes .agents/, a .claude/skills symlink, a stray
agent/skills/ copy inside the Python package, and skills-lock.json, none of
which were ignored. Now they are, while .copilotkit/channels.json — the Channel
declaration the guide says to track — stays trackable. Verified both directions
with git check-ignore.

Verification

pnpm check-types                            ✓
pnpm test                                   ✓ 162 passed (was 161 passed / 1 failed)
cd agent && uv run pytest                   ✓ 70 passed
node node_modules/railway/dist/iac/bin.js   ✓ "diagnostics": []

Not done, deliberately

  • No code change to the Channel-name source of truth. The canonical guide
    says to resolve the name from .copilotkit/channels.json and "do not add a
    second hard-coded or environment-only source of truth" — which is precisely what
    INTELLIGENCE_CHANNEL_NAME defaulting to open-tag is. Fixing it means
    touching app/env.ts and Railway's variables, so it's documented as a footgun
    here and left for its own PR.
  • The quick start is written from the canonical guide, not from a transcript.
    Confirming it end to end means creating a real Channel and Slack app; I didn't
    have authorization to create server-side state in an Intelligence project. The
    CLI surface, the credential fields, channels status output, and the
    LOG_LEVEL default were all verified directly against the installed CLI and
    @copilotkit/runtime@1.66.2. Someone should run step 2 once against a
    throwaway project before this is treated as proven.

The documented path to a first reply could not work. Both Slack manifests set
socket_mode_enabled with no request_url, while managed delivery requires Slack
to POST to an Intelligence-hosted Request URL — so an app created the way the
README instructed installed green and delivered nothing, forever. setup.md
also asked for an xapp- app-level token, which does not exist on this path;
the adapter takes a bot token and a signing secret.

Replace the hand-written Channel walkthrough with `copilotkit channels add`,
which generates a Slack manifest already pointed at the right Request URL and
so removes the failure structurally rather than documenting around it.

- README is now a five-minute path to a working bot, ending in three trigger
  checks that separate "installed" from "answering": mention replies,
  unmentioned follow-up in a subscribed thread replies, unmentioned message in
  a fresh conversation stays silent.
- Document the diagnostics that were missing: `channels status --json`,
  LOG_LEVEL=debug (the logger defaults to error while every Channel lifecycle
  breadcrumb logs at warn), /invite, and the signals that look like health but
  are not — ready() resolving on setup_required, /api/copilotkit/info 200.
- setup.md becomes reference only. Slash commands and modals are now marked
  unverified on the managed path instead of listed as working features.
- Move the internal @kite cutover to docs/migration-kite.md, out of the path
  of anyone reading this repo for the first time, with its credential steps
  corrected.
- Warn that Channel names claim deliveries: two runtimes on one name race and
  the loser is silently starved, so forks need their own name.

Delete both Socket Mode manifests. OpenTag only supports the managed path, so
they could not work here and existed only to mislead.

Stop restating pinned versions in prose. README and setup.md both said 0.7.0
while package.json said 0.7.3, and app/cleanup.test.ts asserted 0.7.0 too —
that third copy had main's test suite red. It now asserts the pin *shape*, so
it keeps guaranteeing reproducible deploys without drifting on every bump.

Gitignore the artifacts `copilotkit channels setup` writes (.agents,
.claude/skills, agent/skills, skills-lock.json, .copilotkit/artifacts) while
leaving .copilotkit/channels.json trackable.
Step 2 now presents both paths: `channels setup`, which installs the
`channels-setup` skill and hands the flow to a coding agent, and the explicit
`project select` + `channels add` sequence.

Two caveats a reader would otherwise hit:

- `channels setup` installs to every coding agent it detects with no way to
  narrow the list. `skills onboard --channels --agent <name>` takes the same
  prompt and does let you narrow it.
- The skill's workflow is written for a project starting from nothing, so it has
  phases for building the agent and writing the Channel runtime. OpenTag already
  has both, and an agent following the guide literally could rewrite working
  code. Say so, and point at agent/ and server.ts.

Also lift the three Slack console gotchas out of the manual path into their own
subsection, since they apply either way.
@jerelvelarde
jerelvelarde merged commit d64b6e7 into main Aug 5, 2026
nanaknihal pushed a commit to nanaknihal/OpenTag that referenced this pull request Aug 6, 2026
channels-sdk calls OpenTag "the flagship application built on Channels SDK" and
vendors it as a submodule at examples/OpenTag. OpenTag never said so back, and
never framed itself as something to take rather than read. Pattern-match its
presentation to channels-sdk and make the clone-and-customize path explicit.

Adopt the channels-sdk README shape: centered header with tagline, nav links and
badges; the demo video directly beneath it; benefit-oriented section headings; a
"You run / CopilotKit Intelligence manages" split table; and a "Developer
resources" table. Add the reciprocal link that was missing in both the header and
the resources table.

New sections:

- "The complete Channels SDK application" — clone / customize / ship, stating the
  relationship channels-sdk already documents from its side.
- "See it work" — three 1600x900 stills in the three-column layout channels-sdk
  uses. These are real frames from the committed demo video (t=18s a CSV becoming
  a native Slack chart, t=43s the Linear approval gate, t=64s research with cited
  sources), not mockups, so they cannot drift from what the code does.
- "Make it yours" — a table mapping each thing a fork would change to the one file
  or directory that owns it, including that AGENT_URL points at any AG-UI agent,
  so swapping frameworks needs no Channel changes.

Add AGENTS.md, following channels-sdk's convention and its lesson: name the
authority, install skills rather than vendoring them. Registry `setup-slack-channel`
turns out to be written for an OpenTag checkout specifically — it assumes
app/channel.tsx, app/env.ts, INTELLIGENCE_CHANNEL_NAME and an agent on 8123 — so
it is named as the preferred path here over a generic sequence. Carries the repo
map, the four verification commands, the gotchas that cost the most time, and the
convention that pinned versions live in package.json and nowhere else.

The quick start, prove-it-works checks, and diagnostics from CopilotKit#31 are unchanged.

Verified: check-types clean, 162 TS tests, 70 Python tests, Railway IaC
diagnostics empty, and every local link and image path in README.md and AGENTS.md
resolves.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant