Commit Graph

5318 Commits

Author SHA1 Message Date
Alberto Schiabel 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.
@composio/cli@0.4.2-beta.395
2026-09-16 15:45:12 +02:00
Alberto Schiabel 84606be9e6 docs: add Atomic Agent to Composio Connect clients (#4490)
Atomic Agent is a local-first AI agent (CLI and TUI) that ships a
built-in Composio integration. It connects to the hosted tool router
over Streamable HTTP MCP, so Composio tools are registered at startup as
`mcp.composio.*`.

This adds it to the Composio Connect client list alongside the other
terminal agents.

**Changes**
- New `ConnectClientOption` entry in
`docs/content/docs/composio-connect.mdx`
- Client icon at `docs/public/images/clients/atomic-agent.svg`
- `atomic agent` appended to the page keywords

The setup steps document the agent's own flow (Integrations tab, or
`COMPOSIO_API_KEY` in its `.env`) rather than a CLI install, since the
integration is native.

Repo: https://github.com/AtomicBot-ai/atomic-agent

Happy to adjust the wording, the description, or the placement, or to
close this if you would rather add the entry yourselves.
2026-09-16 15:44:44 +02:00
Alberto Schiabel 8bf92435ad Merge branch 'next' into docs/add-atomic-agent-connect 2026-09-16 15:27:51 +02:00
Alberto Schiabel 3e268497ba docs: update documentation for new changelog entries (#4356)
## Summary
Automated documentation updates triggered by new changelog entries
merged to next.

Generated by Codex via GitHub Actions.
2026-09-16 15:27:25 +02:00
jkomyno e55b642f3c docs: keep trigger subscription sample buildable 2026-09-16 15:22:04 +02:00
jkomyno bc3e981986 Merge remote-tracking branch 'origin/next' into review-pr-4356-docs 2026-09-16 15:19:11 +02:00
jkomyno 2cfcb464d8 docs: clarify generated changelog notes 2026-09-16 15:09:46 +02:00
Alberto Schiabel b39a9b30e1 docs(py): render raises sections and normalize reST in SDK reference (#4491)
This PR:

- fixes the raw `:raises ...:` reST directives leaking into the
generated Python SDK reference, flagged by [Greptile on the
auto-generated docs
PR](https://github.com/ComposioHQ/composio/pull/4479#discussion_r4004672537)
- teaches `python/scripts/generate-docs.py` to parse `:raises Exc:`
docstring fields (plus `:raise`/`:except`/`:throws` synonyms) into a
structured `**Raises**` section, with indented continuation-line support
- normalizes inline reST in all rendered prose:
`:class:`/`:func:`/`:meth:`/`:mod:` roles honor `~` short-name
semantics, and double-backtick literals become single-backtick inline
code
- regenerates `docs/content/reference/sdk-reference/python/` pages
- adds regression tests for raises parsing and reST normalization in
`python/tests/test_generate_docs.py`

## Context

The Python SDK reference pages are generated by
`python/scripts/generate-docs.py` (workflow: `generate-sdk-docs.yml`),
so the fix lives in the generator rather than the MDX — hand-edits would
be overwritten by the next auto-regen PR. Unrecognized `:raises` lines
previously fell through into the `:returns:` description text.
2026-09-16 14:57:04 +02:00
Alberto Schiabel 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`.
2026-09-16 14:56:45 +02:00
Alberto Schiabel d599778c19 docs(openai): replace assistants examples with responses (#4165)
## Summary
Fixes #4147.

Updates stale OpenAI Assistants API examples to use the Responses API,
matching OpenAI's current migration guidance that the Assistants API is
deprecated and shuts down on August 26, 2026.

## Changes
- Rewrote the Python OpenAI demo to use `OpenAIResponsesProvider` and
`client.responses.create`.
- Replaced the TypeScript provider docs' Assistants/Threads examples
with a Responses API tool-call loop.
- Removed deprecated `openai.beta.assistants` / `openai.beta.threads`
references from the targeted demo and docs page.

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

## How Has This Been Tested?
- `python -m py_compile
python/providers/openai/openai_assistant_demo.py` (passed)
- `rg -n
"openai\.beta|Assistants|assistants|threads|waitAndHandleAssistant|AssistantStream"
python/providers/openai/openai_assistant_demo.py
ts/docs/providers/openai.md` (no matches)
- `git diff --check` (passed)

## Screenshots (if applicable)
N/A

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

## Additional context
The OpenAI platform docs mark the Assistants API as deprecated and
direct new agentic flows to the Responses API. This PR keeps Composio's
public OpenAI examples aligned with that path.
2026-09-16 14:56:19 +02:00
jkomyno c2e70f66a6 fix(py): route establish-time subscription failures through on_subscription_error
pysher performs the channel-auth request synchronously inside
pusher.subscribe(), so an auth rejection raised on the websocket thread
before pusher:subscription_error could ever be bound or fire. The new
on_subscription_error callback was skipped for exactly the failures it
documents, and callers waited out the full connect timeout for a
generic ComposioSDKTimeoutError.

- _connection_handler catches subscribe() failures and routes them
  through the error path (log + callback with {'error': ...}).
- The failure is recorded on the subscription and the connect() wait
  loop re-raises it on its next poll, so subscribe() fails promptly
  with the underlying error and still tears down the pusher.
- Update the Python reference, guide, and docstrings; add regression
  coverage for the handler routing, the failure record, and fast-fail.

Addresses the Cursor Bugbot comment on triggers.py:1023.
2026-09-16 14:54:14 +02:00
Alberto Schiabel 0601190ca0 Merge branch 'next' into fix/openai-responses-demo-docs 2026-09-16 14:47:24 +02:00
Brendan O'Leary 7a63e5acd7 docs: add product architecture guides and KB entry points (#4294)
## Summary

Adds canonical guidance for common Composio product-integration
decisions and makes the main paths easy to find from the Knowledge Base
homepage. This PR is independent of #4258 and #4277 and targets `next`
directly.

## Changes

- Add guides for the Composio skill, consumer-agent architecture,
B2B-agent architecture, and moving from prototype to production
- Expand the white-labeling guide with a minimal setup path and FAQ
- Add five Start here cards to `/kb`, before support topics and toolkit
browsing
- Update OAuth callback examples and add relevant sidebar and quickstart
cross-links

## Type of change

- [x] Documentation

## How Has This Been Tested?

- `bun test tests/static/` (528 passed)
- `bun run lint:links`
- `bun run types:check`
- `bun run lint`
- `bun run build`

## 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 and structural homepage coverage
- [x] No changeset is required for docs-only changes
2026-09-15 13:26:59 -04:00
jkomyno 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.
2026-09-15 17:09:09 +02:00
Brendan O'Leary a0dbc6fbae docs: clarify OAuth callback URL matching 2026-09-15 15:06:56 +00:00
mukund-composio 788476a526 docs: project API key permissions (#4246)
We've split project API key permissions from a broad **Sessions** into
**Session management** and **Session tool execution**.

I've also removed the v3/v3.1 prefixes to keep things simpler to
understand and remove duplication.

Backend: [#12279](https://github.com/ComposioHQ/platform/pull/12279),
[#12291](https://github.com/ComposioHQ/platform/pull/12291), [production
#12370](https://github.com/ComposioHQ/platform/pull/12370). Dashboard:
[#1384](https://github.com/ComposioHQ/dashboard/pull/1384).
2026-09-15 20:33:39 +05:30
jkomyno 27701dd541 feat(py): add optional on_subscription_error for trigger subscriptions
Mirror the TypeScript API surface from the previous commit:

- Triggers.subscribe accepts an optional on_subscription_error callback,
  threaded through _SubcriptionBuilder.connect and bound to pysher's
  pusher:subscription_error event on the trigger channel.
- TriggerSubscription._handle_subscription_error logs the failure at the
  SDK boundary and invokes the callback with the parsed payload (or
  {'raw': frame} for malformed frames); callback exceptions are
  contained and logged so a faulty handler cannot tear down pysher's
  dispatch thread.
- The parameter is optional; existing callers are unaffected.
- Update the Python triggers reference and the subscribing-to-events
  guide.

Python never bound pusher:subscription_error at all, so subscription
failures after connect() were previously invisible to hosts.
2026-09-15 16:58:37 +02:00
jkomyno 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.
2026-09-15 16:42:47 +02:00
jkomyno 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.
2026-09-15 16:42:47 +02:00
jkomyno 14cb6b2e75 docs(openai): align responses demo on gpt-5 and print aggregated output
- Use gpt-5 like the rest of the repo's examples (getting-started.md,
  the pre-PR demo) instead of the gpt-5.2 id used nowhere else.
- Print response.output_text instead of dumping the raw Response object,
  matching the final line of the demo.
2026-09-15 16:42:47 +02:00
jkomyno 39e3c35531 docs(openai): rename assistant demo to responses demo
The demo no longer uses the deprecated Assistants API; the filename now
matches the Responses API content.
2026-09-15 16:40:59 +02:00
jkomyno 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.
2026-09-15 16:33:00 +02:00
Brendan O'Leary 3f31ef9609 Merge remote-tracking branch 'origin/next' into codex/docs-priority-guides
# Conflicts:
#	docs/tests/static/product-navigation.test.ts
2026-09-15 10:12:04 -04:00
Brendan O'Leary a92d4920f0 docs: finish priority guide integration 2026-09-15 10:08:10 -04:00
Brendan O'Leary 4389b2f0ef docs: broaden harness example category (#4492)
## Summary

- classify the existing harness integration guide as both a
general-agent and coding-agent example
- preserve the coding-agent tag because the same integration pattern
applies there too

## Validation

- bun test tests/static/content.test.ts
- git diff --check

Full docs typechecking could not start in this fresh worktree because
fumadocs-mdx is not installed.
2026-09-15 09:36:06 -04:00
Brendan O'Leary e71a9a22b4 docs: broaden harness example category 2026-09-15 09:31:48 -04:00
jkomyno 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.
2026-09-15 15:20:08 +02:00
Alberto Schiabel 7daab1496f fix(core): stop dropping auth field metadata from toolkit auth details (#4411)
## Summary

`transformToolkitRetrieveResponse` projects `auth_config_details[]` key
by key and silently dropped
three keys the pinned client declares. `is_secret` and
`legacy_template_name` are snake_case, so zod
stripped them; `auth_hint_url` was never listed.

The API documents `is_secret` as "Clients use it to decide whether to
mask the input". Without it a
consumer rendering its own credential form cannot tell an API key from a
shop subdomain, so a field holding a secret is not reported as one.

## Changes

- Map auth fields explicitly; add `isSecret`, `legacyTemplateName` and
`authHintUrl` to the schemas
- Spread optional keys conditionally, so a key the API omits stays
absent rather than `undefined`,
  which would beat a caller's fallback
- Add a runtime test over all four field groups, plus a type-level test
that fails the build on an
unlisted client key in any group. It catches new wire keys, not an
assignment removed from the
  mapper; the runtime test pins that for the keys known today
- Add a patch changeset for `@composio/core`

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

## How Has This Been Tested?

- `pnpm --filter @composio/core test`: 55 files, 1288 passed, 2 expected
fail; typecheck and
  `validate:changesets` exit 0
- `pnpm lint:packages`: exit 0 with 54 pre-existing warnings, one in a
file this PR touches; no new
  warning on added lines
- The runtime test fails 5 of its 7 cases on `origin/next`; the two
green on both are the regression
guards. The type-level test was checked against all four client
interfaces
- Node 24.18.0; `mise.toml` pins 24.17.0, unavailable here, so it was
not run under it. Not
run: the root workspace suite (its `test:toolchain` needs Bun), Docker
E2E, the Python suite

## Screenshots (if applicable)

N/A

## Checklist
- [x] I have read the Code of Conduct and this PR adheres to it
- [x] I ran linters/tests locally and they passed, with the exceptions
listed above
- [x] I updated documentation as needed (none needed: the new keys carry
TSDoc; the SDK reference is
      generated from unchanged signatures)
- [x] I added tests or explain why not applicable
- [x] I added a changeset if this change affects published packages

## Additional context

Left out on purpose: `user_visible` and `required_scopes`, in the spec
but not the pinned client;
`deprecated_auth_provider_details`, which the client marks deprecated;
and the keys this transformer
drops outside `auth_config_details`, all pre-existing and adjacent.

One behavior change: the eager mapping now throws if an auth config
detail arrives without its
`auth_config_creation` group, where the pass-through still returned the
connection fields. The
client declares both groups required and non-nullable, so this affects
only out-of-contract
responses.
2026-09-15 15:16:51 +02:00
Mukund 6c2bcc554f docs: correct session proxy permission callout 2026-09-15 18:45:04 +05:30
Alberto Schiabel 65a94e6a52 Merge branch 'next' into fix/ts-pusher-subscription-error-boundary 2026-09-15 15:14:49 +02:00
jkomyno 614ae3cd11 refactor(core): clarify toolkit auth mapping guard 2026-09-15 15:14:30 +02:00
Alberto Schiabel d5a26549a7 docs: update Python SDK reference from source (#4479)
## Summary
Auto-generated Python SDK reference docs from `python/composio/`.

Regenerates pages at `docs/content/reference/sdk-reference/python/` to
reflect changes in the Python package's public API (new methods, updated
signatures, changed types).
2026-09-15 15:14:13 +02:00
Moritz Diesing 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>
2026-09-15 15:11:27 +02:00
Alberto Schiabel 84bc4c2cc0 Merge branch 'next' into fix/toolkit-auth-field-is-secret 2026-09-15 14:59:05 +02:00
sosidudku1 5ea73718bc docs: add Atomic Agent to Composio Connect clients
Atomic Agent is a local-first agent (CLI and TUI) that ships a built-in
Composio integration: it connects to the hosted tool router over
Streamable HTTP MCP, so tools are registered at startup as
mcp.composio.*.

Setup is done from the Integrations tab or by adding COMPOSIO_API_KEY to
the agent's .env, so the entry documents that flow rather than the CLI
install used by other terminal agents.
2026-09-15 15:41:13 +03:00
Alberto Schiabel dcac3e4c9c Merge branch 'next' into fix/ts-pusher-subscription-error-boundary 2026-09-15 13:17:44 +02:00
jkomyno 3271679ee0 docs(py): render Raises sections and normalize reST in generated SDK reference
- parse :raises Exc: docstring fields (plus Sphinx synonyms) into a
  structured Raises section instead of leaking raw directives into the
  Returns description
- normalize inline reST in all rendered prose: roles (:class:, :func:,
  :meth:, ...) honor ~ short-name semantics; double-backtick literals
  become single-backtick inline code
- regenerate docs/content/reference/sdk-reference/python/ pages
- add regression tests for raises parsing and reST normalization

Flagged by Greptile on the legacy-repo auto-PR (ComposioHQ/composio#4479).
2026-09-15 13:12:25 +02:00
Alberto Schiabel 30e4b18e4a fix(cli): bare --stream, dead Slack slug in help, tools info exit code, unknown listen slug (#4344)
Fixes for four `composio` CLI issues found while using the released
binary (v0.4.0). Each item below was reproduced from source on `next`
before the change and re-run after it. All commands were run with stdin
from `/dev/null`.

## 1. Bare `--stream` on `composio listen` is rejected

**Repro (before):**
```
$ composio listen GMAIL_NEW_GMAIL_MESSAGE --stream
Received unknown argument: '--stream='
<usage text>
exit=1
```
The command's own EXAMPLES block shows `composio listen
GMAIL_NEW_GMAIL_MESSAGE -p @trigger.json --stream`, and
`--stream=.data.text` / `--stream '.data.text'` both work.

**Cause:** `normalizeListenStreamFlag` in `src/commands/index.ts`
rewrites a valueless `--stream` to `--stream=`. `@effect/cli` only
recognises `--flag=value` when the value is non-empty (`FLAG_REGEX =
/^(--[^=]+)(?:=(.+))?$/`), so `--stream=` is treated as an unknown
argument.

**Change:** rewrite bare `--stream` to the two tokens `--stream ''`
instead. The listen handler already treats an empty path as "stream the
whole payload", so no handler change is needed.

**After:** `composio listen GMAIL_NEW_GMAIL_MESSAGE --stream` and `...
--stream --max-events 1` both parse and proceed to trigger creation.
Tests added in `listen.cmd.test.ts` cover bare `--stream` at the end of
argv and followed by another option.

## 2. Help examples reference a tool slug that no longer exists

**Repro (before):**
```
$ composio --help full | grep SLACK_
  SLACK_SEND_A_MESSAGE_TO_A_SLACK_CHANNEL -d '{ channel: "general", text: "Hello" }'

$ composio execute SLACK_SEND_A_MESSAGE_TO_A_SLACK_CHANNEL --dry-run -d '{ channel: "general", text: "Hello team" }'
services/HttpServerError
Caused by: 404 {"error":{"message":"Tool SLACK_SEND_A_MESSAGE_TO_A_SLACK_CHANNEL not found","code":2401,"slug":"Tool_ToolNotFound",...}}
exit=1
```
The current slug is `SLACK_SEND_MESSAGE`. Its input schema (`composio
tools info SLACK_SEND_MESSAGE`) has `channel`, `markdown_text`,
`blocks`, `thread_ts`, ... and no `text` key.

**Change:** the three occurrences in `src/commands/root-help.ts`
(execute examples, the `run` script example, and the root help snippet)
now use `SLACK_SEND_MESSAGE` with `markdown_text`. No other file in the
repo references the old slug.

## 3. `composio tools info <bad-slug>` prints nothing and exits 0

**Repro (before):**
```
$ composio tools info BOGUS_TOOL_XYZ; echo exit=$?
exit=0
$ composio tools info BOGUS_TOOL_XYZ 2>/dev/null | wc -c
0
```
`tools info` catches the 404 with the shared `handleHttpServerError`
helper, which logs through `ui.log.error` (rendered only when stderr is
a TTY) and returns a fallback value, so the command completes
successfully with no output when piped.

**Change:** `src/effects/handle-http-error.ts` now sets
`process.exitCode = 1` (the convention used elsewhere in the CLI, e.g.
`toolkits search`) and, when stderr is not a TTY, writes the error
message plainly via `ui.error` so it is still visible. The decorated
log/hint/suggestion flow is unchanged. This helper is shared by the
`info`/`create`/`enable`/`disable`/`status` commands for tools,
triggers, auth configs and connected accounts, all of which return early
on the same failure path, so they now exit non-zero on an API error as
well.

**After:**
```
$ composio tools info BOGUS_TOOL_XYZ; echo exit=$?
Tool "BOGUS_TOOL_XYZ" not found.
exit=1
```
Tests added in `tools.info.cmd.test.ts` assert the exit code and message
for an unknown slug, and that a valid slug leaves the exit code
untouched.

## 4. `composio listen <unknown-slug>` reports a missing connection
instead of an unknown slug

**Repro (before):**
```
$ composio listen BOGUS_SLUG_XYZ
commands/ListenCommandError  • No active connected account found for toolkit "bogus" and consumer user "...". Run `composio link bogus` first.
exit=1
```
The toolkit is inferred from the slug prefix and the connected-account
lookup runs without checking that the trigger type exists, so a typo
sends the user to link an account for a toolkit that does not exist.

**Change:** in `src/commands/listen.cmd.ts`, when no active connected
account matches, the command now retrieves the trigger type first. A 404
fails with a new `unknown_trigger` reason; any other outcome falls
through to the existing connected-account error. The same lookup runs
when creating the temporary trigger fails, because an active account for
the inferred toolkit (e.g. `GMAIL_NEW_GMAIL_MESAGE` with Gmail linked)
skips the first check; a 404 there replaces the generic `create_trigger`
error. The happy path makes no additional request.

**After:**
```
$ composio listen BOGUS_SLUG_XYZ
commands/ListenCommandError  • Unknown trigger slug "BOGUS_SLUG_XYZ". List available slugs with `composio triggers list <toolkit>`.
exit=1
```
The test layer gained a `triggersTypes.retrieve` mock (the base client
would otherwise hit the network), and `listen.cmd.test.ts` covers the
unknown-slug case both without an account and with an active account for
the inferred toolkit (the test layer's `triggerInstances.upsert` can now
reject unknown slugs via `triggersData.rejectUnknownTriggerSlugs`). The
existing missing-connection test now provides a
`GMAIL_NEW_GMAIL_MESSAGE` trigger-type fixture so it still exercises the
connected-account branch.

## Also: `listen` example used a trigger with an empty config

While updating the help examples above, the `-p` example `composio
listen SLACK_RECEIVE_MESSAGE -p '{ trigger_config: { channel: "C123" }
}'` was replaced. `composio triggers info SLACK_RECEIVE_MESSAGE` returns
`"config": {"properties": {}, ...}`, so that example configures nothing.
`SLACK_CHANNEL_MESSAGE_RECEIVED` takes `channel_id`, so the example now
uses that trigger and key. Same one-line change in
`skills-src/composio-cli/index.ts`, which is the source for the
generated CLI skill.

## Changelog

All four fixes are recorded under Unreleased in
`ts/packages/cli/CHANGELOG.md` (the CLI is excluded from Changesets).

## Verification

- `pnpm typecheck` (src + test) in `ts/packages/cli`
- `pnpm test` in `ts/packages/cli` (validate:skills,
validate:boundaries, vitest)
- `oxlint` and `prettier --check` on the changed files
- Live re-runs of each repro above against the API from source
@composio/cli@0.4.2-beta.394
2026-09-15 13:10:18 +02:00
jkomyno f05fbf6323 refactor(cli): replace listen create_trigger error explicitly on unknown slugs 2026-09-15 12:55:29 +02:00
Mukund cc3c5836a9 docs: recommend write-only access for session creation 2026-09-15 15:58:19 +05:30
Mukund 65255d31ac docs: limit permission updates to session changes and reference labels 2026-09-15 15:54:48 +05:30
jkomyno f3bfa06704 fix(cli): report unknown listen slugs when the inferred toolkit has an account 2026-09-15 12:16:43 +02:00
jkomyno bda26b8116 docs(cli): restore changelog and record listen and exit-code fixes 2026-09-15 12:16:42 +02:00
Mukund 77004dacdd docs: document session proxy access under session execution only 2026-09-15 13:58:34 +05:30
Mukund b7ac0ec68d docs: focus scoped key guidance on session permissions 2026-09-15 13:53:46 +05:30
Mukund befbd680fe Merge next and refresh scoped key permission guidance 2026-09-15 13:51:09 +05:30
Mukund 61a2674ef5 docs: simplify scoped key permissions and reconcile current routes 2026-09-15 13:49:57 +05:30
jkomyno 6555773152 fix(cli): port listen slug check to Effect v4 and pin exit-code contract
- listen: replace `Effect.catchAll`, which no longer exists in
  effect@4.0.0-rc.112, with `Effect.result` and narrow the lookup failure
  with `NotFoundError` from @composio/client instead of a structural
  status check.
- tests: `it.scoped` is gone from @effect/vitest v4 (`it.effect` already
  provides a Scope); switch the new cases over and assert the exit code on
  `triggers info` too, so the shared handler's contract is covered by more
  than one command.
- handle-http-error: also print the hint plainly when stderr is not a TTY.
- changelog: record the four user-visible fixes.

Claude-Session: https://claude.ai/code/session_01SvfF1wniMJsBDo5PaBjm2Y
2026-09-15 09:31:13 +02:00
Alberto Schiabel 6a321a13ca Merge branch 'next' into fix/cli-listen-stream-help-slugs-not-found 2026-09-15 00:36:48 +02:00
jkomyno c4daeac1d0 Merge origin/next into claude/cli-execute-output-byte-cutoff
Claude-Session: https://claude.ai/code/session_01MTb47vexN35pLGsSZwBmrJ
2026-09-15 00:13:58 +02:00