mirror of
https://github.com/ComposioHQ/composio.git
synced 2026-09-22 11:46:35 +08:00
@e2e-tests/node-custom-tools@0.0.3
1403 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
781cee45ba |
Release: update version (#4373)
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.19.0 ### Minor Changes - |
||
|
|
dafe1389b1 |
chore(release): prepare Python 0.22.0 and TypeScript releases (#4563)
This PR: - bumps Python `composio` and all 13 provider packages to `0.22.0` - regenerates `uv.lock` and adds the coordinated Python and TypeScript release changelog - records the manually published `@composio/typesafe@0.1.0` as the repository baseline - replaces the original TypeSafe minor changeset with a patch release for `0.1.1`, so post-publication runtime fixes ship instead of being skipped - keeps the existing Changesets train for `@composio/core@0.19.0`, `@composio/slim@0.19.0`, and provider updates - verifies the release workflow, changesets, all 20 TypeScript package builds, 147 TypeSafe tests, 590 docs static tests, and all 28 Python distributions with Twine |
||
|
|
d4d306073c |
fix(sdk): save tool-only MCP updates and connection-management intent (#4512)
This PR: - closes [PLEN-3890](https://linear.app/composio/issue/PLEN-3890/fix-mcp-lifecycle-update-configuration-defects) - fixes `composio.mcp.update()` dropping parts of the requested configuration: tool-only updates (`allowedTools` without `toolkits`) sent no tools field at all, and updates with toolkits sent the create-time `custom_tools` alias, which the update endpoint never reads - inverts `manuallyManageConnections` into `managed_auth_via_composio` on update, so `manuallyManageConnections: true` no longer stores "Composio manages auth" (create and generate already inverted it) - builds the update body sparsely: each provided field is sent independently, omitted fields are left out entirely instead of being sent as `undefined` - keeps the auth config of a `{ toolkit, authConfigId }` toolkit entry in `create()` and `update()` instead of discarding it via an `else if` (Python already extracted both) - sends `allowed_tools` instead of the deprecated `custom_tools` alias from `create()` too, in both SDKs; Python previously raised `TypeError` (masked as `ValidationError`) for the removed `custom_tools` kwarg against the pinned `composio-client` 1.43.0 - adds regression coverage for both SDKs and a changeset for `@composio/core` ## Context Found by the September SDK + Composio client hackathon (Area 5, MCP lifecycle), where the two worst frictions were "successful SDK updates that do not save the requested configuration" and reversed manual connection management. The hackathon's third Area 5 finding — PATCH accepting nonexistent tool slugs — is an Apollo-side defect, fixed separately in ComposioHQ/platform#13015. `MCP.ts` and the Python `mcp.py` are identical between `next` and `main`, so this merges cleanly to the beta channel afterwards. |
||
|
|
62e51e838f |
chore(deps): refresh safe dependencies and Effect v4 (#4538)
## Summary Refreshes the safe TypeScript, Python, and GitHub Actions dependency surface in one maintainer-owned change. Effect 4 rc.115, Vitest 5, the vendored Effect source, CLI migrations, and agent guidance move together, while known incompatible boundaries stay pinned. The Effect v4 config schemas preserve unknown fields across `config.json` and `user_data.json` read-update-write cycles. Fixes #4535 ## Changes - Keeps Cloudflare Workers fixtures on Vitest 4 until `@cloudflare/vitest-pool-workers` supports Vitest 5. - Keeps Mastra on the Workers-compatible versions and AG2 below 1.0 because AG2 1.x no longer ships the imported `autogen` module. - Removes the unused package-level `pnpm` dependency instead of changing the repository's pinned pnpm 11 toolchain. - Migrates the Effect CLI APIs, Eve callback contract, provider peer ranges, and repository skills required by the selected upgrades. - Preserves unknown CLI settings when `config.json` and `user_data.json` are read, updated, and written back. - Uses immutable SHA pins for the refreshed Claude Code actions and adds release metadata for the affected published TypeScript packages. ## Type of change - [x] Bug fix - [ ] New feature - [x] Refactor/Chore - [x] Documentation - [ ] Breaking change ## How Has This Been Tested? - `pnpm install --frozen-lockfile` with pnpm 11.8.0 - `pnpm typecheck` - `pnpm build:packages` - `pnpm --filter @composio/cli test` — 1,400 passed, 1 skipped, including targeted persistence regressions for `config.json` and `user_data.json` - Package tests — 28 workspace tasks passed - Example typechecks/tests and all Cloudflare dry-runs - Provider compatibility, experimental/Eve, Mastra, CLI keyring, and JSON-schema Effect checks - Agent-skill validation, routing validation, Effect skill example compilation, and peer-dependency checks - All three Python `uv lock --check` runs - `nox -s tst_autogen`, `nox -s snt`, and `nox -s chk type_inference` - Production dependency audit completed with the repository's three existing ignored advisories Docker CLI E2E was not run locally because the Docker daemon is unavailable. The exact root lint command also enters the vendored Effect submodule, whose checkout does not install its `@effect/oxc/oxlint` plugin; scoped lint over the changed non-vendor files passed. ## Screenshots (if applicable) Not applicable. ## Checklist - [x] I have read the Code of Conduct and this PR adheres to it - [ ] I ran linters/tests locally and they passed - [x] I updated documentation as needed - [x] I added tests or explain why not applicable - [x] I added a changeset if this change affects published packages The dependency migrations are covered by the focused and workspace suites. Two targeted regression tests verify that CLI updates preserve unknown fields in `config.json` and `user_data.json`. ## Additional context The Connect client sync retains its existing `Bash(curl *)` permission while moving the removed `allowed_tools` input to `claude_args`. A separate hardening change should move logo downloads outside the model-controlled shell boundary. --- [](https://github.com/EveryInc/compound-engineering-plugin) |
||
|
|
bd5984e133 |
chore(cli): refresh baked toolkit slugs (#4548)
## Summary Automated refresh of the toolkit slugs the CLI knows without asking the API, generated by `ts/packages/cli/scripts/generate-toolkit-slugs.ts`. Toolkits added since the last refresh currently cost users one toolkit-list fetch (~2 s) the first time they run one of that toolkit's tools. Merging this makes them free. The generator refuses to write a list that is short, malformed, or missing staple toolkits, so a bad fetch opens no PR at all. Co-authored-by: jkomyno <12381818+jkomyno@users.noreply.github.com> |
||
|
|
4b5920bf7a |
feat(sdk): add session.ensureConnected to reconcile connection state (#4536)
This PR: - addresses the connection-readiness finding from the Sept 2026 SDK + client hackathon (area 8): `session.authorize()` always starts a new link flow, even when the session already resolves an ACTIVE connection for the toolkit — callers ended up with a pending connected account while `session.toolkits()` reported a different, active one, and nothing in the SDK reconciled the two - adds `session.ensureConnected(toolkit, options?)`: it checks the session's connection state first — an ACTIVE connection (or a no-auth toolkit) returns immediately with `wasConnected: true` and no link is created; otherwise it starts the authorization flow and waits for the new connection to become active (`timeout` option, default 60s) - keeps `authorize()` unchanged as the primitive for interactive flows that should surface the redirect URL instead of blocking - documents the `session.execute()` `account` option's runtime contract: accepted on every project, and on single-account projects the identifier must match one of the session's active connections for the toolkit (matching the API behavior after the Apollo side-fix) - adds 5 unit tests for `ensureConnected` (already-connected no-op, no-auth short-circuit, link-and-wait, pending-account relink, option validation) and a changeset Verification: `pnpm exec vitest run` in `ts/packages/core` — 1320 passed; `pnpm typecheck` (tsc + type tests) clean; `pnpm lint` clean at repo root. |
||
|
|
c7843d8a3a |
feat(core): return session config from session.update() (#4533)
This PR: - makes `session.update()` resolve to the updated server-side session configuration instead of `void` - exposes that configuration as `session.config` (new `ToolRouterSessionConfig` type) on sessions from `create()`, `use()` and attach, so the toolkit/tool allowlist is readable without dropping to the raw client - renames the private SDK-config member on `ToolRouterSession` to `sdkConfig`, ending the runtime name clash that made `session.config` look like the SDK's `ComposioConfig` - applies the same change to the Python `ToolRouterSession` (`config` attribute, `update()` returns it) - adds a minor changeset for `@composio/core` ## Context After `sessions.use(id)` there was no way to know the session's allowlist, and `update()` threw the response away except for `configVersion` / `preload` / `sandbox` / `warnings`. Hackathon feedback (area 8). |
||
|
|
756ea915f7 |
docs: update TypeScript SDK reference from source (#4486)
## Summary Auto-generated TypeScript SDK reference docs from `ts/packages/core/src/`. Regenerates pages at `docs/content/reference/sdk-reference/typescript/` to reflect changes in the core package's public API (new methods, updated signatures, changed types). |
||
|
|
aefc3ec897 |
feat(typesafe): add TypeSafe Jev provider for TypeScript and Python (#4513)
## Summary Adds TypeSafe Jev providers for TypeScript and Python that turn tool schemas and a request into a call, a partial call, or an abstention. ## What changed - adds `@composio/typesafe`, a provider for TypeSafe's Jev model. Jev has no tool calling, so `composio.tools.get()` compiles tools into typed questions and `decide` returns a `call`, a `partial` call, or an `abstain`, each with a confidence - adds `execute` for a user ID or a session: caller arguments complete a `partial`, and a tool tagged `destructiveHint` routes at a fixed floor of 0.9 and needs `confirm: true` - adds the companion helpers `shortlistTools` and `confidenceGate` (a `beforeExecute` modifier that fails closed) for use with other providers - adds `composio-typesafe`, the Python counterpart with sync and async clients; both test suites compile one shared question corpus, so both SDKs ask Jev the same questions for the same tool - registers the package in the provider-compatibility release gate, adds a `minor` changeset, the `ts/examples/typesafe` example, a Python demo, and a dedicated `py.test.yml` step - exempts only `@typesafe-ai/sdk@0.6.0` from `minimumReleaseAge` (publisher, SLSA provenance, and the absence of install scripts were checked by hand), and sets `engines.node` to `>=24.17.0` for this package because the SDK terminates the process after a handled cancellation on older Node.js releases (typesafe-ai/typesafe-sdk-js#2) ## Usage ```typescript const provider = new TypesafeProvider(); const composio = new Composio({ provider }); const toolSet = await composio.tools.get('user_123', { tools: ['GITHUB_LIST_REPOSITORY_ISSUES'] }); const decision = await provider.decide(toolSet, 'List the closed issues of ComposioHQ/composio'); if (decision.kind !== 'abstain') { // Jev binds closed-set arguments (enums, booleans, arrays of enums). Free text comes from you. await provider.execute('user_123', decision, { arguments: { owner: 'ComposioHQ', repo: 'composio' } }); } ``` ## Behavior notes - `abstain` means only that the model judged so. A failed request throws one `TypesafeApiError` whose `reason` tells rate limits, timeouts, and rejections apart, and a malformed response throws `TypesafeMalformedResponseError`. No error holds state, argument values, response content, or the SDK's own error. - Routing and the action gate see `request` only, so text in `context` cannot change which tool is picked. `contextScope: 'all'` opts out. - State is never truncated: over-budget state, unknown top-level state keys, and non-JSON values throw. - The options are `client`, `apiKey`, `model`, `thresholds`, and `contextScope`. The provider builds its client at log level `warn`, so `TYPESAFE_LOG_LEVEL=debug` cannot print request bodies. - Root-level `allOf`, `anyOf`, and `oneOf` schemas are rejected explicitly in both SDKs, including after `$ref` resolution, so composed requirements cannot silently disappear. Property-level composition remains supported as documented. - Completing a partial decision requires an own, non-`undefined` argument value in TypeScript; inherited names such as `toString` do not satisfy required arguments. Supplied `__proto__` keys are preserved as own data properties. ## Validation - 147 TypeScript provider tests and 141 Python provider tests pass. The 11 new missing-argument regression cases fail on the original implementation and pass with the fixes. - Typecheck, Oxlint, Prettier, the tsdown build with ATTW/publint, Ruff, mypy, type-inference, and release-gate checks passed locally. - All 13 opt-in live tests passed across the TypeSafe-only and Composio-backed suites against real Jev 1.13.0. These tests make decisions without executing external tools. - The actual TypeScript and Python Hacker News examples both ran end to end against production APIs: fetch tools, decide, detect the missing username, supply `pg`, and execute the read-only lookup. Both returned the live profile for `pg`. Not in this PR: the docs page, which needs the first npm publish so its snippets compile. The first npm and PyPI publishes and a `TYPESAFE_API_KEY` CI secret are manual steps. ```mermaid flowchart LR A[composio.tools.get] --> B[compile tools into questions] B --> C[decide: state + questions] C --> D{Jev answers} D -->|none fits, no action, low confidence| E[abstain] D -->|required arguments missing| F[partial] D -->|everything bound| G[call] F -->|caller arguments| H[execute] G --> H H -->|destructive tool| I[needs confirm: true] ``` |
||
|
|
bfc654ac66 | fix(typesafe): preserve prototype-named caller arguments | ||
|
|
cf15b62e60 | fix(typesafe): guard required arguments in compilation and execution | ||
|
|
cc1248370b |
fix(typesafe): block null-leaf container swaps and tighten gate option checks
- Treat dict/list as their own leaf kind when asserting a redactor masks
only, so a redactor cannot replace a JSON null leaf with an object or
array while the gate would approve the altered call (Python now matches
the TS scalarTypeOf behavior).
- Reject non-number gate thresholds ('', '0.9', true) at construction on
the TS side, matching the strict Python check.
- Omit the gate state context key when getContext returns null, matching
Python and decide's context handling.
- Pin all three with regression tests on both SDKs, and assert the
context key is absent from the sent state when no getContext is given.
|
||
|
|
8878a9bcc5 |
fix(typesafe): fail closed on redaction structure changes and invalid gate options
Review findings from the TypeSafe (Jev) provider PR, fixed in both SDKs: - The confidence gate enforces a masking-only redaction contract: the redacted arguments must keep the original JSON structure (same keys, same array lengths) with every leaf replaced by a value of the same scalar type, or the call is blocked. Jev can no longer approve a call that differs from the one that runs. - `onUnavailable` is validated when the gate is built, in the companion both entry points share: a typo'd mode raises TypesafeInvalidOptionsError at construction instead of failing open at check time. - `minItems` is carried through classification and compilation into array arguments, and a selection with fewer members than `minItems` counts as not stated, so a required array stays missing instead of executing with `[]`. - The boolean class gains `nullable`: a ['boolean', 'null'] property compiles to a yes/no/null Choice so Jev can bind null; plain booleans still compile to yes/no only, and one-boolean enum sets stay open-ended. - `stable()` rejects `undefined` wherever it appears instead of rewriting it, and the gate builds its state without a `context` key when there is no context, so a context-less gate call still works. - `Probability` and the classify number type accept JSON integers, so an API score of 0 or 1 and integer `maxItems`/`minItems` parse instead of marking the property open-ended or the response malformed. Bools, strings, NaN, inf, and out-of-range values are still rejected. |
||
|
|
a648ceff3f | fix(docs): preserve generated parameter metadata | ||
|
|
1501ae6fdb | test: classify the TypeSafe provider in the $ref handling contract | ||
|
|
705888faff |
docs: describe the four verdict hints sessions filter on (#4470)
## Why Requirement 1 of the PRD: sessions accept all four verdict hints. The Configuring Sessions tag table listed the four MCP-spec hints, two of which (idempotentHint, openWorldHint) are set on a minority of tools. Every tool carries at least one of readOnlyHint, createHint, updateHint, destructiveHint. ## What - Tag table leads with the four verdict hints and says every tool carries at least one; idempotentHint and openWorldHint noted as accepted with partial coverage. - Callout: the v3 tools endpoints default to the pinned version 00000000_00, sessions read latest. - Python example uses createHint. The TypeScript twoslash example stays on readOnlyHint so docs CI passes against the published SDK; switch it to createHint when merging, after #4467 is released. - Python and TypeScript SDK reference docs list the widened enum. ## Merge after API: platform#12843 (accept createHint and updateHint). SDK: composio#4467 released. PRD: https://app.notion.com/p/composio/Session-Governance-via-hints-Across-toolkits-3daf261a6dfe80df8e0ce337a2b26e08 Linear workstream: https://linear.app/composio/project/sessions-execution-governance-a0942233a0d0 Stack order (merge top to bottom, each after its API change is deployed): D1 verdict hints, D2 precedence, D3 proxy execute toolkit lists, D4 MCP classification, D5 proxy execute API key permission. Verification, run in `docs/` at the top of the stack (D5 head, which contains this PR): `bun run types:check` passes, `bun run build` compiles (twoslash blocks type-check against the published `@composio/core`), `bun run lint:links` reports 0 errors, `bun run test` 568 pass. `pnpm exec prettier --check` flags the changed mdx files on `next` already, so no reformatting was applied. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01VHkYsmhteM1jJQoaoruiP3 |
||
|
|
ab0a5fa88c |
refactor(typesafe): drop per-tool thresholds, describe overrides, and logLevel
Collapse the TypesafeApiError subclasses into one error with a reason field, consolidate the question corpus to nine tools, and cut the tests that exercised the TypeSafe SDK instead of the provider. |
||
|
|
7681b90ad9 | docs: list the TypeSafe provider | ||
|
|
d36048fbe7 | feat(typesafe): add TypeSafe Jev provider for TypeScript | ||
|
|
eccb80ef10 |
fix(cli): block SSRF in proxy binary downloads (#4511)
This PR: - closes [SEC-1179](https://linear.app/composio/issue/SEC-1179/composio-attacker-can-reach-internal-services-using-ssrf-to-steal) - routes proxy binary downloads through the core `ssrfSafeFetch` guard - requires validation-to-connection pinning and fails closed when a configured dispatcher or proxy prevents it - reapplies that requirement on every redirect hop while preserving default SDK proxy compatibility - covers direct metadata targets, configured-route bypasses, redirects, and the bundled Bun companion - verifies the full core and CLI suites plus the TypeScript workspace typecheck |
||
|
|
c89e66efbc |
fix(cli): curated help for every command family and a help command (#4421)
This PR:
- follows https://github.com/ComposioHQ/composio/pull/3901 (merged as
|
||
|
|
feca0389f9 |
feat(cli): plugin-adoption telemetry for setup and the plugin hint (#4496)
## Summary Live PostHog (2026-09-15): since auto-setup was restored on Sep 14, 704 installer-triggered `composio setup` runs found no host 397 times (56%); of the 316 that found one, 282 installed the plugin (89%). The gap is host detection, and today a real absence is indistinguishable from a PATH miss. Manual `composio setup` over 30 days: 888 succeeded, 626 failed, and `CLI_SETUP_FAILED` only carried `error_name`. 103 of those failures (`yes=false, target=auto, stdout_is_tty=false`) are agents following the daily hint text into "Non-interactive setup requires `--yes`". No event said whether the CLI was running inside Claude Code or Codex at all. Event contract (metrics.composio.io is being built against these names): - Every CLI event gains `agent_host_env: 'claude' | 'codex' | 'none'`, derived from `CLAUDECODE` / `CODEX_THREAD_ID` / `CODEX_SANDBOX`. - `CLI_SETUP_HOST_DETECTED` gains `host_config_dir_present` and `host_binary_in_known_paths` when `available=false` (`$CLAUDE_CONFIG_DIR`/`~/.claude`, `$CODEX_HOME`/`~/.codex`; `~/.claude/local`, `~/.local/bin`, `~/.npm-global/bin`, `/usr/local/bin`, `/opt/homebrew/bin`). Both omitted when the host is detected. - New `CLI_PLUGIN_HINT_SHOWN` (journey stage `setup`) with `source`, `invocation_origin`, `cli_version`, `command_path`, `agent_host`, emitted once per printed hint and never on suppression. - `CLI_SETUP_FAILED` gains `failure_reason_code`: `all_requires_both_hosts | unsupported_host | target_not_installed | no_host_detected | non_interactive_requires_yes | marketplace_conflict | unknown`, carried on `SetupCommandError.reasonCode`. - Hint text is now `Tip: running under <host> without the Composio plugin — 'composio setup --yes' installs it.` Structural notes: `agent_host_env` is stamped in `trackCliEventEffect` (`analytics/dispatch.ts`) next to `org_id`, so every enqueued envelope carries it with no module state or bootstrap hook. `SetupCommandError` and `SetupFailureReasonCode` live in the leaf module `services/setup-command-error.ts` (imports only `effect`) so `analytics/events.ts` can use `instanceof` without a cycle; `setup.cmd.ts` keeps its original `setupCommandError` helper with the reason code as a third argument, and the two validate-stage failures in `services/setup.ts` (`marketplace_conflict`, `target_not_installed`) are raised as `SetupCommandError` directly. The raw host-env read, `detectPluginHost`, and the known-path install probe live in `services/agent-host-env.ts`, shared by `dispatch.ts`, `plugin-hint.ts`, and `setup.ts`. `CLI_SETUP_HOST_DETECTED` passes the two presence booleans straight through; `setup.ts` only probes an undetected host. The hint tracks `CLI_PLUGIN_HINT_SHOWN` right where it prints. ## Validation - `pnpm --filter @composio/cli` `pnpm run test` (validate:skills, validate:boundaries, vitest): 132 files, 1374 passed, 1 skipped. - `pnpm run typecheck` (src + test): clean. - `oxlint` on the 14 changed TS files: clean. `prettier --check` on changed files: clean. `git diff --check`: clean. - `pnpm validate:agent-skills` and `pnpm validate:skill-routing`: pass (skill reference doc changed). - Manual, built binary with isolated `HOME`/`COMPOSIO_CACHE_DIR`/`CLAUDE_CONFIG_DIR` and a dummy PostHog key pointed at a dead local port: `CLAUDECODE=1 composio whoami --telemetry-debug` printed the new hint once and enqueued `CLI_PLUGIN_HINT_SHOWN` (`command_path: whoami`, `agent_host: claude`) plus `CLI_COMMAND_INVOKED`/`SUCCEEDED`, all with `agent_host_env: claude`; a second run printed no hint and no hint event. `PATH=/usr/bin:/bin composio setup --target codex --yes --telemetry-debug` enqueued `CLI_SETUP_HOST_DETECTED` with `available: false, host_config_dir_present: true, host_binary_in_known_paths: false` and `CLI_SETUP_FAILED` with `failure_reason_code: target_not_installed`. Re-run after each simplification pass with identical output; with the host markers unset the same events carry `agent_host_env: none`. ## Known verification limitations - No changeset: `@composio/cli` is ignored by Changesets per `ts/AGENTS.md`; the note went into `ts/packages/cli/CHANGELOG.md` instead. - Docker CLI E2E not run; no binary output contract changed except the hint line. - `host_binary_in_known_paths` checks two absolute directories, so the "absent everywhere" test asserts a boolean rather than `false` to stay machine-independent. Not included: any change to `composio setup` help text or to the dashboard side. 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
37731d5899 |
test(e2e): expect --yes in the setup recovery hint
The setup-plugins suite pins the recovery command printed when native plugin inspection fails. setup remediation messages now carry --yes so non-interactive agents get a command that completes, so the pinned 'composio setup --target claude' fragment became 'composio setup --yes --target claude'. Matches the exact stderr CI reported on the failing scratch run. |
||
|
|
a8e238386b |
fix(cli): thread operation into validateInitialState instead of hardcoding setup
validateInitialState hardcodes operation 'setup' in its SetupCommandError while its only caller, the exported inspectSetupTargets, already threads options.operation for wording. Uninstall skips validation today (allowMarketplaceConflict: uninstall), so nothing mislabels now, but any future uninstall caller that validates would get operation 'setup' and the wrong failure_reason_code in telemetry. Pass options.operation ?? 'setup' through and use it in both constructions. |
||
|
|
8a3a1a53a1 |
fix(cli): carry --yes in every setup remediation rerun command
The plugin hint learned to say 'composio setup --yes', but the error messages an agent hits next still suggested bare reruns that deterministically fail again with non_interactive_requires_yes in a non-TTY shell - the same 103-failure loop this PR set out to fix. Add --yes to the targeted-missing and no-host messages in setup.cmd, the validate-stage target/marketplace messages, the verify-stage messages, and the shared recovery-hint command; the most conflicting case also walked agents through the destructive marketplace remove before a rerun that could not succeed. Interactive users can drop the flag; agents get a command that actually completes. Adds rerun-message assertions for the three reachable failure paths. |
||
|
|
1ec7c312d7 |
fix(cli): release the plugin hint claim when printing fails
showPluginHint claims the 24h stamp before printing, so a print that did not succeed left the stamp standing: the hint was never delivered yet both the hint and CLI_PLUGIN_HINT_SHOWN stayed muted for the full interval. Capture the print with Effect.exit and remove the just-created stamp on any non-success exit so the next invocation can retry. Tracking stays best-effort by contract: trackCliEventEffect never fails, so a delivered hint with a lost event is accepted and does not un-claim. |
||
|
|
4afd5e0620 |
refactor(cli): resolve plugin hint host dirs via hostConfigDirectory
resolvePluginHintConfig inlined the same env-override-else-~/.claude and ~/.codex fallback expressions that agent-host-env.ts now owns, leaving the host-dir default written three times across two files. Use the shared helper for both file paths and drop the now-unused NodeOs yield. The 'preserves nonblank path overrides' test asserted verbatim pass-through of relative overrides, which was the cwd dependence the probe hardening removes. It now pins absolute overrides preserved as-is plus a new case asserting relative overrides anchor to the home directory. |
||
|
|
8088313d5a |
fix(cli): anchor and type-check host config dirs before install probes
CLAUDE_CONFIG_DIR / CODEX_HOME were passed verbatim to the install probe, so a relative override resolved against the process cwd (making host_config_dir_present depend on where composio was invoked) and a plain file at the config path counted as 'present'. Resolve overrides against the home directory - matching how the known-binary list already resolves - and probe with stat so presence means an actual directory. Unreadable paths report false instead of failing the probe. |
||
|
|
8dc3c7496a |
refactor(cli): read host env through the shared loadHostConfig pathway
rawHostEnvironment re-implemented by hand what src/services/config.ts already provides: a fresh unprefixed ConfigProvider.fromEnv() per execution with orDie error handling. Build the five host keys as one Config.all and load them via loadHostConfig, deleting the bespoke readOptionalEnv helper and the per-call provideServiceEffect override. The fromEnv snapshot rationale now lives only in config.ts's documented getBaseConfigProvider. Behavior is unchanged: same live-env semantics (vi.stubEnv stays observable), same blank-marker handling, same orDie on config failures. |
||
|
|
f8a6483cfb |
perf(cli): store large execute output by byte size, not tokens (#4483)
This PR: - builds on top of https://github.com/ComposioHQ/composio/pull/4475 - stores `composio execute` responses over 40,000 UTF-8 bytes in a session file, replacing the check for more than 10,000 o200k tokens added in https://github.com/ComposioHQ/composio/pull/2979 - keeps `tokenCount` in the stored-output summary as an estimate (`ceil(sizeBytes / 4)`), adds `sizeBytes`, and logs `Response stored in <path> (N KB, ~M tokens)` - removes `js-tiktoken` and the `execute-output-encoder-runtime` companion from https://github.com/ComposioHQ/composio/pull/4469, with its tsdown entry, build-guard and startup-import patterns, upgrade fixture entry, and the encoder fallback and special-token tests - keeps `execute-output-encoder-runtime.mjs` in the three uninstall lists, so installs that shipped it can still remove the leftover file - behavior change: a 10–40KB response of more than 10,000 tokens now prints inline, and dense non-ASCII output (about 1–2 bytes per token) can print inline at up to ~20,000 tokens - verified: CLI typecheck, full CLI vitest (131 files, 1343 passed, 1 skipped), `test/release-workflow.test.ts`, and `build-companion-modules.ts` with the executable graph check ## Context Nothing reads `tokenCount` as a number: it appears only in the stored-output summary, the two log lines, session history, and a debug log in `run-helpers-runtime.ts`. o200k is not the tokenizer of the model that reads the output, so the exact count only moved the cutoff. It cost the 2.3MB rank table, ~330ms after large tool calls (measured in #4469, not re-measured here), and a separately shipped companion whose absence made `composio run` require a repair download after an upgrade. |
||
|
|
b320526d11 |
test(cli): isolate help page output and assert exit codes
Check each curated page against its own output, cover experimental commands in the registry check, and assert exit status and stderr for unknown help targets. |
||
|
|
84e7fde93b |
fix(cli): name the mistyped command in composio help errors
Drop the `help` token and redundant --help/-h flags before routing, so unknown targets get the framework's "Did you mean?" suggestion and `composio help --help` renders the curated root page. Document the `install` flags. |
||
|
|
8e47d5d45c | Merge remote-tracking branch 'origin/next' into fix/cli-help-consistency | ||
|
|
11de45889a |
fix(core): contain async Pusher subscription errors (#4448)
## Summary `PusherService.subscribe` binds `pusher:subscription_error` after the Pusher subscription call returns. `pusher-js` dispatches this event asynchronously without catching listener exceptions, so authentication, permission, server, or network subscription failures could escape as uncaught exceptions in Node applications. Fixes #4445 ## Changes - Log asynchronous Pusher subscription errors at the SDK error boundary instead of throwing from the event callback. - Add regression coverage that emits `pusher:subscription_error` after `subscribe()` resolves and verifies that it does not throw. - Add a patch changeset for the fixed `@composio/core`/`@composio/slim` package group. ## Type of change - [x] Bug fix - [ ] New feature - [ ] Refactor/Chore - [ ] Documentation - [ ] Breaking change ## How Has This Been Tested? - Node `v24.17.0` / pnpm `11.8.0` - `pnpm --filter @composio/core exec vitest run test/services/pusher.test.ts test/utils/pusher.test.ts` — 2 files, 5 tests passed - `pnpm --filter @composio/core test` — 55 test files passed; 1,289 tests passed and 2 existing tests reported expected failures; command exited successfully - `pnpm --filter @composio/core typecheck` - `pnpm lint` — passed with existing repository warnings - `pnpm validate:changesets` - `pusher-js` `v8.6.0` runtime probe confirmed that an exception thrown from a `pusher:subscription_error` listener reaches Node's `uncaughtException` handler; the regression test verifies the SDK callback no longer throws. ## Screenshots (if applicable) Not applicable. ## Checklist - [x] I have read the Code of Conduct and this PR adheres to it - [x] I ran linters/tests locally and they passed - [x] I updated documentation as needed - [x] I added tests or explain why not applicable - [x] I added a changeset if this change affects published packages ## Additional context This patch is intentionally limited to the live `PusherService` path. XHR timeout handling is a separate concern and is not included here. The older unreferenced `PusherUtils` helper is unchanged to keep this fix scoped to the path used by `Triggers`. |
||
|
|
0601190ca0 | Merge branch 'next' into fix/openai-responses-demo-docs | ||
|
|
b09b322d1c |
refactor(cli): stamp agent host at dispatch and drop setup error indirection
trackCliEventEffect reads the host environment and adds agent_host_env to every enqueued envelope, so there is no module-level state and no bootstrap hook. SetupCommandError lives in a leaf module so analytics/events.ts can use instanceof without a cycle, setup.cmd.ts keeps its original helper shape with the reason code as a third argument, and plugin-hint.ts keeps its original config resolution. Event names and properties are unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
5a5b5a3308 |
refactor(cli): flatten the plugin-adoption telemetry plumbing
Keep SetupCommandError in services/setup.ts with its reasonCode, read the code structurally in analytics/events.ts, raise the two validate-stage failures as SetupCommandError directly instead of a second reason-code layer, fold the host install probe into agent-host-env.ts, pass the host presence booleans straight through on CLI_SETUP_HOST_DETECTED, and track the plugin hint where it is printed. Event names and properties are unchanged. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
2af18766db |
chore(cli): drop narrating comment
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
c4bf563aaa |
feat(cli): add plugin-adoption telemetry to setup and the plugin hint
Every CLI event now carries agent_host_env (claude, codex, none) read from the host environment. CLI_SETUP_HOST_DETECTED reports whether the host's config dir and a binary at a known install location exist when the host is not detected, CLI_SETUP_FAILED carries a failure_reason_code read from SetupCommandError, and the daily plugin hint emits CLI_PLUGIN_HINT_SHOWN once per printed line and points at `composio setup --yes` so agents no longer run into the non-interactive --yes failure. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> |
||
|
|
1c829b4f73 |
fix(core): contain rejected promises from async onSubscriptionError handlers
The containment around the subscription error callback only caught synchronous throws. TypeScript accepts an async function against a void-returning callback type, so a rejected promise escaped as an unhandled rejection after subscribe() resolved - on modern Node that can terminate the process, the same failure class this PR contains. Route the callback result through Promise.resolve(...).catch so both sync throws and async rejections land in the same contained logger path, and add a regression test for the async case. Addresses greptile-apps P1 and Cursor Bugbot review comments. |
||
|
|
1148b7ba31 |
docs(openai): mark assistants api methods as deprecated in api reference
The handleAssistantMessage, waitAndHandleAssistantStreamToolCalls, and waitAndHandleAssistantToolCalls methods target the OpenAI Assistants API, which shuts down on August 26, 2026. Add a deprecation warning pointing new flows at OpenAIResponsesProvider. |
||
|
|
cedf1a4217 |
docs(openai): align responses examples on gpt-5 and document provider types
- Use gpt-5 in the Responses API examples; gpt-4 predates the Responses API and the repo's other Responses examples use gpt-5. - Print response.output_text instead of indexing into content items, which assumes non-empty message content. - Add the OpenAIResponsesProvider type surface to the Type Definitions section, which previously only showed the chat completions provider. |
||
|
|
1024d1a48c |
feat(core): add optional onSubscriptionError callback for trigger subscriptions
- PusherService.subscribe and Triggers.subscribe accept an optional onSubscriptionError callback invoked with the raw pusher pusher:subscription_error payload, giving hosts a programmatic signal for post-resolution subscription failures (previously log-only). - Exceptions thrown from the callback are contained and logged, never rethrown, so a faulty handler cannot crash the host. - The parameter is optional; existing callers are unaffected. - Document the new parameter in the TypeScript triggers reference and the subscribing-to-events guide; bump the changeset to minor for the new API surface. Applies review finding #1 from the PR #4448 review. |
||
|
|
334abd1e09 |
fix(core): log pusher subscription outcomes truthfully
- Log the full pusher:subscription_error payload (type, error, status) instead of a flattened String(data.error) so operators can tell auth failures from permission failures. - Log the subscription success message only when Pusher dispatches pusher:subscription_succeeded, not when subscribe() returns. - Extend regression coverage for both behaviors. Applies review findings #2 and #3 from the PR #4448 review. |
||
|
|
614ae3cd11 | refactor(core): clarify toolkit auth mapping guard | ||
|
|
876c88767c |
fix(core): normalize a missing toolkit auth field group instead of throwing
Replacing the pass-through with an eager projection changed the failure mode for
an auth config detail that omits a field group. Passing the group through left
`undefined` in place, which zod rejected as a handled validation error;
`transformToolkitAuthFieldGroup` instead reads `group.required`, so the same
response now throws a `TypeError` before validation runs and crashes
`toolkits.get()`.
Default a missing or null group, and a missing list inside a group, to empty
lists. This repo's docs pipeline already assumes that shape: the schemas in
`docs/lib/toolkit-api.ts` carry `.catch({ required: [], optional: [] })` on the
same fields. Normalizing also keeps the other group usable when only one is
absent, which is typically the one the caller asked for, where a validation
error would have returned nothing.
Reported by greptile-apps on #4411.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
84bc4c2cc0 | Merge branch 'next' into fix/toolkit-auth-field-is-secret | ||
|
|
dcac3e4c9c | Merge branch 'next' into fix/ts-pusher-subscription-error-boundary | ||
|
|
f05fbf6323 | refactor(cli): replace listen create_trigger error explicitly on unknown slugs | ||
|
|
f3bfa06704 | fix(cli): report unknown listen slugs when the inferred toolkit has an account |