Commit Graph

4655 Commits

Author SHA1 Message Date
Alberto Schiabel 8b3ccffb03 feat(cli): rewrite installer for POSIX shell (#4015)
This PR:

- builds on top of
[#4011](https://github.com/ComposioHQ/composio/pull/4011) ([Glen
review](https://app.tryglen.com/review/ComposioHQ/composio/4011)) and
implements Stage 2 of the mise-style installer rollout
- rewrites the base installer for POSIX `sh`, install-only defaults,
verified complete bundles, and a `~/.local/bin/composio` entry point
- adds explicit bash, zsh, and fish setup routes with compatibility
fallback for older CLI releases, enforced byte-identical except for the
shell each hardcodes in `requested_shell()` (drift guard in the
installer test harness)
- posts a sticky PR comment with copy-paste preview install commands
once the hermetic install E2E suite passes (`preview-comment` job). The
run-time release resolution means any branch's checked-in scripts are
complete working installers
- updates install workflows, release guidance, public docs, generated
LLM guidance, CODEOWNERS, and the installer changelog
- adds hermetic bash/zsh Docker coverage, corrupt-archive rejection,
upgrade symlink regression coverage, and PR/nightly install E2E CI
- simplifies internals after a review pass: dedupes the curl `--proto`
selection in `install.sh`, merges the duplicated install verification CI
steps, removes the `execPath` test bypass around the `NodeProcess`
service, and threads the Docker image platform through the E2E harness
instead of re-inspecting per test

## Verification

- `shellcheck -s sh install.sh install/*.sh`
- `bash test/install-sh-release-resolution.test.sh` (runs under `sh` and
`dash`, includes the shell-variant drift guard)
- `pnpm turbo typecheck --filter=@composio/cli --filter=@e2e-tests/utils
--filter=@e2e-tests/cli-install`
- `pnpm vitest run` from `ts/packages/cli` (full suite, 1094 tests)
- `pnpm run test:release-workflow` and `pnpm run validate:boundaries`
- Docker install E2E (bash + zsh hermetic legs) runs on this PR via
`cli.install-e2e.yml`
- Docs: typecheck, lint, link lint, static tests, and production build

## Stacked follow-up

- #4042 (`feat/installer-auto-shell-default`) targets this branch and
flips the default to automatic shell setup
(`COMPOSIO_INSTALL_SHELL=auto`, with `none` as the install-only
opt-out). It merges into this PR after its own review; checks and review
then rerun on the combined head before this PR moves to `next`.
- #4042's head now also carries the full stack-review remediation
(2026-08-04): the #4016 atomic-replacement port (support files first,
release metadata next, binary last; atomic `composio upgrade`), legacy
three-line managed-block migration in both reconcilers, a safe tested
uninstall snippet, mandatory checksum verification for official release
downloads, and the scheduled prod E2E moved to the base `/install` route
with `COMPOSIO_INSTALL_SHELL` (the variant routes are still
unprovisioned). See #4042's "Review remediation" section for details;
#4016 is superseded by that merge.
- Rollback order for the combined rollout is copy-first: restore the
previous dashboard/docs copy, then revert installer behavior if needed.
The old copy remains compatible with the new installer; the new promise
is not compatible with the old install-only default.

## Merge gates

- [ ] #4011 is merged and its stable CLI release handoff is verified.
- [ ] The live `next` ruleset requires code-owner review. It currently
requires one approval but reports `require_code_owner_review: false`.

Note: the Cloudflare routes `/install/bash`, `/install/zsh`, and
`/install/fish` remain unprovisioned (404) and are deliberately
undocumented until live checks return the expected scripts. They are no
longer a merge prerequisite; the release-asset/repo `install/*.sh`
variants cover explicit-shell installs.

## Next steps

- Render `install.sh` at release time with the version and per-target
checksums baked in (mise's `install.envsubst` + `render-install.sh`
model), sign the rendered script, and serve it from our own routes. This
removes run-time GitHub API release resolution (rate limits and
missing-asset races) from the user install path.
- If the shell variants ever grow real per-shell logic, generate them
from a single template at build time (mise's `shell.envsubst` model).
Until then, the drift guard enforces lockstep.

No changeset: the standalone CLI is excluded from Changesets, and the
remaining changes are installer, docs, tests, and CI.

## Review follow-up

- `cbb5f5a70` fixes unset `SHELL`, rejects `:` in compatibility fallback
paths, and makes signal traps terminate after cleanup.
`test/install-sh-release-resolution.test.sh` covers all three
regressions under `sh` and `dash`.
- `3d4c3b6cd` bounds the uninstall filter to the legacy install-dir
export and exactly one installer-owned `PATH` line. Legacy POSIX,
current POSIX, fish, unrelated `PATH`, and completions fixtures pass.
- Focused verification: `pnpm test:install-sh`, `shellcheck -s sh
install.sh install/*.sh`, `bash -n
test/install-sh-release-resolution.test.sh`, and `bun test
docs/tests/static/content.test.ts`.
@composio/cli@0.3.2-beta.336
2026-08-05 18:03:34 +05:30
jkomyno f1b25f551b Merge remote-tracking branch 'origin/next' into feat/mise-style-installer-rollout 2026-08-05 17:52:38 +05:30
Alberto Schiabel 5630041145 fix(ci): refresh mise.lock for the republished python 3.12.13 build (#4066)
## Why

`next` is currently red on **Audit Typescript SDK**, and so is every PR
based on it.

`python-build-standalone` republished cpython **3.12.13** under a new
date tag (`20260728` → `20260804`). The pinned version in `mise.toml`
did not change, but `mise lock` now resolves different URLs and
checksums for it. The Audit job runs:

```
mise lock --platform linux-x64,linux-arm64,macos-arm64,macos-x64
git diff --exit-code mise.lock
```

so the committed lockfile no longer matches what `mise lock` produces,
and that step fails on every branch.

Evidence: [Audit on `next` @
`973de6541`](https://github.com/ComposioHQ/composio/actions/runs/31001686227)
— the failing step's diff is exactly the four python entries updated
here.

## What changed

Only the four `[tools.python."platforms.*"]` URL/checksum pairs. No
version pins in `mise.toml` are touched, and no other tool entry moves.

The regenerated checksums match the ones CI computed in the run linked
above, byte for byte.

## Note

Running `mise lock` locally also wanted to append a `[[tools.node]]
version = "24.18.1"` block, picked up from a globally-installed node
rather than from this repo — `mise.toml` pins `node = "24.17.0"`, which
is already locked. That block is deliberately **not** included here.
@composio/cli@0.3.2-beta.335
2026-08-05 17:52:15 +05:30
jkomyno 2dae4c2541 fix(ci): refresh mise.lock for the republished python 3.12.13 build
python-build-standalone republished cpython 3.12.13 under the 20260804
tag, so `mise lock` now resolves different URLs and checksums for the
same pinned version. The Audit job regenerates the lockfile and runs
`git diff --exit-code`, so every branch fails that step until the
committed lockfile matches.

Only the four python platform entries change; the pinned versions in
mise.toml are untouched.
2026-08-05 17:47:54 +05:30
jkomyno aaa3830f35 Merge remote-tracking branch 'origin/next' into feat/mise-style-installer-rollout 2026-08-05 17:42:58 +05:30
Alberto Schiabel 973de6541d feat(cli): rework composio install PATH setup and add --shell (#4011)
# fix(cli): rework `composio install` PATH setup

## Why

`composio install` hardcoded `~/.composio` as the directory it added to
`PATH`, and it wrote the block to `~/.bashrc` only. Two consequences: an
installer that puts the entry point somewhere else (a `~/.local/bin`
shim, a version manager's `bin`) had no way to say so, and a login-only
bash shell — `ssh`, `Terminal.app` — never saw the PATH line at all
whenever a `.bash_profile` or `.bash_login` existed to shadow
`.profile`.

This PR makes the target directory a resolved value rather than a
constant, writes to every startup file bash actually reads, and turns
the command into something an installer can call and trust: it either
configures `PATH` or exits non-zero so the caller's own fallback runs.

## What changed

**Bin-dir resolution.** The `PATH` entry now resolves through
`COMPOSIO_BIN_DIR` → `~/.local/bin` when its `composio` entry point
resolves (through symlinks) to the running executable → the running
binary's own directory. A leftover `composio` from another installer no
longer wins the `~/.local/bin` step, so shells are never pointed at a
foreign program.

**`COMPOSIO_BIN_DIR` is public.** It is the user-facing override for the
`PATH` target and the CLI-side contract the mise-style installer will
use, so it is documented in the CLI README with its full resolution
order and named in the `install` command description — `composio install
--help` mentions it. Deliberately no `--bin-dir` flag: the env var is
the right shape for an installer handoff.

**`--shell <zsh|bash|fish>`.** Overrides `$SHELL` detection, for callers
that know which shell they are configuring.

**Bash login files.** The block also lands in `~/.bash_profile` or
`~/.bash_login` when either exists. `.profile` is deliberately not a
candidate: when neither override exists, bash reads `.profile` itself,
and common `.profile` files already source `.bashrc`. The restart hint
now prints `source ~/.bashrc` instead of the literal string `exec
$SHELL`, and mentions the login file when one was written.

**rc file handling.** Writes go through the file's real target, so a
symlinked `.zshrc` keeps its link; the atomic tmp copy is created with
the target's mode from the start, so a private rc's contents never sit
in a world-readable temp file. Two logical paths that alias one physical
file get the block once.

**Managed blocks are reconciled, not just detected.** The marker alone
no longer means "configured": a file is skipped only when it already
contains the exact rendered `PATH` line for the resolved bin dir.
Otherwise the existing managed block is spliced in place — which is what
migrates the legacy three-line block (`export COMPOSIO_INSTALL_DIR=...`
plus a `PATH` line derived from it), written by an older CLI or by
`install.sh`'s fallback, to the current single-line form. A completions
block elsewhere in the file is untouched, and re-running stays
idempotent.

**No reachability skip.** The command used to skip the write entirely
when the bin dir was already on the invoking process's `$PATH`. That is
not evidence about future shells — under an ad-hoc `export` or a
mise/direnv shim it exited 0 having persisted nothing. A
redundant-but-correct `PATH` line is harmless and the content check
already prevents duplicates. The separate early return for "no shell
detected *and* already on `$PATH`" stays (there is no rc file to write
in that case) with wording that says the conclusion came from the
current process.

**Abort contract.** `composio install` aborts, writing nothing and
exiting non-zero, on two conditions: the resolved bin dir is not
absolute, or it contains a character that cannot be embedded safely in a
quoted rc line. The non-zero exit is load-bearing — `install.sh` only
runs its inline PATH fallback when the CLI fails, so an aborting run
still leaves the user with a working `PATH` instead of a green install
and `command not found`.

**Narrow unsafe-character set.** The bin dir is only ever emitted inside
double quotes (`export PATH="<dir>:$PATH"`, `set --export PATH "<dir>"
$PATH`), where bash and zsh expand only `` ` ``, `$`, `\`, `"` and fish
a subset of those. `;`, `|`, `&`, `(`, `)`, `'` are literal there, so
they no longer abort — `/Users/o'brien/.composio` is a legitimate path.
Newline/carriage return and `:` remain rejected as structural: one
splits the block into extra lines, the other is the PATH separator.

**`install.sh` injection fix.** Because an abort now hands PATH setup to
`install.sh`'s inline fallback, that writer's escaping matters. It
interpolated `COMPOSIO_INSTALL_DIR` raw into the fish and zsh rc lines
and escaped only `"` in the bash arm — so a directory the CLI rejects
was written unescaped into `~/.zshrc` or `config.fish`, where `$(...)`
or a backtick becomes live command substitution at the next shell start.
All three arms now escape backslash, backtick, `$`, and `"` before
embedding, skipping the backtick for fish (which neither substitutes it
nor recognizes `` \` `` inside double quotes). The `$HOME` prefix is
re-applied after escaping, so the intended variable reference survives
while a user-supplied `$` does not.

**CI guard.** `cli.test-installation.yml`'s shell-config check accepted
the legacy `install.sh` block on every leg, justified by a comment
claiming no leg installs a binary built from this checkout. That was
false: `build-cli-binaries.yml` calls the workflow with the tag it just
released, so a completely broken `composio install` silently falling
through to `install.sh`'s writer still reported success. Callers now
declare `built_from_this_checkout`, and those legs must show the
CLI-managed line. `promote-stable` keeps the permissive check because it
rebuilds the promoted beta's own commit, which can predate the writer.

## Known behavior, documented rather than coded around

The rc block no longer records `export COMPOSIO_INSTALL_DIR=`. A user
who installed to a custom directory and later re-runs `curl ... | bash`
without re-specifying the variable gets a second install under
`~/.composio` while their rc `PATH` still resolves the old binary.
Reachability is narrow — existing users are unaffected and `composio
upgrade`, the documented path, replaces `process.execPath` in place and
never consults this. The obvious fix (`command -v composio` + `readlink
-f` inside `install.sh`) can misfire on a foreign `composio`, so this is
a CHANGELOG note telling custom-dir users to re-specify
`COMPOSIO_INSTALL_DIR` or use `composio upgrade`.

## Testing

- `ts/packages/cli/test/src/commands/install.cmd.test.ts` — 47 cases
covering per-shell rendering (full rendered lines, including fish), bash
login-file selection, symlink and mode preservation, legacy-block
migration, idempotency, bin-dir resolution order, and both abort
conditions.
- `test/install-sh-release-resolution.test.sh` — adds a case asserting
that an install directory containing `$(...)` lands in `.bashrc` as
literal text and does not execute when the file is sourced.

Verified locally: `vitest run` for the CLI package (113 files, 1103
passed / 1 skipped), `pnpm run typecheck`, `pnpm run
validate:boundaries`, `pnpm run lint`, `bash -n install.sh`, and `bash
test/install-sh-release-resolution.test.sh`.

## Notes for reviewers

- `@composio/cli` is in `.changeset/config.json`'s ignore list, so this
edits `ts/packages/cli/CHANGELOG.md` directly instead of adding a
changeset.
- No new lint-boundary disables; the two previously registered for this
file (`process.env.SHELL`, `process.env.COMPOSIO_INSTALL_DIR`) are gone,
since both reads now go through `effect/Config`.
- `install.sh` is rewritten wholesale by the follow-up installer PR, so
the change here is the minimum that closes the injection.
- Follow-up #4042 ships a fuller managed-block reconciler with fixtures;
the migration here is its core behavior landed early, without the
fixture harness.
@composio/cli@0.3.2-beta.334
2026-08-05 16:59:48 +05:30
jkomyno 2024fc4403 Merge remote-tracking branch 'origin/next' into feat/cli-install-shell-flag 2026-08-04 20:19:46 +05:30
Alberto Schiabel 85ce22401d fix(deps): let the hono security bump through the release-age floor (#4057)
## Why

`next` is red. Dependabot #4051 bumped the `hono` catalog entry to
`^4.12.34`, which pnpm resolved to `4.13.0`. Both that and `4.12.34`
were published inside the 4320-minute (72h) `minimumReleaseAge` floor,
so `pnpm install --frozen-lockfile` rejects the lockfile — on `next`
itself and on every PR branched from it.

```
[ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION] 1 lockfile entries failed verification:
  hono@4.13.0 was published at 2026-08-03T21:47:05.000Z, within the minimumReleaseAge cutoff
```

Waiting it out is not neutral, because of which versions sit on which
side of the floor:

| Version | Published | Clears the 72h floor | Has the CORS ReDoS fix |
|---|---|---|---|
| 4.12.33 | 2026-07-31 10:42 | yes | **no** |
| 4.12.34 | 2026-08-03 02:36 | not until Aug 6 02:36 | yes |
| 4.13.0 | 2026-08-03 21:54 | not until Aug 6 21:54 | yes |

The newest version old enough to pass the gate is the one the advisory
flags as vulnerable. So pinning back to a compliant version means
deliberately shipping the vulnerable release for two days.

## What changed

One entry added to `minimumReleaseAgeExclude`, with its removal
condition inline. No lockfile change — `pnpm install --frozen-lockfile`
goes from exit 1 to exit 0 with the lockfile untouched.

## Why this is a safe trade

The floor exists to catch compromised fresh releases. `hono` is only
pulled in by `ts/e2e-tests/runtimes/cloudflare/*` and
`ts/examples/cloudflare-wrangler` — test fixtures and examples. It ships
in no published package, so the blast radius of taking it early is
CI-only, while the advisory it fixes is real.

## Verification

```
pnpm install --frozen-lockfile   # exit 0, pnpm-lock.yaml unmodified
```

## Follow-up

Delete the `hono` entry once the resolved version is past the floor
(after 2026-08-06). The inline comment says so.
2026-08-04 20:19:08 +05:30
jkomyno fdb366d090 Merge branch 'feat/cli-install-shell-flag' into feat/mise-style-installer-rollout
# Conflicts:
#	install.sh
#	test/install-sh-release-resolution.test.sh
#	ts/packages/cli/test/__utils__/services/test-layer.ts
#	ts/packages/cli/test/src/commands/install.cmd.test.ts
2026-08-04 20:02:22 +05:30
dependabot[bot] 02c7af88ae chore(deps): bump hono from 4.12.31 to 4.12.34 in the npm-security group across 1 directory (#4051)
Bumps the npm-security group with 1 update in the / directory:
[hono](https://github.com/honojs/hono).

Updates `hono` from 4.12.31 to 4.12.34
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/honojs/hono/releases">hono's
releases</a>.</em></p>
<blockquote>
<h2>v4.12.34</h2>
<h2>Security fixes</h2>
<p>This release includes fixes for the following security issues:</p>
<h3><code>memo()</code> retains SSR output across requests, leading to
cross-user data disclosure</h3>
<p>Affects: <code>hono/jsx</code> (server-side rendering). Fixes
<code>memo()</code> reusing a retained render result across requests
when props compare equal, where a component reading request-scoped
values from ambient context — <code>useContext()</code>,
<code>useRequestContext()</code>, or <code>getContext()</code> — could
serve HTML rendered for another user's request, disclosing account data
or request-scoped secrets such as CSRF tokens. GHSA-f23p-vx2j-j53r</p>
<h3>ReDoS in CORS middleware via
<code>Access-Control-Request-Headers</code></h3>
<p>Affects: <code>hono/cors</code>. Fixes a whitespace-tolerant regular
expression with quadratic backtracking used to parse the
<code>Access-Control-Request-Headers</code> preflight header when
<code>allowHeaders</code> is not configured (the default), where a
single preflight request carrying a long whitespace run could consume
seconds of CPU and stall request processing. GHSA-8j4g-w8fx-2239</p>
<h3>Algorithmic complexity DoS in Language Middleware</h3>
<p>Affects: <code>hono/language</code>. Fixes quadratic string
processing in language-tag normalization, where a crafted language tag
with a large number of hyphen-separated subtags — supplied via a query
parameter, cookie, or <code>Accept-Language</code> header — could cause
excessive CPU consumption and block the event loop.
GHSA-54fx-42gc-7vw4</p>
<h3>Proxy Helper does not remove response headers listed in the
<code>Connection</code> header</h3>
<p>Affects: <code>hono/proxy</code>. Fixes <code>proxy()</code>
forwarding response headers that the origin's <code>Connection</code>
header designates as connection-scoped, where headers intended only for
the immediate peer — per RFC 9110 Section 7.6.1 — could be exposed to
clients, disclosing connection-scoped or internal metadata.
GHSA-79qm-7rj5-m7r9</p>
<hr />
<p>Users who use <code>hono/jsx</code> for server-side rendering,
<code>hono/cors</code>, <code>hono/language</code>, or
<code>hono/proxy</code> are strongly encouraged to upgrade to this
version.</p>
<h2>v4.12.33</h2>
<h2>What's Changed</h2>
<ul>
<li>fix(cookie): relax name validation when parsing Cookie header in <a
href="https://redirect.github.com/honojs/hono/pull/5164">honojs/hono#5164</a></li>
<li>chore: bump <code>@hono/node-server</code> in <a
href="https://redirect.github.com/honojs/hono/pull/5167">honojs/hono#5167</a></li>
<li>fix(jsx): handle useSyncExternalStore subscription and snapshot
changes in <a
href="https://redirect.github.com/honojs/hono/pull/5166">honojs/hono#5166</a></li>
<li>chore: remove undici in favor of global fetch in <a
href="https://redirect.github.com/honojs/hono/pull/5168">honojs/hono#5168</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/honojs/hono/compare/v4.12.32...v4.12.33">https://github.com/honojs/hono/compare/v4.12.32...v4.12.33</a></p>
<h2>v4.12.32</h2>
<h2>What's Changed</h2>
<ul>
<li>ci: enable reports for type &amp; bundle size check in <a
href="https://redirect.github.com/honojs/hono/pull/5148">honojs/hono#5148</a></li>
<li>fix(aws-lambda): add jwt and lambda authorizer types for API Gateway
v2 in <a
href="https://redirect.github.com/honojs/hono/pull/5142">honojs/hono#5142</a></li>
<li>fix(sse): emit empty id field to reset Last-Event-ID in <a
href="https://redirect.github.com/honojs/hono/pull/5138">honojs/hono#5138</a></li>
<li>test(cloudflare-workers): add coverage for onClose, onError, send,
and close in Cloudflare Workers websocket adapter in <a
href="https://redirect.github.com/honojs/hono/pull/5145">honojs/hono#5145</a></li>
<li>fix: use <code>Object.create(null)</code> when parsing query,
headers, and params in <a
href="https://redirect.github.com/honojs/hono/pull/5161">honojs/hono#5161</a></li>
<li>fix(secure-headers): keep CSP callbacks scoped to their header in <a
href="https://redirect.github.com/honojs/hono/pull/5147">honojs/hono#5147</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/honojs/hono/compare/v4.12.31...v4.12.32">https://github.com/honojs/hono/compare/v4.12.31...v4.12.32</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/honojs/hono/commit/734755ace341607628219ea1dd8ca17f01bf1a5c"><code>734755a</code></a>
4.12.34</li>
<li><a
href="https://github.com/honojs/hono/commit/9839ff32a349bf088b6ddfa604010879dd2d3a05"><code>9839ff3</code></a>
chore: update <code>bun.lock</code> (<a
href="https://redirect.github.com/honojs/hono/issues/5182">#5182</a>)</li>
<li><a
href="https://github.com/honojs/hono/commit/0c45036d6b0ddf42ab2fa44639dc8710825d5c0f"><code>0c45036</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/honojs/hono/commit/720b566290793d4358bf39843adcb7cf4da4548f"><code>720b566</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/honojs/hono/commit/f70e2c31684387b3231cc38512a31df6ca76a1c7"><code>f70e2c3</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/honojs/hono/commit/93fc250d8b4df58ea542cb945171de8013d5e6d5"><code>93fc250</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/honojs/hono/commit/51db3131d5e97076327edaa0afdb60ebb77c264f"><code>51db313</code></a>
4.12.33</li>
<li><a
href="https://github.com/honojs/hono/commit/aed146364d5c48a8336b8c82fedfabebf8063d07"><code>aed1463</code></a>
chore: remove undici in favor of global fetch (<a
href="https://redirect.github.com/honojs/hono/issues/5168">#5168</a>)</li>
<li><a
href="https://github.com/honojs/hono/commit/224d2f5cbf2b4bc2ebb7482d0592149a8d9f0574"><code>224d2f5</code></a>
fix(jsx): handle useSyncExternalStore subscription and snapshot changes
(<a
href="https://redirect.github.com/honojs/hono/issues/5166">#5166</a>)</li>
<li><a
href="https://github.com/honojs/hono/commit/df653cea0450657977887d56a5188368387456c8"><code>df653ce</code></a>
chore: bump <code>@hono/node-server</code> (<a
href="https://redirect.github.com/honojs/hono/issues/5167">#5167</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/honojs/hono/compare/v4.12.31...v4.12.34">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=hono&package-manager=npm_and_yarn&previous-version=4.12.31&new-version=4.12.34)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

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
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/ComposioHQ/composio/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-04 19:20:31 +05:30
dependabot[bot] f286ca98ac chore(deps): bump the uv group across 2 directories with 1 update (#4052)
Bumps the uv group with 1 update in the / directory:
[cryptography](https://github.com/pyca/cryptography).
Bumps the uv group with 1 update in the
/python/providers/claude_agent_sdk directory:
[cryptography](https://github.com/pyca/cryptography).

Updates `cryptography` from 49.0.0 to 50.0.0
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst">cryptography's
changelog</a>.</em></p>
<blockquote>
<p>50.0.0 - 2026-07-31</p>
<pre><code>
* **SECURITY ISSUE**:

:func:`~cryptography.hazmat.primitives.serialization.pkcs7.pkcs7_decrypt_der`
and its PEM and S/MIME variants no longer expose distinguishable errors
or
timing when unwrapping a ``RecipientInfo``'s ``encryptedKey``, which
could
act as a Bleichenbacher oracle for callers that decrypt untrusted
messages.
A random key is now substituted on failure, as described in :rfc:`3218`.
  Credit to **@X1AOxiang** for reporting the issue. **CVE-2026-69247**
* Deprecated Diffie-Hellman key exchange over finite fields (FFDH).
  Everything FFDH is deprecated, including the types in
``cryptography.hazmat.primitives.asymmetric.dh`` and loading FFDH keys
or
  parameters with the key loading APIs. Users should migrate to a more
  modern key exchange algorithm.
* Added ``xof()`` class methods to
  :class:`~cryptography.hazmat.primitives.hashes.SHAKE128` and
:class:`~cryptography.hazmat.primitives.hashes.SHAKE256` for
constructing
  algorithm instances configured for use with
  :class:`~cryptography.hazmat.primitives.hashes.XOFHash`.
* The :mod:`X.509 verification &lt;cryptography.x509.verification&gt;`
APIs are now
  considered stable and are subject to our API stability policy.
* Added the :doc:`/cobblestone` recipe, an implementation of the
  Cobblestone-128 and Cobblestone-256 instantiations of the `C2SP
  chunked-encryption specification
&lt;https://c2sp.org/chunked-encryption&gt;`_ for streaming
authenticated
  encryption of large messages.
* Parsing a Signed Certificate Timestamp list now rejects encodings that
carry trailing bytes after the list or after an individual SCT, instead
of
  silently ignoring them.
* Added support for using :class:`~cryptography.x509.Name` as a field
type in
  the :doc:`/hazmat/asn1/index` module.
* Loading a public key or an EC private key now rejects DER where the
``subjectPublicKey`` (or EC ``publicKey``) ``BIT STRING`` declares a
non-zero
  number of unused bits, instead of silently ignoring it.
* Parsing a CRL entry's ``InvalidityDate`` extension now rejects a
``GeneralizedTime`` that carries fractional seconds or another non-DER
form,
matching the strict encoding already required for every other X.509 time
  field.
* :func:`~cryptography.x509.ocsp.load_der_ocsp_request` and
:func:`~cryptography.x509.ocsp.load_der_ocsp_response` now reject a
request
or response whose ``version`` field is not ``v1``, the only version
defined
by RFC 6960, matching the version validation already performed when
loading
  certificates, CSRs and CRLs.
* :class:`~cryptography.hazmat.primitives.hashes.XOFHash` is now
supported
  when building against AWS-LC.
* HMAC (and therefore PBKDF2-HMAC) with SHA-3 hashes is now supported
when
  building against AWS-LC.
* Diffie-Hellman (:doc:`/hazmat/primitives/asymmetric/dh`) is now
supported
  when building against AWS-LC.
&lt;/tr&gt;&lt;/table&gt; 
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pyca/cryptography/commit/dcb7050b807b00392fa9fe2eac7cb362fcf355cc"><code>dcb7050</code></a>
Prepare for 50.0.0 release (<a
href="https://redirect.github.com/pyca/cryptography/issues/15372">#15372</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/53fccd93413a8d7f07d6d8999681f27b75cffa3f"><code>53fccd9</code></a>
Don't leak how PKCS#7 encryptedKey decryption failed (<a
href="https://redirect.github.com/pyca/cryptography/issues/15369">#15369</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/d472f978470fbefa521b86d98b2ecccbbb4d1dd8"><code>d472f97</code></a>
Add <code>from __future__ import annotations</code> to all src/ Python
files (<a
href="https://redirect.github.com/pyca/cryptography/issues/15371">#15371</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/908773d53829fb1466c6db364b31321c3cd8eb9a"><code>908773d</code></a>
Bump downstream dependencies in CI (<a
href="https://redirect.github.com/pyca/cryptography/issues/15368">#15368</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/2cc07cc948948211899bcb0cddd1fddf86e95812"><code>2cc07cc</code></a>
Bump BoringSSL, OpenSSL, AWS-LC in CI (<a
href="https://redirect.github.com/pyca/cryptography/issues/15367">#15367</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/c94ede9f040fa44942f7139772603419000acf66"><code>c94ede9</code></a>
chore(deps): bump ruff from 0.16.0 to 0.16.1 (<a
href="https://redirect.github.com/pyca/cryptography/issues/15366">#15366</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/67a8308dc9ea4cce6056e0f1438f903c208c3f35"><code>67a8308</code></a>
chore(deps): bump virtualenv from 21.7.0 to 21.7.1 (<a
href="https://redirect.github.com/pyca/cryptography/issues/15365">#15365</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/95018ffcdbbc510fd92fc872e3a3e80aa6e58596"><code>95018ff</code></a>
Release the GIL in one-shot AEAD encrypt/decrypt (<a
href="https://redirect.github.com/pyca/cryptography/issues/15361">#15361</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/6954733eaf55a0074abf88f06f7242dfca3a5d02"><code>6954733</code></a>
Release the GIL during DH and DSA parameter generation (<a
href="https://redirect.github.com/pyca/cryptography/issues/15364">#15364</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/6893b94c33e948f6240082461424cfb5da2dacc6"><code>6893b94</code></a>
Import _serialization instead of serialization in x509/extensions (<a
href="https://redirect.github.com/pyca/cryptography/issues/15363">#15363</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/pyca/cryptography/compare/49.0.0...50.0.0">compare
view</a></li>
</ul>
</details>
<br />

Updates `cryptography` from 49.0.0 to 50.0.0
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst">cryptography's
changelog</a>.</em></p>
<blockquote>
<p>50.0.0 - 2026-07-31</p>
<pre><code>
* **SECURITY ISSUE**:

:func:`~cryptography.hazmat.primitives.serialization.pkcs7.pkcs7_decrypt_der`
and its PEM and S/MIME variants no longer expose distinguishable errors
or
timing when unwrapping a ``RecipientInfo``'s ``encryptedKey``, which
could
act as a Bleichenbacher oracle for callers that decrypt untrusted
messages.
A random key is now substituted on failure, as described in :rfc:`3218`.
  Credit to **@X1AOxiang** for reporting the issue. **CVE-2026-69247**
* Deprecated Diffie-Hellman key exchange over finite fields (FFDH).
  Everything FFDH is deprecated, including the types in
``cryptography.hazmat.primitives.asymmetric.dh`` and loading FFDH keys
or
  parameters with the key loading APIs. Users should migrate to a more
  modern key exchange algorithm.
* Added ``xof()`` class methods to
  :class:`~cryptography.hazmat.primitives.hashes.SHAKE128` and
:class:`~cryptography.hazmat.primitives.hashes.SHAKE256` for
constructing
  algorithm instances configured for use with
  :class:`~cryptography.hazmat.primitives.hashes.XOFHash`.
* The :mod:`X.509 verification &lt;cryptography.x509.verification&gt;`
APIs are now
  considered stable and are subject to our API stability policy.
* Added the :doc:`/cobblestone` recipe, an implementation of the
  Cobblestone-128 and Cobblestone-256 instantiations of the `C2SP
  chunked-encryption specification
&lt;https://c2sp.org/chunked-encryption&gt;`_ for streaming
authenticated
  encryption of large messages.
* Parsing a Signed Certificate Timestamp list now rejects encodings that
carry trailing bytes after the list or after an individual SCT, instead
of
  silently ignoring them.
* Added support for using :class:`~cryptography.x509.Name` as a field
type in
  the :doc:`/hazmat/asn1/index` module.
* Loading a public key or an EC private key now rejects DER where the
``subjectPublicKey`` (or EC ``publicKey``) ``BIT STRING`` declares a
non-zero
  number of unused bits, instead of silently ignoring it.
* Parsing a CRL entry's ``InvalidityDate`` extension now rejects a
``GeneralizedTime`` that carries fractional seconds or another non-DER
form,
matching the strict encoding already required for every other X.509 time
  field.
* :func:`~cryptography.x509.ocsp.load_der_ocsp_request` and
:func:`~cryptography.x509.ocsp.load_der_ocsp_response` now reject a
request
or response whose ``version`` field is not ``v1``, the only version
defined
by RFC 6960, matching the version validation already performed when
loading
  certificates, CSRs and CRLs.
* :class:`~cryptography.hazmat.primitives.hashes.XOFHash` is now
supported
  when building against AWS-LC.
* HMAC (and therefore PBKDF2-HMAC) with SHA-3 hashes is now supported
when
  building against AWS-LC.
* Diffie-Hellman (:doc:`/hazmat/primitives/asymmetric/dh`) is now
supported
  when building against AWS-LC.
&lt;/tr&gt;&lt;/table&gt; 
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pyca/cryptography/commit/dcb7050b807b00392fa9fe2eac7cb362fcf355cc"><code>dcb7050</code></a>
Prepare for 50.0.0 release (<a
href="https://redirect.github.com/pyca/cryptography/issues/15372">#15372</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/53fccd93413a8d7f07d6d8999681f27b75cffa3f"><code>53fccd9</code></a>
Don't leak how PKCS#7 encryptedKey decryption failed (<a
href="https://redirect.github.com/pyca/cryptography/issues/15369">#15369</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/d472f978470fbefa521b86d98b2ecccbbb4d1dd8"><code>d472f97</code></a>
Add <code>from __future__ import annotations</code> to all src/ Python
files (<a
href="https://redirect.github.com/pyca/cryptography/issues/15371">#15371</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/908773d53829fb1466c6db364b31321c3cd8eb9a"><code>908773d</code></a>
Bump downstream dependencies in CI (<a
href="https://redirect.github.com/pyca/cryptography/issues/15368">#15368</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/2cc07cc948948211899bcb0cddd1fddf86e95812"><code>2cc07cc</code></a>
Bump BoringSSL, OpenSSL, AWS-LC in CI (<a
href="https://redirect.github.com/pyca/cryptography/issues/15367">#15367</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/c94ede9f040fa44942f7139772603419000acf66"><code>c94ede9</code></a>
chore(deps): bump ruff from 0.16.0 to 0.16.1 (<a
href="https://redirect.github.com/pyca/cryptography/issues/15366">#15366</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/67a8308dc9ea4cce6056e0f1438f903c208c3f35"><code>67a8308</code></a>
chore(deps): bump virtualenv from 21.7.0 to 21.7.1 (<a
href="https://redirect.github.com/pyca/cryptography/issues/15365">#15365</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/95018ffcdbbc510fd92fc872e3a3e80aa6e58596"><code>95018ff</code></a>
Release the GIL in one-shot AEAD encrypt/decrypt (<a
href="https://redirect.github.com/pyca/cryptography/issues/15361">#15361</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/6954733eaf55a0074abf88f06f7242dfca3a5d02"><code>6954733</code></a>
Release the GIL during DH and DSA parameter generation (<a
href="https://redirect.github.com/pyca/cryptography/issues/15364">#15364</a>)</li>
<li><a
href="https://github.com/pyca/cryptography/commit/6893b94c33e948f6240082461424cfb5da2dacc6"><code>6893b94</code></a>
Import _serialization instead of serialization in x509/extensions (<a
href="https://redirect.github.com/pyca/cryptography/issues/15363">#15363</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/pyca/cryptography/compare/49.0.0...50.0.0">compare
view</a></li>
</ul>
</details>
<br />


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
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/ComposioHQ/composio/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-04 19:20:09 +05:30
jkomyno 16b167c94a docs(cli): document COMPOSIO_BIN_DIR and the install abort contract
COMPOSIO_BIN_DIR was discoverable only by reading the changelog: it is
read through a raw ConfigProvider and appeared in no help text. Add it to
the README env-var table with its resolution order, and name it in the
install command description so `composio install --help` mentions it.
No --bin-dir flag: the env var is the right shape for an installer
handoff.

The changelog entry also picks up the behavior changes it was missing —
the non-zero exit on abort and what it means for install.sh's fallback,
both abort conditions, the narrowed character set, legacy-block
migration, and a note for custom-install-dir users reinstalling without
re-specifying COMPOSIO_INSTALL_DIR.
2026-08-04 19:17:14 +05:30
jkomyno d17844c848 ci(cli): fail the installation guard when a freshly built release skips the PATH write
The shell-config check accepted the legacy install.sh block on every leg,
justified by a comment claiming no leg installs a binary built from this
checkout. Build CLI Binaries calls this workflow with the tag it just
released, so that leg does exercise the new binary — and a completely
broken `composio install` that fell through to install.sh's writer still
reported success.

Callers now declare built_from_this_checkout; those legs must show the
CLI-managed PATH line. promote-stable keeps the permissive check, since
it rebuilds the promoted beta's own commit, which can predate the writer.
2026-08-04 19:16:23 +05:30
jkomyno 745bd67cef fix(cli): make composio install reconcile stale managed blocks
Three changes to the PATH writer, all around the same failure mode: the
command reporting success while leaving a shell unable to find composio.

- The unsafe-path denylist rejected characters that are literal inside
  the double quotes the bin dir is always written in. Keep only what
  bash, zsh, and fish still expand there, plus newline and the PATH
  separator, which are structural. /Users/o'brien/.composio now works.
- A file carrying the marker was treated as configured forever, so the
  legacy three-line block written by install.sh's fallback or by an
  older CLI was never migrated. Skip only on the exact rendered PATH
  line for the resolved bin dir; otherwise splice the current block over
  the stale one in place.
- The reachability skip used the invoking process's $PATH as evidence
  about future shells, so an ad-hoc export or a mise/direnv shim made
  the command persist nothing and exit 0. A redundant PATH line is
  harmless, and the content check already prevents duplicates.

installShellIntegration no longer takes an execPath override; it always
reads NodeProcess, and tests thread their exec path through the test
layer instead.
2026-08-04 19:16:09 +05:30
jkomyno 9f10adcc8d fix(installer): escape the install dir before writing it into shell rc files
install.sh's inline PATH fallback interpolated COMPOSIO_INSTALL_DIR raw
into the fish and zsh rc lines, and escaped only " in the bash arm. Since
that fallback is exactly what runs when `composio install` rejects a path
and exits non-zero, a directory containing $(...) or a backtick was
written unescaped into ~/.zshrc or config.fish and became live command
substitution at the next shell start.

Escape backslash, backtick, $ and " for every arm before the value is
embedded, skipping the backtick for fish (which neither substitutes it
nor recognizes \` inside double quotes). The $HOME prefix is re-applied
after escaping so the intended variable reference survives while a
user-supplied $ does not.
2026-08-04 19:15:59 +05:30
Alberto Schiabel 331a1373de Merge branch 'next' into feat/cli-install-shell-flag 2026-08-04 18:25:57 +05:30
jkomyno 72c9fb1dc8 fix(docs): remove legacy fish path on uninstall 2026-08-04 18:21:05 +05:30
jkomyno 47ae5f3029 fix(installer): resolve bin dir before shell setup 2026-08-04 18:18:29 +05:30
jkomyno 4a179f8fdc ci(cli): avoid unavailable installer routes 2026-08-04 18:17:00 +05:30
Alberto Schiabel f7a4503bbe fix(deps): clear high-severity TypeScript audit findings (#4050)
This PR:
- follows up on the failed TypeScript audit in
https://github.com/ComposioHQ/composio/pull/4048
- adds patched transitive floors for `fast-uri`, `ip-address`, and
`brace-expansion`
- refreshes `pnpm-lock.yaml` to resolve 3.1.5, 10.4.0, and 5.0.9
respectively
- clears all high-severity findings from `pnpm audit --prod
--audit-level=high`; one low and one moderate advisory remain below the
gate
- verifies the affected CLI dependency graph with a frozen install,
package build, and 1,072 passing tests (1 skipped)
2026-08-04 17:23:05 +05:30
Alberto Schiabel 15c07ec6c7 docs(cli): restore 0.3.0 and 0.3.1 changelog entries (#4048)
This PR:
- restores missing `0.3.0` and `0.3.1` sections in
`ts/packages/cli/CHANGELOG.md`
- moves the plugin hint and telemetry changes out of `0.2.33`
- records post-`0.3.1` connected-account and login fixes under
`Unreleased`
- rewrites the restored notes as concise, user-facing bullets
- validates the ignored-package boundary with `pnpm validate:changesets`
@composio/cli@0.3.2-beta.333
2026-08-04 17:10:43 +05:30
Soumya Medapati 9a51faf574 docs: "latest" requires the skip-version-check flag for manual execution (#4046)
## What

Runtime testing during eval-rerun prep caught a docs/runtime mismatch:
the guides say `toolkit_versions={"x": "latest"}` works for direct
execution, but `tools.execute()` rejects it —

```
ToolVersionRequiredError: Toolkit version not specified. For manual execution of the
tool please pass a specific toolkit version.
  1. Pass the toolkit version as a parameter to the execute function
     ("latest" is not supported in manual execution)
  ...
  4. Set dangerously_skip_version_check to True
```

Notably, the [TypeScript SDK
reference](/reference/sdk-reference/typescript/tools) already documents
the real behavior — the guides contradicted it. An isolated eval agent
independently hit the same wall and reported it.

Per SDK guidance (@abir-taheer): pass
`dangerously_skip_version_check=True` / `dangerouslySkipVersionCheck:
true` when running `latest` manually.

## Changes

- **All direct-execution samples** (executing-tools,
sessions-vs-direct-execution, custom-auth-params,
before/after-execution-modifiers) keep `"latest"` and add the skip flag
to the execute call with a one-line comment
- **executing-tools warning callout** now presents both paths:
skip-check when an LLM consumes outputs; pinned version (via
`toolkits.get(slug).meta.version`) when code parses them
- **toolkit-versioning page**: the "latest is valid" claims are
corrected to name the manual-execution requirement
- **LLM guardrails** (direct-execution block): same correction — this
block is what AI agents copy verbatim
- **execute-version static test**: now also fails any page showing
`"latest"` in execute samples without the flag (with the runtime
evidence cited in the header comment)

## Verification

- Both patterns executed against the live API before shipping: `latest`
+ flag → success; pinned via `toolkits.get(slug).meta.version` (resolved
`20260615_00`) → success; `latest` alone → the error above
- `bun test tests/static/` — 145 pass; negative check confirmed the new
rule fails with an actionable message when the flag is removed
- `bun run lint:links` — clean

## Note for reviewer

The pinned-version path also returns the *documented* nested response
schema — the "flat response" drift agents reported was a base-version
(`00000000_00`) artifact. Fixing versioning quietly resolves that report
too.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-08-03 16:31:58 -07:00
Soumya Medapati 52e538286e docs: 'latest' requires dangerously_skip_version_check for manual execution
Runtime testing during eval-rerun prep caught that toolkit_versions
'latest' is rejected by tools.execute() (ToolVersionRequiredError:
'"latest" is not supported in manual execution') — the guides recommended
it anyway; only the TS SDK reference documented the real behavior.

Per SDK team (Abir): pass dangerously_skip_version_check=True /
dangerouslySkipVersionCheck: true when running 'latest' manually. All
direct-execution samples now include the flag with a one-line comment;
the version-required callout explains both paths (skip-check for
LLM-consumed outputs, pinned via toolkits.get(slug).meta.version for
parsed outputs); the toolkit-versioning page's 'latest' claims are
corrected; the execute-version static test now fails any page showing
'latest' without the flag. Both patterns runtime-verified against the
live API before shipping.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 16:23:22 -07:00
shams haroon fee2a73a7e docs: document Custom MCP toolkit logo upload (#4021)
## Problem

Custom MCP docs don't mention logos, so developers don't know they can
replace the default Composio logo their toolkit shows in the dashboard
and on end-user connect screens.

## What this adds

A new "Add a toolkit logo" section on the Custom MCP page, after
registration: the `toolkit_config.logo_file` field (base64 `content` +
`mime_type`), a cURL example with a placeholder base64 value, the
constraints (PNG/JPEG, square 256-1024px, max 3MB, single-line base64),
the default-logo behavior when omitted, and the insert-only implication
that changing a logo means delete + re-register. Follows the docs
convention of language/OS-neutral examples.

## Testing

`bun run lint` (0 errors) and `bun run lint:links` (0 errors) from
`docs/`.

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

https://claude.ai/code/session_016x2W47caMs6zW4V8uu1M9g
2026-08-03 16:00:25 -07:00
Soumya Medapati 8dffbcf888 docs: toolkit-discovery entry points + version-policy CI check (eval findings round 2) (#4045)
## What

Round 2 of fixes from the 97-agent docs eval (findings:
ctx.composio.io/soumya/docs-agent-eval/findings-97-run.md). Follow-up to
#3999.

## Commit 1 — toolkit-discovery entry points (eval finding 3)

51/97 agents struggled to identify the right toolkit; 15 abandoned the
docs for the raw REST API. The catalog and search already exist and
score well (46/97 praised them once found) — these edits wire them into
the paths readers actually take:

- Quickstart intro: "1000+ apps" now links to the /toolkits catalog
- executing-tools + fetching-tools: a "finding a toolkit and tool"
pointer (catalog, `composio search`, semantic search) before the
parameter-finding guidance
- direct-execution LLM guardrails: a discovery rule, so AI readers stop
inventing their own path via the REST API

## Commit 2 — version-policy static test (the durable half of eval
finding 1)

The content fix for the 72/97 `ToolVersionRequiredError` failure landed
in #3999; this keeps it fixed. New
`tests/static/execute-version.test.ts`: any authored page whose code
fences call `tools.execute()` must show version configuration in its
fences; the LLM guardrail blocks are held to the same rule. Changelog,
generated reference, and migration guides are exempt as
historical/point-in-time records.

Running the new rule against current content caught **five more pages**
shipping version-less execute samples that the eval never visited —
including sessions-vs-direct-execution. Fixed in the same commit.

## Verification

- `bun test tests/static/` — 145 pass (including the new test)
- Negative check verified: removing a version token from a page fails
the test with an actionable message naming the file
- `bun run lint:links` — clean

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-08-03 13:55:27 -07:00
Soumya Medapati 70f6772037 docs: enforce toolkit-version policy on execution samples via static test
Adds tests/static/execute-version.test.ts: any authored page whose code
fences call tools.execute() must show version configuration, and the LLM
guardrail blocks are held to the same rule. Fixes the five pages the
audit caught (sessions-vs-direct-execution, custom-auth-params,
before/after-execution-modifiers) which shipped version-less samples.
Changelog, generated reference, and migration guides are exempt as
historical/point-in-time records.

This is the durable half of eval finding 1: the content fix landed in
#3999; this test keeps future samples from regressing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 12:17:55 -07:00
Soumya Medapati 1857a8fa1c docs: add toolkit-discovery entry points from quickstart and execution pages
Eval finding 3: 51/97 agents struggled to identify the right toolkit;
15 abandoned the docs for the raw REST API. Links the toolkits catalog
from the quickstart intro, adds a find-your-toolkit pointer to the
executing-tools and fetching-tools pages, and adds a discovery rule to
the direct-execution LLM guardrails.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 11:57:27 -07:00
Alberto Schiabel 1503786358 refactor(core): forbid explicit any and type JSON Schema recursively (#3968)
This PR:

- is refreshed directly onto the current next branch now that #3966 and
#3967 have merged; the PR contains only its intended type-safety work
- enforces no explicit any through the standard .oxlintrc.json, pnpm
lint, and plain oxlint --fix in lint-staged; docs remain covered by
their nested configuration
- replaces the loose JSONSchemaProperty in @composio/core with a
concrete recursive interface, removing explicit any reachable through
Tool.inputParameters and Tool.outputParameters
- includes a minor changeset documenting the type narrowing for
properties, default, and enum consumers
- adds a compile-only public-contract test for recursive schemas,
known-key validation, extension keywords, and Tool reachability
- removes explicit any from FileToolModifier, ts-builders, core and CLI
tests, provider tests, and json-schema-to-zod tests
- keeps TypeScript ESLint-parity rules enabled and closes the
tool-router example lint/typecheck gap
- makes no lockfile changes and no runtime behavior changes

## Context

Final PR from the original #3958 split. The migration foundations are
already on next via #3966 and #3967, so this branch no longer carries a
stacked base commit.
@composio/cli@0.3.2-beta.332
2026-08-03 22:24:57 +05:30
jkomyno 6b964237b9 Merge branch 'feat/cli-install-shell-flag' into feat/mise-style-installer-rollout 2026-08-03 21:41:22 +05:30
jkomyno 7198dcce8d docs(cli): explain the bash login-override special case 2026-08-03 21:41:18 +05:30
composio-zen[bot] 8dcc9b9914 docs(sandbox): clarify Composio doesn't run/replace your agent (LLM tokens are sandbox-only & optional) (#3933)
# Description

Customers evaluating Composio see references to **LLM tokens** and
assume Composio is handing them an agent/LLM that *replaces* their own —
i.e. that they'd be swapping their agent for ours. It isn't: Composio
discovers, authenticates, and executes tools; it never proxies the
customer's model or runs an agent on their behalf.

The one place Composio itself calls a model is **inside the sandbox**
(the optional `invoke_llm` helper + AI-assisted conveniences like error
correction). The sandbox is opt-in per session (`sandbox: { enable: true
}`), so this LLM usage is entirely optional and can be disabled.

This PR adds a short callout to the **Remote sandbox** docs page
(`docs/content/docs/sandbox/remote.mdx`) that says exactly that — placed
right where `invoke_llm` and the sandbox are introduced, with anchor
links to the `invoke_llm` helper, error correction, and session
configuration. It kills the "are they replacing my agent?" misconception
at its source.

The copy is deliberately accurate to today's state: it does **not**
claim we bill LLM tokens (sandbox billing is still upcoming and the
public pricing page only lists Tool Calls). It frames the point
conceptually — *your agent stays yours; the only Composio-side LLM usage
is optional and sandbox-scoped.*

**Follow-up surfaces (not in this PR — see below):** this same
clarification could be mirrored on the dashboard usage/billing UI and
the marketing pricing page when an "LLM tokens" line item actually
surfaces there. Those live outside this repo.

# How did I test this PR

- Docs-only change (single `.mdx` file); no code or dependency surface.
- Verified all anchor targets referenced in the new callout exist on the
same page / site:
  - `#built-in-helpers` → `### Built-in helpers` (the `invoke_llm` row)
  - `#error-correction` → `### Error correction`
- `/docs/configuring-sessions` (existing page; documents `sandbox: {
enable: true }`)
- Matches the existing `<Callout title="...">` component usage already
on the page (the "Renamed from workbench" callout), so it renders
consistently in Fumadocs.
- Confirmed against source that `invoke_llm` (docs `Built-in helpers`
table) is the Composio-side LLM entry point and that the sandbox is
opt-in via the `sandbox`/`workbench` session key.

# Security

- **Scope:** documentation-only change — one `.mdx` file, no
dependencies, lockfiles, or executable code added/changed.
- **Socket / Grype:** not applicable to this diff (no package manifests
or code paths introduced); no new fixable CRITICAL/HIGH/MEDIUM findings
possible from a Markdown copy addition.

Triggered by: palash@composio.dev | Source: slack
Session: https://zen.corp.composio.io/dashboard/#/chat/zen-f6a81a5a6764

---------

Co-authored-by: Zen Agent <zen@composio.dev>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-03 20:46:56 +05:30
sdkrelease[bot] 082ba79ced docs: update toolkits, API spec, and meta tools data (#3959)
## Summary
Automated sync of backend data into the docs site. Triggered by:
`schedule`.

## What changed
- **Toolkit catalog** (`docs/public/data/toolkits.json`,
`toolkits-list.json`) — refreshed list of available toolkits, auth
schemes, and tools from the backend API
- **OpenAPI specs** (`docs/public/openapi.json`,
`docs/public/openapi-v3.json`, `docs/public/openapi-webhooks.json`) —
latest v3.1 and v3.0 API specifications plus the webhook-events spec,
fetched from production
- **API reference pages** (`docs/content/reference/api-reference/`,
`docs/content/reference/v3/api-reference/`) — regenerated index pages
for both API versions
- **Meta tools reference** (`docs/public/data/meta-tools.json`,
`docs/content/toolkits/meta-tools/*.mdx`) — updated meta tool schemas
and reference docs

Co-authored-by: Sushmithamallesh <19796925+Sushmithamallesh@users.noreply.github.com>
2026-08-03 20:46:20 +05:30
jkomyno 32b84ab192 Merge branch 'feat/cli-install-shell-flag' into feat/mise-style-installer-rollout 2026-08-03 20:44:57 +05:30
jkomyno aa28325394 test(cli): add a fish leg to the local install e2e 2026-08-03 20:32:36 +05:30
jkomyno b52dd3c0af refactor(e2e): share docker env args and add the install-image race retry 2026-08-03 20:32:36 +05:30
jkomyno 9afe5a7f81 test(cli): deduplicate harness env setup and the SIGTERM download scenario 2026-08-03 20:32:36 +05:30
jkomyno c41217bff2 test(cli): pin the three uninstall file lists together against drift 2026-08-03 20:32:36 +05:30
jkomyno 367db3b069 ci(cli): pin the installer preview comment to the tested head commit 2026-08-03 20:32:36 +05:30
jkomyno 03c326a19a fix(cli): install the CLI bundle via staged renames to survive busy binaries 2026-08-03 20:32:36 +05:30
jkomyno ba4fa222ab test(cli): exercise the installer extraction-failure branch in the install e2e 2026-08-03 20:32:36 +05:30
jkomyno 648e95727a fix(cli): exit non-zero when shell setup aborts
Both abort branches (unsafe or relative resolved bin dir) printed an error
and returned, so the effect succeeded and the process exited 0. install.sh
gates its inline PATH fallback on a non-zero exit from 'composio install',
so an aborted setup looked green and left the user with no PATH setup at
all. Raise a typed ShellSetupAbortError after printing the abort reason;
cli-main.ts maps it to exit code 1 without printing anything further, so
install.sh now takes its fallback branch.
2026-08-03 20:29:52 +05:30
jkomyno 48f3ebe2a1 refactor(cli): type the install test helper's shell param with the Shell union
The helper widened shell to string and cast it back to the union, bypassing
the checker. Export Shell from install.cmd.ts and use it directly.
2026-08-03 20:26:09 +05:30
jkomyno 021125b7a8 fix(cli): create the rc tmp copy with the preserved file mode
The tmp copy was written with the default 0644 mode and only chmod'd to the
target's mode afterwards, so a 0600 private rc's contents sat world-readable
in <target>.composio-tmp for the duration of the window. Create the tmp file
with the preserved mode from the start; open(2) masks that mode with the
umask (only ever clearing bits), so the follow-up chmod stays to pin the
exact mode before the rename.
2026-08-03 20:25:37 +05:30
jkomyno 184404a4af test(cli): run the bashism sweep with grep so it cannot silently skip 2026-08-03 20:24:45 +05:30
jkomyno 2b9c02aea3 test(cli): close the drift-guard bypass for duplicated requested_shell() 2026-08-03 20:24:30 +05:30
jkomyno 5d007da225 fix(ci): accept the legacy PATH block when verifying installed shell config
The shell-config assertions only passed for binaries that write the new
CLI-managed PATH line, but every leg of this workflow installs a published
release binary: workflow_dispatch re-verification of existing releases,
workflow_call with the default 'latest', and promote-stable rebuilds of an
older beta all install pre-change binaries that write the legacy
COMPOSIO_INSTALL_DIR block (as does install.sh's own fallback). Accept
either working PATH layout, fail only when neither is present, and keep
rejecting a mixed state where the new PATH line coexists with a persisted
COMPOSIO_INSTALL_DIR.
2026-08-03 20:24:07 +05:30
jkomyno b381210c2d test(cli): align the installer analytics guard with the shell-delegation flow 2026-08-03 20:23:55 +05:30
jkomyno 6d0e14f155 fix(cli): only prefer ~/.local/bin when its composio entry is this executable
A bare exists-check let any leftover ~/.local/bin/composio (e.g. a pip or
pipx install) win bin-dir resolution, so the PATH line pointed shells at a
foreign program while the installer reported success. Prefer ~/.local/bin
only when its entry realpath-resolves, following symlinks, to the running
executable; otherwise fall through to the runtime executable's directory.
The COMPOSIO_BIN_DIR override stays highest precedence.
2026-08-03 20:23:14 +05:30
Alberto Schiabel 61aafbc9d3 refactor(docs): parse untyped data with zod and forbid explicit any (#3967)
This PR:

- builds on top of https://github.com/ComposioHQ/composio/pull/3966
- enables `typescript/no-explicit-any` (error, `fixToUnknown`) for docs
in `docs/.oxlintrc.json` and removes every remaining explicit `any` in
docs code
- parses untyped/external data once at the boundary with zod v4 schemas
and lets `z.infer` types flow downstream — no hand-rolled `'x' in obj`
guard chains, no `as`-casts of untyped page data, no
`docs/lib/unknown-value.ts`
- adds domain schema modules: `docs/lib/toolkit-schema.ts` (recursive
JSON-Schema node, raw tool/trigger payloads, list envelopes) and
`docs/lib/reference-page-data.ts` (fumadocs reference page data for both
reference routes)
- rewrites `validate-links.ts`, `generate-toolkits.ts`,
`generate-meta-tools.ts`, the `llms.mdx` route, and
`deprecated-api-sidebar.tsx` on those schemas with identical validation
outcomes
- carries the pure typing improvements from the earlier attempt (typed
reference source in `source.ts`, `LLMPage`/`PageLike`, typed
`ClientLogo[]` in `logo-bar.tsx`, component `any` removals)
- adds `tests/static/toolkit-schema.test.ts` and
`tests/static/generate-toolkits.test.ts` pinning the transform shapes;
no changeset (docs is not published)

## Context

Second of the three-PR split of #3958, replacing its rejected
structural-guard approach with zod schemas at the data boundaries.
Verified with `bun run lint`, `bun run types:check`, `bun test
tests/static/` (125 pass), `bun run lint:links`, and a full `next
build`.

## Review follow-up

Addressed the regressions reported in [the Zod boundary
re-review](https://github.com/ComposioHQ/composio/pull/3967#issuecomment-5105279224):
scalar JSON Schema enums and auth defaults are preserved as strings,
malformed toolkit page envelopes abort generation, and the pre-refactor
empty-string fallbacks are restored. Regression coverage lives in
`tests/static/toolkit-schema.test.ts` and
`tests/static/generate-toolkits.test.ts`.

Verified on `2f26c40be` with `bun test tests/static/` (125 pass), `bun
run types:check`, and `bun run lint` (0 errors; existing warnings only).
2026-08-03 19:52:04 +05:30
Alberto Schiabel 10e93add6b fix(cli): address bugbot review findings from the guardrails stack (#3886)
Follow-up to https://github.com/ComposioHQ/composio/pull/3885, which is
now merged into `next`.

This PR:
- reports pending-login cache read failures as I/O errors instead of
masking them as decode failures (`composio login --poll`)
- restores pairwise polarity assertions for the `semverComparator`
Array.sort compatibility case
- consolidates the duplicated ephemeral HTTP server test helper in
`test/__utils__/http-server.ts`
- makes server-owned connected-account statuses forward-compatible while
preserving the credential-stripping schema allowlist
- redacts raw payload values from connected-account parse warnings and
adds regression coverage for unknown statuses and secret-bearing
malformed payloads
- documents why the client-singleton test re-derives the consumer cache
cwd hash

## Rebase notes

Rebased onto `origin/next` at `ef1ec9148`.

- Dropped the empty `GITHUB_*` compatibility commit; that contract is
already present on `next` through
https://github.com/ComposioHQ/composio/pull/3880.
- Adapted the connected-account decoder rename to the service extracted
upstream in `connected-account-selection.ts`.

## Context

Fix-forward PR for actionable Cursor Bugbot findings on the guardrails
stack (#3877–#3885). The stale decode-error string match and unused
release helper were already resolved upstream, and the `vi.stubEnv(...,
undefined)` concern is not actionable on Vitest 4.1.10.
@composio/cli@0.3.2-beta.331
2026-08-03 19:20:45 +05:30