Files
composiohq__composio/CLAUDE.md
T
Alberto Schiabel 025a657597 feat(ts): drop CommonJS support (#3494)
This PR moves the TypeScript SDK support floor to the latest Node.js 22
release and uses that as the point where we stop carrying custom
CommonJS compatibility machinery. The e2e runtime coverage now exercises
the latest Node 22, Node 24, and Node 25 lines, so the SDK is tested
against the minimum supported version and the newer runtimes users are
likely to adopt next.

Because the SDK packages are still on `0.x`, the accompanying changeset
uses `minor` bumps while calling out that this is a breaking change
inside the existing 0.x line.

It also moves pnpm under mise on this Node 22 layer. That belongs here,
not in #3493, because the pinned `pnpm@10.28.2` requires Node.js
`>=22.13`. Removing Corepack is intentional: Node.js documents that
Corepack is no longer distributed starting with Node.js v25, so relying
on `corepack enable` would keep a toolchain dependency that is already
on the way out of the Node distribution.

## What changed

- Pins the local/toolchain Node.js floor to `22.22.3` in `mise.toml`,
`mise.lock`, `toolchain-versions.json`, and root `devEngines`.
- Pins pnpm in `mise.toml` as `"npm:pnpm" = "10.28.2"` and makes mise
the single source of truth for the pnpm version. Removes the root
`packageManager` / `devEngines.packageManager` Corepack pin entirely
(rather than keeping a second copy of the version that could drift) and
removes stale `packageManager` metadata from real TS packages/examples
and generators.
- Sets `dangerouslyDisablePackageManagerCheck: true` in `turbo.jsonc` so
Turbo discovers pnpm from `pnpm-lock.yaml` instead of requiring a
`packageManager` field. Without this, Turbo fails workspace resolution
(`Could not resolve workspaces -> Missing 'packageManager' field`),
which is the only reason the field would otherwise need to stay.
- Replaces `corepack enable` in the shared setup action with
mise-managed pnpm. The E2E Docker images install bun + pnpm directly
from `mise.toml`/`mise.lock` (with
`dangerouslyDisablePackageManagerCheck`-style separation: Node/Deno stay
on the base image as the test matrix axis and are disabled via
`MISE_DISABLE_TOOLS` so mise does not shadow them; the tool binaries are
symlinked into `/usr/local/bin`). No `BUN_VERSION`/`PNPM_VERSION` build
args are threaded from the host anymore, and bun+pnpm now carry
`mise.lock` checksum verification.
- Extends the install-time toolchain check to validate pnpm against mise
alongside Bun.
- Sets the Node E2E matrix and install fallback checks to `22.22.3`,
`24.16.0`, and `25.9.0`.
- Makes TS package builds ESM-only: `tsdown` now emits `.mjs` / `.d.mts`
only and uses the ATTW `esm-only` profile.
- Removes explicit `require` / `.cjs` / `.d.cts` package export paths
and internal import mappings from the public TS SDK packages.
- Marks public TS SDK packages as `type: module` where they were missing
it.
- Replaces the remaining runtime `require('pusher-js')` with dynamic ESM
import.
- Deletes the legacy CJS example.
- Reintroduces `node/cjs-basic` as a modern Node `require(esm)` interop
E2E: it verifies `require('@composio/core')` works through Node's native
ESM loader on Node 22, 24, and 25 while resolving to `dist/index.mjs`,
not a `.cjs` artifact.
- Removes `.cjs` / `.cts` handling from example validation and CLI
project-language detection.
- Updates provider scaffolding so newly generated providers are
ESM-only.
- Adds a minor changeset warning that CommonJS callers can only rely on
Node's native `require(esm)` interop and that custom CommonJS
compatibility machinery is gone.

## Bundled behavior changes

Two changes here are technically independent of the CommonJS removal but
ride along because they touch the same files and ship in the same
release cut. Calling them out explicitly so they are not missed in
review:

- **`PusherUtils` realtime channel auth (`@composio/core`).** Replacing
the runtime `require('pusher-js')` with a dynamic ESM `import()` was
done alongside conforming `channelAuthorization` to pusher-js's typed
`customHandler(params, callback)` contract. The previous `(authOptions)
=> Promise` shape did not match pusher-js's actual calling convention —
it read `endpoint`/`headers`/`params` off an argument that pusher-js
never passes — so this also fixes that latent mismatch. New unit tests
(`ts/packages/core/test/utils/pusher.test.ts`) cover the auth request
shape (endpoint, `x-api-key` header, JSON `socket_id`/`channel_name`
body) and the success / invalid-JSON / network-failure callback paths.
- **CLI meta-tool slug list (`@composio/cli`).** Drops
`COMPOSIO_UPSERT_RECIPE` and `COMPOSIO_GET_RECIPE` from
`META_TOOL_SLUG_LIST` in `tools-executor.ts`; `@composio/client`
alpha.74 removed those slugs from the `SessionExecuteMetaParams['slug']`
union. The list is declared `satisfies
ReadonlyArray<SessionExecuteMetaParams['slug']>`, so this is enforced at
compile time (`pnpm typecheck`) — keeping the stale slugs would be a
type error — and needs no separate runtime test.

## Verification

- Verified latest Node 22/24/25 releases from the official Node dist
index: `22.22.3`, `24.16.0`, `25.9.0`
(https://nodejs.org/dist/index.json).
- Verified Node docs state Corepack is no longer distributed starting
with Node.js v25:
https://nodejs.org/download/release/v22.22.3/docs/api/corepack.html
- `mise exec -- pnpm --version` -> `10.28.2`
- `mise exec -- pnpm install --frozen-lockfile`
- `mise exec -- bun run ts/scripts/pre-install/check-toolchain.ts`
- `mise exec -- pnpm --filter @e2e-tests/utils typecheck`
- `mise exec -- pnpm --filter @e2e-tests/node-cjs-basic typecheck`
- `mise exec -- pnpm --filter @e2e-tests/node-cjs-basic test:e2e:node`
- `mise exec -- pnpm --filter @e2e-tests/node-esm-basic typecheck`
- `mise exec -- pnpm --filter @composio/cli typecheck`
- `mise exec -- pnpm --filter @composio/cli test -- --runInBand`
- `mise exec -- pnpm --filter @composio/core typecheck`
- `mise exec -- pnpm --filter @composio/core exec vitest run
test/utils/pusher.test.ts`
- `mise exec -- pnpm run build:packages`
- `mise exec -- turbo run build --dry-run` resolves all workspace
packages with no root `packageManager` field (pnpm discovered from
`pnpm-lock.yaml`).
- `mise exec -- pnpm --filter @composio/cli exec vitest run
test/src/services/project-environment-detector.test.ts`
- `mise exec -- pnpm exec prettier --check ...`
- `docker build -f ts/e2e-tests/_utils/Dockerfile.node --build-arg
NODE_VERSION=24.16.0 -t composio-e2e-node:misecheck .` (also
`Dockerfile.deno` with `DENO_VERSION=2.6.7 NODE_MAJOR=22`) — both build
green; runtime resolves Node/Deno from the base image and pnpm 10.28.2 /
bun 1.3.10 from mise.
- `docker manifest inspect node:24.16.0-slim`
- `docker manifest inspect node:25.9.0-slim`
- `bash -n ts/scripts/create-provider.sh && git diff --check`
- `ruby -e "require 'yaml';
YAML.load_file('.github/workflows/ts.test-e2e.yml')"`
- Tracked example validation in a clean temporary tree: `Validated 21
example packages.`
2026-06-19 22:22:17 +04:00

5.0 KiB

CLAUDE.md

Guidance for Claude Code when working in this repository. For Codex / generic-agent guidance see AGENTS.md.

Overview

Composio SDK v3 — monorepo containing the TypeScript SDK (primary, under ts/) and the Python SDK (under python/). Built with pnpm workspaces + Turbo for TS, uv + nox for Python. Default branch: next.

Repository Layout

composio/
├── ts/
│   ├── packages/
│   │   ├── core/              # @composio/core — main SDK
│   │   ├── providers/         # @composio/openai, anthropic, google, langchain, vercel, mastra, ...
│   │   ├── cli/               # @composio/cli — Effect.ts + Bun (see ts/packages/cli/AGENTS.md)
│   │   ├── cli-keyring/       # @composio/cli-keyring — macOS Keychain / Linux Secret Service
│   │   ├── cli-local-tools/   # @composio/cli-local-tools — local toolkit declarations
│   │   ├── json-schema-to-zod/
│   │   └── ts-builders/       # AST builders for code generation
│   ├── vendor/                # Read-only Effect + Clack submodules (do NOT modify)
│   ├── e2e-tests/             # Docker-based Node/Deno/Cloudflare runtime tests
│   └── examples/
├── python/                    # Python SDK (composio, providers, examples)
└── docs/                      # Fumadocs site (see docs/CLAUDE.md)

TypeScript Commands

mise install                # Installs Node, Bun, Deno, pnpm, Python, uv from mise.toml (one-time per machine)
pnpm install                # First-time setup
pnpm build                  # Build all packages (Turbo)
pnpm build:packages         # TS packages only
pnpm lint / lint:fix
pnpm format
pnpm typecheck              # MANDATORY before pushing CLI changes
pnpm test                   # Vitest, all packages
pnpm test:e2e               # All runtimes (Node ESM + require(esm), Deno, Cloudflare Workers) via Docker
pnpm test:e2e:node          # Override with COMPOSIO_E2E_NODE_VERSION=22.22.3
pnpm test:e2e:deno          # Override with COMPOSIO_E2E_DENO_VERSION=2.6.7
pnpm test:e2e:cloudflare
pnpm changeset              # Create release changeset (required for stable CLI/SDK releases)
pnpm create:provider <name> [--agentic]
pnpm create:example <name>

Toolchain versions are pinned in mise.toml (Node, Bun, Deno, pnpm, Python, uv). Install mise once with brew install mise (macOS), winget install jdx.mise (Windows), or curl https://mise.run | sh (any), then activate it in your shell — see https://mise.jdx.dev/installing-mise.html. CI can set BYPASS_TOOLCHAIN_CHECK=1 only when using prebuilt toolchain images.

Python Commands

cd python
make env                    # uv-managed venv with all deps (NOT pre-built in sandboxes)
source .venv/bin/activate   # ALWAYS activate before pytest/ruff/pip
make fmt                    # ruff format
make chk                    # ruff check + mypy
make tst / make snt         # pytest / sanity tests
pytest -m core              # Markers: core, openai, langchain, agno
make build / make bump

Python: >=3.10, <4. Formatter/linter: Ruff (88 char). Type checker: mypy strict. Core deps include composio-client (Stainless-generated; source repo is ComposioHQ/composio-base-py).

Environment Variables

COMPOSIO_API_KEY            # Required
COMPOSIO_BASE_URL           # Optional override
COMPOSIO_LOG_LEVEL          # silent | error | warn | info | debug
COMPOSIO_DISABLE_TELEMETRY  # "true" to disable

Gotchas

  • Default branch is next, not main/master. Branch from next and target next for PRs.
  • Docs PRs also target next (see docs/CLAUDE.md rule).
  • pnpm install checks Bun against mise.toml; run mise install when it fails.
  • ts/vendor/effect/ and ts/vendor/clack/ are read-only reference submodules — npm provides the actual deps.
  • The CLI is Effect.ts + Bun, not plain Node — see ts/packages/cli/AGENTS.md (CLI's CLAUDE.md is a symlink to it).
  • E2E tests run in Docker and require Docker daemon access; skip them in restricted sandboxes.
  • Tool execution code generation is auto-derived from OpenAPI specs in hermes — don't hand-edit generated files under @composio/core/generated.

Key Files

  • Main SDK entry: ts/packages/core/src/index.ts
  • Core Composio class: ts/packages/core/src/composio.ts
  • Types: ts/packages/core/src/types/, errors: ts/packages/core/src/errors/
  • Build configs: turbo.jsonc, tsconfig.base.json, tsdown.config.base.ts
  • Toolchain pins: mise.toml (Node, Bun, Deno, pnpm, Python, uv), mise.lock, toolchain-versions.json (test matrices)
  • CI release docs to update when bumping toolchain: ts/docs/internal/release.md
  • Python config: python/Makefile, python/noxfile.py, python/config/{pytest.ini,ruff.toml}

See Also

  • AGENTS.md — Codex/generic-agent variant of this file
  • docs/CLAUDE.md — Fumadocs site, link-checker, API-reference versioning
  • ts/packages/cli/AGENTS.md — CLI architecture, services, commands, release flow