Commit Graph

4150 Commits

Author SHA1 Message Date
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 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
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
Abir Taheer 02723698b0 Release: update version (#3402)
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/cli-local-tools@0.0.3

### Patch Changes

-   Updated dependencies [84a3a07]
-   Updated dependencies [c358ffa]
    -   @composio/core@0.9.1

## @composio/core@0.9.1

### Patch Changes

- 84a3a07: Add `accountType` and per-user ACL support for SHARED
connected accounts.

- **`accountType` on create**: `composio.connectedAccounts.link(userId,
authConfigId, { accountType: 'SHARED' })` creates a SHARED connection.
Default remains `PRIVATE`. A SHARED connection can be used by other
`userId`s, but only when the connection is explicitly pinned in a
tool-router session's config and only when the requesting `userId`
passes the connection's ACL.
- **`accountType` on retrieve**: `get()` and `list()` responses now
include `accountType` (`'PRIVATE' | 'SHARED'`).
- **`aclConfigForShared` on create + retrieve**: per-user ACL block — `{
allowAllUsers, allowedUserIds, notAllowedUserIds }`. On responses the
field is `undefined` when the caller isn't authorised to see the ACL, so
callers can distinguish _"I can't see the ACL"_ from _"ACL is the
default deny-by-default state"_.
- **`updateAcl()` method** (new):
`composio.connectedAccounts.updateAcl(nanoid, { allowAllUsers,
allowedUserIds, notAllowedUserIds })` writes the ACL via `PATCH`. PATCH
semantics — omit a field to leave it unchanged; pass an empty array to
clear an allow/deny list. At least one field required. Calling on a
PRIVATE connection raises `ComposioAclOnlyForSharedError` (400).
- **`ToolRouterSession.authorize()` options gain `accountType` +
`aclConfigForShared`**, so a SHARED connection with an ACL can be
created in one call from inside a tool-router session.

    ACL resolution rule (deny wins):

    1.  requesting `userId` ∈ `notAllowedUserIds` → DENY
    2.  `allowAllUsers === true` → ALLOW
    3.  requesting `userId` ∈ `allowedUserIds` → ALLOW
    4.  otherwise → DENY (deny-by-default)

Limits: each ACL list accepts up to 1000 entries; each `userId` is
1..256 characters. The SDK enforces these caps at the input boundary.

    New error classes:

- `ComposioSharedAccessDeniedError` (403) — surfaces from direct
`connectedAccountId` execution paths when the requesting user fails the
ACL.
- `ComposioAclOnlyForSharedError` (400) — ACL fields sent on a PRIVATE
connection.
- `ComposioSharedConnectionNotAccessibleError` (400) — tool-router
session create / PATCH with a pinned SHARED connection the session user
cannot use.

No breaking changes. Existing `link()` callers without the new options
get a `PRIVATE` connection exactly as today; existing `get()` / `list()`
callers see new optional fields.

    The Python SDK mirror ships in a separate PR.

- c358ffa: Fix false-positive `initiate()` deprecation warning for
custom auth configs (SEC-339 follow-up).

`composio.connectedAccounts.initiate()` previously emitted a one-time
`console.warn` on every redirectable-OAuth response, regardless of
whether the auth config was Composio-managed (subject to the 2026-07-03
cutover) or custom (unaffected). The wording was conditional ("If this
auth config is Composio-managed…") so callers using their own OAuth apps
could ignore it, but the warning still printed and caused noise in logs.

Apollo already emits the SEC-339 `Deprecation` / `Sunset` / `Link
rel="deprecation"` headers (RFC 9745 / RFC 8594) **only** on the
retiring branch — managed + redirectable OAuth. The SDK now reads the
`Deprecation` header from the response (via `APIPromise.withResponse()`)
and gates the warning on its presence. Custom auth configs and non-OAuth
schemes get a clean response from the server and now stay silent in the
SDK as well.

- **Behavior change:** No warning is emitted for `initiate()` calls
against custom OAuth auth configs or non-OAuth schemes (API key, bearer,
basic). Managed-OAuth callers continue to get exactly one warning per
process, now with revised wording that points at the response's `Sunset`
header for the precise cutover date.
- **No public API change:** `initiate()` returns the same
`ConnectionRequest` shape and respects the same `allowMultiple` guard.
`ComposioLegacyConnectedAccountsEndpointRetiredError` continues to
surface from the 400 retired-path response.
- **Test scaffolding:** new mock helper `mockApiPromiseWithHeaders()` in
`connectedAccounts.test.ts` wraps a value as an `APIPromise`-shaped
thenable so the new tests can simulate apollo's header behavior.
Pre-existing initiate tests using `mockResolvedValueOnce` continue to
pass via the SDK's defensive fallback when `withResponse` is absent on
the mock.

    Python SDK gets the matching change in the same release train.

## @composio/anthropic@0.9.1

### Patch Changes

-   Updated dependencies [84a3a07]
-   Updated dependencies [c358ffa]
    -   @composio/core@0.9.1

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

### Patch Changes

-   Updated dependencies [84a3a07]
-   Updated dependencies [c358ffa]
    -   @composio/core@0.9.1

## @composio/cloudflare@0.9.1

### Patch Changes

-   Updated dependencies [84a3a07]
-   Updated dependencies [c358ffa]
    -   @composio/core@0.9.1

## @composio/google@0.9.1

### Patch Changes

-   Updated dependencies [84a3a07]
-   Updated dependencies [c358ffa]
    -   @composio/core@0.9.1

## @composio/langchain@0.9.1

### Patch Changes

-   Updated dependencies [84a3a07]
-   Updated dependencies [c358ffa]
    -   @composio/core@0.9.1

## @composio/llamaindex@0.9.1

### Patch Changes

-   Updated dependencies [84a3a07]
-   Updated dependencies [c358ffa]
    -   @composio/core@0.9.1

## @composio/mastra@0.9.1

### Patch Changes

-   Updated dependencies [84a3a07]
-   Updated dependencies [c358ffa]
    -   @composio/core@0.9.1

## @composio/openai@0.9.1

### Patch Changes

-   Updated dependencies [84a3a07]
-   Updated dependencies [c358ffa]
    -   @composio/core@0.9.1

## @composio/openai-agents@0.9.1

### Patch Changes

-   Updated dependencies [84a3a07]
-   Updated dependencies [c358ffa]
    -   @composio/core@0.9.1

## @composio/vercel@0.9.1

### Patch Changes

-   Updated dependencies [84a3a07]
-   Updated dependencies [c358ffa]
    -   @composio/core@0.9.1

## @composio/cli@0.2.29

### Patch Changes

-   Updated dependencies [84a3a07]
-   Updated dependencies [c358ffa]
    -   @composio/core@0.9.1
    -   @composio/cli-local-tools@0.0.3

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@composio/google@0.9.1 @composio/openai-agents@0.9.1 @composio/cloudflare@0.9.1 @composio/core@0.9.1 @composio/langchain@0.9.1 @composio/llamaindex@0.9.1 @composio/mastra@0.9.1 @composio/anthropic@0.9.1 @composio/openai@0.9.1 @composio/vercel@0.9.1 @composio/cli-local-tools@0.0.3 @composio/claude-agent-sdk@0.9.1 @composio/cli@0.2.29-beta.244
2026-05-11 16:11:04 -07:00
Abir Taheer 0e993fcb2b chore: change @composio/core version bump from minor to patch (#3404)
# Description

Demote the `connected-accounts-acl` changeset from `minor` to `patch`
for `@composio/core`.

Duplicate of #3403 (by @abir-taheer) — opened so the change can be
merged without waiting for review on the original PR.

# How did I test this PR

- Diff is one line in `.changeset/connected-accounts-acl.md`
(`'@composio/core': minor` → `'@composio/core': patch`).
- No code, tests, or runtime behavior changed — only the version-bump
label that `changeset` reads at release time.
- Worth a human sanity check on the semver call: the underlying
changeset description adds a new feature (`accountType` + per-user ACL
for SHARED connected accounts), which is conventionally a minor bump.
The changeset body itself states "No breaking changes." If we
deliberately want to avoid cutting a minor here, patch is fine — just
confirming this is intentional.
2026-05-11 14:49:36 -07:00
Zen Agent 3b98ee0fc2 chore: change @composio/core version bump from minor to patch
Demote the connected-accounts-acl changeset from minor to patch, matching
PR #3403 by @abir-taheer.

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

Co-authored-by: abir <abir@composio.dev>
2026-05-11 21:48:25 +00:00
venkat82 9b31c66e3f feat(connected-accounts-py): surface account_type + per-user ACL on SHARED connections (#3401)
## Summary

**Python mirror of
[#3392](https://github.com/ComposioHQ/composio/pull/3392) (TypeScript
SDK).** Same Apollo-side Shared Accounts feature shipped across four
Hermes PRs ([#9860](https://github.com/ComposioHQ/hermes/pull/9860),
[#9882](https://github.com/ComposioHQ/hermes/pull/9882),
[#9887](https://github.com/ComposioHQ/hermes/pull/9887) internal-only,
[#9902](https://github.com/ComposioHQ/hermes/pull/9902)), now exposed
through `composio.*` Python SDK wrappers.

`composio-client` bumped from `1.37.0` → `1.38.0`
([composio-base-py#66](https://github.com/ComposioHQ/composio-base-py/pull/66),
merged 2026-05-11). The regenerated client already carries
`account_type` + `acl_config_for_shared` on `LinkCreateParams`,
`ConnectedAccountPatchParams`, `SessionLinkParams`, the retrieve
response, and the list response item — so the Python SDK consumes
generated types directly without local body-shape declarations (no
Python equivalent of the TS forward-compat casts needed).

## Implemented

### `composio/core/models/connected_accounts.py`

- **`link()`** — new optional kwargs `account_type:
Literal['PRIVATE','SHARED']` and `acl_config_for_shared:
link_create_params.ACLConfigForShared`. Default behaviour (both omitted)
creates a PRIVATE connection exactly as before.
- **New `update_acl(nanoid, *, allow_all_users, allowed_user_ids,
not_allowed_user_ids)`** — wraps `PATCH /connected_accounts/{id}` with
the same semantics as the TS sibling. PATCH semantics: omit a param to
leave unchanged; pass `[]` to clear an allow/deny list. Raises
`ValidationError` if all three are `None`. Returns the
`ConnectedAccountPatchResponse` (`{id, status, success}`) — to read the
updated ACL block, call `get(nanoid)` after.
- Both methods wrap `BadRequestError` whose message contains
`"acl_config_for_shared is only valid on SHARED"` and re-raise as
`ComposioAclOnlyForSharedError`. Verified against Apollo's
`apps/apollo/src/lib/connected_accounts/createConnectedAccount.ts` in
hermes#9902 — same substring match the TS SDK uses.

### `composio/core/models/tool_router_session.py`

- **`authorize()`** — new optional kwargs `account_type` and
`acl_config_for_shared`, plus the same `ComposioAclOnlyForSharedError`
mapping. So a SHARED connection with an ACL can be created in one call
from inside a tool-router session.

### `composio/exceptions.py`

Three new typed exception classes under `ConnectedAccountError`:

| Class | Status | Wired? |
|---|---|---|
| `ComposioAclOnlyForSharedError` | 400 | ✅ Wrapped at `link()`,
`update_acl()`, `authorize()` |
| `ComposioSharedAccessDeniedError` | 403 | ⚠️ Exported, not yet wrapped
— wraps when `Tools.execute()` error mapping lands (separate PR) |
| `ComposioSharedConnectionNotAccessibleError` | 400 | ⚠️ Exported, not
yet wrapped — wraps when `tool_router_session.create()/patch()`
session-validator error mapping lands (separate PR) |

The two non-wired classes are exported now so the public API surface is
stable; doctstrings explicitly disclose when they'll start being raised.

### `composio/client/types.py`

- Re-exports `link_create_params` (the generated client's TypedDicts for
link create payloads, including `ACLConfigForShared`).

### Tests (`tests/test_connected_accounts.py`)

New `TestConnectedAccountsAcl` class with 12 tests mirroring the TS PR's
coverage:

- **link() ACL forwarding (4)**: forwards `account_type` + nested
`acl_config_for_shared`; omits ACL when not provided; forwards only
fields the caller supplied; preserves explicit empty lists.
- **link() error mapping (2)**: maps `AclOnlyForShared` 400 to
`ComposioAclOnlyForSharedError`; rethrows unrelated `BadRequestError`
unchanged.
- **update_acl() body construction (3)**: serializes nested body; omits
absent fields (PATCH semantics); preserves empty array.
- **update_acl() validation + mapping (3)**: rejects all-`None` params;
maps `AclOnlyForShared` 400; rethrows unrelated errors.

### Version

Package version bumped `0.13.0` → `0.14.0` (minor — purely additive
surface, no breaking changes).

## Verified

- ✅ `uv run nox -s chk` — ruff + mypy clean across `composio/`,
`providers/`, `tests/`, `scripts/`
- ✅ `uv run pytest tests/test_connected_accounts.py` — 49/49 pass (37
pre-existing + 12 new)
- ✅ `uv run pytest tests/` — 635 pass / 31 skipped (1 pre-existing
failure in `test_provider.py` is `composio_langchain` not installed in
env — unrelated)

## Not implemented (deliberate scope cuts — match TS PR)

| Skipped | Why | Where it lands |
|---|---|---|
| **Wrapping `ComposioSharedAccessDeniedError`** | Throw site is in
`Tools.execute()` and direct-execute paths — outside this PR's surface.
| Follow-up PR scoped to execute error mapping. |
| **Wrapping `ComposioSharedConnectionNotAccessibleError`** | Throw site
is in `tool_router_session.create()`/`patch()` session-validator. |
Follow-up PR scoped to session error mapping. |
| **`account_type` / `acl_config_for_shared` on `initiate()` (legacy
create)** | `initiate()` is the retiring legacy path. Customers should
use `link()` for SHARED. | N/A — deprecated surface. |
| **Internal link-session GET (hermes#9887)** | Internal route, not in
public OpenAPI spec; consumed by dashboard UI, not the SDK. | N/A. |

## Test plan

- [x] `uv run nox -s chk` clean
- [x] `uv run pytest tests/test_connected_accounts.py` 49/49 pass
- [x] `uv run pytest tests/` 635 pass / 31 skipped (langchain-dep
failure is pre-existing env issue)
- [ ] Manual smoke after publish: `pip install composio==0.14.0` →
create SHARED → `update_acl(allow_all_users=True,
not_allowed_user_ids=['user_bob'])` → verify `get()` returns
`acl_config_for_shared` block for creator, omits it for non-creator.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-12 01:33:56 +05:30
venkat82 7ff870b138 feat(core): surface accountType + per-user ACL on SHARED connected accounts (#3392)
## Summary

SDK wrappers for the Apollo-side Shared Accounts feature shipped across
four Hermes PRs:

- [hermes#9860](https://github.com/ComposioHQ/hermes/pull/9860) —
`account_type` enum (PRIVATE / SHARED) + pin-only invariant
- [hermes#9882](https://github.com/ComposioHQ/hermes/pull/9882) — echo
`account_type` in create-flow responses
- [hermes#9887](https://github.com/ComposioHQ/hermes/pull/9887) — echo
`account_type` in internal link-session GET (no public docs surface)
- [hermes#9902](https://github.com/ComposioHQ/hermes/pull/9902) —
per-user ACL for SHARED connections, nested under
`acl_config_for_shared`

Ready for review — Apollo, the OpenAPI spec, and
`@composio/client@0.1.0-alpha.71` (published from
[composio-base-ts#77](https://github.com/ComposioHQ/composio-base-ts/pull/77))
all carry the merged contract.

## Implemented

### Types (`types/connectedAccounts.types.ts`)
- `ConnectedAccountTypes` constants + `ConnectedAccountTypeSchema` Zod
enum + `ConnectedAccountType` TS type.
- `ConnectedAccountAclConfigSchema` (input — all 3 fields optional) and
`ConnectedAccountAclConfigResponseSchema` (output — fields populated
when block visible). Per-list cap **1000 entries**, per-`userId` length
cap **1..256 chars** — matches Apollo's `aclConfig.ts`.
- Extended `CreateConnectedAccountLinkOptionsSchema` with `accountType`
+ `aclConfigForShared` (nested object).
- Extended `ConnectedAccountRetrieveResponseSchema` with `accountType` +
optional `aclConfigForShared` (`undefined` when caller can't see ACL —
distinguishes hidden-ACL from default-state).
- New `UpdateConnectedAccountAclParamsSchema`, refined to require ≥1
field (rejects no-op `{}`). Inline comment notes the ZodEffects `.shape`
quirk for future maintainers.

### Model (`models/ConnectedAccounts.ts`)
- `link(userId, authConfigId, options)` — forwards `accountType` and
serializes `aclConfigForShared` to the nested `acl_config_for_shared`
wire block via a new internal `serializeAclConfigForWire` helper.
Default behaviour (no options) creates a PRIVATE connection exactly as
today.
- **New** `updateAcl(nanoid, params)` — wraps
`client.connectedAccounts.patch` (PATCH `/connected_accounts/{id}`),
serialising flat camelCase params into the nested wire block. PATCH
semantics: omit a field to leave unchanged; pass `[]` to clear an
allow/deny list. JSDoc flags the empty-array footgun
(`notAllowedUserIds: []` silently re-grants previously-blocked users).
Returns `ConnectedAccountPatchResponse` to match sibling-method
ergonomics.
- Clarifying JSDoc on existing `update()` pointing readers at
`updateAcl()` for ACL and noting the historical "alias and/or
credentials" doc is inaccurate (separate cleanup PR).

### Model (`models/ToolRouterSession.ts`)
- `authorize(toolkit, options)` — options gain `accountType` +
`aclConfigForShared`. The `/tool_router/session/{session_id}/link`
endpoint accepts the same fields, so a SHARED connection with an ACL can
be created in one call from inside a tool-router session.

### Transformer (`utils/transformers/connectedAccounts.ts`)
- Maps `account_type` → `accountType`.
- Maps `acl_config_for_shared` (nested) → `aclConfigForShared` (nested
camelCase). Forwards `undefined` when the block is absent so callers can
distinguish *"I can't see the ACL"* (cookie caller, non-creator) from
*"ACL is the default deny-by-default state"*.

### Errors (`errors/ConnectedAccountsErrors.ts`)
- `ComposioAclOnlyForSharedError` (400) — **wired** at three call sites:
`link()`, `updateAcl()`, `ToolRouterSession.authorize()`. Substring
match on `'acl_config_for_shared is only valid on SHARED'` (verified
against Apollo's `createConnectedAccount.ts` in hermes#9902).
- `ComposioSharedAccessDeniedError` (403) — exported, **not yet wrapped
by SDK code**. Will be wrapped when `Tools.execute()`/direct-execute
error mapping lands in a follow-up. For now, callers seeing this from a
raw `BadRequestError`/`ForbiddenError` can match on message substring.
- `ComposioSharedConnectionNotAccessibleError` (400) — same status. Will
be wrapped when `ToolRouterSession.create()`/`update()`
session-validator error mapping lands.

### Tests (`test/connectedAccounts/connectedAccounts.test.ts`)
- 12 new behaviour tests covering `link()` ACL forwarding (5),
`updateAcl()` body construction + empty-object refine + AclOnlyForShared
mapping (6), and `link()` error-mapping fallback (1). 911 tests pass (up
from 899).

### Changeset
- `.changeset/connected-accounts-acl.md` — `@composio/core: minor`
(additive surface, no breaking changes), describes the nested shape and
resolution rule.

## Not implemented (deliberate scope cuts)

| Skipped | Why | Where it lands |
|---|---|---|
| **Python SDK mirror** | `composio-client@1.38.0` (from
[composio-base-py#66](https://github.com/ComposioHQ/composio-base-py/pull/66))
now exposes the same fields. Better as its own PR scoped to
`python/composio/` so Python's release cadence stays independent. |
Separate PR, same release train (called out in changeset). |
| **Docs cookbook entry** ("share a connection with specific users") |
Needs `@composio/core` to be published before the TS code samples can
`twoslash`-typecheck against the new methods. | Separate PR under
`docs/content/cookbooks/`. |
| **`docs/public/openapi*.json` spec refresh** | Auto-PR
[#3399](https://github.com/ComposioHQ/composio/pull/3399) already opened
against `next` with the post-9902 spec. | Mergeable independently from
this PR. |
| **`update()` → real PATCH endpoint** | Pre-existing — JSDoc says
"alias and/or credentials" but implementation calls `updateStatus`. The
new JSDoc explicitly disclaims it; the behaviour-change rewrite is
unrelated to ACL. | Separate cleanup PR. |
| **`ComposioSharedAccessDeniedError` +
`ComposioSharedConnectionNotAccessibleError` wiring** | Need to map at
`Tools.execute()` and `ToolRouterSession.create()`/`update()`/`patch()`.
Out of scope for a connected-accounts PR — the failure modes are in
different SDK touchpoints. Exported now so the public-API contract is
stable, JSDocs explicit about when they'll start being thrown. |
Follow-up PR scoped to execute/session error mapping. |
| **Internal link-session GET (hermes#9887)** | Endpoint is
`/api/v3/internal/...` and filtered out of the public spec by
`docs/scripts/fetch-openapi.mjs`. Dashboard UI consumes it, not the SDK.
| N/A — internal only. |
| **Cast tightening / shared wire-ACL fragment** (review P3-13, P3-14) |
Casts and local body types are gone (commit `483af3607`). Shared
fragment was already extracted as `AclConfigWireShape` in commit
`752efd886` — now removed since it lives in the generated types. | Done.
|
| **Duplicate-account guard extraction** (review P3-16) | Reviewer
explicitly says "parity-by-copy is fine for this PR" — `link()` and
`initiate()` share a 14-line guard. Extracting
`assertNoActiveConnections()` is mechanical and unrelated. | Follow-up.
|

## Commits

1.
[`84a3a074`](https://github.com/ComposioHQ/composio/pull/3392/commits/84a3a074b)
— initial draft against the flat-field shape described in 9902's PR
body.
2.
[`752efd88`](https://github.com/ComposioHQ/composio/pull/3392/commits/752efd886)
— reshape to the nested `aclConfigForShared` shape that actually merged
in 9902. Verified against `staging-backend.composio.dev`'s spec.
3.
[`483af3607`](https://github.com/ComposioHQ/composio/pull/3392/commits/483af3607)
— bump `@composio/client` to `0.1.0-alpha.71`, drop the three casts +
local body types, apply the 9 in-scope multi-agent review fixes, wire
`ComposioAclOnlyForSharedError` at three call sites, add 12 behaviour
tests.

## Test plan

- [x] `pnpm --filter @composio/core typecheck` — clean
- [x] `pnpm --filter @composio/core test` — 911/911 pass (12 new, 899
pre-existing)
- [x] `pnpm --filter @composio/core build` — `publint` + `attw` clean
- [x] Wire contract spot-checked against prod spec for all five
endpoints (POST link, POST connected_accounts, PATCH, GET single, GET
list, tool_router/session link)
- [x] All forward-compat casts removed; SDK now uses `LinkCreateParams`,
`ConnectedAccountPatchParams`, `SessionLinkParams` from the generated
client directly
- [ ] **Manual smoke (reviewer or merger):** create SHARED →
`updateAcl({ allowAllUsers: true, notAllowedUserIds: ['user_bob'] })` →
verify `get()` returns `aclConfigForShared` for creator, returns
`undefined` for non-creator.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@composio/cli@0.2.29-beta.243
2026-05-12 01:33:22 +05:30
venkat82 a202b9ea90 docs(connected-accounts): drop residual "at create time" wording in error class
Two more spots leaking the same immutability wording removed from the
upstream API description:

- ComposioAclOnlyForSharedError possibleFixes said "Set accountType:
  'SHARED' at create time". Reworded to "Use accountType: 'SHARED'".
- ComposioSharedConnectionNotAccessibleError JSDoc said "caught at
  session-create time". Replaced "caught" framing with "Raised at
  session-create time" — "session-create time" stays because it's
  user-facing (tells the SDK caller when the error is raised, i.e.
  during session.create() / session.patch()).

Also tightened the surrounding wording — class doc cross-references the
actual SDK method names (`toolRouter.session.create()` /
`session.patch()`) instead of abstract phrasing.

No behaviour changes — docstring cleanup only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 01:28:34 +05:30
venkat82 613d3804af docs(py): drop residual "at create time" wording in error class docstrings
Two more spots leaking the same immutability wording removed from the
upstream API description:

- ComposioAclOnlyForSharedError docstring said "sent on a PRIVATE
  connection — at create time or via PATCH" and the Fix suggested "set
  account_type='SHARED' at create time". Reworded to drop the
  "at create time" assertion.
- ComposioSharedConnectionNotAccessibleError docstring said "caught at
  session-create time". Replaced the "caught" framing with "Raised at
  session-create time" — "session-create time" stays because it's
  user-facing (tells the SDK caller when the error is raised, i.e.
  during session.create() / session.patch(), not later during
  execution).

Also tightened the surrounding wording — class doc cross-references the
actual SDK method names (``tool_router.session.create()`` /
``session.patch()``) instead of abstract phrasing.

No behaviour changes — docstring cleanup only.

Verified: ruff check + format clean, nox -s chk clean, 49 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 01:28:00 +05:30
venkat82 10b914fd43 docs(connected-accounts): drop residual internal references
Final sweep caught three more spots leaking internal detail:

- `CreateConnectedAccountLinkOptionsSchema.aclConfigForShared` JSDoc
  said "the backend rejects ACL on a PRIVATE connection". Replaced with
  "raises ComposioAclOnlyForSharedError on a PRIVATE connection" —
  describes the SDK contract from the caller's perspective.
- `UpdateConnectedAccountAclParamsSchema` JSDoc had a parallel
  "Backend rejects ACL writes on a PRIVATE connection" sentence.
  Reworded the same way.
- Test comment in toolRouter.test.ts had a "Bugbot-flagged gap"
  annotation referencing internal review tooling. Replaced with a
  neutral description of what the tests verify.

No behaviour changes — JSDoc / comment cleanup only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 01:26:09 +05:30
venkat82 d27eecce20 docs(py): sanitize public docstrings — remove internal references
Addresses 2 review comments from @abir-taheer on #3401:

  - tests/test_connected_accounts.py:546 — remove Hermes PR reference
  - models/connected_accounts.py:708 — update_acl docstring too long;
    match the style of other methods in the file (cf. update())

Swept the full PR diff for the same patterns rather than just the two
flagged lines:

- Removed Hermes PR numbers and TS-test cross-reference from
  TestConnectedAccountsAcl class docstring.
- Trimmed update_acl docstring — kept ~10 lines (one-line description,
  param list, one example) instead of the original ~40 lines with the
  resolution-rule table, multiple examples, and verbose footgun-warning
  block. Matches the style of update() / delete() / refresh() in the
  same file. Resolution rule + per-list caps stay documented on
  ConnectedAccountAclConfigSchema (where the contract belongs).
- Removed internal backend error codes from exception class docstrings
  (``ConnectedAccount_AclOnlyForShared``,
  ``ConnectedAccount_SharedAccessDenied``,
  ``ToolRouterV2_SharedConnectionNotAccessible``). Surfacing the
  internal code names leaks implementation details.
- Reworded "users in the project" / "project member" / "Open access to
  everyone in the project" — users don't belong to a project entity in
  Composio's data model. Replaced with phrasing focused on ``user_id``
  and the pinning mechanism.
- Removed "Set at create time only" wording from the link() param
  description on connected_accounts.py and tool_router_session.py (the
  corresponding upstream API description has the same wording removed).
- Cleaned inline catch comments referencing internal error code names.

No behaviour changes — docstring / comment cleanup only.

Verified: nox -s chk clean, ruff format --check clean, 49/49 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 01:21:10 +05:30
venkat82 382ffe5ee9 docs(connected-accounts): drop "set at creation time only" wording
Two more JSDoc spots — `ConnectedAccountTypes` and the `accountType` field
on `CreateConnectedAccountLinkOptionsSchema` — claimed `accountType` was
"set at creation time only — cannot be changed later". The wording has
been removed from the corresponding API parameter description upstream,
so the SDK shouldn't echo it independently.

No behaviour changes — JSDoc-only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 01:14:40 +05:30
venkat82 eba561f771 docs(connected-accounts): sanitize public docstrings — remove internal references
Addresses 4 review comments from @abir-taheer on #3392:

  - transformers/connectedAccounts.ts:21 — remove Hermes PR references
  - types/connectedAccounts.types.ts:79  — users don't belong to projects
  - types/connectedAccounts.types.ts:55  — drop backend storage detail
  - models/ToolRouterSession.ts:330      — remove internal information

Swept the full PR diff for similar leaks rather than just the four
flagged lines, since the same patterns repeat across the new files:

- Removed Hermes PR numbers (#9860 / #9882 / #9902) from inline
  comments and JSDoc in transformers, types, model, test describe block,
  and changeset.
- Removed "JSONB column on `connected_accounts`" storage detail.
- Reworded "any user_id in the project" / "users in the project" /
  "project member" / "project/org API key" — users don't belong to a
  project entity in Composio's data model, so the wording was
  misleading. Replaced with phrasing focused on the mechanism (pinning
  in a tool-router session, authorisation via creator or API key) and
  on the `userId` identifier.
- Removed "Backend response: 400 with code `ConnectedAccount_...`"
  blocks from error class JSDoc — surfacing the internal error code
  name leaked implementation details.
- Cleaned up the augmented `RawConnectedAccountResponseWithLabels`
  intersection — `account_type` and `acl_config_for_shared` are now on
  the regenerated `@composio/client@0.1.0-alpha.71` types, so the
  manual augmentation lines (which carried the Hermes refs) can be
  deleted entirely. Field access still works through the existing
  intersection used for `word_id` / `alias`.

Also tightened a pre-existing leak I introduced earlier in the PR's
own JSDoc on `update()` — dropped the "historical JSDoc mentioning
alias/credentials" callout since that's internal noise.

No behaviour changes — pure docstring / comment / changeset cleanup.

Verified: pnpm typecheck clean, 915 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 01:08:37 +05:30
venkat82 fafaa55f88 fix(py): ruff format the new files + regenerate uv.lock for 0.14.0
Two CI / review issues on #3401:

1. "Lint and Format Check" failed — `ruff format --check` flagged
   `composio/core/models/tool_router_session.py` and
   `tests/test_connected_accounts.py`. Local `nox -s chk` only runs
   `ruff check` (lint), not `ruff format --check`, so the gap slipped
   through. Ran `ruff format` on both.

2. Bugbot caught uv.lock drift — pyproject.toml bumped to 0.14.0 but
   uv.lock still recorded 0.13.0 from when the dep bump commit was
   created. Ran `uv lock` to regenerate; the lockfile now records 0.14.0.

No behaviour changes — formatting + lockfile sync only.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 00:30:52 +05:30
venkat82 14a5b52b60 fix(connected-accounts): validate ACL input in ToolRouterSession.authorize()
Bugbot caught a parity gap (cursor[bot] review on #3392): authorize()
accepted aclConfigForShared and passed it straight to the wire, while
ConnectedAccounts.link() validated through CreateConnectedAccountLinkOptionsSchema
(which enforces the 1000-entry list cap and 1..256 char user_id length from
ConnectedAccountAclConfigSchema). Callers using authorize() with oversized
lists or invalid user IDs got opaque backend 400s instead of clear SDK-level
ValidationError, breaking the changeset's claim that "The SDK enforces these
caps via Zod at the input boundary."

Added a local `AuthorizeOptionsSchema` (callbackUrl + alias + accountType +
aclConfigForShared) and a safeParse + ValidationError throw at the top of
authorize(), mirroring the pattern in link() / updateAcl(). The shape is
identical to link's options sub-shape so the same caps apply.

Tests (toolRouter.test.ts):
  - forwards accountType + nested acl_config_for_shared on the wire
  - throws ValidationError when allowedUserIds exceeds 1000 entries
  - throws ValidationError when a user_id exceeds 256 chars
  - throws ValidationError when a user_id is empty

915 tests pass (4 new + 911 prior). pnpm typecheck clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 00:26:17 +05:30
venkat82 b283fbbccc feat(connected-accounts-py): surface account_type + per-user ACL on SHARED connections
Python mirror of #3392 (TypeScript SDK). Same Apollo-side feature shipped
across four Hermes PRs (#9860, #9882, #9887 internal, #9902), now exposed
through @composio/* Python SDK wrappers.

Bumped composio-client 1.37.0 → 1.38.0 (the regenerated client published
by composio-base-py#66 — contains account_type + acl_config_for_shared on
LinkCreateParams, ConnectedAccountPatchParams, SessionLinkParams, the
retrieve response, and the list response item).

SDK changes:

- composio.connected_accounts.link() now accepts `account_type` and
  `acl_config_for_shared`. Default behaviour (omit both) creates a
  PRIVATE connection exactly as before.
- New composio.connected_accounts.update_acl(nanoid, *, allow_all_users,
  allowed_user_ids, not_allowed_user_ids) — wraps PATCH /connected_accounts/{id}
  with the same semantics as the TS sibling. PATCH semantics: omit a
  param to leave unchanged; pass [] to clear an allow/deny list. Raises
  ValidationError if all three are None.
- composio.tool_router_session.authorize() options gain `account_type`
  and `acl_config_for_shared` — the /tool_router/session/{id}/link
  endpoint accepts the same fields.
- New typed errors in composio.exceptions:
    * ComposioAclOnlyForSharedError (400) — wired at link() / update_acl()
      / authorize() catch sites via the same
      `acl_config_for_shared is only valid on SHARED` substring match used
      in the TS SDK. Verified against Apollo's createConnectedAccount.ts.
    * ComposioSharedAccessDeniedError (403) — exported, not yet wrapped.
      Wraps when Tools.execute() error mapping lands in a follow-up.
    * ComposioSharedConnectionNotAccessibleError (400) — exported, not
      yet wrapped. Wraps when ToolRouterSession.create()/patch() session-
      validator error mapping lands.

Plumbing:
- python/composio/client/types.py re-exports `link_create_params` (the
  generated client's TypedDicts for link create payloads, including
  `ACLConfigForShared`).

Tests: 12 new tests in TestConnectedAccountsAcl class covering link()
ACL forwarding (4), AclOnlyForShared mapping on link() (1), pass-through
of unrelated BadRequestError (1), update_acl() body construction (3),
empty-fields rejection (1), AclOnlyForShared mapping on update_acl() (1),
pass-through of unrelated BadRequestError on update_acl() (1). 49 tests
pass (37 pre-existing + 12 new); full suite 635 pass / 31 skipped.

Verified: nox -s chk clean (ruff + mypy on src + tests).

Version: 0.13.0 → 0.14.0 (minor — additive surface).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 00:20:01 +05:30
venkat82 49a23fed24 fix(cli): add account_type to SessionLinkResponse test mocks
@composio/client@0.1.0-alpha.71 (just bumped in 483af3607) tightened
SessionLinkResponse to require `account_type: 'PRIVATE' | 'SHARED'` —
the four test mocks of `client.toolRouter.session.link` no longer
satisfy the typed surface.

CI was failing Build + Typecheck + every E2E job with the same 3 errors
at connected-accounts.link.cmd.test.ts:287, 341, 373 (cascade — Typecheck
fails first, Build/E2E inherit). All fixed by adding `account_type: 'PRIVATE'
as const` at the four mock sites (3 in connected-accounts.link.cmd.test.ts,
1 in test-layer.ts default).

PRIVATE chosen as the default because that matches what the backend now
returns when account_type isn't supplied on input.

Lesson: when bumping @composio/client, run `pnpm -r typecheck` at the
workspace root, not just `pnpm --filter @composio/core typecheck`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 00:06:17 +05:30
venkat82 483af36070 feat(connected-accounts): bump @composio/client to alpha.71, drop casts, add tests + error mapping
Now that #77 in composio-base-ts merged and @composio/client@0.1.0-alpha.71 is
published with account_type + acl_config_for_shared in the typed surface,
all the forward-compat shims come out.

Removed:
- AclConfigWireShape, LinkCreateBodyWithAcl, ConnectedAccountPatchBodyWithAcl
  local types
- 3x `as unknown as Parameters<typeof X>[N]` casts in ConnectedAccounts.ts +
  ToolRouterSession.ts

Now uses the generated types directly:
- ConnectedAccountPatchParams, ConnectedAccountPatchResponse from
  @composio/client/resources/connected-accounts
- LinkCreateParams + LinkCreateParams.ACLConfigForShared from
  @composio/client/resources/link
- SessionLinkParams + SessionLinkParams.ACLConfigForShared from
  @composio/client/resources/tool-router/session/session

Review fixes from #3392 multi-agent review:

- P1-1: moved orphaned JSDoc back onto ComposioLegacyConnectedAccountsEndpoint-
  RetiredError (was stranded above ComposioSharedAccessDeniedError)
- P1-2: added empty-array footgun warning to updateAcl() JSDoc — passing
  `notAllowedUserIds: []` silently clears the deny list
- P1-3: changeset reconciled with PR body (Python ships as separate PR)
- P2-9: updateAcl() returns ConnectedAccountPatchResponse instead of void,
  matching sibling update()/refresh() ergonomics
- P2-11: clarifying JSDoc on update() pointing at updateAcl() and noting the
  pre-existing "alias/credentials" doc is inaccurate (this PR doesn't fix it)
- P3-12: callbackUrl/alias guards normalized to `!== undefined` (was a mix
  of `&&` and `!= null`) — empty strings now propagate correctly
- P3-17: refine-guard comment on UpdateConnectedAccountAclParamsSchema noting
  ZodEffects doesn't expose .shape

P2-6/P2-7: typed error mapping for ComposioAclOnlyForSharedError (400)
wired at three call sites:
- ConnectedAccounts.link()    — wraps existing
  ComposioFailedToCreateConnectedAccountLink catch
- ConnectedAccounts.updateAcl() — new catch with rethrow fallback
- ToolRouterSession.authorize() — new catch with rethrow fallback

Substring match on `'acl_config_for_shared is only valid on SHARED'` —
verified against apps/apollo/src/lib/connected_accounts/createConnectedAccount.ts
in hermes#9902. ComposioSharedAccessDeniedError and
ComposioSharedConnectionNotAccessibleError remain exported but not yet
thrown — they'll be wrapped when Tools.execute() and ToolRouterSession.create()
error-mapping lands in a follow-up.

Tests: 12 new behaviour tests in test/connectedAccounts/connectedAccounts.test.ts
covering link() ACL forwarding (5), updateAcl() body construction + empty-object
refine + AclOnlyForShared mapping (6), and link() error-mapping fallback (1).
911 tests pass (up from 899).

Verified: pnpm typecheck clean, pnpm build clean (publint + attw clean).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 23:55:13 +05:30
venkat82 752efd8863 refactor(connected-accounts): nest ACL under aclConfigForShared, match merged 9902 contract
The original draft built against 9902's PR description shape — three flat
top-level ACL fields (`allow_all_users`, `allowed_user_ids`,
`not_allowed_user_ids`). The merged design (deployed to staging now)
collapsed them into a single JSONB column and exposes them on the wire
as a nested `acl_config_for_shared` object. This commit reshapes the SDK
to match.

Wire contract changes verified against staging-backend.composio.dev:

  POST /connected_accounts/link        body: account_type, acl_config_for_shared
  POST /connected_accounts             body.connection.{account_type, acl_config_for_shared}
  PATCH /connected_accounts/{id}       body: alias, connection, acl_config_for_shared
  GET  /connected_accounts             item.{account_type, acl_config_for_shared?}
  GET  /connected_accounts/{id}        response.{account_type, acl_config_for_shared?}
  POST /tool_router/session/{id}/link  body: account_type, acl_config_for_shared

SDK changes:

- types: `ConnectedAccountAclSchema` → `ConnectedAccountAclConfigSchema`
  (input — all fields optional) + `ConnectedAccountAclConfigResponseSchema`
  (output — all fields populated when block is visible). Added per-user_id
  length cap (1..256) matching aclConfig.ts. `link()` options exposes
  `aclConfigForShared?` instead of three flat fields. Retrieve response
  exposes `aclConfigForShared?` (undefined when caller can't see ACL).

- model: `link()` and `updateAcl()` serialize the SDK's flat camelCase
  ACL params into the nested snake_case `acl_config_for_shared` wire
  block via a new `serializeAclConfigForWire` helper. Local body types
  updated to match.

- transformer: maps `acl_config_for_shared` (nested) → `aclConfigForShared`
  (nested camelCase). Forwards `undefined` when the block is absent.

- ToolRouterSession.authorize() options gain `accountType` +
  `aclConfigForShared` — the `/tool_router/session/{id}/link` endpoint
  accepts the same fields.

- changeset rewritten to document the nested shape.

Verified: pnpm typecheck clean, build clean, 899 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 18:52:55 +05:30
Zen Agent f273e95f92 docs: update CLAUDE.md for composio SDK
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-11 09:53:07 +00:00
Anshu Garg 0e0b152111 docs(triggers): unify webhook-endpoint concept end-to-end [PLEN-2435] (#3361)
## What this PR is

The trigger docs predate the current webhook-endpoints model and never
explained it. The site has zero mentions of webhook endpoints, signing
secrets at ingress, or the trigger-type flag that tells you whether
endpoint setup is required. This PR fixes that gap end-to-end and
surfaces the per-toolkit setup on the toolkit pages where customers
look.

## The mental model the docs now teach

**Two delivery types:** webhook (provider pushes events to Composio in
real time) or polling (Composio polls). Determined by the trigger type.

**Two pieces of setup, both one-time:**

| Piece | When it's needed | Scope |
|---|---|---|
| **Webhook subscription** — your URL where Composio delivers signed
events | Always | Once per project |
| **Webhook endpoint** — the URL the provider posts events to | Only
when the trigger type's `requires_webhook_endpoint` flag is true | Once
per OAuth app |

**Discovery is at the trigger level.** When you inspect a trigger type
with `composio.triggers.get_type()`, the response includes a
`requires_webhook_endpoint` flag. If true, configure the endpoint before
creating the trigger; if false, just create. With Composio-managed OAuth
apps the flag is always false. The trigger creation call also returns a
`400` if the flag is true and no endpoint exists yet.

The toolkit-level schema endpoint (`GET
/api/v3.1/webhook_endpoints/schema?toolkit_slug=...`) is documented as a
sub-step inside the configuration walkthrough — it's the source of truth
for *which credentials* the endpoint needs once you know you're
configuring one. It's not the upfront check.

## What I changed (10 files)

### Conceptual docs (`/docs/...`)

| File | Change |
|---|---|
| `docs/triggers.mdx` | New overview structure: two delivery types →
setup-at-a-glance table → end-to-end flow with the two-URLs table →
Working-with-triggers steps that lead with "inspect the trigger type."
No upfront schema-endpoint check; no toolkit-name lists. |
| `docs/setting-up-triggers/creating-triggers.mdx` | Reordered. SDK and
dashboard sections now come first (the common path); the 5-step
"Configuring the webhook endpoint" walkthrough is last, gated behind
"skip unless your trigger needs it." SDK code samples print
`requires_webhook_endpoint` / `requiresWebhookEndpoint` alongside
`config` so the discovery moment is visible in-line. |
| `docs/setting-up-triggers/subscribing-to-events.mdx` | Top callout
reframed around the flag instead of toolkit names. |
| `docs/webhook-verification.mdx` | Two-signatures callout. **Ingress
signature verification** section reframed around the flag. |
| `docs/troubleshooting/triggers.mdx` | **Webhook endpoint issues**
section: header drops the toolkit names; lead-in references the flag.
Failure modes unchanged. |
| `docs/glossary.mdx` | Trigger entry simplified to two delivery types.
New Webhook Endpoint and Webhook Subscription entries, both phrased
around the flag. |
| `docs/setting-up-triggers/meta.json` | No new pages — the walkthrough
lives in `creating-triggers.mdx`. |

### Toolkit-page FAQs (`/toolkits/...`)

Toolkit pages (e.g. `/toolkits/slack`) get triggers and tools
server-side from Apollo (`/api/v3/triggers_types`, `/api/v3/tools`). The
only piece of per-toolkit content in this repo is
`content/toolkits/faq/{slug}.md` — plain markdown rendered as a FAQ
accordion at the bottom of the toolkit page.

| File | Change |
|---|---|
| `content/toolkits/faq/slack.md` | Rewrite the **"How do I set up Slack
event webhooks?"** answer: it pointed at the legacy
`/trigger_instances/slack/default/handle` URL. Replace with the
webhook_endpoints flow (POST endpoint → PATCH signing secret → optional
`app_token` → paste URL into Event Subscriptions). Lead with
"Composio-managed credentials = nothing to do." Update **"Why aren't my
Slack triggers working?"** to reference the same flow. |
| `content/toolkits/faq/notion.md` | Add **"How do I set up Notion
webhook triggers?"** with the same Composio-managed-vs-your-own split.
Step 1 calls the schema endpoint to discover required fields, since I
don't want to invent Notion-specific field names. |

Both FAQ entries link to
`/docs/setting-up-triggers/creating-triggers#configuring-the-webhook-endpoint`
for the canonical reference.

## What's deliberately NOT in this PR

- **No V1/V2 split in the prose.** Per direction: keep the docs unified
around the current model. V1 isn't mentioned in user-facing copy. The V2
announcement changelog still exists at `/docs/changelog/2026/04/27` for
historical reference.
- **No invented vocabulary.** Earlier drafts had "user-level webhook"
and "app-level webhook endpoint" as named delivery models — both
removed.
- **No standalone V2 setup page.** The walkthrough is folded into
`creating-triggers.mdx` so readers don't context-switch mid-flow.
- **No API reference changes.** All API ref pages under
`/reference/api-reference/webhooks/` are auto-generated by the
`docs-update-data` workflow from Apollo's OpenAPI export — see Companion
PR.

## Companion PR — must merge with this one

**[#3238 —
docs/auto-update-data](https://github.com/ComposioHQ/composio/pull/3238)**
is the auto-update PR (open since 2026-04-18). It contains the
regenerated `webhooks/index.mdx` and the latest `openapi.json`, both of
which include the new `webhook_endpoints` CRUD operations. **That PR is
what surfaces the API reference pages** (`postWebhookEndpoints`,
`getWebhookEndpoints`, `getWebhookEndpointsByNanoId`,
`postWebhookEndpointsByNanoId`, `patchWebhookEndpointsByNanoId`).

Verified the auto-PR is correct:
- Branch `docs/auto-update-data`, force-pushed every cycle (every 5
hours) by `peter-evans/create-pull-request`.
- Latest commit `2026-05-07T10:42:33Z`. Single commit. **14 files**, all
in the expected auto-generated set:
`docs/content/reference/api-reference/*`,
`docs/content/reference/v3/api-reference/*`,
`docs/content/reference/meta-tools/*`, `docs/public/data/*`,
`docs/public/openapi*.json`. Zero unrelated changes.
- `+27,173 / -16,704` lines come from `openapi.json` (~31k lines) and
`toolkits.json` (~6.7k lines) being fully regenerated. Review by file
list, not by line count.
- Status: `mergeStateStatus: BLOCKED, reviewDecision: REVIEW_REQUIRED`.
All CI green (CodeQL, Vercel preview).

Either PR can merge first; they touch disjoint files. Both must be in
for the trigger story to be complete.

## Two open product items (separate from this PR)

1. **`requires_webhook_endpoint` flag on trigger types.** This PR's code
samples and conceptual prose write against this flag as the discovery
mechanism. Per discussion, the product team will expose it on the
trigger type / SDK. If the field name shipped is different, this PR will
need a small follow-up rename (one place in `triggers.mdx`, two places
in `creating-triggers.mdx`'s code samples, plus the cross-references in
`subscribing-to-events.mdx`, `webhook-verification.mdx`,
`troubleshooting/triggers.mdx`, and `glossary.mdx`).
2. **`GET /api/v3.1/webhook_endpoints/schema?toolkit_slug=...` not in
the OpenAPI spec.** This endpoint is documented (used inside the
configuration walkthrough) but Apollo isn't exporting it. Without Apollo
source in this repo I can't say whether it's missing the `Webhooks` tag,
marked `x-internal: true`, or just unannotated. The endpoint works in
production today; it just doesn't show up in the auto-generated API
reference. Action item on the Apollo side.

## Test plan

- [x] `bun x fumadocs-mdx && bun run scripts/validate-links.ts` — 0
errors after each commit
- [ ] Reviewer: open the Vercel preview and confirm:
- `/docs/triggers` reads coherently end-to-end (no V1/V2 in prose;
setup-at-a-glance table is accurate)
- `/docs/setting-up-triggers/creating-triggers` — SDK/dashboard sections
come first; walkthrough at the bottom is clearly skippable
- `/toolkits/slack` and `/toolkits/notion` FAQ accordions show the new
webhook setup steps
- The `requires_webhook_endpoint` flag references read correctly across
all the trigger pages

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-11 13:15:01 +05:30
Anshu Garg 6ed8c7487d docs(triggers): repoint links to the split Webhook Subscriptions / Webhook Endpoints API pages
Apollo split the Webhooks tag into Webhook Subscriptions + Webhook Endpoints, so /reference/api-reference/webhook-subscriptions and /webhook-endpoints are the canonical pages now. Repoint:

- glossary, creating-triggers, subscribing-to-events, webhook-verification, and the webhook-subscriptions changelog
- delete the orphan /reference/api-reference/webhooks/index.mdx (and its v3 twin) — Apollo's openapi.json no longer routes any operation to the legacy Webhooks tag, but generate-api-index iterates only tags-with-operations, so the orphan never got auto-removed (separate script bug, follow-up)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 13:01:02 +05:30
Anshu Garg 6c7be673e8 Merge remote-tracking branch 'origin/next' into docs/triggers-webhook-endpoints 2026-05-11 12:56:59 +05:30
Anshu Garg 0006e10323 docs(triggers): point Webhooks API links to specific create operations
The /reference/api-reference/webhooks page lists both Subscriptions and Endpoints operations on one page, so the generic page-level link was ambiguous about which API the prose was referring to. Each label now points to its create operation page (postWebhookSubscriptions / postWebhookEndpoints).

Also moves the Webhook Endpoints API pointer up out of Step 2 into the section intro so it scopes the whole walkthrough.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 12:36:56 +05:30
Anshu Garg 73a5ccf238 docs(triggers): add Webhook Endpoints API pointer + Notion ingress FAQ
- Single Webhook Endpoints API pointer at Step 2 of creating-triggers, mirroring the Subscriptions API pointer pattern; same pointer added to the Webhook Endpoint glossary entry.
- Reword Slack-walkthrough intro to direct readers to per-toolkit FAQ (Slack, Notion).
- Add "How do I set up the Notion webhook ingress endpoint?" FAQ covering the reverse-direction verification flow (token from Composio pasted back into Notion).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 12:31:49 +05:30
Anshu Garg 8ff9068a8c docs(scripts): clean up stale api-reference index.mdx for orphan tags (#3384)
# Description

`docs/scripts/generate-api-index.ts` iterates every tag declared in
`spec.tags` (both v3.1 and v3.0 OpenAPI specs) and writes an `index.mdx`
per tag. The old code did:

```ts
if (ops31.length === 0 && ops3.length === 0) continue;
```

When a tag is renamed in Apollo (recent example: `Webhooks` → `Webhook
Endpoints` + `Webhook Subscriptions`), the orphan tag is still listed in
`spec.tags` but no operation references it anymore. The script's
`continue` silently skips it. The previously-committed
`webhooks/index.mdx` (generated when those operations were still tagged
`Webhooks`) is left untouched on disk — and since git doesn't surface
"files we didn't change," the auto-update PR never includes the deletion
either. Result: a phantom **Webhooks** category survives in the rendered
docs alongside the new split categories, with broken `href`s pointing at
non-existent operation pages.

**Symptom:** [PR #3377
(auto-update-data)](https://github.com/ComposioHQ/composio/pull/3377/files)
added `webhook-endpoints/index.mdx` and
`webhook-subscriptions/index.mdx` but did not delete
`webhooks/index.mdx`, even though Apollo's openapi.json no longer routes
any operation to the `Webhooks` tag.

## What this changes

Replace the silent `continue` with an `rmSync` of any stale `index.mdx`
for that tag in both:

- `content/reference/api-reference/<slug>/index.mdx`
- `content/reference/v3/api-reference/<slug>/index.mdx`

The next scheduled `docs-update-data` run will pick up the orphan tag(s)
and surface the deletion(s) in the auto-PR — no manual `git rm` needed.

This is a minimal targeted fix (3-line behavior change at the exact spot
that already detects "tag is empty"). No new manifest files, no
full-directory wipes, no infra changes. Existing tags with operations
behave identically.

## Caveat

Only fixes the **fully orphan** tag case (zero ops in both v3.1 and
v3.0). The asymmetric case — tag has ops in one spec but not the other —
would still leave a stale file behind, since the per-spec write guards
on lines 98 and 136 don't have matching delete branches. Not in scope
for this PR; leaving as a follow-up if it ever happens.

# How did I test this PR

Sanity-ran `bun scripts/generate-api-index.ts` against the current
`next` openapi specs and confirmed all existing tag pages regenerate
identically (no spurious deletions, no diffs in `git status`).

End-to-end verification of the cleanup path against the post-retag specs
from PR #3377 left to reviewer — feed the PR-3377 `openapi.json` +
`openapi-v3.json` into `public/`, run the script, expect
`content/reference/api-reference/webhooks/index.mdx` and
`content/reference/v3/api-reference/webhooks/index.mdx` to be removed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-05-11 12:02:37 +05:30