fix(tracker-linear): fall back to direct transport when @composio/core is missing#2010
Conversation
…e is missing A bare COMPOSIO_API_KEY (often exported globally for unrelated Composio work) hijacked transport selection into the Composio SDK path, which hard-failed because @composio/core is an optional dependency not installed with the plugin — breaking the tracker even when a valid LINEAR_API_KEY was present. The Composio transport now throws a typed ComposioSdkMissingError; when a LINEAR_API_KEY is available the tracker transparently falls back to the direct transport. The dep_missing event fires only when no fallback exists. Also isolate COMPOSIO_API_KEY in the direct-transport test suite so it is deterministic regardless of the developer's shell. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Greptile SummaryAdds a typed
Confidence Score: 5/5Safe to merge — the fallback logic is correct, the once-per-process event guard is properly shielded by recordTransportActivityEvent, and the test suite covers all four key scenarios including the activity-log-throws edge case. The withComposioFallback wrapper correctly handles the fallback path, emitDepMissingOnce calls recordTransportActivityEvent which already swallows logging exceptions, and env-var isolation in the direct-transport test suite removes the previously non-deterministic behaviour on developer machines. No new defects were identified in the changed code. No files require special attention.
|
| Filename | Overview |
|---|---|
| packages/plugins/tracker-linear/src/index.ts | Fallback logic, error extraction, and dep_missing guard all look correct; emitDepMissingOnce calls recordTransportActivityEvent which already has the try-catch shield. |
| packages/plugins/tracker-linear/test/composio-fallback.test.ts | New regression suite covering fallback, no-dep_missing-on-fallback, no-key-throws, and activity-log-throws scenarios. Relies on @composio/core being absent rather than a mocked dynamic import, an explicit authorial choice noted in the file comment. |
| packages/plugins/tracker-linear/test/index.test.ts | Adds save/restore of COMPOSIO_API_KEY and COMPOSIO_ENTITY_ID around each test so the direct-transport suite is deterministic on developer machines with those vars globally set. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["create()"] --> B{"COMPOSIO_API_KEY set?"}
B -- No --> C["createDirectTransport()"]
B -- Yes --> D["createComposioTransport() + withComposioFallback()"]
D --> E["Call composio transport"]
E --> F{"import @composio/core"}
F -- Success --> G["Execute via Composio SDK"]
F -- ERR_MODULE_NOT_FOUND --> H["throw ComposioSdkMissingError"]
H --> I{"LINEAR_API_KEY set?"}
I -- Yes --> J["createDirectTransport() cached"]
J --> K["active = direct, call direct transport"]
K --> L["Return result, no dep_missing event"]
I -- No --> M["emitDepMissingOnce()"]
M --> N["re-throw ComposioSdkMissingError"]
G --> O["Return result"]
C --> P["Execute via Linear HTTPS API"]
P --> O
Reviews (2): Last reviewed commit: "fix(tracker-linear): address review — gu..." | Re-trigger Greptile
…ize fallback transport - emitDepMissingOnce now routes through recordTransportActivityEvent so a throwing activity sink can't replace the ComposioSdkMissingError that callers (and tests) pattern-match on. - Memoize the direct transport in withComposioFallback so concurrent first-calls reuse one instance instead of creating redundant ones. - Add regression test: SDK-missing error still surfaces when logging throws. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
Both addressed in 3aed256:
|
Summary
Fixes #2009.
tracker-linear'screate()picks its transport by sniffing env: ifCOMPOSIO_API_KEYis set it routes through the Composio SDK, otherwise the directLINEAR_API_KEYAPI. But@composio/coreis an optional dependency that isn't installed with the plugin, so any user withCOMPOSIO_API_KEYexported (common — AO is a Composio project, so contributors set it globally for unrelated work) hit a hard"Composio SDK (@composio/core) is not installed"failure on every tracker call, even with a validLINEAR_API_KEY. There was no fallback.This PR:
ComposioSdkMissingErrorwhen@composio/corecan't be loaded.withComposioFallback: when the SDK is missing and aLINEAR_API_KEYis present, the tracker transparently falls back to the direct transport instead of failing.tracker.dep_missingevent only when there is genuinely no fallback (noLINEAR_API_KEY), so a successful fallback no longer raises a false error-level event.COMPOSIO_API_KEY/COMPOSIO_ENTITY_IDin the direct-transport test suite (test/index.test.ts) so it's deterministic regardless of the developer's shell. (Previously this suite failed wholesale on machines withCOMPOSIO_API_KEYexported; CI stayed green only because it deliberately omits the var.)Test plan
test/composio-fallback.test.ts: falls back to direct transport when@composio/coreis missing butLINEAR_API_KEYis set; does not emitdep_missingon successful fallback; still throws when noLINEAR_API_KEYis available.activity-events.test.ts(dep_missing MUST emit) andcomposio-transport.test.ts(mocked SDK) unchanged and green.pnpm --filter @aoagents/ao-plugin-tracker-linear test→ 81 passed.typecheckandeslintclean on changed files.🤖 Generated with Claude Code