The 07-31 changelog entry is already published on next and describes the
install-only default that composio.dev/install serves today. Rewriting it
in place would replace a live, accurate description with its opposite
under a date on which that behavior never shipped, and readers who
already saw it would get no notice of the flip.
Restore that entry verbatim and add a dated 08-05 entry carrying the
behavior-change callout, the auto/none bullets, and the created
~/.bash_profile disclosure.
The download-verification section moves to the new entry rather than
staying on 07-31: the strict abort is new here. The live installer warns
and continues when checksums.txt is missing -- the official_release_source
gate that turns that into an abort does not exist there.
Also scope the HTTPS claim, which is_allowed_http_authority contradicts
for loopback and COMPOSIO_INSTALL_ALLOW_HTTP_HOST; document the second
shape of the installer-created ~/.bash_profile, which survives the
documented uninstall when ~/.profile existed; and record the checksum
abort in INSTALL.md, where someone hitting 'Refusing to install' will
look for it.
Keeps this branch's fixture-driven managed-block reconciler
(reconcileManagedPathBlock, pinned byte-for-byte against install.sh's awk
rewrite by test/managed-block-fixtures) and drops next's narrower
replaceManagedPathBlock/applyFileChanges pair, which it supersedes.
Adopts from next: the narrowed unsafe-path character set on both the TS and
sh sides, the removal of the $PATH-reachability write skip, the hedged
no-shell PATH message, and the COMPOSIO_BIN_DIR command documentation.
Runtime testing during eval-rerun prep caught that toolkit_versions
'latest' is rejected by tools.execute() (ToolVersionRequiredError:
'"latest" is not supported in manual execution') — the guides recommended
it anyway; only the TS SDK reference documented the real behavior.
Per SDK team (Abir): pass dangerously_skip_version_check=True /
dangerouslySkipVersionCheck: true when running 'latest' manually. All
direct-execution samples now include the flag with a one-line comment;
the version-required callout explains both paths (skip-check for
LLM-consumed outputs, pinned via toolkits.get(slug).meta.version for
parsed outputs); the toolkit-versioning page's 'latest' claims are
corrected; the execute-version static test now fails any page showing
'latest' without the flag. Both patterns runtime-verified against the
live API before shipping.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
## Problem
Custom MCP docs don't mention logos, so developers don't know they can
replace the default Composio logo their toolkit shows in the dashboard
and on end-user connect screens.
## What this adds
A new "Add a toolkit logo" section on the Custom MCP page, after
registration: the `toolkit_config.logo_file` field (base64 `content` +
`mime_type`), a cURL example with a placeholder base64 value, the
constraints (PNG/JPEG, square 256-1024px, max 3MB, single-line base64),
the default-logo behavior when omitted, and the insert-only implication
that changing a logo means delete + re-register. Follows the docs
convention of language/OS-neutral examples.
## Testing
`bun run lint` (0 errors) and `bun run lint:links` (0 errors) from
`docs/`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_016x2W47caMs6zW4V8uu1M9g
Adds tests/static/execute-version.test.ts: any authored page whose code
fences call tools.execute() must show version configuration, and the LLM
guardrail blocks are held to the same rule. Fixes the five pages the
audit caught (sessions-vs-direct-execution, custom-auth-params,
before/after-execution-modifiers) which shipped version-less samples.
Changelog, generated reference, and migration guides are exempt as
historical/point-in-time records.
This is the durable half of eval finding 1: the content fix landed in
#3999; this test keeps future samples from regressing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Eval finding 3: 51/97 agents struggled to identify the right toolkit;
15 abandoned the docs for the raw REST API. Links the toolkits catalog
from the quickstart intro, adds a find-your-toolkit pointer to the
executing-tools and fetching-tools pages, and adds a discovery rule to
the direct-execution LLM guardrails.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The uninstall snippet now stages each startup-file rewrite in a 0600
mktemp file, promotes it only when the filter succeeds (preserving
symlinks, inode, owner, and mode), always cleans up, removes legacy
three-line blocks including the fish install-dir export, and deletes an
installer-created ~/.bash_profile left empty so bash regains its default
startup-file selection. A new suite extracts the snippet verbatim from
the docs and exercises it under sh and dash, wired into the install
script unit-test workflow.
Call out the breaking default change (curl | sh now edits startup files
and can create ~/.bash_profile), document COMPOSIO_INSTALL_SHELL=none as
the install-only opt-out, and align the verification claims with the
implemented checksum policy.
# Description
Customers evaluating Composio see references to **LLM tokens** and
assume Composio is handing them an agent/LLM that *replaces* their own —
i.e. that they'd be swapping their agent for ours. It isn't: Composio
discovers, authenticates, and executes tools; it never proxies the
customer's model or runs an agent on their behalf.
The one place Composio itself calls a model is **inside the sandbox**
(the optional `invoke_llm` helper + AI-assisted conveniences like error
correction). The sandbox is opt-in per session (`sandbox: { enable: true
}`), so this LLM usage is entirely optional and can be disabled.
This PR adds a short callout to the **Remote sandbox** docs page
(`docs/content/docs/sandbox/remote.mdx`) that says exactly that — placed
right where `invoke_llm` and the sandbox are introduced, with anchor
links to the `invoke_llm` helper, error correction, and session
configuration. It kills the "are they replacing my agent?" misconception
at its source.
The copy is deliberately accurate to today's state: it does **not**
claim we bill LLM tokens (sandbox billing is still upcoming and the
public pricing page only lists Tool Calls). It frames the point
conceptually — *your agent stays yours; the only Composio-side LLM usage
is optional and sandbox-scoped.*
**Follow-up surfaces (not in this PR — see below):** this same
clarification could be mirrored on the dashboard usage/billing UI and
the marketing pricing page when an "LLM tokens" line item actually
surfaces there. Those live outside this repo.
# How did I test this PR
- Docs-only change (single `.mdx` file); no code or dependency surface.
- Verified all anchor targets referenced in the new callout exist on the
same page / site:
- `#built-in-helpers` → `### Built-in helpers` (the `invoke_llm` row)
- `#error-correction` → `### Error correction`
- `/docs/configuring-sessions` (existing page; documents `sandbox: {
enable: true }`)
- Matches the existing `<Callout title="...">` component usage already
on the page (the "Renamed from workbench" callout), so it renders
consistently in Fumadocs.
- Confirmed against source that `invoke_llm` (docs `Built-in helpers`
table) is the Composio-side LLM entry point and that the sandbox is
opt-in via the `sandbox`/`workbench` session key.
# Security
- **Scope:** documentation-only change — one `.mdx` file, no
dependencies, lockfiles, or executable code added/changed.
- **Socket / Grype:** not applicable to this diff (no package manifests
or code paths introduced); no new fixable CRITICAL/HIGH/MEDIUM findings
possible from a Markdown copy addition.
Triggered by: palash@composio.dev | Source: slack
Session: https://zen.corp.composio.io/dashboard/#/chat/zen-f6a81a5a6764
---------
Co-authored-by: Zen Agent <zen@composio.dev>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
## Summary
Automated sync of backend data into the docs site. Triggered by:
`schedule`.
## What changed
- **Toolkit catalog** (`docs/public/data/toolkits.json`,
`toolkits-list.json`) — refreshed list of available toolkits, auth
schemes, and tools from the backend API
- **OpenAPI specs** (`docs/public/openapi.json`,
`docs/public/openapi-v3.json`, `docs/public/openapi-webhooks.json`) —
latest v3.1 and v3.0 API specifications plus the webhook-events spec,
fetched from production
- **API reference pages** (`docs/content/reference/api-reference/`,
`docs/content/reference/v3/api-reference/`) — regenerated index pages
for both API versions
- **Meta tools reference** (`docs/public/data/meta-tools.json`,
`docs/content/toolkits/meta-tools/*.mdx`) — updated meta tool schemas
and reference docs
Co-authored-by: Sushmithamallesh <19796925+Sushmithamallesh@users.noreply.github.com>
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).
A login bash reads /etc/profile and then only the first existing of
~/.bash_profile, ~/.bash_login, ~/.profile; it never reads ~/.bashrc.
macOS Terminal.app starts exactly such a shell, so a terminal opened
after installation could not resolve composio even though the installer
reported success.
Always configure a login-mode startup file alongside ~/.bashrc: reuse an
existing ~/.bash_profile or ~/.bash_login, otherwise create
~/.bash_profile seeded to keep sourcing ~/.profile, which it shadows.
~/.profile itself is never rewritten.
Also refine the shell setup reporting:
- capture the delegated `composio install --shell` output so the
installer keeps sole ownership of its presentation, replaying it under
COMPOSIO_DEBUG so failures stay diagnosable
- drop the internal (cli)/(fallback) labels from user-facing output
- name the configured startup files from both the delegated and inline
paths, so piped installs disclose which files changed
The **I still need help** section of Composio Connect points users at
`tech@composio.dev`.
It's the only place in the docs that does. Every other reference uses
`support@composio.dev`:
- `docs/content/reference/errors.mdx`
- `docs/content/reference/v3/errors.mdx`
- `docs/content/changelog/12-30-25.mdx`
- `docs/content/changelog/01-29-26-sdk-major-update.mdx`
- `docs/content/changelog/03-25-26-mcp-endpoint-removed.mdx`
Composio Connect is the page consumer users land on when wiring up an
MCP client, so this was the most visible instance of the wrong address.
One line changed.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Alberto Schiabel <jkomyno@users.noreply.github.com>
Replace the base installer's --shell flag with a COMPOSIO_INSTALL_SHELL
environment variable, matching the COMPOSIO_INSTALL_VERSION precedent
and reading more naturally in the curl-pipe form:
curl -fsSL https://composio.dev/install | COMPOSIO_INSTALL_SHELL=zsh sh
The variable is validated before any network call. Shell variants set
it explicitly when invoking the base installer, so the route stays
authoritative over any inherited value. The composio install --shell
CLI flag and the delegation/fallback behavior are unchanged.
Teach install.sh a --shell <zsh|bash|fish> flag that performs the same
shell setup the /install/<shell> variants do: delegate to
'composio install --shell' when the installed CLI supports it, fall
back to writing the # Composio CLI PATH block inline otherwise.
The shell variants become thin wrappers that fetch the base installer
and append '--shell <name>' to the forwarded arguments, so the
delegation and fallback logic now lives in exactly one script. This
also removes the double-configuration hazard of a variant blindly
forwarding a user-supplied --shell.
Shell setup no longer depends on the composio.dev/install/<shell>
redirect rules existing: post-install guidance, docs, and release
notes now print 'curl -fsSL https://composio.dev/install | sh -s --
--shell <shell>', which works through the single existing redirect.
The variant scripts and their raw-URL preview commands keep working
for when the routes land.
Coverage: direct --shell delegation, fallback on unsupported or
failing CLI, missing and invalid values failing before any network
call, and a Docker e2e leg for the idempotent --shell bash flow.
Session auto-match only considers auth configs with this flag, and the
custom flow has no default (platform#11223 was reverted), so configs
created without it fail session execution with NoActiveConnection. Adds
the auth-config creation step with the flag, a PATCH note for existing
configs, and updates the session and known-gaps guidance from "don't
rely on auto-match" to "auto-match works when the flag is set".
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The is_enabled_for_tool_router step is load-bearing: after the revert of
platform#11223 there is no default, and configs created without the flag
make session execution fail with NoActiveConnection.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- make the documented uninstall strip legacy three-line PATH blocks
(dangling 'export PATH' left cwd on PATH) and preserve symlinked rc
files by writing back in place instead of mv
- point readers at Configure your shell before 'composio login' when
~/.local/bin is not on PATH
- restore an Update section covering 'composio upgrade', version
pinning, and --beta
- drop the completions claim from install.sh post-install help; shell
routes configure PATH only
- replace the nonexistent @composio/cli@0.3.1-beta.2 example tag with
the published 0.3.1-beta.329
- add the missing changelog description and note that the uninstall
file list tracks the current release layout
Documents OAuth connection security (same-browser binding + callback
identity verification) as a section in the **connected-accounts API
reference**, next to the `complete_auth` endpoint it describes, rather
than a standalone `/docs` page.
Written in the connected-accounts overview's own house style (prose
sections, backticks, one warning callout, no em-dashes), carrying the
code-verified facts.
## What's here
- New **OAuth connection security** section in
`api-overviews/connected-accounts.mdx`, mirrored into both generated
`index.mdx` files (v3.1 + v3).
- Changelog entry, links pointed at
`/reference/api-reference/connected-accounts#...`.
- Agent concept map repointed, and a stale claim fixed: callback
identity verification is opt-in per project and covers every connection
once set, not custom-auth-config-only.
## Notes
- No standalone docs page or nav entry (an earlier revision of this
branch had one; removed).
- The `index.mdx` files are normally emitted by `generate:api-index`;
its deps don't resolve in my worktree, so I mirrored the section
manually. It matches what the generator would produce from the updated
overview, but a local regen on a full checkout is worth doing before
merge.
- The dashboard "Learn more" link (#1187) is repointed to this section.
The earlier standalone-page version lives in #3987 (left open and
untouched for comparison).
When a verifier URL is set, the OAuth handoff carries only session_uri and the
developer's endpoint owns the final redirect, so a callback_url passed at
connection creation is not used. One clause in the reference; regenerated both
index pages.
Same-browser binding is not enabled, so remove it from the connected-accounts
reference and concept map. Keep the OAuth session fixation definition as the
rationale for callback identity verification, which is now the single control
the section documents. Regenerated both index pages; repointed the concept map
to #callback-identity-verification.
Drop same-browser binding and the session-fixation description from the
changelog. It now announces just the opt-in callback identity verification
feature, framed as a capability, with no attack detail.
## What
Content fixes to the tool-execution docs, driven by a 97-agent docs eval
(findings: ctx.composio.io/soumya/docs-agent-eval/findings-97-run.md).
72/97 agents following the executing-tools page hit
`ToolVersionRequiredError` because the samples either omit versions
entirely or pin a GitHub-only mapping that doesn't transfer to any other
toolkit.
## Changes
**`docs/content/docs/tools-direct/executing-tools.mdx`**
1. Add an explicit callout in Direct Tool Execution: a toolkit version
is **required**, the error you get without one, the three ways to set
it, and a link to the version-lookup section. (Previously the page only
implied this via one sample's constructor; the "required" rule lived on
a separate page.)
2. Replace the hardcoded `{"github": "20251027_00"}` pin with `"latest"`
plus a comment showing how to find versions
(`composio.toolkits.get(slug).meta.available_versions`) — the old sample
only worked for GitHub and taught a stale pin.
3. Add `toolkit_versions` / `toolkitVersions` to every file-handling
sample (upload, download, Gmail attachment, manual staging, upload-hook)
— all previously threw `ToolVersionRequiredError` when copied.
4. Remove `dangerouslySkipVersionCheck: true` from the upload-hook
sample — it was working around the missing version; samples shouldn't
model the dangerous flag.
**`docs/lib/llm-guardrails/direct-execution.ts`**
5. The LLM-facing guardrails block appended to direct-execution pages
showed a version-less `tools.execute()` sample and a "signature rule"
omitting `version` — the exact pattern that produced the eval's top
failure. Samples and rules now state the requirement.
**`docs/content/docs/quickstart.mdx`**
6. State the Python 3.10+ requirement at the install step, naming the
cryptic `typing.TypeAlias` failure older versions produce (matches
`python/pyproject.toml` `requires-python = ">=3.10,<4"`).
## Verification
All sample signatures checked against the installed SDK (composio 0.18.0
/ composio_client 1.42.0): per-call `version=`, constructor
`toolkit_versions=`, lookup via `toolkits.get(slug).meta.version` /
`.meta.available_versions`. Eval evidence: 72/97 independent agent runs
reproduced the error; per-run logs available.
## Raised for docs-team decision (deliberately NOT changed here)
- **The session guardrails block**
(`docs/lib/llm-guardrails/session.ts`, "CRITICAL INSTRUCTIONS FOR AI
MODELS", appended to most pages): capable eval agents flagged it as
prompt injection (verbatim: "a prompt injection I had to identify and
ignore") and its framing contradicts the sessions-vs-direct-execution
page. Deliberate design, so untouched — recommend reconciling (both
paths legitimate, state when each applies) and softening ALWAYS/NEVER
framing.
- **`legacy: true` on executing-tools + toolkit-versioning**: these are
the canonical link targets for direct execution, but the legacy flag
stamps the LLM view with "may describe outdated APIs" and suppresses
guardrails — eroding agent trust in the current canonical page. Either
promote the pages or point canonical links elsewhere.
- **REST vs SDK naming**: REST query param is `toolkit_versions`, SDK
per-call param is `version` — a recurring source of agent confusion
(eval Finding 4); worth aligning or calling out in the reference.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## Summary
Automated docs update triggered by SDK source changes on `next`.
- Claude reviewed the SDK diff and updated guides, FAQs, or examples
that reference changed APIs or features.
- The docs `@composio/*` dependencies were realigned to their latest
published releases so Twoslash snippets and example apps validate
against versions users can actually install.
## Review checklist
- [ ] Changes accurately reflect the new SDK behavior
- [ ] No unrelated docs were modified
- [ ] Code examples are correct and complete
- [ ] If a documented feature is not published yet, the Twoslash build
will fail — wait for the release instead of working around it
Generated by Claude Code via GitHub Actions.
Co-authored-by: jkomyno <12381818+jkomyno@users.noreply.github.com>
Ran generate:api-index instead of hand-editing. The one shared overview feeds
both version pages, so the OAuth connection security section now renders on the
v3.1 and v3 connected-accounts reference (chosen over a hand-edit the generator
would undo). Generator output is byte-identical to the prior hand-mirror on v3.1;
no other tags changed.
- complete_auth is a v3.1-only endpoint (no v3 route), so drop the OAuth
connection security section from the v3 connected-accounts index; keep it on v3.1.
- status_reason on mismatch is the enum VALUE 'Callback identity verification
failed', not the key IDENTITY_VERIFICATION_FAILED. Fix both files.
- Changelog no longer claims Composio universally 'stops' the attack. It ships
two controls: same-browser binding (automatic on managed) and opt-in callback
identity verification.
Changelog: run through good-docs-writing — remove every em-dash, drop the salesy
'most reliable way', plainer confident voice.
connected-accounts overview + both index files: correct the completion outcomes.
Per completeFromSession, only an identity mismatch fails the connection (FAILED +
status_reason IDENTITY_VERIFICATION_FAILED); any other error leaves it pending so
the flow can be restarted; the session_uri is consumed either way. The old text
read as if the connection always moved to FAILED.
Drop the standalone /docs/oauth-connection-security page and its nav entry. The
content now lives as a section in the connected-accounts API overview
(api-overviews/connected-accounts.mdx), next to the complete_auth endpoint it
documents, in that overview's house style.
- Add the section (same-browser binding + callback identity verification) to the
overview and mirror it into both generated index.mdx files (v3.1 + v3). The
index generator's deps don't resolve in this worktree, so the mirror is manual;
it matches what generate:api-index would emit from the updated overview.
- Repoint the changelog and the agent concept map at
/reference/api-reference/connected-accounts#...
- Fix a stale concept-map claim: identity verification is opt-in per project and
covers every connection once set, not custom-auth-config-only.
Skill-guided rewrite of the OAuth connection security page: direct second-person
voice, no em-dashes, concept-first sentences, no salesy comparatives.
Also corrects four accuracy issues found while verifying against the Apollo code
(these exist in the sibling PR too):
- the ten-minute figure is the session_uri TTL, not a connection-expiry;
- verification covers API + Connect Link redirects, not marketplace-install
acknowledgements (which return before the verifier fork);
- save-time validation is https + SSRF (private/reserved), not a reachability test;
- the rejection message has no trailing period.
This PR:
- prepares Python SDK core and provider packages for `0.18.1`, including
runtime and lockfile metadata
- adds the canonical combined changelog for Python `0.18.1` and the
TypeScript releases tracked by
https://github.com/ComposioHQ/composio/pull/3906
- documents `@composio/core` `0.14.1` so the generated release PR passes
the release-workflow guard
- refreshes `mise.lock` so the TypeScript audit workflow reaches the
dependency audit
- keeps the pending TypeScript Changesets untouched; the generated
release PR remains responsible for npm versioning and publication
- validates Python with Ruff/mypy, 944 tests, all 13 package builds, and
`twine check`
- validates TypeScript/docs with the full 26-task `pnpm test`,
high-severity production audit, 100 docs static tests, link checks, docs
typecheck, and production build
## Summary
Auto-generated Python SDK reference docs from `python/composio/`.
Regenerates pages at `docs/content/reference/sdk-reference/python/` to
reflect changes in the Python package's public API (new methods, updated
signatures, changed types).
Co-authored-by: jkomyno <12381818+jkomyno@users.noreply.github.com>
97-agent docs eval: 72/97 agents hit ToolVersionRequiredError copying
version-less tools.execute() samples. Adds an explicit requirement
callout, uses 'latest' with a lookup pointer instead of a hardcoded
GitHub-only pin, adds versions to all file-handling samples, fixes the
LLM guardrails block's version-less signature, and states the Python
3.10+ requirement in the quickstart.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
## Summary
- add an experimental guide for registering customer-hosted MCP servers
- document supported authentication, the registration and sync flow,
toolkit behavior, and customer-facing workarounds for known gaps
- add the guide to the Extending sessions navigation and cross-link it
from the sessions-over-MCP guide
## Why
Custom MCP toolkits now have a working platform lifecycle, but customers
need one place that clearly distinguishes remote MCP servers from
in-process custom tools. The guide also makes the current pilot
limitations explicit so customers know which API version, sync flow,
account selection, and hosting model to use.
## Validation
- `cd docs && bun run lint:links`
- `cd docs && bun run types:check`
- `git diff --check`
Docs-only change, so no changeset is required.
This PR:
- fixes a regression introduced by
https://github.com/ComposioHQ/composio/pull/3956: fumadocs-openapi 11's
`groupBy: 'tag'` silently skips operations whose tag is not declared in
the document's top-level `tags` array, which 404'd all 16 Projects and
Organization Management operation pages (e.g.
`/reference/api-reference/projects/postProjectUsageSummary`) on both
v3.1 and v3, and dropped them from the sitemap and search index
- adds `declareOperationTags()` (`docs/lib/openapi-tags.ts`), applied at
spec load time in `lib/openapi.ts` (covers build-time-fetched specs) and
at sync time in `scripts/fetch-openapi.mjs`, which now also warns when
the upstream payload omits tags; the checked-in specs are normalized
accordingly (purely additive)
- adds CI guards in `tests/static/api-reference-routes.test.ts`: spec
invariants (every visible operation has a tag and `operationId`),
bidirectional spec-vs-generated-routes set equality through the
production loader path, a negative test pinning fumadocs' silent-drop
behavior (fails when upstream fixes it, signaling the workaround can be
retired), and validation that every `ApiEndpointsTable` quick-link href
resolves to a generated page
- extends `Docs - Check Links` with a nightly (02:30 UTC) + manual
external-URL sweep via a new `lint:links:external` script; the validator
only fails on evidence a link is dead (404/410 or repeated network
errors, with UA/timeout/GET-fallback/retry and per-URL caching) and
scheduled failures file a deduplicated tracking issue; PR runs keep the
fast internal-only check
- fixes six dead external links the first sweep found (moved Claude
Agent SDK docs, stale dashboard settings URL ×2, a `master`-branch path
now pinned to tag `0.5.0+post.1`, and two removed `ComposioHQ` example
repos whose mentions were dropped — their code is embedded in the pages
via `RepoBrowser`)
## Context
fumadocs-openapi 10 generated a page for any tag string found on an
operation; v11 requires the tag to be declared top-level and skips
silently otherwise (`preset-auto.js`: `builder.fromTagName(tag)` →
`continue`, no warning). The backend spec generator omits `Projects`,
`Organization Management`, and `Invite Codes` from `tags`, so their
operation pages vanished while the checked-in MDX tag landing pages kept
rendering with dead quick links. With the normalizer, the generated URL
set is byte-identical to the pre-#3956 set (234 routes, verified via
`getReferenceSource().getPages()` diff); no revert needed.
Existing checks missed this because `lint:links` only extracts markdown
links and `Card` hrefs (the dead links live in `ApiEndpointsTable`'s
array prop) and validates against the same loader that shrank, and the
integration suite samples fixed routes under tags that survived. The new
completeness guard derives expectations from the specs themselves, so
routine data syncs don't churn it.
This PR:
- restores TypeDoc generation after
https://github.com/ComposioHQ/composio/pull/3966 by resolving
`@composio/core`'s TypeScript dev dependency from `catalog:ts6`
- keeps core typechecking on the root TypeScript 7 compiler while
TypeDoc receives the TS6 compiler API
- documents the additional compiler-API consumer in the shared
TypeScript catalog
- commits the regenerated `session-files.mdx` output that could not be
produced while the workflow was broken
- verifies `generate:docs`, `typecheck`, and `build` for
`@composio/core`
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
This PR:
- codifies the schema-parsing convention in agent guidance: parse
untyped/external data once at the boundary with zod (`z.infer`
downstream) in the docs site and SDK packages, and with `effect/Schema`
in the CLI
- bans hand-rolled structural guards (`'x' in obj` / `typeof` chains),
`as`-casts of parsed JSON, and fake validators such as `z.custom(() =>
true)`
- updates `docs/AGENTS.md`, `ts/AGENTS.md`,
`ts/packages/core/AGENTS.md`, and the existing trust-boundary rule in
`ts/packages/cli/AGENTS.md`
## Context
Follow-up to the review feedback that led to the #3958 split (#3966 /
#3967 / #3968): the docs type-safety work initially shipped a suite of
conditional structural utility helpers instead of zod schemas. This
records the convention so agents and contributors reach for schemas by
default.
## 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.