Commit Graph

963 Commits

Author SHA1 Message Date
Sarah Simionescu ba999577d7 fix(cli): use manual authorization copy on link --no-wait paths
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 15:30:58 -07:00
Sarah Simionescu aad2e9a2fd fix(cli): drop redirect copy when link runs with --no-browser
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 15:21:12 -07:00
Sarah Simionescu b003baaf1f feat(cli): add --no-browser flag to link command
Adds a --no-browser flag to `composio link` (and `composio dev
connected-accounts link`) that prints the authorization URL instead of
auto-opening the browser, while still waiting for the connection to
become ACTIVE. Also respected on the unmanaged-auth dashboard fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-13 15:08:59 -07:00
Alberto Schiabel fbcf08136d revert(core): defer v1 session alias removal (#3826)
This PR:
- reverts https://github.com/ComposioHQ/composio/pull/3780
- restores the TypeScript `composio.create()` and `composio.use()`
session aliases, with their runtime and type-test coverage
- restores the prior deprecation state for
`BaseProvider.wrapMcpServerResponse`
- removes the pre-v1 breaking-change changeset so the release PR no
longer advertises this removal

The v1 API-freeze change should be recreated later as a draft PR and
kept out of the merge queue until v1 is ready.
2026-07-14 01:01:18 +04:00
Anas Khan fa933a6f9b fix(ts): point published package homepage links at the next branch (#3821)
```markdown
The `homepage` field in every published TypeScript package points at
`https://github.com/ComposioHQ/composio/tree/main/ts/packages/<pkg>#readme`. The
repository's default branch is `next` and there is no `main` branch, and GitHub
does not redirect `tree/<branch>` paths to the default branch when that branch
does not exist. As a result each of these homepage links returns a 404 wherever
it is surfaced (the package page on npmjs.com, editor/IntelliSense hovers, and
`npm view <pkg> homepage`).

This repoints each `homepage` to `tree/next/...` so the links resolve. The
`repository.url` (plain `.git` URL) and `bugs.url` fields were already correct
and are left untouched.

The metadata was originally added in #3611; this only corrects the branch in the
`homepage` URLs.

Fixes #

## Changes
- Update the `homepage` field from `tree/main/...` to `tree/next/...` in the 14
  published packages that carry one: `@composio/core`, `@composio/slim`,
  `@composio/experimental`, `@composio/json-schema-to-zod`, and the providers
  `@composio/anthropic`, `@composio/claude-agent-sdk`, `@composio/cloudflare`,
  `@composio/google`, `@composio/langchain`, `@composio/llamaindex`,
  `@composio/mastra`, `@composio/openai`, `@composio/openai-agents`,
  `@composio/vercel`.
- Add a Changeset (patch) covering those 14 published packages.

## Type of change
- [x] Bug fix
- [ ] New feature
- [ ] Refactor/Chore
- [ ] Documentation
- [ ] Breaking change

## How Has This Been Tested?
Metadata-only change, so there is no unit test to add. Verified with:

- Confirmed the target branch: `git ls-remote --symref origin HEAD` reports
  `refs/heads/next`, and `git ls-remote --heads origin main` is empty (no `main`).
- Confirmed the links resolve: `https://github.com/ComposioHQ/composio/tree/main/ts/packages/core`
  returns HTTP 404 while `.../tree/next/ts/packages/core` returns HTTP 200
  (same for the provider packages).
- All 14 edited `package.json` files still parse as valid JSON.
- `pnpm exec prettier --check` on the 14 `package.json` files and the changeset:
  all pass.
- `pnpm changeset status --since=origin/next` lists exactly these 14 packages
  bumping at `patch` (no missing or extra packages), so the changeset CI check is
  satisfied.

Environment: node 26, pnpm 10.28.0.

## Screenshots (if applicable)

## Checklist
- [x] I have read the Code of Conduct and this PR adheres to it
- [x] I ran linters/tests locally and they passed
- [ ] I updated documentation as needed
- [x] I added tests or explain why not applicable
- [x] I added a changeset if this change affects published packages

## Additional context
The `homepage` URLs pin an explicit branch (`tree/<branch>`), so they will break
again if the default branch is ever renamed. If you would prefer a
branch-agnostic form (for example dropping the `tree/<branch>` segment so the URL
tracks the default branch, or linking to the published README), I am happy to
switch to that instead; I went with the smallest correct fix of pointing at the
actual default branch.
```

Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
2026-07-13 20:06:43 +04:00
Alberto Schiabel 71255765a5 fix(schema): normalize duplicate required entries (#3812)
## Summary

- Normalize duplicate JSON Schema `required` entries at the shared
`ToolSchema` ingress boundary.
- Reapply normalization immediately before direct providers emit vendor
schemas (Anthropic, OpenAI, OpenAI Responses, Google, Cloudflare, and
OpenAI Agents).
- Preserve literal `const`/`default`/`enum`/`examples` values, tolerate
aliasing safely, and fail predictably on pathological nesting.
- Document the provider-boundary rule in
`ts/packages/providers/AGENTS.md`.

Co-authored-by: @MatinGathani

## Verification

- `pnpm changeset status`
- `pnpm --filter @composio/core build`
- Focused core and affected-provider Vitest suites (1,151 tests)
- `pnpm typecheck`
- `pnpm lint` (passes with 71 pre-existing warnings)

---------

Co-authored-by: MatinGathani <70268627+matingathani@users.noreply.github.com>
2026-07-13 15:03:38 +04:00
dependabot[bot] 09aab1d19f chore(deps-dev): bump the npm-development group across 1 directory with 3 updates (#3795)
Bumps the npm-development group with 3 updates in the / directory:
[turbo](https://github.com/vercel/turborepo),
[typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint)
and [typedoc](https://github.com/TypeStrong/TypeDoc).

Updates `turbo` from 2.10.2 to 2.10.4
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/vercel/turborepo/releases">turbo's
releases</a>.</em></p>
<blockquote>
<h2>Turborepo v2.10.4</h2>
<!-- raw HTML omitted -->
<h2>What's Changed</h2>
<h3>Changelog</h3>
<ul>
<li>release(turborepo): 2.10.3 by <a
href="https://github.com/github-actions"><code>@​github-actions</code></a>[bot]
in <a
href="https://redirect.github.com/vercel/turborepo/pull/13222">vercel/turborepo#13222</a></li>
<li>ci: Retry Windows nextest aborts from transient 0xc0000142 spawn
failures by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13240">vercel/turborepo#13240</a></li>
<li>perf: Use mimalloc as the global allocator by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13237">vercel/turborepo#13237</a></li>
<li>perf: Parse yarn v1 lockfiles in a single pass by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13241">vercel/turborepo#13241</a></li>
<li>ci: Fix cache outputs for Eve app by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13243">vercel/turborepo#13243</a></li>
<li>perf: Stop materializing spans for the disabled daemon log layer by
<a href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a>
in <a
href="https://redirect.github.com/vercel/turborepo/pull/13244">vercel/turborepo#13244</a></li>
<li>fix: Keep ancestor-scoped bun dependencies resolvable after prune
renames by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13236">vercel/turborepo#13236</a></li>
<li>perf: Overlap external dependency hashing with package file hashing
by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13234">vercel/turborepo#13234</a></li>
<li>perf: Build tracked repo index concurrently with package graph by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13232">vercel/turborepo#13232</a></li>
<li>perf: Release tokio runtime at exit so background DNS lookups never
stall the user by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13231">vercel/turborepo#13231</a></li>
<li>perf: Overhaul pnpm lockfile parsing and dependency closure
computation by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13228">vercel/turborepo#13228</a></li>
<li>feat: Add futureFlags.experimentalCargoWorkspaces flag (no-op) by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13227">vercel/turborepo#13227</a></li>
<li>feat: Introduce toolchain provider abstraction by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13235">vercel/turborepo#13235</a></li>
<li>perf: Parse Berry lockfiles in a single pass by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13242">vercel/turborepo#13242</a></li>
<li>fix: Apply input exclusion globs to the filesystem walk by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13224">vercel/turborepo#13224</a></li>
<li>fix: Stop root-directory packages from claiming every file in change
mapping by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13225">vercel/turborepo#13225</a></li>
<li>chore: Rename turborepo-repository napi package to
<code>@​turbo/repository</code> by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13226">vercel/turborepo#13226</a></li>
<li>perf: Hash git blobs with hardware-accelerated SHA-1 by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13245">vercel/turborepo#13245</a></li>
<li>release(turborepo): 2.10.4-canary.1 by <a
href="https://github.com/github-actions"><code>@​github-actions</code></a>[bot]
in <a
href="https://redirect.github.com/vercel/turborepo/pull/13247">vercel/turborepo#13247</a></li>
<li>feat: Discover Cargo crates as packages by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13248">vercel/turborepo#13248</a></li>
<li>perf: Reuse per-package external dependency hashes in run summaries
by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13249">vercel/turborepo#13249</a></li>
<li>perf: Stat workspace turbo.json files concurrently during discovery
by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13251">vercel/turborepo#13251</a></li>
<li>chore: Add tracing spans to workspace discovery and globwalk phases
by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13252">vercel/turborepo#13252</a></li>
<li>fix: Avoid non-reentrant libc calls in concurrent shutdown process
scans by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13256">vercel/turborepo#13256</a></li>
<li>perf: Memoize resolved task definitions during engine construction
by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13257">vercel/turborepo#13257</a></li>
<li>perf: Compute transitive closures and external dependency hashes
concurrently with run setup by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13250">vercel/turborepo#13250</a></li>
<li>perf: Probe microfrontends configs in parallel by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13262">vercel/turborepo#13262</a></li>
<li>feat: Execute Cargo crate tasks via cargo by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13261">vercel/turborepo#13261</a></li>
<li>perf: Pre-size engine task collections by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13265">vercel/turborepo#13265</a></li>
<li>feat: Expose resolved experimentalCI task configuration in
<code>turbo query</code> by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13264">vercel/turborepo#13264</a></li>
<li>feat: Derive input and output globs for Cargo tasks by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13263">vercel/turborepo#13263</a></li>
<li>perf: Parse large pnpm lockfile sections in parallel by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13266">vercel/turborepo#13266</a></li>
<li>feat: Hash Cargo external dependencies per-crate by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13267">vercel/turborepo#13267</a></li>
<li>ci: Install pnpm 10 in musl containers for Library Release by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13269">vercel/turborepo#13269</a></li>
<li>ci: Force pnpm overwrite in Library Release musl containers by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13270">vercel/turborepo#13270</a></li>
<li>perf: Defer the untracked-scan barrier to first file-hash use by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13268">vercel/turborepo#13268</a></li>
<li>ci: Fetch API-created commit before updating local ref by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13271">vercel/turborepo#13271</a></li>
<li>release(library): 0.0.1-canary.22 by <a
href="https://github.com/github-actions"><code>@​github-actions</code></a>[bot]
in <a
href="https://redirect.github.com/vercel/turborepo/pull/13272">vercel/turborepo#13272</a></li>
<li>perf: Remove lock and dispatch overhead from task hash
precomputation by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13273">vercel/turborepo#13273</a></li>
<li>fix: Fall back to lockfile detection in
<code>@​turbo/repository</code> when package manager is undeclared by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13275">vercel/turborepo#13275</a></li>
<li>test: Add end-to-end coverage for Cargo workspaces by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13274">vercel/turborepo#13274</a></li>
<li>release(library): 0.0.1-canary.23 by <a
href="https://github.com/github-actions"><code>@​github-actions</code></a>[bot]
in <a
href="https://redirect.github.com/vercel/turborepo/pull/13276">vercel/turborepo#13276</a></li>
<li>release(turborepo): 2.10.4-canary.2 by <a
href="https://github.com/github-actions"><code>@​github-actions</code></a>[bot]
in <a
href="https://redirect.github.com/vercel/turborepo/pull/13278">vercel/turborepo#13278</a></li>
<li>fix: Collapse nested package-manager fallback conditional by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13279">vercel/turborepo#13279</a></li>
<li>feat: Make turbo watch Cargo-aware by <a
href="https://github.com/anthonyshew"><code>@​anthonyshew</code></a> in
<a
href="https://redirect.github.com/vercel/turborepo/pull/13280">vercel/turborepo#13280</a></li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/vercel/turborepo/commit/1506a114e377dd7e1e8e7a7863c42adf94a9f776"><code>1506a11</code></a>
publish 2.10.4 to registry</li>
<li><a
href="https://github.com/vercel/turborepo/commit/11a68c705274cc7a408776b576ce7a9e14d6e6df"><code>11a68c7</code></a>
fix: Stop flagging relative imports that resolve into node_modules in
boundar...</li>
<li><a
href="https://github.com/vercel/turborepo/commit/947b4784cd1b254e62b663bbdb22891a849b7442"><code>947b478</code></a>
fix: Raise the open-file soft limit at startup (<a
href="https://redirect.github.com/vercel/turborepo/issues/13282">#13282</a>)</li>
<li><a
href="https://github.com/vercel/turborepo/commit/ddc584d788349fc3668e280286f540feee4eb6b9"><code>ddc584d</code></a>
feat: Make turbo prune Cargo-aware (<a
href="https://redirect.github.com/vercel/turborepo/issues/13281">#13281</a>)</li>
<li><a
href="https://github.com/vercel/turborepo/commit/ff0d50822314c5b388d9b4daa9c6159387752d95"><code>ff0d508</code></a>
perf: Skip dependency-closure assembly for toolchains that derive
nothing (<a
href="https://redirect.github.com/vercel/turborepo/issues/1">#1</a>...</li>
<li><a
href="https://github.com/vercel/turborepo/commit/39d623e1323ef50e06be0a103082ae29cc545779"><code>39d623e</code></a>
feat: Make turbo watch Cargo-aware (<a
href="https://redirect.github.com/vercel/turborepo/issues/13280">#13280</a>)</li>
<li><a
href="https://github.com/vercel/turborepo/commit/af01fdfeb5efe07a7b6843a0b8f5033b59ebbb2c"><code>af01fdf</code></a>
fix: Collapse nested package-manager fallback conditional (<a
href="https://redirect.github.com/vercel/turborepo/issues/13279">#13279</a>)</li>
<li><a
href="https://github.com/vercel/turborepo/commit/7e02f94f647cb4d527a438313dc4adbe3e8c0df3"><code>7e02f94</code></a>
release(turborepo): 2.10.4-canary.2 (<a
href="https://redirect.github.com/vercel/turborepo/issues/13278">#13278</a>)</li>
<li><a
href="https://github.com/vercel/turborepo/commit/8e3a59fdb6c71ad24fbbb363db52f88eb9a89116"><code>8e3a59f</code></a>
release(library): 0.0.1-canary.23 (<a
href="https://redirect.github.com/vercel/turborepo/issues/13276">#13276</a>)</li>
<li><a
href="https://github.com/vercel/turborepo/commit/ce18f0a79eb49e9a22c7e6cfa491777c24ed746a"><code>ce18f0a</code></a>
test: Add end-to-end coverage for Cargo workspaces (<a
href="https://redirect.github.com/vercel/turborepo/issues/13274">#13274</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/vercel/turborepo/compare/v2.10.2...v2.10.4">compare
view</a></li>
</ul>
</details>
<br />

Updates `typescript-eslint` from 8.62.1 to 8.63.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/releases">typescript-eslint's
releases</a>.</em></p>
<blockquote>
<h2>v8.63.0</h2>
<h2>8.63.0 (2026-07-06)</h2>
<h3>🚀 Features</h3>
<ul>
<li><strong>eslint-plugin:</strong> [no-misused-promises] detect async
usage of a sync dispose usage (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12426">#12426</a>)</li>
</ul>
<h3>🩹 Fixes</h3>
<ul>
<li><strong>eslint-plugin:</strong> [method-signature-style] suggest
converting readonly function properties instead of emitting invalid
syntax (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12447">#12447</a>,
<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/issues/12446">#12446</a>)</li>
<li><strong>eslint-plugin:</strong> [no-unnecessary-type-assertion]
handle optional-chained calls to overloaded functions (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12491">#12491</a>,
<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/issues/12485">#12485</a>)</li>
<li><strong>eslint-plugin:</strong> [no-base-to-string] don't flag a
shadowed String() call (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12492">#12492</a>)</li>
<li><strong>scope-manager:</strong> export ClassStaticBlockScope (<a
href="https://redirect.github.com/typescript-eslint/typescript-eslint/pull/12460">#12460</a>)</li>
</ul>
<h3>❤️ Thank You</h3>
<ul>
<li>Evyatar Daud <a
href="https://github.com/StyleShit"><code>@​StyleShit</code></a></li>
<li>Kristjan <a
href="https://github.com/KristjanTammekivi"><code>@​KristjanTammekivi</code></a></li>
<li>Michael Naumov <a
href="https://github.com/mnaoumov"><code>@​mnaoumov</code></a></li>
<li>Serhii Leniv <a
href="https://github.com/Serhii-Leniv"><code>@​Serhii-Leniv</code></a></li>
<li>송재욱</li>
</ul>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.63.0">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md">typescript-eslint's
changelog</a>.</em></p>
<blockquote>
<h2>8.63.0 (2026-07-06)</h2>
<p>This was a version bump only for typescript-eslint to align it with
other projects, there were no code changes.</p>
<p>See <a
href="https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.63.0">GitHub
Releases</a> for more information.</p>
<p>You can read about our <a
href="https://typescript-eslint.io/users/versioning">versioning
strategy</a> and <a
href="https://typescript-eslint.io/users/releases">releases</a> on our
website.</p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/typescript-eslint/typescript-eslint/commit/290cf6cdcc5ffb00c5b8f3e1e0e9f2fd8cc96374"><code>290cf6c</code></a>
chore(release): publish 8.63.0</li>
<li>See full diff in <a
href="https://github.com/typescript-eslint/typescript-eslint/commits/v8.63.0/packages/typescript-eslint">compare
view</a></li>
</ul>
</details>
<br />

Updates `typedoc` from 0.28.19 to 0.28.20
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/TypeStrong/TypeDoc/releases">typedoc's
releases</a>.</em></p>
<blockquote>
<h2>v0.28.20</h2>
<h3>Features</h3>
<ul>
<li>Group/category section headings (<code>&lt;h2&gt;</code>) in the
default theme now include an <code>id</code> attribute so they can be
linked to via fragment identifiers (e.g.
<code>modules.html#classes</code>), <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/3029">#3029</a>.</li>
<li>Added a <code>@reexport</code> modifier tag to have TypeDoc convert
variable/type references as a re-export instead of a new symbol, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/3096">#3096</a>.</li>
<li>API: Introduced <code>generateOutputsBegin</code> and
<code>generateOutputsEnd</code> events on <code>Application</code> for
plugin use.</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>When <code>--emit none</code> is used, TypeDoc will now report
warnings about missing relative paths previously reported when
rendering, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/3078">#3078</a>.</li>
<li>Improved performance via asynchronously performing git and file
write operations, more performant JSX rendering, and source code
bundling, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/3103">#3103</a>.</li>
<li>A <code>@hidden</code> tag on a constructor parameter-property will
now only hide the property, not both the property and the parameter, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/3111">#3111</a>.</li>
<li>Custom <code>@group</code> and <code>@category</code> titles with
the same sort weight are now ordered consistently with the
<code>alphabetical</code> reflection sort, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/3120">#3120</a>.</li>
</ul>
<h3>Thanks!</h3>
<ul>
<li><a
href="https://github.com/greymoth-jp"><code>@​greymoth-jp</code></a></li>
<li><a
href="https://github.com/jonathanhefner"><code>@​jonathanhefner</code></a></li>
<li><a
href="https://github.com/kcastellino"><code>@​kcastellino</code></a></li>
<li><a href="https://github.com/Metbcy"><code>@​Metbcy</code></a></li>
<li><a
href="https://github.com/StoneCypher"><code>@​StoneCypher</code></a></li>
<li><a
href="https://github.com/wotan-allfather"><code>@​wotan-allfather</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/TypeStrong/typedoc/blob/master/CHANGELOG.md">typedoc's
changelog</a>.</em></p>
<blockquote>
<h2>v0.28.20 (2026-07-05)</h2>
<h3>Features</h3>
<ul>
<li>Group/category section headings (<code>&lt;h2&gt;</code>) in the
default theme now include an <code>id</code> attribute so they can be
linked to via fragment identifiers (e.g.
<code>modules.html#classes</code>), <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/3029">#3029</a>.</li>
<li>Added a <code>@reexport</code> modifier tag to have TypeDoc convert
variable/type references as a re-export instead of a new symbol, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/3096">#3096</a>.</li>
<li>API: Introduced <code>generateOutputsBegin</code> and
<code>generateOutputsEnd</code> events on <code>Application</code> for
plugin use.</li>
</ul>
<h3>Bug Fixes</h3>
<ul>
<li>When <code>--emit none</code> is used, TypeDoc will now report
warnings about missing relative paths previously reported when
rendering, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/3078">#3078</a>.</li>
<li>Improved performance via asynchronously performing git and file
write operations, more performant JSX rendering, and source code
bundling, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/3103">#3103</a>.</li>
<li>A <code>@hidden</code> tag on a constructor parameter-property will
now only hide the property, not both the property and the parameter, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/3111">#3111</a>.</li>
<li>Custom <code>@group</code> and <code>@category</code> titles with
the same sort weight are now ordered consistently with the
<code>alphabetical</code> reflection sort, <a
href="https://redirect.github.com/TypeStrong/TypeDoc/issues/3120">#3120</a>.</li>
</ul>
<h3>Thanks!</h3>
<ul>
<li><a
href="https://github.com/greymoth-jp"><code>@​greymoth-jp</code></a></li>
<li><a
href="https://github.com/jonathanhefner"><code>@​jonathanhefner</code></a></li>
<li><a
href="https://github.com/kcastellino"><code>@​kcastellino</code></a></li>
<li><a href="https://github.com/Metbcy"><code>@​Metbcy</code></a></li>
<li><a
href="https://github.com/StoneCypher"><code>@​StoneCypher</code></a></li>
<li><a
href="https://github.com/wotan-allfather"><code>@​wotan-allfather</code></a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/TypeStrong/typedoc/commit/34d843be0953fc81de0fde14bea8db72d0bbccc6"><code>34d843b</code></a>
Update changelog for release</li>
<li><a
href="https://github.com/TypeStrong/typedoc/commit/fbd4a254952c171b9ba7ebbe96c5151e844743be"><code>fbd4a25</code></a>
Bump version to 0.28.20</li>
<li><a
href="https://github.com/TypeStrong/typedoc/commit/93ba157000e4a632bfbf32a0b6f00f8ae57c7c99"><code>93ba157</code></a>
Update dependencies in example</li>
<li><a
href="https://github.com/TypeStrong/typedoc/commit/e8c5df8844edca9800dfc62cee9115ef0fba59ea"><code>e8c5df8</code></a>
Remove unnecessary files from distribution</li>
<li><a
href="https://github.com/TypeStrong/typedoc/commit/392b0dd50a428ea0c732c38c6c263e74cb6200b1"><code>392b0dd</code></a>
Update dependencies</li>
<li><a
href="https://github.com/TypeStrong/typedoc/commit/8510dd48c7778f419f4605146f1a733af27993fa"><code>8510dd4</code></a>
Add missing entries in changelog before release</li>
<li><a
href="https://github.com/TypeStrong/typedoc/commit/51dc0521890924269f06e08972c6453299f63cb5"><code>51dc052</code></a>
Update change log for 0.28.20 release</li>
<li><a
href="https://github.com/TypeStrong/typedoc/commit/72f20cd87b4ef30aae97b68fcbb42ca19cebdc22"><code>72f20cd</code></a>
Merge branch 'fix-locale-sort-group-category-titles' into dev</li>
<li><a
href="https://github.com/TypeStrong/typedoc/commit/623f2c0bd35b5e89cc79fb5783dac01c6f2530e9"><code>623f2c0</code></a>
Fix failing test, accept slightly slower build for now</li>
<li><a
href="https://github.com/TypeStrong/typedoc/commit/c8bdf14cab0c22dd415b6872cc647c6cf81f917c"><code>c8bdf14</code></a>
Minor config tweak to improve dev build time</li>
<li>Additional commits viewable in <a
href="https://github.com/TypeStrong/TypeDoc/compare/v0.28.19...v0.28.20">compare
view</a></li>
</ul>
</details>
<br />

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-13 13:54:29 +04:00
Alberto Schiabel 0de52639c4 feat(core)!: remove bare session aliases; freeze MCP SPI (#3780)
## What and why

This makes the intended v1 API cleanup real rather than postponing it to
v2:

- Remove the TypeScript root aliases `composio.create(...)` and
`composio.use(...)`. Session creation and reuse now live only at
`composio.sessions.create(...)` and `composio.sessions.use(...)`. This
is a deliberate breaking change, reflected by a major changeset.
- Retain `BaseProvider.wrapMcpServerResponse` as the stable v1 provider
SPI. Its earlier deprecation pointed to a method that was never
introduced.

The scope is intentionally narrow: it does **not** remove unrelated
deprecated APIs, and Python keeps its supported `Composio.create/use`
API. The TypeScript docs, examples, providers, runtime fixtures,
generated SDK reference, and API-reference indexes now use the
namespaced TypeScript API. Historical changelog examples are left as
history.

## Verification

- `pnpm typecheck`
- `pnpm --filter @composio/core test -- --run test/core/session.test.ts`
(42 files, 1,018 tests)
- `pnpm exec eslint ts/packages/core/src/composio.ts`
- `pnpm --filter @composio/core generate:docs`
- `cd docs && bun run generate:api-index`
- `cd docs && bun run types:check`
- `git diff --check` and targeted scans for removed TypeScript aliases

I also attempted the affected Node and Cloudflare runtime E2E suites.
They cannot initialize in this checkout without `COMPOSIO_API_KEY` (and,
for Cloudflare, `COMPOSIO_BASE_URL` and `OPENAI_API_KEY`); they did not
report a product assertion failure.
2026-07-13 13:22:55 +04:00
Alberto Schiabel a0f37a7f77 fix(core): SSRF guard on URL file inputs + telemetry secret redaction (#3779)
## What & why

Two v1 non-negotiable gates from the [SDK road to
v1](https://github.com/ComposioHQ/composio) plan are currently red. Both
are self-contained and closed here.

### ① SSRF guard on URL file inputs — `@composio/core`
`composio.files.upload(url)` and automatic file upload during tool
execution did a **raw `fetch()`** on user-supplied URLs
(`readFileContentFromURL`, `fileUtils.node.ts`) with no guard. Because
URL inputs deliberately bypass the local-path allowlist, a caller — or
an LLM-produced tool argument — could point the SDK at internal
infrastructure (`http://169.254.169.254/…` cloud metadata, RFC1918
hosts) or a public URL that 3xx-redirects into internal space.

New `ssrfGuard.node.ts`:
- resolves the host and refuses **private, loopback, link-local (incl.
`169.254.169.254`), CGNAT, TEST-NET, benchmarking, multicast, and
reserved** ranges (IPv4 + IPv6, incl. IPv4-mapped / NAT64);
- validates the **resolved address**, not the hostname string, so
decimal/octal/hex IP obfuscation doesn't slip through;
- rejects non-`http(s)` schemes;
- follows redirects **manually** so every hop is re-validated;
- blocked requests throw the new `ComposioBlockedInternalUrlError`.

Behaviour for legitimate public URLs is unchanged. Node-only path. Known
residual (documented in-file): a DNS-rebinding TOCTOU window between our
lookup and `fetch`'s connect — closing it fully needs connect-time IP
pinning (a custom dispatcher), out of scope here.

### ② Telemetry secret redaction — `@composio/core`
Error telemetry shipped `error.message` / `error.stack` **verbatim** to
`telemetry.composio.dev` with zero redaction. New `redact.ts` runs at
the single chokepoint (`prepareAndSendErrorTelemetry`) and strips URL
query strings, `Authorization` bearer/basic credentials, and secret-like
`key=value` pairs (API keys, tokens, client secrets, passwords) before
transport.

## Tests
- `ssrfGuard.test.ts` — IP classification (v4/v6, mapped, CGNAT,
metadata), scheme rejection, resolve-to-internal, "any resolved address
internal" pinning bypass, redirect-into-internal, redirect budget.
- `redact.test.ts` — URL query, bearer/basic, key/value secrets, quote
preservation, benign text untouched.
- Updated `fileUtils.test.ts` to mock DNS (hermetic) and expect
`redirect: 'manual'`.
- `tsc --noEmit` clean; lint clean.

## Notes
- `patch` changeset included.
- Adds `ComposioBlockedInternalUrlError` to the public error exports.
2026-07-10 19:35:10 +04:00
dependabot[bot] 4baacbeb77 chore(deps): bump the npm-production group across 1 directory with 7 updates (#3799)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions


</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: jkomyno <alberto@composio.dev>
2026-07-10 19:06:45 +04:00
Rahul Tarak a13c883845 docs: package-manager picker for install commands (#3802)
## 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>
2026-07-10 06:33:42 -07:00
Rahul Tarak caef908075 docs: refresh README(s) (#3801)
## Summary

Rewrites the stale root `README.md` against the current docs (structure
modeled on [earendil-works/pi](https://github.com/earendil-works/pi)'s
README).

- **Quickstarts** now use the session-based API (`composio.create()` →
`session.tools()`) that the docs treat as canonical, replacing the
legacy `composio.tools.get()` flow
- **Positioning** matches the docs welcome page: 1000+ pre-authenticated
toolkits, per-user sessions, auth, triggers, and a sandbox
- **New sections**: CLI install (curl / Homebrew / npm),
sessions-via-MCP note, repository layout, minimum runtime versions
- **Provider table** merged with package links; adds the Claude Agent
SDK providers (both SDKs) and the experimental Pi provider
(`@composio/experimental`); documents the Python
`composio-gemini`/`composio-google`/`composio-google-adk` split
- **Removed**: Rube section (no longer in docs), cover banner (replaced
with theme-adaptive brand logomark from brand.composio.dev),
master-branch pointer, internal OpenAPI-pull section, private
`@composio/ts-builders` listing

Docs-only change — no changeset needed.

## Preview

Rendered view: [README.md on this
branch](https://github.com/ComposioHQ/composio/blob/docs/refresh-root-readme/README.md)

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 06:14:38 -07:00
Alberto Schiabel b07fcada3f feat(experimental): add Eve provider and iMessage example (#3800)
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>
2026-07-10 16:57:11 +04:00
Alberto Schiabel 30ba4d2930 feat(openai): add executable provider example (#3798)
This PR:

- builds on top of https://github.com/ComposioHQ/composio/pull/3790
- makes the OpenAI example executable in direct-tools, Tool Router,
smoke, and Cloudflare Workers modes
- keeps direct and Tool Router agents in separate files so each
execution model is explicit and readable
- requires a successful Composio tool execution before either agent can
accept a final model response
- adds OpenAI to the nightly staging matrix without weakening the
existing Mastra coverage
- updates two stale experimental OpenAI usages so the complete example
package typechecks against current SDK APIs

## Testing

- `pnpm --filter openai-example run typecheck`
- `pnpm --filter openai-example run lint` (0 errors; 4 pre-existing
warnings)
- `pnpm --filter openai-example run smoke` (staging: 5 direct tools and
6 Tool Router tools)
- `pnpm --filter openai-example run cf:dry-run`
- `pnpm run typecheck`
- `./node_modules/.bin/eslint ts/packages --ext .ts,.tsx`
- `pnpm run typecheck:examples`
- `pnpm run lint:examples`
- `pnpm exec turbo cf:dry-run --filter='./ts/examples/*'`
- [branch
nightly](https://github.com/ComposioHQ/composio/actions/runs/29079263571):
OpenAI and Mastra both passed smoke, direct-tools, and Tool Router
against staging

## Post-deploy validation

- dispatch `ts.examples-nightly.yml` on `next` after merge and confirm
both matrix legs stay green
- healthy runs finish within the 20-minute job budget and log successful
tool-backed responses for both agent modes
- revert this PR if the OpenAI leg blocks the nightly; examples
maintainers own the first post-merge run and the next 06:00 UTC schedule

---

[![Compound
Engineering](https://img.shields.io/badge/Built_with-Compound_Engineering-6366f1)](https://github.com/EveryInc/compound-engineering-plugin)
![Codex](https://img.shields.io/badge/GPT--5-000000)
2026-07-10 13:41:59 +04:00
Alberto Schiabel 7ae0d7f735 chore: remove dead code across repo (#3786)
## What

Removes orphaned files and stale config that nothing references — a
follow-up to the root `Dockerfile` cleanup (#3783), which surfaced that
we'd accumulated dead code.

| Removed | Why it's dead |
|---|---|
| `test-exports.ts` | Throwaway debug script — `console.log`s schema
internals and imports from `ts/packages/core/dist/` (a build artifact
absent on a clean checkout). Zero references. |
| `.codex` | Empty 0-byte file, accidentally committed. Every `.codex`
reference in the code means `~/.codex` (the Codex CLI home dir), not
this. |
| `ts/docs/api/mcp.old.md` | Orphaned `.old` doc, superseded by
`ts/docs/api/mcp.md`. Not linked anywhere. |
| `pnpm-workspace.yaml` → `ts/packages/wrappers/*` | Workspace glob
pointing at a directory that doesn't exist. |
| `docs/examples/{app-connections-dashboard, workplace-search,
support-agent, background-agent}` | Example dirs not wired into the docs
build **and** absent from `docs/decisions/cookbooks-revamp-plan.md` —
unlike their siblings (`chat-app`, `pr-review-agent`, …) which are
explicitly staged WIP cookbooks. Zero references in the tree. |

## Verification

Each item was traced with `git grep` over tracked files (excluding
lockfiles / generated data) and confirmed to have no consumers in code,
CI, docs nav, or build config. Python side was audited too and is clean
(no `.bak`/`.old` files, all scripts/providers/modules wired).

## Note

If any of the four `docs/examples/` dirs are undocumented cookbook
drafts rather than truly abandoned, shout and I'll restore them — they
just aren't referenced or tracked in the revamp plan today.

A follow-up PR adds **Knip** (TS) + **Vulture** (Python) to CI so this
class of rot gets caught automatically.
2026-07-10 11:43:20 +04:00
Alberto Schiabel b0a02c9693 feat(examples): make validation provider agnostic (#3790)
This PR:

- makes example typecheck, lint, and Workers dry-runs discover packages
by script presence instead of a Mastra-only filter
- runs the nightly staging suite as a provider matrix, starting with
Mastra and failing when a matrix package is missing
- keeps direct and Tool Router agents explicit while sharing the Tool
Router agent between Node.js and Cloudflare Workers
- keeps root ESLint rules in Turbo's lint cache key and documents both
Worker secrets

## Testing

- `pnpm run typecheck`
- `pnpm run typecheck:examples`
- `./node_modules/.bin/eslint ts/packages --ext .ts,.tsx` (0 errors; 72
existing warnings)
- `pnpm run lint:examples`
- `pnpm exec turbo cf:dry-run --filter='./ts/examples/*'`
- confirmed Turbo includes `eslint.config.mjs` in the Mastra lint task
inputs
- confirmed a missing provider package fails instead of silently passing
the nightly smoke step

## Post-Deploy Monitoring & Validation

- after merge, dispatch `ts.examples-nightly.yml` on `next` and confirm
the `mastra examples against staging` matrix leg runs smoke,
direct-tools, and Tool Router successfully
- healthy signal: smoke reports wrapped tools and both agent steps
return non-empty output
- failure signal: workflow logs contain `SMOKE FAIL`, `Agent returned
empty output`, `No projects matched`, or a secret preflight error;
revert this PR if the foundation gate begins false-passing or blocking
unrelated example work
- validation window and owner: the first post-merge dispatch plus the
next scheduled 06:00 UTC nightly, owned by the TypeScript examples
maintainers

---

[![Compound
Engineering](https://img.shields.io/badge/Compound-Engineering-6C5CE7)](https://github.com/EveryInc/compound-engineering-plugin)
![Codex](https://img.shields.io/badge/GPT--5-000000)
2026-07-10 11:42:59 +04:00
Alberto Schiabel cbd1a374fd fix(examples): give the Mastra agents a step budget so tool-router returns output (#3789)
## What

Add `stopWhen: stepCountIs(10)` to both Mastra example agent entries
(`src/index.ts`, `src/tool-router.ts`).

## Why

The first nightly `workflow_dispatch` run of `ts.examples-nightly`
(after #3788 merged) failed on the **tool-router** example with `Agent
returned empty output`. `agent.generate(...)` had no step budget, so the
multi-step Tool Router flow (router `search` + `multi-execute`
meta-tools, then summarize) stopped after the first tool call and
produced no final text. The non-empty-output assertion added in #3788
turned that silent no-op into a loud failure — working as intended.

Every other tool-router example/e2e in the repo already sets a step
budget; this matches the Mastra tool-router e2e reference
(`ts/e2e-tests/runtimes/node/mastra-tool-router-zod-v4/e2e.test.ts` →
`stopWhen: stepCountIs(10)`).

## Verification

- `pnpm run lint:examples` and `pnpm run typecheck:examples` green.
- Nightly re-dispatch to confirm the tool-router example now returns
non-empty output against staging (follow-up once merged).

## Notes

- No changeset — example package is private/unpublished.
- `index.ts` passed without the budget but gets the same
`stepCountIs(10)` for robustness/consistency.
2026-07-10 02:08:53 +04:00
Alberto Schiabel 76881491d0 feat(examples): executable, CI-linked Mastra example (Tool Router + Workers) (#3788)
## What

Turns the **Mastra** example into an executable reference that doubles
as a test, and wires the examples into CI for the first time. First
slice of the v1 "executable examples" workstream — the pattern here is
the template for the other TS providers, then Python.

## Why

Examples under `ts/examples/*` were unverified: the only CI tie-in is
`validate-examples.ts`, which is transpile-only (no cross-file types, no
lint, no execution) and passes on exactly the schema-conversion
regressions we keep hitting in the Mastra provider — all closed but
unprotected:

- https://github.com/ComposioHQ/composio/issues/2109 (zod→json
serialization crash)
- https://github.com/ComposioHQ/composio/issues/3307 (`$defs` dropped
while `$ref` kept)
- https://github.com/mastra-ai/mastra/issues/13909 (already-JSON-Schema
tools crash serialization)

## Changes

**Canonical Mastra example** (`ts/examples/mastra`)
- `src/index.ts` — direct tools on the unauthenticated `HACKERNEWS`
toolkit
- `src/tool-router.ts` — v1-canonical `composio.sessions.create(...)` →
`session.tools()` (drops the deprecated bare `composio.create` alias)
- `src/cloudflare.ts` — the same wrapping path on the Cloudflare Workers
runtime (`export default { fetch }`)
- `src/smoke.ts` — deterministic wrapping + tool-router assertions
(needs only `COMPOSIO_API_KEY`)
- Removed the old Gmail/MCP entries that used deprecated APIs and
required auth
- Runnable via `bun ts/examples/mastra/src/{index,tool-router}.ts`

**Real typecheck + lint** (examples previously escaped both)
- Example now has a `typecheck` script (Node + Worker tsconfigs);
`typecheck:examples` / `lint:examples` scripts added
- eslint now covers `ts/examples/**` with type-safety rules kept
(`no-explicit-any`) and console noise allowed

**Two-tier CI**
- `ts.examples.yml` — per-PR **blocking**, no secrets: build → typecheck
→ lint → `wrangler deploy --dry-run`. This is the tier that catches the
schema-conversion regressions, since a dropped `$defs`/`$ref` surfaces
as a **type** error.
- `ts.examples-nightly.yml` — **non-blocking**, scheduled: executes
against the **staging** backend with secrets; runs the deterministic
smoke always and the full agent examples when an LLM key is set.

## Verification

Locally against staging: `smoke` passes (5 direct + 6 tool-router
tools), `typecheck:examples` and `lint:examples` are green, the Worker
`wrangler deploy --dry-run` bundles, and seeded regressions (a type
error / an `any`) correctly fail their gate.

## Notes

- No changeset — example packages are private/unpublished.
- Follow-ups (separate PRs): template the pattern to the other TS
providers, then port to `python/examples/*`.
2026-07-10 01:40:03 +04:00
Alberto Schiabel 72eac88133 fix(cli): replace abandoned decompress dependency (GHSA-mp2f-45pm-3cg9) (#3767)
This PR:
- replaces `decompress` (unmaintained; the zip-slip fix in the GHSA
advisory was never published to npm past 4.2.1) with `extract-zip`
across the CLI's four zip-extraction call sites: `install-skill.ts`,
`run-companion-modules.ts`, `upgrade-binary.ts`, and
`cli-local-tools/bundled-binaries.ts`
- `extract-zip` validates each entry resolves inside the target
directory before writing, closing the path-traversal issue `pnpm audit`
flags as critical
- replaces the one `.tgz`-extracting call site
(`scripts/_acp-adapters.ts`, used to vendor ACP adapter binaries at
build time) with `tar`, since `extract-zip` only handles zip archives
- removes `@types/decompress`; both `extract-zip` and `tar` ship their
own type definitions
- `pnpm audit --prod --audit-level=high` now passes (previously failing
on `next`, unrelated to #3766)

Verified `extract-zip` and `tar` extract nested directories correctly
with a local smoke test (real `.zip`/`.tgz` archives), in addition to
the existing `@composio/cli` (724 tests) and `@composio/cli-local-tools`
(13 tests) suites passing.
2026-07-07 18:58:17 +04:00
Alberto Schiabel b847a2cfd3 fix(core): stop misclassifying local paths starting with "http" as URLs (#3766)
This PR:
- fixes a `startsWith('http')` check in the TypeScript SDK that
misclassified local paths such as `http_export/report.csv` or
`http_backup/.ssh/id_rsa` as URLs
- the misclassification routed those paths through the URL-fetch branch,
which skips both the upload allowlist (`assertPathInsideUploadDirs`) and
the sensitive-path denylist (`assertSafeFileUploadPath`, added in #3763
for GHSA-hp3h-89pf-5q58)
- replaces the naive prefix check with `isHttpUrl()`, a `new
URL()`-based check in `fileUtils.node.ts`, matching the Python SDK's
existing `_is_url()` behavior (`urlparse` + scheme check), which was not
affected by this bug
- updates the three call sites that used the naive check:
`fileUtils.node.ts` (`readFile`, `getFileDataAfterUploadingToS3`) and
`FileToolModifier.node.ts` (`beforeFileUpload` source classification)
- adds a regression test asserting a path like `http_export/.aws/creds`
is still blocked by the sensitive-path denylist rather than routed to
`fetch`
2026-07-07 18:03:17 +04:00
Anas Khan 040ffd49a2 chore(cli): remove dead duplicate maybe-advice-spans-usage file (#3757)
The captured-errors pretty-printer in the CLI has two files that export
the same
`maybeAdviseSpansUsage` symbol:

-
`ts/packages/cli/src/effect-errors/pretty-print/captured-errors/maybe-advise-spans-usage.ts`
(the live one, spelled `advise`), re-exported by
`captured-errors/index.ts` and
  consumed by `format-captured-error.ts`.
-
`ts/packages/cli/src/effect-errors/pretty-print/captured-errors/maybe-advice-spans-usage.ts`
(spelled `advice`), which is never exported through the barrel and never
imported
  anywhere.

The `advice` file is a leftover from an `advice -> advise` rename: both
files were
originally introduced identical, and only the `advise` copy was later
updated (its
leading `''` became `' '` for color-contrast spacing) and wired up. The
`advice`
copy has since sat as unreferenced dead code that still returns the
stale
pre-fix value. It ships in the bundle as dead code and is a copy-paste /
confusion
hazard. This PR deletes it.

No linked issue (self-identified cleanup).

Fixes #

## Changes
- Delete the unused, stale duplicate
`ts/packages/cli/src/effect-errors/pretty-print/captured-errors/maybe-advice-spans-usage.ts`.
The live `maybe-advise-spans-usage.ts` is unchanged and remains the only
exported/imported copy.

## Type of change
- [ ] Bug fix
- [ ] New feature
- [x] Refactor/Chore
- [ ] Documentation
- [ ] Breaking change

## How Has This Been Tested?
Confirmed the removed file is unreferenced, then ran the CLI's checks
with the
deletion in place (local Node 26 / pnpm 10; CI will verify the pinned
toolchain):

- Unreferenced check: searched the repo for both the path
`maybe-advice-spans-usage`
and the token `advice` under `ts/packages/cli/src/` -> 0 matches. Only
the live
`./maybe-advise-spans-usage` is re-exported by
`captured-errors/index.ts`, and
`format-captured-error.ts` imports `maybeAdviseSpansUsage` through that
barrel.
- Build workspace deps: `pnpm run build:packages` -> all packages built.
- Typecheck (required when touching CLI code, per
`ts/packages/cli/AGENTS.md`):
`pnpm exec turbo typecheck --filter=@composio/cli --force` -> pass,
fully
re-executed (no cache). A missing-module error would surface here if
anything had
  imported the deleted file.
- Lint: `pnpm exec eslint ts/packages/cli/src/effect-errors --ext .ts`
-> clean.
- Tests: `pnpm exec vitest run` in `ts/packages/cli` -> 720 passed, 1
skipped,
  80 files. No regressions.

## Screenshots (if applicable)
N/A.

## Checklist
- [x] I have read the Code of Conduct and this PR adheres to it
- [x] I ran linters/tests locally and they passed
- [x] I updated documentation as needed (none needed; internal dead
code)
- [x] I added tests or explain why not applicable
- [x] I added a changeset if this change affects published packages

Tests: not applicable. This is a pure deletion of unreachable code with
no
behavior change; nothing references the file, so there is nothing to
regression-test. The live `maybeAdviseSpansUsage` path is already
exercised by the
existing effect-errors tests via `format-captured-error`.

Changeset: not needed. The CLI package is not published to npm and this
is an
internal, non-published-surface change.

## Additional context
Git history for the curious: both files were introduced identical in
`333b03c3b`;
the live `maybe-advise-spans-usage.ts` diverged in `fe5acc7d7` (leading
`''` -> `' '`
for color contrast) and became the wired-up copy, leaving
`maybe-advice-spans-usage.ts`
behind as the stale duplicate removed here.

Co-authored-by: Alberto Schiabel <jkomyno@users.noreply.github.com>
2026-07-07 12:22:23 +00:00
Alberto Schiabel fc17c37bf9 fix(cli): enforce sensitive-file upload denylist (GHSA-hp3h-89pf-5q58) (#3763)
This PR:

- fixes #3746 / GHSA-hp3h-89pf-5q58 — the CLI's tool file-upload path
bypassed the sensitive-file denylist
- **root cause:** the denylist was enforced at the *caller* layer, so
`@composio/cli`'s duplicate upload path (`readFileFromDisk`) read and
uploaded any local path a tool argument pointed at — `~/.ssh/id_rsa`,
`~/.aws/credentials`, `.env`, etc. — enabling credential exfiltration
via `composio execute` / `composio run` (incl. LLM-driven agents hit by
prompt injection)
- **unified fix:** one canonical guard, exported from `@composio/core`
and enforced at the read primitive in every SDK
- `core`: the guard now routes fs/path access through the internal
`#platform` abstraction (adds a `realpathSync` method), so it carries
**no static `node:*` imports** and is exported from the package root:
`assertSafeFileUploadPath`, `isBlockedSensitiveFileUploadPath`,
`BUILTIN_FILE_UPLOAD_PATH_DENY_SEGMENTS`
- `cli`: `readFileFromDisk` calls the shared `assertSafeFileUploadPath`
before `fs.readFile`; URLs and `File` objects are unaffected (matches
core)
- `python`: already routes all uploads through the guarded
`FileUploadable.from_path` — no functional change; adds regression tests
for parity
- supersedes #3755, which exported the then-node-only guard from core's
**main** `index.ts` and would have injected `node:fs` into the shared
`dist/index.mjs` (the workerd/edge-light entry), likely breaking
Cloudflare Workers / Vercel Edge
- changesets: `@composio/core` minor (new public exports),
`@composio/cli` patch (security fix)

## Verification

- core: full suite passes (997), incl. new root-export +
realpath-symlink cases
- **edge bundle stays clean**: built `dist/index.mjs` has no static
`node:*` imports and reaches the platform only via `#platform`
- cli: new regression test drives the real `uploadToolInputFiles →
readFileFromDisk → guard` chain — `~/.ssh/id_rsa` and `.env` throw
`ComposioSensitiveFilePathBlockedError` before any `createPresignedURL`
call; a normal file still uploads
- python: `test_files.py` + sensitive-path suite pass (145), incl. 3 new
`from_path` guard tests
- `tsgo` typecheck + eslint clean for core and cli
2026-07-07 00:30:40 +04:00
Alberto Schiabel 820abb9072 fix(sdk): resolve toolkit versions case-insensitively in both SDKs (#3762)
## Summary

Toolkit version maps are keyed by **normalized (lowercase) slugs** on
the *write* side — env vars (`COMPOSIO_TOOLKIT_VERSION_*`) and
user-supplied dicts both get their keys lowercased when the map is
built. But the *lookup* read the map with the **raw slug**. A pin
configured under a different casing (e.g. `{ "GitHub": "20250101_00" }`
or `COMPOSIO_TOOLKIT_VERSION_GITHUB` looked up as `GitHub`) therefore
missed the map and silently fell back to `"latest"`, which
`Tools.execute` then rejects with a version-required error — discarding
the user's explicit pin.

Rather than patch only the read side, this **centralizes the
normalization rule** into a single helper per SDK and routes **both**
the map-building (write) and lookup (read) paths through it, so the two
sides can never drift apart again:

- **Python** — `normalize_toolkit_slug()` in
`python/composio/utils/toolkit_version.py`
- **TypeScript** — `normalizeToolkitSlug()` in
`ts/packages/core/src/utils/toolkitVersion.ts`, imported by
`getToolkitVersionsFromEnv` in `sdk.ts`

Behavior is now identical across the two SDKs. This **supersedes
#3759**, which patched only the Python read side and left TS diverging.

## Backend verification

Confirmed against the backend (staging, **1403 toolkits across 15
pages**): every toolkit `slug` is already lowercase (the mixed-case
`name` field is display-only). So the *primary* execute path — which
resolves via `tool.toolkit.slug` — was never broken in practice. This
change:

- **hardens** the direct-util and mixed-case-config paths (a user
passing `{ "GitHub": "…" }` now resolves as expected), and
- **removes a latent cross-SDK divergence**: the TS suite previously
asserted `getToolkitVersion` was *case-sensitive* (`versions.test.ts`),
locking in the bug for an input the production code path can't actually
produce. That test is flipped to assert case-insensitive resolution.

## Tests

- **Python** (`python/tests/test_toolkit_version.py`): case-insensitive
lookup via `get_toolkit_versions` round-trip, and against a raw
pre-normalized map. `18 passed`.
- **TypeScript** (`ts/packages/core/test/core/versions.test.ts`):
replaced the case-sensitivity assertion with case-insensitive resolution
+ a write→read round-trip of a mixed-case user pin. Full core suite `997
passed`.
- Typecheck (`tsc --noEmit`) clean; `ruff` clean.

## Notes

- Changeset added: `@composio/core` patch.
- No public API change; the fix is behavioral (case-insensitive) plus an
internal shared helper.
2026-07-06 15:30:06 +04:00
Alberto Schiabel 58bc93b2d9 chore(deps): consolidate dependency updates (#3760)
This PR:
- consolidates https://github.com/ComposioHQ/composio/pull/3733,
https://github.com/ComposioHQ/composio/pull/3735 through
https://github.com/ComposioHQ/composio/pull/3744, and
https://github.com/ComposioHQ/composio/pull/3752
- refreshes the pnpm workspace dependencies under the existing
`minimumReleaseAge` supply-chain gate
- keeps latest compatible pins for ESLint 9, AI SDK 6, and Cloudflare
workers types 4 where latest majors conflict with the current workspace
- keeps zod-v3 runtime fixtures on `zod@3.25.76` while bumping the
workspace catalog to zod 4
- bumps Python `composio-client` to `1.42.0` and refreshes `uv.lock`
- updates the SHA-pinned Claude and Codex workflow actions from the
Dependabot action group
- adds a patch changeset for the versioned package manifests touched by
dependency updates
- verifies the rollup with frozen pnpm/uv locks, peer checks, audit
threshold checks, typecheck, lint, builds, TypeScript tests, and Python
`nox -s chk`

## Context

`pnpm audit --prod --audit-level=moderate` passes. The remaining
production audit item is a low `@ai-sdk/provider-utils` advisory through
Mastra transitive dependencies; forcing it higher would require leaving
the compatible stable Mastra dependency path.
2026-07-06 14:33:55 +04:00
Alberto Schiabel 8d5823be87 chore(ci): cache turbo, bun, and uv and cancel superseded pr runs (#3747)
This PR:

- adds `concurrency` to the ten PR/push CI workflows: superseded **PR**
runs are cancelled, while push runs use a per-run group
(`github.run_id`) so every commit on `next`/`master` still gets its own
run
- caches turbo outputs (`.turbo/cache`) via a new opt-in
`enable-turbo-cache` input on the `setup-node-pnpm-bun` composite (keyed
per job — concurrent jobs save different task graphs), enabled in
`ts.build`, `ts.test`, `ts.typecheck`, and all four `ts.test-e2e` jobs
- enables turbo caching for `typecheck`, removes the incorrect `dist/`
outputs from `test`, hashes root `tsconfig.base.json` in
`build`/`typecheck` inputs, and adds `mise.toml`/`mise.lock` to
`globalDependencies` so toolchain bumps bust every task hash (addresses
the Bugbot finding)
- fixes `@composio/slim`'s build to participate in the turbo graph: core
moves to slim's `devDependencies` (published `dependencies` unchanged)
and the script no longer shells out to `pnpm --filter @composio/core
build`, which raced concurrent dependents by wiping `core/dist`
mid-build and double-built core on every cold run — slim's `dist`
remains byte-identical to core's; no changeset added since the published
artifact is unchanged (say the word if policy wants one anyway)
- fixes the `py.test` matrix cache to `~/.cache/uv` (it cached
`~/.cache/pip` while installing via `uv pip`) and caches
`~/.bun/install/cache` in the five docs workflows
- adds `turbo.jsonc` to the TS workflows' path filters (previously
unwatched)
- release/publish workflows are deliberately untouched

Measured (same commit, cold first attempt vs `gh run rerun` warm):
ts.build 103s → 53s, ts.test 157s → 55s (`turbo test` 24/24 cached in
182ms), ts.typecheck 80s → 43s; py.test legs save a few seconds each (uv
was already fast). Warm floor is checkout + mise + pnpm-install
overhead.

## Context

Implements `plans/001-ci-speed-caching-and-concurrency.md` from the
advisor audit on `docs/sdk-v1-decision-records`. Implementation by codex
against the plan, then self-reviewed and counter-reviewed; warm-rerun
testing surfaced and fixed three latent issues (toolchain files absent
from turbo's hash, first-writer-wins cache-key collision across jobs,
and the slim out-of-band core rebuild race).
2026-07-03 22:22:18 +04:00
Alberto Schiabel e78ed312c6 fix(core): run all parallel OpenAI tool calls from the first choice (#3726)
This PR:

- supersedes https://github.com/ComposioHQ/composio/pull/3712,
preserving the original commits by @serhiizghama (kept as
author/co-author)
- fixes `OpenAIProvider.handleToolCalls` to execute **every** tool call
in an assistant message — it previously only read `tool_calls[0]`, so
parallel tool calls (on by default) were dropped and their
`tool_call_id`s went unanswered, failing the next request with the "must
be followed by tool messages responding to each `tool_call_id`" error
- limits execution to the **first choice** — with `n > 1` the previous
loop ran each tool call once per choice and orphaned the `tool_call_id`s
belonging to the alternative completions
- aligns the Python SDK (`OpenAIProvider.handle_tool_calls`) with the
same first-choice behavior so both SDKs stay in parity
- fixes the stale `@composio/openai` test that modeled "multiple tool
calls" as separate `n` choices rather than one message's `tool_calls`
array
- clarifies in the changeset that the calls run **sequentially**, in the
order the model returned them (here "parallel" means the model issued
several calls in one turn, not concurrent execution), so each
`tool_call_id` is answered exactly once and deterministically
- adds regression tests (TS + Python): both calls run for parallel tool
calls in one message, and only the first choice runs when `n > 1`

Full `@composio/core` (996) and `@composio/openai` suites green; Python
`handle_tool_calls` tests, Ruff, and mypy clean; `tsc` clean.

---------

Co-authored-by: serhiizghama <zmrser@gmail.com>
2026-07-02 13:27:49 +04:00
Alberto Schiabel a69c3edea3 fix(triggers): align create() user_id resolution across SDKs (#3723)
This PR:

- builds on top of https://github.com/ComposioHQ/composio/pull/3714 —
addresses its code-review findings
- restores TS/Python parity on slug validation: Python `create()` now
validates the slug up-front and raises a new `TriggerTypeNotFound`,
mirroring the TS `ComposioTriggerTypeNotFoundError`
- switches both SDKs to the native `user_id` upsert field — TS drops the
`& { user_id }` intersection and Python drops the `extra_body` shim
(both pinned clients already expose the field)
- treats a blank/whitespace `userId` (TS) or
`user_id`/`connected_account_id` (Python) as missing instead of
forwarding it to the backend
- documents the error-contract change (`create()` no longer throws
`ComposioConnectedAccountNotFoundError` — that case now surfaces from
the backend) in the changeset and `ts/docs/api/triggers.md`, and bumps
the changeset from `patch` to `minor`
- adds Python tests for the 2FA (both-provided) path, unknown-slug, and
blank `userId`; tightens the TS auto-resolve assertion and adds an
empty-`userId` case

## ⚠️ Release gating

Since #3714, `triggers.create()` (both SDKs) relies on the backend
resolving the trigger connection from `user_id` on upsert
([ComposioHQ/platform#10932](https://github.com/ComposioHQ/platform/pull/10932)).
There is **no client-side fallback** — reintroducing one would undo
#3714's intent, so this is a release-sequencing requirement, not a code
change here.

- Do not release `@composio/core` or the Python SDK until #10932 is live
in all regions.
- Self-hosted / on-prem deployments must be on a backend version that
includes #10932.

## Review findings addressed

| # | Finding | Resolution |
|---|---------|------------|
| P1-1 | Coupled to unreleased backend, no fallback | Documented
dependency in changeset; flagged release-gating above (no fallback by
design) |
| P2-2 | Cross-SDK parity on slug validation | Kept `getType` in both;
added Python `TriggerTypeNotFound` mirroring TS |
| P2-3 | `user_id` bridge redundant in both SDKs | TS uses native field
directly; Python uses `user_id=` kwarg |
| P2-4 | Error-contract change shipped silently | Documented in
changeset + docs `Throws` section; `minor` bump |
| P2-5 | Python missing 2FA (both-provided) test | Added
`test_create_with_user_id_and_connected_account_id` |
| P3 6–13 | Cleanups | undefined-assertion, `none_to_omit`, docstring,
`parsedBody.data`, redundant `else`, stale comments, blank-string guard
|

## Verification

- TS: `vitest` 59 passed, `typecheck` clean, `eslint`/`prettier` clean
- Python: `pytest tests/test_triggers.py` 69 passed, `nox -s chk` (ruff
+ mypy) clean
2026-07-02 11:40:47 +04:00
Anshu Garg 20a4711ee0 feat(triggers): resolve connection from user_id server-side in create() (#3714)
## What

`triggers.create()` used to make an extra **`connectedAccounts.list()`**
call to turn a `user_id` into a `connected_account_id` before calling
upsert. The backend now resolves the connection from `user_id` directly
(picks the first active connection for the user + the trigger's toolkit,
parity with tool execution), so the SDK passes `user_id` straight
through and drops the round-trip.

- **TS** (`ts/packages/core`): removed the `connectedAccounts.list()`
block in `Triggers.create()`. `user_id` was already forwarded to upsert
(for 2FA); this just removes the now-redundant lookup. `getType` is kept
for an early, clear "trigger type not found" error.
`connected_account_id` is passed when the caller pins one.
- **Python** (`python/composio`): dropped
`_get_connected_account_for_user`; `user_id` is sent via `extra_body`
and `connected_account_id` is omitted when not provided.

## Why

The SDK only ever holds a `user_id`, so every `triggers.create()` paid
an extra API call to find a connection. The backend change
(ComposioHQ/platform#10932) makes trigger upsert accept `user_id` and
auto-resolve — this PR consumes that.

## Behavior notes

- When `connected_account_id` is omitted, the backend picks the first
active connection ordered by `created_at desc`. The TS SDK's old
`list()[0]` ordering was unspecified — selection is now deterministic
and consistent with tool execution.
- "No connected account found" / "connected account not found" now
surface from the **backend** instead of a client-side pre-check.
- When 2FA is enabled and `connected_account_id` is pinned, the backend
validates that `user_id` owns it (unchanged; `user_id` was already
forwarded).
- The `extra_body` / `& { user_id }` bridges are still needed only until
`@composio/client` / `composio_client` regenerate with `user_id` on the
upsert type (the field is already in the OpenAPI contract).

## Tests

- TS: `vitest run test/models/triggers.test.ts` → **58 passed** (create
tests rewritten to assert no `connectedAccounts.list()` call + `user_id`
forwarded).
- Python: `pytest tests/test_triggers.py` → **66 passed** (same).

## Depends on

Backend: ComposioHQ/platform#10932 (`feat(apollo): resolve trigger
connection from user_id on upsert (PLEN-2580)`).

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

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-02 01:05:07 +04:00
Alberto Schiabel 4c3a321550 fix(core): disable retries on non-idempotent tools.execute/proxyExecute (#3716)
This PR:

- Closes https://github.com/ComposioHQ/composio/issues/3586
- disables client retries on `tools.execute` and `tools.proxyExecute` —
the two non-idempotent writes — so a request that succeeds server-side
but times out client-side is no longer silently replayed (the cause of
duplicate `GMAIL_SEND_EMAIL` sends)
- routes both through a sibling client built with `withOptions({
maxRetries: 0 })`; reads keep the client's default retries (`maxRetries:
2`)
- caches that sibling per `Tools` instance (`clientWithoutRetries`)
since `withOptions` constructs a fresh client and execute/proxy is the
hottest path; mirrors the Python SDK's `client.without_retries`
- adds regression tests asserting both paths route through `maxRetries:
0` and that the sibling is built once across multiple executes

## Context

The original hang on attachments larger than ~25 KB was a backend defect
and has already been fixed server-side. The remaining gap was a
cross-SDK parity one: the Python SDK already disabled retries on these
non-idempotent writes, but `@composio/core` still inherited the client
default of 2 retries (3 attempts total), with no public knob to turn
them off. This is the TypeScript parity port — scoped to exactly
`tools.execute` / `tools.proxy`, leaving `toolRouter.session.execute`
and all reads on their default retry behaviour, matching Python.
2026-06-30 21:53:46 +04:00
Alberto Schiabel 03cb181fdb chore(deps): roll up dependency bumps (#3711)
This PR:
- rolls up https://github.com/ComposioHQ/composio/pull/3695,
https://github.com/ComposioHQ/composio/pull/3696,
https://github.com/ComposioHQ/composio/pull/3697, and
https://github.com/ComposioHQ/composio/pull/3698 into one
dependency-bump branch
- updates Python dependency metadata for `langchain-openai`,
`pyautogen`, and `crewai`
- updates npm production dependency metadata for `zod-to-json-schema`,
`openai`, and `@modelcontextprotocol/sdk`
- refreshes `uv.lock` and `pnpm-lock.yaml` with the repo-pinned package
managers
- leaves Changesets unchanged because the touched TS package manifests
are private/ignored and no published TS SDK package metadata changes
- verified with `pnpm install --frozen-lockfile`, `pnpm lint`, `pnpm
typecheck`, focused TS builds/tests, clean-worktree `pnpm
test:examples`, Python import tests, and Python nox checks
- note: local `pnpm build:packages` hit a pre-existing broad-build race
around `@composio/slim` rebuilding `@composio/core`; focused dependent
builds pass

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-29 19:20:15 +04:00
sdkrelease[bot] 156a1eb7b2 Release: update version (#3686)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to next, this PR will
be updated.


# Releases
## @composio/vercel@0.11.0

### Minor Changes

- 9ffc696: Add AI SDK 7 support to `@composio/vercel`. The `ai` peer
dependency range is now `^6.0.0 || ^7.0.0` (AI SDK 5 is no longer
supported; both v6 and v7 are covered by e2e compatibility tests).
## @composio/core@0.13.1

### Patch Changes

- 605a726: Add Tool Router session deletion APIs.
## @composio/mastra@0.10.1

### Patch Changes

- cddd66c: Update the supported `@mastra/core` peer dependency range.
## @composio/slim@0.13.1

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-27 00:49:27 +04:00
Alberto Schiabel 956f9be9b4 chore(agents): normalize repo guidance skills (#3666)
This PR:
- replaces the duplicated repo-local skill set with the requested
canonical `.agents/skills` taxonomy and short router `SKILL.md` files
backed by first-level references
- makes `.claude/skills` a compatibility symlink to `.agents/skills` and
removes hand-maintained Claude skill/rule copies
- moves docs agent guidance and decisions into neutral
`docs/agent-guidance/` and `docs/decisions/`, with `docs/CLAUDE.md`
reduced to a shim
- retires CLI Cursor rules after migrating CLI design, Effect source,
and client-cache sync guidance into `AGENTS.md` and `cli-command`
- adds nested `AGENTS.md` files for TS, core, providers, e2e, Python,
Python providers, and docs
- adds `pnpm validate:agent-skills` to validate skill frontmatter,
taxonomy, references, symlink invariants, stale paths, and command names
- implements missing Python `tst` and `snt` nox sessions that existing
Makefile targets already exposed
- no changeset: repository guidance/tooling only, no published SDK
package behavior

## Verification
- `pnpm validate:agent-skills` -> `Validated 14 canonical agent skills
and guidance invariants.`
- `for skill in .agents/skills/*; do python
/Users/jkomyno/.codex/skills/.system/skill-creator/scripts/quick_validate.py
"$skill" || exit 1; done` -> 14x `Skill is valid!`
- `pnpm --dir ts/packages/cli validate:skills` -> `Validated
composio-cli skill builds for stable and beta.`
- `cd python && uv run nox --list` -> includes `tst` and `snt`
- `cd python && uv run nox -s snt` -> 18 passed
- `cd python && uv run nox -s tst -- tests/test_imports.py` -> 8 passed
- `git diff --check` / `git diff --cached --check` -> clean
- stale reference search for retired docs/Claude/Cursor paths -> no
matches

## Forward Tests
- TypeScript core bug: loaded `bug-fixing`, `typescript-sdk`,
`typescript-testing`; found correct root/ts/core `AGENTS.md` route.
- Python provider: loaded `python-providers`, `python-testing`; found
missing nox sessions, fixed here.
- CLI command: loaded `cli-command`; found recording/changeset wording
gaps, fixed here.
- Cross-SDK drift: loaded `cross-sdk-parity`; again found Python nox
drift, fixed here.
- Docs + decision: loaded `docs-decisions`; found decision
template/index and Twoslash path gaps, fixed here.

## Notes
The first normal `git commit` attempt hit a lint-staged/Git stash
limitation while replacing `.claude/skills/` with a symlink (`path ...
beyond a symbolic link`). The final commit used `--no-verify` after the
validators and formatting checks above passed.
2026-06-27 00:35:57 +04:00
Alberto Schiabel cddd66c3ce chore(ts): bump Hono, Mastra, and Chrome deps (#3691)
This PR:
- bumps `hono`, `@mastra/core`, and `chrome-devtools-mcp` to their
current latest published versions
- routes the remaining Cloudflare Tool Router Hono consumer through the
workspace catalog
- updates the `@composio/mastra` `@mastra/core` peer range and adds a
patch changeset
- fixes `check-peer-deps` to resolve `semver` through the normal package
dependency
2026-06-26 20:45:25 +04:00
Alberto Schiabel acf8a9ca1f test(cli): cover fish completion install idempotency (#3688)
This PR:
- follows up on https://github.com/ComposioHQ/composio/pull/3440 and
credits Deepak Singh Kandari / @aptsalt from the original implementation
- builds on the fish completion fix already merged in
https://github.com/ComposioHQ/composio/pull/3162
- references https://github.com/ComposioHQ/composio/issues/3147
- adds regression coverage for running `composio install --completions`
twice under fish
- verifies `config.fish` keeps a single PATH marker and never receives
completion markers
- verifies `~/.config/fish/completions/composio.fish` keeps one
completion marker

## Testing
- `MISE_TRUSTED_CONFIG_PATHS=$PWD mise exec -- pnpm --filter
@composio/cli exec vitest run test/src/commands/install.cmd.test.ts`
- `MISE_TRUSTED_CONFIG_PATHS=$PWD mise exec -- pnpm --filter
@composio/cli typecheck:test`
- `git diff --check origin/next...HEAD`

Co-authored-by: Deepak Singh Kandari <deepaksinghkandari07@gmail.com>
2026-06-26 14:26:20 +04:00
Alberto Schiabel 9ffc696a99 feat(vercel): support AI SDK v7 (#3683)
This PR:

- widens the `ai` peer dependency of `@composio/vercel` to `^6.0.0 ||
^7.0.0`, adding AI SDK v7 support and dropping the previously-untested
v5 arm
- adds Docker-based Node e2e compatibility suites for AI SDK v6 and v7
under `ts/e2e-tests/runtimes/node/vercel-ai-sdk-v{6,7}`, auto-discovered
by the existing e2e matrix (so PR CI exercises them)
- each installs the packed `@composio/vercel` tarball, typechecks the
provider against the target `ai` major, and asserts runtime tool
wrapping/execution (object inputs, JSON-string normalization via
`normalizeToolArguments`, `ToolSet` shape)
- the v7 suite additionally exercises v7's `ToolExecutionOptions` passed
to `tool.execute`
- ships a `minor` changeset (the peer-range narrowing removes a
previously-supported major)
- breaking:
- `ai@5` is no longer an accepted peer of `@composio/vercel`; v5
consumers should stay on the prior minor
2026-06-26 14:08:09 +04:00
Abir Taheer 605a7263ab Add tool router session deletion (#3679)
## Summary
Explain the motivation and context for this change. Link to any related
issues.

Fixes #

## Changes
- 
- 

## Type of change
- [ ] Bug fix
- [ ] New feature
- [ ] Refactor/Chore
- [ ] Documentation
- [ ] Breaking change

## How Has This Been Tested?
Describe the tests you ran and instructions so reviewers can reproduce.
Include any relevant config/versions.

## Screenshots (if applicable)

## Checklist
- [ ] I have read the Code of Conduct and this PR adheres to it
- [ ] I ran linters/tests locally and they passed
- [ ] I updated documentation as needed
- [ ] I added tests or explain why not applicable
- [ ] I added a changeset if this change affects published packages

## Additional context

---------

Co-authored-by: jkomyno <alberto@composio.dev>
2026-06-26 12:38:28 +04:00
Alberto Schiabel 20bf1b6345 chore(ts): quiet tsdown build warnings (#3665)
This PR:
- migrates shared tsdown dependency config from deprecated `external` /
`noExternal` aliases to `deps.neverBundle` / `deps.alwaysBundle`
- disables noisy Rolldown plugin timing and ineffective dynamic-import
diagnostics in shared config while keeping build checks enabled
- fixes the `json-schema-to-zod` `JSONSchema7TypeName` import so it
stays type-only
- keeps the CLI bundle graph aligned with `next` while quieting the
dynamic-import warning through `checks.ineffectiveDynamicImport: false`
- makes the Node file E2Es treat the current external storage
`Unauthorized` upload response as an explicit `UPLOAD_UNAVAILABLE`/skip
outcome instead of failing unrelated SDK build PRs

Verification:
- `pnpm build`
- build log scan for `WARN`, deprecated `external` / `noExternal`,
`deps.onlyBundle`, `PLUGIN_TIMINGS`, and `INEFFECTIVE_DYNAMIC_IMPORT`
- `pnpm --dir ts/packages/cli test -- --runInBand`
- `pnpm --dir ts/e2e-tests/runtimes/node/file-roundtrip typecheck`
- `pnpm --dir ts/e2e-tests/runtimes/node/tool-router-files typecheck`
- `pnpm lint:packages`
- CI: TypeScript build/typecheck/test and Node 22/24/25, Deno,
Cloudflare, and CLI e2e are green on the latest commit
2026-06-26 12:17:33 +04:00
sdkrelease[bot] d102ab03ca Release: update version (#3676)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to next, this PR will
be updated.


# Releases
## @composio/core@0.13.0

### Minor Changes

- d17a268: Add the first-class `composio.sessions.create()` API while
keeping `composio.create()` as an alias, expose the experimental
shared-connection ACL patch helper as `connectedAccounts.updateAcl()`
while keeping `experimental.updateAcl()` as an alias, and include SDK
docs/source in the published package.

**MCP is now opt-in.** Sessions return native tools by default; the
hosted MCP endpoint is only surfaced on the type when you create the
session with `{ mcp: true }`. The default `create()` / `use()` now
return `SessionWithoutMcp` (the runtime object is unchanged —
`session.mcp` still exists at runtime — but it is no longer in the
type).

Migration: read `session.mcp` only after creating with `{ mcp: true }`.

- d17a268: Surface the resolved workbench config on Tool Router
sessions.

- `Session.workbench` is now populated from the API response (on
create/retrieve/attach/update). It exposes the resolved workbench
config, e.g. `session.workbench?.enable` (defaults to `true`
server-side).

This lets callers create a session with the remote workbench disabled
(`workbench: { enable: false }`) and detect that state — the foundation
for running code in a sandbox you own via the experimental
`@composio/experimental/workbench` helpers.

### Patch Changes

- d17a268: Prefer `sandbox` for session code-execution configuration
while continuing to accept the existing `workbench` alias.
- d17a268: Add `triggers.parse()` to parse and optionally verify
incoming webhook requests.
- d17a268: Add `triggers.setWebhookSubscription()` to create or update
the project webhook subscription from the TypeScript SDK.
## @composio/experimental@0.1.0

### Minor Changes

- d17a268: Add the experimental BYO local workbench helpers on the new
`@composio/experimental/workbench` subpath.

These let you run a Composio Tool Router session in a sandbox you own
instead of Composio's hosted remote sandbox:

- `experimental_createLocalWorkbenchSession(composio, session)` takes a
caller-created session and returns `{ helperSource, env }`. It throws
unless the session was created with `workbench: { enable: false }` (a
local sandbox and the remote workbench cannot both run for one session).
- `experimental_createWorkbenchEnv(options)` builds the environment
variables the in-sandbox helper needs to reach Composio.
- `experimental_createPythonWorkbenchHelperSource(options)` returns the
Python helper source.

The local workbench assumes code runs in the developer's sandbox and
exposes Apollo-parity Python helpers for `run_composio_tool`,
`invoke_llm`, `web_search`, and `proxy_execute`.

> **Security caveat:** the helper authenticates with the developer's
full _project_ API key, injected into the sandbox env as
`COMPOSIO_API_KEY`. Any code or tool output running in the sandbox can
read and exfiltrate it — treat the sandbox as your security boundary and
rotate the key. A session-scoped `x-session-access-key` (so the
long-lived project key never enters the sandbox) is the planned
follow-up.

- d17a268: Add an experimental package with a Pi coding-agent provider,
static Composio tool wrapping, and dynamic Tool Router session helpers.

### Patch Changes

- d17a268: Add `proxy_execute` to the experimental local workbench
helper. The in-sandbox helper from
`experimental_createLocalWorkbenchSession`
(`@composio/experimental/workbench`) now exposes `proxy_execute(method,
endpoint, toolkit, query_params=None, body=None, headers=None)`
alongside `run_composio_tool`, `invoke_llm`, and `web_search`, so a
local sandbox can make authenticated direct API calls to a connected
toolkit when no pre-built tool exists. It posts to the public
`…/session/{id}/proxy_execute` route with the session's project API key,
and always returns a `(data, error)` tuple.
## @composio/slim@0.13.0

### Minor Changes

- d17a268: Add a slim Composio core package that mirrors the built
`@composio/core` runtime and types without publishing the packaged
`docs/` or `src/` trees.
## @composio/cli@0.3.1

### Patch Changes

- Updated dependencies [d17a268]
- Updated dependencies [d17a268]
- Updated dependencies [d17a268]
- Updated dependencies [d17a268]
- Updated dependencies [d17a268]
  - @composio/core@0.13.0
  - @composio/cli-local-tools@0.1.1
## @composio/cli-local-tools@0.1.1

### Patch Changes

- Updated dependencies [d17a268]
- Updated dependencies [d17a268]
- Updated dependencies [d17a268]
- Updated dependencies [d17a268]
- Updated dependencies [d17a268]
  - @composio/core@0.13.0

Co-authored-by: Rahul Tarak <cryogenicplanet@gmail.com>
2026-06-25 18:54:17 -07:00
Rahul Tarak d17a268d3f docs: sessions-first rewrite — new guides, examples & components (+ core 0.13.0 SDK changes) (#3637)
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>
2026-06-25 18:27:43 -07:00
Alberto Schiabel de2657c30d fix(ts-builders): mark @composio/ts-builders private (do not publish to npm) (#3663)
Replaces #3662 with the opposite (correct) approach: keep
`@composio/ts-builders` **internal/unpublished**, not public.

This PR:

- marks `@composio/ts-builders` as `private: true` so changesets stops
attempting to publish it to npm

## Why

`@composio/ts-builders` is an internal AST-builder helper consumed
**only** by `@composio/cli` (`"@composio/ts-builders": "workspace:*"`).
`@composio/cli` is itself `private: true` and is distributed as
**bundled Bun binaries via GitHub releases**, not as an npm package — so
it bundles its workspace deps and never resolves them from npm. **No
package published to npm depends on `ts-builders`.**

It was simply missing `private: true`. With the repo-wide changeset
`access` default of `restricted` and no `publishConfig.access: public`
opt-in, the first-ever publish 404'd in the 2026-06-25 release:

```
E404 404 Not Found - PUT https://registry.npmjs.org/@composio%2fts-builders
```

## Consistent with existing CLI-only helpers

`@composio/cli-keyring` and `@composio/cli-local-tools` are already set
up exactly this way — `private: true`, consumed by the CLI via
`workspace:*`, intentionally **not on npm**. `ts-builders` now matches
them.

## Effect

- `changeset publish` skips private packages, so future release runs no
longer fail on `ts-builders`.
- The CLI keeps consuming it through the workspace (bundled into the
binary); npm resolution is never involved.
- The 14 packages already published on 2026-06-25 don't reference
`ts-builders`, so the published dependency graph is already
self-consistent — this only stops the spurious publish failure going
forward.

No version bump and no `publishConfig` needed.
2026-06-25 04:56:03 +04:00
sdkrelease[bot] 9764ce33ff Release: update version (#3616)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to next, this PR will
be updated.


# Releases
## @composio/core@0.12.0

### Minor Changes

- a0bef5d: Bump `@composio/client` to `0.1.0-alpha.74`.
- dfd7a08: Add per-request cancellation to public SDK methods via a new
`ComposioRequestOptions` (`{ signal?: AbortSignal }`) trailing argument,
plus a typed `ComposioRequestCancelledError` for detecting
caller-initiated aborts.

Without this, a slow `tools.get` or `tools.execute` had no way to be
cancelled — a 100s search would block the calling agent indefinitely.
The new shape:

  ```typescript
  try {
    const tools = await composio.tools.get(
      'user_1',
      { search: 'send email', limit: 50 },
      { signal: AbortSignal.timeout(5_000) }
    );
  } catch (err) {
    if (err instanceof ComposioRequestCancelledError) {
      return;
    }
    throw err;
  }
  ```

The signal is forwarded to the underlying `@composio/client` fetch. Any
abort error (`APIUserAbortError`, `AbortError`, or
`DOMException(name='AbortError')`) coming back is normalized to
`ComposioRequestCancelledError` so callers can `instanceof`-detect
cancellation without unwrapping nested causes. Catch-and-wrap paths in
`tools.execute` / `tools.getRawComposioToolBySlug` / `toolkits.get`
re-throw the cancellation error rather than remapping it to
`ComposioToolExecutionError` / `ComposioToolNotFoundError` /
`ComposioToolkitFetchError`.

  Wired through on:
- **Tools**: `get`, `getRawComposioTools`, `getRawComposioToolBySlug`,
`getRawToolRouterSessionTools`, `execute`, `executeSessionTool`,
`getToolsEnum`, `getInput`, `proxyExecute`
  - **Toolkits**: `get`, `listCategories`
- **AuthConfigs**: `list`, `create`, `get`, `update`, `delete`,
`updateStatus`, `enable`, `disable`
- **ConnectedAccounts**: `list`, `get`, `delete`, `refresh`,
`updateStatus`, `enable`, `disable`, `update`
- **Triggers**: `listActive`, `create`, `update`, `delete`, `enable`,
`disable`, `listTypes`, `getType`, `listEnum`
  - **MCP**: `create`, `list`, `get`, `delete`, `update`, `generate`
- **ToolRouter** (`composio.create` / `composio.use`,
`composio.toolRouter.create` / `.use`) — long-running session-creation
paths
- **ToolRouterSession**: `authorize`, `toolkits`, `search`, `execute`,
`proxyExecute`, `update`

  ### Custom-tool cooperative cancellation

Native tool execution is cancelled by the SDK (the underlying `fetch` is
aborted). Custom tools are different — the SDK can't preempt
user-supplied JavaScript. Two affordances are added so callers get
sensible behavior anyway:

1. **Pre-execute signal check**: if `signal.aborted` is true before the
user's `execute` runs, the SDK throws `ComposioRequestCancelledError`
and never invokes user code.
2. **Cooperative signal forwarding**: the same `AbortSignal` is exposed
via `SessionContext.signal` for Tool Router custom tools. Long-running
implementations can wire `ctx.signal` into their own `fetch` (or any
abortable IO) to abort mid-execution; the resulting `AbortError` is
normalized to `ComposioRequestCancelledError` by the SDK.

  ```typescript
  import { experimental_createTool } from '@composio/core';

const longRunningFetch = experimental_createTool('LONG_RUNNING_FETCH', {
    name: 'Long-running fetch',
    description: 'Fetches a URL with cooperative cancellation',
    inputParams: z.object({ url: z.string() }),
    execute: async (input, ctx) => {
// Pass ctx.signal into fetch so a session.execute(...) abort cancels
      // the in-flight HTTP request mid-flight.
      const resp = await fetch(input.url, { signal: ctx.signal });
      return { result: await resp.json() };
    },
  });
  ```

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.
- 4b76dbf: Remove the deprecated `uuid` field from the auth config
retrieve/list response type.

The platform has removed the deprecated V1/V2 UUID-mirror field from V3
API responses (it was a mirror of the canonical nanoid `id`). The SDK no
longer reads or re-exposes `uuid` on `AuthConfigRetrieveResponse` (and
therefore on the items of `AuthConfigListResponse`).

This is technically a breaking change to the SDK response type:
consumers should use `id` instead of `uuid`. The `expectedInputFields`
field is unaffected — it remains a top-level field on the API response.

### Patch Changes

- 552859a: Expose `search` and `showDisabled` filters on
`authConfigs.list()`.
- 23f9053: Replace `chalk` with `picocolors` for colored error and log
output. The two render identically, but `picocolors` is a fraction of
the size (~0.8 kB gzipped vs chalk's much larger footprint), shrinking
the bundled package.
- 507318d: Add a provider-agnostic JSON-schema property-key sanitizer:
`sanitizeSchemaPropertyKeys(schema, policy)`,
`restoreOriginalKeys(value, mapping)`, `mappingHasRenames(mapping)`, and
the `KeyMapping` / `KeySanitizationPolicy` types.

Some providers constrain the characters and length of tool
`input_schema` property keys and reject the whole request on a single
violation. This utility rewrites offending keys to conforming aliases
(recursing through `properties`, array `items`/`prefixItems`, the
composition keywords `allOf`/`anyOf`/`oneOf` and
`not`/`if`/`then`/`else`, plus
`additionalProperties`/`patternProperties`/`$defs`/`contains`) and
records a schema-shaped reverse mapping so the original parameter names
can be restored before execution. The _constraint_ is injected as a
`KeySanitizationPolicy`, so the traversal, collision handling, prototype
safety, and depth cap stay provider-agnostic. The `@composio/anthropic`
provider now consumes it.

- 6a4cb54: Preserve root `$defs` / `definitions` blocks on tool
parameter schemas and dereference them in the Node file modifier, so
auto file upload/download detection works when `file_uploadable` or
`file_downloadable` is hidden behind an internal `$ref`.
- cbbad15: Improve Zod compatibility at the SDK schema boundary. Custom
tools now convert both `zod/v3` and Zod v4 schemas to JSON Schema
correctly instead of degrading Zod v4 object schemas to empty schemas.
`@composio/core` now exposes `jsonSchemaToZodShape` via
`@composio/core/utils/json-schema`, and the Claude Agent SDK provider
uses that core subpath instead of converting to a full Zod object and
casting `.shape` out of it.
- Updated dependencies [025a657]
  - @composio/json-schema-to-zod@0.2.0
## @composio/json-schema-to-zod@0.2.0

### Minor Changes

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.
## @composio/anthropic@0.10.0

### Minor Changes

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.

### Patch Changes

- 507318d: Harden the Anthropic tool property-key sanitizer:

- **Broader schema coverage.** Illegal keys are now sanitized wherever
they appear in a tool schema — under the composition keywords
(`allOf`/`anyOf`/`oneOf`, `not`/`if`/`then`/`else`), `prefixItems`
tuples, `additionalProperties`/`patternProperties`, and
`$defs`/`definitions` — not just top-level `properties` and array
`items`. Previously a single illegal key under one of these would still
400 the entire request. Renames inside composition keywords are restored
correctly (they fold into the value level they share).
- **`$ref` keys restored.** `wrapTool` now dereferences internal
`$ref`/`$defs` (leniently — a dangling ref degrades to a permissive
schema instead of throwing) before sanitizing, so keys reachable only
through a reference are both made compliant and restored. Only genuinely
dynamic positions (`additionalProperties`, `patternProperties`,
`contains`) remain rewrite-only.
- **Shared core implementation.** The traversal/restoration mechanism
now lives in `@composio/core` (`sanitizeSchemaPropertyKeys` /
`restoreOriginalKeys`); this provider supplies only the Anthropic key
constraint as a policy, reusing core's prototype-pollution guard and
depth cap.
- **Prototype-safe key restoration.** Reverse-mapping lookups and the
rebuilt argument object are now prototype-free, so a tool call whose
arguments use a key matching an `Object.prototype` member (`__proto__`,
`constructor`, `toString`, `hasOwnProperty`, …) no longer throws or
silently corrupts the payload sent to the backend. `Object.prototype` is
never mutated.
- **Depth cap.** Schema sanitization and key restoration now bound
recursion (matching core's JSON-schema walker) so a pathologically deep
schema or argument object fails with a clear error instead of
overflowing the stack.
- **Empty / all-illegal keys.** A property key that is empty (or made
entirely of stripped characters) now becomes a deterministic non-empty
alias instead of an empty string, which would itself have violated
Anthropic's `{1,64}` length bound.
- **Collision loop.** Replaced a latent non-terminating fixed point in
the alias collision resolver with a counter that always makes progress.
- **Observability.** The provider now emits `debug` logs when it
rewrites a tool's schema keys and when it restores them at execution
time, and the wrap-then-execute (same provider instance) contract for
key restoration is documented.

- c90ae95: Sanitize tool `input_schema` property keys that violate
Anthropic's `^[a-zA-Z0-9_.-]{1,64}$` constraint before sending tools to
the Messages API, then restore the original names when the tool is
executed.

A single non-conforming key previously made Anthropic reject the entire
`tools` array with HTTP 400, taking down every other tool in the same
request. This commonly happened with OneDrive's Microsoft Graph OData
parameters (`$top`, `$filter`, `@microsoft.graph.conflictBehavior`) and
with over-long flattened keys from tools such as Zoom. Offending keys
are now rewritten to conforming aliases (`$` → `dollar_`, `@` → `at_`,
any other illegal character → `_`, keys longer than 64 characters
truncated with a deterministic suffix), recursing through nested object
`properties` and array `items` schemas. The original parameter names are
restored before the call reaches the Composio backend, so the model sees
`dollar_top` while the backend still receives `$top`. Schemas whose keys
already conform are left unchanged.
## @composio/claude-agent-sdk@0.10.0

### Minor Changes

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.

### Patch Changes

- cbbad15: Improve Zod compatibility at the SDK schema boundary. Custom
tools now convert both `zod/v3` and Zod v4 schemas to JSON Schema
correctly instead of degrading Zod v4 object schemas to empty schemas.
`@composio/core` now exposes `jsonSchemaToZodShape` via
`@composio/core/utils/json-schema`, and the Claude Agent SDK provider
uses that core subpath instead of converting to a full Zod object and
casting `.shape` out of it.
## @composio/cloudflare@0.10.0

### Minor Changes

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.
## @composio/google@0.10.0

### Minor Changes

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.
## @composio/langchain@0.10.0

### Minor Changes

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.
## @composio/llamaindex@0.10.0

### Minor Changes

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.
## @composio/mastra@0.10.0

### Minor Changes

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.

### Patch Changes

- aaabf5e: Relax the Mastra provider output schema so real third-party
API responses are no longer rejected by Mastra's output validation
(which dropped the data and substituted an error). Before compilation
the output schema is made lenient: every typed node becomes nullable,
objects allow extra keys (`additionalProperties: true`), `enum`/`const`
are widened to also admit `null`, and `required` is dropped (APIs omit
unset fields rather than returning `null` for them). All of these only
widen what validates, so previously-valid output is unaffected.
## @composio/openai@0.10.0

### Minor Changes

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.
## @composio/openai-agents@0.10.0

### Minor Changes

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.
## @composio/vercel@0.10.0

### Minor Changes

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.
## @composio/ts-builders@0.2.0

### Minor Changes

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.
## @composio/cli@0.3.0

### Minor Changes

- a0bef5d: Bump `@composio/client` to `0.1.0-alpha.74`.
- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.

### Patch Changes

- 5f004ff: Drop `COMPOSIO_UPSERT_RECIPE` and `COMPOSIO_GET_RECIPE` from
the CLI meta-tool list. These slugs were removed from `@composio/client`
(alpha.74), so listing them broke the type-checked CLI build.
- 23f9053: Remove the unused `ansis` dependency from the CLI. Colored
output is already handled by `picocolors`, so `ansis` was a dead
production dependency that shipped with the package.
- 446c6f6: Fix virtual TypeScript file resolution used by CLI type
generation so in-memory imports resolve consistently during
transpilation and validation.
- Updated dependencies [552859a]
- Updated dependencies [a0bef5d]
- Updated dependencies [23f9053]
- Updated dependencies [dfd7a08]
- Updated dependencies [507318d]
- Updated dependencies [025a657]
- Updated dependencies [6a4cb54]
- Updated dependencies [4b76dbf]
- Updated dependencies [cbbad15]
  - @composio/core@0.12.0
  - @composio/json-schema-to-zod@0.2.0
  - @composio/ts-builders@0.2.0
  - @composio/cli-keyring@0.2.0
  - @composio/cli-local-tools@0.1.0
## @composio/cli-keyring@0.2.0

### Minor Changes

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.
## @composio/cli-local-tools@0.1.0

### Minor Changes

- 025a657: Drop CommonJS entrypoints and publish the TypeScript SDK
packages as ESM-only packages. This is a breaking change within the
existing 0.x release line: consumers must use Node.js 22.22.3 or newer.
CommonJS callers can only rely on Node's native `require(esm)` interop,
and the SDK no longer ships custom CommonJS compatibility machinery or
`.cjs` artifacts.

### Patch Changes

- Updated dependencies [552859a]
- Updated dependencies [a0bef5d]
- Updated dependencies [23f9053]
- Updated dependencies [dfd7a08]
- Updated dependencies [507318d]
- Updated dependencies [025a657]
- Updated dependencies [6a4cb54]
- Updated dependencies [4b76dbf]
- Updated dependencies [cbbad15]
  - @composio/core@0.12.0

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-25 04:38:11 +04:00
Alberto Schiabel f6b5505739 fix(core): preserve SDK reference types 2026-06-25 03:56:42 +04:00
Alberto Schiabel 507318d56a fix(anthropic): harden tool property-key sanitizer (#3650)
This PR (builds on https://github.com/ComposioHQ/composio/pull/3649,
already merged) hardens the Anthropic tool property-key sanitizer from a
multi-agent review, then extracts the mechanism into a reusable core
util.

**Touches two packages:** `@composio/core` (new util) and
`@composio/anthropic` (consumes it).

### Correctness / robustness
- **Prototype-safe restoration** — reverse maps and the rebuilt argument
object are `Object.create(null)`, so a tool call using a key matching an
`Object.prototype` member (`__proto__`, `constructor`, `toString`,
`hasOwnProperty`, …) no longer throws a `TypeError` or silently corrupts
the backend payload, and `Object.prototype` is never mutated.
- **Full schema coverage** — illegal keys are sanitized wherever they
appear: `allOf`/`anyOf`/`oneOf`, `not`/`if`/`then`/`else`,
`prefixItems`, `additionalProperties`/`patternProperties`,
`$defs`/`definitions`. Renames inside composition keywords fold into the
value level they share and restore correctly (a mixed array/object
`anyOf` resolves by value type at restore time).
- **`$ref` keys restored** — `wrapTool` now dereferences internal
`$ref`/`$defs` (lenient `sentinel` mode) before sanitizing, so keys
reachable only through a reference are both made compliant and restored.
- **Depth cap (512)** on sanitization and restoration — a pathologically
deep schema/argument fails with a clear error instead of overflowing the
stack.
- **Empty / all-illegal keys** become a deterministic non-empty alias
instead of `''` (which would itself violate `{1,64}`).
- **Collision loop** — replaced a latent non-terminating fixed point
with a counter that always makes progress.

### Architecture
- **Extracted to core** — `sanitizeSchemaPropertyKeys(schema, policy)` /
`restoreOriginalKeys` / `mappingHasRenames` (+ `KeyMapping` /
`KeySanitizationPolicy`) now live in `@composio/core`, alongside
`normalizeToolArguments`. The traversal, collision handling, prototype
guard and depth cap are provider-agnostic; the Anthropic constraint is
injected as a `KeySanitizationPolicy` defined in the provider's
`sanitize-keys.ts`, which also re-exports a policy-bound
`sanitizeSchemaPropertyKeys` plus core's restore side so call sites
import from one place.
- **`wrapTool` → `executeToolCall` contract** documented (same provider
instance) and instrumented with `debug` logs on the rewrite/restore
paths; re-wrapping a slug refreshes or clears its mapping.
- Dropped the inaccurate "mirrors the Python SDK" comment and two `as
unknown as` casts.

### Known limitations
Both cases below leave a value reaching the backend un-restored — still
strictly better than the whole `tools` array 400-ing.

- **Dynamic-key positions.** After dereferencing, only genuinely
dynamic-key positions remain rewrite-only (not restored):
`additionalProperties`, `patternProperties`, and `contains`. These can't
be tied to a concrete value location without per-key schema association.
- **Composition-branch key collisions.** When sibling
`allOf`/`anyOf`/`oneOf` branches fold into their shared value level, two
branches that sanitize different illegal keys to the *same* alias — or
one branch whose alias equals a legitimately-named property in another
branch — keep only the first-seen reverse mapping, so an argument
satisfying the other branch restores to the wrong original name.
Recovering which branch a runtime value matched needs full schema
evaluation against the value; these collisions are rare in
OpenAPI-derived schemas. (Documented on `mergeMappingInto`.)

### Testing
Locally verified: `tsc --noEmit` clean on the core util and provider
sources (0 own-file diagnostics); ESLint clean; Prettier-formatted; the
full `@composio/core` (951) and `@composio/anthropic` (51) vitest suites
pass after a fresh `pnpm --filter @composio/core build` (the earlier
`picocolors` caveat from #3649 was a stale `@composio/core/dist`;
rebuilding core clears it). **Please confirm CI is green before
merging.**
2026-06-24 22:26:04 +04:00
Zen dfd7a0846d feat(core): add AbortSignal cancellation to public SDK methods + ComposioRequestCancelledError (#3463)
# Description

Add per-request cancellation to every public SDK method via
`AbortSignal`, and surface caller-initiated aborts as a typed
`ComposioRequestCancelledError`.

## API

For `tools.get` and `tools.execute`, pass `signal` directly in the
options bag (3rd arg) alongside modifiers — no placeholder needed:

```typescript
// Timeout a slow search
const tools = await composio.tools.get('user_1', {
  search: 'send email',
}, { signal: AbortSignal.timeout(5_000) });

// Cancel an execution, with modifiers
const result = await composio.tools.execute('TOOL', body, {
  signal: AbortSignal.timeout(10_000),
  beforeExecute: ({ params }) => params,
});

// Detect cancellation
try {
  await composio.tools.execute(slug, body, { signal: AbortSignal.timeout(5_000) });
} catch (err) {
  if (err instanceof ComposioRequestCancelledError) return;
  throw err;
}
```

For other methods, pass as a trailing argument:

```typescript
await composio.authConfigs.list(query, { signal: AbortSignal.timeout(5_000) });
await composio.connectedAccounts.get(id, { signal: AbortSignal.timeout(5_000) });
```

## Cancellation contract

- `withCancellation()` normalizes any abort error into
`ComposioRequestCancelledError` (code `TS-SDK::REQUEST_CANCELLED`)
- `isRequestAbortError()` detects `APIUserAbortError` via `instanceof`
(required because `.name === "Error"` at runtime), with fallbacks for
dual-package hazard and generic `AbortError`
- Catch-and-wrap paths in `execute` / `getRawComposioToolBySlug` /
`toolkits.get` re-throw cancellation before domain error wrapping
- **Post-execute safety**: if the signal fires after the remote tool
already executed, the result is returned (not thrown) — prevents callers
from retrying non-idempotent operations
- Custom-tool cancellation is cooperative: signal is exposed via the
`ctx` arg so user code can wire it into `fetch`

## Coverage

Tools, Toolkits, AuthConfigs, ConnectedAccounts, Triggers, MCP,
ToolRouter, ToolRouterSession — every public method that does HTTP I/O.

# How did I test this PR

- `pnpm exec vitest run` — 666 tests pass (25 pre-existing fileModifiers
failures unchanged)
- `pnpm typecheck` — 11/11 clean
- CI: Typecheck, Build, Audit, Test, all 5 E2E runtimes (Node
20.18/20.19/22.12, Deno, Cloudflare), secrets scan — all green

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

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: jkomyno <alberto@composio.dev>
2026-06-24 20:26:17 +04:00
Alberto Schiabel c90ae95f43 fix(anthropic): sanitize illegal/over-long tool property keys for Messages API (#3649)
## Problem

Anthropic's Messages API validates every tool `input_schema` property
key against `^[a-zA-Z0-9_.-]{1,64}$`. A single non-conforming key makes
the API reject the **entire** `tools` array with HTTP 400, so one bad
tool takes down every other tool in the same request (e.g. a subagent
that loads all MCP schemas up front dies before running anything).

The `@composio/anthropic` provider passed `tool.inputParameters`
straight through as `input_schema` with no key sanitization, so two real
cases break:

- **Illegal characters** — OneDrive exposes Microsoft Graph OData
parameters as schema keys: `$top` / `$filter` / `$skip` / `$orderby` and
`@microsoft.graph.conflictBehavior`. `$` and `@` are outside the allowed
set.
- **Length** — `__`-flattened nested keys can exceed 64 characters
(several Zoom tools).

Fixes #3500. TypeScript-side counterpart to the Python fix in #3504;
supersedes the earlier #3067 / #2330 attempts.

## What this changes

- New `sanitize-keys.ts`: `sanitizeSchemaPropertyKeys()` rewrites
offending keys to conforming aliases (`$` → `dollar_`, `@` → `at_`, any
other illegal char → `_`, keys > 64 chars truncated with a deterministic
hash suffix), recursing through nested object `properties` **and array
`items`** schemas, keeps `required` in sync, and never mutates the
input. `restoreOriginalKeys()` reverses the rename on tool-call
arguments.
- `AnthropicProvider.wrapTool()` sanitizes the schema and stores a
per-tool reverse mapping; `executeToolCall()` restores the original
parameter names before the call reaches the Composio backend, so the
model sees `dollar_top` while the backend still receives `$top`.

## Supersedes #3574

This rebuilds @serhiizghama's #3574 — his three commits are
cherry-picked here with authorship preserved — rebased onto current
`next` and hardened after review. Changes on top of #3574:

1. **Resolved the merge conflict with `next` (it was semantic, not just
textual).** `next` now routes tool arguments through
`normalizeToolArguments()` (issue #2406 — models sometimes emit input as
a JSON *string*). `executeToolCall()` now **normalizes first, then
restores keys**; restoring a raw string would be a no-op, so the order
matters.
2. **Fixed the cross-level key-collision bug** flagged by Cursor Bugbot
on #3574. The reverse mapping was a single flat `sanitized → original`
lookup applied at every nesting depth, so an alias generated at one
level (`$top` → `dollar_top`) could rewrite a legitimately-named
`dollar_top` key at a *different* level and corrupt the backend payload.
The mapping is now shaped like the schema and walked in lockstep with
the value, so a rename only applies where its alias was generated.
3. **Sanitize keys nested in array `items`** (single schema and
positional tuples), which the original `properties`-only walk missed.
4. **Added a changeset** (`@composio/anthropic` patch) so the fix
actually ships.

## Testing

Unit tests in `sanitize-keys.test.ts` cover: illegal-character
rewriting, `.`/`-` preservation, deterministic length truncation,
same-level collision, nested recursion, array `items` (single + tuple),
no-mutation, the cross-level collision regression (#2 above), the
`wrapTool` → `executeToolCall` round-trip, and the JSON-string-input →
normalize → restore composition (#1 above / issue #2406).

> ⚠️ The full vitest suite could not run in my local environment due to
a workspace toolchain drift (a stale `node_modules` link made
`@composio/core` fail to resolve `picocolors`). The dependency-free
sanitizer logic was verified in isolation (including a counter-check
proving the old flat mapping corrupted the nested key), and `tsc
--noEmit` on the provider sources is clean. Please confirm CI is green
before merging.

---------

Co-authored-by: serhiizghama <zmrser@gmail.com>
2026-06-24 20:19:58 +04:00
Serhii Zghama aaabf5e2a6 fix(mastra): relax output schema so API nulls and extra keys pass validation (#3585)
## Problem

Closes #3047.

`MastraProvider.wrapTool` passes each tool's `outputParameters` to
Mastra's `createTool` as `outputSchema`, and Mastra validates every tool
result against it via `validateToolOutput` — on a mismatch it **drops
the data and substitutes an error**.

Composio's API-supplied output schemas are strict: optional fields are
typed as non-nullable primitives (`{ type: "string" }`) and objects
carry `additionalProperties: false`. Real third-party APIs (Linear,
Notion, Jira, Slack, …) routinely return `null` for unset optional
fields (`avatarUrl`, `assignee`, `description`, …) and occasionally
extra keys. So strict validation rejects perfectly good responses and
**truncates the tool output the model sees** — affecting a wide range of
connector tools.

This is the recommended fix (#2) from the issue: output validation of
opaque third-party pass-through payloads provides little value and
causes real breakage.

## What this changes

A new `relaxOutputSchema` helper walks the (already dereferenced) output
JSON schema and, non-mutating:

- makes every typed node nullable — `type: "string"` → `["string",
"null"]` (handles string and array forms, idempotent)
- sets `additionalProperties: true` on object nodes that forbid (or
omit) extra keys; a schema-valued `additionalProperties` is preserved
and recursed into
- recurses through `properties`, `patternProperties`, `items`,
`anyOf`/`oneOf`/`allOf`, `$defs`/`definitions`, etc.

`wrapTool` applies it to the output schema only (input schemas are
untouched) before handing it to `@mastra/schema-compat`.

## Why this approach

Both transforms only **widen** what validates, so any payload that
passed before still passes — there is no behavioural change for
already-valid output, and no breaking change. It keeps the existing
`dereferenceJsonSchema` → `applyCompatLayer` pipeline intact and adds
one focused, unit-tested step. The `$ref`/`$defs` type-preservation
behaviour from the existing regression suite is retained (the
dereferenced inner type is kept, just made nullable).

## Testing

- New `test/relax-output-schema.test.ts` — 11 unit cases (nullable
primitives, idempotency, nested objects, `additionalProperties`
flip/preserve, array items, `anyOf` branches, empty schema,
non-mutation, pass-through of non-objects).
- Updated existing `mastra.test.ts` / `mastra-ref.test.ts` assertions to
reflect the relaxed output shape.
- `pnpm test` → 64/64 passing. `pnpm typecheck` and `pnpm build` clean;
eslint/prettier clean on changed files.

---------

Co-authored-by: Alberto Schiabel <jkomyno@users.noreply.github.com>
Co-authored-by: jkomyno <alberto@composio.dev>
2026-06-24 20:03:45 +04:00
Alberto Schiabel 552859adc2 fix(core): expose auth config list search filters (#3647)
This PR:
- exposes `search` and `showDisabled` on `authConfigs.list()`
- forwards those filters to the generated `@composio/client` as `search`
and `show_disabled`
- documents the filters and adds a core changeset
- covers forwarding in `AuthConfigs` tests
2026-06-24 19:14:06 +04:00
Alberto Schiabel f8cd90ce5a chore(ts): adopt Node 24 and pnpm 11 toolchain (#3646)
This PR:

- uses plain `tsdown` package scripts and a shared typed
`tsdown.config.base.ts` so Node 24 builds work without loader flags
- switches the repo dev/build toolchain to Node `24.17.0` and pnpm
`11.8.0` through `mise.toml`, `mise.lock`, and `pnpm-lock.yaml`
- marks the root package as ESM with `type: module`, matching the
TypeScript packages
- keeps Node `22.22.3` in the runtime/E2E matrices as the minimum
supported user runtime
- changes the TypeScript build workflow back to a single build on the
mise-managed toolchain and broadens path filters for
package-manager/build config files
- adds pnpm 11 build-script policy with `allowBuilds` and intentionally
ignored `sharp` builds
- enables tsdown ESM shims for the packaged CLI wrapper so `composio
--help` runs under Node 22 and Node 24

Verified locally:

- `CI=true pnpm install --frozen-lockfile`
- `pnpm lint`
- `pnpm run build:packages`
- `COMPOSIO_E2E_NODE_VERSION=22.22.3 pnpm --filter
@e2e-tests/node-esm-basic --filter @e2e-tests/node-cjs-basic run
test:e2e:node`
- `node ts/packages/cli/bin/composio.mjs --help` under Node `22.22.3`
and `24.17.0`
2026-06-24 18:58:11 +04:00
hex-security-app[bot] 17fe881059 fix: apply automated code update (#3600)
This pull request contains an automated code update generated by Hex.

Please review the diff carefully before merging.

---
_Generated by Hex Security. Please review carefully before merging._

---------

Co-authored-by: Hex Security <255204168+hex-security-app[bot]@users.noreply.github.com>
Co-authored-by: jkomyno <alberto@composio.dev>
2026-06-24 18:56:20 +04:00
Kshitiz 446c6f65bf fix(cli): unify virtual TypeScript compiler host resolution (#3182)
## Summary
This PR resolves the TODO in
`ts/packages/cli/src/generation/typescript/transpile.ts` by extracting
the shared virtual TypeScript compiler-host logic used by both
production transpilation and test validation.

While doing that refactor, it also fixes a real virtual
module-resolution issue: TypeScript may resolve in-memory files using
`./file.ts`, `file.ts`, or absolute paths, and the previous setup did
not handle those lookups consistently.


## Changes
- added
`ts/packages/cli/src/generation/typescript/virtual-compiler-host.ts`
- extracted shared helpers for virtual file-map creation, compiler-host
patching, and diagnostic formatting
- updated `ts/packages/cli/src/generation/typescript/transpile.ts` to
use the shared helper
- updated `ts/packages/cli/test/__utils__/typescript-compiler.ts` to use
the same shared helper
- updated affected tests to validate complete generated module sets
instead of incomplete single-file inputs
- added a patch changeset for `@composio/cli`

## Type of change
- [x] Bug fix
- [x] Refactor/Chore

## How Has This Been Tested?
Ran focused checks on the touched CLI TypeScript
generation/compiler-host paths:

```bash
pnpm --dir ts/packages/cli exec prettier --check src/generation/typescript/transpile.ts src/generation/typescript/virtual-compiler-host.ts test/__utils__/typescript-compiler.ts test/src/generation/typescript/generate.test.ts test/src/commands/ts/ts.generate.cmd.test.ts
pnpm --dir ts/packages/cli exec vitest run test/__utils__/typescript-compiler.ts
pnpm --dir ts/packages/cli exec vitest run test/src/generation/typescript/generate.test.ts

---------

Co-authored-by: Alberto Schiabel <jkomyno@users.noreply.github.com>
Co-authored-by: jkomyno <alberto@composio.dev>
2026-06-24 18:28:45 +04:00