Commit Graph

4175 Commits

Author SHA1 Message Date
Malay Vasa e1ec52bbca docs: dark mode, navbar polish, scroll reset, platform→dashboard rename (#3465)
## Summary

- **Dark/light theme switcher** in the navbar. Drops `forcedTheme:
'light'` so the toggle actually flips themes; sidebar footer toggle
stays disabled so there's only one switcher.
- **Dark mode color pass.** `--composio-brand` lifts to a muted
`#5B8BF0` (the deep `#0007cd` brand reads as unlit text on `#0f0f0f`).
Card / muted greys nudge to `#1c1c1c` / `#1f1f1f`. Borders drop from 10%
white to 6% so card edges sit back. `--border` / `--sidebar-border`
follow suit.
- **Square navbar.** Search input and the new theme toggle render with
`border-radius: 0` to match the rest of the navbar.
- **Welcome-page scroll reset.** New `ScrollReset` client component
wired into the root layout. Next.js App Router skips its built-in scroll
reset when the new route resolves to the same dynamic `page.tsx` segment
— every link from the welcome page to a `/docs/*` page hits this case,
so users were landing mid-page on the new route. Now `usePathname()`
change ⇒ `window.scrollTo(0, 0)` (skips first render and any
hash-bearing navigation).
- **`platform.composio.dev` → `dashboard.composio.dev`** across docs
content + the direct-execution LLM guardrail (28 files).
`docs/public/openapi*.json` left alone — auto-generated, and the
surviving reference is literally to the legacy dashboard.

## Test plan

- [ ] Toggle theme from the navbar; verify both light and dark render
- [ ] In dark mode, confirm "Docs" nav active state, chip icons,
"CONNECTED" labels, and Ask AI button read clearly against `#0f0f0f`
- [ ] Scroll to the bottom of `/docs`, click any link in HomeResources /
HomeSurfaces / HomeFeatures — the new page should land at scroll 0
- [ ] Click a TOC `#anchor` link inside a docs page — should still
scroll to the anchor (not get clobbered to 0)
- [ ] Spot-check a few rewritten URLs in cookbooks / quickstart — all
`platform.composio.dev` should now be `dashboard.composio.dev`

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@composio/cli@0.2.31-beta.256
2026-05-20 00:06:06 -07:00
Malay Vasa d84557ca21 docs: rework welcome page with v2 hero and homepage sections (#3464)
## Summary

Reworks the docs welcome page (`/docs`) into a two-column hero with an
animated agent chat mock + tool overlay, plus four restructured homepage
sections.

### Hero (`DocsHeroV2`)
- Left: headline (`Start building with Composio.`), short sub,
brand-blue chip column (Quickstart, API reference, Toolkits).
- Right (lg+ only): mock chat panel with the v1 hero's per-agent skin
(`Claude Cowork` / `ChatGPT Codex` / `Your AI Agent`), step-by-step
timeline-driven animation (user prompt → thinking dots → tool-trail
items → assistant response), and a floating "active tool" card layered
over the chat's left edge.
- L-shape SVG connector between chat and overlay: muted grey resting
state + brand-blue glow + bright line that re-draw via `pathLength` on
every tool change.
- Mock chat hidden below lg.

### Homepage sections
- **`HomeFeatures`** — `Everything you need to ship production agents.`
2×2 grid with bespoke visuals per pillar: 8×2 toolkit grid with `+1K`
cell, sessions panel (`USER_ID` + connected apps), triggers feed (`LIVE`
indicator + recent events), and a workbench mock with animated 4×2 CPU
lights. `auto-rows-fr` on `sm:` so cards equalize on tablet/desktop but
breathe on mobile.
- **`HomeSurfaces`** — `Three ways to use Composio.` bento: Developer
card spans full width (`md:col-span-3`) and shows 8 provider logos
(Anthropic, OpenAI, Vercel AI, Google, LangChain, CrewAI, LlamaIndex,
Mastra). Row 2: For You (with Claude / Codex / Cursor / Windsurf /
OpenClaw client logos), CLI (with `curl ... | bash` install snippet and
functional copy button), Agents.
- **`HomeResources`** — `Reach for the rest.` six-card footer row with
Quickstart, API reference, Cookbooks, Changelog, Toolkits,
Troubleshooting.

### Other
- Ports the landing-page hero into `components/landing-hero/` (kept
under the original `DocsHero` for easy revert; commented out, V2 wired
in).
- Theme-aware `--hero-*` CSS vars for chat-skin colors so the chat reads
in both light and dark.
- Removes the old `Works with your stack` provider grid (the providers
now live inside the Developer surface card).

## Test plan
- [ ] Verify hero animation cycles through 3 examples on desktop
- [ ] Verify L-shape connector pulses in brand blue on every tool change
- [ ] Verify chat mock is hidden on mobile and left column reads on its
own
- [ ] Verify dark mode (chat skins, connector, card surfaces, code
blocks)
- [ ] Verify CLI install copy button copies and toggles the icon to ✓
- [ ] Verify all chip / card hrefs resolve

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 22:06:35 -07:00
Rahul Tarak 3411c39adc docs: update CLI and reference navigation (#3462)
## Summary
- Rework the CLI docs around Composio for You / Claude Code usage, with
sections for knowledge work, `run`/sub-agents, trigger listening,
developer workflows, and unsupported direct CLI embedding.
- Move CLI into the top of Other topics and remove single-toolkit MCP
from the Docs sidebar.
- Move Changelog into Reference after Errors, with a grouped single-page
changelog, scroll-based date anchors, and redirects from old
`/docs/changelog` URLs.
- Add the Claude logo to the “Open in Claude” page action.

## Tests
- `cd docs && bun run lint:links`
- `cd docs && bun test tests/static/navigation.test.ts`
- `cd docs && bun run build`
2026-05-19 17:01:58 -07:00
Rahul Tarak e842e68e4b docs: merge and group guide content (#3456)
## Summary
- Stack this PR on top of #3455 (`docs/love-fixes`).
- Rework the former Core Concepts / Getting Started / Guides / Features
area into a smaller set of sections:
  - Build with sessions
  - Authenticate users
  - Triggers and webhooks
  - Direct Tool Execution Guides (Legacy)
  - Other topics
- Move conceptual session pages (`how-composio-works`, users/sessions,
tools/toolkits, authentication, workbench, triggers) into the
appropriate grouped sections.
- Merge duplicated custom-auth content into `Managed vs custom auth`
(`/docs/custom-app-vs-managed-app`) and redirect the old
`/docs/using-custom-auth-configuration` URL.
- Trim repeated OAuth-app setup from white-labeling docs so that page
focuses on branding, callback-domain routing, and post-auth redirect UX.
- Clean up “What to read next” cards so non-legacy pages no longer point
at direct-execution docs and first point to the next item in their
section where possible.
- Fix the session lifecycle contradiction in `how-composio-works` so it
matches the current persisted/reusable session model.

## Checks
- `cd docs && bun run lint:links`
- `cd docs && bun test tests/static/navigation.test.ts`
2026-05-19 05:17:31 -07:00
Rahul Tarak 9acfa852b2 docs: tidy welcome page, fix playground link, hide ugly Ask AI tab (#3455)
## Summary

Three small docs polishes:

- **Hide the disgusting "Ask AI" side tab.** The Decimal widget renders
its own `.decimal-widget-sidebar-tab` launcher (vertical pill with
sideways text) on every page. We already trigger the widget from our own
"Ask AI" button in the nav, so the third-party launcher is redundant
*and* ugly. Hidden via CSS in `app/global.css`.
- **Fix the Playground nav link.** It pointed at
`platform.composio.dev/auth?next_page=/tool-router` — which (a) hits a
dead host now that platform has moved to `dashboard.composio.dev`, and
(b) lost the playground's connect check on the redirect. Repointed to
`https://dashboard.composio.dev/~/project/playground`, which is the
dashboard's smart-resolver route: it handles login (`?next=`), looks up
`last_visited` / default org+project, and lands the user on
`/{org}/{project}/playground` with the connect step intact. Same fix
applied to the toolkits landing CTA and the welcome-page Playground
card.
- **Trim the welcome page.** Dropped the duplicated intro Cards row, the
"Get Started" / "Explore" / "Features" / "Community" headers, and the
secondary Features grid. Now it's: intro → AIToolsBanner → Quickstart →
Toolkits + Playground → Providers. Much cleaner.

## Test plan

- [ ] `bun run scripts/validate-links.ts` passes (already verified
locally — 0 errors)
- [ ] On preview deploy, the side "Ask AI" tab is gone
- [ ] Clicking "Playground" in the nav (logged out) lands on login →
playground; (logged in) lands on `/{org}/{project}/playground`
- [ ] Welcome page renders without missing-icon errors

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-19 04:09:48 -07:00
Rahul Tarak 18c3b98de6 docs: reapply Algolia docs search (#3454)
## Summary
- Re-apply the Algolia docs search migration after the previous PR was
merged and reverted.
- Keep the existing Fumadocs search UI while using Algolia API when
search keys are configured, with `/api/search` fallback for local
development and tests.
- Add a first-party Algolia index builder/sync script that creates
section-sized docs records from MDX/OpenAPI/toolkit/changelog content,
configures index relevance settings, and replaces index objects without
relying on Algolia Crawler.
- Add Algolia Insights view/click events and a terminal search relevance
test script.
- Clean search breadcrumbs so results show labels like `Toolkit` and
`Cookbook` instead of duplicated `toolkits > Gmail` formatting.

## Tests
- `cd docs && bun run types:check`
- `cd docs && bun run sync:search --dry-run`
- `cd docs && bunx eslint components/custom-search-dialog.tsx
lib/search-index.ts scripts/sync-algolia-search.ts
scripts/test-algolia-search.ts`

## Notes
- Live Algolia sync requires `ALGOLIA_ADMIN_API_KEY`.
- Live search relevance tests require `ALGOLIA_SEARCH_API_KEY` or
`NEXT_PUBLIC_ALGOLIA_SEARCH_API_KEY`.
2026-05-19 02:27:40 -07:00
Rahul Tarak 1692bbee7a fix(cli): make output more LLM friendly (#3450)
## Summary
- Route Effect pretty logger output to stderr and share a TTY-based
interactive detector for human-only CLI UI.
- Gate upgrade notices and default browser login waiting on interactive
stdio; non-interactive `composio login` now emits session JSON and
exits.
- Stream `composio run` helper/subagent logs to stderr (or only to the
run log with `--logs-off`) without polluting stdout.
- Add a CLI patch changeset.

## Tests
- `pnpm -C ts/packages/cli exec vitest run
test/src/services/update-check.test.ts
test/src/commands/login.cmd.test.ts test/src/commands/run.cmd.test.ts`
- `pnpm --filter @composio/cli typecheck`
- `pnpm typecheck`
- `pnpm exec eslint ts/packages/cli/src/utils/stdio.ts
ts/packages/cli/src/services/terminal-ui.ts
ts/packages/cli/src/services/update-check.ts
ts/packages/cli/src/cli-main.ts
ts/packages/cli/src/commands/login.cmd.ts
ts/packages/cli/src/commands/run.cmd.ts
ts/packages/cli/src/services/run-helpers-runtime.ts --no-warn-ignored`
- `pnpm exec prettier --check ts/packages/cli/src/utils/stdio.ts
ts/packages/cli/src/services/terminal-ui.ts
ts/packages/cli/src/services/update-check.ts
ts/packages/cli/src/cli-main.ts
ts/packages/cli/src/commands/login.cmd.ts
ts/packages/cli/src/commands/run.cmd.ts
ts/packages/cli/src/services/run-helpers-runtime.ts
ts/packages/cli/test/src/services/update-check.test.ts
ts/packages/cli/test/src/commands/login.cmd.test.ts`

## Notes
- Initial targeted `pnpm --filter @composio/cli test -- ...` ran the
full CLI suite and failed before building `@composio/cli-keyring`; after
building/installing workspace deps, the targeted Vitest command above
passed.
@composio/cli@0.2.31-beta.255
2026-05-19 01:45:56 -07:00
Rahul Tarak 5f400fc5f7 Revert "docs: migrate search to Algolia" (#3453)
Reverts ComposioHQ/composio#3452
2026-05-19 01:34:36 -07:00
Rahul Tarak 7bd3e0669c docs: migrate search to Algolia (#3452)
## Summary
- Switch docs search dialog to Algolia when public Algolia env vars are
configured, with local `/api/search` fallback for development/tests
- Add a shared docs search index builder plus `bun run sync:search` to
publish records to Algolia
- Add a GitHub Actions workflow to dry-run and sync the Algolia index on
`next` docs changes when secrets are configured
- Document required Algolia env vars and sync command

## Tests
- `cd docs && bun run types:check`
- `cd docs && bun run sync:search --dry-run`
- `cd docs && bun test tests/static/`
- `cd docs && bunx eslint components/custom-search-dialog.tsx
lib/search-index.ts scripts/sync-algolia-search.ts`
- `cd docs && bun run build`

## Notes
- `bun run lint` still fails on existing unrelated repo-wide lint errors
in files outside this change (for example `app/global-error.tsx`,
`components/ask-ai-button.tsx`, `components/version-selector.tsx`). The
changed search files pass targeted ESLint.
- Production search requires `NEXT_PUBLIC_ALGOLIA_APP_ID`,
`NEXT_PUBLIC_ALGOLIA_SEARCH_API_KEY`, and optionally
`NEXT_PUBLIC_ALGOLIA_INDEX_NAME` (default `composio_docs`). Index
syncing requires `ALGOLIA_APP_ID`/`ALGOLIA_ADMIN_API_KEY` secrets.
2026-05-19 01:33:26 -07:00
Rahul Tarak afa118c8fb fix(cli): make permission allows expire after one hour (#3449)
## Summary
- Rename the permission prompt action from “Allow for session” to “Allow
for 1 hr” in browser and native UI flows.
- Cache allow decisions with a 1-hour expiry in
`tool-permissions-cache.json`, with an in-memory fast path and
stale-entry pruning.
- Preserve existing permission snapshot cache behavior while keeping
cached allow decisions across CLI invocations until expiry.

## Tests
- `pnpm install --frozen-lockfile --ignore-scripts`
- `pnpm build:packages`
- `cd ts/packages/cli && pnpm run typecheck`

## Notes
- The decision enum remains `allow_session` for compatibility with
existing backend/native callback payloads; only the UX/caching semantics
now expose and enforce a 1-hour duration.
@composio/cli@0.2.31-beta.254
2026-05-19 00:19:31 -07:00
Alberto Schiabel 4367513f82 fix(python): guard enhance_schema_descriptions against empty schemas (#3398)
Stacked on #3397 · refs
https://github.com/ComposioHQ/composio/issues/3354

## Summary

The TS fix in #3397 handled the reported case (`output_parameters: {}`
from MCP toolkits) by normalizing empty schemas at `transformToolCases`.
While verifying the Python SDK didn't have the equivalent Zod check, I
found an **adjacent** crash on the input side.

The Python SDK does not have the same Pydantic check** —
`composio_client` types `input_parameters` / `output_parameters` as
`Dict[str, Optional[object]]`, which accepts `{}` trivially.
However, `Tools._get()` pipes every fetched tool's `input_parameters`
unconditionally through `FileHelper.enhance_schema_descriptions`
(`python/composio/core/models/tools.py:361-363`), which does:

```python
for _param, _schema in schema["properties"].items():
```

That crashes with `KeyError: 'properties'` on `schema={}`. Not reachable
for the specific `granola_mcp` tools in the original report (they all
have populated `input_parameters`), but it's the same API contract — any
MCP tool with no required inputs would hit this through the public
`Composio.tools.get(...)` call.

The sibling `FileHelper.process_file_uploadable_schema`
(`_files.py:760`) already guards this with `if "properties" not in
schema: return schema`. This applies the same guard to
`enhance_schema_descriptions`.

## Fix

```diff
 def enhance_schema_descriptions(self, schema: t.Dict) -> t.Dict:
     ...
+    if "properties" not in schema:
+        return schema
     required = schema.get("required") or []
     for _param, _schema in schema["properties"].items():
```

## Testing

Red → green confirmed locally. New
`TestEnhanceSchemaDescriptionsEmptySchema` class in
`tests/test_files.py` covers:

1. `schema={}` → returns `{}` (the bug repro).
2. Schema with metadata but no `properties` key → returned unchanged
(mirrors the sibling method).
3. Schema with `properties: {}` (empty dict) → already works today;
pinning behavior.
4. Populated schema → still enhanced (regression guard for the type-hint
/ required-marker enhancement).

Cases 1–2 **fail on `next`** with `KeyError: 'properties'`. All 4 pass
with the guard. Full `tests/test_files.py` stays green (116 tests).

```bash
cd python
.venv/bin/python -m pytest tests/test_files.py::TestEnhanceSchemaDescriptionsEmptySchema -v   # → 4 passed
.venv/bin/python -m pytest tests/test_files.py -q                                              # → 116 passed
```

## Stacked PR notes

- Base: `jkomyno/fix-mcp-empty-output-parameters` (#3397).
- This PR's diff against that base shows **only** the Python changes
(`_files.py` + `tests/test_files.py`).
- After #3397 merges, this should be retargeted to `next` (or rebased
automatically by GitHub).

---------

Co-authored-by: jkomyno <12381818+jkomyno@users.noreply.github.com>
2026-05-17 01:03:33 +04:00
Rahul Tarak eb51b923bb feat(cli): send x-cli-session-id header on every request (#3430)
## Summary

- Pulls the per-cwd CLI session id (already generated by
`getCurrentCwdSessionId()` and used as `cli_session_id` on analytics
events) and attaches it as the `x-cli-session-id` header on every
request from the composio client.
- Backend reads the header off `requestInfo`, threads it through
`enrichSessionInfo`, and writes `session_info.cli_session_id` on every
tool execution log row.

Companion hermes PR: ComposioHQ/hermes#9990

## Why

The CLI already tracks a stable per-cwd session id for analytics, but
tool execution logs are blind to it — there's no way to filter the logs
UI / retool back to a single CLI session. Wiring the header through lets
us group all tool calls from one CLI workflow together.

## Test plan

- [x] `pnpm --filter @composio/cli typecheck` clean
- [ ] Run `composio tools execute <slug>` against a build with the
hermes companion deployed, confirm ClickHouse tool log has
`session_info.cli_session_id`
- [ ] Confirm header is absent (and log field absent) when no cwd
session is cached

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@composio/cli@0.2.31-beta.253
2026-05-17 00:47:21 +04:00
Alberto Schiabel 1ba66ca045 fix(core): normalize empty output_parameters so MCP tools can execute [PLEN-2450] (#3397)
Closes
[PLEN-2450](https://linear.app/composio/issue/PLEN-2450/toolsexecute-fails-for-all-mcp-toolkits-strict-zod-validation-rejects)
· refs https://github.com/ComposioHQ/composio/issues/3354

## Summary

`composio.tools.execute('<MCP_TOOL>', ...)` currently throws a
`ZodError` for **every** tool from an MCP-backed toolkit (`granola_mcp`,
`apify_mcp`, `tavily_mcp`, …) on `@composio/core` 0.6.x–0.9.x. The
reporter on #3354 confirmed all three versions hit the identical
failure; users are working around it by dropping to `@composio/client`
and losing modifiers, custom-tool routing, version checks, and provider
wrapping.

**Root cause** (`ts/packages/core/src/models/Tools.ts` +
`src/types/tool.types.ts`):
- `tools.execute` and `tools.get` both run the API response through
`transformToolCases → ToolSchema.parse`.
- `ParametersSchema` requires `{ type: 'object', properties: {...} }`.
- The API returns `output_parameters: {}` for MCP tools that have no
declared output schema, so the validator throws.

**Fix:** a tiny module-private `normalizeRawToolParameters` helper
applied to both `input_parameters` and `output_parameters` inside
`transformToolCases`. `null` / `undefined` / `{}` all map to
`undefined`; everything else passes through to strict Zod validation.
This:

- Preserves the existing `outputParameters: undefined` ⇒ "no declared
schema" contract — `outputParameters` was already optional in the public
`Tool` type, so no public API change.
- Fixes both `tools.execute` and `tools.list` (single funnel covers both
paths).
- Doesn't relax `ParametersSchema` — tools that actually declare a
schema remain strictly validated.
- Forward-compatible for every present / future `*_mcp` toolkit with no
toolkit allow-list.

## Testing

Red → green confirmed locally. New `describe('MCP-shaped tool metadata
(PLEN-2450)')` block in `tools.test.ts` covers:

1. `getRawComposioToolBySlug` does not throw `ZodError` for
`output_parameters: {}`.
2. Empty `output_parameters` is normalized to `undefined` on the
transformed `Tool`.
3. Both-empty edge case (`input_parameters: {}` + `output_parameters:
{}`).
4. `tools.list` path also tolerates empty `output_parameters`.
5. End-to-end `tools.execute` succeeds against an MCP-shaped fixture.

All five tests **fail** on `next` without the helper (reproducing the
exact `ZodError` from the report) and **pass** with it. Full
`@composio/core` suite: **904 / 904 green**.

```bash
cd ts/packages/core
pnpm vitest run tools.test -t "MCP-shaped tool metadata"   # → PASS (5) FAIL (0)
pnpm vitest run                                            # → PASS (904) FAIL (0)
```

## Test plan

- [x] Red phase confirmed: 5 new tests fail with the exact `ZodError`
from the report.
- [x] Green phase confirmed: 5 new tests pass after the helper lands.
- [x] Full `@composio/core` test suite stays green (904 tests).
- [x] `pnpm typecheck` clean.
- [ ] Optional live sanity: build a tarball and run the reporter's
`repro.mjs` against a sandbox user (`pg-test-9f4d0df7-…`) — not
blocking; the mocked end-to-end test pins the same path.

## Follow-ups (out of scope)

- **Python SDK** — verify whether `composio` Python has the same
over-strict Pydantic check and apply the equivalent normalization if so.

> Note: not proposing an API-side change. `output_parameters: {}` is the
correct JSON Schema for "no declared schema" (the empty schema validates
anything); the bug was the SDK's Zod validator being over-strict, not
the API. The fix belongs at the SDK layer, where it now lives.

Co-authored-by: jkomyno <12381818+jkomyno@users.noreply.github.com>
2026-05-17 00:44:51 +04:00
Rahul Tarak 5555dee25c feat(cli): refresh approval fallback page (#3431)
## Summary
- Refresh the browser fallback tool-approval page with the Composio CLI
landing page visual language: light dithered background, mono terminal
card, and brand-blue actions.
- Serve the approval HTML directly from the temporary `127.0.0.1`
callback server instead of writing/opening a `file://` page, so approval
buttons call back to the active CLI process with relative local routes.
- Keep the native macOS sidecar as the preferred prompt when available;
the browser prompt remains the fallback when the sidecar is missing or
fails before returning a decision.
- Add a CLI patch changeset.

## Tests
- `pnpm exec eslint ts/packages/cli/src/services/tool-permissions.ts`
- `pnpm --filter @composio/cli typecheck:src`
- `git diff --check`

## Notes
- Initially `typecheck:src` failed before workspace package build
artifacts existed in the fresh worktree; after building required
workspace dependencies it passed.

---------

Co-authored-by: Malay Vasa <malayvasa@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@composio/cli@0.2.31-beta.252
2026-05-15 17:41:04 -07:00
palash-c dc052f5c0e docs: add Shared Connections page under Authentication (#3406)
## Summary

New documentation page at `/docs/auth-configuration/shared-connections`
covering the `accountType` and per-user ACL surface added to
`@composio/core@0.9.1` and `composio==0.14.0`.

## What's covered

- **SHARED vs PRIVATE** — comparison table; what each means for who can
use the connection and how it's resolved
- **Creating a SHARED connection** — `link()` with `accountType:
'SHARED'` and an initial ACL
- **ACL resolution rule** — 4-step deny-wins ordering + a *"common
patterns"* table (only-creator, allow-all, targeted-allow,
everyone-except-N, combined)
- **Updating the ACL** — `updateAcl()` with PATCH semantics, plus an
explicit footgun warning about `notAllowedUserIds: []` clearing the deny
list
- **Using a shared connection** — pinning into a tool-router session via
`connectedAccounts`, or direct execute via `connectedAccountId`
- **Inspecting the ACL** — `get()` returns `accountType` +
`aclConfigForShared`; the latter is `undefined` when the caller isn't
authorised to see it
- **Error handling** — table mapping `ComposioAclOnlyForSharedError`,
`ComposioSharedAccessDeniedError`, and
`ComposioSharedConnectionNotAccessibleError` to their trigger
conditions, with try/except examples

## Other changes

- **`docs/package.json`**: bump `@composio/core` from `^0.9.0` to
`^0.9.1`. The published `0.9.1` is what carries the new typed surface;
without this bump, twoslash type-checks against `0.9.0` and the new
fields show as unknown properties.
- **`docs/content/docs/auth-configuration/meta.json`**: insert
`shared-connections` into the Authentication sidebar between
`connected-accounts` and `migrating-initiate-to-link`.

## Sanitization

Followed the same scrub conventions the SDK PRs landed on:

- No Hermes / Apollo PR references
- No internal backend error code names
- No JSONB / storage-layer details
- No *"project member"* wording (users don't belong to a project
entity); used `userId` and the pinning mechanism instead
- *"API key caller"* instead of *"project/org API key"*

## Test plan

- [x] `bun run build` — 1411 pages generated, no twoslash errors against
the published `@composio/core@0.9.1`
- [x] Manual link audit — `/docs/configuring-sessions`,
`/docs/managing-multiple-connected-accounts`,
`/docs/auth-configuration/connected-accounts`, and the internal
`#using-a-shared-connection` anchor all resolve
- [ ] Preview deploy spot-check — confirm the Cards icons (`Database`,
`Plug`, `Wrench`) render and the sidebar shows the new entry under
Authentication

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-14 16:42:37 +05:30
Shrey Singla 93b67e8b2f fix(ts-sdk): handle file upload list unions (#3374)
## Summary

This updates the TypeScript SDK's automatic file upload/download
modifier to handle tool schemas that accept either a single file or a
list of files.

Tools can expose file inputs as a composed schema such as:

```json
{
  "anyOf": [
    { "type": "object", "file_uploadable": true },
    { "type": "array", "items": { "type": "object", "file_uploadable": true } }
  ]
}
```

When auto-upload is enabled, the SDK presents those file-uploadable
objects to models as file path strings. If the model supplies a list of
local paths, the old upload resolver selected the first file-bearing
branch, usually the single-file branch, and left the list unchanged.
That means the backend could receive local paths instead of staged `{
name, mimetype, s3key }` descriptors.

## Changes

- Adds runtime-shape-aware composed-schema selection for file
upload/download modifiers.
- Chooses the array branch for list values while preserving single-file
behavior for string/File values.
- Preserves the existing fallback behavior: if no runtime shape matches,
use the first file-bearing variant.
- Keeps `anyOf`, `oneOf`, and `allOf` on the same composed-schema path
used by the SDK today.
- Adds regression coverage for single-file vs multi-file unions, array
item unions, and download parity.
- Adds a patch changeset for `@composio/core`.

## Why

Some file-capable tool schemas are backward compatible at the API level
by accepting both a single file and multiple files. The TypeScript SDK
should transform a list of local paths into a list of staged file
descriptors, just as it already does for direct array schemas.

## Verification

- `pnpm --filter @composio/core exec prettier --check
src/utils/modifiers/FileToolModifier.node.ts
test/tools/fileModifiers.test.ts`

Blocked locally:

- `pnpm --filter @composio/core test -- fileModifiers.test.ts` fails
before collecting tests because this workspace cannot resolve the
unbuilt `@composio/json-schema-to-zod` package entry.
- `pnpm --filter @composio/core typecheck:tsc` is also blocked by
existing local generated-client/workspace dependency errors unrelated to
this patch.

---------

Co-authored-by: Zen <zen@composio.dev>
2026-05-14 13:38:27 +05:30
Alberto Schiabel 5dcb363446 docs(py): add 0.13.1 entry to CHANGELOG (#3427)
Adds a `0.13.1` entry to `python/CHANGELOG.md` covering the changes
accumulated on `next` since the last Python release (`py@0.13.0`, May
7).

The CHANGELOG had been quietly abandoned since `0.8.11` (Sept 2025);
rather than try to backfill the 4-minor gap, this PR draws a line and
adds a banner pointing readers at the git log for that window. Future
releases start fresh from here.

## What's in 0.13.1

- **SHARED connected accounts (experimental)** —
`composio.experimental.update_acl`, `experimental={...}` on `link()` /
`session.authorize()`, `account_type` filter on `list()`. Mirrors
`@composio/core@0.10.0` shipping in #3425.
- **`initiate()` deprecation warning** — gated on response `Deprecation`
header (RFC 9745) instead of `auth_scheme`, eliminating false positives
for custom auth configs and non-OAuth schemes.
- **Schema converter** — preserves nullability on `null`-only `anyOf`
blocks.
- **Dep bump** — `composio-client` 1.36.0 → 1.39.0.

## Release plan

Documentation only — does NOT trigger a release on its own. The Python
release flow is tag-triggered:

```bash
# After this PR merges and after #3425 ships:
git tag py@0.13.1 <next HEAD sha>
git push origin py@0.13.1
```

That fires `.github/workflows/py.release.yml` which builds and publishes
to PyPI.

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

Co-authored-by: jkomyno <12381818+jkomyno@users.noreply.github.com>
py@0.13.1
2026-05-14 09:32:03 +02:00
Shrey Singla fccec8b143 fix(python-sdk): handle file upload list unions (#3373)
## Summary

This updates the Python SDK's automatic file upload/download
substitution so it can handle tool schemas that accept either a single
file or a list of files.

Tools can expose file inputs as a union such as:

```json
{
  "anyOf": [
    { "type": "object", "file_uploadable": true },
    { "type": "array", "items": { "type": "object", "file_uploadable": true } }
  ]
}
```

When auto-upload is enabled, the SDK presents those file-uploadable
objects to models as file path strings. If the model supplies a list of
local paths, the old resolver selected the first file-bearing union
branch, usually the single-file branch, and attempted to upload the
entire Python list as one path. That fails before the backend ever
receives the intended list of staged file descriptors.

## Changes

- Refactors upload substitution into a value/schema recursive walker via
`_substitute_file_upload_value`.
- Adds the same value/schema traversal shape for downloads via
`_substitute_file_download_value`.
- Selects composed-schema variants by runtime shape when possible, so
list values choose array branches and string/dict values keep the
single-value behavior.
- Preserves the existing fallback behavior: if no runtime shape matches,
use the first file-bearing variant.
- Treats `anyOf`, `oneOf`, and `allOf` consistently with the SDK's
existing composed-schema convention.
- Preserves root request/response dict mutation behavior for existing
call sites.
- Adds regression coverage for single-file vs multi-file unions, nested
array-item unions, download parity, and first-match fallback.

## Why

This is needed for file-capable tool schemas that are backward
compatible at the API level by accepting both a single file and multiple
files. The Python SDK should transform a list of local paths into a list
of staged `{name, mimetype, s3key}` descriptors, just as it already does
for direct array schemas.

## Verification

- `python -m ruff check python/tests/test_files.py
python/composio/core/models/_files.py`
- `python -m pytest python/tests/test_files.py -q` -> 119 passed
- `python -m pytest python/tests/test_files.py
python/tests/test_auto_upload_download_files.py
python/tests/test_upload_dir_allowlist.py
python/tests/test_tool_router_session_files.py -q` -> 166 passed
- Manual playground verification with a Gmail send using two local
attachments: both files were staged and sent successfully as an
attachment array.

Note: a full local `python/tests` run still has three unrelated failures
because `composio_langchain` is not installed in this environment; the
affected file-upload suites pass.

---------

Co-authored-by: Zen <zen@composio.dev>
2026-05-14 12:57:26 +05:30
Rahul Tarak 2d52e7f7c0 feat(cli): support composio upgrade <version> for specific releases (#3428)
## Summary

- `composio upgrade` now accepts an optional `<version>` argument so
users can install any published CLI release — stable or beta — without
having to wait for the channel pointer to move.
- Accepts `0.13.1`, `v0.13.1`, `0.13.1-beta.42`, or the full
`@composio/cli@0.13.1` tag (normalized internally).
- When a version is provided, the "already on latest" guard is skipped
so the command also supports downgrades and reinstalls. `--beta`
continues to control the no-arg case.

## Examples

```bash
composio upgrade                       # latest stable (unchanged)
composio upgrade --beta                # latest beta (unchanged)
composio upgrade 0.13.1                # pin to a specific stable
composio upgrade 0.13.1-beta.42        # install a specific beta
composio upgrade @composio/cli@0.13.1  # full release tag also accepted
```

## Implementation

- `upgrade.cmd.ts`: added optional `version` Args, normalizes input to a
`@composio/cli@<semver>` release tag, passes it through to the service.
- `upgrade-binary.ts`: `upgrade`/`fetchLatestRelease` now accept a `tag`
option that fetches the GitHub release directly via
`/releases/tags/<tag>`, bypassing the channel resolver. When a tag is
explicit, the update-availability check is skipped.
- Falls back to the explicit tag for `installSkillSafe` when the upgrade
completes without returning one.

## Test plan

- [x] `pnpm typecheck` (CLI package) — clean
- [x] `pnpm test` in `ts/packages/cli` — 703 passed, 1 skipped, no
regressions in `upgrade-binary.test.ts`
- [ ] Manual: `composio upgrade 0.13.0` from a newer beta to confirm
downgrade path works against real GitHub releases
- [ ] Manual: `composio upgrade --beta` still resolves the latest beta
when no version is given

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

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@composio/cli@0.2.31-beta.251
2026-05-13 17:11:27 -07:00
Abir Taheer 878ac4d34b Release: update version (#3425)
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.10.0

### Minor Changes

- 42ebff3: feat(connected-accounts): namespace SHARED-connection surface
under `experimental`

Aligns the TypeScript SDK with the experimental wire shape used by
Shared Connections. The flat `accountType` / `aclConfigForShared`
options on `connectedAccounts.link()` and `session.authorize()` have
moved under a single `experimental` block, and
`connectedAccounts.updateAcl()` has moved off the class onto a top-level
`experimental_updateAcl(composio, id, opts)` export — same precedent as
`experimental_createTool` / `experimental_createToolkit`.

The `experimental` namespace is the signal that the shape may change in
future releases. Pinning a SHARED connection in a session config
(`connectedAccounts: { gmail: [...] }`) and direct execute by
`connectedAccountId` are unchanged — only the connection-create / patch
/ authorize surfaces are namespaced.

Also surfaces the `accountType` filter on `connectedAccounts.list()` so
SHARED connections can be listed without dropping to the raw client. The
wire keeps this as a flat query param, so the SDK keeps it flat too.

`@composio/client` bumped from `0.1.0-alpha.71` → `0.1.0-alpha.72` so
the generated typed client carries the `Experimental` namespaces for
`link.create`, `toolRouter.session.link`, and `connectedAccounts.patch`.

    Caller migration:

    ```typescript
    // before
    await composio.connectedAccounts.link('user_id', 'auth_config_id', {
      accountType: 'SHARED',
      aclConfigForShared: { allowAllUsers: true },
    });
await composio.connectedAccounts.updateAcl('ca_abc', { allowAllUsers:
true });
    await session.authorize('github', {
      accountType: 'SHARED',
      aclConfigForShared: { allowAllUsers: true },
    });

    // after
    await composio.connectedAccounts.link('user_id', 'auth_config_id', {
      experimental: {
        accountType: 'SHARED',
        aclConfigForShared: { allowAllUsers: true },
      },
    });
await experimental_updateAcl(composio, 'ca_abc', { allowAllUsers: true
});
    await session.authorize('github', {
      experimental: {
        accountType: 'SHARED',
        aclConfigForShared: { allowAllUsers: true },
      },
    });

    // new — list SHARED connections
    const shared = await composio.connectedAccounts.list({
      accountType: 'SHARED',
      userIds: ['user_creator'],
    });
    ```

## @composio/cli-local-tools@0.0.4

### Patch Changes

-   Updated dependencies [42ebff3]
    -   @composio/core@0.10.0

## @composio/anthropic@1.0.0

### Patch Changes

-   Updated dependencies [42ebff3]
    -   @composio/core@0.10.0

## @composio/claude-agent-sdk@1.0.0

### Patch Changes

-   Updated dependencies [42ebff3]
    -   @composio/core@0.10.0

## @composio/cloudflare@1.0.0

### Patch Changes

-   Updated dependencies [42ebff3]
    -   @composio/core@0.10.0

## @composio/google@1.0.0

### Patch Changes

-   Updated dependencies [42ebff3]
    -   @composio/core@0.10.0

## @composio/langchain@1.0.0

### Patch Changes

-   Updated dependencies [42ebff3]
    -   @composio/core@0.10.0

## @composio/llamaindex@1.0.0

### Patch Changes

-   Updated dependencies [42ebff3]
    -   @composio/core@0.10.0

## @composio/mastra@1.0.0

### Patch Changes

-   Updated dependencies [42ebff3]
    -   @composio/core@0.10.0

## @composio/openai@1.0.0

### Patch Changes

-   Updated dependencies [42ebff3]
    -   @composio/core@0.10.0

## @composio/openai-agents@1.0.0

### Patch Changes

-   Updated dependencies [42ebff3]
    -   @composio/core@0.10.0

## @composio/vercel@1.0.0

### Patch Changes

-   Updated dependencies [42ebff3]
    -   @composio/core@0.10.0

## @composio/cli@0.2.30

### Patch Changes

-   Updated dependencies [42ebff3]
    -   @composio/core@0.10.0
    -   @composio/cli-local-tools@0.0.4

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: jkomyno <12381818+jkomyno@users.noreply.github.com>
@composio/openai@0.9.2 @composio/google@0.9.2 @composio/cli-local-tools@0.0.4 @composio/cli@0.2.30 @composio/cloudflare@0.9.2 @composio/langchain@0.9.2 @composio/vercel@0.9.2 @composio/claude-agent-sdk@0.9.2 @composio/anthropic@0.9.2 @composio/llamaindex@0.9.2 @composio/openai-agents@0.9.2 @composio/mastra@0.9.2 @composio/core@0.10.0 @composio/cli@0.2.31-beta.250
2026-05-13 19:23:33 +02:00
venkat82 2a904db6c9 docs(shared-connections): move under Getting Started → Authenticating users
The page was sitting under Direct Tool Execution Guides → Authentication.
Shared Connections is a connection-creation feature, not a direct-tool
workflow, so it slots better under Getting Started → Authenticating
users alongside `in-chat-authentication` and `manually-authenticating`.

Changes:
- `git mv docs/content/docs/auth-configuration/shared-connections.mdx
  docs/content/docs/authenticating-users/shared-connections.mdx`
- Removed `shared-connections` entry from
  `auth-configuration/meta.json`.
- Appended `shared-connections` to `authenticating-users/meta.json`.
- Doc body unchanged. The internal link to
  `/docs/auth-configuration/connected-accounts` in "What to read next"
  still resolves (the connected-accounts page stays under
  auth-configuration).

New URL: `/docs/authenticating-users/shared-connections`.

Verified: `bun run build` clean, `bun run scripts/validate-links.ts`
clean (0 errors).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 21:17:14 +05:30
venkat82 3e581d5959 docs(shared-connections): clarify camelCase/snake_case in prose
Two prose tweaks so TypeScript readers don't have to mentally translate
from Python-style field names:

- "Creating a SHARED connection" intro now mentions both
  (`accountType` in TypeScript, `account_type` in Python).
- "Common ACL patterns" caption notes the table uses camelCase and tells
  Python callers what to translate to.

Pure prose change — no code samples touched. Build clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 20:52:07 +05:30
venkat82 1292bc2149 docs(shared-connections): align with final SDK surface + add list filter section
Three updates after the post-review changes on the SDK PRs:

1. **TS `updateAcl` shape** — the review feedback on PR #3424 moved the
   call from a top-level `experimental_updateAcl(composio, id, opts)`
   export to a method on the `composio.experimental` namespace, mirroring
   Python (`composio.experimental.update_acl(id, ...)`). All TS code
   samples now call `composio.experimental.updateAcl(id, opts)`. The
   stale `experimental_updateAcl` import is dropped from the
   error-handling sample too.

2. **Top callout** — no longer mentions the discarded top-level export;
   reads as "the SDK methods live under the `composio.experimental`
   namespace" with both language names.

3. **Listing SHARED connections** — new section before "Inspecting the
   ACL". Shows the `account_type` (Py) / `accountType` (TS) filter that
   was missing from the doc. The wire keeps this flat as a query param
   (unlike the nested experimental block on create/update), so the SDK
   surface stays flat too — table of `PRIVATE` / `SHARED` / `ALL` and
   tabbed Python + TS examples scoping by user.

Build: `bun run build` clean.

TS blocks still carry `// @noErrors` because `@composio/core` on npm
doesn't yet expose `composio.experimental.updateAcl` or the typed
`accountType` filter — both ship in PR #3424. Those directives come
out in a follow-up doc commit once the SDK publishes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 20:42:58 +05:30
venkat82 ff4085a78d feat(connected-accounts-py): namespace SHARED-connection surface under experimental (#3412)
## Summary

Moves the SHARED connected-accounts surface in the Python SDK under the
`composio.experimental` namespace, mirroring the wire-level restructure
of the same fields. Same precedent as `composio.experimental.tool` /
`composio.experimental.Toolkit` — the namespace tells callers the shape
may still change.

- `link()` and `session.authorize()`: flat `account_type` /
`acl_config_for_shared` kwargs → single `experimental={}` dict
- `composio.connected_accounts.update_acl(...)` →
`composio.experimental.update_acl(...)`
- `composio.connected_accounts.list(...)` now exposes
`account_type='PRIVATE' | 'SHARED' | 'ALL'` (flat — the wire keeps this
as a query param)
- `composio-client` bumped `1.38.0` → `1.39.0` so the generated typed
client carries the `Experimental` TypedDicts

Pinning a SHARED connection in a session (`connected_accounts={...}`)
and direct execute by `connected_account_id` are unchanged — only the
connection-create / patch / authorize surfaces moved.

## Caller migration

```python
# before
composio.connected_accounts.link(
    user_id, auth_config_id,
    account_type="SHARED",
    acl_config_for_shared={"allow_all_users": True},
)
composio.connected_accounts.update_acl("ca_abc", allow_all_users=True)
session.authorize(
    "github",
    account_type="SHARED",
    acl_config_for_shared={"allow_all_users": True},
)

# after
composio.connected_accounts.link(
    user_id, auth_config_id,
    experimental={
        "account_type": "SHARED",
        "acl_config_for_shared": {"allow_all_users": True},
    },
)
composio.experimental.update_acl("ca_abc", allow_all_users=True)
session.authorize(
    "github",
    experimental={
        "account_type": "SHARED",
        "acl_config_for_shared": {"allow_all_users": True},
    },
)

# new — list SHARED connections
shared = composio.connected_accounts.list(
    account_type="SHARED",
    user_ids=["user_creator"],
)
```

## Tests

- `link()` forwards the experimental block / omits it when not provided
/ preserves explicit empty lists
- `link()` maps the `acl_config_for_shared is only valid on SHARED` 400
to `ComposioAclOnlyForSharedError`; non-ACL 400s re-raise
- `experimental.update_acl()` body construction, deny-list handling,
`ValidationError` when no fields provided, `ValidationError` when no
client is bound, same 400-mapper as `link()`
- `authorize()` forwards the experimental block
- `list(account_type="SHARED")` delegates the flat filter through to the
client

## Test plan

- [ ] `nox -s fmt` and `nox -s chk` clean for `composio/` (pre-existing
4 mypy errors in `providers/langgraph` and `providers/langchain` are
unrelated — same on `origin/next`)
- [ ] `pytest tests/test_connected_accounts.py
tests/test_tool_router.py` → 136 passed
- [ ] Docs page update (separate PR — code samples already on the
experimental shape there; `account_type=` list filter example to be
added once this lands)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@composio/cli@0.2.30-beta.249
2026-05-13 19:22:07 +05:30
venkat82 22bc3f9eb0 feat(connected-accounts): namespace SHARED-connection surface under experimental (#3424)
## Summary

Moves the SHARED connected-accounts surface in the TypeScript SDK under
the `experimental` namespace, mirroring the wire-level restructure of
the same fields. Same precedent as `experimental_createTool` /
`experimental_createToolkit` — the namespace tells callers the shape may
still change. Python equivalent: #3412.

- `connectedAccounts.link()` and `session.authorize()`: flat
`accountType` / `aclConfigForShared` options → single `experimental:
{...}` block
- `composio.connectedAccounts.updateAcl(...)` → top-level
`experimental_updateAcl(composio, id, opts)` export
- `composio.connectedAccounts.list(...)` now exposes `accountType:
'PRIVATE' | 'SHARED' | 'ALL'` (flat — the wire keeps this as a query
param)
- `@composio/client` bumped `0.1.0-alpha.71` → `0.1.0-alpha.72` so the
generated typed client carries the `Experimental` namespaces

Pinning a SHARED connection in a session (`connectedAccounts: { gmail:
[...] }`) and direct execute by `connectedAccountId` are unchanged —
only the connection-create / patch / authorize surfaces moved.

## Caller migration

```typescript
// before
await composio.connectedAccounts.link('user_id', 'auth_config_id', {
  accountType: 'SHARED',
  aclConfigForShared: { allowAllUsers: true },
});
await composio.connectedAccounts.updateAcl('ca_abc', { allowAllUsers: true });
await session.authorize('github', {
  accountType: 'SHARED',
  aclConfigForShared: { allowAllUsers: true },
});

// after
import { experimental_updateAcl } from '@composio/core';

await composio.connectedAccounts.link('user_id', 'auth_config_id', {
  experimental: {
    accountType: 'SHARED',
    aclConfigForShared: { allowAllUsers: true },
  },
});
await experimental_updateAcl(composio, 'ca_abc', { allowAllUsers: true });
await session.authorize('github', {
  experimental: {
    accountType: 'SHARED',
    aclConfigForShared: { allowAllUsers: true },
  },
});

// new — list SHARED connections
const shared = await composio.connectedAccounts.list({
  accountType: 'SHARED',
  userIds: ['user_creator'],
});
```

## Tests

- `link()` forwards the experimental block / omits it when not provided
/ preserves explicit empty arrays
- `link()` maps the `acl_config_for_shared is only valid on SHARED` 400
to `ComposioAclOnlyForSharedError`; unrelated errors fall back to
`ComposioFailedToCreateConnectedAccountLink`
- `experimental_updateAcl()` PATCH body construction, deny-list
handling, `ValidationError` when no fields provided, same 400-mapper as
`link()`
- `authorize()` forwards the experimental block; ACL caps (1000-entry
list, 256-char userId, non-empty) still enforced
- `list({ accountType: 'SHARED' })` delegates the flat filter through to
the client

## Test plan

- [ ] `pnpm typecheck` clean (core)
- [ ] `pnpm test` → 919 passed
- [ ] Once published, follow-up docs PR (#3406) removes `// @noErrors`
directives from TypeScript code samples

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-13 19:18:20 +05:30
jkomyno cfa30ceef3 chore(connected-accounts): drop dead re-exports from Experimental.ts
Three types (LinkCreateParams, SessionLinkParams, ConnectedAccountListParamsRaw)
were imported and re-exported but had zero external consumers. The named-type
imports of LinkCreateParams / SessionLinkParams were only referenced in a
descriptive comment; ConnectedAccountListParamsRaw wasn't used at all.

Rewrote the comment so it documents the structural-typing rationale without
referencing the now-unimported namespace names.

Typecheck clean, 919/919 tests pass.
2026-05-13 15:47:58 +02:00
venkat82 123b8d6f34 fix(connected-accounts): address review feedback on #3424
Six code-review nits from the multi-agent review on PR #3424:

P1.1 — `experimental_updateAcl(composio, id, opts)` doesn't match the
`experimental_createTool` precedent it cited. That export is a *pure
factory* (returns a value object, no client, no I/O), whereas
`updateAcl` takes a client and performs a network call. Costs the
current shape was paying:
- Awkward call site (composio passed as first arg every time)
- Bypassed `telemetry.instrument(this, 'ConnectedAccounts')` — the
  proxy only wraps class methods
- Diverged from the Python sibling (#3412) which mounts at
  `composio.experimental.update_acl(id, opts)`

Moved to `composio.experimental.updateAcl(id, opts)` as a method on a
new `Experimental` class. Top-level `experimental_*` prefix is now
reserved for stateless factories, matching the Python parity.

P2.2 — `ToolRouterSession.authorize` was re-inlining the same
camelCase→snake_case wire mapping that `ConnectedAccounts.link` already
encoded. Extracted `serializeExperimentalForWire` /
`serializeAclConfigForWire` into `models/Experimental.ts` and imported
both call sites from there. Next field added to the experimental block
now lands in one place.

P2.3 — `AuthorizeOptionsSchema` was a structural duplicate of
`ConnectedAccountExperimentalSchema`. Composed from the canonical
schema instead.

P2.4 — Substring match `acl_config_for_shared is only valid on SHARED`
extracted to `ACL_ONLY_FOR_SHARED_ERROR_FRAGMENT` in
`models/Experimental.ts` and reused from `ConnectedAccounts.link`,
`ToolRouterSession.authorize`, and `Experimental.updateAcl`. Single
source of truth so a server-side message tweak doesn't silently
downgrade three call sites to generic BadRequestError.

P2.5 — `ConnectedAccountsErrors.ts` `possibleFixes` strings on
`ComposioSharedAccessDeniedError` and
`ComposioSharedConnectionNotAccessibleError` were pointing at
`composio.connectedAccounts.updateAcl()` (method now removed). Rewrote
to `composio.experimental.updateAcl()` so the typed-error hint
compiles.

P2.6 — Telemetry bypass auto-fixed by P1.1. `Experimental` is now an
instrumented class; methods on it get the same telemetry proxy as
`ConnectedAccounts`.

P2.7 — Inline `import('../types/connectedAccounts.types')` type at the
old `serializeExperimentalForWire` declaration is gone with the
function move. Sibling models use plain top-level imports.

Tests: 919/919 pass, typecheck clean.

**Push-back on remaining findings:**
- P2.8 (`ComposioFailedToCreateConnectedAccountLink` missing `Error`
  suffix) — pre-existing naming, not introduced by this PR. Rename with
  back-compat alias is bigger scope; deferred.
- P2.9 (TS Zod caps vs Python no caps) — the TS caps are a UX win
  (clear ValidationError vs server 400). Better direction is adding the
  caps to Python in a follow-up, not dropping them from TS.
- All P3 nice-to-haves deferred.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 18:39:18 +05:30
venkat82 44972d90ad Merge remote-tracking branch 'origin/next' into feat/connected-accounts-experimental-py
# Conflicts:
#	python/composio/utils/schema_converter.py
2026-05-13 18:30:01 +05:30
venkat82 1645634866 fix(schema-converter): silence mypy on null-only-anyOf fallback return
The `return t.Optional[t.Any] if has_null else str` line introduced in
630038ab8 returns a union of `<typing special form>` and `type[str]`,
which mypy can't reconcile with the function's declared `t.Type` return.

Same `# type: ignore` pattern already used three other times in this
function (lines 280, 285, 287) for the identical reason — `t.Optional`
isn't a `type[T]`, it's a typing special form.

Unblocks Checks/common-checks on this PR and any other PR cut after
630038ab8 landed on next.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 18:26:47 +05:30
venkat82 ed3bb936d2 fix(connected-accounts-py): address review feedback on #3412
Six code-review nits from the multi-agent review on PR #3412:

P1.1 — python/setup.py was still pinning composio-client==1.36.0 while
pyproject.toml is on 1.39.0. The Experimental TypedDict that the new
link() docstring imports only exists in 1.39+, so anyone installing
via the legacy setup.py path would crash at import. Bumped to 1.39.0.

P1.2 — exceptions.py ComposioSharedAccessDeniedError and
ComposioSharedConnectionNotAccessibleError docstrings told users to
call composio.connected_accounts.update_acl(), which no longer exists.
Rewrote both to composio.experimental.update_acl().

P2.5 — ExperimentalAPI.update_acl returned t.Any; restored the typed
ConnectedAccountPatchResponse return so callers reading .id / .status /
.success keep type-safety at the API boundary.

P2.6 — ExperimentalAPI.__init__(client: Optional[Any]) tightened to
Optional[HttpClient]. The None branch stays for the one test that
exercises it; production code in sdk.py always passes a real client.

P2.7 — Dropped redundant alias=omit / connection=omit on the patch()
call. Verified against the composio-client==1.39.0 wheel: both default
to omit. Sibling ConnectedAccounts.update() already follows the cleaner
pattern. Test assertions updated to match.

P2.10 — Extracted the substring "acl_config_for_shared is only valid on
SHARED" into ACL_ONLY_FOR_SHARED_ERROR_FRAGMENT in experimental.py, and
reused it from connected_accounts.py + tool_router_session.py. Single
source of truth so a server-side message tweak doesn't silently
downgrade three call sites to generic BadRequestError.

Tests: 201/201 pass. mypy on composio/ clean.

Pushed back on the remaining P2 (TS divergence) in the review — the
companion TS PR #3424 ships the exact same restructure, so parity is
preserved once both land together.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 18:22:07 +05:30
venkat82 42ebff3f6b feat(connected-accounts): namespace SHARED-connection surface under experimental
Aligns the TypeScript SDK with the experimental wire shape used by
Shared Connections. The flat accountType / aclConfigForShared options
on connectedAccounts.link() and session.authorize() have moved under a
single experimental block, and connectedAccounts.updateAcl() has moved
off the class onto a top-level experimental_updateAcl(composio, id, opts)
export — same precedent as experimental_createTool /
experimental_createToolkit.

The experimental namespace is the signal that the shape may change in
future releases. Pinning a SHARED connection in a session config and
direct execute by connectedAccountId are unchanged — only the
connection-create / patch / authorize surfaces are namespaced.

Also surfaces the accountType filter on connectedAccounts.list() so
SHARED connections can be listed without dropping to the raw client.
The wire keeps this as a flat query param, so the SDK keeps it flat too.

@composio/client bumped from 0.1.0-alpha.71 -> 0.1.0-alpha.72 so the
generated typed client carries the Experimental namespaces for
link.create, toolRouter.session.link, and connectedAccounts.patch.

Caller migration:

  // before
  await composio.connectedAccounts.link('user_id', 'auth_config_id', {
    accountType: 'SHARED',
    aclConfigForShared: { allowAllUsers: true },
  });
  await composio.connectedAccounts.updateAcl('ca_abc', { allowAllUsers: true });
  await session.authorize('github', {
    accountType: 'SHARED',
    aclConfigForShared: { allowAllUsers: true },
  });

  // after
  await composio.connectedAccounts.link('user_id', 'auth_config_id', {
    experimental: {
      accountType: 'SHARED',
      aclConfigForShared: { allowAllUsers: true },
    },
  });
  await experimental_updateAcl(composio, 'ca_abc', { allowAllUsers: true });
  await session.authorize('github', {
    experimental: {
      accountType: 'SHARED',
      aclConfigForShared: { allowAllUsers: true },
    },
  });

  // new — list SHARED connections
  const shared = await composio.connectedAccounts.list({
    accountType: 'SHARED',
    userIds: ['user_creator'],
  });

Tests cover: experimental block forwarding (link + authorize), no-op
when omitted, empty-array preservation, typed error mapping for the
PRIVATE-with-ACL case, experimental_updateAcl body construction +
deny-list handling + ValidationError when no fields are provided, and
list(accountType: 'SHARED') flat-filter delegation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 16:16:56 +05:30
Rahul Tarak 69e6ef6495 chore(cli): drop darwin-x64 local tools, bundles, and enhanced controls (#3421)
## Summary
- Remove darwin-x64 from local toolkit platform lists (beeper-imessage,
peekaboo, chrome-devtools) and drop the corresponding bundled binary
path entries.
- Skip building native Swift sidecar binaries (peekaboo, imessage-cli,
composio-native-ui) for darwin-x64; remove the bun-darwin-x64 matrix
entry from `build-cli-binaries.yml` so we no longer produce a darwin-x64
CLI bundle.
- Locally force-disable enhanced controls / elicitation on darwin-x64 in
`tool-permissions.ts` even when the backend opts the org in (logs a
debug message).

## Test plan
- [x] `pnpm --filter @composio/cli typecheck`
- [x] `pnpm --filter @composio/cli-local-tools typecheck`
- [ ] CI green on the build workflow (no darwin-x64 job runs)

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

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@composio/cli@0.2.30-beta.248
2026-05-13 02:34:36 -07:00
Rahul Tarak d6bf4370d7 feat(cli): add enhanced permission cache gating (#3419)
## Summary
- Add a CLI consumer permission cache backed by
`~/.composio/tool-permissions-cache.json` with a 5 minute TTL.
- Read enhanced-controls state from `/api/v3.1/org/consumer/config` and
resolve stored connected-account permissions from
`/api/v3.1/consumer/permissions/resolve`.
- Thread consumer cache scope through Tool Router session creation so
CLI link sessions use the enhanced public link URL when enhanced
controls are enabled.
- Add execute/run-compatible gating: CLI execute checks cached
permission config before the Tool Router execute call and opens the
bundled macOS native UI sidecar for ask modes.
- Use the sidecar `--callback-file` JSON decision channel, pass the
selected connection `word_id` to the UI account line, and treat no
response within 30 seconds as denial.
- Fall back to browser approval when the native sidecar is
unavailable/non-macOS.

## Stack
- Base PR: #3418 (`pi/swift-sidecar-ui-dfceb48e`) — native UI sidecar.
- This PR: CLI permissions cache and native sidecar gating integration.

## Tests
- `pnpm --filter @composio/cli typecheck`
- `pnpm exec eslint
ts/packages/cli/src/effects/create-tool-router-session.ts
ts/packages/cli/src/services/tools-executor.ts
ts/packages/cli/src/services/native-ui-sidecar.ts
ts/packages/cli/src/services/tool-permissions.ts`
- `pnpm --filter @composio/cli build`
- `pnpm --filter @composio/cli-local-tools build:composio-native-ui --
--target darwin-arm64`
- Earlier on this branch: `pnpm install --frozen-lockfile`, `pnpm
build:packages`

## Notes / Risks
- Native approval UI is macOS-only. Non-macOS or missing sidecar
binaries fall back to the temporary browser approval page.
- The CLI gates locally and does not pass `experimental.permissions`
into Tool Router sessions yet, because direct CLI execute does not
provide MCP elicitation transport. It does pass
`experimental.link_url_overwrite` for enhanced link flows.
- On a cold cache, the first consumer Tool Router session creation
refreshes permission state synchronously; fresh cache entries are
returned immediately while a background refresh updates disk for future
calls.
@composio/cli@0.2.30-beta.247
2026-05-13 01:37:20 -07:00
Rahul Tarak 7477aa9566 feat(cli): scaffold native UI sidecar (#3418)
## Summary
- Scaffold a macOS Swift `composio-native-ui` sidecar with a borderless
floating native overlay and Metal-driven pulsing/liquid-glass visual
treatment.
- Add a hidden/dev `composio dev native-ui` command that spawns the
bundled sidecar from CLI local-tool assets.
- Wire the sidecar into local-tool binary build scripts and CLI binary
release packaging checks for Darwin artifacts.

## Tests
- `pnpm install --frozen-lockfile`
- `pnpm typecheck`
- `pnpm --filter @composio/cli build`
- `pnpm --filter @composio/cli-local-tools build:composio-native-ui --
--target darwin-arm64`
- Manual launch via
`COMPOSIO_LOCAL_TOOLS_BIN_DIR=../cli-local-tools/local-tools-binaries
bun dist/bin.mjs dev native-ui --timeout 35`

## Notes / Risks
- This is a scaffold/prototype and is intentionally opened as a draft
PR.
- The visual effect uses a transparent AppKit panel,
`NSVisualEffectView`, and a Metal overlay. True optical distortion of
arbitrary content behind the window would require a different approach
such as ScreenCaptureKit/backdrop sampling and associated permissions.
- Generated sidecar executables remain ignored; release jobs rebuild
them before packaging artifacts.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@composio/cli@0.2.30-beta.246
2026-05-13 01:30:14 -07:00
Sarthak Agrawal d21df6b7f9 docs(changelog): introduce connected_accounts revoke endpoint (#3407)
# Description

Adds a customer-facing changelog entry announcing the new `POST
/api/v3.1/connected_accounts/{nanoid}/revoke` endpoint.

The entry covers:

- The endpoint shape, an example request, and an example `200 OK`
response (with the `revoked_tokens` array reflecting which token
subjects were killed at the provider on this call)
- Full status code table (`200` / `400` / `404` / `409` / `500`)
- **Revoke-then-delete semantics**: deleting a connected account does
NOT currently cascade to upstream revoke — customers should call
`/revoke` first if they need credentials killed at the provider. A
future release may cascade automatically; we'll announce separately
- **Best-effort behavior**: some providers don't expose revoke for one
or both token subjects; customers should always read `revoked_tokens`
rather than assume both were revoked
- **Externally revoked tokens**: if a user revokes via the provider's
UI, the revoke call may fail — such connections are eventually marked
`EXPIRED` by the platform

Endpoint path and response shape verified against
`apps/apollo/src/pages/api/v3.1/connected_accounts/[nanoId]/revoke.ts`
in hermes.

Follows `docs/.claude/guides/changelog.md` conventions (filename
`MM-DD-YY-suffix.mdx`, frontmatter with `title` + `date` +
`description`, sections start at `###`, no top-level `#`, no emojis).

> Note: SDK / public OpenAPI visibility for this endpoint is being added
in parallel in hermes — by the time this entry publishes, the endpoint
will be reachable from `backend.composio.dev` for customer projects.

# How did I test this PR

- Verified file location, filename pattern, and frontmatter against
`docs/.claude/guides/changelog.md` and a recent peer entry
(`12-30-25-proxy-binary-data.mdx`)
- Cross-checked the documented request path, response schema, and status
codes against
`apps/apollo/src/pages/api/v3.1/connected_accounts/[nanoId]/revoke.ts`
(route definition, `RevokeConnectedAccountResponseSchema`, declared
response codes)
- The repo's Fumadocs build (`bun run build`) validates MDX and will
catch any syntax / link issues in CI
2026-05-13 12:28:13 +05:30
Sarthak Agrawal 804fc922ff docs: update toolkits, API spec, and meta tools data (#3399)
## 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`) — latest v3.1 and v3.0 API specifications
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/reference/meta-tools/*.mdx`) — updated meta tool schemas
and reference docs
2026-05-13 12:22:02 +05:30
Sushmithamallesh 466574be3a docs: update toolkits and API data 2026-05-13 06:06:06 +00:00
Abir Taheer a8475f3653 chore(py): bump all packages to 0.13.1 (#3417)
## Summary

- Patch release for Python SDK, matching the TS `@composio/*@0.9.1`
release
- Bumps core `composio` and all 12 provider packages to `0.13.1`
- Core was erroneously bumped to `0.14.0` in #3401 without a release tag
— since `0.14.0` was never published to PyPI, all packages align at
`0.13.1`

### Changes included in this release (since `py@0.13.0`)

- **feat**: `account_type` + per-user ACL on SHARED connected accounts
(#3401)
- **fix**: SEC-339 — gate `initiate()` deprecation warning on response
`Deprecation` header (#3380)
- **fix**: preserve nullability in null-only `anyOf` and fix `validate`
param alias (630038a)
- **docs**: sanitize public docstrings, drop residual internal
references

## Test plan

- [ ] CI passes (py.test.yml — unit tests on Python 3.10/3.11/3.12)
- [ ] CI passes (py.check.yaml — ruff lint + mypy + type inference)
- [ ] After merge: tag `py@0.13.1` on `next` to trigger `py.release.yml`
→ PyPI publish
- [ ] Verify on PyPI: `pip index versions composio` shows `0.13.1`

## Known pre-existing CI failure (NOT introduced by this PR)

`common-checks` fails on `python/composio/utils/schema_converter.py:275`
with:
> error: Incompatible return value type (got "<typing special form> |
type[str]", expected "type[Any]") [return-value]

- The offending line is **identical** between `origin/next` and this
branch (`diff` returns no output).
- Introduced in commit `630038a8` (PR #3173, merged to `next`
2026-05-12), not in this PR.
- Not previously caught because `.github/workflows/py.check.yaml`
triggers on `push: master` and `pull_request` only — the default branch
is `next`, so direct pushes / merge commits to `next` do not run this
workflow.
- All other 19 checks pass (Test Python SDK 3.10/3.11/3.12, Integration
Tests, CodeQL, Lint and Format Check, etc.).

This release PR contains only `pyproject.toml` / `setup.py` version
bumps. Fixing the unrelated mypy regression should be done in a separate
PR against `next`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-12 18:40:50 -07:00
Abir Taheer d676cd8b30 chore(py): bump all packages to 0.13.1
Patch release matching TS 0.9.1 — includes account_type + per-user ACL
on SHARED connections, SEC-339 deprecation header fix, nullability fix
in schema converter, and docstring cleanup.

Core was erroneously bumped to 0.14.0 in #3401 without a release; since
0.14.0 was never published to PyPI, all packages align at 0.13.1.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-12 16:47:39 -07:00
Rahul Tarak 99324d5a0d fix(install): resolve latest CLI release from assets (#3411)
## Summary
- Resolve the default CLI install version from GitHub Releases instead
of git tags.
- Require the selected CLI release to include the current platform
archive asset and fall back to older stable CLI releases when the newest
release is missing that asset.
- Add a mocked install.sh regression test covering missing release
assets, ignored beta/provider releases, and tag-only versions with no
release.

## Tests
- `bash -n install.sh test/install-sh-release-resolution.test.sh`
- `pnpm run test:install-sh`
- `git diff --check`
- Parsed `.github/workflows/cli.test-installation.yml` with Ruby YAML
- Parsed `package.json` with Node JSON.parse
- Manual real install smoke test with temporary
HOME/COMPOSIO_INSTALL_DIR selected `@composio/cli@0.2.28`

## Notes
- This prevents the install health check from selecting tag-only
versions like `@composio/cli@0.2.29` when no GitHub release/asset exists
yet.
@composio/cli@0.2.29
2026-05-12 13:36:41 -07:00
Yizuki_Ame 630038ab83 fix: preserve nullability in null-only anyOf and fix validate param alias
Merge PR #3173 as the preferred fix for the null-only anyOf schema behavior and validate alias handling.
2026-05-12 18:20:05 +02:00
Alberto Schiabel 126b79cdbf docs: update CLAUDE.md for composio SDK (#3396)
# Description
Weekly automated CLAUDE.md refresh. Updates stale CLAUDE.md files to
reflect recent codebase changes.

Files updated:
- `CLAUDE.md` — 403 -> 97 lines. Rewrote to current state: removed stale
`examples/` top-level entry, added `cli-keyring` and `cli-local-tools`
packages, noted default branch is `next`, kept the Bun version-mismatch
gotcha and the e2e Docker note, pointed agents at `AGENTS.md`,
`docs/CLAUDE.md`, and `ts/packages/cli/AGENTS.md`.
- `ts/packages/cli/AGENTS.md` (which `ts/packages/cli/CLAUDE.md`
symlinks to) — 379 -> 197 lines. Replaced the outdated command table
(the `manage` namespace was removed in #2937 and many new top-level
commands were added: `agent`, `auth-configs`, `connected-accounts`,
`orgs`, `projects`, `toolkits`, `tools`, `triggers`, `logs`, `init`,
`install`, `signup`, `proxy`, `listen`, `run`, `dev`, `artifacts`,
`config`, `local-tools`). Added a note that `@composio/cli-keyring`
powers OS credential storage. Dropped duplicate Effect / Clack
"Reference Source" sections (already consolidated). Kept the
load-bearing pieces: required typecheck, output-conventions (stdout vs
stderr), Effect patterns, release workflow.
- `docs/CLAUDE.md` — unchanged. Already current (last updated
2026-04-21) and within the 30-70 line target at 107 lines; the
`.claude/` subtree matches what it documents.

# How did I test this PR
- Verified line counts: root 97 (target 60-150), `docs/CLAUDE.md` 107
(unchanged), `ts/packages/cli/AGENTS.md` 197.
- Cross-checked the CLI command table against
`ts/packages/cli/src/commands/` (`ls ts/packages/cli/src/commands/`) and
against recent commits (`02e72116d`, `3415a4a15`, `d1ef6b25e`,
`67867aea1`).
- Cross-checked `ts/packages/` listing against the structure block in
the root `CLAUDE.md` (cli, cli-keyring, cli-local-tools, core,
json-schema-to-zod, providers, ts-builders).
- Confirmed `ts/packages/cli/CLAUDE.md` is still the symlink to
`AGENTS.md` after rewriting.

Origin: cron-update-claude-docs /
[zen-cron-248f7d9ad575](https://zen-api-production-4c98.up.railway.app/dashboard/#/chat/zen-cron-248f7d9ad575)
Triggered by: karan@composio.dev | Source: cron
Session:
https://zen-api-production-4c98.up.railway.app/dashboard/#/chat/zen-cron-248f7d9ad575
@composio/cli@0.2.30-beta.245
2026-05-12 18:05:54 +02:00
venkat82 38620df152 refactor(experimental-py): move ExperimentalAPI to its own module
ExperimentalAPI was sitting inside custom_tool.py because custom tools
were the first thing the SDK exposed on the composio.experimental
namespace. Now that update_acl has moved onto the same namespace,
keeping the class in custom_tool.py reads wrong — grepping for
update_acl lands in a file named after custom tools.

Splits the class out into core/models/experimental.py. custom_tool.py
keeps the custom-tool machinery (ExperimentalToolkit, decorator
helpers, serializers); experimental.py imports what it needs from
custom_tool.py and is now the home for anything on the
composio.experimental namespace.

Pure rearrangement — no behaviour change, no public-import-path change
(composio.core.models still re-exports ExperimentalAPI). Stack-frame
depth in _get_caller_locals(depth=2) stays correct: the
decorator → user-module hop is the same regardless of which file
ExperimentalAPI.tool lives in.

Tests still pass (201/201), mypy still clean on composio/.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 20:53:01 +05:30
venkat82 706b01ce75 feat(connected-accounts-py): namespace SHARED-connection surface under experimental
Aligns the Python SDK with the experimental wire shape used by Shared
Connections. The flat `account_type` / `acl_config_for_shared` kwargs on
`link()` and `authorize()` have moved under a single `experimental` dict,
and `update_acl` has moved off `composio.connected_accounts` onto the
`composio.experimental` namespace — same precedent as
`composio.experimental.tool` / `composio.experimental.Toolkit`.

The `experimental` namespace is the signal that the shape may change in
future releases. Pinning a SHARED connection in a session config and
direct execute by `connectedAccountId` are unchanged — only the
connection-create / patch / authorize surfaces are namespaced.

Also surfaces the `account_type=` filter on `composio.connected_accounts.list()`
so SHARED connections can be listed without dropping to the raw client.
The wire keeps this as a flat query param (`?account_type=`), so the
SDK keeps it flat too with the experimental signal carried in the value
enum description.

Caller migration:

  # before
  composio.connected_accounts.link(
      user_id, auth_config_id,
      account_type="SHARED",
      acl_config_for_shared={"allow_all_users": True},
  )
  composio.connected_accounts.update_acl(
      "ca_abc", allow_all_users=True,
  )
  session.authorize(
      "github",
      account_type="SHARED",
      acl_config_for_shared={"allow_all_users": True},
  )

  # after
  composio.connected_accounts.link(
      user_id, auth_config_id,
      experimental={
          "account_type": "SHARED",
          "acl_config_for_shared": {"allow_all_users": True},
      },
  )
  composio.experimental.update_acl(
      "ca_abc", allow_all_users=True,
  )
  session.authorize(
      "github",
      experimental={
          "account_type": "SHARED",
          "acl_config_for_shared": {"allow_all_users": True},
      },
  )

  # new — list SHARED connections
  shared = composio.connected_accounts.list(
      account_type="SHARED",
      user_ids=["user_creator"],
  )

composio-client bumped from 1.38.0 -> 1.39.0 so the generated typed
client carries the Experimental TypedDicts for link.create,
tool_router.session.link, and connected_accounts.patch.

Tests cover: experimental block forwarding (link + authorize),
no-op when omitted, empty-list preservation, typed error mapping for
the PRIVATE-with-ACL case, experimental.update_acl body construction +
deny-list handling + ValidationError when no fields are provided +
ValidationError when called without a bound client, and
list(account_type="SHARED") flat-filter delegation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 20:43:25 +05:30
venkat82 22557104f9 docs(shared-connections): align code samples with experimental wire shape (hermes#9960)
The previous samples called the flat-field surface that `@composio/core@0.9.1`
and `composio==0.14.0` shipped. The wire is being restructured by
hermes#9960 to nest those fields under an `experimental` block, and the
follow-up SDK PRs will move the call sites to a matching `experimental`
namespace (mirroring the custom-tools precedent of `experimental_createTool`
/ `composio.experimental.tool`). This commit updates every code sample to
the post-restructure shape so the doc is internally consistent with the
experimental rollout it advertises in the top callout.

Specific changes:

- `link()`: `experimental: { accountType, aclConfigForShared }` (TS) /
  `experimental={"account_type": ..., "acl_config_for_shared": ...}` (Py).
- `updateAcl()` → `experimental_updateAcl(client, id, opts)` (TS top-level
  export, mirrors `experimental_createTool`) / `composio.experimental.update_acl(id, ...)`
  (Py, mirrors `composio.experimental.tool`).
- Retrieve response inspection now reads from `account.experimental?.accountType`
  / `account.experimental?.aclConfigForShared` to match the response shape.
- Error-handling examples use the experimental method names too.
- Common ACL patterns table clarifies the inner shape is wrapped inside the
  `experimental` block at the call site.
- Top callout updated to call out the namespace move so readers know what
  they're looking at.

TypeScript blocks that target the post-restructure surface carry
`// @noErrors` because the published `@composio/core@0.9.1` doesn't yet
expose `experimental_updateAcl` or the nested `experimental` options on
`link()`. The directives will come out in a follow-up docs PR once the
SDK PRs publish.

Pinning a SHARED connection in a session (`connectedAccounts: { gmail: [...] }`)
and direct execute (`composio.tools.execute(slug, { connectedAccountId })`)
stay unchanged — session config and execute aren't part of the experimental
wire restructure.

Verified: bun run build clean (1411 pages, no twoslash errors with @noErrors).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 18:44:47 +05:30
venkat82 b1f2a7976b docs(shared-connections): mark page as Experimental
Mirrors the convention used by `Custom Tools and Toolkits (Experimental)`:

- Title becomes `Shared Connections (Experimental)` so the experimental
  status is visible in the sidebar entry and at the top of the page.
- Adds a `<Callout type="warn">` immediately under the frontmatter with
  the same wording style custom-tools uses, plus a forward-looking note
  that the SDK surface is being restructured under a
  `composio.experimental.*` namespace so callers know to expect future
  migration.

Code samples stay on the currently-published SDK shape (flat
`accountType` / `aclConfigForShared` args on `link()`, `updateAcl()`,
`authorize()` — what `@composio/core@0.9.1` and `composio==0.14.0` ship
today) so twoslash continues to typecheck. A follow-up docs PR will
update them to the experimental-namespace shape once those SDK PRs
publish.

Verified: bun run build clean (1411 pages, no twoslash errors).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 18:36:10 +05:30
Zen Agent 357fa4a9d9 docs(changelog): address review feedback on revoke entry
- Reword 400 row: "Revoke is not supported for this toolkit"
- Simplify 404 row to "Connected account does not exist"
- Drop "Database failure" wording from 500 row
- Drop "(Today)" qualifier and the future-cascade speculation paragraph
- Drop the auto-EXPIRED platform-detection claim (not true for non-OAuth2
  or OAuth2 without refresh tokens)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Co-authored-by: sarthak <sarthak@composio.dev>
2026-05-12 11:47:16 +00:00
Abir Taheer a8256242dc docs(changelog): fix May 8 minimum @composio/core version (0.10.0 → 0.9.1) (#3409)
# Description

The May 8 changelog
(\`05-08-26-session-use-update-connected-accounts.mdx\`) lists the
minimum TypeScript SDK version as \`@composio/core@0.10.0\` for the
\`composio.use()\` / \`session.update()\` / \`connectedAccounts\` array
changes. That version doesn't exist on npm — the current \`latest\` tag
is \`0.9.1\` — and the public surface of \`0.9.1\` already exposes
\`Composio.use(id)\`, \`Session.update()\`, and the
\`connectedAccounts\` array form.

Verification:

\`\`\`bash
$ npm view @composio/core dist-tags
{ latest: '0.9.1', next: '0.1.36-next.13', ... }

$ npm pack @composio/core@0.9.1
$ tar -xzf composio-core-0.9.1.tgz -C /tmp/c91
$ grep -nE 'use\(id: string|session\.update|connectedAccounts.*ZodUnion'
\\
    /tmp/c91/package/dist/*.d.cts | head
dist/composio-BnLWW0B6.d.cts:5125: use(id: string, options?: { ... }):
Promise<Session<...>>;
dist/composio-BnLWW0B6.d.cts:5328: use: (id: string, options?: { ... })
=> Promise<Session<...>>;
dist/customTool.types-BVgnEbR2.d.cts:1057: connectedAccounts:
z\$1.ZodOptional<z\$1.ZodDefault<z\$1.ZodRecord<z\$1.ZodString,
z\$1.ZodUnion<[z\$1.ZodString, z\$1.ZodArray<z\$1.ZodString,
"many">]>>>>;
\`\`\`

The adjacent May 7 changelog
(\`05-07-26-toolrouter-preload-direct-tools.mdx\`) already pins the
minimum to \`0.9.0\`, which is consistent with \`0.9.1\` being the
shipped release.

# How did I test this PR

- \`grep\` over the unpacked \`@composio/core@0.9.1\` type definitions
to confirm the API surface listed in the changelog (\`composio.use()\`,
\`session.update()\`, \`connectedAccounts\` as \`string | string[]\`) is
present.
- \`npm view\` confirms \`0.9.1\` is \`dist-tags.latest\` and \`0.10.0\`
is not yet published.
- Visual diff: only the table cell value changes (`0.10.0` → `0.9.1`);
no surrounding prose or code blocks are touched.

If \`0.10.0\` was intentional (e.g. an upcoming release that wasn't cut
yet), feel free to close this and we'll re-pin once the package is
published.
2026-05-12 01:02:36 -07:00
Zen Agent b78c8ba22a docs(changelog): fix May 8 minimum @composio/core version (0.10.0 → 0.9.1)
The May 8 changelog ("Session reuse, update, and connected accounts as
arrays") lists @composio/core ≥ 0.10.0 as the minimum version for the
composio.use() / session.update() / connectedAccounts-array changes, but
the latest published version on npm is 0.9.1 and the .create()/.use()
methods plus the array-shape connectedAccounts field are both present in
its public type surface (verified by extracting the published 0.9.1
tarball and grepping dist/*.d.cts). 0.10.0 does not exist on npm.

The adjacent May 7 changelog ("preload + direct tools preset") already
lists @composio/core ≥ 0.9.0, which is consistent with 0.9.1 being the
shipped version.

Co-authored-by: dhawal <dhawal@composio.dev>
2026-05-12 07:54:07 +00:00
Zen Agent df9298aeeb docs(changelog): introduce connected_accounts revoke endpoint
Add a customer-facing changelog entry for the new
POST /api/v3.1/connected_accounts/{nanoid}/revoke endpoint, documenting
revoke-then-delete semantics, best-effort behavior, and how externally
revoked connections are handled.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Co-authored-by: sarthak <sarthak@composio.dev>
2026-05-12 07:11:33 +00:00