Deprecated API fields clutter the interactive playground at the top of
reference pages. Hide those inputs while retaining their descriptions,
deprecation badges, defaults, and response examples in the reference
below.
Filter a cloned schema only inside the playground renderer. Keep the
shared OpenAPI loader unchanged and preserve synchronization between
playground edits, example selection, server selection, and generated
request code. Published OpenAPI files remain unchanged.
Validation: all 547 docs static tests pass, `bun run types:check`
passes, and `bun run lint` passes with existing warnings. Browser checks
on Create auth config confirm both auth variants omit deprecated inputs,
the JSON editor omits deprecated values, reference descriptions and
badges remain, and edits update the cURL example.
Fixes DEVREL-51.
This PR:
- upgrades every CI action to its latest release (only
`changesets/action` had one: v2.1.1 -> v2.1.2, SHA-pinned) and every
outdated dependency across the pnpm workspace, the docs bun workspace,
and all three `uv.lock` files
- moves zod to 4.5.4 everywhere first-party — catalog, docs,
`@composio/json-schema-to-zod`, `@composio/claude-agent-sdk` and the
zod-v4 e2e fixtures; the `*-zod-v3` fixtures stay on 3.25.76 because
that is what they exercise
- moves `@mastra/core` 1.52.1 -> 1.53.0, which is the ceiling rather
than a preference: bisecting `ts/examples/mastra`'s `cf:dry-run` shows
1.54.0 moved the workspace/sandbox subsystem behind
`@mastra/core/agent`, which drags execa (-> `npm-run-path` ->
`unicorn-magic`) into the Workers bundle where esbuild cannot link it.
`@mastra/mcp` is capped at 1.17.2 for the same reason — 1.17.3 wants
`@mastra/core` >=1.64. The docs bun workspace mirrors that cap as an
explicit devDependency plus `overrides` entry, because bun does not
apply overrides to auto-installed peers
- clears every production advisory that has a published fix, so the
audit gate can run without `--ignore`, which does not filter a single
run: it writes the advisory into `auditConfig` and exits 0 whatever else
is outstanding, so the gate was passing over nine advisories
- `qs` -> >=6.16.0, `fast-uri` -> >=3.1.6, `toml` -> the 4.x line, all
via overrides in the existing `# temporary: … drop when` style
- `extract-zip` (GHSA-jmr9-qjv8-65gv) has no fixed version to move to —
2.0.1 is the newest release and GitHub records `first_patched_version`
as null — so it moves to `auditConfig.ignoreGhsas` pointing at the
`extractZipSafely` mitigation that already covers it
- GHSA-866g-f22w-33x8 (`@ai-sdk/provider-utils` 3.x, low) also has
nothing to move to: the advisory names 3.0.98 as patched but the 3.x
line stopped at 3.0.30 and GitHub records no fixed version. It only
enters the tree through `@mastra/core`, which is a peer or dev
dependency of every published package, so all flagged paths are private
examples and e2e fixtures. It goes in `ignoreGhsas` with that rationale
so the un-levelled `pnpm audit --prod` step stops posting a warning
comment on every PR
- widens `@composio/anthropic`'s `@anthropic-ai/sdk` peer range to
include `^0.124.0`, the line its devDependency now tests against (for a
`0.x` caret, `^0.120.0` excluded it); the package is in the changeset
for that reason
- adapts three call sites that upstream broke: `eve` 0.52 moved
`ApprovalContext` to `eve/tools/approval`, `@pierre/diffs` 1.4 gave
`FileDiffProps` a second type parameter, and `fumadocs-openapi` 11.4
fixed the undeclared-tag drop that a docs guard test asserted (the guard
now also asserts the page positively, so it cannot pass vacuously)
- drops the stale `hono` `minimumReleaseAgeExclude` entry (its comment
said to after 2026-08-06) and adds an `undici` `peerDependencyRules`
allowance for openai 7.10's new optional peer
## Context
Some upgrades were deliberately declined, each for a reason recorded
next to the pin:
- `vitest`/`@vitest/ui` stay on 4.1.11 —
`@cloudflare/vitest-pool-workers@0.22.0` (latest) peers on `vitest
^4.1.0`
- `undici` stays on `^7` in core — `pinnedDispatcher.node.ts` documents
that Node's `fetch` rejects undici 8 dispatchers
- the `pnpm` catalog entry stays on `^11` to match the mise-owned
toolchain
- `eve` stays on 0.27.6 in docs — 0.52 changes the `defineAgent` model
definition and the `useEveAgent` helpers, so `agent/agent.ts` and
`components/eve-chat.tsx` fail `types:check`; migrating the docs agent
is its own PR
- `@earendil-works/pi-coding-agent` stays on 0.84.4 — 0.85.x imports
`@earendil-works/pi-server` without declaring it, so `test/pi.test.ts`
fails to load
`declareOperationTags` is kept as a safety net rather than retired, even
though `fumadocs-openapi` 11.4 makes it redundant: removing it changes
how specs are normalised at sync time and is worth its own PR.
Verified locally: `pnpm build:packages`, `pnpm typecheck`, `pnpm test`,
`pnpm typecheck:examples`, `pnpm lint:examples`, `turbo cf:dry-run
--filter='./ts/examples/*'`, `pnpm peers check`, `pnpm audit --prod
--audit-level=high` (exit 0), frozen-lockfile installs for pnpm and bun,
docs `types:check` + 542 static tests, and Python `make chk` + `make
tst` (1790 passed).
https://claude.ai/code/session_018evFic47PFPXuB95uRE1aw
EOF -R ComposioHQ/composio
## Summary
Applies the top findings from a multi-reviewer code review of #4335
(which merged before these could land on the PR branch). Four validated
findings, all small and behavior-preserving outside the fixes
themselves:
- **Cross-tab theme fight (P1):** #4335 routed the product-derived theme
through next-themes' shared `theme` localStorage key -- written by the
root layout's inline head script on every hard load and by `setTheme` on
every client switch. next-themes listens for cross-tab storage events on
that key, so two docs tabs on different products (Platform dark / For
You light) silently repaint each other with no self-heal (the provider
effect's deps are `[product, setTheme]`, so the flipped tab never
corrects). The product theme is derived state, not a preference: this PR
applies it directly to the document element (`applyProductTheme`) and
passes `forcedTheme: initialTheme` from the server-resolved product so
hydration cannot flip a stale stored value. No `theme` localStorage
writes remain anywhere.
- **theme-color meta (P2):** the two `prefers-color-scheme`-keyed metas
meant mobile browser chrome mismatched the forced page theme (white
chrome over dark Platform pages for light-OS users). Now a single meta
keyed to the product theme.
- **Switcher current-option href (P2):** the popover option marked
`aria-current="page"` resolved to the product landing route, so
middle-click, hover status bar, and copy-link all pointed at the wrong
URL. It now hrefs the current pathname.
- **Explore-card aria-label (P3):** `aria-label` replaced the link's
accessible name, so the product description inside the card was not
announced. Dropped; heading + description now form the name.
## Changes
- `docs/app/layout.tsx` -- inline script no longer writes localStorage
(pre-paint class priming unchanged); single product-keyed `theme-color`
meta; `forcedTheme: initialTheme` on `RootProvider`.
- `docs/components/docs-product-context.tsx` -- `setTheme`/`useTheme`
removed; new `applyProductTheme` used in the product effect and the
flushSync commit.
- `docs/components/product-switcher.tsx` -- `destination = isCurrent ?
pathname : docsProductDestination(...)`.
- `docs/components/home-surfaces.tsx` -- Explore-card `aria-label`
removed.
- `docs/tests/static/product-navigation.test.ts` -- pins the new
invariants (`applyProductTheme`, `forcedTheme: initialTheme`, and a
negative assertion that `localStorage.setItem('theme'` stays out).
## Testing
- `bun test tests/static/` -- 541 pass / 0 fail
- `bun run types:check` -- clean
- `bun run lint` -- only pre-existing warnings (`home-surfaces.tsx:102`
`no-img-element` is in `ForYouVisual`, untouched)
- Worth a manual check: two tabs on different products no longer repaint
each other (static tests cannot prove cross-tab storage isolation)
## Notes
- Docs-only change; no changeset required.
- Review context: follow-up to #4335. Remaining review findings
(navigation state-machine races, theme-scope design call, decision
record) are tracked separately.
## Summary
Composio's new pricing went live on Aug 15, 2026: **Hobby** ($0) /
**Pro** ($29/mo) / **Enterprise** (custom). This PR updates the public
docs to describe only the current offering and reprices premium tools as
pass-through (provider cost + 5% platform fee).
## Principle
- Docs describe the **current** plans only (Hobby / Pro / Enterprise).
No Starter/Growth tables, no dual documentation.
- Where a legacy note is genuinely useful (rate limits), exactly one
sentence pointing pre-Aug-15 customers to
https://composio.dev/pricing/legacy.
- **Link to https://composio.dev/pricing instead of repeating numbers**,
so future price changes are a one-place edit.
## Files changed
- `docs/content/toolkits/pro-tools.mdx` — replaced the "3x the cost"
line and the Totally Free / Ridiculously Cheap / Serious Business tier
table with pass-through pricing copy: paid third-party providers,
provider price + 5% platform fee (no markup), per-call prices on the
pricing page's "Premium tools" section, Hobby includes up to $2/mo of
premium tool usage, prices depend on provider and can change with
advance notice. Retitled the page from "Pro Tools" to "Premium Tools"
(matches the pricing page and avoids confusion with the new Pro plan).
URL slug `/toolkits/pro-tools` is unchanged so no links break. Rest of
the page (what counts as a premium tool, rate limits) intact.
- `docs/content/reference/rate-limits.mdx` +
`docs/content/reference/v3/rate-limits.mdx` (manual copies, updated
identically) — plan table now Hobby 2,000 req/min · Pro 10,000 req/min ·
Enterprise Custom (kept the doc's existing per-minute unit and "Custom"
wording for Enterprise). No legacy/grandfathering note — docs describe
current plans only; grandfathered customers are served by the dashboard
and composio.dev/pricing/legacy.
- `docs/app/llms.mdx/[[...slug]]/route.ts`,
`docs/components/toolkits/toolkits-landing.tsx` — label text "Pro Tools"
→ "Premium Tools" (link targets unchanged).
## Not changed / notes for reviewers
- `docs/content/docs/common-faq.mdx` no longer exists on `next` (removed
in the sessions-first rewrite, #3637); a grep for self-host / on-prem
across `docs/content` found **no** page advertising self-hosting as an
Enterprise feature, so nothing to remove there.
- Grep sweep (case-insensitive) over `docs/content` for: Starter, Growth
plan/tier, Ridiculously, Serious Business, Totally Free, on-prem,
self-host(ed), $229, $599, 20k tool calls, 200k, per seat, per-seat, 3x
the cost. All customer-facing hits were in the three files above and are
fixed. Left alone:
- `changelog/*` — historical entries (self-hosted Supabase/PostHog
instances, "self-hosted deployments need backend version X"); these
refer to third-party instances or historical SDK notes, not to an
Enterprise plan feature.
- `docs/auth-configuration/custom-auth-configs.mdx:23`,
`docs/authentication/custom-app-vs-managed-app.mdx:30` — "self-hosted"
refers to the *customer's* self-hosted third-party app (e.g. Salesforce
subdomain), unrelated to Composio plans.
- `docs/configuring-sessions.mdx`, `docs/sandbox/remote.mdx` —
"Sandboxes are not billed today" note; not part of this change, flagging
in case sandbox billing status changed with the new pricing.
- `pro-tools.mdx` "Rate limits" table: **fixed in `421789d90`** —
dropped the "Standard Tool Calls" column (100/min · 5,000/min
contradicted `reference/rate-limits.mdx`), kept only the
premium-execution limiter mapped to plan names (Hobby 1,000/hr · Pro
10,000/hr · Enterprise Custom) with a note that it is separate from the
org API limit. Also added Pro's premium allowance bullet.
## Validation
- `bun run lint` (oxlint): passes; only pre-existing warnings in
untouched files.
- `bun run lint:links` (`scripts/validate-links.ts`): 0 errors.
## Related PRs
- landing: https://github.com/ComposioHQ/landing/pull/289
- platform: https://github.com/ComposioHQ/platform/pull/12078
- dashboard: https://github.com/ComposioHQ/dashboard/pull/1326🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01P3JgWs8DcjeQTRKoJd8gmQ
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The docs hero, feature cards, site metadata, and llms.txt all hardcoded
"1,000+" apps, while the published catalog is 1,327 toolkits (the length of
docs/public/data/toolkits-list.json, already rendered by the /toolkits page).
Add a server-only helper docs/lib/toolkit-count.ts that imports that same
JSON and exports TOOLKIT_COUNT_LABEL = Math.floor(len/100)*100 -> "1,300+",
with the locale pinned (toLocaleString('en-US')) so the separator is a comma
on any build host. Six server-side files now consume it. No client bundle
cost: none of the importers is a "use client" module, so the JSON never
reaches the browser.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The new AuthDiagram sized its hub (`w-36`) and account cards (`w-44`) with
fixed widths totalling 320px, but the feature-grid pane is not monotonic in
the viewport: ~404px at 1280px, and only ~242px at 640px where the grid goes
two-column. Below ~394px viewport the two blocks shrank until they touched,
`ex === sx` collapsed every wire into `elbowPath`'s straight-line fallback,
and the middle connector became a zero-length, invisible path. The card
rendered as three stray tick marks on every iPhone below Pro Max, and the
account cards overflowed the clip at 360px.
Use proportional widths with caps (`w-[36%] max-w-36` / `w-[52%] max-w-56`)
so ~12% of the pane is always reserved as horizontal run for the elbows.
Measured after: 29px gap at the 242px worst case, 34px at 360px, 50px at
1280px, no overflow and no degenerate paths anywhere in the range. The
account label now hides by container query rather than a viewport
breakpoint, which would gate on the wrong axis.
Also from review:
- Sandbox mock showed `composio.sandbox.run()` in a file chromed `sandbox.ts`.
Per content/docs/sandbox/remote.mdx — where the card links — the sandbox is
a persistent Python environment driven through COMPOSIO_REMOTE_WORKBENCH
with `run_composio_tool` / `invoke_llm`. Rewritten on that real surface and
relabelled `sandbox.py`; `WorkbenchVisual` renamed to `SandboxVisual`.
- `twilio` is not in public/data/toolkits.json, so the tile advertised an app
with no /toolkits page behind it. Swapped for `zendesk`.
- The dark logo was `aria-hidden`, so the heading's accessible name lost
"Composio" in dark mode only. Both variants now carry the same alt.
- Restored the badge style assertions the PR dropped, which still held, and
added regression coverage for the diagram widths, the catalog check, and
the sandbox surface.
- Restored the window resize listener that connection-refresh-visual.tsx
keeps alongside its ResizeObserver.
- Nits: stale "8×2" comment, redundant fragment, shared the duplicated fade
style, renamed the misleading `homeIntentAnchor(title)` parameter.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Show the actual six-line quickstart snippet (`import Composio` + `import OpenAIAgentsProvider` + `new Composio({ provider })` + `composio.create(userId)` + `session.tools()` + `new Agent({ … })`), tightened to 11.5px / 1.75 leading so it fits inside the same left-pane height as the For You card.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two-ways-to-start hero: cards now lead with the canonical Composio + product-badge lockup (dashboard-parity) and the same product mocks the dashboard onboarding path step uses — a chat composer flanked by client logos for For You, a code panel for Platform. Right link pane width matches a feature-grid card exactly.
Features grid: whole-card links restored, each mock fades into the card edge with a mask-image, cards live on a single flush bg-fd-card surface. Tools mock bumps from an 8×2 grid of 16 tiles to 10×3 = 30 for more impact, Auth becomes a live schematic — one user identity card wired to three connected-account cards via elbow connectors computed from real DOM geometry (`home-auth-diagram.tsx`), Triggers drops the fake LIVE ping in favor of a plain event list, Sandbox drops the workbench chrome + CPU lights for a clean filename + code panel.
Resources: adds a Platform Dashboard link so the 3×2 grid is complete. Drops the "Get started / What you get / Reach for the rest" eyebrows and section heading — headings stand on their own.
Copy: `audience` → `product`, so llms.txt emits `**Platform**` / `**For You**` instead of `**Platform**` / `**For you**`; matched in `home-navigation.test.ts`.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Review follow-ups on the docs_sidebar_click instrumentation.
usePostHog() resolves to the posthog-js module singleton whether or not a
provider is mounted, so the `!posthog` guard never fired: with no
NEXT_PUBLIC_POSTHOG_KEY the listener still attached and every sidebar
click called capture() on an uninitialized instance, logging "You must
initialize PostHog before calling posthog.capture". Gate the effect on
the same env var components/posthog-provider.tsx gates on.
position threaded through folder recursion, so a collapsed folder's
hidden children counted as rows: Triggers is the 4th visible row under
Core concepts but reported 11, which would inflate any "clicks land in
the top N rows" reading — the same inference error this instrumentation
exists to remove. Count per level instead, so a folder occupies one row
for its siblings and its children get their own 1..n sequence. Making
group and position per-level locals also removes the latent collision
where a separator nested in a folder reset the counter for the folder's
siblings; a test pins that case.
Also: capture auxclick (middle button only) so sidebar links opened in a
new tab are not missing while Cmd/Ctrl+click ones are counted; a folder
with a non-string name now reports folder: null rather than inheriting
its parent's label; and both reference layouts memoize the index instead
of rebuilding it on every render.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The docs app had exactly one posthog.capture call ($pageview), so any
question about how people move through the sidebar had to be answered by
reverse-engineering pageview ordering within a session. $referring_domain
is no help either: pageviews are captured manually on client-side route
change, so document.referrer never updates on internal navigation.
Adds a docs_sidebar_click event carrying href, group, folder, depth,
position and from_path. Group/folder/depth are derived from the fumadocs
page tree at build time and the click handler only does an href lookup —
reading them off the rendered sidebar would mean depending on separators
being <p> and folder triggers being <button>, which is fumadocs-internal
and breaks on upgrade.
Mounted on the docs, examples and both reference sidebars. Nothing fires
when PostHog is unconfigured, for non-sidebar links, or for an href that
is not in the index.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This PR:
- fixes
[UXE-233](https://linear.app/composio/issue/UXE-233/docs-should-explicitly-direct-agents-to-use-v31-apis)
- makes the agent-facing Markdown channels publish concrete REST v3.1
base URLs and endpoint tables while preserving the supported v3.0
reference tree
- centralizes `REST_VERSION_GUIDANCE`, `TOOL_VERSION_GUIDANCE`, and
raw-spec path matching in `lib/api-version-guidance.ts`
- renders `ApiBaseUrl` and `ApiEndpointsTable` in authored MDX and adds
an explicit version pointer to generated OpenAPI operation Markdown
- separates current and legacy REST references in `llms.txt`, excludes
v3.0 page bodies from `llms-full.txt`, and adds v3.1 selection guidance
to Context7
- validates serialized `ApiEndpointsTable` payloads with Zod before
generation while preserving forward-compatible fields
- addresses review feedback for the renamed authentication page,
SDK-reference pointer scope, generator validation behavior, and stale
OpenAPI tool-version descriptions
## Context
REST v3.0 is superseded but remains supported for existing integrations.
This PR changes what new agent-generated code discovers first; it does
not require existing v3.0 callers to migrate.
Authenticated read-only probes against the deployed API confirmed that
the affected v3 endpoints default to `00000000_00`, while their v3.1
counterparts default to `latest`. `POST /tools/scopes/required` is
available only on v3.1 and defaults to `latest`.
This PR does not move public URLs. A future `/reference/v3/` to
`/reference/v3.0/` migration remains separate because it has independent
compatibility and search-indexing risk.
## Verification
- `bun test tests/static/`
- `bun run build`
- `bun run test:integration`
- `bun run types:check`
- `bun run lint`
## Review follow-up
The version-default guidance is intentionally limited to the five
verified tool endpoints. v3.1 is a structural superset of v3, so this PR
does not claim route parity. Static coverage rejects broad non-tool
parity wording in both the shared guidance and Context7 rules.
This PR:
- builds on top of https://github.com/ComposioHQ/composio/pull/3966
- enables `typescript/no-explicit-any` (error, `fixToUnknown`) for docs
in `docs/.oxlintrc.json` and removes every remaining explicit `any` in
docs code
- parses untyped/external data once at the boundary with zod v4 schemas
and lets `z.infer` types flow downstream — no hand-rolled `'x' in obj`
guard chains, no `as`-casts of untyped page data, no
`docs/lib/unknown-value.ts`
- adds domain schema modules: `docs/lib/toolkit-schema.ts` (recursive
JSON-Schema node, raw tool/trigger payloads, list envelopes) and
`docs/lib/reference-page-data.ts` (fumadocs reference page data for both
reference routes)
- rewrites `validate-links.ts`, `generate-toolkits.ts`,
`generate-meta-tools.ts`, the `llms.mdx` route, and
`deprecated-api-sidebar.tsx` on those schemas with identical validation
outcomes
- carries the pure typing improvements from the earlier attempt (typed
reference source in `source.ts`, `LLMPage`/`PageLike`, typed
`ClientLogo[]` in `logo-bar.tsx`, component `any` removals)
- adds `tests/static/toolkit-schema.test.ts` and
`tests/static/generate-toolkits.test.ts` pinning the transform shapes;
no changeset (docs is not published)
## Context
Second of the three-PR split of #3958, replacing its rejected
structural-guard approach with zod schemas at the data boundaries.
Verified with `bun run lint`, `bun run types:check`, `bun test
tests/static/` (125 pass), `bun run lint:links`, and a full `next
build`.
## Review follow-up
Addressed the regressions reported in [the Zod boundary
re-review](https://github.com/ComposioHQ/composio/pull/3967#issuecomment-5105279224):
scalar JSON Schema enums and auth defaults are preserved as strings,
malformed toolkit page envelopes abort generation, and the pre-refactor
empty-string fallbacks are restored. Regression coverage lives in
`tests/static/toolkit-schema.test.ts` and
`tests/static/generate-toolkits.test.ts`.
Verified on `2f26c40be` with `bun test tests/static/` (125 pass), `bun
run types:check`, and `bun run lint` (0 errors; existing warnings only).
This PR:
- replaces ESLint with oxlint across the pnpm workspace and the
Bun-based docs site, porting the rules to `.oxlintrc.json` /
`docs/.oxlintrc.json` with behavior parity (restricted-syntax selectors
kept via `oxlint-plugin-eslint`)
- migrates typecheck to TypeScript 7 (`typescript@^7.0.2` catalog) and
keeps a TS6 pin for JS compiler API consumers via a named `ts6` pnpm
catalog (`ts/scripts/validate-examples.ts`, the `@composio/cli` generate
pipeline). The CLI's `typescript` dependency rebinds only the
compiler-API import — its typecheck still runs the root TS7 `tsc`, since
the alias package only ships a `tsc6` bin (documented in
`ts/packages/cli/AGENTS.md`)
- removes the `paths` mappings that pointed `@composio/core` (and, in
`experimental`, `@composio/json-schema-to-zod` plus core-internal
`#`-imports) at sibling `src` directories: under TS7, tsdown's
tsgo-based dts step emitted stray `.d.ts` files next to those
out-of-root sources on every dependent package build. Workspace deps now
resolve through their built dist types, which turbo's `dependsOn:
^build` already guarantees exist — and which the deep-path exports
(`@composio/core/*`) always used anyway
- renames the cli boundary tooling `eslint-boundaries*` →
`lint-boundaries*` and hardens the scanner to reject `oxlint-disable`
spellings so the disable manifest cannot be bypassed
- rewrites inline `eslint-disable` comments to oxlint rule names
(comment-only; no runtime changes), and adds **one new** declared
boundary: `tool-file-uploads.ts` needs `no-restricted-imports` disabled
for `node:crypto` (MD5 for the presigned-upload checksum is not in Web
Crypto), because oxlint also catches dynamic `await import()` where
ESLint did not. The manifest grows 46 → 47 deliberately
- updates CI path filters, `turbo.jsonc` lint inputs, and the docs
typescript-check workflow (renamed to "Docs - Lint and TypeScript
Validation" since it now lints too); drops `eslint`,
`typescript-eslint`, `eslint-config-next`, and `globals` from the
dependency graphs
- ships no changeset: I built `@composio/core` and `@composio/anthropic`
on this branch and on the pre-migration base and diffed the emitted
`dist/**/*.d.mts`. The provider output is byte-identical. Core's output
is **semantically identical but not byte-identical**: TS7 changes quote
style (`"x"` → `'x'`), object-property and union-member ordering in
inferred types, and picks equivalent shorter re-export alias paths for
five signatures (e.g. `OpenAI.Beta.Threads.Runs.Run` →
`OpenAI.Beta.Threads.Run` — verified both names alias the same type in
the shipped typings). Chunk-name hashes shift as a consequence. No type
gains, losses, or shape changes; `attw` and `publint` pass on the TS7
build
## Context
First of a three-PR split of #3958. The type-safety refactors are
stacked on this branch and merge after it:
- docs: https://github.com/ComposioHQ/composio/pull/3967
- `@composio/core`: https://github.com/ComposioHQ/composio/pull/3968
## Summary
- upgrades `fumadocs-openapi` 10 → 11, `fumadocs-mdx` 14 → 15, and
`fumadocs-core` / `fumadocs-ui` 16.4 → 16.13
- migrates the Fumadocs OpenAPI API while preserving the custom schema
renderer
- restores local `$ref` resolution in both the visible API schema UI and
generated LLM markdown
- reduces API-reference client payloads by slicing the bundled OpenAPI
document to each page's reachable operations and components
- restores required badges for GET parameters
- normalizes the OpenAPI `no_auth` sentinel so explicitly public
endpoints render without authentication
- moves to `getOpenAPIPageProps()` / `OpenAPIPageProps` and removes
obsolete CSS overrides
## Correctness fixes
Fumadocs 11 changed the page contract from a server-resolved document id
to a client-side bundled document. That exposed several silent
regressions:
- **Reference resolution:** bundled documents retain local `$ref`s. The
LLM renderer now dereferences them, including alias chains and cycles,
while the custom schema renderer uses Fumadocs' resolver and retains raw
reference identity for stable deduplication.
- **Dereference reuse:** repeated LLM-page requests reuse the
dereferenced copy for each cached bundled document instead of walking
the complete spec per page.
- **Client payload size:** each API page now receives only its selected
operations and transitively reachable components. The slicer falls back
to the complete document for non-component pointers, deep component
pointers, missing operations, or dangling references.
- **Required badges:** `readOnly` cannot distinguish GET inputs from
responses. The renderer now uses the page hook's client name to identify
responses.
- **Recursive rendering:** schema markdown rendering now caps both
structural recursion and nested array type rendering.
- **No-auth normalization:** the undeclared `no_auth` sentinel is
removed without discarding any real security alternatives that may
accompany it.
- **Contract drift:** code consuming `getSchema()` now treats `bundled`
as required, matching the upstream type.
Review follow-up also replaces the new OpenAPI `any` types with typed
Fumadocs page props and a narrow recursive schema model. Historical
Fumadocs 10/11 migration explanations live here in the PR, not as
version-specific source comments; source comments retain only durable
invariants.
## Payload impact
| | before | after |
| --- | --- | --- |
| bundled document | 451 KB | 7.7 KB avg / 30 KB worst |
| served page HTML | 693 KB | 198 KB |
| 10-page sample | 6.55 MB | 2.02 MB (69% smaller) |
## Verification
- `bun install --frozen-lockfile`
- `bun run test` — 89 pass
- `bun run lint:links` — 0 errors
- `bun run lint` — 0 errors (77 existing warnings)
- `bun run types:check`
- `bun run build`
- production server + `bun run test:integration` — 74 pass, including
v3.1/v3 API pages, redirects, search, and LLM endpoints
The production build has one existing Turbopack NFT tracing warning from
`next.config.mjs`; it does not fail the build.
## Production vs preview checks
A live sample comparison between [production](https://docs.composio.dev)
and the [PR
preview](https://docs-git-chore-docs-fumadocs-11.preview.composio.dev)
found no docs regression:
- all 14 representative routes returned 200 with matching titles,
headings, canonical production URLs, and key content
- redirects for `/`, `/api-reference`, `/tools`, and `/docs/welcome`
matched exactly
- the sampled pages exposed the same 1,137 internal-link targets; a
balanced sample of 29 links resolved successfully on both deployments
- sampled v3 and v3.1 OpenAPI pages retained endpoint paths, required
fields, response schemas, and legacy indicators
- the generated OpenAPI LLM page was byte-for-byte identical
- selecting TypeScript in a hydrated browser rendered both inactive-tab
examples and synchronized the language tab groups
- `llms.txt` retained the same 139 unique lines in a different order
- `/docs/quickstart.md` only added an explicit `[#next]` heading anchor
The sampled OpenAPI HTML was roughly 35–42% smaller in the preview,
consistent with document slicing rather than missing rendered content.
This PR:
- follows up on https://github.com/ComposioHQ/composio/pull/3838
- renders the existing `Legacy` badge in v3 and v3.1 endpoint headers
when the OpenAPI operation has `deprecated: true`
- centralizes deprecated-endpoint badge copy across API overview tables
and detail pages
- adds static coverage plus running-server assertions for the reported
routes and active control endpoints
- verifies the fix with `bun run test`, `bun run types:check`, `bun run
lint:links`, `bun run build`, and the focused integration suite
Tag every dashboard.composio.dev link in authored docs content and
components with utm_source=docs plus utm_medium/utm_campaign, and enforce
the convention going forward: an ESLint no-restricted-syntax rule covers
TS/TSX and a static bun test covers MDX (runs in docs-tests CI).
- content links use utm_medium=content and utm_campaign=<page-slug>
- content/reference is excluded (generated upstream)
- delete unused landing-hero/_stub-links.ts
- fix the no-html-link-for-pages errors; downgrade the pre-existing
react-hooks compiler violations to warnings until burned down, so
bun run lint exits with zero errors
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
## Summary
Deprecated REST endpoints now surface the existing `Legacy` badge in
generated API-reference indexes, with endpoint-specific tooltip copy
instead of the Sessions-specific default. The generator behavior is
covered end to end for both v3 and v3.1, including rendered table
output.
This branch also restores CI compatibility with the organization Actions
policy: workflow tool versions still come from `mise.toml`, but
installation uses the approved, SHA-pinned setup actions. Secret
scanning pins the repaired organization reusable workflow from
ComposioHQ/.github#13.
## Changes
- Read the OpenAPI `deprecated` flag and emit `legacy: true` only for
deprecated operations.
- Render `LegacyBadge` on affected endpoint rows with accurate lifecycle
tooltip copy.
- Regenerate the affected `files` and `connected-accounts` indexes for
v3 and v3.1.
- Cover the real generator output, active-operation omission, badge
count, and tooltip through a focused regression test.
- Replace disallowed transitive Actions dependencies while retaining
`mise.toml` as the single tool-version source.
Endpoint detail pages continue to use `fumadocs-openapi`'s built-in
deprecated marker. The indexed endpoints are `GET /files/list` and `POST
/connected_accounts/{nanoid}/refresh`; internal operations remain
filtered from the docs.
## Spec data
The committed OpenAPI snapshots lagged the live backend for `POST
/connected_accounts/{nanoid}/refresh`. Both snapshots now carry its
current summary, description, and `deprecated: true`; the next
`fetch-openapi.mjs` run will preserve that state from the live spec.
## Validation
- `bun run test`: 25 passed, 0 failed.
- `bun run types:check`: passed.
- Focused ESLint and generated-index drift checks: clean.
- Composite-action and workflow YAML parsed successfully; extracted tool
pins match `mise.toml`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: jkomyno <alberto@composio.dev>
## What
Two changes to the docs install experience:
**1. Package-manager picker on install code blocks.** New
`PackageInstall` client component
(`docs/components/package-install.tsx`): the code block's copy button
opens a dropdown of package managers. Selecting one rewrites the
displayed command and copies it to the clipboard.
- TypeScript blocks: npm (default, `npm install`) / pnpm / bun / yarn
(`<pm> add`)
- Python blocks: uv (default, `uv add`) / pip (`pip install`)
- The menu is portaled to `document.body` so it isn't clipped by the
`Tabs`/`CodeBlock` overflow containers, and closes on outside click,
Escape, or real scroll movement.
**2. `@composio/slim` callout in the quickstart.** The quickstart
TypeScript install blocks carry display-only `#` comment lines noting
that `@composio/core` ships its docs and TypeScript source in the
package (inspectable to coding agents) and that `@composio/slim` is the
smaller install with the same API. Comment lines are rendered muted and
are **never copied** — the picker copies only the command.
## Where
Converted every plain `npm install` / `pip install` code block under
`docs/content` (quickstart, all provider pages, single-toolkit MCP,
custom tools, migration guides, standup example, SDK reference indexes).
The TS reference index's manual npm/pnpm/yarn/bun tabs collapse into one
picker. The two SDK-reference generators
(`ts/packages/core/scripts/generate-docs.ts`,
`python/scripts/generate-docs.py`) emit the new component so
regeneration keeps it. Flagged upgrade commands (`pip install
-U/--upgrade`) and the bun-first examples were left as-is.
## Verification
- `bun run types:check` — pass
- `bun run build` — pass
- `eslint` on touched TS files — clean (remaining repo lint errors are
pre-existing on `next`)
- Visual check via dev server + browser: comment lines render muted
below the command, picker opens npm/pnpm/bun/yarn (uv/pip on Python
tabs), selecting a manager rewrites the command, and the clipboard
receives exactly the command with no comment lines.
Docs-only behavior change; no changeset (generator-script edits don't
touch published code).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This PR:
- supersedes https://github.com/ComposioHQ/composio/pull/3642 and
credits @shamsharoon for the original Eve provider and iMessage work
- rebases the integration onto the current `next` branch and resolves
its lockfile conflicts
- publishes an isolated `@composio/experimental/eve` entry with the
correct Eve 0.12+ peer contract
- adds recoverable per-session discovery, native Eve context
propagation, and durable approval policies for direct and batched side
effects
- centralizes circular-safe auth-link extraction across Eve and Pi and
replaces dense conditional expressions with named control flow
- hardens the iMessage example against `osascript` option injection,
unsafe trigger scoping, and third-party prompt injection
- preserves completed local-tool results when a mixed local/remote batch
loses its remote transport
- consolidates the example documentation onto shared components,
documents direct model-provider credentials, and clarifies that the
browsable source is not yet a standalone fixture
- verifies the change with 999 core tests, 32 experimental tests,
package builds/typechecks, packed peer-isolation smokes, and a
production docs build
---------
Co-authored-by: shams haroon <144290365+shamsharoon@users.noreply.github.com>
Co-authored-by: shams haroon <shamsharoon7@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: shams haroon <shams@composio.dev>
Follow-up doc fixes from a re-audit of the June "Pi Slack-bot friction"
report against the current docs. Low-risk changes across the migration
guides, the example `.md` output, and legacy handling.
## 1. Migration guides: selective legacy + a "Written {date}" stamp
Migration guides are point-in-time documents, but not all are legacy.
Two mechanisms, decoupled:
- **`legacy: true`** (existing Legacy badge) — only on guides that
migrate off something dead: **new-sdk** (deprecated v1 SDK) and
**tool-router-beta** (removed experimental tool router).
- **`written: "{Month YYYY}"`** (new frontmatter field, dates from git
creation) — renders a standalone **"Written {date}"** stamp on *every*
guide, independent of legacy. So current guides (direct-to-sessions,
mcp-servers-to-sessions, toolkit-versioning, the hub) show their date
without being mislabeled legacy.
Files: `source.config.ts` (new `written` field),
`components/legacy-badge.tsx` (plain badge again), docs page (badge +
date row), 6 migration guides.
## 2. Real example code now in the `.md`/llms output
`<FileBuildup>` / `<RepoBrowser>` render an example's actual source
(`bot.ts`, `install.ts`, …) interactively, but they're React components
that don't serialize to markdown — so
`examples/general-agent-with-pi.md` (what an agent fetches) had all the
prose and **no code**. `mdxToCleanMarkdown` now resolves them from the
`FILE_BUILDS` registry. That example's `.md` grows **6.5 KB → 34 KB**
with the real
`createSessionTools`/`proxyExecute`/`waitForConnections`/`verifyWebhook`
code. Also fixes standup-slackbot and local-workbench.
## 3. Legacy pages: flag in `.md`, skip the current-pattern guardrail
`getLLMText` now prepends "Legacy · written {date}" (or "Written {date}"
for current-dated pages) to the `.md`, and **skips the "enforce ONLY the
current patterns" guardrail block on legacy pages** — appending it to a
legacy guide contradicted the guide's own older content (e.g. new-sdk
showing `tools.execute()` as the v3 target).
## 4. Note that `subscribe()` uses Pusher under the hood
Short aside on the triggers subscribe doc, for readers on runtimes that
restrict WebSocket clients.
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## Summary
- Switch the docs Eve agent from the AI Gateway `openai/gpt-5.4-mini`
string to an Inception Labs Mercury 2 OpenAI-compatible chat model.
- Keep tool calling on the chat-completions path and pass Mercury's
`reasoning_effort=medium` through the AI SDK OpenAI adapter.
- Add `DOCS_AGENT_MODEL_FLOW` so the same agent can run either `mercury`
or the old AI Gateway flow for eval comparisons.
- Add docs-agent eve evals covering grounded docs answers, docs
retrieval, citations, and account-specific support refusal.
- Replace the docs-agent retriever with an in-process BM25-style lexical
ranker that returns bounded full content for the top results, so Mercury
gets rich context in one fast tool call instead of a serial
`search_docs` → `read_doc` round trip.
- Precompute BM25 term counts/document frequencies into the generated
`agent/lib/docs-index.ts` snapshot at build time, removing deployed
cold-start corpus construction while keeping retrieval in-process.
- Add opt-in search perf logging (`DOCS_AGENT_SEARCH_PERF_LOG=1`,
optional `DOCS_AGENT_SEARCH_LOG_QUERY=1`) with timings for tokenization,
corpus load/cache, ranking, hydration, total duration, corpus source,
and top URLs.
- Add `eval:agent` and `eval:agent:flows` scripts; `eval:agent:flows`
can run local model-flow comparisons or remote target comparisons via
`DOCS_AGENT_EVAL_TARGETS`.
- Add `INCEPTION_API_KEY` / optional Mercury and gateway model knobs to
`docs/.env.example`, and move `@ai-sdk/openai` to runtime dependencies
for the agent import.
## Notes
- This is intentionally an experiment to see how Mercury's diffusion
model behaves with Eve tool calling (`search_docs` and `read_doc`).
- Preview/runtime environments need `INCEPTION_API_KEY`;
`INCEPTION_MODEL` and `INCEPTION_BASE_URL` are optional overrides.
- The custom fetch prevents accidentally falling back to
`OPENAI_API_KEY` against Inception's endpoint.
- The docs search is lexical/in-memory, not vector search. The slow path
was mostly serial model/tool round trips and cold index construction,
not embedding lookup.
- The generated BM25 snapshot is process-local once loaded: warm for the
lifetime of the running Node/Vercel function instance, and reset on cold
starts, redeploys, or process restarts. The expensive term-count corpus
is now built at docs build time.
- Perf logs omit raw user queries by default; set
`DOCS_AGENT_SEARCH_LOG_QUERY=1` only when you explicitly want raw
query/term logging.
- Local A/B-style eval run:
```bash
DOCS_AGENT_EVAL_FLOWS=gateway,mercury bun run eval:agent:flows --
--strict
```
- Live target comparison:
```bash
DOCS_AGENT_EVAL_TARGETS=baseline=https://<prod>,mercury=https://<preview>
bun run eval:agent:flows -- --strict
```
## Tests
- `bunx eslint scripts/build-agent-index.ts agent/lib/docs.ts
agent/tools/search_docs.ts`
- `bun scripts/build-agent-index.ts` (wrote 133 pages + 1000 toolkits +
1139 BM25 rows)
- `DOCS_AGENT_SEARCH_PERF_LOG=1 EVE_FORCE_BUNDLE=1 bun -e "const
tool=(await import('./agent/tools/search_docs.ts?log=' +
Date.now())).default; await tool.execute({query:'create a session with
github tools'}); await tool.execute({query:'auth config connected
account'});"` (logs cold and warm timing JSON)
- `EVE_FORCE_BUNDLE=1 bun -e "const tool=(await
import('./agent/tools/search_docs.ts?bundle=' + Date.now())).default;
const started=performance.now(); const r=await
tool.execute({query:'create a session with github tools'});
console.log(r.retrieval, r.results[0].url, r.results[0].content.length,
Math.round(performance.now()-started)+'ms');"` (precomputed bundle path,
~12ms)
- `bun -e "const tool=(await import('./agent/tools/search_docs.ts?live='
+ Date.now())).default; const started=performance.now(); const r=await
tool.execute({query:'create a session with github tools'});
console.log(r.retrieval, r.results[0].url, r.results[0].content.length,
Math.round(performance.now()-started)+'ms');"` (live-content path,
~34ms)
- `EVE_FORCE_BUNDLE=1 bun -e "const tool=(await
import('./agent/tools/search_docs.ts')).default; await
tool.execute({query:'create a session with github tools'}); const
started=performance.now(); const r=await tool.execute({query:'auth
config connected account'}); console.log(r.results[0].url,
r.results[0].content.length,
Math.round(performance.now()-started)+'ms');"` (warm path ~2ms)
-
`PATH=/Users/cryogenicplanet/.vite-plus/js_runtime/node/24.15.0/bin:$PATH
./node_modules/.bin/eve info --json` (reports `status: ready`, `model:
inception/mercury-2`, `errors: 0`)
- `DOCS_AGENT_MODEL_FLOW=gateway
PATH=/Users/cryogenicplanet/.vite-plus/js_runtime/node/24.15.0/bin:$PATH
./node_modules/.bin/eve info --json` (reports `status: ready`, `model:
openai/gpt-5.4-mini`, `errors: 0`)
-
`PATH=/Users/cryogenicplanet/.vite-plus/js_runtime/node/24.15.0/bin:$PATH
./node_modules/.bin/eve eval --list`
-
`PATH=/Users/cryogenicplanet/.vite-plus/js_runtime/node/24.15.0/bin:$PATH
bun scripts/eval-agent-flows.ts --list`
- `bun test tests/static/` (16 passed)
- `bun run types:check` currently fails on existing docs type-generation
errors in `app/(home)/docs/changelog/[...slug]/page.tsx`,
`app/(home)/examples/[[...slug]]/page.tsx`,
`app/(home)/toolkits/[[...slug]]/page.tsx`,
`app/llms.mdx/[[...slug]]/route.ts`, `lib/search-index.ts`, and
`lib/source.ts`; no new eval or `docs/agent/agent.ts` errors were
reported.
## Not run
- Real live model evals, because this local environment does not have
`INCEPTION_API_KEY` or AI Gateway credentials.
## Latest update
- Added default eager docs retrieval in the Eve HTTP channel: the server
runs the same BM25 search on the user's message before the first model
step and injects the results as one-turn context.
- Kept `search_docs` and `read_doc` available so Mercury can still
search/read more when the eager context is weak, ambiguous, or missing.
- Added `DOCS_AGENT_EAGER_SEARCH=0` as an escape hatch and labeled perf
logs with `invocation: "eager_context" | "tool"`.
- Updated the loading copy from “Searching the docs…” to “Thinking with
the docs…” so UI latency is not attributed solely to the search call.
## Latest tests
- `bun run lint -- agent/channels/eve.ts agent/tools/search_docs.ts
agent/lib/docs-search.ts components/eve-chat.tsx
evals/docs-agent/grounded-answers.eval.ts`
-
`PATH=/Users/cryogenicplanet/.vite-plus/js_runtime/node/24.15.0/bin:$PATH
node_modules/eve/bin/eve.js info --json` (reports `status: ready`,
`errors: 0`)
- `DOCS_AGENT_SEARCH_PERF_LOG=1 EVE_FORCE_BUNDLE=1 bun -e "import {
searchDocs } from './agent/lib/docs-search'; const r = searchDocs('How
do I create a session in Composio? Keep it brief.', { invocation:
'eager_context' }); console.log(JSON.stringify({count:r.results.length,
top:r.results[0]?.url, content: !!r.results[0]?.content}, null, 2));"`
- `DOCS_AGENT_SEARCH_PERF_LOG=1 bun -e "import { searchDocs } from
'./agent/lib/docs-search'; searchDocs('How do I create a session in
Composio? Keep it brief.', { invocation: 'eager_context' });
searchDocs('How do I create a session in Composio? Keep it brief.', {
invocation: 'tool' });"`
- `bun run types:check` still fails only on the pre-existing docs
type-generation issues listed above.
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## The bug
The live Algolia index was renamed to **`docs_composio`**, but every
default in the repo still pointed at the old
**`docs_composio_dev_62hi9pqz1l_pages`** in three places:
1. `.github/workflows/docs-search-sync.yml` — `ALGOLIA_INDEX_NAME`
fallback
2. `docs/lib/search-index.ts` — `ALGOLIA_DEFAULT_INDEX_NAME` (used by
the sync script)
3. `docs/components/custom-search-dialog.tsx` — client query fallback
(×2)
So unless the `ALGOLIA_INDEX_NAME` Actions variable happened to be set,
the **docs-search-sync** workflow rebuilt the dead old index on every
push to `next`, while the live site queried a different one. Net effect:
search index updates never showed up.
## The fix
Repoint the default to `docs_composio` in all three spots (+ README /
CLAUDE.md docs). The env overrides still take precedence, so nothing
breaks if a variable is set.
## Env to set (so it actually publishes & reads the right index)
The code now defaults to `docs_composio`, so the only things that
**must** be configured:
**GitHub Actions (repo → Settings → Secrets and variables → Actions):**
- `ALGOLIA_ADMIN_API_KEY` *(secret, required)* — without it the workflow
skips the sync.
- `ALGOLIA_APP_ID` *(variable, optional)* — defaults to `62HI9PQZ1L`.
- `ALGOLIA_INDEX_NAME` *(variable, optional)* — now defaults to
`docs_composio`; set only to override.
**Vercel (Production env) — for the live search to query the same
index:**
- `NEXT_PUBLIC_ALGOLIA_SEARCH_API_KEY` *(required; without it the client
falls back to `/api/search`)*
- `NEXT_PUBLIC_ALGOLIA_APP_ID` = `62HI9PQZ1L` *(optional, defaulted)*
- `NEXT_PUBLIC_ALGOLIA_INDEX_NAME` = `docs_composio` *(optional now that
the default matches; set it to be explicit)*
> If `NEXT_PUBLIC_ALGOLIA_INDEX_NAME` was previously set to the old name
in Vercel, update or remove it — otherwise the client keeps reading the
old index regardless of this PR.
## Testing
- `bun run types:check` passes.
- `grep` confirms no remaining references to the old index name.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
## What
Reworks the `/examples` index into a Modal-style **featured gallery**,
styled to the Composio brand (pulled from `~/composio/landing`): flat
editorial cards, sharp corners, mono uppercase category tags in accent
colors, the signature brand offset-shadow on hover, and real toolkit
logos on white chips.
| Light | Dark |
|---|---|
| Big `font-sans` hero, filter pills with live counts, responsive card
grid | Same, brand-consistent |
### Highlights
- **`<ExamplesGallery>`** — hero, category filter pills (Featured /
General agents / Background agents / Coding agents) with live counts,
responsive 1–3 col grid, staggered load-in.
- **Data-driven from frontmatter.** Card title/description come from
each page's own `title`/`description`. Presentation metadata lives in a
new optional `gallery` block in the frontmatter schema:
```yaml
gallery:
categories: [General agents, Background agents]
logos: [slack]
featured: true
order: 0
```
Examples can belong to **multiple category lanes** (the Pi bot is both
General + Background).
- The index route renders the gallery; nested example pages keep the
standard docs renderer.
### Drive-by fix
`PageActions` lifts a **full-width** row over the page title (`-mt-12`)
to place the "Copy page" button beside it. That invisible overlay sat on
top of the title and blocked selecting/copying it. Fixed by making the
overlay `pointer-events-none` and re-enabling them only on the button
wrapper. Affects every docs page.
## Testing
- `bun run types:check` passes.
- Verified in light + dark: titles/descriptions match page frontmatter,
multi-tag cards, filter counts, logo visibility (GitHub on white chips),
title now selectable, Copy button still clickable.
## Notes
- Category lanes are a fixed enum in two spots (`source.config.ts` enum
+ `CATEGORY_STYLES` color map in `examples-gallery.tsx`) — adding a new
lane is a two-place edit.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Integration branch for the next docs release: a **sessions-first
documentation rewrite** — new and rewritten guides, example pages,
interactive components, and docs tooling — plus the supporting SDK
changes that the new docs describe.
The bulk of this PR is docs (~24k lines across ~150 commits); the SDK
changes (~5k lines) back the new guides.
## Documentation (the bulk)
- **Sessions-first restructure** — reorganized navigation and section
structure (incl. the "Sandbox (prev workbench)" section), with
v3-reorganization redirects so old URLs keep resolving.
- **Rewritten core guides** — quickstart, configuring sessions, triggers
(creating + subscribing to events), proxy-execute, toolkits
enable/disable, and common FAQ, rewritten in the house voice.
- **New example pages** — local-sandbox PR reviewer, daily standup bot,
and slack bot, with runnable build-ups.
- **New interactive components & diagrams** — triggers flow animation,
manage-connections visual, connection-refresh visual, and the
terminal-kit components.
- **Docs tooling** — a docs-graph link-graph connectivity checker,
search reprioritization (deprioritize legacy pages), and SDK-reference
regeneration.
## Supporting SDK changes
**`@composio/core` → 0.13.0 (minor)**
- `composio.sessions.create()` as the first-class sessions API
(`composio.create()` kept as an alias).
- **MCP is opt-in:** default `create()` / `use()` return native-tool
sessions (`SessionWithoutMcp`); pass `{ mcp: true }` to surface
`session.mcp`. _Migration: read `session.mcp` only after creating with
`{ mcp: true }`._
- `session.sandbox` is the canonical resolved config;
`session.workbench` kept as a deprecated alias. `sandbox` is the
preferred session-config key (`workbench` still accepted).
- `connectedAccounts.updateAcl()` graduated from experimental (alias
kept).
- `triggers.parse()` (parse + optionally verify an incoming webhook) and
`triggers.setWebhookSubscription()`.
**`@composio/experimental` → minor** — local-workbench helpers moved
onto the `@composio/experimental/workbench` subpath (out of
`@composio/core/experimental`), keeping the ~14 KB embedded Python
helper out of core. Plus the experimental Pi provider.
**`@composio/slim` → minor.**
**Python → 0.17.0** — mirrors the TS surface: `composio.sessions` mount
(`tool_router` deprecated), `triggers.parse()` /
`set_webhook_subscription()`, the `sandbox` config key, and
`connected_accounts.update_acl()`.
## Review response (#3664)
Addressed the `@composio/core` review:
- **Security:** `triggers.parse()` no longer fails open — a
present-but-empty `verifySecret` (e.g. unset `COMPOSIO_WEBHOOK_SECRET`)
now throws instead of silently skipping verification; omitting it stays
an explicit opt-out (both SDKs).
- Removed snake_case leakage from `transformWebhookSubscription` (+ the
index signature that allowed it).
- **Removed** the TS-only `connectedAccounts.link()` toolkit
auto-resolve (shipped with cancellability / orphaned-auth-config bugs
and was effectively undocumented; to be reintroduced properly later).
- Unified Python error types on `ValidationError`; added `mcp=True`
Python tests; fixed runtime-portability + error-type test assertions.
- Polished deprecation messages; fixed the backwards `/experimental`
`@deprecated` note and the `SessionWithMcp` JSDoc.
## Testing
- **TS:** `@composio/core` + `@composio/experimental` typecheck pass;
vitest green for the touched suites.
- **Python:** `test_tool_router.py` + `test_triggers.py` pass (161
tests).
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Kshitij Jhunjhunwala <kj@composio.dev>
Co-authored-by: Malay Vasa <malayvasa@gmail.com>
Co-authored-by: Sarah Simionescu <sarah@composio.dev>
Co-authored-by: Kshitij Jhunjhunwala <113939507+KJ-11@users.noreply.github.com>
## Summary
- stop loading the Decimal widget globally from the docs root layout
- load the Decimal script only when the user clicks Ask AI or uses the
shortcut
- preserve Decimal theme syncing after the widget has loaded
## Why
Slack/GSC investigation pointed at mobile CLS regressions on docs pages.
Lighthouse trace comparison isolated the layout shift to the Decimal
iframe/sidebar; blocking Decimal took /docs CLS from ~0.302 to 0, while
blocking PostHog did not change CLS.
## Validation
- bun run types:check
- bunx eslint app/layout.tsx components/ask-ai-button.tsx
components/custom-search-dialog.tsx components/decimal-widget.ts
- bun run test
- local Playwright check on http://localhost:3000/docs: no getdecimal
scripts or requests before interaction; after clicking Ask AI the
Decimal script loads and the sidebar opens
## Notes
- full `bun run lint` is still red on existing unrelated docs lint
issues on next, including @next/next/no-html-link-for-pages and
react-hooks compiler rules in other files
## Summary
- **Dark/light theme switcher** in the navbar. Drops `forcedTheme:
'light'` so the toggle actually flips themes; sidebar footer toggle
stays disabled so there's only one switcher.
- **Dark mode color pass.** `--composio-brand` lifts to a muted
`#5B8BF0` (the deep `#0007cd` brand reads as unlit text on `#0f0f0f`).
Card / muted greys nudge to `#1c1c1c` / `#1f1f1f`. Borders drop from 10%
white to 6% so card edges sit back. `--border` / `--sidebar-border`
follow suit.
- **Square navbar.** Search input and the new theme toggle render with
`border-radius: 0` to match the rest of the navbar.
- **Welcome-page scroll reset.** New `ScrollReset` client component
wired into the root layout. Next.js App Router skips its built-in scroll
reset when the new route resolves to the same dynamic `page.tsx` segment
— every link from the welcome page to a `/docs/*` page hits this case,
so users were landing mid-page on the new route. Now `usePathname()`
change ⇒ `window.scrollTo(0, 0)` (skips first render and any
hash-bearing navigation).
- **`platform.composio.dev` → `dashboard.composio.dev`** across docs
content + the direct-execution LLM guardrail (28 files).
`docs/public/openapi*.json` left alone — auto-generated, and the
surviving reference is literally to the legacy dashboard.
## Test plan
- [ ] Toggle theme from the navbar; verify both light and dark render
- [ ] In dark mode, confirm "Docs" nav active state, chip icons,
"CONNECTED" labels, and Ask AI button read clearly against `#0f0f0f`
- [ ] Scroll to the bottom of `/docs`, click any link in HomeResources /
HomeSurfaces / HomeFeatures — the new page should land at scroll 0
- [ ] Click a TOC `#anchor` link inside a docs page — should still
scroll to the anchor (not get clobbered to 0)
- [ ] Spot-check a few rewritten URLs in cookbooks / quickstart — all
`platform.composio.dev` should now be `dashboard.composio.dev`
🤖 Generated with [Claude Code](https://claude.com/claude-code)