From 027aac22aace776ae49e067173efdcda3bd0a163 Mon Sep 17 00:00:00 2001 From: Igor Date: Sun, 17 May 2026 08:47:10 +0700 Subject: [PATCH 01/32] temp-before-merge-codex-2be5-composio --- AGENTS.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index c2eaa1316..e938ac0dd 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -15,7 +15,8 @@ 1. commit task in feature worktree 2. create/switch feature branch 3. rebase feature branch on `main` - 4. from main worktree: `git checkout main && git merge --no-ff ` + 4. if a GitHub PR exists or GitHub merge is available, prefer updating/creating the PR, rebasing the branch, and merging the PR on GitHub instead of merging locally + 5. if no PR/GitHub merge path is available, from main worktree: `git checkout main && git merge --no-ff ` - If user explicitly asks for a single merge commit, use: - `git checkout main` - `git reset --hard ` From 7140fd38bd42bf2aa189882b55371c9c644993a1 Mon Sep 17 00:00:00 2001 From: Igor Date: Sun, 17 May 2026 08:47:25 +0700 Subject: [PATCH 02/32] Add Composio preview, suggestions, and logout --- src/api/codexGateway.test.ts | 26 +- src/api/codexGateway.ts | 16 + src/components/content/DirectoryHub.vue | 267 +++-- src/components/content/ThreadComposer.vue | 102 ++ .../composioComposerSuggestions.test.ts | 46 + .../content/composioComposerSuggestions.ts | 47 + .../content/composioConnectorCatalog.test.ts | 15 + .../content/composioConnectorCatalog.ts | 1004 +++++++++++++++++ src/server/codexAppServerBridge.ts | 36 + tests.md | 71 ++ 10 files changed, 1504 insertions(+), 126 deletions(-) create mode 100644 src/components/content/composioComposerSuggestions.test.ts create mode 100644 src/components/content/composioComposerSuggestions.ts create mode 100644 src/components/content/composioConnectorCatalog.test.ts create mode 100644 src/components/content/composioConnectorCatalog.ts diff --git a/src/api/codexGateway.test.ts b/src/api/codexGateway.test.ts index 7bb4980f9..978874181 100644 --- a/src/api/codexGateway.test.ts +++ b/src/api/codexGateway.test.ts @@ -1,5 +1,5 @@ import { afterEach, describe, expect, it, vi } from 'vitest' -import { getAvailableModelIds, getThreadDetail, listDirectoryComposioConnectors, resumeThread, startThreadTurn } from './codexGateway' +import { getAvailableModelIds, getThreadDetail, listDirectoryComposioConnectors, logoutDirectoryComposioCli, resumeThread, startThreadTurn } from './codexGateway' function mockRpcFetch(): { requests: Array<{ method: string, params: Record }> } { const requests: Array<{ method: string, params: Record }> = [] @@ -86,6 +86,30 @@ describe('listDirectoryComposioConnectors', () => { expect(requests).toEqual(['/codex-api/composio/connectors?query=instagram&cursor=50&limit=25']) }) + + it('posts to the logout endpoint', async () => { + const requests: Array<{ input: string, method: string }> = [] + vi.stubGlobal('fetch', vi.fn(async (input: RequestInfo | URL, init?: RequestInit) => { + requests.push({ + input: String(input), + method: String(init?.method ?? 'GET'), + }) + return new Response(JSON.stringify({ + ok: true, + command: 'composio logout', + output: '', + }), { + status: 200, + headers: { + 'Content-Type': 'application/json', + }, + }) + })) + + await logoutDirectoryComposioCli() + + expect(requests).toEqual([{ input: '/codex-api/composio/logout', method: 'POST' }]) + }) }) describe('getAvailableModelIds', () => { diff --git a/src/api/codexGateway.ts b/src/api/codexGateway.ts index 9bfa06437..1eb1f9da8 100644 --- a/src/api/codexGateway.ts +++ b/src/api/codexGateway.ts @@ -241,6 +241,12 @@ export type DirectoryComposioInstallResult = { output: string } +export type DirectoryComposioLogoutResult = { + ok: boolean + command: string + output: string +} + type DirectoryComposioConnectorPage = { data: DirectoryComposioConnector[] nextCursor: string | null @@ -2376,6 +2382,16 @@ export async function installDirectoryComposioCli(): Promise { + const response = await fetch('/codex-api/composio/logout', { + method: 'POST', + }) + if (!response.ok) { + throw new Error(`Failed to logout Composio CLI (${response.status})`) + } + return await response.json() as DirectoryComposioLogoutResult +} + export async function getAccountRateLimitsResponse(): Promise { return await callRpc('account/rateLimits/read') } diff --git a/src/components/content/DirectoryHub.vue b/src/components/content/DirectoryHub.vue index beff5537a..01e1c9d28 100644 --- a/src/components/content/DirectoryHub.vue +++ b/src/components/content/DirectoryHub.vue @@ -228,56 +228,76 @@
{{ composioError }}
-
Loading Composio connectors...
-
-
-

Composio CLI is not installed in this environment.

-
- -
-
-
-
+
Loading Composio connectors...
+
C

Connector catalog preview

-

Connect everyday apps like Gmail, Calendar, Reddit, YouTube, and Drive.

+

Browse the full Composio connector catalog before install or login.

- Composio is installed locally. Login to browse the live catalog, connect your accounts, and try simple actions from this machine. + {{ !composioStatus?.available + ? 'This preview is hardcoded from a fetched Composio toolkit export. Install the CLI to connect accounts and unlock live status.' + : 'Composio is installed locally. Login to merge your live account status into this catalog and try simple actions from this machine.' }}

- + -
-
+
-
{{ connector.initial }}
+ +
{{ connector.name.charAt(0) }}
{{ connector.name }} Preview
- {{ connector.meta }} + {{ composioMetaLabel(connector) }}

{{ connector.description }}

- {{ chip }} + {{ connector.toolsCount }} tools + {{ connector.triggersCount }} triggers + No auth +
+
+
+
+ +
@@ -298,13 +318,16 @@ {{ composioStatus.defaultOrgName }} CLI {{ composioStatus.cliVersion }} - Showing {{ composioConnectors.length }}{{ composioTotal ? ` / ${composioTotal}` : '' }} connectors + Showing {{ visibleComposioConnectors.length }} / {{ composioTotal }} connectors
+
@@ -633,7 +656,34 @@ Open dashboard + + +
+
+ +
+
{ } } +async function logoutComposioCli(): Promise { + const invocation = resolveComposioInvocation(['logout']) + if (!invocation) { + throw new Error('Composio CLI is not installed') + } + const result = spawnSync(invocation.command, invocation.args, { + encoding: 'utf8', + env: process.env, + windowsHide: true, + }) + const output = `${result.stdout ?? ''}${result.stderr ?? ''}`.trim() + if (result.error || result.status !== 0) { + throw new Error(output || result.error?.message || 'Failed to logout Composio CLI') + } + return { + ok: true, + command: invocation.displayCommand, + output, + } +} + function countRecoveredContentLines(value: string): number { if (!value) return 0 const normalized = value.replace(/\r\n/g, '\n') @@ -6905,6 +6932,15 @@ export function createCodexBridgeMiddleware(): CodexBridgeMiddleware { return } + if (req.method === 'POST' && url.pathname === '/codex-api/composio/logout') { + try { + setJson(res, 200, await logoutComposioCli()) + } catch (error) { + setJson(res, 500, { error: getErrorMessage(error, 'Failed to logout Composio CLI') }) + } + return + } + if (req.method === 'GET' && url.pathname === '/codex-api/connector-logo') { const src = url.searchParams.get('src')?.trim() ?? '' if (!src) { diff --git a/tests.md b/tests.md index a275a391a..ad124885c 100644 --- a/tests.md +++ b/tests.md @@ -336,6 +336,77 @@ Rollback/cleanup: --- +### Composio panel shows hardcoded connector preview without install or login + +#### Feature/Change Name +Composio connector catalog preview and live-status merge in the directory panel. + +#### Prerequisites/Setup +1. Dev server running (`pnpm run dev --host 127.0.0.1 --port 4173`) +2. Open the Skills and Apps directory route with the Composio tab available +3. Be able to switch between light theme and dark theme +4. For the unauthenticated preview path, either use an environment without the Composio CLI or log out of Composio before opening the tab + +#### Steps +1. In light theme, open the Composio tab. +2. If Composio is not installed, confirm the preview hero still renders, the Install Composio button is visible, and connector cards still load from the hardcoded catalog. +3. If Composio is installed but logged out, confirm the preview hero renders, the Login to Composio button is visible, and the connector list is still searchable. +4. Search for `gmail` and confirm Gmail appears with tool counts from the hardcoded catalog. +5. Clear the search and click Load more; confirm more connector cards render without another server round-trip. +6. Open a preview connector Details modal and confirm overview data renders even before install/login. +7. Log into Composio, refresh the Composio tab, and confirm the same catalog now shows merged live connection badges and actions where applicable. +8. Click the Logout button in the Composio workspace card or connector detail footer. +9. Confirm the panel returns to preview mode while still showing the hardcoded connector catalog. +10. Switch to dark theme and repeat steps 1-9. + +#### Expected Results +- The Composio tab always renders connector cards from the hardcoded TypeScript catalog, even when the CLI is missing or logged out. +- Install/login state changes only the hero/actions and any merged live status, not whether the catalog is visible. +- Logout is available directly from the authenticated Composio panel and returns the UI to the logged-out preview state. +- Search and Load more work client-side against the full hardcoded catalog. +- Preview Details works before install/login, and live Details still works after authentication. +- Light theme and dark theme both render the preview and authenticated states correctly. + +#### Rollback/Cleanup +- If you logged into Composio only for this test, log out afterward if desired. + +--- + +### Composer suggests matching Composio connectors while typing + +#### Feature/Change Name +Realtime Composio connector suggestions in the chat composer. + +#### Prerequisites/Setup +1. Dev server running (`pnpm run dev --host 127.0.0.1 --port 4173`) +2. Open any thread with the normal composer visible +3. Light theme and dark theme available +4. For connected ranking checks, have at least one active Composio connector such as Reddit + +#### Steps +1. In light theme, focus the composer and type `reddit`. +2. Confirm a connector suggestion strip appears above the textarea. +3. Confirm Reddit is shown and, if connected, the suggestion copy indicates it is connected. +4. Click the Reddit suggestion. +5. Confirm the `composio-cli` skill chip is added to the composer and a connector-specific instruction line is appended to the draft. +6. Clear the draft, type another connector name such as `gmail`, and confirm the matching suggestion updates while typing. +7. Type `@` to open file mentions and confirm the Composio suggestion strip does not interfere with the file mention popup. +8. Log out of Composio and repeat steps 1-7. +9. Switch to dark theme and repeat steps 1-8. + +#### Expected Results +- Connector suggestions appear in realtime from normal draft text without requiring `@` syntax. +- Matching connected connectors rank ahead of unconnected matches. +- After Composio logout, matching suggestions still appear from the hardcoded catalog but without connected-state emphasis. +- Clicking a suggestion attaches the Composio skill and appends a connector-specific instruction to the draft. +- File mention behavior remains intact and takes precedence when the `@` popup is open. +- Light theme and dark theme both render the suggestion strip correctly. + +#### Rollback/Cleanup +- Remove the appended connector instruction and skill chip if you do not want to send them. + +--- + ### Automation editor scrolls on small viewports #### Feature/Change Name From 82b9cccebd47236f86da6982d7fc3a0a4fd399d9 Mon Sep 17 00:00:00 2001 From: Igor Date: Sun, 17 May 2026 09:05:52 +0700 Subject: [PATCH 03/32] Attach Composio connector docs from composer --- src/components/content/ThreadComposer.vue | 130 ++++++++++++++---- .../composioComposerSuggestions.test.ts | 25 +++- .../content/composioComposerSuggestions.ts | 74 +++++++++- src/server/codexAppServerBridge.ts | 2 +- src/style.css | 16 +++ tests.md | 30 ++++ 6 files changed, 244 insertions(+), 33 deletions(-) diff --git a/src/components/content/ThreadComposer.vue b/src/components/content/ThreadComposer.vue index 93ad5728f..7e00e7c8e 100644 --- a/src/components/content/ThreadComposer.vue +++ b/src/components/content/ThreadComposer.vue @@ -82,25 +82,6 @@
-
- -
- +
+ +