`composio --version` goes from 288ms to 199ms, peak RSS from 97.8MB to
77.3MB, and the executable from 85.9MB to 79.7MB. Every command benefits.
A compiled Bun binary parses its whole embedded bundle before the first
line of JavaScript runs, and #4468 had already made sure the TypeScript
compiler and the tokenizer rank table were never *evaluated* unless
`generate`, `run`, or a large `execute` response needed them. They were
still *parsed* on every start: the compiler alone was 44% of the
executable's JavaScript and the o200k rank table another 28%, so
`--version` spent ~75ms reading code it could never call.
Both now ship as companion modules next to the executable, through the
mechanism `composio run` already uses for its own runtime helpers:
- `generation-runtime.mjs` carries `src/generation/*`, the `composio run`
source rewrites, `typescript`, `@composio/ts-builders` and
`openapi-typescript`. `generate ts`, `generate py` and `run` load it
with `loadInstalledCompanionModule`; from a source checkout the loader
resolves the `.ts` next to `run-companion-modules.ts` instead, so tests
and `bun run src/bin.ts` need no build step.
- `execute-output-encoder-runtime.mjs` carries `js-tiktoken/lite` and the
rank table. `execute` loads it only once a response exceeds the 10KB
byte pre-filter.
A companion bundles its own copy of `effect`, and a fiber cannot run
primitives built by another copy of the runtime, so nothing Effect-shaped
crosses the boundary: the generation companion exposes plain functions
and promises, runs its pipelines on its own runtime, and returns failures
as values that `src/generation/errors.ts` rebuilds as the CLI's own error
classes, stack included. Generated output is byte-identical to #4468 for
`generate ts`, `generate ts --transpiled` and `generate py`.
Both modules join `RUN_COMPANION_MODULE_BASENAMES`, so the build, release
packaging, install verification, `upgrade` and the self-repair download
pick them up unchanged. The three hand-maintained uninstall lists and the
upgrade E2E fixture gain the two file names.
Two smaller startup costs go with it:
- `src/constants.ts` imported `constants` from `@composio/core`'s root
entry for two strings and two URLs, which evaluated the whole SDK at
startup (~25ms of module-scope work, mostly zod schemas). The four
values are spelled out and pinned to core's by a test.
- `tool-file-uploads.ts` imported three core helpers at module scope that
only a file upload reaches; they are imported on that path now.
The binary build gains a guard: after bundling the companions it bundles
`src/bin.ts` once more unminified and fails if the executable's graph
reaches `typescript`, `js-tiktoken`, core's root entry, `src/generation/*`
or a companion entry. Without it a stray static import would put the
compiler back into the executable with nothing to notice.
Building also surfaced that `assertBundledRuntimeFiles` blanked string
literals to same-length runs of spaces, which made the import patterns'
`^\s*` backtrack quadratically across the compiler's multi-megabyte
embedded lib strings and stalled the build for over ten minutes. String
bodies are dropped now. (The check itself has never matched a specifier,
since the specifiers it looks for are the string literals it removes;
that is left as it was.)
Measured on the pinned toolchain, Bun 1.4.1+4661e494f, linux-x64, best
of 15, telemetry disabled, both binaries built in the same session:
composio --version 288ms -> 199ms
tools execute --help 287ms -> 202ms
peak RSS 97.8MB -> 77.3MB
executable 85.9MB -> 79.7MB
executable JavaScript 8.3MB -> 2.1MB (minified)
The `execute` tail after `execute.tool_call.end` is unchanged for
responses under 10KB (~10ms) and ~20ms slower above it (351 -> 374ms),
which is the on-demand parse of the 2.2MB encoder companion.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Wx9gEjuiHux2weiHjdNcDs
The 07-31 changelog entry is already published on next and describes the
install-only default that composio.dev/install serves today. Rewriting it
in place would replace a live, accurate description with its opposite
under a date on which that behavior never shipped, and readers who
already saw it would get no notice of the flip.
Restore that entry verbatim and add a dated 08-05 entry carrying the
behavior-change callout, the auto/none bullets, and the created
~/.bash_profile disclosure.
The download-verification section moves to the new entry rather than
staying on 07-31: the strict abort is new here. The live installer warns
and continues when checksums.txt is missing -- the official_release_source
gate that turns that into an abort does not exist there.
Also scope the HTTPS claim, which is_allowed_http_authority contradicts
for loopback and COMPOSIO_INSTALL_ALLOW_HTTP_HOST; document the second
shape of the installer-created ~/.bash_profile, which survives the
documented uninstall when ~/.profile existed; and record the checksum
abort in INSTALL.md, where someone hitting 'Refusing to install' will
look for it.
The uninstall snippet now stages each startup-file rewrite in a 0600
mktemp file, promotes it only when the filter succeeds (preserving
symlinks, inode, owner, and mode), always cleans up, removes legacy
three-line blocks including the fish install-dir export, and deletes an
installer-created ~/.bash_profile left empty so bash regains its default
startup-file selection. A new suite extracts the snippet verbatim from
the docs and exercises it under sh and dash, wired into the install
script unit-test workflow.
A login bash reads /etc/profile and then only the first existing of
~/.bash_profile, ~/.bash_login, ~/.profile; it never reads ~/.bashrc.
macOS Terminal.app starts exactly such a shell, so a terminal opened
after installation could not resolve composio even though the installer
reported success.
Always configure a login-mode startup file alongside ~/.bashrc: reuse an
existing ~/.bash_profile or ~/.bash_login, otherwise create
~/.bash_profile seeded to keep sourcing ~/.profile, which it shadows.
~/.profile itself is never rewritten.
Also refine the shell setup reporting:
- capture the delegated `composio install --shell` output so the
installer keeps sole ownership of its presentation, replaying it under
COMPOSIO_DEBUG so failures stay diagnosable
- drop the internal (cli)/(fallback) labels from user-facing output
- name the configured startup files from both the delegated and inline
paths, so piped installs disclose which files changed
Replace the base installer's --shell flag with a COMPOSIO_INSTALL_SHELL
environment variable, matching the COMPOSIO_INSTALL_VERSION precedent
and reading more naturally in the curl-pipe form:
curl -fsSL https://composio.dev/install | COMPOSIO_INSTALL_SHELL=zsh sh
The variable is validated before any network call. Shell variants set
it explicitly when invoking the base installer, so the route stays
authoritative over any inherited value. The composio install --shell
CLI flag and the delegation/fallback behavior are unchanged.
Teach install.sh a --shell <zsh|bash|fish> flag that performs the same
shell setup the /install/<shell> variants do: delegate to
'composio install --shell' when the installed CLI supports it, fall
back to writing the # Composio CLI PATH block inline otherwise.
The shell variants become thin wrappers that fetch the base installer
and append '--shell <name>' to the forwarded arguments, so the
delegation and fallback logic now lives in exactly one script. This
also removes the double-configuration hazard of a variant blindly
forwarding a user-supplied --shell.
Shell setup no longer depends on the composio.dev/install/<shell>
redirect rules existing: post-install guidance, docs, and release
notes now print 'curl -fsSL https://composio.dev/install | sh -s --
--shell <shell>', which works through the single existing redirect.
The variant scripts and their raw-URL preview commands keep working
for when the routes land.
Coverage: direct --shell delegation, fallback on unsupported or
failing CLI, missing and invalid values failing before any network
call, and a Docker e2e leg for the idempotent --shell bash flow.
- make the documented uninstall strip legacy three-line PATH blocks
(dangling 'export PATH' left cwd on PATH) and preserve symlinked rc
files by writing back in place instead of mv
- point readers at Configure your shell before 'composio login' when
~/.local/bin is not on PATH
- restore an Update section covering 'composio upgrade', version
pinning, and --beta
- drop the completions claim from install.sh post-install help; shell
routes configure PATH only
- replace the nonexistent @composio/cli@0.3.1-beta.2 example tag with
the published 0.3.1-beta.329
- add the missing changelog description and note that the uninstall
file list tracks the current release layout
curl install.sh is now the only CLI install channel.
- INSTALL.md: drop npm/pnpm/yarn section; Windows guidance is WSL
- install.sh: Windows error no longer advises the dead npm package
- build-cli-binaries.yml: strip npm section from generated release INSTALL.md
- cli.install-health-check.yml: drop stale npm dist-tag/Homebrew comment
- cli.test-installation.yml: delete no-op npm-fallback job and its
toolchain-versions feeder job; prune summary references
- delete cli.bump-homebrew-tap.yml + bump-homebrew-formula.py (automation
never fired: GITHUB_TOKEN-published releases suppress release-triggered
workflows and HOMEBREW_TAP_TOKEN is dead)
- ts/packages/cli/package.json: drop unused publishConfig (package is private)
- cli-release skill + CLI AGENTS.md: remove Homebrew steps from release docs
- toolchain-versions.json: drop now-unused node_install_compat matrix
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The documented one-line CLI install command curls `install.sh` from the
`main`
branch:
```bash
curl -fsSL https://raw.githubusercontent.com/ComposioHQ/composio/main/install.sh | bash
```
But the repository's default branch is `next` and there is no `main`
branch.
`raw.githubusercontent.com` does not fall back to the default branch, so
the
documented command returns HTTP 404 and the install fails for anyone who
copies
it from `INSTALL.md`.
This replaces the `main` branch segment with `next` in the
`raw.githubusercontent.com/ComposioHQ/composio/<branch>/install.sh` URL
at every
documented occurrence, so the install one-liner resolves. It matches the
`next`
branch already used for the raw asset URL in `README.md`. `install.sh`
itself
needs no change: it downloads binaries from release assets, not from a
branch raw
URL.
Fixes #
<!-- No open issue; self-identified bug. Leave the Fixes line blank, or
remove it. -->
### Changes
- `INSTALL.md`: update the 5 `.../composio/main/install.sh` URLs to
`.../composio/next/install.sh` (One-line Install, Install specific
version, and
the Troubleshooting / manual-download / environment-variable examples).
- `.github/workflows/build-cli-binaries.yml`: same `main` -> `next`
update at the
2 URLs inside the `create-install-instructions` job's heredoc, which
regenerates
`INSTALL.md` as a GitHub Release artifact, so the released copy carries
the
working URL too and stays consistent with the checked-in file.
### Type of change
- [ ] Bug fix
- [ ] New feature
- [ ] Refactor/Chore
- [x] Documentation
- [ ] Breaking change
<!-- It is a documentation URL fix that also updates the CI job which
regenerates
that documentation. Marked Documentation; a reviewer may also consider
it a Bug
fix. -->
### How Has This Been Tested?
No application code changed (static Markdown plus a CI heredoc), so no
unit test
applies. Verified the branch/URL facts directly:
```
# Default branch is next; no main branch exists
git ls-remote --symref origin HEAD # -> ref: refs/heads/next
git ls-remote --heads origin main next # only refs/heads/next (+ changeset-release/next); no main
# The broken vs working URL, live
curl -s -o /dev/null -w "%{http_code}" https://raw.githubusercontent.com/ComposioHQ/composio/main/install.sh # 404
curl -s -o /dev/null -w "%{http_code}" https://raw.githubusercontent.com/ComposioHQ/composio/next/install.sh # 200
# After the change: 0 remaining main URLs, 7 next URLs
grep -rn "composio/main/install.sh" INSTALL.md .github/workflows/build-cli-binaries.yml # no matches
grep -rn "composio/next/install.sh" INSTALL.md .github/workflows/build-cli-binaries.yml # 7 matches
# The workflow YAML still parses cleanly after the heredoc edit
python -c "import yaml; yaml.safe_load(open('.github/workflows/build-cli-binaries.yml'))"
```
### 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 <!-- YAML re-parses;
grep + curl checks above -->
- [x] I updated documentation as needed <!-- this change is the
documentation fix -->
- [ ] I added tests or explain why not applicable <!-- N/A: static docs
URL + CI heredoc, no code path to test -->
- [ ] I added a changeset if this change affects published packages <!--
N/A: docs + CI only, no published package -->
### Additional context
The 14 `github.com/ComposioHQ/composio/tree/main/...` `homepage` fields
in
`ts/**/package.json` also point at the non-existent `main` branch, but
those are
published-package metadata (a different URL form that would require a
changeset)
and are left out to keep this PR single-purpose. They are a reasonable
follow-up.